diff --git a/src/Perspex.SceneGraph/Point.cs b/src/Perspex.SceneGraph/Point.cs index 917ebc749a..62daee8870 100644 --- a/src/Perspex.SceneGraph/Point.cs +++ b/src/Perspex.SceneGraph/Point.cs @@ -59,6 +59,16 @@ namespace Perspex return new Vector(p.x, p.y); } + /// + /// Negates a point. + /// + /// The point. + /// The negated point. + public static Point operator -(Point a) + { + return new Point(-a.x, -a.y); + } + /// /// Checks for equality between two s. /// diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs index 43e193dfd3..2dce69e3d0 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs @@ -34,7 +34,7 @@ namespace Perspex.Rendering /// An optional platform-specific handle. public virtual void Render(IVisual visual, IPlatformHandle handle) { - this.Render(visual, handle, Matrix.Identity, Matrix.Identity); + this.Render(visual, handle, Matrix.Identity); } /// @@ -42,14 +42,12 @@ namespace Perspex.Rendering /// /// The visual to render. /// An optional platform-specific handle. - /// The translation. /// The transform. - public virtual void Render(IVisual visual, IPlatformHandle handle, Matrix translation, Matrix transform) + public virtual void Render(IVisual visual, IPlatformHandle handle, Matrix transform) { using (var context = this.CreateDrawingContext(handle)) { - //context.PushTransform(translation * transform); - this.Render(visual, context, translation, transform); + this.Render(visual, context, Matrix.Identity, transform); } ++this.RenderCount; diff --git a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs index 2d98e367f8..a17106b6b5 100644 --- a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs @@ -28,10 +28,10 @@ namespace Perspex.Direct2D1.Media layoutable.Arrange(new Rect(layoutable.DesiredSize)); } - var sourceSize = layoutable.Bounds.Size; + var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size); var destinationRect = brush.DestinationRect.ToPixels(destinationSize); - var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceSize); - var translate = CalculateTranslate(brush, destinationRect.Size, sourceSize * scale); + var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); + var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); using (var brt = new BitmapRenderTarget( target, @@ -39,33 +39,41 @@ namespace Perspex.Direct2D1.Media destinationRect.Size.ToSharpDX())) { var renderer = new Renderer(brt); - renderer.Render(visual, null, Matrix.CreateTranslation(translate), Matrix.CreateScale(scale)); + var transform = Matrix.CreateTranslation(-sourceRect.Position) * + Matrix.CreateScale(scale) * + Matrix.CreateTranslation(translate); + renderer.Render(visual, null, transform); this.PlatformBrush = new BitmapBrush(brt, brt.Bitmap); } } - private static Vector CalculateTranslate(VisualBrush brush, Size destinationSize, Size sourceSize) + private static Vector CalculateTranslate( + VisualBrush brush, + Rect sourceRect, + Rect destinationRect, + Vector scale) { - double x = 0; - double y = 0; + var x = 0.0; + var y = 0.0; + var size = sourceRect.Size * scale; switch (brush.AlignmentX) { case AlignmentX.Center: - x = (destinationSize.Width - sourceSize.Width) / 2; + x += (destinationRect.Width - size.Width) / 2; break; case AlignmentX.Right: - x = destinationSize.Width - sourceSize.Width; + x += destinationRect.Width - size.Width; break; } switch (brush.AlignmentY) { case AlignmentY.Center: - y = (destinationSize.Height - sourceSize.Height) / 2; + y += (destinationRect.Height - size.Height) / 2; break; case AlignmentY.Bottom: - y = destinationSize.Height - sourceSize.Height; + y += destinationRect.Height - size.Height; break; } diff --git a/tests/Perspex.RenderTests/Media/VisualBrushTests.cs b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs index 9b7fb7fbdd..fc74160e74 100644 --- a/tests/Perspex.RenderTests/Media/VisualBrushTests.cs +++ b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs @@ -247,47 +247,41 @@ namespace Perspex.Direct2D1.RenderTests.Media this.CompareImages(); } - ////[Fact] - ////public void VisualBrush_Line_Fill() - ////{ - //// Decorator target = new Decorator - //// { - //// Padding = new Thickness(8), - //// Width = 200, - //// Height = 200, - //// Child = new Line - //// { - //// X1 = 16, - //// Y1 = 16, - //// X2 = 184, - //// Y2 = 184, - //// StrokeThickness = 40, - //// StrokeStartLineCap = "Triangle", - //// StrokeEndLineCap = "Triangle", - //// Fill = new VisualBrush - //// { - //// Visual = new Border - //// { - //// Width = 92, - //// Height = 92, - //// Background = Brushes.Red, - //// BorderBrush = Brushes.Black, - //// BorderThickness = 2, - //// Child = new TextBlock - //// { - //// Text = "Perspex", - //// FontSize = 12, - //// FontFamily = "Arial", - //// HorizontalAlignment = HorizontalAlignment.Center, - //// VerticalAlignment = VerticalAlignment.Center, - //// } - //// } - //// } - //// } - //// }; + [Fact] + public void VisualBrush_SourceRect_Absolute() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 200, + Height = 200, + Child = new Rectangle + { + Fill = new VisualBrush + { + SourceRect = new RelativeRect(40, 40, 100, 100, OriginUnit.Pixels), + Visual = new Border + { + Width = 180, + Height = 180, + Background = Brushes.Red, + BorderBrush = Brushes.Black, + BorderThickness = 2, + Child = new Ellipse + { + Width = 100, + Height = 100, + Fill = Brushes.Yellow, + VerticalAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Center, + } + } + } + } + }; - //// this.RenderToFile(target); - //// this.CompareImages(); - ////} + this.RenderToFile(target); + this.CompareImages(); + } } } diff --git a/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png b/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png new file mode 100644 index 0000000000..e1fcdbc1a6 Binary files /dev/null and b/tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png differ