diff --git a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs index 4dd858ba11..247789243f 100644 --- a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs +++ b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs @@ -279,10 +279,17 @@ namespace Perspex.Direct2D1.Media }); } + /// + /// Creates a Direct2D brush wrapper for a Perspex brush. + /// + /// The perspex brush. + /// The size of the brush's target area. + /// The Direct2D brush wrapper. public BrushImpl CreateBrush(Perspex.Media.Brush brush, Size destinationSize) { - Perspex.Media.SolidColorBrush solidColorBrush = brush as Perspex.Media.SolidColorBrush; - Perspex.Media.LinearGradientBrush linearGradientBrush = brush as Perspex.Media.LinearGradientBrush; + var solidColorBrush = brush as Perspex.Media.SolidColorBrush; + var linearGradientBrush = brush as Perspex.Media.LinearGradientBrush; + var visualBrush = brush as Perspex.Media.VisualBrush; if (solidColorBrush != null) { @@ -292,6 +299,10 @@ namespace Perspex.Direct2D1.Media { return new LinearGradientBrushImpl(linearGradientBrush, this.renderTarget, destinationSize); } + else if (visualBrush != null) + { + return new VisualBrushImpl(visualBrush, this.renderTarget, destinationSize); + } else { return new SolidColorBrushImpl(null, this.renderTarget, destinationSize); diff --git a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs new file mode 100644 index 0000000000..5b399fd9b3 --- /dev/null +++ b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs @@ -0,0 +1,51 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Direct2D1.Media +{ + using Perspex.Layout; + using Perspex.Media; + using SharpDX.Direct2D1; + + public class VisualBrushImpl : BrushImpl + { + public VisualBrushImpl( + Perspex.Media.VisualBrush brush, + SharpDX.Direct2D1.RenderTarget target, + Size destinationSize) + : base(brush, target, destinationSize) + { + var visual = brush.Visual; + var layoutable = visual as ILayoutable; + + if (layoutable?.IsArrangeValid == false) + { + layoutable.Measure(Size.Infinity); + layoutable.Arrange(new Rect(layoutable.DesiredSize)); + } + + var sourceSize = layoutable.Bounds.Size; + var destinationRect = brush.DestinationRect.ToPixels(destinationSize); + var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceSize); + + using (var brt = new BitmapRenderTarget( + target, + CompatibleRenderTargetOptions.None, + destinationRect.Size.ToSharpDX())) + { + var renderer = new Renderer(brt); + renderer.Render(visual, null, Matrix.Identity, Matrix.CreateScale(scale)); + this.PlatformBrush = new BitmapBrush(brt, brt.Bitmap); + } + } + + public override void Dispose() + { + ((BitmapBrush)this.PlatformBrush).Bitmap.Dispose(); + base.Dispose(); + } + } +} diff --git a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj index 11053fdc40..c7271b74bd 100644 --- a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj +++ b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj @@ -83,6 +83,7 @@ + diff --git a/tests/Perspex.RenderTests/Brushes/VisualBrushTests.cs b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs similarity index 97% rename from tests/Perspex.RenderTests/Brushes/VisualBrushTests.cs rename to tests/Perspex.RenderTests/Media/VisualBrushTests.cs index 1cb4c526f3..301d09852e 100644 --- a/tests/Perspex.RenderTests/Brushes/VisualBrushTests.cs +++ b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs @@ -4,7 +4,7 @@ // // ----------------------------------------------------------------------- -namespace Perspex.Direct2D1.RenderTests.Controls +namespace Perspex.Direct2D1.RenderTests.Media { using Perspex.Controls; using Perspex.Controls.Shapes; @@ -15,7 +15,7 @@ namespace Perspex.Direct2D1.RenderTests.Controls public class VisualBrushTests : TestBase { public VisualBrushTests() - : base(@"Brushes\VisualBrush") + : base(@"Media\VisualBrush") { } @@ -31,6 +31,7 @@ namespace Perspex.Direct2D1.RenderTests.Controls { Fill = new VisualBrush { + Stretch = Stretch.None, Visual = new Border { Width = 92, diff --git a/tests/Perspex.RenderTests/Perspex.Direct2D1.RenderTests.csproj b/tests/Perspex.RenderTests/Perspex.Direct2D1.RenderTests.csproj index b9ff14c875..bc8fd43376 100644 --- a/tests/Perspex.RenderTests/Perspex.Direct2D1.RenderTests.csproj +++ b/tests/Perspex.RenderTests/Perspex.Direct2D1.RenderTests.csproj @@ -77,7 +77,7 @@ - + diff --git a/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png b/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png new file mode 100644 index 0000000000..f1914a404f Binary files /dev/null and b/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png differ diff --git a/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_Stretch_None.expected.png b/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_Stretch_None.expected.png new file mode 100644 index 0000000000..905ec5386a Binary files /dev/null and b/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_Stretch_None.expected.png differ