コード例 #1
0
        public SvgPathSegList(ISvgPathSegList pathList)
        {
            _pathScript = string.Empty;
            _readOnly   = false;

            _isClosed      = false;
            _mayHaveCurves = false;

            if (pathList == null)
            {
                _segments = new List <ISvgPathSeg>();
            }
            else
            {
                _segments = new List <ISvgPathSeg>(pathList);

                var segList = pathList as SvgPathSegList;

                if (segList != null)
                {
                    _pathScript    = segList.PathScript;
                    _readOnly      = segList.IsReadOnly;
                    _isClosed      = segList.IsClosed;
                    _mayHaveCurves = segList.MayHaveCurves;
                }
            }
        }
コード例 #2
0
        public SvgPathSegList(ISvgPathSegList pathList)
        {
            _pathScript = string.Empty;
            _readOnly   = false;

            _isClosed      = false;
            _mayHaveCurves = false;

            if (pathList == null)
            {
                _segments = new List <SvgPathSeg>();
            }
            else
            {
                _segments = new List <SvgPathSeg>(pathList.NumberOfItems);
                for (int i = 0; i < pathList.NumberOfItems; i++)
                {
                    _segments.Add((SvgPathSeg)pathList.GetItem(i));
                }

                var segList = pathList as SvgPathSegList;

                if (segList != null)
                {
                    _pathScript    = segList.PathScript;
                    _readOnly      = segList.IsReadOnly;
                    _isClosed      = segList.IsClosed;
                    _mayHaveCurves = segList.MayHaveCurves;
                }
            }
        }
コード例 #3
0
        public override void HandleAttributeChange(XmlAttribute attribute)
        {
            if (attribute.NamespaceURI.Length == 0)
            {
                switch (attribute.LocalName)
                {
                case "d":
                    pathSegList = null;
                    Invalidate();
                    return;

                case "pathLength":
                    _pathLength = null;
                    Invalidate();
                    return;

                case "marker-start":
                case "marker-mid":
                case "marker-end":
                // Color.attrib, Paint.attrib
                case "color":
                case "fill":
                case "fill-rule":
                case "stroke":
                case "stroke-dasharray":
                case "stroke-dashoffset":
                case "stroke-linecap":
                case "stroke-linejoin":
                case "stroke-miterlimit":
                case "stroke-width":
                // Opacity.attrib
                case "opacity":
                case "stroke-opacity":
                case "fill-opacity":
                // Graphics.attrib
                case "display":
                case "image-rendering":
                case "shape-rendering":
                case "text-rendering":
                case "visibility":
                    Invalidate();
                    break;

                case "transform":
                    Invalidate();
                    break;
                }
                base.HandleAttributeChange(attribute);
            }
        }
コード例 #4
0
        public bool Parse(ISvgPathSegList pathList, string pathSegs)
        {
            if (pathList == null || string.IsNullOrWhiteSpace(pathSegs))
            {
                return(false);
            }

            _isClosed      = false;
            _mayHaveCurves = false;

            int closedPath = 0;

            ISvgPathSeg seg;

            string[] segs = RegexPathCmd.Split(pathSegs);

            SvgPointF startPoint = new SvgPointF(0, 0);

            foreach (string s in segs)
            {
                string segment = s.Trim();
                if (segment.Length > 0)
                {
                    char     cmd    = segment.ToCharArray(0, 1)[0];
                    double[] coords = ParseCoords(segment);
                    int      length = coords.Length;
                    switch (cmd)
                    {
                        #region moveto
                    case 'M':
                        for (int i = 0; i < length; i += 2)
                        {
                            if (i == 0)
                            {
                                seg = new SvgPathSegMovetoAbs(coords[i], coords[i + 1]);

                                startPoint = new SvgPointF(coords[i], coords[i + 1]);
                                SvgPointF endPoint = new SvgPointF(coords[i], coords[i + 1]);
                                seg.Limits = new SvgPointF[] { startPoint, endPoint };
                                startPoint = endPoint;
                            }
                            else
                            {
                                seg = new SvgPathSegLinetoAbs(coords[i], coords[i + 1]);

                                SvgPointF endPoint = new SvgPointF(coords[i], coords[i + 1]);
                                seg.Limits = new SvgPointF[] { startPoint, endPoint };
                                startPoint = endPoint;
                            }
                            pathList.AppendItem(seg);
                        }
                        break;

                    case 'm':
                        for (int i = 0; i < length; i += 2)
                        {
                            if (i == 0)
                            {
                                seg = new SvgPathSegMovetoRel(coords[i], coords[i + 1]);

                                SvgPointF endPoint = new SvgPointF(coords[i] + startPoint.X, coords[i + 1] + startPoint.Y);
                                seg.Limits = new SvgPointF[] { startPoint, endPoint };
                                startPoint = endPoint;
                            }
                            else
                            {
                                seg = new SvgPathSegLinetoRel(coords[i], coords[i + 1]);

                                SvgPointF endPoint = new SvgPointF(coords[i] + startPoint.X, coords[i + 1] + startPoint.Y);
                                seg.Limits = new SvgPointF[] { startPoint, endPoint };
                                startPoint = endPoint;
                            }
                            pathList.AppendItem(seg);
                        }
                        break;
                        #endregion

                        #region lineto
                    case 'L':
                        for (int i = 0; i < length; i += 2)
                        {
                            seg = new SvgPathSegLinetoAbs(coords[i], coords[i + 1]);
                            pathList.AppendItem(seg);

                            SvgPointF endPoint = new SvgPointF(coords[i], coords[i + 1]);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'l':
                        for (int i = 0; i < length; i += 2)
                        {
                            seg = new SvgPathSegLinetoRel(coords[i], coords[i + 1]);
                            pathList.AppendItem(seg);

                            SvgPointF endPoint = new SvgPointF(coords[i] + startPoint.X, coords[i + 1] + startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'H':
                        for (int i = 0; i < length; i++)
                        {
                            seg = new SvgPathSegLinetoHorizontalAbs(coords[i]);
                            pathList.AppendItem(seg);

                            SvgPointF endPoint = new SvgPointF(coords[i], startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'h':
                        for (int i = 0; i < length; i++)
                        {
                            seg = new SvgPathSegLinetoHorizontalRel(coords[i]);
                            pathList.AppendItem(seg);

                            SvgPointF endPoint = new SvgPointF(coords[i] + startPoint.X, startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'V':
                        for (int i = 0; i < length; i++)
                        {
                            seg = new SvgPathSegLinetoVerticalAbs(coords[i]);
                            pathList.AppendItem(seg);

                            SvgPointF endPoint = new SvgPointF(startPoint.X, coords[i]);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'v':
                        for (int i = 0; i < length; i++)
                        {
                            seg = new SvgPathSegLinetoVerticalRel(coords[i]);
                            pathList.AppendItem(seg);

                            SvgPointF endPoint = new SvgPointF(startPoint.X, coords[i] + startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;
                        #endregion

                        #region beziers
                    case 'C':
                        for (int i = 0; i < length; i += 6)
                        {
                            seg = new SvgPathSegCurvetoCubicAbs(
                                coords[i + 4],
                                coords[i + 5],
                                coords[i],
                                coords[i + 1],
                                coords[i + 2],
                                coords[i + 3]);
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i + 4], coords[i + 5]);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'c':
                        for (int i = 0; i < length; i += 6)
                        {
                            seg = new SvgPathSegCurvetoCubicRel(
                                coords[i + 4],
                                coords[i + 5],
                                coords[i],
                                coords[i + 1],
                                coords[i + 2],
                                coords[i + 3]);

                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i + 4] + startPoint.X, coords[i + 5] + startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'S':
                        for (int i = 0; i < length; i += 4)
                        {
                            seg = new SvgPathSegCurvetoCubicSmoothAbs(
                                coords[i + 2],
                                coords[i + 3],
                                coords[i],
                                coords[i + 1]);
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i + 2], coords[i + 3]);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 's':
                        for (int i = 0; i < length; i += 4)
                        {
                            seg = new SvgPathSegCurvetoCubicSmoothRel(
                                coords[i + 2],
                                coords[i + 3],
                                coords[i],
                                coords[i + 1]);
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i + 2] + startPoint.X, coords[i + 3] + startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'Q':
                        for (int i = 0; i < length; i += 4)
                        {
                            seg = new SvgPathSegCurvetoQuadraticAbs(
                                coords[i + 2],
                                coords[i + 3],
                                coords[i],
                                coords[i + 1]);
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i + 2], coords[i + 3]);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'q':
                        for (int i = 0; i < length; i += 4)
                        {
                            seg = new SvgPathSegCurvetoQuadraticRel(
                                coords[i + 2],
                                coords[i + 3],
                                coords[i],
                                coords[i + 1]);
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i + 2] + startPoint.X, coords[i + 3] + startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 'T':
                        for (int i = 0; i < length; i += 2)
                        {
                            seg = new SvgPathSegCurvetoQuadraticSmoothAbs(
                                coords[i], coords[i + 1]);
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i], coords[i + 1]);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;

                    case 't':
                        for (int i = 0; i < length; i += 2)
                        {
                            seg = new SvgPathSegCurvetoQuadraticSmoothRel(
                                coords[i], coords[i + 1]);
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;

                            SvgPointF endPoint = new SvgPointF(coords[i] + startPoint.X, coords[i + 1] + startPoint.Y);
                            seg.Limits = new SvgPointF[] { startPoint, endPoint };
                            startPoint = endPoint;
                        }
                        break;
                        #endregion

                        #region arcs
                    case 'A':
                    case 'a':
                        for (int i = 0; i < length; i += 7)
                        {
                            if (cmd == 'A')
                            {
                                seg = new SvgPathSegArcAbs(
                                    coords[i + 5],
                                    coords[i + 6],
                                    coords[i],
                                    coords[i + 1],
                                    coords[i + 2],
                                    (!coords[i + 3].Equals(0)),
                                    (!coords[i + 4].Equals(0)));

                                SvgPointF endPoint = new SvgPointF(coords[i + 5], coords[i + 6]);
                                seg.Limits = new SvgPointF[] { startPoint, endPoint };
                                startPoint = endPoint;
                            }
                            else
                            {
                                seg = new SvgPathSegArcRel(
                                    coords[i + 5],
                                    coords[i + 6],
                                    coords[i],
                                    coords[i + 1],
                                    coords[i + 2],
                                    (!coords[i + 3].Equals(0)),
                                    (!coords[i + 4].Equals(0)));

                                SvgPointF endPoint = new SvgPointF(coords[i + 5] + startPoint.X, coords[i + 6] + startPoint.Y);
                                seg.Limits = new SvgPointF[] { startPoint, endPoint };
                                startPoint = endPoint;
                            }
                            pathList.AppendItem(seg);

                            _mayHaveCurves = true;
                        }
                        break;

                        #endregion
                        #region close
                    case 'z':
                    case 'Z':
                        closedPath++;
                        seg = new SvgPathSegClosePath();
                        pathList.AppendItem(seg);

                        if (pathList.Count >= 2)
                        {
                            SvgPointF endPoint = pathList[0].Limits[0];
                            seg.Limits = new SvgPointF[] { endPoint, startPoint };
                            startPoint = endPoint;
                        }
                        else
                        {
                            seg.Limits = new SvgPointF[] { startPoint, startPoint };
                            startPoint = new SvgPointF(0, 0);
                        }
                        break;

                        #endregion
                        #region Unknown path command
                    default:
                        throw new ApplicationException(string.Format("Unknown path command - ({0})", cmd));
                        #endregion
                    }
                }
            }

            _isClosed = (closedPath == 1);

            return(true);
        }
コード例 #5
0
 public override void HandleAttributeChange(XmlAttribute attribute)
 {
     if(attribute.NamespaceURI.Length == 0)
     {
         switch(attribute.LocalName)
         {
             case "d":
                 pathSegList = null;
     Invalidate();
                 return;
             case "pathLength":
                 _pathLength = null;
     Invalidate();
     return;
       case "marker-start":
       case "marker-mid":
       case "marker-end":
     // Color.attrib, Paint.attrib
       case "color":
       case "fill":
       case "fill-rule":
       case "stroke":
       case "stroke-dasharray":
       case "stroke-dashoffset":
       case "stroke-linecap":
       case "stroke-linejoin":
       case "stroke-miterlimit":
       case "stroke-width":
     // Opacity.attrib
       case "opacity":
       case "stroke-opacity":
       case "fill-opacity":
     // Graphics.attrib
       case "display":
       case "image-rendering":
       case "shape-rendering":
       case "text-rendering":
       case "visibility":
     Invalidate();
     break;
       case "transform":
     Invalidate();
     break;
     }
     base.HandleAttributeChange(attribute);
       }
 }
コード例 #6
0
        public Geometry CreateGeometry(SvgPathElement element)
        {
            PathGeometry geometry = new PathGeometry();

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

            if (!string.IsNullOrWhiteSpace(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.Equals(0) || pathArc.R2.Equals(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);
        }
コード例 #7
0
ファイル: GdiRendering.cs プロジェクト: naver/protonow
        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);
        }