From 8bb8f3c79fed45ec03398b56bb4202a06b94745a Mon Sep 17 00:00:00 2001 From: "oliver.holliday@lontra.co.uk" Date: Wed, 7 Oct 2020 20:03:08 +0100 Subject: [PATCH] Add Skia support for Conic Gradients. Add a place holder implementation for Direct2D using SolidColorBrushImpl. --- .../Media/ConicGradientBrush.cs | 55 ++++++ .../Media/IConicGradientBrush.cs | 19 ++ .../Immutable/ImmutableConicGradientBrush.cs | 47 +++++ src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 17 ++ .../Media/DrawingContextImpl.cs | 6 + .../Media/SolidColorBrushImpl.cs | 17 ++ .../Media/ConicGradientBrushTests.cs | 178 ++++++++++++++++++ .../ConicGradientBrush_RedBlue.expected.png | Bin 0 -> 601 bytes ...cGradientBrush_RedBlue_Center.expected.png | Bin 0 -> 601 bytes ...h_RedBlue_Center_and_Rotation.expected.png | Bin 0 -> 601 bytes ...radientBrush_RedBlue_Rotation.expected.png | Bin 0 -> 601 bytes ...radientBrush_RedBlue_SoftEdge.expected.png | Bin 0 -> 601 bytes .../ConicGradientBrush_Umbrella.expected.png | Bin 0 -> 601 bytes .../ConicGradientBrush_RedBlue.expected.png | Bin 0 -> 7249 bytes ...cGradientBrush_RedBlue_Center.expected.png | Bin 0 -> 6797 bytes ...h_RedBlue_Center_and_Rotation.expected.png | Bin 0 -> 6792 bytes ...radientBrush_RedBlue_Rotation.expected.png | Bin 0 -> 7232 bytes ...radientBrush_RedBlue_SoftEdge.expected.png | Bin 0 -> 8805 bytes .../ConicGradientBrush_Umbrella.expected.png | Bin 0 -> 11408 bytes 19 files changed, 339 insertions(+) create mode 100644 src/Avalonia.Visuals/Media/ConicGradientBrush.cs create mode 100644 src/Avalonia.Visuals/Media/IConicGradientBrush.cs create mode 100644 src/Avalonia.Visuals/Media/Immutable/ImmutableConicGradientBrush.cs create mode 100644 tests/Avalonia.RenderTests/Media/ConicGradientBrushTests.cs create mode 100644 tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue.expected.png create mode 100644 tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center.expected.png create mode 100644 tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center_and_Rotation.expected.png create mode 100644 tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Rotation.expected.png create mode 100644 tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_SoftEdge.expected.png create mode 100644 tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_Umbrella.expected.png create mode 100644 tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue.expected.png create mode 100644 tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center.expected.png create mode 100644 tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center_and_Rotation.expected.png create mode 100644 tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Rotation.expected.png create mode 100644 tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_SoftEdge.expected.png create mode 100644 tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_Umbrella.expected.png diff --git a/src/Avalonia.Visuals/Media/ConicGradientBrush.cs b/src/Avalonia.Visuals/Media/ConicGradientBrush.cs new file mode 100644 index 0000000000..7c1266fa17 --- /dev/null +++ b/src/Avalonia.Visuals/Media/ConicGradientBrush.cs @@ -0,0 +1,55 @@ +using Avalonia.Media.Immutable; + +namespace Avalonia.Media +{ + /// + /// Paints an area with a swept circular gradient. + /// + public sealed class ConicGradientBrush : GradientBrush, IConicGradientBrush + { + /// + /// Defines the property. + /// + public static readonly StyledProperty CenterProperty = + AvaloniaProperty.Register( + nameof(Center), + RelativePoint.Center); + + /// + /// Defines the property. + /// + public static readonly StyledProperty AngleProperty = + AvaloniaProperty.Register( + nameof(Angle), + 0); + + static ConicGradientBrush() + { + AffectsRender(CenterProperty, AngleProperty); + } + + /// + /// Gets or sets the center point of the gradient. + /// + public RelativePoint Center + { + get { return GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + + /// + /// Gets or sets the angle of the start and end of the sweep, measured from above the center point. + /// + public double Angle + { + get { return GetValue(AngleProperty); } + set { SetValue(AngleProperty, value); } + } + + /// + public override IBrush ToImmutable() + { + return new ImmutableConicGradientBrush(this); + } + } +} diff --git a/src/Avalonia.Visuals/Media/IConicGradientBrush.cs b/src/Avalonia.Visuals/Media/IConicGradientBrush.cs new file mode 100644 index 0000000000..5368dd1851 --- /dev/null +++ b/src/Avalonia.Visuals/Media/IConicGradientBrush.cs @@ -0,0 +1,19 @@ +namespace Avalonia.Media +{ + /// + /// Paints an area with a conic gradient. + /// + public interface IConicGradientBrush : IGradientBrush + { + /// + /// Gets the center point for the gradient. + /// + RelativePoint Center { get; } + + /// + /// Gets the starting angle for the gradient in degrees, measured from + /// the point above the center point. + /// + double Angle { get; } + } +} diff --git a/src/Avalonia.Visuals/Media/Immutable/ImmutableConicGradientBrush.cs b/src/Avalonia.Visuals/Media/Immutable/ImmutableConicGradientBrush.cs new file mode 100644 index 0000000000..d3c80dfcad --- /dev/null +++ b/src/Avalonia.Visuals/Media/Immutable/ImmutableConicGradientBrush.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; + +namespace Avalonia.Media.Immutable +{ + /// + /// A brush that draws with a sweep gradient. + /// + public class ImmutableConicGradientBrush : ImmutableGradientBrush, IConicGradientBrush + { + /// + /// Initializes a new instance of the class. + /// + /// The gradient stops. + /// The opacity of the brush. + /// The spread method. + /// The center point for the gradient. + /// The starting angle for the gradient. + public ImmutableConicGradientBrush( + IReadOnlyList gradientStops, + double opacity = 1, + GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad, + RelativePoint? center = null, + double angle = 0) + : base(gradientStops, opacity, spreadMethod) + { + Center = center ?? RelativePoint.Center; + Angle = angle; + } + + /// + /// Initializes a new instance of the class. + /// + /// The brush from which this brush's properties should be copied. + public ImmutableConicGradientBrush(ConicGradientBrush source) + : base(source) + { + Center = source.Center; + Angle = source.Angle; + } + + /// + public RelativePoint Center { get; } + + /// + public double Angle { get; } + } +} diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 05a8daaec8..b8c81b3409 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -624,6 +624,23 @@ namespace Avalonia.Skia } } + break; + } + case IConicGradientBrush conicGradient: + { + var center = conicGradient.Center.ToPixels(targetSize).ToSKPoint(); + + // Skia's default is that angle 0 is from the right hand side of the center point + // but we are matching CSS where the vertical point above the center is 0. + var angle = (float)(conicGradient.Angle - 90); + var rotation = SKMatrix.CreateRotationDegrees(angle, center.X, center.Y); + + using (var shader = + SKShader.CreateSweepGradient(center, stopColors, stopOffsets, rotation)) + { + paintWrapper.Paint.Shader = shader; + } + break; } } diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index 258a51db5a..5d20bff1e9 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs @@ -424,6 +424,7 @@ namespace Avalonia.Direct2D1.Media var solidColorBrush = brush as ISolidColorBrush; var linearGradientBrush = brush as ILinearGradientBrush; var radialGradientBrush = brush as IRadialGradientBrush; + var conicGradientBrush = brush as IConicGradientBrush; var imageBrush = brush as IImageBrush; var visualBrush = brush as IVisualBrush; @@ -439,6 +440,11 @@ namespace Avalonia.Direct2D1.Media { return new RadialGradientBrushImpl(radialGradientBrush, _deviceContext, destinationSize); } + else if (conicGradientBrush != null) + { + // there is no Direct2D implementation of Conic Gradients so use Radial as a stand-in + return new SolidColorBrushImpl(conicGradientBrush, _deviceContext); + } else if (imageBrush?.Source != null) { return new ImageBrushImpl( diff --git a/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs index f93b4a2e08..fea1ca9157 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs @@ -16,5 +16,22 @@ namespace Avalonia.Direct2D1.Media } ); } + + /// + /// Direct2D has no ConicGradient implementation so fall back to a solid colour brush based on + /// the first gradient stop. + /// + public SolidColorBrushImpl(IConicGradientBrush brush, SharpDX.Direct2D1.DeviceContext target) + { + PlatformBrush = new SharpDX.Direct2D1.SolidColorBrush( + target, + brush?.GradientStops[0].Color.ToDirect2D() ?? new SharpDX.Mathematics.Interop.RawColor4(), + new SharpDX.Direct2D1.BrushProperties + { + Opacity = brush != null ? (float)brush.Opacity : 1.0f, + Transform = target.Transform + } + ); + } } } diff --git a/tests/Avalonia.RenderTests/Media/ConicGradientBrushTests.cs b/tests/Avalonia.RenderTests/Media/ConicGradientBrushTests.cs new file mode 100644 index 0000000000..db69a0a028 --- /dev/null +++ b/tests/Avalonia.RenderTests/Media/ConicGradientBrushTests.cs @@ -0,0 +1,178 @@ +using Avalonia.Controls; +using Avalonia.Media; +using System.Threading.Tasks; +using Xunit; + +#if AVALONIA_SKIA +namespace Avalonia.Skia.RenderTests +#else +namespace Avalonia.Direct2D1.RenderTests.Media +#endif +{ + public class ConicGradientBrushTests : TestBase + { + public ConicGradientBrushTests() : base(@"Media\ConicGradientBrush") + { + } + + [Fact] + public async Task ConicGradientBrush_RedBlue() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 200, + Height = 200, + Child = new Border + { + Background = new ConicGradientBrush + { + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Blue, Offset = 1 } + } + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + + [Fact] + public async Task ConicGradientBrush_RedBlue_Rotation() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 200, + Height = 200, + Child = new Border + { + Background = new ConicGradientBrush + { + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Blue, Offset = 1 } + }, + Angle = 90 + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + + [Fact] + public async Task ConicGradientBrush_RedBlue_Center() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 200, + Height = 200, + Child = new Border + { + Background = new ConicGradientBrush + { + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Blue, Offset = 1 } + }, + Center = new RelativePoint(0.25, 0.25, RelativeUnit.Relative) + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + + [Fact] + public async Task ConicGradientBrush_RedBlue_Center_and_Rotation() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 200, + Height = 200, + Child = new Border + { + Background = new ConicGradientBrush + { + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Blue, Offset = 1 } + }, + Center = new RelativePoint(0.25, 0.25, RelativeUnit.Relative), + Angle = 90 + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + + [Fact] + public async Task ConicGradientBrush_RedBlue_SoftEdge() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 200, + Height = 200, + Child = new Border + { + Background = new ConicGradientBrush + { + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Blue, Offset = 0.5 }, + new GradientStop { Color = Colors.Red, Offset = 1 }, + } + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + + [Fact] + public async Task ConicGradientBrush_Umbrella() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 200, + Height = 200, + Child = new Border + { + Background = new ConicGradientBrush + { + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Yellow, Offset = 0.1667 }, + new GradientStop { Color = Colors.Lime, Offset = 0.3333 }, + new GradientStop { Color = Colors.Aqua, Offset = 0.5000 }, + new GradientStop { Color = Colors.Blue, Offset = 0.6667 }, + new GradientStop { Color = Colors.Magenta, Offset = 0.8333 }, + new GradientStop { Color = Colors.Red, Offset = 1 }, + } + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + } +} diff --git a/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue.expected.png b/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8e08d02f66d15179e5fd004f39bb13cbd4fe274f GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggiP_V|F{C2y?d5}<4F(J>2Q&WLuJ)K$$lYNq6T@l^)Bpr#rDy(^>}|HS vWlUjyUX$RcAi%;jN(}Wd07osue&b`j+h#Kt7)_eY2omvh^>bP0l+XkKIR;Xb literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center.expected.png b/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8e08d02f66d15179e5fd004f39bb13cbd4fe274f GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggiP_V|F{C2y?d5}<4F(J>2Q&WLuJ)K$$lYNq6T@l^)Bpr#rDy(^>}|HS vWlUjyUX$RcAi%;jN(}Wd07osue&b`j+h#Kt7)_eY2omvh^>bP0l+XkKIR;Xb literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center_and_Rotation.expected.png b/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center_and_Rotation.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8e08d02f66d15179e5fd004f39bb13cbd4fe274f GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggiP_V|F{C2y?d5}<4F(J>2Q&WLuJ)K$$lYNq6T@l^)Bpr#rDy(^>}|HS vWlUjyUX$RcAi%;jN(}Wd07osue&b`j+h#Kt7)_eY2omvh^>bP0l+XkKIR;Xb literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Rotation.expected.png b/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Rotation.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8e08d02f66d15179e5fd004f39bb13cbd4fe274f GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggiP_V|F{C2y?d5}<4F(J>2Q&WLuJ)K$$lYNq6T@l^)Bpr#rDy(^>}|HS vWlUjyUX$RcAi%;jN(}Wd07osue&b`j+h#Kt7)_eY2omvh^>bP0l+XkKIR;Xb literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_SoftEdge.expected.png b/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_SoftEdge.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8e08d02f66d15179e5fd004f39bb13cbd4fe274f GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggiP_V|F{C2y?d5}<4F(J>2Q&WLuJ)K$$lYNq6T@l^)Bpr#rDy(^>}|HS vWlUjyUX$RcAi%;jN(}Wd07osue&b`j+h#Kt7)_eY2omvh^>bP0l+XkKIR;Xb literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_Umbrella.expected.png b/tests/TestFiles/Direct2D1/Media/ConicGradientBrush/ConicGradientBrush_Umbrella.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8e08d02f66d15179e5fd004f39bb13cbd4fe274f GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggiP_V|F{C2y?d5}<4F(J>2Q&WLuJ)K$$lYNq6T@l^)Bpr#rDy(^>}|HS vWlUjyUX$RcAi%;jN(}Wd07osue&b`j+h#Kt7)_eY2omvh^>bP0l+XkKIR;Xb literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue.expected.png b/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..563bbfcc611681e14d54f391c617f12e3ed7e7e1 GIT binary patch literal 7249 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 literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center_and_Rotation.expected.png b/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Center_and_Rotation.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..a8719e2e704e51f328ef90998babfdfc4cc5845b GIT binary patch literal 6792 zcmZ`;XH-*Lx3vHU6b%s&Lrn-sQ!c#)xWR;wP?VAo`X`|mkt!hNil`830(g<8h9D4{ zASg)tq$45_ItVDe2?C+FmwVsOH{KcJoPBsdl5&0!5}{(2Y-0P6|^IK`Yf1J=bL5f;H&zwB)MglhbZO{c$ZhwZrz z`R>kUtJi_#mrIEaLJAE^LZ&D05Kjujvck?heY=eOgR8^nb?=0FxS}a9DqyB9K~U}f z_iEq&^Rl6^(Rp!C?V!hJ>O@}7ue&m@!R7rbSs>tkk$lxnLBDOUj49G?n0=jd*NAL` zK|J5C1G8+N%^|r{w@>Xr|J4s!Q6+x$j|=I2^YX}w4V94Jj`PM|2{XQA<8kB5PQpB* zjA5_rom-L0-=YkYWi)__2ALDkGuXt(a%9+Mu_Wj6?QtFl*xUZK{ZB+_c?lP^^_yy8 z_qF9hj)NxkUNyB(_vRJqZni=#d*1Gs>=`wB6deF{!6~s4=Q#CdQ;?*W-uOq%yla1~ zzP#41p!&z=8-q-=IEO=KYj*B5XL2Rw1q9E3)_lpAw-7vorUGc%xjBv@;D<(>1Y z-HDs6azt%ZyoQ7$Augx0xzAWKK`x`)!=X^@WyBzU8}iQwLHaAwLj;3aCf2$R$q@~g zwLnAT1{<*ms1D6%RLSFUn5vz^O9Hpyo$@xQw&MdmCkMjp-owc~Mv@B0l4}PKq~$() z=ZLoGG@1zY<&nbyQw4G~0~#L0oiWSG69aMTzZ$npfla3z@MJpghQ){`#I`ukjK88K zq1+17EMgvQqhNCkz*A6j6pFtry9PgQpzGK*QhU@_?FC04rZ5*b?(d)i28AhRZn_Nh z!YSiKJ}$E=TzHHw`0s>|Ks?aXR0^XXnIrm`*+k|oHZ+B^|Jv;F(c2a{@e0 ze4G@r5UZ6Kq7+wUQV;d1LkU=*s=2*wEPI}PAV;*gjQ)#Wu{=!yd6C2nL8Og6xowuU zEGX|C=G4G9+d+X%$Biil4J5T8r|CqP+o4o&WA!V$C&)fCDs&*l+#mP~tE%57AI$~ZBXOLWTt#Srg z_N;0xwarbSxyRXC>-f5h4^ zrR6l#o`#_?eVAwfLRoOvU(knTPHP!Wl-Zb=k@df|kGtwAQqn^V$-Ig@+!)IDUgKjc zFJ-afsoJ%+4^>FpTdp45%FB83J4nri@49!A82>yse0SlMWoYQbdWsk;lW&KS(+zBg zs|WqvS%e7xX-0bqd$l;OMKzfHVR>_oZ1CpTEkfs2knR$Rm5M`&2f4n33bG5GR12D` z7@0WI_Et!M7DIV*ULtlVf^F^{%gw8QC#;J!hMuHGeRU$oC=K7-!ewOU>)v4=BuXi1 z^&IwrMg-MZ{a7 zo<-W$ha$~m3!=XIXTJvLT-iX+d}?1ymya8G(j)_;x=pS6XQ5M*hGipy4_AhDh>GDt3cp=|}{TK`{LvfsqSro=7&n5Flr~F6q+$jQ}*rPGV z81xVi?|!!T4|h2Ktbj7-d;-7KysBmLW5gNv6inf_FkX0jPo_PT{YH#FB}8ZP#gI$Y zzoouFS8!ZohxQ10_rw{+mSN@wBdadlIM`W>_AGWig7>XxvHuhdk!-R&5Q28Vue`GP zw5iG}={&mNevLJH$ip{wh)Q0pIJ+JwR_MI{S250AjMER;DCRONYjas}Cbn?zLT}D3 zh)ueu>QfXJs-ZBlM?&ABk;7EBANQ0I;N;1G$d>lJ%GP$zNFG0#6;e1OT%2I`#7%k- z{)#5j{B4|g{!#0m<-t*D@^Fm8)fOn);$|tHR9b#xV#Xu-%%08n(ifH$g!{?Gq>sZ7JPOro?dVHHumu%IWrnPz?uZwdO8*7Xa zmA3L%h~F$jsf~+WRuN(V)n6mY~TY?IE>0dN8A6%Ucv)x=r zzMOu=LQMi5V*JX7l!8Od-xIMC;fuqYcXu9`ztT-%D7N_WLs8|!GG0KP?w^4 zO;wf*TIuWUm}O)te14lzQ1dI#!halF!m3*{E?;3UiL}V3IGM5ZVZ*B8-GE5|SVPXy zVgQy4U3B@5pmx;Lca4wjie(VJ2~y-{C}-nG)fKV!k?7o>)9l!2jX~?D_f^OZ%9V#6 z9dGZytf6iNPW~+(_%&0)KwrDs&uy71-EqbeWD>8zCk|EVp3dwuOOPFeVZk@Qk=DV2 z*=348yh{sW1=ens4L@OyZpiW+tFOPem+GlvT#7w6!~`CIy_r0&-T5L~cO< zdLTm#kn)u#U>PR_&yjlJ@+Muaen|g-;hF9I{aZN2ffU;kLQM8ugukp&1YBFPa*UVN z1Loi%9>jZ+XV(2I2w%!CUYF=B0O)btNz1FUS%fC4SO)2E{sgx`JKQ{5(#K;+P7!jy z7t1$bRZIU(cR1WxzY9td7_2N3pVL$I+;v&UPGDL4eufi(@kZc0AWuIlpj!_b?Sk(7 ztX7u?Eyz9uHuC1SI?s?d`ZRhqG|W_D(DA;5UO4ujGgN{x@Cx{GWqLeG%xNR+ds!=T zx-vMxc2`J5PX&Oz6j1_f$xP|Fch96mKho<%NPmfB$6xwUQX2R?+wACaR)-Mc?=%lN z$H$7R2qIXQF2firR(pK4*(^a00dxMrR_R!`Q>R*{JFXbCmU844&%e@Y*$&wXb}K}{ zqrR#}1HQXX#C?#TU6n1Q_>rMUR4Lk=du@hzH#igbzI#Vb0}c(4 zF-Vhxw~^x7g5uxzW;jBSKm9|#d?r=}zD_n!92@h@Y4;0eOCRT#F7~y5WN(8r>;$tLBBGE`~KO{KCMTiri+nh#%xT%y>!&ywc{Em~~+p9%2b`liXg ztVaAsYc7%ID`IwqOKCQJ;ft4_F^=|u!@D^lB0zgfJqfmm1B-XNPh=kMc_MM_RjxzSjIwzXs{XOeXEa4NnwK<#)A-UXMrCiy_Re*nsD~Tuf z?!5k^2ugnHxk1)|N~e9`5J~cK5fPMlj(&!v&yC8}F5Eu)*JFGe(A%UOj*2NTn0<x=wUr-{PW$lms!q zc-z~6tolO3nPKPh%sap(I#W&s-5JeWAzS(joh=@J z0Vt5?`C?<*b%Dsv6hy##f_K-mHiEC2&6fKyy&D?M<}*VT)G~Ylxc3^GEtO;Mn>jEP zQ-S4H4))3Uc+cc+GAYBtJLVWxL0Fj^DHWq+7(^3{d1tv%svWUhjwRbN)Zm7g#!NYW zmNeCAM5SJ?Ku-Oq>lsjjE;bhIbE`9g%M@S01#X^EjCK#dJUvQN#q#znoDK0WzGAWB zDX5eywixUkU!}Sp=vF3*EA+ztsO#KMu zQuk?`@P=s)z!1_{M$5%@5{aYQdk#=J%o+&T6C7B z0+U-jEm@+iZEc^W>y_FeQcE=baxMi}$m&>@$HTFFX0MA=~Yp=H@-F9cGB9qUX#&e9f zP@RK=`iC8dj1nQ!sa13*=<^F`eI_iM7V9PC*&Oo03;VS6toJ`Y*QVaqvkY~HP-VK} z0(73wf1DQgto*Ca*IE?wP}$}gtmBBh!=+L~lH!R}tpWpN4U{LvIp{*N7O)JgmG}Mk zs@k9=${!UC_f^Wh@`3CLeLy-QW;qbBYvt`}q*j-Z)FK`oSMW3_N$MVb`SW2>YVH%M z33`QgD}6|uk#+sG4~Q;6@kV>3LG+&~{IcC_h=b!#wTV zfQ;THckZ!jEJ+4yP#o>j{6c;Y zAV>)X258dL;*Ynriyv8<%XJPFf@RH$9`9UunzkR5EU_sGncBe}0i=gYnI7z>W1_sJ zMl}^qg%m0U>uf>H3w1J+DH5$h^_P;aU>e~x5ngG)-L5FP zo8aZ4aweZZ@qS8LrDJ5KqQ5_k3U!*!g^lJ(cC3)%Zy$jfk=KeY_6-z)EI$`6-y2OX zFi<%`$TK@e=}Tzj3J3g`67xlIoH5|NxnIzPFAzdz01eMcB6ExZ*(9Nt*F#LRry zs;#sP87+lkB<7ZlYVi@z@`#f$GRTD?N7;@BatxP6yYuFL5r*1oG0^h<;UPRVDTJKP zMGnfhA*(4;^h1bMD#0W_c8tsy$ml1=t(I#N*!{AMtYEfPNX6sYwLp|LA0+nL_?uf} zw${b2Wi-3R1wqaEUlvI?I)nR;grZCo{kfA33MBo(&< z({1(e_hlSFY@Y<=Sqb-`HIpGxsuz~G);3K0WjjCIHZJxR z$^*B&hv@M3T}T|$-z~kqTB?=&XcdZ4br}gN!05YkSc~w6s;)gst^CrA3q+%_&Ls=8 zU>e2Rxp(vRA2vyFuxSPM-u|bRMA1TyzSYr6!=_EBwqB|^=T&1L;8f`+Vj#C;Np17| zsAUmm{E43Y+JJ+8<-0h6KI`+JOPN^1yt+fehtdK1ZDTW3Xp2K^BT32<*qpi0$0(9D zljTm6&$b{(eCfoimBRF0`qAw+)ho1a4a!JycI#LodRH1d6I>Z zesL{SB7LK%7t)_(k&YgU`DR%an1>%dcv3)k0<=r<%hsb_e|bgB+}vV*$*8_UfyX9) zV#}QnN(z*z@NpdGSj3Y%>NVqbyyBh5$$qF9Mg(bYUo_j+G$8p6NOarIm}0bwRdLs7 zWjJa*I2TfSt4&Gej;m%M2oscVI|q(l)Rb6)-O1zV_-ZNLcIR&5eM)hu;S0W{jL=m) zMfO3J-|IywM(%E3n=6LF<2kDR>KQ-#bwVL5Nw2y;HTS&%y6yE=v1I2C^jKU9GnaXU zocnXVs@4EK48)Wak95T`r9`roUnWev5$fAZx*HkL;_UaJA8rR1ckmrJeV6Ta-lPi*;m;ec1PUX=&DmaQ5q zgbFWOBn-j|ha~27g)Cb+1;h2*=a-H0D??-(`pt^cV4aEA4NjN(WErKR?7EH~gDA>c zN^!24+?CqcDkYp1**dT+vdROAVOag`CZ&5Jgw2+$nw@MNQhtN3Km2wbirLrbNW$k9 zw}{j5g9-N6$K8Eo8RFHRsp>kLg*eH!xQX!ZnI~5QMEHu-uKG<4(yHlVXh#u9Nk-qM z!#iymeDd5t?)PO)6V2scm5)Yt zR??3FLB3ED~d0erEKO#=E(uQatsDo?K#YuAm);?B2r!rVjdj?{b> zO;b;@O?I81LePpX22kTp-I_VK@DC)Up}W-=ncew>MVI3krzJ_$ux60ZN+=OO5;Sr% zRg~A>_=PY5L&6mfa1HJO*h87`zaO+0<@(kxWcYGPL${E_buxqW;?JMj`Cv6im;=n0 zip>sXt%nOsy)q2TL5SbfM9*#P6|RTbUfJ=N&9Z6Wjg=)`mRIIu(kUO-CG`_>G^hfWlgT> zW42>BQl--oeKw-WKk;fmeGpc|oT8lqkk+WE#7b%ZQ<7emUj<*y`sOJ|=)%+nYDSZh zCl^G2rZ)9uK_s7s!%=K^+KWVmi%i}?cj0y@6Vv#Awx~!Dv(%;mZRuOL8KLEoH0Y#0 kSGoEB9`5+g@E%>U{w;M@7mV6r9W9-~piGdZdjE;~AEw3!%K!iX literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Rotation.expected.png b/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_Rotation.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..1c79db413bb90fee0331107c23578aae6089c841 GIT binary patch literal 7232 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 literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_SoftEdge.expected.png b/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_RedBlue_SoftEdge.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf8eddd81ad5984cd8124fecc2bc2ccbea94fad GIT binary patch literal 8805 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 ROvxLe(uF>R)ZDiZ`+qS-*r5Ob literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_Umbrella.expected.png b/tests/TestFiles/Skia/Media/ConicGradientBrush/ConicGradientBrush_Umbrella.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..98dfda782dcd436656c74249ec05013b7b6c3608 GIT binary patch literal 11408 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