public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv) { if (!conv.TrySplitValues(commandString.Substring(1), out var values, false)) { yield break; } int valuePos = 0; while (valuePos < values.Length) { var start = new Pnt2d(); if (lastSegment != null) { start = lastSegment.End; } double rx = values[0] * conv.Scale; double ry = values[1] * conv.Scale; double angle = values[2]; SvgArcSize size = values[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large; SvgArcSweep sweep = values[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive; Pnt2d end = new Pnt2d(values[5] * conv.Scale, values[6] * conv.Scale); if (char.IsLower(commandString[0])) { end += start; } valuePos += 7; lastSegment = new SvgPathSegArc(start, rx, ry, angle, size, sweep, end); yield return(lastSegment); } }
public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv) { if (!conv.TrySplitValues(commandString.Substring(1), out var values, true)) { yield break; } int valuePos = 0; while (valuePos < values.Length) { var start = lastSegment?.End ?? Pnt2d.Origin; Pnt2d c1; Pnt2d c2; Pnt2d end; if (char.ToLower(commandString[0]) == 'c') { c1 = new Pnt2d(values[valuePos], values[valuePos + 1]); c2 = new Pnt2d(values[valuePos + 2], values[valuePos + 3]); end = new Pnt2d(values[valuePos + 4], values[valuePos + 5]); valuePos += 6; if (char.IsLower(commandString[0])) { c1 += start; c2 += start; end += start; } lastSegment = new SvgPathSegCurvetoCubic(start, c1, c2, end); yield return(lastSegment); } else if (char.ToLower(commandString[0]) == 's') { c2 = new Pnt2d(values[valuePos], values[valuePos + 1]); end = new Pnt2d(values[valuePos + 2], values[valuePos + 3]); valuePos += 4; if (char.IsLower(commandString[0])) { c2 += start; end += start; } if (lastSegment is SvgPathSegCurvetoCubic lastSeg) { c1 = lastSeg.C2; } else { c1 = c2; } lastSegment = new SvgPathSegCurvetoCubic(start, c1, c2, end); yield return(lastSegment); } } }
public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv) { if (!conv.TrySplitValues(commandString.Substring(1), out var values, true)) { yield break; } int valuePos = 0; while (valuePos < values.Length) { var start = lastSegment?.End ?? Pnt2d.Origin; SvgPathSegLineto segment = null; switch (commandString[0]) { case 'L': segment = new SvgPathSegLineto(start, new Pnt2d(values[valuePos], values[valuePos + 1])); valuePos += 2; break; case 'l': segment = new SvgPathSegLineto(start, start + new Pnt2d(values[valuePos], values[valuePos + 1])); valuePos += 2; break; case 'H': segment = new SvgPathSegLineto(start, new Pnt2d(values[valuePos], start.Y)); valuePos += 1; break; case 'h': segment = new SvgPathSegLineto(start, start + new Pnt2d(values[valuePos], 0)); valuePos += 1; break; case 'V': segment = new SvgPathSegLineto(start, new Pnt2d(start.X, values[valuePos])); valuePos += 1; break; case 'v': segment = new SvgPathSegLineto(start, start + new Pnt2d(0, values[valuePos])); valuePos += 1; break; } yield return(segment); lastSegment = segment; } }
internal static IEnumerable <SvgTransform> Create(string transformString, SvgConverter conv) { var transformParts = transformString.Split(_TransformSplitChars); for (int i = 0; i < transformParts.Length - 1; i += 2) { if (!conv.TrySplitValues(transformParts[i + 1], out var values, false)) { continue; } SvgTransform transform; switch (transformParts[i].ToLower().Trim()) { case "matrix": transform = SvgMatrixTransform.Create(values, conv); break; case "translate": transform = SvgTranslateTransform.Create(values, conv); break; case "scale": transform = SvgScaleTransform.Create(values, conv); break; case "rotate": transform = SvgRotateTransform.Create(values, conv); break; case "skewx": transform = SvgSkewXTransform.Create(values, conv); break; case "skewy": transform = SvgSkewYTransform.Create(values, conv); break; default: Messages.Warning($"Unknown transform type {transformParts[i]} found in SVG file."); continue; } if (transform != null) { yield return(transform); } } }
//-------------------------------------------------------------------------------------------------- void _CalculateScale(XmlReader reader, SvgConverter conv) { var viewBox = reader.GetAttribute("viewBox"); if (viewBox.IsNullOrWhiteSpace() || !conv.TrySplitValues(viewBox, out var viewBoxValues, false)) { Messages.Warning("SVG document has not defined a ViewBox. The scaling may be incorrect."); return; } double fScaleX = 1.0; double fScaleY = 1.0; if (conv.TryConvertToMillimeter(reader.GetAttribute("width"), out var width, false) && conv.TryConvertToMillimeter(reader.GetAttribute("height"), out var height, false)) { fScaleX = width / viewBoxValues[2]; fScaleY = height / viewBoxValues[3]; }
public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv) { if (!conv.TrySplitValues(commandString.Substring(1), out var values, true)) { yield break; } bool isRelative = commandString[0] == 'm'; int valuePos = 0; Pnt2d endPoint = new Pnt2d(); if (valuePos < values.Length) { endPoint = new Pnt2d(values[valuePos], values[valuePos + 1]); if (isRelative && lastSegment != null) { endPoint += lastSegment.End; } yield return(new SvgPathSegMoveto(endPoint)); valuePos += 2; } // subsequent value pairs are implicit lineto's while (valuePos < values.Length) { var startPoint = endPoint; endPoint = new Pnt2d(values[valuePos], values[valuePos + 1]); if (isRelative) { endPoint += startPoint; } yield return(new SvgPathSegLineto(startPoint, endPoint)); valuePos += 2; } }