From 252bc9473e4621905ce3a5938c5268b81b434f6f Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 6 Feb 2017 00:00:15 +0100 Subject: [PATCH] Make LinearGradientBrush work again. With deferred renderer. --- src/Avalonia.Visuals/Avalonia.Visuals.csproj | 4 ++ src/Avalonia.Visuals/Media/GradientBrush.cs | 6 ++- src/Avalonia.Visuals/Media/IGradientBrush.cs | 21 ++++++++ .../Media/ILinearGradientBrush.cs | 18 +++++++ .../Media/Immutable/ImmutableGradientBrush.cs | 47 +++++++++++++++++ .../Immutable/ImmutableLinearGradientBrush.cs | 51 +++++++++++++++++++ .../Media/LinearGradientBrush.cs | 10 +++- .../Media/DrawingContextImpl.cs | 2 +- .../Media/LinearGradientBrushImpl.cs | 2 +- ...ia.Direct2D1.RenderTests.v3.ncrunchproject | 41 --------------- 10 files changed, 157 insertions(+), 45 deletions(-) create mode 100644 src/Avalonia.Visuals/Media/IGradientBrush.cs create mode 100644 src/Avalonia.Visuals/Media/ILinearGradientBrush.cs create mode 100644 src/Avalonia.Visuals/Media/Immutable/ImmutableGradientBrush.cs create mode 100644 src/Avalonia.Visuals/Media/Immutable/ImmutableLinearGradientBrush.cs diff --git a/src/Avalonia.Visuals/Avalonia.Visuals.csproj b/src/Avalonia.Visuals/Avalonia.Visuals.csproj index 3286baeb9c..a167cbe753 100644 --- a/src/Avalonia.Visuals/Avalonia.Visuals.csproj +++ b/src/Avalonia.Visuals/Avalonia.Visuals.csproj @@ -69,7 +69,11 @@ + + + + diff --git a/src/Avalonia.Visuals/Media/GradientBrush.cs b/src/Avalonia.Visuals/Media/GradientBrush.cs index 4c62a2b836..9059df73d7 100644 --- a/src/Avalonia.Visuals/Media/GradientBrush.cs +++ b/src/Avalonia.Visuals/Media/GradientBrush.cs @@ -1,12 +1,13 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; using System.Collections.Generic; using Avalonia.Metadata; namespace Avalonia.Media { - public abstract class GradientBrush : Brush + public abstract class GradientBrush : Brush, IGradientBrush { public static readonly StyledProperty SpreadMethodProperty = AvaloniaProperty.Register(nameof(SpreadMethod)); @@ -25,11 +26,14 @@ namespace Avalonia.Media set { SetValue(SpreadMethodProperty, value); } } + // TODO: We shouldn't be returning a concrete List<> here [Content] public List GradientStops { get { return GetValue(GradientStopsProperty); } set { SetValue(GradientStopsProperty, value); } } + + IReadOnlyList IGradientBrush.GradientStops => GradientStops; } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/IGradientBrush.cs b/src/Avalonia.Visuals/Media/IGradientBrush.cs new file mode 100644 index 0000000000..a9079ecfda --- /dev/null +++ b/src/Avalonia.Visuals/Media/IGradientBrush.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace Avalonia.Media +{ + /// + /// A brush that draws with a linear gradient. + /// + public interface IGradientBrush : IBrush + { + /// + /// Gets the brush's gradient stops. + /// + IReadOnlyList GradientStops { get; } + + /// + /// Gets the brush's spread method that defines how to draw a gradient that doesn't fill + /// the bounds of the destination control. + /// + GradientSpreadMethod SpreadMethod { get; } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/ILinearGradientBrush.cs b/src/Avalonia.Visuals/Media/ILinearGradientBrush.cs new file mode 100644 index 0000000000..3e2a5a0e22 --- /dev/null +++ b/src/Avalonia.Visuals/Media/ILinearGradientBrush.cs @@ -0,0 +1,18 @@ +namespace Avalonia.Media +{ + /// + /// A brush that draws with a linear gradient. + /// + public interface ILinearGradientBrush : IGradientBrush + { + /// + /// Gets or sets the start point for the gradient. + /// + RelativePoint StartPoint { get; } + + /// + /// Gets or sets the end point for the gradient. + /// + RelativePoint EndPoint { get; } + } +} \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/Immutable/ImmutableGradientBrush.cs b/src/Avalonia.Visuals/Media/Immutable/ImmutableGradientBrush.cs new file mode 100644 index 0000000000..e8507f8fc3 --- /dev/null +++ b/src/Avalonia.Visuals/Media/Immutable/ImmutableGradientBrush.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Avalonia.Media.Immutable +{ + /// + /// A brush that draws with a gradient. + /// + public abstract class ImmutableGradientBrush : IGradientBrush + { + /// + /// Initializes a new instance of the class. + /// + /// The gradient stops. + /// The opacity of the brush. + /// The spread method. + protected ImmutableGradientBrush( + IReadOnlyList gradientStops, + double opacity, + GradientSpreadMethod spreadMethod) + { + GradientStops = gradientStops; + Opacity = opacity; + SpreadMethod = spreadMethod; + } + + /// + /// Initializes a new instance of the class. + /// + /// The brush from which this brush's properties should be copied. + protected ImmutableGradientBrush(IGradientBrush source) + : this(source.GradientStops.ToList(), source.Opacity, source.SpreadMethod) + { + + } + + /// + public IReadOnlyList GradientStops { get; } + + /// + public double Opacity { get; } + + /// + public GradientSpreadMethod SpreadMethod { get; } + } +} diff --git a/src/Avalonia.Visuals/Media/Immutable/ImmutableLinearGradientBrush.cs b/src/Avalonia.Visuals/Media/Immutable/ImmutableLinearGradientBrush.cs new file mode 100644 index 0000000000..985e535b22 --- /dev/null +++ b/src/Avalonia.Visuals/Media/Immutable/ImmutableLinearGradientBrush.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Avalonia.Media.Immutable +{ + /// + /// A brush that draws with a linear gradient. + /// + public class ImmutableLinearGradientBrush : ImmutableGradientBrush, ILinearGradientBrush + { + /// + /// Initializes a new instance of the class. + /// + /// The gradient stops. + /// The opacity of the brush. + /// The spread method. + /// The start point for the gradient. + /// The end point for the gradient. + public ImmutableLinearGradientBrush( + IReadOnlyList gradientStops, + double opacity = 1, + GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad, + RelativePoint? startPoint = null, + RelativePoint? endPoint = null) + : base(gradientStops, opacity, spreadMethod) + { + StartPoint = startPoint ?? RelativePoint.TopLeft; + EndPoint = endPoint ?? RelativePoint.BottomRight; + } + + /// + /// Initializes a new instance of the class. + /// + /// The brush from which this brush's properties should be copied. + public ImmutableLinearGradientBrush(ILinearGradientBrush source) + : base(source) + { + StartPoint = source.StartPoint; + EndPoint = source.EndPoint; + } + + /// + public RelativePoint StartPoint { get; } + + /// + public RelativePoint EndPoint { get; } + } +} diff --git a/src/Avalonia.Visuals/Media/LinearGradientBrush.cs b/src/Avalonia.Visuals/Media/LinearGradientBrush.cs index 6ba2c5093e..344e05e16e 100644 --- a/src/Avalonia.Visuals/Media/LinearGradientBrush.cs +++ b/src/Avalonia.Visuals/Media/LinearGradientBrush.cs @@ -1,12 +1,14 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; + namespace Avalonia.Media { /// /// A brush that draws with a linear gradient. /// - public sealed class LinearGradientBrush : GradientBrush + public sealed class LinearGradientBrush : GradientBrush, ILinearGradientBrush, IMutableBrush { /// /// Defines the property. @@ -41,5 +43,11 @@ namespace Avalonia.Media get { return GetValue(EndPointProperty); } set { SetValue(EndPointProperty, value); } } + + /// + IBrush IMutableBrush.ToImmutable() + { + return new Immutable.ImmutableLinearGradientBrush(this); + } } } \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index 19d90d15f6..20b5f54784 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs @@ -319,7 +319,7 @@ namespace Avalonia.Direct2D1.Media public BrushImpl CreateBrush(IBrush brush, Size destinationSize) { var solidColorBrush = brush as Avalonia.Media.ISolidColorBrush; - var linearGradientBrush = brush as Avalonia.Media.LinearGradientBrush; + var linearGradientBrush = brush as Avalonia.Media.ILinearGradientBrush; var radialGradientBrush = brush as Avalonia.Media.RadialGradientBrush; var imageBrush = brush as Avalonia.Media.IImageBrush; var visualBrush = brush as Avalonia.Media.IVisualBrush; diff --git a/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs index 8d8058340e..2eb585e6ef 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs @@ -8,7 +8,7 @@ namespace Avalonia.Direct2D1.Media public class LinearGradientBrushImpl : BrushImpl { public LinearGradientBrushImpl( - Avalonia.Media.LinearGradientBrush brush, + Avalonia.Media.ILinearGradientBrush brush, SharpDX.Direct2D1.RenderTarget target, Size destinationSize) { diff --git a/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject b/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject index 8bcb864f82..235da29767 100644 --- a/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject +++ b/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject @@ -1,47 +1,6 @@  1000 - - - Avalonia.Direct2D1.RenderTests.Media.LinearGradientBrushTests.LinearGradientBrush_RedBlue_Vertical_Fill - - - Avalonia.Direct2D1.RenderTests.Controls.BorderTests - - - Avalonia.Direct2D1.RenderTests.Controls.ImageTests - - - Avalonia.Direct2D1.RenderTests.GeometryClippingTests - - - Avalonia.Direct2D1.RenderTests.Media.FormattedTextImplTests - - - Avalonia.Direct2D1.RenderTests.OpacityMaskTests - - - Avalonia.Direct2D1.RenderTests.Shapes.EllipseTests - - - Avalonia.Direct2D1.RenderTests.Shapes.LineTests - - - Avalonia.Direct2D1.RenderTests.Shapes.PathTests - - - Avalonia.Direct2D1.RenderTests.Shapes.PolygonTests - - - Avalonia.Direct2D1.RenderTests.Shapes.PolylineTests - - - Avalonia.Direct2D1.RenderTests.Shapes.RectangleTests - - - Avalonia.Direct2D1.RenderTests.Media.LinearGradientBrushTests.LinearGradientBrush_RedBlue_Horizontal_Fill - - True \ No newline at end of file