private SvgPointF getPrevPoint()
 {
     SvgPathSeg prevSeg = PreviousSeg;
     SvgPointF prevPoint;
     if(prevSeg == null)
     {
         prevPoint = new SvgPointF(0,0);
     }
     else
     {
         prevPoint = prevSeg.AbsXY;
     }
     return prevPoint;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="SvgTransformF"/> class 
        /// to the geometric transform defined by the specified rectangle and 
        /// array of points.
        /// </summary>
        /// <param name="rect">
        /// A <see cref="SvgRectF"/> structure that represents the rectangle 
        /// to be transformed.
        /// </param>
        /// <param name="plgpts">
        /// An array of three <see cref="SvgPointF"/> structures that represents the 
        /// points of a parallelogram to which the upper-left, upper-right, and 
        /// lower-left corners of the rectangle is to be transformed. The 
        /// lower-right corner of the parallelogram is implied by the first three 
        /// corners.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// If the <paramref name="plgpts"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If the length of the <paramref name="plgpts"/> array is not equal
        /// to 3.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// If the width or height of the <paramref name="rect"/> is zero.
        /// </exception>
        public SvgTransformF(SvgRectF rect, SvgPointF[] plgpts)
        {
            if (plgpts == null)
            {
                throw new ArgumentNullException("plgpts");
            }
            if (plgpts.Length != 3)
            {
                throw new ArgumentException("plgpts");
            }

            if ((rect.Width == 0) || (rect.Height == 0))
            {
                throw new ArgumentOutOfRangeException("rect");
            }

            MapRectToRect(rect, plgpts);
        }
Exemple #3
0
        public void RenderMarker0(WpfDrawingRenderer renderer, WpfDrawingContext gr,
                                  SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            //PathGeometry g;
            //g.GetPointAtFractionLength(

            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start;
            int         len;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }

            for (int i = start; i < start + len; i++)
            {
                SvgPointF point = vertexPositions[i];

                Matrix m = GetTransformMatrix(_svgElement);

                //GraphicsContainer gc = gr.BeginContainer();

                this.BeforeRender(renderer);

                //gr.TranslateTransform(point.X, point.Y);

                //PAUL:
                //m.Translate(point.X, point.Y);

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    m.Rotate(markerElm.OrientAngle.AnimVal.Value);
                    //gr.RotateTransform((double)markerElm.OrientAngle.AnimVal.Value);
                }
                else
                {
                    double angle;

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i + 1);
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i);
                        break;
                    }
                    //gr.RotateTransform(angle);
                    m.Rotate(angle);
                }

                if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    string propValue = refElement.GetPropertyValue("stroke-width");
                    if (propValue.Length == 0)
                    {
                        propValue = "1";
                    }

                    SvgLength strokeWidthLength = new SvgLength("stroke-width", propValue, refElement, SvgLengthDirection.Viewport);
                    double    strokeWidth       = strokeWidthLength.Value;
                    //gr.ScaleTransform(strokeWidth, strokeWidth);
                    m.Scale(strokeWidth, strokeWidth);
                }

                SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal;
                double[] translateAndScale  = spar.FitToViewBox(
                    (SvgRect)markerElm.ViewBox.AnimVal, new SvgRect(0, 0,
                                                                    markerElm.MarkerWidth.AnimVal.Value, markerElm.MarkerHeight.AnimVal.Value));


                //PAUL:
                //m.Translate(-(double)markerElm.RefX.AnimVal.Value * translateAndScale[2], -(double)markerElm.RefY.AnimVal.Value * translateAndScale[3]);

                //PAUL:
                m.Scale(translateAndScale[2], translateAndScale[3]);
                m.Translate(point.X, point.Y);

                //Matrix oldTransform = TransformMatrix;
                //TransformMatrix = m;
                //try
                //{
                //newTransform.Append(m);
                //TransformGroup tg = new TransformGroup();

                //renderer.Canvas.re

                //gr.TranslateTransform(
                //    -(double)markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -(double)markerElm.RefY.AnimVal.Value * translateAndScale[3]
                //    );

                //gr.ScaleTransform(translateAndScale[2], translateAndScale[3]);

                renderer.RenderChildren(markerElm);
                //                markerElm.RenderChildren(renderer);
                //}
                //finally
                //{
                //    TransformMatrix = oldTransform;
                //}
                //    //gr.EndContainer(gc);

                _matrix = m;
                this.Render(renderer);

                //gr.EndContainer(gc);

                this.AfterRender(renderer);
            }
        }
Exemple #4
0
        public void RenderMarker(WpfDrawingRenderer renderer, WpfDrawingContext gr,
                                 SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start           = 0;
            int         len             = 0;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }
            int end = start + len;

            TransformGroup transform = new TransformGroup();

            for (int i = start; i < end; i++)
            {
                SvgPointF point = vertexPositions[i];

                //GdiGraphicsContainer gc = gr.BeginContainer();

                this.BeforeRender(renderer);

                //Matrix matrix = Matrix.Identity;

                Matrix matrix = GetTransformMatrix(_svgElement, transform);

                ISvgAnimatedEnumeration orientType = _markerElement.OrientType;

                if (orientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    double scaleValue = _markerElement.OrientAngle.AnimVal.Value;
                    if (!scaleValue.Equals(0))
                    {
                        matrix.Rotate(scaleValue);
                        transform.Children.Add(new RotateTransform(scaleValue));
                    }
                }
                else
                {
                    bool isAutoReverse = orientType.AnimVal.Equals((ushort)SvgMarkerOrient.AutoStartReverse);

                    double angle = 0;
                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i);
                        //angle = markerHostElm.GetStartAngle(i + 1);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start];
                            SvgPointF pMarkerPoint2 = vertexPositions[end];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        // A value of 'auto-start-reverse' means the same as 'auto' except that for a
                        // marker placed by 'marker-start', the orientation is 180° different from
                        // the orientation as determined by 'auto'.
                        if (isAutoReverse)
                        {
                            angle += 180;
                        }
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i - 1);
                        //angle = markerHostElm.GetEndAngle(i);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start - 1];
                            SvgPointF pMarkerPoint2 = vertexPositions[start];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        break;
                    }
                    matrix.Rotate(angle);
                    transform.Children.Add(new RotateTransform(angle));
                }

                // 'viewBox' and 'preserveAspectRatio' attributes
                // viewBox -> viewport(0, 0, markerWidth, markerHeight)
                SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)_markerElement.PreserveAspectRatio.AnimVal;
                double[] translateAndScale  = spar.FitToViewBox((SvgRect)_markerElement.ViewBox.AnimVal,
                                                                new SvgRect(0, 0, _markerElement.MarkerWidth.AnimVal.Value, _markerElement.MarkerHeight.AnimVal.Value));

                // Warning at this time, refX and refY are relative to the painted element's coordinate system.
                // We need to move the reference point to the marker's coordinate system
                double refX = _markerElement.RefX.AnimVal.Value;
                double refY = _markerElement.RefY.AnimVal.Value;

                if (!(refX.Equals(0) && refY.Equals(0)))
                {
                    var ptRef = matrix.Transform(new Point(refX, refY));

                    refX = ptRef.X;
                    refY = ptRef.Y;

                    matrix.Translate(-refX, -refY);
                    transform.Children.Add(new TranslateTransform(-refX, -refY));
                }

                //matrix.Translate(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -markerElm.RefY.AnimVal.Value * translateAndScale[3]);
                //transform.Children.Add(new TranslateTransform(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -markerElm.RefY.AnimVal.Value * translateAndScale[3]));

                // compute an additional transform for 'strokeWidth' coordinate system
                ISvgAnimatedEnumeration markerUnits = _markerElement.MarkerUnits;
                if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                    double strokeWidth = strokeWidthLength.Value;
                    if (!strokeWidth.Equals(1))
                    {
                        matrix.Scale(strokeWidth, strokeWidth);
                        transform.Children.Add(new ScaleTransform(strokeWidth, strokeWidth));
                    }
                }

                if (!(translateAndScale[2].Equals(1) && translateAndScale[3].Equals(1)))
                {
                    matrix.Scale(translateAndScale[2], translateAndScale[3]);
                    transform.Children.Add(new ScaleTransform(translateAndScale[2], translateAndScale[3]));
                }

                matrix.Translate(point.X, point.Y);
                transform.Children.Add(new TranslateTransform(point.X, point.Y));

                _matrix = matrix;

                this.Transform = transform;

                this.Render(renderer);

                //Clip(gr);

                renderer.RenderChildren(_markerElement);

                //gr.EndContainer(gc);

                this.AfterRender(renderer);
            }
        }
        private double GetAngleAt(int index, double angle, SvgMarkerPosition position, ISharpMarkerHost markerHost)
        {
            if (markerHost == null || _pathFigures == null || _pathFigures.Count == 0)
            {
                return(angle);
            }
            var marker = markerHost.GetMarker(index + 1);

            PathGeometry pathFlattened = null;

            if (_pathFigures.Count != 1)
            {
                if (index < _pathFigures.Count)
                {
                    PathGeometry path = new PathGeometry(new PathFigure[] { _pathFigures[index] });
                    pathFlattened = path.GetFlattenedPathGeometry();
                }
            }
            else
            {
                PathFigure figureAt = _pathFigures[0];

                if (figureAt.Segments.Count == 1)
                {
                    PathGeometry path = new PathGeometry(new PathFigure[] { figureAt });
                    pathFlattened = path.GetFlattenedPathGeometry();
                }
                else
                {
                    if (marker.IsCurve == false)
                    {
                        return(angle);
                    }

                    if (index < figureAt.Segments.Count)
                    {
                        var pathSegment = figureAt.Segments[index];

                        Point startPoint = new Point(0, 0);
                        if (marker != null)
                        {
                            var pathSet = marker.Segment;

                            if (pathSet != null && pathSet.Limits != null && pathSet.Limits.Length == 2)
                            {
                                SvgPointF point = pathSet.Limits[0];
                                startPoint = new Point(point.ValueX, point.ValueY);
                            }
                        }

                        PathFigure   targetFigure = new PathFigure(startPoint, new PathSegment[] { pathSegment }, false);
                        PathGeometry path         = new PathGeometry(new PathFigure[] { targetFigure });
                        pathFlattened = path.GetFlattenedPathGeometry();
                    }
                }
            }

            if (pathFlattened != null)
            {
                double progress = 1;
                switch (position)
                {
                case SvgMarkerPosition.End:
                    progress = 1;
                    break;

                case SvgMarkerPosition.Start:
                    progress = 0;
                    break;

                case SvgMarkerPosition.Mid:
                    progress = 0;
                    break;
                }
                Point locationAt;
                Point tagentAt;

                pathFlattened.GetPointAtFractionLength(progress, out locationAt, out tagentAt);

                return(Math.Atan2(tagentAt.Y, tagentAt.X) * 180 / Math.PI);
            }

            return(angle);
        }
        private void MapRectToRect(SvgRectF rect, SvgPointF[] plgpts)
        {
            SvgPointF pt1 = new SvgPointF(plgpts[1].X - plgpts[0].X,
                            plgpts[1].Y - plgpts[0].Y);
            SvgPointF pt2 = new SvgPointF(plgpts[2].X - plgpts[0].X,
                            plgpts[2].Y - plgpts[0].Y);

            this.m11 = pt1.X / rect.Width;
            this.m12 = pt1.Y / rect.Width;
            this.m21 = pt2.X / rect.Height;
            this.m22 = pt2.Y / rect.Height;
            this.dx = plgpts[0].X - rect.X / rect.Width * pt1.X - rect.Y / rect.Height * pt2.X;
            this.dy = plgpts[0].Y - rect.X / rect.Width * pt1.Y - rect.Y / rect.Height * pt2.Y;
        }
        /// <summary>
        /// Multiplies each vector in an array by the matrix. The translation 
        /// elements of this matrix (third row) are ignored.
        /// </summary>
        /// <param name="pts">
        /// An array of <see cref="SvgPointF"/> structures that represents the points 
        /// to transform.
        /// </param>
        public void TransformVectors(SvgPointF[] pts)
        {
            if (pts == null)
            {
                throw new ArgumentNullException("pts");
            }

            int nLength = pts.Length;

            for (int i = nLength - 1; i >= 0; --i)
            {
                float x  = pts[i].X;
                float y  = pts[i].Y;
                pts[i].ValueX = x * m11 + y * m21;
                pts[i].ValueY = x * m12 + y * m22;
            }
        }
Exemple #8
0
        public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphicsWrapper gr,
                                SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)element;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start;
            int         len;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }

            for (int i = start; i < start + len; i++)
            {
                SvgPointF point = vertexPositions[i];

                GdiGraphicsContainer gc = gr.BeginContainer();

                gr.TranslateTransform(point.X, point.Y);

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    gr.RotateTransform((float)markerElm.OrientAngle.AnimVal.Value);
                }
                else
                {
                    double angle;

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i + 1);
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i);
                        break;
                    }
                    gr.RotateTransform((float)angle);
                }

                if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                    float strokeWidth = (float)strokeWidthLength.Value;
                    gr.ScaleTransform(strokeWidth, strokeWidth);
                }

                SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal;
                double[] translateAndScale  = spar.FitToViewBox((SvgRect)markerElm.ViewBox.AnimVal,
                                                                new SvgRect(0, 0, markerElm.MarkerWidth.AnimVal.Value,
                                                                            markerElm.MarkerHeight.AnimVal.Value));


                gr.TranslateTransform(-(float)(markerElm.RefX.AnimVal.Value * translateAndScale[2]),
                                      -(float)(markerElm.RefY.AnimVal.Value * translateAndScale[3]));

                gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]);

                Clip(gr);

                renderer.RenderChildren(markerElm);

                gr.EndContainer(gc);
            }
        }
 /// <overloads>
 /// Applies a clockwise rotation about the specified point to this 
 /// <see cref="SvgTransformF"/> by appending or prepending the rotation.
 /// </overloads>
 /// <summary>
 /// Applies a clockwise rotation about the specified point to this 
 /// <see cref="SvgTransformF"/> by prepending the rotation.
 /// </summary>
 /// <param name="angle">
 /// The angle (extent) of the rotation, in degrees.
 /// </param>
 /// <param name="point">
 /// A <see cref="SvgPointF"/> that represents the center of the rotation.
 /// </param>
 public void RotateAt(float angle, SvgPointF point)
 {
     Translate(point.X, point.Y);
     Rotate(angle);
     Translate(-point.X, -point.Y);
 }
        public static GraphicsPath CreatePath(SvgPathElement element)
        {
            GraphicsPath gp = new GraphicsPath();

            SvgPointF initPoint = new SvgPointF(0, 0);
            SvgPointF lastPoint = new SvgPointF(0, 0);

            ISvgPathSeg segment = null;
            SvgPathSegMoveto pathMoveTo = null;
            SvgPathSegLineto pathLineTo = null;
            SvgPathSegCurveto pathCurveTo = null;
            SvgPathSegArc pathArc = null;

            ISvgPathSegList segments = element.PathSegList;
            int nElems = segments.NumberOfItems;

            for (int i = 0; i < nElems; i++)
            {
                segment = segments.GetItem(i);

                if (DynamicCast.Cast(segment, out pathMoveTo))
                {
                    //SvgPathSegMoveto seg = (SvgPathSegMoveto)segment;
                    gp.StartFigure();
                    lastPoint = initPoint = pathMoveTo.AbsXY;
                }
                else if (DynamicCast.Cast(segment, out pathLineTo))
                {
                    //SvgPathSegLineto seg = (SvgPathSegLineto)segment;
                    SvgPointF p = pathLineTo.AbsXY;
                    gp.AddLine(lastPoint.X, lastPoint.Y, p.X, p.Y);

                    lastPoint = p;
                }
                else if (DynamicCast.Cast(segment, out pathCurveTo))
                {
                    // SvgPathSegCurveto seg = (SvgPathSegCurveto)segment;
                    SvgPointF xy = pathCurveTo.AbsXY;
                    SvgPointF x1y1 = pathCurveTo.CubicX1Y1;
                    SvgPointF x2y2 = pathCurveTo.CubicX2Y2;
                    gp.AddBezier(lastPoint.X, lastPoint.Y, x1y1.X, x1y1.Y, x2y2.X, x2y2.Y, xy.X, xy.Y);

                    lastPoint = xy;
                }
                else if (DynamicCast.Cast(segment, out pathArc))
                {
                    //SvgPathSegArc seg = (SvgPathSegArc)segment;
                    SvgPointF p = pathArc.AbsXY;
                    if (lastPoint.Equals(p))
                    {
                        // If the endpoints (x, y) and (x0, y0) are identical, then this
                        // is equivalent to omitting the elliptical arc segment entirely.
                    }
                    else if (pathArc.R1 == 0 || pathArc.R2 == 0)
                    {
                        // Ensure radii are valid
                        gp.AddLine(lastPoint.X, lastPoint.Y, p.X, p.Y);
                    }
                    else
                    {
                        CalculatedArcValues calcValues = pathArc.GetCalculatedArcValues();

                        GraphicsPath gp2 = new GraphicsPath();
                        gp2.StartFigure();
                        gp2.AddArc((float)(calcValues.Cx - calcValues.CorrRx),
                            (float)(calcValues.Cy - calcValues.CorrRy),
                            (float)calcValues.CorrRx * 2, (float)calcValues.CorrRy * 2,
                            (float)calcValues.AngleStart, (float)calcValues.AngleExtent);

                        Matrix matrix = new Matrix();
                        matrix.Translate(-(float)calcValues.Cx, -(float)calcValues.Cy);
                        gp2.Transform(matrix);

                        matrix = new Matrix();
                        matrix.Rotate((float)pathArc.Angle);
                        gp2.Transform(matrix);

                        matrix = new Matrix();
                        matrix.Translate((float)calcValues.Cx, (float)calcValues.Cy);
                        gp2.Transform(matrix);

                        gp.AddPath(gp2, true);
                    }

                    lastPoint = p;
                }
                else if (segment is SvgPathSegClosePath)
                {
                    gp.CloseFigure();
                    lastPoint = initPoint;
                }
            }

            string fillRule = element.GetPropertyValue("fill-rule");
            if (fillRule == "evenodd")
                gp.FillMode = FillMode.Alternate;
            else
                gp.FillMode = FillMode.Winding;

            return gp;
        }
Exemple #11
0
        public Geometry CreateGeometry(SvgPathElement element)
        {
            PathGeometry geometry = new PathGeometry();

            var    comparer = StringComparison.OrdinalIgnoreCase;
            string fillRule = element.GetPropertyValue("fill-rule");
            string clipRule = element.GetAttribute("clip-rule");

            if (!string.IsNullOrWhiteSpace(clipRule) && string.Equals(clipRule, "evenodd", comparer) ||
                string.Equals(clipRule, CssConstants.ValNonzero, comparer))
            {
                fillRule = clipRule;
            }
            if (string.Equals(fillRule, "evenodd", comparer))
            {
                geometry.FillRule = FillRule.EvenOdd;
            }
            else if (string.Equals(fillRule, CssConstants.ValNonzero, comparer))
            {
                geometry.FillRule = FillRule.Nonzero;
            }

            SvgPointF initPoint = new SvgPointF(0, 0);
            SvgPointF lastPoint = new SvgPointF(0, 0);
            SvgPointF ptXY      = new SvgPointF(0, 0);

            SvgPathSeg        segment     = null;
            SvgPathSegMoveto  pathMoveTo  = null;
            SvgPathSegLineto  pathLineTo  = null;
            SvgPathSegCurveto pathCurveTo = null;
            SvgPathSegArc     pathArc     = null;

            SvgPathSegList segments = element.PathSegList;
            int            numSegs  = segments.NumberOfItems;

            if (numSegs == 0)
            {
                return(geometry);
            }

            PathFigure pathFigure = null;

            for (int i = 0; i < numSegs; i++)
            {
                segment = segments.GetItem(i);

                switch (segment.PathType)
                {
                case SvgPathType.MoveTo:     //if (DynamicCast.Cast(segment, out pathMoveTo))
                    pathMoveTo = (SvgPathSegMoveto)segment;
                    if (pathFigure != null)
                    {
                        pathFigure.IsClosed = false;
                        pathFigure.IsFilled = true;
                        geometry.Figures.Add(pathFigure);
                        pathFigure = null;
                    }

                    lastPoint = initPoint = pathMoveTo.AbsXY;

                    pathFigure            = new PathFigure();
                    pathFigure.StartPoint = new Point(initPoint.ValueX, initPoint.ValueY);
                    break;

                case SvgPathType.LineTo:     //else if (DynamicCast.Cast(segment, out pathLineTo))
                    pathLineTo = (SvgPathSegLineto)segment;
                    ptXY       = pathLineTo.AbsXY;
                    pathFigure.Segments.Add(new LineSegment(new Point(ptXY.ValueX, ptXY.ValueY), true));

                    lastPoint = ptXY;
                    break;

                case SvgPathType.CurveTo:     //else if (DynamicCast.Cast(segment, out pathCurveTo))
                    pathCurveTo = (SvgPathSegCurveto)segment;

                    SvgPointF xy   = pathCurveTo.AbsXY;
                    SvgPointF x1y1 = pathCurveTo.CubicX1Y1;
                    SvgPointF x2y2 = pathCurveTo.CubicX2Y2;
                    pathFigure.Segments.Add(new BezierSegment(new Point(x1y1.ValueX, x1y1.ValueY),
                                                              new Point(x2y2.ValueX, x2y2.ValueY), new Point(xy.ValueX, xy.ValueY), true));

                    lastPoint = xy;
                    break;

                case SvgPathType.ArcTo:     //else if (DynamicCast.Cast(segment, out pathArc))
                    pathArc = (SvgPathSegArc)segment;
                    ptXY    = pathArc.AbsXY;
                    if (lastPoint.Equals(ptXY))
                    {
                        // If the endpoints (x, y) and (x0, y0) are identical, then this
                        // is equivalent to omitting the elliptical arc segment entirely.
                    }
                    else if (pathArc.R1.Equals(0) || pathArc.R2.Equals(0))
                    {
                        // Ensure radii are valid
                        pathFigure.Segments.Add(new LineSegment(new Point(ptXY.ValueX, ptXY.ValueY), true));
                    }
                    else
                    {
                        CalculatedArcValues calcValues = pathArc.GetCalculatedArcValues();

                        pathFigure.Segments.Add(new ArcSegment(new Point(ptXY.ValueX, ptXY.ValueY),
                                                               new Size(pathArc.R1, pathArc.R2), pathArc.Angle, pathArc.LargeArcFlag,
                                                               pathArc.SweepFlag ? SweepDirection.Clockwise : SweepDirection.Counterclockwise,
                                                               true));
                    }

                    lastPoint = ptXY;
                    break;

                case SvgPathType.Close:    //else if (segment is SvgPathSegClosePath)
                    if (pathFigure != null)
                    {
                        pathFigure.IsClosed = true;
                        pathFigure.IsFilled = true;
                        geometry.Figures.Add(pathFigure);
                        pathFigure = null;
                    }

                    lastPoint = initPoint;
                    break;
                }
            }

            if (pathFigure != null)
            {
                pathFigure.IsClosed = false;
                pathFigure.IsFilled = true;
                geometry.Figures.Add(pathFigure);
            }

            return(geometry);
        }
Exemple #12
0
        public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphics gr,
                                SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            if (vertexPositions == null)
            {
                return;
            }
            var comparer = StringComparison.OrdinalIgnoreCase;

            bool mayHaveCurves = markerHostElm.MayHaveCurves;
            int  start;
            int  len;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }
            int end = start + len;

            for (int i = start; i < end; i++)
            {
                SvgPointF point = vertexPositions[i];

                GdiGraphicsContainer gc = gr.BeginContainer();

                gr.TranslateTransform(point.X, point.Y);

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    double scaleValue = markerElm.OrientAngle.AnimVal.Value;
                    if (!scaleValue.Equals(0))
                    {
                        gr.RotateTransform((float)scaleValue);
                    }
                }
                else
                {
                    double angle;

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i);
                        //angle = markerHostElm.GetStartAngle(i + 1);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start];
                            SvgPointF pMarkerPoint2 = vertexPositions[end];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i - 1);
                        //double angle2 = markerHostElm.GetEndAngle(i);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start - 1];
                            SvgPointF pMarkerPoint2 = vertexPositions[start];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        //if (mayHaveCurves)
                        //{
                        //	angle = this.GetAngleAt(start - 1, angle, markerPos, markerHostElm);
                        //}
                        break;
                    }
                    gr.RotateTransform((float)angle);
                }

                // 'viewBox' and 'preserveAspectRatio' attributes
                // viewBox -> viewport(0, 0, markerWidth, markerHeight)
                var      spar = (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal;
                double[] translateAndScale = spar.FitToViewBox((SvgRect)markerElm.ViewBox.AnimVal,
                                                               new SvgRect(0, 0, markerElm.MarkerWidth.AnimVal.Value, markerElm.MarkerHeight.AnimVal.Value));

                //// Warning at this time, refX and refY are relative to the painted element's coordinate system.
                //// We need to move the reference point to the marker's coordinate system
                //float refX = (float)markerElm.RefX.AnimVal.Value;
                //float refY = (float)markerElm.RefY.AnimVal.Value;

                ////if (!(refX.Equals(0) && refY.Equals(0)))
                ////{
                ////	var points = new PointF[] { new PointF(refX, refY) };
                ////	gr.Transform.TransformPoints(points);

                ////	refX = points[0].X;
                ////	refY = points[0].Y;

                ////	gr.TranslateTransform(-refX, -refY);
                ////}

                //if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                //{
                //	SvgLength strokeWidthLength = new SvgLength(refElement,
                //                    "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                //	float strokeWidth = (float)strokeWidthLength.Value;
                //	gr.ScaleTransform(strokeWidth, strokeWidth);
                //}

                //gr.TranslateTransform(-(float)(markerElm.RefX.AnimVal.Value * translateAndScale[2]),
                //	-(float)(markerElm.RefY.AnimVal.Value * translateAndScale[3]));

                //gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]);

                // compute an additional transform for 'strokeWidth' coordinate system
                ISvgAnimatedEnumeration markerUnits = markerElm.MarkerUnits;
                if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, SvgConstants.ValOne);
                    double strokeWidth = strokeWidthLength.Value;
                    if (!strokeWidth.Equals(1))
                    {
                        gr.ScaleTransform((float)strokeWidth, (float)strokeWidth);
                    }
                }

                gr.TranslateTransform(-(float)(markerElm.RefX.AnimVal.Value * translateAndScale[2]),
                                      -(float)(markerElm.RefY.AnimVal.Value * translateAndScale[3]));

                if (!(translateAndScale[2].Equals(1) && translateAndScale[3].Equals(1)))
                {
                    gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]);
                }

                //				gr.TranslateTransform(point.X, point.Y);

                RectangleF rectClip = RectangleF.Empty;

                if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    string overflowAttr = markerElm.GetAttribute("overflow");
                    if (string.IsNullOrWhiteSpace(overflowAttr) ||
                        overflowAttr.Equals("scroll", comparer) || overflowAttr.Equals(CssConstants.ValHidden, comparer))
                    {
                        var     markerClip = RectangleF.Empty;
                        SvgRect clipRect   = (SvgRect)markerElm.ViewBox.AnimVal;
                        if (clipRect != null && !clipRect.IsEmpty)
                        {
                            rectClip = new RectangleF((float)clipRect.X, (float)clipRect.Y,
                                                      (float)clipRect.Width, (float)clipRect.Height);
                        }
                        else if (markerElm.IsSizeDefined)
                        {
                            rectClip = new RectangleF(0, 0,
                                                      (float)markerElm.MarkerWidth.AnimVal.Value, (float)markerElm.MarkerHeight.AnimVal.Value);
                        }
                    }
                }

                if (rectClip.IsEmpty)
                {
                    SetClip(gr);
                }
                else
                {
                    gr.SetClip(rectClip);
                }

                renderer.RenderChildren(markerElm);

                gr.EndContainer(gc);
            }
        }
Exemple #13
0
        public void RenderMarker(WpfDrawingRenderer renderer, WpfDrawingContext gr,
                                 SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start;
            int         len;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }

            TransformGroup transform = new TransformGroup();

            for (int i = start; i < start + len; i++)
            {
                SvgPointF point = vertexPositions[i];

                //GdiGraphicsContainer gc = gr.BeginContainer();

                this.BeforeRender(renderer);

                //Matrix matrix = Matrix.Identity;

                Matrix matrix = GetTransformMatrix(_svgElement, transform);

                ISvgAnimatedEnumeration orientType = _markerElement.OrientType;

                if (orientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    matrix.Rotate(_markerElement.OrientAngle.AnimVal.Value);
                    transform.Children.Add(new RotateTransform(_markerElement.OrientAngle.AnimVal.Value));
                }
                else
                {
                    double angle = 0;
//                    double angle0 = 0;

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        //angle0 = markerHostElm.GetStartAngle(i + 1);
                        angle = markerHostElm.GetStartAngle(i);
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i - 1);
                        //angle0 = markerHostElm.GetEndAngle(i);
                        break;
                    }
                    matrix.Rotate(angle);
                    transform.Children.Add(new RotateTransform(angle));
                }

                // 'viewBox' and 'preserveAspectRatio' attributes
                // viewBox -> viewport(0, 0, markerWidth, markerHeight)
                SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)_markerElement.PreserveAspectRatio.AnimVal;
                double[] translateAndScale  = spar.FitToViewBox((SvgRect)_markerElement.ViewBox.AnimVal,
                                                                new SvgRect(0, 0, _markerElement.MarkerWidth.AnimVal.Value, _markerElement.MarkerHeight.AnimVal.Value));

                // Warning at this time, refX and refY are relative to the painted element's coordinate system.
                // We need to move the reference point to the marker's coordinate system
                double refX = _markerElement.RefX.AnimVal.Value;
                double refY = _markerElement.RefY.AnimVal.Value;

                var ptRef = matrix.Transform(new Point(refX, refY));

                refX = ptRef.X;
                refY = ptRef.Y;

                matrix.Translate(-refX, -refY);
                transform.Children.Add(new TranslateTransform(-refX, -refY));

                //matrix.Translate(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -markerElm.RefY.AnimVal.Value * translateAndScale[3]);
                //transform.Children.Add(new TranslateTransform(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -markerElm.RefY.AnimVal.Value * translateAndScale[3]));

                // compute an additional transform for 'strokeWidth' coordinate system
                ISvgAnimatedEnumeration markerUnits = _markerElement.MarkerUnits;
                if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                    double strokeWidth = strokeWidthLength.Value;
                    matrix.Scale(strokeWidth, strokeWidth);
                    transform.Children.Add(new ScaleTransform(strokeWidth, strokeWidth));
                }

                matrix.Scale(translateAndScale[2], translateAndScale[3]);
                transform.Children.Add(new ScaleTransform(translateAndScale[2], translateAndScale[3]));

                matrix.Translate(point.X, point.Y);
                transform.Children.Add(new TranslateTransform(point.X, point.Y));

                _matrix = matrix;

                this.Transform = transform;

                this.Render(renderer);

                //Clip(gr);

                renderer.RenderChildren(_markerElement);

                //gr.EndContainer(gc);

                this.AfterRender(renderer);
            }
        }
        public static Geometry CreateGeometry(SvgPathElement element)
        {
            PathGeometry geometry = new PathGeometry();

            string fillRule = element.GetPropertyValue("fill-rule");
            string clipRule = element.GetAttribute("clip-rule");
            if (!String.IsNullOrEmpty(clipRule) &&
                String.Equals(clipRule, "evenodd") || String.Equals(clipRule, "nonzero"))
            {
                fillRule = clipRule;
            }
            if (fillRule == "evenodd")
                geometry.FillRule = FillRule.EvenOdd;
            else if (fillRule == "nonzero")
                geometry.FillRule = FillRule.Nonzero;

            SvgPointF initPoint = new SvgPointF(0, 0);
            SvgPointF lastPoint = new SvgPointF(0, 0);

            ISvgPathSeg segment           = null;
            SvgPathSegMoveto pathMoveTo   = null;
            SvgPathSegLineto pathLineTo   = null;
            SvgPathSegCurveto pathCurveTo = null;
            SvgPathSegArc pathArc         = null;

            ISvgPathSegList segments = element.PathSegList;
            int nElems = segments.NumberOfItems;

            PathFigure pathFigure = null;

            for (int i = 0; i < nElems; i++)
            {
                segment = segments.GetItem(i);

                if (DynamicCast.Cast(segment, out pathMoveTo))
                {
                    if (pathFigure != null)
                    {
                        pathFigure.IsClosed = false;
                        pathFigure.IsFilled = true;
                        geometry.Figures.Add(pathFigure);
                        pathFigure = null;
                    }

                    lastPoint = initPoint = pathMoveTo.AbsXY;

                    pathFigure = new PathFigure();
                    pathFigure.StartPoint = new Point(initPoint.ValueX, initPoint.ValueY);
                }
                else if (DynamicCast.Cast(segment, out pathLineTo))
                {
                    SvgPointF p = pathLineTo.AbsXY;
                    pathFigure.Segments.Add(new LineSegment(new Point(p.ValueX, p.ValueY), true));

                    lastPoint = p;
                }
                else if (DynamicCast.Cast(segment, out pathCurveTo))
                {
                    SvgPointF xy   = pathCurveTo.AbsXY;
                    SvgPointF x1y1 = pathCurveTo.CubicX1Y1;
                    SvgPointF x2y2 = pathCurveTo.CubicX2Y2;
                    pathFigure.Segments.Add(new BezierSegment(new Point(x1y1.ValueX, x1y1.ValueY),
                        new Point(x2y2.ValueX, x2y2.ValueY), new Point(xy.ValueX, xy.ValueY), true));

                    lastPoint = xy;
                }
                else if (DynamicCast.Cast(segment, out pathArc))
                {
                    SvgPointF p = pathArc.AbsXY;
                    if (lastPoint.Equals(p))
                    {
                        // If the endpoints (x, y) and (x0, y0) are identical, then this
                        // is equivalent to omitting the elliptical arc segment entirely.
                    }
                    else if (pathArc.R1 == 0 || pathArc.R2 == 0)
                    {
                        // Ensure radii are valid
                        pathFigure.Segments.Add(new LineSegment(new Point(p.ValueX, p.ValueY), true));
                    }
                    else
                    {
                        CalculatedArcValues calcValues = pathArc.GetCalculatedArcValues();

                        pathFigure.Segments.Add(new ArcSegment(new Point(p.ValueX, p.ValueY),
                            new Size(pathArc.R1, pathArc.R2), pathArc.Angle, pathArc.LargeArcFlag,
                            pathArc.SweepFlag ? SweepDirection.Clockwise : SweepDirection.Counterclockwise,
                            true));
                    }

                    lastPoint = p;
                }
                else if (segment is SvgPathSegClosePath)
                {
                    if (pathFigure != null)
                    {
                        pathFigure.IsClosed = true;
                        pathFigure.IsFilled = true;
                        geometry.Figures.Add(pathFigure);
                        pathFigure = null;
                    }

                    lastPoint = initPoint;
                }
            }

            if (pathFigure != null)
            {
                pathFigure.IsClosed = false;
                pathFigure.IsFilled = true;
                geometry.Figures.Add(pathFigure);
            }

            return geometry;
        }
Exemple #15
0
        public void RenderMarker2(WpfDrawingRenderer renderer, WpfDrawingContext gr,
                                  SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start;
            int         len;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }

            for (int i = start; i < start + len; i++)
            {
                SvgPointF point = vertexPositions[i];

                //GdiGraphicsContainer gc = gr.BeginContainer();

                this.BeforeRender(renderer);

                //Matrix matrix = Matrix.Identity;

                Matrix matrix = GetTransformMatrix(_svgElement);

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    matrix.Rotate(markerElm.OrientAngle.AnimVal.Value);
                }
                else
                {
                    double angle = 0;

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i + 1);
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i);
                        break;
                    }
                    matrix.Rotate(angle);
                }

                if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                    double strokeWidth = strokeWidthLength.Value;
                    matrix.Scale(strokeWidth, strokeWidth);
                }

                SvgPreserveAspectRatio spar =
                    (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal;
                double[] translateAndScale = spar.FitToViewBox((SvgRect)markerElm.ViewBox.AnimVal,
                                                               new SvgRect(0, 0, markerElm.MarkerWidth.AnimVal.Value,
                                                                           markerElm.MarkerHeight.AnimVal.Value));


                matrix.Translate(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                                 -markerElm.RefY.AnimVal.Value * translateAndScale[3]);

                matrix.Scale(translateAndScale[2], translateAndScale[3]);

                matrix.Translate(point.X, point.Y);

                _matrix = matrix;
                this.Render(renderer);

                //Clip(gr);

                renderer.RenderChildren(markerElm);

                //gr.EndContainer(gc);

                this.AfterRender(renderer);
            }
        }
        public static GraphicsPath CreatePath(SvgPathElement element)
        {
            GraphicsPath gp = new GraphicsPath();

            SvgPointF initPoint = new SvgPointF(0, 0);
            SvgPointF lastPoint = new SvgPointF(0, 0);

            SvgPointF ptXY = new SvgPointF(0, 0);

            SvgPathSeg        segment     = null;
            SvgPathSegMoveto  pathMoveTo  = null;
            SvgPathSegLineto  pathLineTo  = null;
            SvgPathSegCurveto pathCurveTo = null;
            SvgPathSegArc     pathArc     = null;

            SvgPathSegList segments = element.PathSegList;
            int            nElems   = segments.NumberOfItems;

            for (int i = 0; i < nElems; i++)
            {
                segment = segments.GetItem(i);
                switch (segment.PathType)
                {
                case SvgPathType.MoveTo:     //if (DynamicCast.Cast(segment, out pathMoveTo))
                    pathMoveTo = (SvgPathSegMoveto)segment;
                    gp.StartFigure();
                    lastPoint = initPoint = pathMoveTo.AbsXY;
                    break;

                case SvgPathType.LineTo:     //else if (DynamicCast.Cast(segment, out pathLineTo))
                    pathLineTo = (SvgPathSegLineto)segment;
                    ptXY       = pathLineTo.AbsXY;
                    gp.AddLine(lastPoint.X, lastPoint.Y, ptXY.X, ptXY.Y);

                    lastPoint = ptXY;
                    break;

                case SvgPathType.CurveTo:     //else if (DynamicCast.Cast(segment, out pathCurveTo))
                    pathCurveTo = (SvgPathSegCurveto)segment;

                    SvgPointF xy   = pathCurveTo.AbsXY;
                    SvgPointF x1y1 = pathCurveTo.CubicX1Y1;
                    SvgPointF x2y2 = pathCurveTo.CubicX2Y2;
                    gp.AddBezier(lastPoint.X, lastPoint.Y, x1y1.X, x1y1.Y, x2y2.X, x2y2.Y, xy.X, xy.Y);

                    lastPoint = xy;
                    break;

                case SvgPathType.ArcTo:     //else if (DynamicCast.Cast(segment, out pathArc))
                    pathArc = (SvgPathSegArc)segment;
                    ptXY    = pathArc.AbsXY;
                    if (lastPoint.Equals(ptXY))
                    {
                        // If the endpoints (x, y) and (x0, y0) are identical, then this
                        // is equivalent to omitting the elliptical arc segment entirely.
                    }
                    else if (pathArc.R1.Equals(0) || pathArc.R2.Equals(0))
                    {
                        // Ensure radii are valid
                        gp.AddLine(lastPoint.X, lastPoint.Y, ptXY.X, ptXY.Y);
                    }
                    else
                    {
                        CalculatedArcValues calcValues = pathArc.GetCalculatedArcValues();

                        GraphicsPath subPath = new GraphicsPath();
                        subPath.StartFigure();
                        subPath.AddArc((float)(calcValues.Cx - calcValues.CorrRx),
                                       (float)(calcValues.Cy - calcValues.CorrRy),
                                       (float)calcValues.CorrRx * 2, (float)calcValues.CorrRy * 2,
                                       (float)calcValues.AngleStart, (float)calcValues.AngleExtent);

                        Matrix matrix = new Matrix();
                        matrix.Translate(-(float)calcValues.Cx, -(float)calcValues.Cy);
                        subPath.Transform(matrix);

                        matrix = new Matrix();
                        matrix.Rotate((float)pathArc.Angle);
                        subPath.Transform(matrix);

                        matrix = new Matrix();
                        matrix.Translate((float)calcValues.Cx, (float)calcValues.Cy);
                        subPath.Transform(matrix);

                        gp.AddPath(subPath, true);
                    }

                    lastPoint = ptXY;
                    break;

                case SvgPathType.Close:    //else if (segment is SvgPathSegClosePath)
                    gp.CloseFigure();

                    lastPoint = initPoint;
                    break;
                }
            }

            string fillRule = element.GetPropertyValue("fill-rule");

            if (fillRule == "evenodd")
            {
                gp.FillMode = FillMode.Alternate;
            }
            else
            {
                gp.FillMode = FillMode.Winding;
            }

            return(gp);
        }
 /// <summary>
 /// Applies a clockwise rotation about the specified point to this 
 /// <see cref="SvgTransformF"/> in the specified order. 
 /// </summary>
 /// <param name="angle">
 /// The angle (extent) of the rotation, in degrees.
 /// </param>
 /// <param name="point">
 /// A <see cref="SvgPointF"/> that represents the center of the rotation.
 /// </param>
 /// <param name="order">
 /// A <see cref="TransformOrder"/> that specifies the order (append or 
 /// prepend) in which the rotation is applied.
 /// </param>
 public void RotateAt(float angle, SvgPointF point, SvgTransformOrder order)
 {
     if (order == SvgTransformOrder.Prepend)
     {
         Translate(point.X, point.Y);
         Rotate(angle);
         Translate(-point.X, -point.Y);
     }
     else
     {
         Translate(-point.X, -point.Y);
         Rotate(angle, SvgTransformOrder.Append);
         Translate(point.X, point.Y);
     }
 }