Browse Source

Fix gradient stop reordeing (#18907) (#18933)

pull/18940/head
Benedikt Stebner 1 year ago
committed by GitHub
parent
commit
f4fd2eb8fd
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 13
      src/Avalonia.Base/Media/GradientStops.cs
  2. 11
      src/Avalonia.Base/Media/Immutable/ImmutableGradientStop.cs
  3. 46
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs

13
src/Avalonia.Base/Media/GradientStops.cs

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Media.Immutable; using Avalonia.Media.Immutable;
@ -17,7 +16,17 @@ namespace Avalonia.Media
public IReadOnlyList<ImmutableGradientStop> ToImmutable() public IReadOnlyList<ImmutableGradientStop> ToImmutable()
{ {
return this.Select(x => new ImmutableGradientStop(x.Offset, x.Color)).ToArray(); var count = Count;
var stops = new ImmutableGradientStop[count];
for (var i = 0; i < count; i++)
{
var currentStop = this[i];
stops[i] = new ImmutableGradientStop(currentStop.Offset, currentStop.Color);
}
return stops;
} }
} }
} }

11
src/Avalonia.Base/Media/Immutable/ImmutableGradientStop.cs

@ -1,4 +1,6 @@
namespace Avalonia.Media.Immutable using Avalonia.Utilities;
namespace Avalonia.Media.Immutable
{ {
/// <summary> /// <summary>
/// Describes the location and color of a transition point in a gradient. /// Describes the location and color of a transition point in a gradient.
@ -7,7 +9,12 @@
{ {
public ImmutableGradientStop(double offset, Color color) public ImmutableGradientStop(double offset, Color color)
{ {
Offset = offset; if (MathUtilities.IsZero(offset))
{
offset = 0;
}
Offset = (offset < 0) ? 0 : (offset > 1) ? 1 : offset;
Color = color; Color = color;
} }

46
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -963,39 +963,43 @@ namespace Avalonia.Skia
(originPoint.Y - centerPoint.Y) * radiusX / radiusY + centerPoint.Y); (originPoint.Y - centerPoint.Y) * radiusX / radiusY + centerPoint.Y);
var origin = originPoint.ToSKPoint(); var origin = originPoint.ToSKPoint();
var endOffset = 0.0;
// and then reverse the reference point of the stops var endOffset = stopOffsets[stopOffsets.Length - 1];
var reversedStops = new float[stopOffsets.Length];
for (var i = 0; i < stopOffsets.Length; 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 - offset);
}
}
var start = origin; var start = origin;
var radiusStart = 0f; var radiusStart = 0f;
var end = center; var end = center;
var radiusEnd = (float)radiusX; var radiusEnd = (float)radiusX;
var reverse = MathUtilities.AreClose(1, endOffset); var reverse = (centerPoint.X != originPoint.X || centerPoint.Y != originPoint.Y) && endOffset == 1;
if (reverse) if (reverse)
{ {
// reverse the order of the stops to match D2D
(start, radiusStart, end, radiusEnd) = (end, radiusEnd, start, radiusStart); (start, radiusStart, end, radiusEnd) = (end, radiusEnd, start, radiusStart);
// reverse the order of the stops to match D2D var count = stopOffsets.Length;
var reversedColors = new SKColor[stopColors.Length]; var reversedColors = new SKColor[stopColors.Length];
Array.Copy(stopColors, reversedColors, stopColors.Length); // and then reverse the reference point of the stops
Array.Reverse(reversedColors); var reversedStops = new float[count];
for (var i = 0; i < count; i++)
{
var offset = radialGradient.GradientStops[i].Offset;
offset = 1 - offset;
if (MathUtilities.IsZero(offset))
{
offset = 0;
}
var reversedIndex = count - 1 - i;
reversedStops[reversedIndex] = (float)offset;
reversedColors[reversedIndex] = stopColors[i];
}
stopColors = reversedColors; stopColors = reversedColors;
stopOffsets = reversedStops; stopOffsets = reversedStops;
} }

Loading…
Cancel
Save