Skip to content

Commit

Permalink
Skia - Only reverse radial gradient stops if we cover the whole conte…
Browse files Browse the repository at this point in the history
…nt bounds
  • Loading branch information
Gillibald committed Jan 15, 2025
1 parent 03f91a2 commit 9a94a62
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 16 deletions.
37 changes: 21 additions & 16 deletions src/Skia/Avalonia.Skia/DrawingContextImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -964,34 +964,39 @@ private static void ConfigureGradientBrush(ref PaintWrapper paintWrapper, Rect t
(originPoint.Y - centerPoint.Y) * radiusX / radiusY + centerPoint.Y);

var origin = originPoint.ToSKPoint();

// reverse the order of the stops to match D2D
var reversedColors = new SKColor[stopColors.Length];
Array.Copy(stopColors, reversedColors, stopColors.Length);
Array.Reverse(reversedColors);

var endOffset = 0.0;

// and then reverse the reference point of the stops
var reversedStops = new float[stopOffsets.Length];
for (var i = 0; i < stopOffsets.Length; i++)
{
reversedStops[i] = stopOffsets[i];
var offset = stopOffsets[i];

if (endOffset < offset)
{
endOffset = offset;
}

reversedStops[i] = offset;

if (reversedStops[i] > 0 && reversedStops[i] < 1)
{
reversedStops[i] = Math.Abs(1 - stopOffsets[i]);
reversedStops[i] = Math.Abs(1 - offset);
}
}

// compose with a background colour of the final stop to match D2D's behaviour of filling with the final color
using (var shader = SKShader.CreateCompose(
SKShader.CreateColor(reversedColors[0]),
transform.HasValue
? SKShader.CreateTwoPointConicalGradient(center, (float)radiusX, origin, 0,
reversedColors, reversedStops, tileMode, transform.Value.ToSKMatrix())
: SKShader.CreateTwoPointConicalGradient(center, (float)radiusX, origin, 0,
reversedColors, reversedStops, tileMode)

)
)
SKShader.CreateColor(stopColors[0]),
transform.HasValue
? SKShader.CreateTwoPointConicalGradient(start, radiusStart, end, radiusEnd,
stopColors, stopOffsets, tileMode, transform.Value.ToSKMatrix())
: SKShader.CreateTwoPointConicalGradient(start, radiusStart, end, radiusEnd,
stopColors, stopOffsets, tileMode)

)
)
{
paintWrapper.Paint.Shader = shader;
}
Expand Down
26 changes: 26 additions & 0 deletions tests/Avalonia.RenderTests/Media/RadialGradientBrushTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@ public RadialGradientBrushTests() : base(@"Media\RadialGradientBrush")
{
}

[Fact]
public async Task RadialGradientBrush_Partial_Cover()
{
Decorator target = new Decorator
{
Padding = new Thickness(8),
Width = 200,
Height = 200,
Child = new Border
{
Background = new RadialGradientBrush
{
GradientStops =
{
new GradientStop { Color = Colors.White, Offset = 0 },
new GradientStop { Color = Color.Parse("#00DD00"), Offset = 0.7 }
},
GradientOrigin = new RelativePoint(0.7, 0.15, RelativeUnit.Relative)
}
}
};

await RenderToFile(target);
CompareImages();
}

[Fact]
public async Task RadialGradientBrush_RedBlue()
{
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9a94a62

Please sign in to comment.