Skip to content

Commit 1884fd5

Browse files
PoyoJimBobSquarePants
authored andcommitted
Fix incorrect gradient color-stop calculation (SixLabors#864)
* Fix incorrect gradient color-stop calculation * Update submodule * Add multi-stop gradient test * Add missing reference image
1 parent acb5766 commit 1884fd5

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ protected GradientBrushApplicatorBase(
121121
{
122122
var fromAsVector = from.Color.ToVector4();
123123
var toAsVector = to.Color.ToVector4();
124-
float onLocalGradient = (positionOnCompleteGradient - from.Ratio) / to.Ratio;
124+
float onLocalGradient = (positionOnCompleteGradient - from.Ratio) / (to.Ratio - from.Ratio);
125125

126126
// TODO: this should be changeble for different gradienting functions
127127
Vector4 result = PorterDuffFunctions.NormalSrcOver(

tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,5 +350,52 @@ public void ArbitraryGradients<TPixel>(
350350
false,
351351
false);
352352
}
353+
354+
[Theory]
355+
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0, 0, 199, 199, new[] { 0f, .25f, .5f, .75f, 1f }, new[] { 0, 1, 2, 3, 4 })]
356+
public void MultiplePointGradients<TPixel>(
357+
TestImageProvider<TPixel> provider,
358+
int startX, int startY,
359+
int endX, int endY,
360+
float[] stopPositions,
361+
int[] stopColorCodes)
362+
where TPixel : struct, IPixel<TPixel>
363+
{
364+
TPixel[] colors =
365+
{
366+
NamedColors<TPixel>.Black, NamedColors<TPixel>.Blue, NamedColors<TPixel>.Red,
367+
NamedColors<TPixel>.White, NamedColors<TPixel>.Lime
368+
};
369+
370+
var coloringVariant = new StringBuilder();
371+
var colorStops = new ColorStop<TPixel>[stopPositions.Length];
372+
373+
for (int i = 0; i < stopPositions.Length; i++)
374+
{
375+
TPixel color = colors[stopColorCodes[i % colors.Length]];
376+
float position = stopPositions[i];
377+
colorStops[i] = new ColorStop<TPixel>(position, color);
378+
Rgba32 rgba = default;
379+
color.ToRgba32(ref rgba);
380+
coloringVariant.AppendFormat(CultureInfo.InvariantCulture, "{0}@{1};", rgba.ToHex(), position);
381+
}
382+
383+
FormattableString variant = $"({startX},{startY})_TO_({endX},{endY})__[{coloringVariant}]";
384+
385+
provider.VerifyOperation(
386+
image =>
387+
{
388+
var unicolorLinearGradientBrush = new LinearGradientBrush<TPixel>(
389+
new SixLabors.Primitives.Point(startX, startY),
390+
new SixLabors.Primitives.Point(endX, endY),
391+
GradientRepetitionMode.None,
392+
colorStops);
393+
394+
image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
395+
},
396+
variant,
397+
false,
398+
false);
399+
}
353400
}
354401
}

0 commit comments

Comments
 (0)