Browse Source

Implemented VisualBrush.SourceRect.

Steven Kirk 10 years ago
parent
commit
ec010a1c4d

+ 10 - 0
src/Perspex.SceneGraph/Point.cs

@@ -59,6 +59,16 @@ namespace Perspex
             return new Vector(p.x, p.y);
         }
 
+        /// <summary>
+        /// Negates a point.
+        /// </summary>
+        /// <param name="a">The point.</param>
+        /// <returns>The negated point.</returns>
+        public static Point operator -(Point a)
+        {
+            return new Point(-a.x, -a.y);
+        }
+
         /// <summary>
         /// Checks for equality between two <see cref="Point"/>s.
         /// </summary>

+ 3 - 5
src/Perspex.SceneGraph/Rendering/RendererBase.cs

@@ -34,7 +34,7 @@ namespace Perspex.Rendering
         /// <param name="handle">An optional platform-specific handle.</param>
         public virtual void Render(IVisual visual, IPlatformHandle handle)
         {
-            this.Render(visual, handle, Matrix.Identity, Matrix.Identity);
+            this.Render(visual, handle, Matrix.Identity);
         }
 
         /// <summary>
@@ -42,14 +42,12 @@ namespace Perspex.Rendering
         /// </summary>
         /// <param name="visual">The visual to render.</param>
         /// <param name="handle">An optional platform-specific handle.</param>
-        /// <param name="translation">The translation.</param>
         /// <param name="transform">The transform.</param>
-        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;

+ 19 - 11
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;
             }
 

+ 35 - 41
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();
+        }
     }
 }

BIN
tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png