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.Linq;
using Avalonia.Collections;
using Avalonia.Media.Immutable;
@ -17,7 +16,17 @@ namespace Avalonia.Media
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>
/// Describes the location and color of a transition point in a gradient.
@ -7,7 +9,12 @@
{
public ImmutableGradientStop(double offset, Color color)
{
Offset = offset;
if (MathUtilities.IsZero(offset))
{
offset = 0;
}
Offset = (offset < 0) ? 0 : (offset > 1) ? 1 : offset;
Color = color;
}

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

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

Loading…
Cancel
Save