Browse Source

Change existing gradient brushes to accept PointF (#865)

* Change existing gradient brushes to accept PointF

* Change PositionOnGradient to accept float

* Remove invalid assert.
pull/879/head
Poyo 7 years ago
committed by James Jackson-South
parent
commit
0dfa2f9f98
  1. 18
      src/ImageSharp.Drawing/Processing/EllipticGradientBrush{TPixel}.cs
  2. 12
      src/ImageSharp.Drawing/Processing/GradientBrushBase{TPixel}.cs
  3. 22
      src/ImageSharp.Drawing/Processing/LinearGradientBrush{TPixel}.cs
  4. 10
      src/ImageSharp.Drawing/Processing/RadialGradientBrush{TPixel}.cs
  5. 4
      tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs
  6. 2
      tests/Images/External

18
src/ImageSharp.Drawing/Processing/EllipticGradientBrush{TPixel}.cs

@ -18,9 +18,9 @@ namespace SixLabors.ImageSharp.Processing
public sealed class EllipticGradientBrush<TPixel> : GradientBrushBase<TPixel> public sealed class EllipticGradientBrush<TPixel> : GradientBrushBase<TPixel>
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
private readonly Point center; private readonly PointF center;
private readonly Point referenceAxisEnd; private readonly PointF referenceAxisEnd;
private readonly float axisRatio; private readonly float axisRatio;
@ -35,8 +35,8 @@ namespace SixLabors.ImageSharp.Processing
/// <param name="repetitionMode">Defines how the colors of the gradients are repeated.</param> /// <param name="repetitionMode">Defines how the colors of the gradients are repeated.</param>
/// <param name="colorStops">the color stops as defined in base class.</param> /// <param name="colorStops">the color stops as defined in base class.</param>
public EllipticGradientBrush( public EllipticGradientBrush(
Point center, PointF center,
Point referenceAxisEnd, PointF referenceAxisEnd,
float axisRatio, float axisRatio,
GradientRepetitionMode repetitionMode, GradientRepetitionMode repetitionMode,
params ColorStop<TPixel>[] colorStops) params ColorStop<TPixel>[] colorStops)
@ -64,9 +64,9 @@ namespace SixLabors.ImageSharp.Processing
/// <inheritdoc /> /// <inheritdoc />
private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase
{ {
private readonly Point center; private readonly PointF center;
private readonly Point referenceAxisEnd; private readonly PointF referenceAxisEnd;
private readonly float axisRatio; private readonly float axisRatio;
@ -99,8 +99,8 @@ namespace SixLabors.ImageSharp.Processing
public RadialGradientBrushApplicator( public RadialGradientBrushApplicator(
ImageFrame<TPixel> target, ImageFrame<TPixel> target,
GraphicsOptions options, GraphicsOptions options,
Point center, PointF center,
Point referenceAxisEnd, PointF referenceAxisEnd,
float axisRatio, float axisRatio,
ColorStop<TPixel>[] colorStops, ColorStop<TPixel>[] colorStops,
GradientRepetitionMode repetitionMode) GradientRepetitionMode repetitionMode)
@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Processing
} }
/// <inheritdoc /> /// <inheritdoc />
protected override float PositionOnGradient(int xt, int yt) protected override float PositionOnGradient(float xt, float yt)
{ {
float x0 = xt - this.center.X; float x0 = xt - this.center.X;
float y0 = yt - this.center.Y; float y0 = yt - this.center.Y;

12
src/ImageSharp.Drawing/Processing/GradientBrushBase{TPixel}.cs

@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Processing
{ {
get get
{ {
float positionOnCompleteGradient = this.PositionOnGradient(x, y); float positionOnCompleteGradient = this.PositionOnGradient(x + 0.5f, y + 0.5f);
switch (this.repetitionMode) switch (this.repetitionMode)
{ {
@ -137,18 +137,18 @@ namespace SixLabors.ImageSharp.Processing
} }
/// <summary> /// <summary>
/// calculates the position on the gradient for a given pixel. /// calculates the position on the gradient for a given point.
/// This method is abstract as it's content depends on the shape of the gradient. /// This method is abstract as it's content depends on the shape of the gradient.
/// </summary> /// </summary>
/// <param name="x">The x coordinate of the pixel</param> /// <param name="x">The x coordinate of the point</param>
/// <param name="y">The y coordinate of the pixel</param> /// <param name="y">The y coordinate of the point</param>
/// <returns> /// <returns>
/// The position the given pixel has on the gradient. /// The position the given point has on the gradient.
/// The position is not bound to the [0..1] interval. /// The position is not bound to the [0..1] interval.
/// Values outside of that interval may be treated differently, /// Values outside of that interval may be treated differently,
/// e.g. for the <see cref="GradientRepetitionMode" /> enum. /// e.g. for the <see cref="GradientRepetitionMode" /> enum.
/// </returns> /// </returns>
protected abstract float PositionOnGradient(int x, int y); protected abstract float PositionOnGradient(float x, float y);
private (ColorStop<TPixel> from, ColorStop<TPixel> to) GetGradientSegment( private (ColorStop<TPixel> from, ColorStop<TPixel> to) GetGradientSegment(
float positionOnCompleteGradient) float positionOnCompleteGradient)

22
src/ImageSharp.Drawing/Processing/LinearGradientBrush{TPixel}.cs

@ -17,9 +17,9 @@ namespace SixLabors.ImageSharp.Processing
public sealed class LinearGradientBrush<TPixel> : GradientBrushBase<TPixel> public sealed class LinearGradientBrush<TPixel> : GradientBrushBase<TPixel>
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
private readonly Point p1; private readonly PointF p1;
private readonly Point p2; private readonly PointF p2;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LinearGradientBrush{TPixel}"/> class. /// Initializes a new instance of the <see cref="LinearGradientBrush{TPixel}"/> class.
@ -29,8 +29,8 @@ namespace SixLabors.ImageSharp.Processing
/// <param name="repetitionMode">defines how colors are repeated.</param> /// <param name="repetitionMode">defines how colors are repeated.</param>
/// <param name="colorStops"><inheritdoc /></param> /// <param name="colorStops"><inheritdoc /></param>
public LinearGradientBrush( public LinearGradientBrush(
Point p1, PointF p1,
Point p2, PointF p2,
GradientRepetitionMode repetitionMode, GradientRepetitionMode repetitionMode,
params ColorStop<TPixel>[] colorStops) params ColorStop<TPixel>[] colorStops)
: base(repetitionMode, colorStops) : base(repetitionMode, colorStops)
@ -48,9 +48,9 @@ namespace SixLabors.ImageSharp.Processing
/// </summary> /// </summary>
private sealed class LinearGradientBrushApplicator : GradientBrushApplicatorBase private sealed class LinearGradientBrushApplicator : GradientBrushApplicatorBase
{ {
private readonly Point start; private readonly PointF start;
private readonly Point end; private readonly PointF end;
/// <summary> /// <summary>
/// the vector along the gradient, x component /// the vector along the gradient, x component
@ -93,8 +93,8 @@ namespace SixLabors.ImageSharp.Processing
/// <param name="options">the graphics options</param> /// <param name="options">the graphics options</param>
public LinearGradientBrushApplicator( public LinearGradientBrushApplicator(
ImageFrame<TPixel> source, ImageFrame<TPixel> source,
Point start, PointF start,
Point end, PointF end,
ColorStop<TPixel>[] colorStops, ColorStop<TPixel>[] colorStops,
GradientRepetitionMode repetitionMode, GradientRepetitionMode repetitionMode,
GraphicsOptions options) GraphicsOptions options)
@ -116,15 +116,15 @@ namespace SixLabors.ImageSharp.Processing
this.length = (float)Math.Sqrt(this.alongsSquared); this.length = (float)Math.Sqrt(this.alongsSquared);
} }
protected override float PositionOnGradient(int x, int y) protected override float PositionOnGradient(float x, float y)
{ {
if (this.acrossX == 0) if (this.acrossX == 0)
{ {
return (x - this.start.X) / (float)(this.end.X - this.start.X); return (x - this.start.X) / (this.end.X - this.start.X);
} }
else if (this.acrossY == 0) else if (this.acrossY == 0)
{ {
return (y - this.start.Y) / (float)(this.end.Y - this.start.Y); return (y - this.start.Y) / (this.end.Y - this.start.Y);
} }
else else
{ {

10
src/ImageSharp.Drawing/Processing/RadialGradientBrush{TPixel}.cs

@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Processing
public sealed class RadialGradientBrush<TPixel> : GradientBrushBase<TPixel> public sealed class RadialGradientBrush<TPixel> : GradientBrushBase<TPixel>
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
private readonly Point center; private readonly PointF center;
private readonly float radius; private readonly float radius;
@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Processing
/// <param name="repetitionMode">Defines how the colors in the gradient are repeated.</param> /// <param name="repetitionMode">Defines how the colors in the gradient are repeated.</param>
/// <param name="colorStops">the color stops as defined in base class.</param> /// <param name="colorStops">the color stops as defined in base class.</param>
public RadialGradientBrush( public RadialGradientBrush(
Point center, PointF center,
float radius, float radius,
GradientRepetitionMode repetitionMode, GradientRepetitionMode repetitionMode,
params ColorStop<TPixel>[] colorStops) params ColorStop<TPixel>[] colorStops)
@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Processing
/// <inheritdoc /> /// <inheritdoc />
private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase
{ {
private readonly Point center; private readonly PointF center;
private readonly float radius; private readonly float radius;
@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing
public RadialGradientBrushApplicator( public RadialGradientBrushApplicator(
ImageFrame<TPixel> target, ImageFrame<TPixel> target,
GraphicsOptions options, GraphicsOptions options,
Point center, PointF center,
float radius, float radius,
ColorStop<TPixel>[] colorStops, ColorStop<TPixel>[] colorStops,
GradientRepetitionMode repetitionMode) GradientRepetitionMode repetitionMode)
@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Processing
/// <param name="x">The X coordinate of the target pixel.</param> /// <param name="x">The X coordinate of the target pixel.</param>
/// <param name="y">The Y coordinate of the target pixel.</param> /// <param name="y">The Y coordinate of the target pixel.</param>
/// <returns>the position on the color gradient.</returns> /// <returns>the position on the color gradient.</returns>
protected override float PositionOnGradient(int x, int y) protected override float PositionOnGradient(float x, float y)
{ {
float distance = (float)Math.Sqrt(Math.Pow(this.center.X - x, 2) + Math.Pow(this.center.Y - y, 2)); float distance = (float)Math.Sqrt(Math.Pow(this.center.X - x, 2) + Math.Pow(this.center.Y - y, 2));
return distance / this.radius; return distance / this.radius;

4
tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs

@ -275,10 +275,6 @@ namespace SixLabors.ImageSharp.Tests.Drawing
int verticalSign = startY == 0 ? 1 : -1; int verticalSign = startY == 0 ? 1 : -1;
int horizontalSign = startX == 0 ? 1 : -1; int horizontalSign = startX == 0 ? 1 : -1;
// check first and last pixel, these are known:
Assert.Equal(red, image[startX, startY]);
Assert.Equal(yellow, image[endX, endY]);
for (int i = 0; i < image.Height; i++) for (int i = 0; i < image.Height; i++)
{ {
// it's diagonal, so for any (a, a) on the gradient line, for all (a-x, b+x) - +/- depending on the diagonal direction - must be the same color) // it's diagonal, so for any (a, a) on the gradient line, for all (a-x, b+x) - +/- depending on the diagonal direction - must be the same color)

2
tests/Images/External

@ -1 +1 @@
Subproject commit bc2765fb949d5d4ddba289b29174022bb94646de Subproject commit 94b5a8e11b33ba62c15d1d03f1b8b721468764f1
Loading…
Cancel
Save