From 5b79178947ffe9d8ed61117d241d62e911e36c12 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Thu, 28 Jan 2016 14:43:41 +0300 Subject: [PATCH] Added LineJoin parameter to geometric primitives. Fixed Bounds for Line, Polygon, Polyline. --- src/Perspex.Controls/Shapes/Line.cs | 5 --- src/Perspex.Controls/Shapes/Polygon.cs | 5 --- src/Perspex.Controls/Shapes/Polyline.cs | 5 --- src/Perspex.Controls/Shapes/Shape.cs | 4 +- .../Media/PolylineGeometry.cs | 30 +++++++++++++++ .../Perspex.SceneGraph.csproj | 2 +- src/Skia/Perspex.Skia/DrawingContextImpl.cs | 6 +-- .../Shapes/PolygonTests.cs | 33 +++++++++++++---- .../Shapes/PolylineTests.cs | 37 +++++++++++++++---- 9 files changed, 91 insertions(+), 36 deletions(-) diff --git a/src/Perspex.Controls/Shapes/Line.cs b/src/Perspex.Controls/Shapes/Line.cs index 40b00a1317..f9a8c9cbc5 100644 --- a/src/Perspex.Controls/Shapes/Line.cs +++ b/src/Perspex.Controls/Shapes/Line.cs @@ -50,10 +50,5 @@ namespace Perspex.Controls.Shapes return _geometry; } } - - protected override Size MeasureOverride(Size availableSize) - { - return new Size(StrokeThickness, StrokeThickness); - } } } diff --git a/src/Perspex.Controls/Shapes/Polygon.cs b/src/Perspex.Controls/Shapes/Polygon.cs index 0e6d846d90..9536d710a5 100644 --- a/src/Perspex.Controls/Shapes/Polygon.cs +++ b/src/Perspex.Controls/Shapes/Polygon.cs @@ -19,10 +19,5 @@ namespace Perspex.Controls.Shapes } public override Geometry DefiningGeometry => new PolylineGeometry(Points, true); - - protected override Size MeasureOverride(Size availableSize) - { - return new Size(StrokeThickness, StrokeThickness); - } } } diff --git a/src/Perspex.Controls/Shapes/Polyline.cs b/src/Perspex.Controls/Shapes/Polyline.cs index 8e27535dc5..ba6ce1c174 100644 --- a/src/Perspex.Controls/Shapes/Polyline.cs +++ b/src/Perspex.Controls/Shapes/Polyline.cs @@ -24,10 +24,5 @@ namespace Perspex.Controls.Shapes } public override Geometry DefiningGeometry => new PolylineGeometry(Points, false); - - protected override Size MeasureOverride(Size availableSize) - { - return new Size(StrokeThickness, StrokeThickness); - } } } diff --git a/src/Perspex.Controls/Shapes/Shape.cs b/src/Perspex.Controls/Shapes/Shape.cs index 6e7934b0e7..eb07be6a78 100644 --- a/src/Perspex.Controls/Shapes/Shape.cs +++ b/src/Perspex.Controls/Shapes/Shape.cs @@ -96,6 +96,8 @@ namespace Perspex.Controls.Shapes public PenLineCap StrokeEndLineCap { get; set; } = PenLineCap.Flat; + public PenLineJoin StrokeJoin { get; set; } = PenLineJoin.Miter; + public override void Render(DrawingContext context) { var geometry = RenderedGeometry; @@ -103,7 +105,7 @@ namespace Perspex.Controls.Shapes if (geometry != null) { var pen = new Pen(Stroke, StrokeThickness, new DashStyle(StrokeDashArray), - StrokeDashCap, StrokeStartLineCap, StrokeEndLineCap); + StrokeDashCap, StrokeStartLineCap, StrokeEndLineCap, StrokeJoin); context.DrawGeometry(Fill, pen, geometry); } } diff --git a/src/Perspex.SceneGraph/Media/PolylineGeometry.cs b/src/Perspex.SceneGraph/Media/PolylineGeometry.cs index 244f027339..817d1d8012 100644 --- a/src/Perspex.SceneGraph/Media/PolylineGeometry.cs +++ b/src/Perspex.SceneGraph/Media/PolylineGeometry.cs @@ -39,6 +39,36 @@ namespace Perspex.Media } /// + public override Rect Bounds + { + get + { + double xMin = double.MaxValue, yMin = double.MaxValue; + double xMax = double.MinValue, yMax = double.MinValue; + foreach (var point in _points) + { + if (point.X < xMin) + { + xMin = point.X; + } + else if (point.X > xMax) + { + xMax = point.X; + } + + if (point.Y < yMin) + { + yMin = point.Y; + } + else if (point.Y > yMax) + { + yMax = point.Y; + } + } + + return new Rect(xMin, yMin, xMax - xMin, yMax - yMin); + } + } public override Rect Bounds => PlatformImpl.Bounds; /// diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index e6448449d9..6578b9c7b5 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -72,12 +72,12 @@ + - diff --git a/src/Skia/Perspex.Skia/DrawingContextImpl.cs b/src/Skia/Perspex.Skia/DrawingContextImpl.cs index 405f021515..a430ead5a3 100644 --- a/src/Skia/Perspex.Skia/DrawingContextImpl.cs +++ b/src/Skia/Perspex.Skia/DrawingContextImpl.cs @@ -56,7 +56,6 @@ namespace Perspex.Skia var rv = NativeBrushPool.Instance.Get(); rv.Brush->Opacity = brush.Opacity; - var solid = brush as SolidColorBrush; if (solid != null) { @@ -108,8 +107,6 @@ namespace Perspex.Skia rv.Brush->Bitmap = bitmap.Handle; rv.Brush->BitmapTileMode = tileBrush.TileMode; rv.Brush->BitmapTranslation = new SkiaPoint(-helper.DestinationRect.X, -helper.DestinationRect.Y); - - } return rv; @@ -119,8 +116,9 @@ namespace Perspex.Skia { var brush = CreateBrush(pen.Brush, targetSize); brush.Brush->Stroke = true; - brush.Brush->StrokeThickness = (float)pen.Thickness; + brush.Brush->StrokeThickness = (float)(pen.Thickness / ((Transform.M11 + Transform.M22) * 0.5)); brush.Brush->StrokeLineCap = pen.StartLineCap; + brush.Brush->StrokeLineJoin = pen.LineJoin; brush.Brush->StrokeMiterLimit = (float)pen.MiterLimit; if (pen.DashStyle?.Dashes != null) diff --git a/tests/Perspex.RenderTests/Shapes/PolygonTests.cs b/tests/Perspex.RenderTests/Shapes/PolygonTests.cs index 284315a246..dd1db5bd06 100644 --- a/tests/Perspex.RenderTests/Shapes/PolygonTests.cs +++ b/tests/Perspex.RenderTests/Shapes/PolygonTests.cs @@ -24,22 +24,17 @@ namespace Perspex.Direct2D1.RenderTests.Shapes [Fact] public void Polygon_1px_Stroke() { - var polygonPoints = new Point[] { new Point(5, 0), new Point(8, 8), new Point(0, 3), new Point(10, 3), new Point(2, 8) }; - for (int i = 0; i < polygonPoints.Length; i++) - { - polygonPoints[i] = polygonPoints[i] * 15; - } - Decorator target = new Decorator { Padding = new Thickness(8), Width = 200, - Height = 150, + Height = 200, Child = new Polygon { Stroke = Brushes.DarkBlue, + Stretch = Stretch.Uniform, Fill = Brushes.Violet, - Points = polygonPoints, + Points = new [] { new Point(5, 0), new Point(8, 8), new Point(0, 3), new Point(10, 3), new Point(2, 8) }, StrokeThickness = 1 } }; @@ -47,5 +42,27 @@ namespace Perspex.Direct2D1.RenderTests.Shapes RenderToFile(target); CompareImages(); } + + [Fact] + public void Polygon_NonUniformFill() + { + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 400, + Height = 200, + Child = new Polygon + { + Stroke = Brushes.DarkBlue, + Stretch = Stretch.Fill, + Fill = Brushes.Violet, + Points = new[] { new Point(5, 0), new Point(8, 8), new Point(0, 3), new Point(10, 3), new Point(2, 8) }, + StrokeThickness = 5, + } + }; + + RenderToFile(target); + CompareImages(); + } } } diff --git a/tests/Perspex.RenderTests/Shapes/PolylineTests.cs b/tests/Perspex.RenderTests/Shapes/PolylineTests.cs index 79e45ace28..72aac1b0f8 100644 --- a/tests/Perspex.RenderTests/Shapes/PolylineTests.cs +++ b/tests/Perspex.RenderTests/Shapes/PolylineTests.cs @@ -26,21 +26,17 @@ namespace Perspex.Direct2D1.RenderTests.Shapes { var polylinePoints = new Point[] { new Point(0, 0), new Point(5, 0), new Point(6, -2), new Point(7, 3), new Point(8, -3), new Point(9, 1), new Point(10, 0), new Point(15, 0) }; - var offsetPoint = new Point(0, 50); - for (int i = 0; i < polylinePoints.Length; i++) - { - polylinePoints[i] = polylinePoints[i] * 13 + offsetPoint; - } Decorator target = new Decorator { Padding = new Thickness(8), - Width = 230, - Height = 130, + Width = 400, + Height = 200, Child = new Polyline { Stroke = Brushes.Brown, Points = polylinePoints, + Stretch = Stretch.Uniform, StrokeThickness = 1 } }; @@ -48,5 +44,32 @@ namespace Perspex.Direct2D1.RenderTests.Shapes RenderToFile(target); CompareImages(); } + + [Fact] + public void Polyline_10px_Stroke_PenLineJoin() + { + var polylinePoints = new Point[] { new Point(0, 0), new Point(5, 0), new Point(6, -2), new Point(7, 3), new Point(8, -3), + new Point(9, 1), new Point(10, 0), new Point(15, 0) }; + + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 400, + Height = 200, + Child = new Polyline + { + Stroke = Brushes.Brown, + Points = polylinePoints, + Stretch = Stretch.Uniform, + StrokeJoin = PenLineJoin.Round, + StrokeStartLineCap = PenLineCap.Round, + StrokeEndLineCap = PenLineCap.Round, + StrokeThickness = 10 + } + }; + + RenderToFile(target); + CompareImages(); + } } }