From ab93de0d51cb5802bc94780c89243ed00e698a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=C4=9Bzslav=20Imr=C3=BD=C5=A1ek?= Date: Fri, 30 Jul 2021 14:14:13 +0200 Subject: [PATCH] feat: Added CompositionLinearGradientBrush implementation --- src/Uno.UI/UI/Xaml/Shapes/Shape.skia.cs | 20 +++----- .../CompositionLinearGradientBrush.cs | 6 +-- .../CompositionLinearGradientBrush.cs | 30 +++++++++++ .../CompositionLinearGradientBrush.skia.cs | 50 +++++++++++++++++++ 4 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.cs create mode 100644 src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.skia.cs diff --git a/src/Uno.UI/UI/Xaml/Shapes/Shape.skia.cs b/src/Uno.UI/UI/Xaml/Shapes/Shape.skia.cs index 605af13fab24..ad54b78cec30 100644 --- a/src/Uno.UI/UI/Xaml/Shapes/Shape.skia.cs +++ b/src/Uno.UI/UI/Xaml/Shapes/Shape.skia.cs @@ -13,7 +13,6 @@ using Uno.Disposables; using System.IO.Compression; using SkiaSharp; -using Windows.Devices.Usb; using System.Numerics; namespace Windows.UI.Xaml.Shapes @@ -81,15 +80,8 @@ private void UpdateFill() _pathSpriteShape.FillBrush = null; - switch(Fill) - { - case SolidColorBrush scb: - _fillSubscription.Disposable = - Brush.AssignAndObserveBrush(scb, c => _pathSpriteShape.FillBrush = Visual.Compositor.CreateColorBrush(c)); - break; - case GradientBrush gb: - break; - } + _fillSubscription.Disposable = + Brush.AssignAndObserveBrush(Fill, Visual.Compositor, compositionBrush => _pathSpriteShape.FillBrush = compositionBrush); } } @@ -103,12 +95,14 @@ private void UpdateStrokeThickness() private void UpdateStroke() { - var brush = Stroke as SolidColorBrush ?? SolidColorBrushHelper.Transparent; - if (_pathSpriteShape != null) { + _strokeSubscription.Disposable = null; + + _pathSpriteShape.StrokeBrush = null; + _strokeSubscription.Disposable = - Brush.AssignAndObserveBrush(brush, c => _pathSpriteShape.StrokeBrush = Visual.Compositor.CreateColorBrush(c)); + Brush.AssignAndObserveBrush(Stroke, Visual.Compositor, compositionBrush => _pathSpriteShape.StrokeBrush = compositionBrush); } } } diff --git a/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionLinearGradientBrush.cs b/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionLinearGradientBrush.cs index 56c40245f00d..5a81f04c9d42 100644 --- a/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionLinearGradientBrush.cs +++ b/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionLinearGradientBrush.cs @@ -2,12 +2,12 @@ #pragma warning disable 114 // new keyword hiding namespace Windows.UI.Composition { - #if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ + #if false [global::Uno.NotImplemented] #endif public partial class CompositionLinearGradientBrush : global::Windows.UI.Composition.CompositionGradientBrush { - #if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ + #if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public global::System.Numerics.Vector2 StartPoint { @@ -21,7 +21,7 @@ public partial class CompositionLinearGradientBrush : global::Windows.UI.Compos } } #endif - #if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ + #if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public global::System.Numerics.Vector2 EndPoint { diff --git a/src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.cs b/src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.cs new file mode 100644 index 000000000000..ea1cd57b0800 --- /dev/null +++ b/src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.cs @@ -0,0 +1,30 @@ +#nullable enable + +using System.Numerics; + +namespace Windows.UI.Composition +{ + public partial class CompositionLinearGradientBrush : CompositionGradientBrush + { + private Vector2 _startPoint = Vector2.Zero; + private Vector2 _endPoint = new Vector2(1, 0); + + internal CompositionLinearGradientBrush(Compositor compositor) + : base(compositor) + { + + } + + public Vector2 StartPoint + { + get => _startPoint; + set => SetProperty(ref _startPoint, value); + } + + public Vector2 EndPoint + { + get => _endPoint; + set => SetProperty(ref _endPoint, value); + } + } +} diff --git a/src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.skia.cs b/src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.skia.cs new file mode 100644 index 000000000000..fc91520a14dd --- /dev/null +++ b/src/Uno.UWP/UI/Composition/CompositionLinearGradientBrush.skia.cs @@ -0,0 +1,50 @@ +#nullable enable + +using SkiaSharp; + +namespace Windows.UI.Composition +{ + public partial class CompositionLinearGradientBrush + { + private protected override void UpdatePaintCore(SKPaint paint, SKRect bounds) + { + var startPoint = StartPoint.ToSKPoint(); + var endPoint = EndPoint.ToSKPoint(); + var transform = CreateTransformMatrix(bounds); + + // Transform the points into absolute coordinates. + if (MappingMode == CompositionMappingMode.Relative) + { + // If mapping is relative to bounding box, multiply points by bounds. + startPoint.X *= (float)bounds.Width; + startPoint.Y *= (float)bounds.Height; + + endPoint.X *= (float)bounds.Width; + endPoint.Y *= (float)bounds.Height; + } + + // Translate gradient points by bounds offset. + startPoint.X += bounds.Left; + startPoint.Y += bounds.Top; + + endPoint.X += bounds.Left; + endPoint.Y += bounds.Top; + // + + // Create linear gradient shader. + var shader = SKShader.CreateLinearGradient( + startPoint, endPoint, + Colors, ColorPositions, + TileMode, transform); + + // Clean up old shader + if (paint.Shader != null) + { + paint.Shader.Dispose(); + paint.Shader = null; + } + + paint.Shader = shader; + } + } +}