public SvgTransform(string str) { int start = str.IndexOf("(", StringComparison.OrdinalIgnoreCase); string type = str.Substring(0, start); string valuesList = (str.Substring(start + 1, str.Length - start - 2)).Trim(); //JR added trim Regex re = new Regex("[\\s\\,]+"); valuesList = re.Replace(valuesList, ","); string[] valuesStr = valuesList.Split(new char[] { ',' }); int len = valuesStr.GetLength(0); double[] values = new double[len]; try { for (int i = 0; i < len; i++) { values[i] = SvgNumber.Parse(valuesStr[i]); } } catch { values = SvgNumber.ParseDoubles(str); len = values.Length; } _values = values; switch (type.Trim()) { case "translate": switch (len) { case 1: SetTranslate(values[0], 0); break; case 2: SetTranslate(values[0], values[1]); break; default: throw new ApplicationException("Wrong number of arguments in translate transform"); } break; case "rotate": switch (len) { case 1: SetRotate(values[0]); break; case 3: SetRotate(values[0], values[1], values[2]); break; default: throw new ApplicationException("Wrong number of arguments in rotate transform"); } break; case "scale": switch (len) { case 1: SetScale(values[0], values[0]); break; case 2: SetScale(values[0], values[1]); break; default: throw new ApplicationException("Wrong number of arguments in scale transform"); } break; case "skewX": if (len != 1) { throw new ApplicationException("Wrong number of arguments in skewX transform"); } SetSkewX(values[0]); break; case "skewY": if (len != 1) { throw new ApplicationException("Wrong number of arguments in skewY transform"); } SetSkewY(values[0]); break; case "matrix": if (len != 6) { throw new ApplicationException("Wrong number of arguments in matrix transform"); } SetMatrix(new SvgMatrix(values[0], values[1], values[2], values[3], values[4], values[5])); break; default: _type = SvgTransformType.Unknown; break; } }
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[] paths = RegexPathCmd.Split(pathSegs); SvgPointF startPoint = new SvgPointF(0, 0); foreach (string path in paths) { string segment = path.Trim(); if (segment.Length == 0) { continue; } // char cmd = segment.ToCharArray(0, 1)[0]; // double[] coords = ParseCoords(segment); char cmd = segment[0]; double[] coords = SvgNumber.ParseDoubles(segment.Substring(1)); int length = coords.Length; switch (cmd) { // Parse: 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; // End of: moveto // Parse: 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; // End of: lineto // Parse: 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) { if ((i + 5) >= length) { break; } 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; // End of: bezier // Parse: 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; // End of: arcs // Parse: 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; // End of: close // Unknown path command default: throw new ApplicationException(string.Format("Unknown path command - ({0})", cmd)); } } _isClosed = (closedPath == 1); return(true); }