Exemple #1
0
        private void DrawFileViewLasso(
            CanvasDrawingSession ds, float leftTop, float leftHeight, float rightTop, float rightHeight)
        {
            var pathBuilder = new CanvasPathBuilder(ds);

            float num1 = Math.Min(4.0f, leftHeight * 0.5f);  // bezier curve control point
            float num2 = Math.Min(4.0f, rightHeight * 0.5f); // bezier curve control point
            float y1   = leftTop + leftHeight;
            float y2   = rightTop + rightHeight;

            pathBuilder.BeginFigure(new Vector2(32.0f, leftTop));
            pathBuilder.AddLine(new Vector2(36.0f, rightTop));
            pathBuilder.AddLine(new Vector2(56.0f, rightTop));
            pathBuilder.AddQuadraticBezier(new Vector2(60.0f, rightTop), new Vector2(60.0f, rightTop + num2));
            pathBuilder.AddLine(new Vector2(60.0f, y2 - num2));
            pathBuilder.AddQuadraticBezier(new Vector2(60.0f, y2), new Vector2(56.0f, y2));
            pathBuilder.AddLine(new Vector2(36.0f, y2));
            pathBuilder.AddLine(new Vector2(32.0f, y1));
            pathBuilder.AddLine(new Vector2(12.0f, y1));
            pathBuilder.AddQuadraticBezier(new Vector2(8.0f, y1), new Vector2(8.0f, y1 - num1));
            pathBuilder.AddLine(new Vector2(8.0f, leftTop + num1));
            pathBuilder.AddQuadraticBezier(new Vector2(8.0f, leftTop), new Vector2(12.0f, leftTop));
            pathBuilder.EndFigure(CanvasFigureLoop.Closed);

            var finalGeo = CanvasGeometry.CreatePath(pathBuilder);

            ds.DrawGeometry(finalGeo, _lassoColor);
        }
Exemple #2
0
        /// <summary>
        /// Adds the Path Element to the Path.
        /// </summary>
        /// <param name="pathBuilder">CanvasPathBuilder object</param>
        /// <param name="currentPoint">The last active location in the Path before adding
        /// the Path Element</param>
        /// <param name="lastElement">The previous PathElement in the Path.</param>
        /// <returns>The latest location in the Path after adding the Path Element</returns>
        public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint, ref ICanvasPathElement lastElement)
        {
            // Calculate coordinates
            var controlPoint = new Vector2(_x1, _y1);
            var point        = new Vector2(_x, _y);

            if (IsRelative)
            {
                controlPoint += currentPoint;
                point        += currentPoint;
            }

            // Save the absolute control point so that it can be used by the following
            // SmoothQuadraticBezierElement (if any)
            _absoluteControlPoint = controlPoint;

            // Execute command
            pathBuilder.AddQuadraticBezier(controlPoint, point);

            // Set Last Element
            lastElement = this;

            // Return current point
            return(point);
        }
Exemple #3
0
        /// <summary>
        /// Adds the Path Element to the Path.
        /// </summary>
        /// <param name="pathBuilder">CanvasPathBuilder object</param>
        /// <param name="currentPoint">The last active location in the Path before adding
        /// the Path Element</param>
        /// <param name="lastElement">The previous PathElement in the Path.</param>
        /// <param name="logger">For logging purpose. To log the set of CanvasPathBuilder
        /// commands, used for creating the CanvasGeometry, in string format.</param>
        /// <returns>The latest location in the Path after adding the Path Element</returns>
        public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint,
                                           ref ICanvasPathElement lastElement, StringBuilder logger)
        {
            // Calculate coordinates
            var controlPoint = new Vector2(_x1, _y1);
            var point        = new Vector2(_x, _y);

            if (IsRelative)
            {
                controlPoint += currentPoint;
                point        += currentPoint;
            }

            // Save the absolute control point so that it can be used by the following
            // SmoothQuadraticBezierElement (if any)
            _absoluteControlPoint = controlPoint;

            // Execute command
            pathBuilder.AddQuadraticBezier(controlPoint, point);

            // Log command
            logger?.Append($"{Indent}pathBuilder.AddQuadraticBezier(new Vector2({controlPoint.X}, {controlPoint.Y})");
            logger?.AppendLine($", new Vector2({point.X}, {point.Y}));");

            // Set Last Element
            lastElement = this;
            // Return current point
            return(point);
        }
Exemple #4
0
        public void QuadTo(float x1, float y1, float x, float y)
        {
            var controlPoint = new System.Numerics.Vector2(x1, y1);
            var endPoint     = new System.Numerics.Vector2(x, y);

            _pathBuilder.AddQuadraticBezier(controlPoint, endPoint);
        }
Exemple #5
0
        public void VerifySendPathTo()
        {
            //
            // This calls each of the path functions, once, and verfies that it works.
            // Sink behavior is verified in more detail in the geometry unit tests.
            //
            CanvasDevice device = new CanvasDevice();

            CanvasPathBuilder pathBuilder = new CanvasPathBuilder(device);

            pathBuilder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate);
            pathBuilder.BeginFigure(0, 0);
            pathBuilder.AddLine(0, 0);
            pathBuilder.AddQuadraticBezier(new Vector2(), new Vector2());
            pathBuilder.AddCubicBezier(new Vector2(), new Vector2(), new Vector2());

            // D2D tries to be smart about degenerate arcs and redundant set segment options, and may sometimes actually
            // surpress them. Therefore, these calls use non-defaults.
            pathBuilder.AddArc(new Vector2 {
                X = 100, Y = 100
            }, 10, 10, 90, CanvasSweepDirection.Clockwise, CanvasArcSize.Small);
            pathBuilder.SetSegmentOptions(CanvasFigureSegmentOptions.ForceUnstroked);

            pathBuilder.EndFigure(CanvasFigureLoop.Closed);

            CanvasGeometry pathGeometry = CanvasGeometry.CreatePath(pathBuilder);

            MyGeometryStreamReader myStreamReader = new MyGeometryStreamReader();

            pathGeometry.SendPathTo(myStreamReader);

            myStreamReader.Verify();
        }
Exemple #6
0
        public void QuadTo(float controlX, float controlY, float endX, float endY)
        {
            CheckPathBuilder();

            _builder.AddQuadraticBezier(new Vector2()
            {
                X = controlX, Y = controlY
            }, new Vector2()
            {
                X = endX, Y = endY
            });
        }
Exemple #7
0
        /// <summary>
        /// Adds the Path Element to the Path.
        /// </summary>
        /// <param name="pathBuilder">CanvasPathBuilder object</param>
        /// <param name="currentPoint">The last active location in the Path before adding
        /// the Path Element</param>
        /// <param name="lastElement">The previous PathElement in the Path.</param>
        /// <param name="logger">For logging purpose. To log the set of CanvasPathBuilder
        /// commands, used for creating the CanvasGeometry, in string format.</param>
        /// <returns>The latest location in the Path after adding the Path Element</returns>
        public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint,
                                           ref ICanvasPathElement lastElement, StringBuilder logger)
        {
            // Calculate coordinates
            // Check if the last element was a Quadratic Bezier
            var quadBezier = lastElement as QuadraticBezierElement;

            if (quadBezier != null)
            {
                // Reflect the control point of the Quadratic Bezier over the current point. The
                // resulting point will be the control point of this Bezier.
                _absoluteControlPoint = Utils.Reflect(quadBezier.GetControlPoint(), currentPoint);
            }
            // Or if the last element was s Smooth Quadratic Bezier
            else
            {
                var smoothQuadBezier = lastElement as SmoothQuadraticBezierElement;
                // If the last element was a Smooth Quadratic Bezier then reflect its control point
                // over the current point. The resulting point will be the control point of this
                // Bezier. Otherwise, if the last element was not a Smooth Quadratic Bezier,
                // then the currentPoint will be the control point of this Bezier.
                _absoluteControlPoint = smoothQuadBezier != null
                    ? Utils.Reflect(smoothQuadBezier.GetControlPoint(), currentPoint)
                    : currentPoint;
            }

            var point = new Vector2(_x, _y);

            if (IsRelative)
            {
                point += currentPoint;
            }

            // Execute command
            pathBuilder.AddQuadraticBezier(_absoluteControlPoint, point);

            // Log command
            logger?.Append($"{Indent}pathBuilder.AddQuadraticBezier(new Vector2({_absoluteControlPoint.X},");
            logger?.AppendLine($" {_absoluteControlPoint.Y}), new Vector2({point.X}, {point.Y}));");

            // Set Last Element
            lastElement = this;
            // Return current point
            return(point);
        }
        /// <summary>
        /// Adds the Path Element to the Path.
        /// </summary>
        /// <param name="pathBuilder">CanvasPathBuilder object</param>
        /// <param name="currentPoint">The last active location in the Path before adding
        /// the Path Element</param>
        /// <param name="lastElement">The previous PathElement in the Path.</param>
        /// <returns>The latest location in the Path after adding the Path Element</returns>
        public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint, ref ICanvasPathElement lastElement)
        {
            // Calculate coordinates
            // Check if the last element was a Quadratic Bezier
            if (lastElement is QuadraticBezierElement quadBezier)
            {
                // Reflect the control point of the Quadratic Bezier over the current point. The
                // resulting point will be the control point of this Bezier.
                _absoluteControlPoint = Utils.Reflect(quadBezier.GetControlPoint(), currentPoint);
            }

            // Or if the last element was s Smooth Quadratic Bezier
            else
            {
                // If the last element was a Smooth Quadratic Bezier then reflect its control point
                // over the current point. The resulting point will be the control point of this
                // Bezier. Otherwise, if the last element was not a Smooth Quadratic Bezier,
                // then the currentPoint will be the control point of this Bezier.
                _absoluteControlPoint = lastElement is SmoothQuadraticBezierElement smoothQuadBezier
                    ? Utils.Reflect(smoothQuadBezier.GetControlPoint(), currentPoint)
                    : currentPoint;
            }

            var point = new Vector2(_x, _y);

            if (IsRelative)
            {
                point += currentPoint;
            }

            // Execute command
            pathBuilder.AddQuadraticBezier(_absoluteControlPoint, point);

            // Set Last Element
            lastElement = this;

            // Return current point
            return(point);
        }
        public void Draw(object ds, XQBezier qbezier, double dx, double dy, ImmutableArray <ShapeProperty> db, Record r)
        {
            var _ds = ds as CanvasDrawingSession;

            double thickness = qbezier.Style.Thickness / _state.Zoom;
            var    brush     = ToColor(qbezier.Style.Fill);
            var    pen       = ToColor(qbezier.Style.Stroke);
            var    ss        = CreateStrokeStyle(qbezier.Style);

            CanvasGeometry g;

            using (var builder = new CanvasPathBuilder(_ds))
            {
                builder.BeginFigure((float)qbezier.Point1.X, (float)qbezier.Point1.Y);
                builder.AddQuadraticBezier(
                    new N.Vector2(
                        (float)qbezier.Point2.X,
                        (float)qbezier.Point2.Y),
                    new N.Vector2(
                        (float)qbezier.Point3.X,
                        (float)qbezier.Point3.Y));
                builder.EndFigure(CanvasFigureLoop.Open);
                g = CanvasGeometry.CreatePath(builder);
            }

            if (qbezier.IsFilled)
            {
                _ds.FillGeometry(g, brush);
            }

            if (qbezier.IsStroked)
            {
                _ds.DrawGeometry(g, pen, (float)thickness, ss);
            }

            g.Dispose();
            ss.Dispose();
        }
Exemple #10
0
        private static CanvasGeometry BuildGeometry(ICanvasResourceCreator resourceCreator, IReadOnlyList <Vector2> points)
        {
            using (var builder = new CanvasPathBuilder(resourceCreator.Device))
            {
                builder.BeginFigure(points[0]);

                for (var i = 0; i < points.Count / 3; i++)
                {
                    builder.AddQuadraticBezier(points[(i * 3) + 1], points[(i * 3) + 2]);

                    var lastIndex = (i * 3) + 3;

                    if (lastIndex < points.Count - 1)
                    {
                        builder.AddLine(points[lastIndex]);
                    }
                }

                builder.EndFigure(CanvasFigureLoop.Closed);

                return(CanvasGeometry.CreatePath(builder));
            }
        }
Exemple #11
0
        public static CanvasGeometry AsPathFromSegment(this PathF path, int segmentIndex, float zoom, ICanvasResourceCreator creator)
        {
            float scale = 1 / zoom;

            var builder = new CanvasPathBuilder(creator);

            var type = path.GetSegmentType(segmentIndex);

            if (type == PathOperation.Line)
            {
                int segmentStartingPointIndex = path.GetSegmentPointIndex(segmentIndex);
                var startPoint = path[segmentStartingPointIndex - 1];
                builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default);

                var point = path[segmentStartingPointIndex];
                builder.AddLine(point.X * scale, point.Y * scale);
            }
            else if (type == PathOperation.Quad)
            {
                int segmentStartingPointIndex = path.GetSegmentPointIndex(segmentIndex);
                var startPoint = path[segmentStartingPointIndex - 1];
                builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default);

                var controlPoint = path[segmentStartingPointIndex++];
                var endPoint     = path[segmentStartingPointIndex];
                builder.AddQuadraticBezier(
                    new Vector2(controlPoint.X * scale, controlPoint.Y * scale),
                    new Vector2(endPoint.X * scale, endPoint.Y * scale));
            }
            else if (type == PathOperation.Cubic)
            {
                int segmentStartingPointIndex = path.GetSegmentPointIndex(segmentIndex);
                var startPoint = path[segmentStartingPointIndex - 1];
                builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default);

                var controlPoint1 = path[segmentStartingPointIndex++];
                var controlPoint2 = path[segmentStartingPointIndex++];
                var endPoint      = path[segmentStartingPointIndex];
                builder.AddCubicBezier(
                    new Vector2(controlPoint1.X * scale, controlPoint1.Y * scale),
                    new Vector2(controlPoint2.X * scale, controlPoint2.Y * scale),
                    new Vector2(endPoint.X * scale, endPoint.Y * scale));
            }
            else if (type == PathOperation.Arc)
            {
                path.GetSegmentInfo(segmentIndex, out var pointIndex, out var arcAngleIndex, out var arcClockwiseIndex);

                var topLeft     = path[pointIndex++];
                var bottomRight = path[pointIndex];
                var startAngle  = path.GetArcAngle(arcAngleIndex++);
                var endAngle    = path.GetArcAngle(arcAngleIndex);
                var clockwise   = path.GetArcClockwise(arcClockwiseIndex);

                while (startAngle < 0)
                {
                    startAngle += 360;
                }

                while (endAngle < 0)
                {
                    endAngle += 360;
                }

                var rotation    = Geometry.GetSweep(startAngle, endAngle, clockwise);
                var absRotation = Math.Abs(rotation);

                var rectX      = topLeft.X * scale;
                var rectY      = topLeft.Y * scale;
                var rectWidth  = (bottomRight.X * scale) - rectX;
                var rectHeight = (bottomRight.Y * scale) - rectY;

                var startPoint = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -startAngle);
                var endPoint   = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -endAngle);

                builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default);

                builder.AddArc(
                    new Vector2(endPoint.X, endPoint.Y),
                    rectWidth / 2,
                    rectHeight / 2,
                    0,
                    clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise,
                    absRotation >= 180 ? CanvasArcSize.Large : CanvasArcSize.Small
                    );
            }

            builder.EndFigure(CanvasFigureLoop.Open);

            return(CanvasGeometry.CreatePath(builder));
        }
Exemple #12
0
        private CanvasGeometry CreatePath(CanvasDrawingSession session, SvgPathElement element)
        {
            if (this.PathCache.ContainsKey(element))
            {
                return(this.PathCache[element]);
            }

            var open = false;
            var v    = new Vector2 {
                X = 0.0F, Y = 0.0F
            };

            CanvasGeometry geometry;

            using (var builder = new CanvasPathBuilder(this.ResourceCreator))
            {
                var fillRule = element.Style.FillRule;
                if (fillRule.HasValue && fillRule.Value.Value != SvgFillRuleType.EvenOdd)
                {
                    builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding);
                }
                foreach (var segment in element.Segments)
                {
                    if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.ClosePath)
                    {
                        builder.EndFigure(CanvasFigureLoop.Closed);
                        open = false;
                        continue;
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.MoveToAbsolute)
                    {
                        if (open)
                        {
                            builder.EndFigure(CanvasFigureLoop.Open);
                        }

                        var casted = (SvgPathSegmentMoveToAbsolute)segment;
                        v.X = casted.X;
                        v.Y = casted.Y;
                        builder.BeginFigure(v);
                        open = true;
                        continue;
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.MoveToRelative)
                    {
                        if (open)
                        {
                            builder.EndFigure(CanvasFigureLoop.Open);
                        }

                        var casted = (SvgPathSegmentMoveToRelative)segment;
                        v.X += casted.X;
                        v.Y += casted.Y;
                        builder.BeginFigure(v);
                        open = true;
                        continue;
                    }

                    if (!open)
                    {
                        builder.BeginFigure(v);
                        open = true;
                    }
                    if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToAbsolute)
                    {
                        var casted = (SvgPathSegmentLineToAbsolute)segment;
                        v.X = casted.X;
                        v.Y = casted.Y;
                        builder.AddLine(v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToRelative)
                    {
                        var casted = (SvgPathSegmentLineToRelative)segment;
                        v.X += casted.X;
                        v.Y += casted.Y;
                        builder.AddLine(v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicAbsolute)
                    {
                        var casted = (SvgPathSegmentCurveToCubicAbsolute)segment;
                        v.X = casted.X;
                        v.Y = casted.Y;
                        builder.AddCubicBezier(new Vector2 {
                            X = casted.X1, Y = casted.Y1
                        }, new Vector2 {
                            X = casted.X2, Y = casted.Y2
                        }, v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicRelative)
                    {
                        var casted = (SvgPathSegmentCurveToCubicRelative)segment;
                        var c1     = v;
                        c1.X += casted.X1;
                        c1.Y += casted.Y1;
                        var c2 = v;
                        c2.X += casted.X2;
                        c2.Y += casted.Y2;
                        v.X  += casted.X;
                        v.Y  += casted.Y;
                        builder.AddCubicBezier(c1, c2, v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticAbsolute)
                    {
                        var casted = (SvgPathSegmentCurveToQuadraticAbsolute)segment;
                        v.X = casted.X;
                        v.Y = casted.Y;
                        builder.AddQuadraticBezier(new Vector2 {
                            X = casted.X1, Y = casted.Y1
                        }, v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticRelative)
                    {
                        var casted = (SvgPathSegmentCurveToQuadraticRelative)segment;
                        var c1     = v;
                        c1.X += casted.X1;
                        c1.Y += casted.Y1;
                        v.X  += casted.X;
                        v.Y  += casted.Y;
                        builder.AddQuadraticBezier(c1, v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.ArcAbsolute)
                    {
                        var casted         = (SvgPathSegmentArcAbsolute)segment;
                        var size           = casted.LargeArcFlag ? CanvasArcSize.Large : CanvasArcSize.Small;
                        var sweepDirection = casted.SweepFlag ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise;
                        builder.AddArc(new Vector2 {
                            X = casted.X, Y = casted.Y
                        }, casted.RadiusX, casted.RadiusY, 180.0F * casted.Angle / (float)Math.PI, sweepDirection, size);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.ArcRelative)
                    {
                        var casted = (SvgPathSegmentArcRelative)segment;
                        v.X += casted.X;
                        v.Y += casted.Y;
                        var size           = casted.LargeArcFlag ? CanvasArcSize.Large : CanvasArcSize.Small;
                        var sweepDirection = casted.SweepFlag ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise;
                        builder.AddArc(v, casted.RadiusX, casted.RadiusY, 180.0F * casted.Angle / (float)Math.PI, sweepDirection, size);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToHorizontalAbsolute)
                    {
                        var casted = (SvgPathSegmentLineToHorizontalAbsolute)segment;
                        v.X = casted.X;
                        builder.AddLine(v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToHorizontalRelative)
                    {
                        var casted = (SvgPathSegmentLineToHorizontalRelative)segment;
                        v.X += casted.X;
                        builder.AddLine(v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToVerticalAbsolute)
                    {
                        var casted = (SvgPathSegmentLineToVerticalAbsolute)segment;
                        v.Y = casted.Y;
                        builder.AddLine(v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToVerticalRelative)
                    {
                        var casted = (SvgPathSegmentLineToVerticalRelative)segment;
                        v.Y += casted.Y;
                        builder.AddLine(v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicSmoothAbsolute)
                    {
                        var casted = (SvgPathSegmentCurveToCubicSmoothAbsolute)segment;
                        var c1     = v;
                        v.X = casted.X;
                        v.Y = casted.Y;
                        builder.AddCubicBezier(c1, new Vector2 {
                            X = casted.X2, Y = casted.Y2
                        }, v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicSmoothRelative)
                    {
                        var casted = (SvgPathSegmentCurveToCubicSmoothRelative)segment;
                        var c1     = v;
                        var c2     = v;
                        c2.X += casted.X2;
                        c2.Y += casted.Y2;
                        v.X  += casted.X;
                        v.Y  += casted.Y;
                        builder.AddCubicBezier(c1, c2, v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticSmoothAbsolute)
                    {
                        var casted = (SvgPathSegmentCurveToQuadraticSmoothAbsolute)segment;
                        var c1     = v;
                        v.X = casted.X;
                        v.Y = casted.Y;
                        builder.AddQuadraticBezier(c1, v);
                    }
                    else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticSmoothRelative)
                    {
                        var casted = (SvgPathSegmentCurveToQuadraticSmoothRelative)segment;
                        var c1     = v;
                        v.X += casted.X;
                        v.Y += casted.Y;
                        builder.AddQuadraticBezier(c1, v);
                    }
                }
                if (open)
                {
                    builder.EndFigure(CanvasFigureLoop.Open);
                }

                geometry = CanvasGeometry.CreatePath(builder);
            }
            this.DisposableObjects.Add(geometry);
            this.PathCache.Add(element, geometry);
            return(geometry);
        }
 /// <summary>
 /// Adds a line in the form of a cubic bezier. The control point of the quadratic bezier will be the endpoint of the line itself.
 /// </summary>
 /// <param name="pathBuilder"><see cref="CanvasPathBuilder"/></param>
 /// <param name="end">Ending location of the line segment.</param>
 public static void AddLineAsQuadraticBezier(this CanvasPathBuilder pathBuilder, Vector2 end)
 {
     pathBuilder.AddQuadraticBezier(end, end);
 }
Exemple #14
0
 public void AddQuadCurveToPoint(Vector2 endPoint, Vector2 controlPoint)
 {
     mBuilder.AddQuadraticBezier(controlPoint, endPoint);
 }
        /*public override object Clone()
        {
            SVGPath clone = new SVGPath();
            clone._gp = (GraphicsPath)_gp.Clone();
            clone._ID = _ID;
            clone._strPath = (String)_strPath.Clone();
            return clone;
        }*/

        private void parsePath(CanvasPathBuilder pb, String path)
        {
            char[] delimiter = { ' ' };
            string[] commands = Regex.Split(path, _regex1);
            string[] values = null;
            float[] points = new float[7];
            Vector2[] Vector2s = new Vector2[4];
            Vector2 lastPoint = new Vector2(0, 0);
            Vector2 lastControlPoint = new Vector2(0, 0);
            //Vector2 firstPoint = new Vector2(0, 0);
            //Vector2 firstPoint = new Vector2(0, 0);

            try
            {

                for (int i = 0; i < commands.Length; i++)
                {

                    String strCommand = commands[i];
                    char action = (strCommand != null && strCommand.Length > 0) ? strCommand[0] : ' ';
                    values = strCommand.Split(delimiter);

                    if (action == 'M')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        lastPoint = new Vector2(points[0], points[1]);
                        //firstPoint = new Vector2(points[0], points[1]);
                        
                        pb.BeginFigure(lastPoint);
                    }
                    else if (action == 'm')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;

                        pb.BeginFigure(points[0], points[1]);
                        lastPoint.X = points[0];
                        lastPoint.Y = points[1];
                        pb.BeginFigure(lastPoint);
                    }
                    else if (action == 'L')//capital letter is absolute location
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        
                        pb.AddLine(points[0], points[1]);

                        lastPoint.X = points[0];
                        lastPoint.Y = points[1];
                        

                    }
                    else if (action == 'l')//lowercase letter is relative location
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;

                        pb.AddLine(points[0], points[1]);

                        lastPoint.X = points[0];
                        lastPoint.Y = points[1];
                    }
                    else if (action == 'H')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));

                        pb.AddLine(points[0], lastPoint.Y);

                        lastPoint.X = points[0];

                    }
                    else if (action == 'h')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;

                        pb.AddLine(points[0], lastPoint.Y);

                        lastPoint.X = points[0];
                    }
                    else if (action == 'V')
                    {
                        points[0] = -(float)Convert.ToDouble(values[0].Substring(1));

                        pb.AddLine(lastPoint.X, points[0]);

                        lastPoint.Y = points[0]; 

                    }
                    else if (action == 'v')
                    {
                        points[0] = -(float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.Y;

                        pb.AddLine(lastPoint.X, points[0]);

                        lastPoint.Y = points[0];
                    }
                    else if (action == 'C')//cubic bezier, 2 control points
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = -(float)Convert.ToDouble(values[3]);
                        points[4] = (float)Convert.ToDouble(values[4]);
                        points[5] = -(float)Convert.ToDouble(values[5]);

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = new Vector2(points[0], points[1]);
                        Vector2s[2] = new Vector2(points[2], points[3]);
                        Vector2s[3] = new Vector2(points[4], points[5]);
                        
                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 'c')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;
                        points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X;
                        points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y;
                        points[4] = (float)Convert.ToDouble(values[4]) + lastPoint.X;
                        points[5] = -(float)Convert.ToDouble(values[5]) + lastPoint.Y;

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = new Vector2(points[0], points[1]);
                        Vector2s[2] = new Vector2(points[2], points[3]);
                        Vector2s[3] = new Vector2(points[4], points[5]);
                        
                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 'S')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = -(float)Convert.ToDouble(values[3]);

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint);
                        Vector2s[2] = new Vector2(points[0], points[1]);
                        Vector2s[3] = new Vector2(points[2], points[3]);

                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 's')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;
                        points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X;
                        points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y;

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint);
                        Vector2s[2] = new Vector2(points[0], points[1]);
                        Vector2s[3] = new Vector2(points[2], points[3]);

                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 'Q')//quadratic bezier, 1 control point
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = -(float)Convert.ToDouble(values[3]);


                        //convert quadratic to cubic bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = new Vector2(points[0], points[1]);
                        Vector2 QP2 = new Vector2(points[2], points[3]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //old
                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);

                        //new
                        Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));

                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);

                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 'q')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;
                        points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X;
                        points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y;


                        //convert quadratic to cubic bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = new Vector2(points[0], points[1]);
                        Vector2 QP2 = new Vector2(points[2], points[3]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //old
                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);
                        //new
                        //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));

                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);


                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 'T')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);

                        //convert quadratic to bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0);
                        Vector2 QP2 = new Vector2(points[0], points[1]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);

                        //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));


                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);

                       
                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 't')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;

                        //convert quadratic to bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0);
                        Vector2 QP2 = new Vector2(points[0], points[1]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);

                        //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));


                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);


                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 'A')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));//radiusX
                        points[1] = (float)Convert.ToDouble(values[1]);//radiusY
                        points[2] = (float)Convert.ToDouble(values[2]);//angle
                        points[3] = (float)Convert.ToDouble(values[3]);//size
                        points[4] = (float)Convert.ToDouble(values[4]);//sweep
                        points[5] = (float)Convert.ToDouble(values[5]);//endX
                        points[6] = -(float)Convert.ToDouble(values[6]);//endY

                        //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large;
                        //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive;
                        Vector2 endPoint = new Vector2(points[5], points[6]);

                        //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint);
                        //arc.AddToPath(_gp);

                        CanvasArcSize arcSize = CanvasArcSize.Large;//if size = 1, size is large.  0 for small
                        CanvasSweepDirection sweep = CanvasSweepDirection.Clockwise;//if sweep == 1, sweep is clockwise or positive

                        if(points[3]==0.0f)
                            arcSize = CanvasArcSize.Small;
                        if (points[4] == 0.0f)
                            sweep = CanvasSweepDirection.CounterClockwise;

                        pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize);


                        //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint);

                        lastPoint.X = points[5];
                        lastPoint.Y = points[6];
                    }
                    else if (action == 'a')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = (float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = (float)Convert.ToDouble(values[3]);
                        points[4] = (float)Convert.ToDouble(values[4]);
                        points[5] = (float)Convert.ToDouble(values[5] + lastPoint.X);
                        points[6] = -(float)Convert.ToDouble(values[6] + lastPoint.Y);

                        //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large;
                        //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive;
                        Vector2 endPoint = new Vector2(points[5], points[6]);

                        //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint);
                        //arc.AddToPath(_gp);

                        CanvasArcSize arcSize = CanvasArcSize.Large;//if size = 1, size is large.  0 for small
                        CanvasSweepDirection sweep = CanvasSweepDirection.Clockwise;//if sweep == 1, sweep is clockwise or positive

                        if (points[3] == 0.0f)
                            arcSize = CanvasArcSize.Small;
                        if (points[4] == 0.0f)
                            sweep = CanvasSweepDirection.CounterClockwise;

                        pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize);

                        //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint);

                        lastPoint.X = points[5];
                        lastPoint.Y = points[6];
                    }
                    else if (action == 'Z' || action == 'z')
                    {
                        pb.EndFigure(CanvasFigureLoop.Closed);
                    }
                }
                _cg = CanvasGeometry.CreatePath(pb);
            }
            catch (Exception exc)
            {
                Debug.WriteLine(exc.Message);
                Debug.WriteLine(exc.StackTrace);
                
                ErrorLogger.LogException("SVGPath", "parsePath", exc);
            }



        }
Exemple #16
0
        public static CanvasGeometry AsPath(this PathF path, float ox, float oy, float fx, float fy, ICanvasResourceCreator creator, CanvasFilledRegionDetermination fillMode = CanvasFilledRegionDetermination.Winding)
        {
            var builder = new CanvasPathBuilder(creator);

#if DEBUG
            try
            {
#endif
            builder.SetFilledRegionDetermination(fillMode);

            var pointIndex        = 0;
            var arcAngleIndex     = 0;
            var arcClockwiseIndex = 0;
            var figureOpen        = false;
            var segmentIndex      = -1;

            var lastOperation = PathOperation.Move;

            foreach (var type in path.SegmentTypes)
            {
                segmentIndex++;

                if (type == PathOperation.Move)
                {
                    if (lastOperation != PathOperation.Close && lastOperation != PathOperation.Move)
                    {
                        builder.EndFigure(CanvasFigureLoop.Open);
                    }

                    var point = path[pointIndex++];
                    var begin = CanvasFigureFill.Default;
                    builder.BeginFigure(ox + point.X * fx, oy + point.Y * fy, begin);
                    figureOpen = true;
                }
                else if (type == PathOperation.Line)
                {
                    var point = path[pointIndex++];
                    builder.AddLine(ox + point.X * fx, oy + point.Y * fy);
                }

                else if (type == PathOperation.Quad)
                {
                    var controlPoint = path[pointIndex++];
                    var endPoint     = path[pointIndex++];

                    builder.AddQuadraticBezier(
                        new Vector2(ox + controlPoint.X * fx, oy + controlPoint.Y * fy),
                        new Vector2(ox + endPoint.X * fx, oy + endPoint.Y * fy));
                }
                else if (type == PathOperation.Cubic)
                {
                    var controlPoint1 = path[pointIndex++];
                    var controlPoint2 = path[pointIndex++];
                    var endPoint      = path[pointIndex++];
                    builder.AddCubicBezier(
                        new Vector2(ox + controlPoint1.X * fx, oy + controlPoint1.Y * fy),
                        new Vector2(ox + controlPoint2.X * fx, oy + controlPoint2.Y * fy),
                        new Vector2(ox + endPoint.X * fx, oy + endPoint.Y * fy));
                }
                else if (type == PathOperation.Arc)
                {
                    var topLeft     = path[pointIndex++];
                    var bottomRight = path[pointIndex++];
                    var startAngle  = path.GetArcAngle(arcAngleIndex++);
                    var endAngle    = path.GetArcAngle(arcAngleIndex++);
                    var clockwise   = path.GetArcClockwise(arcClockwiseIndex++);

                    while (startAngle < 0)
                    {
                        startAngle += 360;
                    }

                    while (endAngle < 0)
                    {
                        endAngle += 360;
                    }

                    var rotation    = Geometry.GetSweep(startAngle, endAngle, clockwise);
                    var absRotation = Math.Abs(rotation);

                    var rectX      = ox + topLeft.X * fx;
                    var rectY      = oy + topLeft.Y * fy;
                    var rectWidth  = (ox + bottomRight.X * fx) - rectX;
                    var rectHeight = (oy + bottomRight.Y * fy) - rectY;

                    var startPoint = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -startAngle);
                    var endPoint   = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -endAngle);


                    if (!figureOpen)
                    {
                        var begin = CanvasFigureFill.Default;
                        builder.BeginFigure(startPoint.X, startPoint.Y, begin);
                        figureOpen = true;
                    }
                    else
                    {
                        builder.AddLine(startPoint.X, startPoint.Y);
                    }

                    builder.AddArc(
                        new Vector2(endPoint.X, endPoint.Y),
                        rectWidth / 2,
                        rectHeight / 2,
                        0,
                        clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise,
                        absRotation >= 180 ? CanvasArcSize.Large : CanvasArcSize.Small
                        );
                }
                else if (type == PathOperation.Close)
                {
                    builder.EndFigure(CanvasFigureLoop.Closed);
                }

                lastOperation = type;
            }

            if (segmentIndex >= 0 && lastOperation != PathOperation.Close)
            {
                builder.EndFigure(CanvasFigureLoop.Open);
            }

            var geometry = CanvasGeometry.CreatePath(builder);
            return(geometry);

#if DEBUG
        }

        catch (Exception exc)
        {
            builder.Dispose();

            var definition = path.ToDefinitionString();
            Logger.Debug(string.Format("Unable to convert the path to a Win2D Path: {0}", definition), exc);
            return(null);
        }
#endif
        }
Exemple #17
0
        public void VerifySendPathTo()
        {
            //
            // This calls each of the path functions, once, and verfies that it works.
            // Sink behavior is verified in more detail in the geometry unit tests.
            //
            CanvasDevice device = new CanvasDevice();

            CanvasPathBuilder pathBuilder = new CanvasPathBuilder(device);
            pathBuilder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate);
            pathBuilder.BeginFigure(0, 0);
            pathBuilder.AddLine(0, 0);
            pathBuilder.AddQuadraticBezier(new Vector2(), new Vector2());
            pathBuilder.AddCubicBezier(new Vector2(), new Vector2(), new Vector2());

            // D2D tries to be smart about degenerate arcs and redundant set segment options, and may sometimes actually
            // surpress them. Therefore, these calls use non-defaults.
            pathBuilder.AddArc(new Vector2 { X = 100, Y = 100 }, 10, 10, 90, CanvasSweepDirection.Clockwise, CanvasArcSize.Small);
            pathBuilder.SetSegmentOptions(CanvasFigureSegmentOptions.ForceUnstroked);

            pathBuilder.EndFigure(CanvasFigureLoop.Closed);

            CanvasGeometry pathGeometry = CanvasGeometry.CreatePath(pathBuilder);

            MyGeometryStreamReader myStreamReader = new MyGeometryStreamReader();
            pathGeometry.SendPathTo(myStreamReader);

            myStreamReader.Verify();
        }
Exemple #18
0
        /*public override object Clone()
         * {
         *  SVGPath clone = new SVGPath();
         *  clone._gp = (GraphicsPath)_gp.Clone();
         *  clone._ID = _ID;
         *  clone._strPath = (String)_strPath.Clone();
         *  return clone;
         * }*/

        private void parsePath(CanvasPathBuilder pb, String path)
        {
            char[]    delimiter        = { ' ' };
            string[]  commands         = Regex.Split(path, _regex1);
            string[]  values           = null;
            float[]   points           = new float[7];
            Vector2[] Vector2s         = new Vector2[4];
            Vector2   lastPoint        = new Vector2(0, 0);
            Vector2   lastControlPoint = new Vector2(0, 0);

            //Vector2 firstPoint = new Vector2(0, 0);
            //Vector2 firstPoint = new Vector2(0, 0);

            try
            {
                for (int i = 0; i < commands.Length; i++)
                {
                    String strCommand = commands[i];
                    char   action     = (strCommand != null && strCommand.Length > 0) ? strCommand[0] : ' ';
                    values = strCommand.Split(delimiter);

                    if (action == 'M')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        lastPoint = new Vector2(points[0], points[1]);
                        //firstPoint = new Vector2(points[0], points[1]);

                        pb.BeginFigure(lastPoint);
                    }
                    else if (action == 'm')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;

                        pb.BeginFigure(points[0], points[1]);
                        lastPoint.X = points[0];
                        lastPoint.Y = points[1];
                        pb.BeginFigure(lastPoint);
                    }
                    else if (action == 'L')//capital letter is absolute location
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);

                        pb.AddLine(points[0], points[1]);

                        lastPoint.X = points[0];
                        lastPoint.Y = points[1];
                    }
                    else if (action == 'l')//lowercase letter is relative location
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;

                        pb.AddLine(points[0], points[1]);

                        lastPoint.X = points[0];
                        lastPoint.Y = points[1];
                    }
                    else if (action == 'H')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));

                        pb.AddLine(points[0], lastPoint.Y);

                        lastPoint.X = points[0];
                    }
                    else if (action == 'h')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;

                        pb.AddLine(points[0], lastPoint.Y);

                        lastPoint.X = points[0];
                    }
                    else if (action == 'V')
                    {
                        points[0] = -(float)Convert.ToDouble(values[0].Substring(1));

                        pb.AddLine(lastPoint.X, points[0]);

                        lastPoint.Y = points[0];
                    }
                    else if (action == 'v')
                    {
                        points[0] = -(float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.Y;

                        pb.AddLine(lastPoint.X, points[0]);

                        lastPoint.Y = points[0];
                    }
                    else if (action == 'C')//cubic bezier, 2 control points
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = -(float)Convert.ToDouble(values[3]);
                        points[4] = (float)Convert.ToDouble(values[4]);
                        points[5] = -(float)Convert.ToDouble(values[5]);

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = new Vector2(points[0], points[1]);
                        Vector2s[2] = new Vector2(points[2], points[3]);
                        Vector2s[3] = new Vector2(points[4], points[5]);

                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint        = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 'c')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;
                        points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X;
                        points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y;
                        points[4] = (float)Convert.ToDouble(values[4]) + lastPoint.X;
                        points[5] = -(float)Convert.ToDouble(values[5]) + lastPoint.Y;

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = new Vector2(points[0], points[1]);
                        Vector2s[2] = new Vector2(points[2], points[3]);
                        Vector2s[3] = new Vector2(points[4], points[5]);

                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint        = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 'S')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = -(float)Convert.ToDouble(values[3]);

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint);
                        Vector2s[2] = new Vector2(points[0], points[1]);
                        Vector2s[3] = new Vector2(points[2], points[3]);

                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint        = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 's')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;
                        points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X;
                        points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y;

                        Vector2s[0] = lastPoint;
                        Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint);
                        Vector2s[2] = new Vector2(points[0], points[1]);
                        Vector2s[3] = new Vector2(points[2], points[3]);

                        //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]);
                        pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]);

                        lastPoint        = Vector2s[3];
                        lastControlPoint = Vector2s[2];
                    }
                    else if (action == 'Q')//quadratic bezier, 1 control point
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = -(float)Convert.ToDouble(values[3]);


                        //convert quadratic to cubic bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = new Vector2(points[0], points[1]);
                        Vector2 QP2 = new Vector2(points[2], points[3]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //old
                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);

                        //new
                        Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));

                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);

                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 'q')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;
                        points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X;
                        points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y;


                        //convert quadratic to cubic bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = new Vector2(points[0], points[1]);
                        Vector2 QP2 = new Vector2(points[2], points[3]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //old
                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);
                        //new
                        //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));

                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);


                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 'T')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = -(float)Convert.ToDouble(values[1]);

                        //convert quadratic to bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0);
                        Vector2 QP2 = new Vector2(points[0], points[1]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);

                        //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));


                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);


                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 't')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X;
                        points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y;

                        //convert quadratic to bezier
                        Vector2 QP0 = lastPoint;
                        Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0);
                        Vector2 QP2 = new Vector2(points[0], points[1]);

                        Vector2 CP0 = QP0;
                        Vector2 CP3 = QP2;

                        //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f);
                        //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f);

                        //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y));
                        //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y));


                        //_gp.AddBezier(CP0, CP1, CP2, CP3);
                        //pb.AddCubicBezier(CP1, CP2, QP2);
                        pb.AddQuadraticBezier(QP1, QP2);


                        lastPoint = QP2;

                        lastControlPoint = QP1;
                    }
                    else if (action == 'A')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1)); //radiusX
                        points[1] = (float)Convert.ToDouble(values[1]);              //radiusY
                        points[2] = (float)Convert.ToDouble(values[2]);              //angle
                        points[3] = (float)Convert.ToDouble(values[3]);              //size
                        points[4] = (float)Convert.ToDouble(values[4]);              //sweep
                        points[5] = (float)Convert.ToDouble(values[5]);              //endX
                        points[6] = -(float)Convert.ToDouble(values[6]);             //endY

                        //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large;
                        //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive;
                        Vector2 endPoint = new Vector2(points[5], points[6]);

                        //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint);
                        //arc.AddToPath(_gp);

                        CanvasArcSize        arcSize = CanvasArcSize.Large;            //if size = 1, size is large.  0 for small
                        CanvasSweepDirection sweep   = CanvasSweepDirection.Clockwise; //if sweep == 1, sweep is clockwise or positive

                        if (points[3] == 0.0f)
                        {
                            arcSize = CanvasArcSize.Small;
                        }
                        if (points[4] == 0.0f)
                        {
                            sweep = CanvasSweepDirection.CounterClockwise;
                        }

                        pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize);


                        //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint);

                        lastPoint.X = points[5];
                        lastPoint.Y = points[6];
                    }
                    else if (action == 'a')
                    {
                        points[0] = (float)Convert.ToDouble(values[0].Substring(1));
                        points[1] = (float)Convert.ToDouble(values[1]);
                        points[2] = (float)Convert.ToDouble(values[2]);
                        points[3] = (float)Convert.ToDouble(values[3]);
                        points[4] = (float)Convert.ToDouble(values[4]);
                        points[5] = (float)Convert.ToDouble(values[5] + lastPoint.X);
                        points[6] = -(float)Convert.ToDouble(values[6] + lastPoint.Y);

                        //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large;
                        //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive;
                        Vector2 endPoint = new Vector2(points[5], points[6]);

                        //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint);
                        //arc.AddToPath(_gp);

                        CanvasArcSize        arcSize = CanvasArcSize.Large;            //if size = 1, size is large.  0 for small
                        CanvasSweepDirection sweep   = CanvasSweepDirection.Clockwise; //if sweep == 1, sweep is clockwise or positive

                        if (points[3] == 0.0f)
                        {
                            arcSize = CanvasArcSize.Small;
                        }
                        if (points[4] == 0.0f)
                        {
                            sweep = CanvasSweepDirection.CounterClockwise;
                        }

                        pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize);

                        //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint);

                        lastPoint.X = points[5];
                        lastPoint.Y = points[6];
                    }
                    else if (action == 'Z' || action == 'z')
                    {
                        pb.EndFigure(CanvasFigureLoop.Closed);
                    }
                }
                _cg = CanvasGeometry.CreatePath(pb);
            }
            catch (Exception exc)
            {
                Debug.WriteLine(exc.Message);
                Debug.WriteLine(exc.StackTrace);

                ErrorLogger.LogException("SVGPath", "parsePath", exc);
            }
        }
        public static CanvasGeometry ToCanvasGeometry(this XPathGeometry pg, CanvasDrawingSession ds)
        {
            CanvasGeometry g;

            using (var builder = new CanvasPathBuilder(ds))
            {
                if (pg.FillRule == XFillRule.EvenOdd)
                    builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate);
                else
                    builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding);

                foreach (var pf in pg.Figures)
                {
                    builder.BeginFigure(
                        (float)pf.StartPoint.X,
                        (float)pf.StartPoint.Y,
                        pf.IsFilled ? CanvasFigureFill.Default : CanvasFigureFill.DoesNotAffectFills);

                    foreach (var segment in pf.Segments)
                    {
                        var options = CanvasFigureSegmentOptions.None;
                        if (!segment.IsStroked)
                            options |= CanvasFigureSegmentOptions.ForceUnstroked;

                        if (segment.IsSmoothJoin)
                            options |= CanvasFigureSegmentOptions.ForceRoundLineJoin;

                        builder.SetSegmentOptions(options);

                        if (segment is XArcSegment)
                        {
                            var arcSegment = segment as XArcSegment;
                            builder.AddArc(
                                new N.Vector2(
                                    (float)arcSegment.Point.X,
                                    (float)arcSegment.Point.Y),
                                (float)(arcSegment.Size.Width / 2.0),
                                (float)(arcSegment.Size.Height / 2.0),
                                (float)arcSegment.RotationAngle,
                                arcSegment.SweepDirection == XSweepDirection.Clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise,
                                arcSegment.IsLargeArc ? CanvasArcSize.Large : CanvasArcSize.Small);
                        }
                        else if (segment is XBezierSegment)
                        {
                            var bezierSegment = segment as XBezierSegment;
                            builder.AddCubicBezier(
                                new N.Vector2(
                                    (float)bezierSegment.Point1.X,
                                    (float)bezierSegment.Point1.Y),
                                new N.Vector2(
                                    (float)bezierSegment.Point2.X,
                                    (float)bezierSegment.Point2.Y),
                                new N.Vector2(
                                    (float)bezierSegment.Point3.X,
                                    (float)bezierSegment.Point3.Y));
                        }
                        else if (segment is XLineSegment)
                        {
                            var lineSegment = segment as XLineSegment;
                            builder.AddLine(
                                new N.Vector2(
                                    (float)lineSegment.Point.X,
                                    (float)lineSegment.Point.Y));
                        }
                        else if (segment is XPolyBezierSegment)
                        {
                            var polyBezierSegment = segment as XPolyBezierSegment;
                            if (polyBezierSegment.Points.Count >= 3)
                            {
                                builder.AddCubicBezier(
                                    new N.Vector2(
                                        (float)polyBezierSegment.Points[0].X,
                                        (float)polyBezierSegment.Points[0].Y),
                                    new N.Vector2(
                                        (float)polyBezierSegment.Points[1].X,
                                        (float)polyBezierSegment.Points[1].Y),
                                    new N.Vector2(
                                        (float)polyBezierSegment.Points[2].X,
                                        (float)polyBezierSegment.Points[2].Y));
                            }

                            if (polyBezierSegment.Points.Count > 3
                                && polyBezierSegment.Points.Count % 3 == 0)
                            {
                                for (int i = 3; i < polyBezierSegment.Points.Count; i += 3)
                                {
                                    builder.AddCubicBezier(
                                        new N.Vector2(
                                            (float)polyBezierSegment.Points[i].X,
                                            (float)polyBezierSegment.Points[i].Y),
                                        new N.Vector2(
                                            (float)polyBezierSegment.Points[i + 1].X,
                                            (float)polyBezierSegment.Points[i + 1].Y),
                                        new N.Vector2(
                                            (float)polyBezierSegment.Points[i + 2].X,
                                            (float)polyBezierSegment.Points[i + 2].Y));
                                }
                            }
                        }
                        else if (segment is XPolyLineSegment)
                        {
                            var polyLineSegment = segment as XPolyLineSegment;

                            if (polyLineSegment.Points.Count >= 1)
                            {
                                builder.AddLine(
                                    new N.Vector2(
                                        (float)polyLineSegment.Points[0].X,
                                        (float)polyLineSegment.Points[0].Y));
                            }

                            if (polyLineSegment.Points.Count > 1)
                            {
                                for (int i = 1; i < polyLineSegment.Points.Count; i++)
                                {
                                    builder.AddLine(
                                        new N.Vector2(
                                            (float)polyLineSegment.Points[i].X,
                                            (float)polyLineSegment.Points[i].Y));
                                }
                            }
                        }
                        else if (segment is XPolyQuadraticBezierSegment)
                        {
                            var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment;
                            if (polyQuadraticSegment.Points.Count >= 2)
                            {
                                builder.AddQuadraticBezier(
                                    new N.Vector2(
                                        (float)polyQuadraticSegment.Points[0].X,
                                        (float)polyQuadraticSegment.Points[0].Y),
                                    new N.Vector2(
                                        (float)polyQuadraticSegment.Points[1].X,
                                        (float)polyQuadraticSegment.Points[1].Y));
                            }

                            if (polyQuadraticSegment.Points.Count > 2
                                && polyQuadraticSegment.Points.Count % 2 == 0)
                            {
                                for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3)
                                {
                                    builder.AddQuadraticBezier(
                                        new N.Vector2(
                                            (float)polyQuadraticSegment.Points[i].X,
                                            (float)polyQuadraticSegment.Points[i].Y),
                                        new N.Vector2(
                                            (float)polyQuadraticSegment.Points[i + 1].X,
                                            (float)polyQuadraticSegment.Points[i + 1].Y));
                                }
                            }
                        }
                        else if (segment is XQuadraticBezierSegment)
                        {
                            var qbezierSegment = segment as XQuadraticBezierSegment;
                            builder.AddQuadraticBezier(
                                new N.Vector2(
                                    (float)qbezierSegment.Point1.X,
                                    (float)qbezierSegment.Point1.Y),
                                new N.Vector2(
                                    (float)qbezierSegment.Point2.X,
                                    (float)qbezierSegment.Point2.Y));
                        }
                        else
                        {
                            throw new NotSupportedException("Not supported segment type: " + segment.GetType());
                        }
                    }

                    builder.EndFigure(pf.IsClosed ? CanvasFigureLoop.Closed : CanvasFigureLoop.Open);
                }

                g = CanvasGeometry.CreatePath(builder);
            }

            return g;
        }
Exemple #20
0
        public void Draw(object ds, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r)
        {
            var _ds = ds as CanvasDrawingSession;

            double thickness = qbezier.Style.Thickness / _state.Zoom;
            var brush = ToColor(qbezier.Style.Fill);
            var pen = ToColor(qbezier.Style.Stroke);
            var ss = CreateStrokeStyle(qbezier.Style);

            CanvasGeometry g;
            using (var builder = new CanvasPathBuilder(_ds))
            {
                builder.BeginFigure((float)qbezier.Point1.X, (float)qbezier.Point1.Y);
                builder.AddQuadraticBezier(
                    new N.Vector2(
                        (float)qbezier.Point2.X,
                        (float)qbezier.Point2.Y),
                    new N.Vector2(
                        (float)qbezier.Point3.X,
                        (float)qbezier.Point3.Y));
                builder.EndFigure(CanvasFigureLoop.Open);
                g = CanvasGeometry.CreatePath(builder);
            }

            if (qbezier.IsFilled)
            {
                _ds.FillGeometry(g, brush);
            }

            if (qbezier.IsStroked)
            {
                _ds.DrawGeometry(g, pen, (float)thickness, ss);
            }

            g.Dispose();
            ss.Dispose();
        }
Exemple #21
0
        public static CanvasGeometry ToCanvasGeometry(this XPathGeometry pg, CanvasDrawingSession ds)
        {
            CanvasGeometry g;

            using (var builder = new CanvasPathBuilder(ds))
            {
                if (pg.FillRule == XFillRule.EvenOdd)
                {
                    builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate);
                }
                else
                {
                    builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding);
                }

                foreach (var pf in pg.Figures)
                {
                    builder.BeginFigure(
                        (float)pf.StartPoint.X,
                        (float)pf.StartPoint.Y,
                        pf.IsFilled ? CanvasFigureFill.Default : CanvasFigureFill.DoesNotAffectFills);

                    foreach (var segment in pf.Segments)
                    {
                        var options = CanvasFigureSegmentOptions.None;
                        if (!segment.IsStroked)
                        {
                            options |= CanvasFigureSegmentOptions.ForceUnstroked;
                        }

                        if (segment.IsSmoothJoin)
                        {
                            options |= CanvasFigureSegmentOptions.ForceRoundLineJoin;
                        }

                        builder.SetSegmentOptions(options);

                        if (segment is XArcSegment)
                        {
                            var arcSegment = segment as XArcSegment;
                            builder.AddArc(
                                new N.Vector2(
                                    (float)arcSegment.Point.X,
                                    (float)arcSegment.Point.Y),
                                (float)(arcSegment.Size.Width / 2.0),
                                (float)(arcSegment.Size.Height / 2.0),
                                (float)arcSegment.RotationAngle,
                                arcSegment.SweepDirection == XSweepDirection.Clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise,
                                arcSegment.IsLargeArc ? CanvasArcSize.Large : CanvasArcSize.Small);
                        }
                        else if (segment is XBezierSegment)
                        {
                            var bezierSegment = segment as XBezierSegment;
                            builder.AddCubicBezier(
                                new N.Vector2(
                                    (float)bezierSegment.Point1.X,
                                    (float)bezierSegment.Point1.Y),
                                new N.Vector2(
                                    (float)bezierSegment.Point2.X,
                                    (float)bezierSegment.Point2.Y),
                                new N.Vector2(
                                    (float)bezierSegment.Point3.X,
                                    (float)bezierSegment.Point3.Y));
                        }
                        else if (segment is XLineSegment)
                        {
                            var lineSegment = segment as XLineSegment;
                            builder.AddLine(
                                new N.Vector2(
                                    (float)lineSegment.Point.X,
                                    (float)lineSegment.Point.Y));
                        }
                        else if (segment is XPolyBezierSegment)
                        {
                            var polyBezierSegment = segment as XPolyBezierSegment;
                            if (polyBezierSegment.Points.Count >= 3)
                            {
                                builder.AddCubicBezier(
                                    new N.Vector2(
                                        (float)polyBezierSegment.Points[0].X,
                                        (float)polyBezierSegment.Points[0].Y),
                                    new N.Vector2(
                                        (float)polyBezierSegment.Points[1].X,
                                        (float)polyBezierSegment.Points[1].Y),
                                    new N.Vector2(
                                        (float)polyBezierSegment.Points[2].X,
                                        (float)polyBezierSegment.Points[2].Y));
                            }

                            if (polyBezierSegment.Points.Count > 3 &&
                                polyBezierSegment.Points.Count % 3 == 0)
                            {
                                for (int i = 3; i < polyBezierSegment.Points.Count; i += 3)
                                {
                                    builder.AddCubicBezier(
                                        new N.Vector2(
                                            (float)polyBezierSegment.Points[i].X,
                                            (float)polyBezierSegment.Points[i].Y),
                                        new N.Vector2(
                                            (float)polyBezierSegment.Points[i + 1].X,
                                            (float)polyBezierSegment.Points[i + 1].Y),
                                        new N.Vector2(
                                            (float)polyBezierSegment.Points[i + 2].X,
                                            (float)polyBezierSegment.Points[i + 2].Y));
                                }
                            }
                        }
                        else if (segment is XPolyLineSegment)
                        {
                            var polyLineSegment = segment as XPolyLineSegment;

                            if (polyLineSegment.Points.Count >= 1)
                            {
                                builder.AddLine(
                                    new N.Vector2(
                                        (float)polyLineSegment.Points[0].X,
                                        (float)polyLineSegment.Points[0].Y));
                            }

                            if (polyLineSegment.Points.Count > 1)
                            {
                                for (int i = 1; i < polyLineSegment.Points.Count; i++)
                                {
                                    builder.AddLine(
                                        new N.Vector2(
                                            (float)polyLineSegment.Points[i].X,
                                            (float)polyLineSegment.Points[i].Y));
                                }
                            }
                        }
                        else if (segment is XPolyQuadraticBezierSegment)
                        {
                            var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment;
                            if (polyQuadraticSegment.Points.Count >= 2)
                            {
                                builder.AddQuadraticBezier(
                                    new N.Vector2(
                                        (float)polyQuadraticSegment.Points[0].X,
                                        (float)polyQuadraticSegment.Points[0].Y),
                                    new N.Vector2(
                                        (float)polyQuadraticSegment.Points[1].X,
                                        (float)polyQuadraticSegment.Points[1].Y));
                            }

                            if (polyQuadraticSegment.Points.Count > 2 &&
                                polyQuadraticSegment.Points.Count % 2 == 0)
                            {
                                for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3)
                                {
                                    builder.AddQuadraticBezier(
                                        new N.Vector2(
                                            (float)polyQuadraticSegment.Points[i].X,
                                            (float)polyQuadraticSegment.Points[i].Y),
                                        new N.Vector2(
                                            (float)polyQuadraticSegment.Points[i + 1].X,
                                            (float)polyQuadraticSegment.Points[i + 1].Y));
                                }
                            }
                        }
                        else if (segment is XQuadraticBezierSegment)
                        {
                            var qbezierSegment = segment as XQuadraticBezierSegment;
                            builder.AddQuadraticBezier(
                                new N.Vector2(
                                    (float)qbezierSegment.Point1.X,
                                    (float)qbezierSegment.Point1.Y),
                                new N.Vector2(
                                    (float)qbezierSegment.Point2.X,
                                    (float)qbezierSegment.Point2.Y));
                        }
                        else
                        {
                            throw new NotSupportedException("Not supported segment type: " + segment.GetType());
                        }
                    }

                    builder.EndFigure(pf.IsClosed ? CanvasFigureLoop.Closed : CanvasFigureLoop.Open);
                }

                g = CanvasGeometry.CreatePath(builder);
            }

            return(g);
        }
        CanvasGeometry BuildGeometry(ICanvasResourceCreator resourceCreator, Geometry geometry)
        {
            CanvasGeometry canvasGeometry = null;

            // Determine what type of geometry we're dealing with.
            if (geometry is RectangleGeometry)
            {
                Rect          xamRect = (geometry as RectangleGeometry).Rect;
                winFound.Rect winRect = new winFound.Rect(xamRect.X, xamRect.Y, xamRect.Width, xamRect.Height);
                canvasGeometry = CanvasGeometry.CreateRectangle(resourceCreator, winRect);
            }

            else if (geometry is EllipseGeometry)
            {
                EllipseGeometry ellipseGeometry = geometry as EllipseGeometry;
                Vector2         center          = ConvertPoint(ellipseGeometry.Center);
                canvasGeometry = CanvasGeometry.CreateEllipse(resourceCreator, center, (float)ellipseGeometry.RadiusX, (float)ellipseGeometry.RadiusY);
            }

            else if (geometry is GeometryGroup)
            {
                GeometryGroup         geometryGroup = geometry as GeometryGroup;
                List <CanvasGeometry> geometries    = new List <CanvasGeometry>();

                foreach (Geometry geometryChild in geometryGroup.Children)
                {
                    geometries.Add(BuildGeometry(resourceCreator, geometryChild));
                }

                canvasGeometry = CanvasGeometry.CreateGroup(resourceCreator, geometries.ToArray(), (CanvasFilledRegionDetermination)(int)geometryGroup.FillRule);
            }

            else
            {
                using (CanvasPathBuilder pathBuilder = new CanvasPathBuilder(resourceCreator))
                {
                    // Determine what type of geometry we're dealing with.
                    if (geometry is LineGeometry)
                    {
                        LineGeometry lineGeometry = geometry as LineGeometry;
                        pathBuilder.BeginFigure(ConvertPoint(lineGeometry.StartPoint), CanvasFigureFill.Default);
                        pathBuilder.AddLine(ConvertPoint(lineGeometry.EndPoint));
                        pathBuilder.EndFigure(CanvasFigureLoop.Open);
                    }

                    else if (geometry is PathGeometry)
                    {
                        PathGeometry pathGeometry = geometry as PathGeometry;
                        pathBuilder.SetFilledRegionDetermination((CanvasFilledRegionDetermination)(int)pathGeometry.FillRule);

                        foreach (PathFigure pathFigure in pathGeometry.Figures)
                        {
                            // TODO: Check this logic!
                            pathBuilder.BeginFigure(ConvertPoint(pathFigure.StartPoint),
                                                    pathFigure.IsFilled ? CanvasFigureFill.Default : CanvasFigureFill.DoesNotAffectFills);

                            foreach (PathSegment pathSegment in pathFigure.Segments)
                            {
                                // LineSegment
                                if (pathSegment is LineSegment)
                                {
                                    pathBuilder.AddLine(ConvertPoint((pathSegment as LineSegment).Point));
                                }

                                // PolylineSegment
                                else if (pathSegment is PolyLineSegment)
                                {
                                    foreach (Point point in (pathSegment as PolyLineSegment).Points)
                                    {
                                        pathBuilder.AddLine(ConvertPoint(point));
                                    }
                                }

                                // BezierSegment
                                else if (pathSegment is BezierSegment)
                                {
                                    BezierSegment bezierSegment = pathSegment as BezierSegment;

                                    pathBuilder.AddCubicBezier(ConvertPoint(bezierSegment.Point1),
                                                               ConvertPoint(bezierSegment.Point2),
                                                               ConvertPoint(bezierSegment.Point3));
                                }

                                // PolyBezierSegment
                                else if (pathSegment is PolyBezierSegment)
                                {
                                    PointCollection points = (pathSegment as PolyBezierSegment).Points;

                                    for (int i = 0; i < points.Count; i += 3)
                                    {
                                        pathBuilder.AddCubicBezier(ConvertPoint(points[i + 0]),
                                                                   ConvertPoint(points[i + 1]),
                                                                   ConvertPoint(points[i + 2]));
                                    }
                                }

                                // QuadraticBezierSegment
                                else if (pathSegment is QuadraticBezierSegment)
                                {
                                    QuadraticBezierSegment quadSegment = pathSegment as QuadraticBezierSegment;

                                    pathBuilder.AddQuadraticBezier(ConvertPoint(quadSegment.Point1),
                                                                   ConvertPoint(quadSegment.Point2));
                                }

                                // PolyQuadraticBezierSegment
                                else if (pathSegment is PolyQuadraticBezierSegment)
                                {
                                    PointCollection points = (pathSegment as PolyQuadraticBezierSegment).Points;

                                    for (int i = 0; i < points.Count; i += 2)
                                    {
                                        pathBuilder.AddQuadraticBezier(ConvertPoint(points[i + 0]),
                                                                       ConvertPoint(points[i + 1]));
                                    }
                                }

                                // ArcSegment
                                else if (pathSegment is ArcSegment)
                                {
                                    ArcSegment arcSegment = pathSegment as ArcSegment;

                                    pathBuilder.AddArc(ConvertPoint(arcSegment.Point),
                                                       (float)arcSegment.Size.Width,
                                                       (float)arcSegment.Size.Height,
                                                       (float)arcSegment.RotationAngle,
                                                       (CanvasSweepDirection)(int)arcSegment.SweepDirection,
                                                       arcSegment.IsLargeArc ? CanvasArcSize.Large : CanvasArcSize.Small);
                                }
                            }

                            pathBuilder.EndFigure(pathFigure.IsClosed ? CanvasFigureLoop.Closed : CanvasFigureLoop.Open);
                        }
                    }

                    else
                    {
                        return(null);
                    }

                    canvasGeometry = CanvasGeometry.CreatePath(pathBuilder);
                }
            }

            // Set transform
            if (geometry.Transform != null)
            {
                canvasGeometry = canvasGeometry.Transform((Matrix3x2)geometry.Transform.GetNativeObject());
            }

            return(canvasGeometry);
        }