protected override Path ParsePath(Dictionary <string, string> properties) { // Get the attributes of the circle var cx = DoubleUtils.TryParse(properties.GetOrDefault("cx")) ?? 0; var cy = DoubleUtils.TryParse(properties.GetOrDefault("cy")) ?? 0; var r = DoubleUtils.TryParse(properties.GetOrDefault("r")) ?? 0; // Quit on invalid values if (r <= 0) { return(new Path()); } var rr = new Double2(r, r); // Mount the path commands return(new Path(new[] { PathCommand.MoveTo(new Double2(cx + r, cy)), PathCommand.ArcTo(rr, 0, false, true, new Double2(cx, cy + r)), PathCommand.ArcTo(rr, 0, false, true, new Double2(cx - r, cy)), PathCommand.ArcTo(rr, 0, false, true, new Double2(cx, cy - r)), PathCommand.ArcToClose(rr, 0, false, true) })); }
public virtual void AddVertex(Point aPoint, PathCommand aCommand, bool closeFigure) { if (closeFigure) aCommand |= PathCommand.CloseFigure; fVertexList.Add(aPoint); fCommandList.Add((byte)aCommand); }
private void SetPath(PathCommand pathCommand, double x, double y, double cx, double cy, double cx1, double cy1) { PathCommand = pathCommand; X = x * Scale; Y = y * Scale; Cx = cx * Scale; Cy = cy * Scale; Cx1 = cx1 * Scale; Cy1 = cy1 * Scale; }
private Path AddCommand(PathCommand command) { _commands.Enqueue(command); SetX(GetAllPoints.Min(x => x.X)); SetY(GetAllPoints.Min(x => x.Y)); SetWidth(GetAllPoints.Max(x => x.X) - (Width ?? 0)); SetHeight(GetAllPoints.Max(x => x.Y) - (Height ?? 0)); return(this); }
public PathData(string data) { var cmds = CommandSplit.Split(data); // i = 1 to avoid the empty first value for (int i = 1; i < cmds.Length; i++) { this.commands.Add(PathCommand.Create(cmds[i])); } Calculate(); }
public static PathSegment FromPathCommand(PathCommand command) { var points = new List <PointF>(); var i = 0; while (i < command.Values.Count) { points.Add(new PointF(command.Values[i], command.Values[i + 1])); i += 2; } return(new PathSegment(command.Command, points)); }
public void CommandCreationTest(string commandString, Type expectedException) { try { PathCommand.Create(commandString); } catch (Exception ex) { if (!expectedException.Equals(ex?.GetType())) { throw; } } }
protected override Path ParsePath(Dictionary <string, string> properties) { // Get the attributes of the line var x1 = DoubleUtils.TryParse(properties.GetOrDefault("x1")) ?? 0; var y1 = DoubleUtils.TryParse(properties.GetOrDefault("y1")) ?? 0; var x2 = DoubleUtils.TryParse(properties.GetOrDefault("x2")) ?? 0; var y2 = DoubleUtils.TryParse(properties.GetOrDefault("y2")) ?? 0; // And finally return return(new Path(new[] { PathCommand.MoveTo(new Double2(x1, y1)), PathCommand.LineTo(new Double2(x2, y2)) })); }
public PathCommand PathCommandFrom() { switch (Type) { case CurveType.Line: return(PathCommand.LineTo(B)); case CurveType.QuadraticBezier: return(PathCommand.QuadraticCurveTo(B, C)); case CurveType.CubicBezier: return(PathCommand.CubicCurveTo(B, C, D)); case CurveType.EllipticArc: return(PathCommand.ArcTo(Radii, ComplexRot.Angle, Math.Abs(DeltaAngle) > DoubleUtils.Pi, DeltaAngle > 0, At(1))); default: return(PathCommand.None); } }
protected override Path ParsePath(Dictionary <string, string> properties) { // Get the attributes of the ellipse var cx = DoubleUtils.TryParse(properties.GetOrDefault("cx")) ?? 0; var cy = DoubleUtils.TryParse(properties.GetOrDefault("cy")) ?? 0; var radii = new Double2(); radii.X = DoubleUtils.TryParse(properties.GetOrDefault("rx")) ?? double.NaN; radii.Y = DoubleUtils.TryParse(properties.GetOrDefault("ry")) ?? double.NaN; // Check both radii if (double.IsNaN(radii.X) && double.IsNaN(radii.Y)) { radii.X = radii.Y = 0; } else if (double.IsNaN(radii.X)) { radii.X = radii.Y; } else if (double.IsNaN(radii.Y)) { radii.Y = radii.X; } // Take out the sign and clamp them radii.X = Math.Abs(radii.X); radii.Y = Math.Abs(radii.Y); // Quit on invalid values if (radii.X <= 0 || radii.Y <= 0) { return(new Path()); } // Mount the path commands return(new Path(new[] { PathCommand.MoveTo(new Double2(cx + radii.X, cy)), PathCommand.ArcTo(radii, 0, false, true, new Double2(cx, cy + radii.Y)), PathCommand.ArcTo(radii, 0, false, true, new Double2(cx - radii.X, cy)), PathCommand.ArcTo(radii, 0, false, true, new Double2(cx, cy - radii.Y)), PathCommand.ArcToClose(radii, 0, false, true) })); }
public void WriteContent(XmlElement xmlElement, SvgWriter svgWriter) { _background.ID = ID + "_background"; _background.Path = Path; _background.Fill = Fill; _border.ID = ID + "_border"; _border.Path = Path; _border.Stroke = Stroke; _border.StrokeWidth = StrokeWidth; _border.Fill = System.Drawing.Color.Transparent; if (Content != null) { var doc = xmlElement.OwnerDocument; var clipPath = doc.CreateElement("clipPath", XmlNamespace.Svg); var id = "clip" + Guid.NewGuid().ToString("N"); clipPath.SetAttribute("id", id); xmlElement.AppendChild(clipPath); clipPath = doc.CreateElement("path", XmlNamespace.Svg); xmlElement.LastChild.AppendChild(clipPath); clipPath.SetAttribute("d", PathCommand.ToSvgString(Path)); xmlElement.SetAttribute("clip-path", string.Format("url(#{0})", id)); } var xml = svgWriter.CreateXmlElementFromSvg(_background); xmlElement.AppendChild(xml); svgWriter.Write(_background, xml); if (Content != null) { xml = svgWriter.CreateXmlElementFromSvg(Content); xmlElement.AppendChild(xml); svgWriter.Write(Content, xml); } xml = svgWriter.CreateXmlElementFromSvg(_border); xmlElement.AppendChild(xml); svgWriter.Write(_border, xml); }
public static void Add() { string fullPath = RuntimeInfo.ExeLocation; if (!RuntimeInfo.IsExeInAppFolder) { bool v = CliOutput.ReadConfirm("Could not find exe in system path. Add now?"); if (v) { PathCommand.Add(); return; } if (fullPath == null) { throw new ApplicationException(); } } // Add command string[] commandCode = { "@echo off", String.Format("reg.exe add {0} /ve /d \"{1} \"\"%%1\"\"\" /f >nul",RuntimeInfo.REG_SHELL_CMD, fullPath) }; Cli.CreateRunBatchFile("add_to_menu.bat", commandCode); // Add icon string[] iconCode = { "@echo off", String.Format("reg.exe add {0} /v Icon /d \"{1}\" /f >nul",RuntimeInfo.REG_SHELL, fullPath), }; Cli.CreateRunBatchFile("add_icon_to_menu.bat", iconCode); }
internal static Path FromSvgString(string svg) { Path path; if (!string.IsNullOrEmpty(svg)) { try { var commands = PathCommand.ParseCommands(svg); path = FromPathCommands(commands); } catch (Exception) { path = new Path(); } } else { path = new Path(); } return(path); }
// Main parse loop void Parse() { // Use an exception to break out the loop try { bool isfirst = true; while (true) { // Pick the command list var cmd = ParseCommand(out var relative); // First command MUST be a moveto if (isfirst && cmd != 'M') { throw new ParserException($"First path command MUST be a moveto! Error at position {index}."); } // Moveto command if (cmd == 'M') { bool first = true; bool onlyone = true; foreach (var vs in DelimitedPositionTuple(1)) { onlyone = first; var lpos = lastValue; var pos = ProcessRelative(vs[0], relative); commands.Add(first ? PathCommand.MoveTo(pos) : PathCommand.LineTo(pos)); lastControl = pos; lastTangent = first ? 0 : lpos.AngleFacing(pos); first = false; } lastCommand = onlyone ? PathCommandType.MoveTo : PathCommandType.LineTo; } // Lineto command else if (cmd == 'L') { foreach (var vs in DelimitedPositionTuple(1)) { var lpos = lastValue; var pos = ProcessRelative(vs[0], relative); commands.Add(PathCommand.LineTo(pos)); lastTangent = lpos.AngleFacing(pos); lastControl = pos; } lastCommand = PathCommandType.LineTo; } // Horizontal lineto command else if (cmd == 'H') { foreach (var h in DelimitedSequence()) { var lpos = lastValue; var v = relative ? 0 : lpos.Y; var pos = ProcessRelative(new Double2(h, v), relative); commands.Add(PathCommand.LineTo(pos)); lastTangent = lpos.AngleFacing(pos); lastControl = pos; } lastCommand = PathCommandType.LineTo; } // Vertical lineto command else if (cmd == 'V') { foreach (var v in DelimitedSequence()) { var lpos = lastValue; var h = relative ? 0 : lpos.X; var pos = ProcessRelative(new Double2(h, v), relative); commands.Add(PathCommand.LineTo(pos)); lastTangent = lpos.AngleFacing(pos); lastControl = pos; } lastCommand = PathCommandType.LineTo; } // Quadratic bezier command else if (cmd == 'Q') { foreach (var vs in DelimitedPositionTuple(2)) { var ctl = ProcessRelative(vs[0], relative, false); var pos = ProcessRelative(vs[1], relative); commands.Add(PathCommand.QuadraticCurveTo(ctl, pos)); lastTangent = ctl.AngleFacing(pos); lastControl = ctl; } lastCommand = PathCommandType.QuadraticCurveTo; } // Smooth quadratic bezier command else if (cmd == 'T') { foreach (var vs in DelimitedPositionTuple(1)) { var lpos = lastValue; var lctl = lastCommand == PathCommandType.QuadraticCurveTo ? lastControl : lastValue; var ctl = 2 * lpos - lctl; var pos = ProcessRelative(vs[0], relative); commands.Add(PathCommand.QuadraticCurveTo(ctl, pos)); lastTangent = ctl.AngleFacing(pos); } lastCommand = PathCommandType.QuadraticCurveTo; } // Cubic bezier command else if (cmd == 'C') { foreach (var vs in DelimitedPositionTuple(3)) { var ctl = ProcessRelative(vs[0], relative, false); var ctl2 = ProcessRelative(vs[1], relative, false); var pos = ProcessRelative(vs[2], relative); commands.Add(PathCommand.CubicCurveTo(ctl, ctl2, pos)); lastTangent = ctl2.AngleFacing(pos); lastControl = ctl2; } lastCommand = PathCommandType.CubicCurveTo; } // Smooth cubic bezier command else if (cmd == 'S') { foreach (var vs in DelimitedPositionTuple(2)) { var lpos = lastValue; var lctl = lastCommand == PathCommandType.CubicCurveTo ? lastControl : lastValue; var ctl = 2 * lpos - lctl; var ctl2 = ProcessRelative(vs[0], relative, false); var pos = ProcessRelative(vs[1], relative); commands.Add(PathCommand.CubicCurveTo(ctl, ctl2, pos)); lastTangent = ctl.AngleFacing(pos); lastControl = ctl2; } lastCommand = PathCommandType.CubicCurveTo; } // Arc command else if (cmd == 'A') { double ThrowF() => throw new ParserException($"Invalid parameter passed to arc command at position {index}."); bool ThrowB() => ThrowF() == 0; // Pick parameters while (true) { // If there isn't a next double, end the command var next = ParseDouble(); if (!next.HasValue) { break; } // Pick the doubles and flags in order var rx = next.Value; SkipWhitespaceAndDelimiters(); var ry = ParseDouble() ?? ThrowF(); SkipWhitespaceAndDelimiters(); var rAngle = ParseDouble() ?? ThrowF(); SkipWhitespaceAndDelimiters(); var largeArc = ParseFlag() ?? ThrowB(); SkipWhitespaceAndDelimiters(); var sweep = ParseFlag() ?? ThrowB(); Double2 target; // Check if the target isn't a premature closepath next = ParseDouble(); SkipWhitespaceAndDelimiters(); if (!next.HasValue) { if (parseString[index] == 'z' || parseString[index] == 'Z') { target = new Double2(double.NaN, double.NaN); } else { ThrowF(); } } // Assign the target target.X = next.Value; target.Y = ParseDouble() ?? ThrowF(); // Adjust for relative rAngle = (rAngle.ToRadians() + (relative ? currentBearing : 0)).WrapAngle(); target = ProcessRelative(target, relative); // Add the command commands.Add(PathCommand.ArcTo(new Double2(rx, ry), rAngle, largeArc, sweep, target)); } } // Bearing command else if (cmd == 'B') { if (!relative) { currentBearing = DelimitedSequence().Last().ToRadians(); } else { currentBearing += DelimitedSequence().Sum().ToRadians(); } lastCommand = PathCommandType.None; } // Complete closepath command else if (cmd == 'Z') { commands.Add(PathCommand.ClosePath()); lastCommand = PathCommandType.ClosePath; } // Unknown command else { throw new ParserException($"Unrecognized command at position {index-1}."); } isfirst = false; } } catch (EndParseException) { // The expression says it } }
void _addArcCommands( float cx, float cy, float r, float a0, float a1, PathWinding dir, bool forceMoveTo, Matrix3 transform = null) { // Clamp angles float da = a1 - a0; if (dir == PathWinding.clockwise) { if (Mathf.Abs(da) >= Mathf.PI * 2) { da = Mathf.PI * 2; } else { while (da < 0.0f) { da += Mathf.PI * 2; } if (da <= 1e-5) { return; } } } else { if (Mathf.Abs(da) >= Mathf.PI * 2) { da = -Mathf.PI * 2; } else { while (da > 0.0f) { da -= Mathf.PI * 2; } if (da >= -1e-5) { return; } } } // Split arc into max 90 degree segments. int ndivs = Mathf.Max(1, Mathf.Min((int)(Mathf.Abs(da) / (Mathf.PI * 0.5f) + 0.5f), 5)); float hda = (da / ndivs) / 2.0f; float kappa = Mathf.Abs(4.0f / 3.0f * (1.0f - Mathf.Cos(hda)) / Mathf.Sin(hda)); if (dir == PathWinding.counterClockwise) { kappa = -kappa; } PathCommand move = (forceMoveTo || this._commands.Count == 0) ? PathCommand.moveTo : PathCommand.lineTo; float px = 0, py = 0, ptanx = 0, ptany = 0; for (int i = 0; i <= ndivs; i++) { float a = a0 + da * (i / (float)ndivs); float dx = Mathf.Cos(a); float dy = Mathf.Sin(a); float x = cx + dx * r; float y = cy + dy * r; float tanx = -dy * r * kappa; float tany = dx * r * kappa; if (i == 0) { float x1 = x, y1 = y; if (transform != null) { transform.mapXY(x1, y1, out x1, out y1); } if (move == PathCommand.moveTo) { this._appendMoveTo(x1, y1); } else { this._appendLineTo(x1, y1); } } else { float c1x = px + ptanx; float c1y = py + ptany; float c2x = x - tanx; float c2y = y - tany; float x1 = x; float y1 = y; if (transform != null) { transform.mapXY(c1x, c1y, out c1x, out c1y); transform.mapXY(c2x, c2y, out c2x, out c2y); transform.mapXY(x1, y1, out x1, out y1); } this._appendBezierTo(c1x, c1y, c2x, c2y, x1, y1); } px = x; py = y; ptanx = tanx; ptany = tany; } }
static System.Drawing.Drawing2D.GraphicsPath ResolveGraphicsPath(GraphicsPath path) { //convert from graphics path to internal presentation System.Drawing.Drawing2D.GraphicsPath innerPath = path.InnerPath as System.Drawing.Drawing2D.GraphicsPath; if (innerPath != null) { return(innerPath); } //-------- innerPath = new System.Drawing.Drawing2D.GraphicsPath(); path.InnerPath = innerPath; List <float> points; List <PathCommand> cmds; GraphicsPath.GetPathData(path, out points, out cmds); int j = cmds.Count; int p_index = 0; for (int i = 0; i < j; ++i) { PathCommand cmd = cmds[i]; switch (cmd) { default: throw new NotSupportedException(); case PathCommand.Arc: innerPath.AddArc( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5]); p_index += 6; break; case PathCommand.Bezier: innerPath.AddBezier( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5], points[p_index + 6], points[p_index + 7]); p_index += 8; break; case PathCommand.CloseFigure: innerPath.CloseFigure(); break; case PathCommand.Ellipse: innerPath.AddEllipse( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Line: innerPath.AddLine( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Rect: innerPath.AddRectangle( new System.Drawing.RectangleF( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3])); p_index += 4; break; case PathCommand.StartFigure: break; } } return(innerPath); }
public string PathRepresentation() => PathCommand.MoveTo(At(0)).ToString() + " " + PathCommandFrom().ToString();
static SkiaSharp.SKPath ResolveGraphicsPath(GraphicsPath path) { //convert from graphics path to internal presentation SkiaSharp.SKPath innerPath = path.InnerPath as SkiaSharp.SKPath; if (innerPath != null) { return(innerPath); } //-------- innerPath = new SkiaSharp.SKPath(); path.InnerPath = innerPath; List <float> points; List <PathCommand> cmds; GraphicsPath.GetPathData(path, out points, out cmds); int j = cmds.Count; int p_index = 0; for (int i = 0; i < j; ++i) { PathCommand cmd = cmds[i]; switch (cmd) { default: throw new NotSupportedException(); case PathCommand.Arc: var oval = SkiaSharp.SKRect.Create(points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); innerPath.ArcTo(oval, points[p_index + 4], points[p_index + 5], true); p_index += 6; break; case PathCommand.Bezier: innerPath.MoveTo(points[p_index] , points[p_index + 1]); innerPath.CubicTo( points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5], points[p_index + 6], points[p_index + 7]); p_index += 8; break; case PathCommand.CloseFigure: //? break; case PathCommand.Ellipse: innerPath.AddOval( SkiaSharp.SKRect.Create( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3] )); p_index += 4; break; case PathCommand.Line: innerPath.MoveTo(points[p_index], points[p_index + 1]); innerPath.LineTo( points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Rect: innerPath.AddRect( SkiaSharp.SKRect.Create( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3] )); p_index += 4; break; case PathCommand.StartFigure: break; } } return(innerPath); }
internal string ToSvgString() { return(PathCommand.ToSvgString(ToPathCommands())); }
public PathCommandDebuggerView(PathCommand pathCommand) { this.pathCommand = pathCommand; }
protected override Path ParsePath(Dictionary <string, string> properties) { // Get the attributes of the rectangle var x = DoubleUtils.TryParse(properties.GetOrDefault("x")) ?? 0; var y = DoubleUtils.TryParse(properties.GetOrDefault("y")) ?? 0; var width = DoubleUtils.TryParse(properties.GetOrDefault("width")) ?? 0; var height = DoubleUtils.TryParse(properties.GetOrDefault("height")) ?? 0; var radii = new Double2(); radii.X = DoubleUtils.TryParse(properties.GetOrDefault("rx")) ?? double.NaN; radii.Y = DoubleUtils.TryParse(properties.GetOrDefault("ry")) ?? double.NaN; // Quit on invalid values if (width <= 0 || height <= 0) { return(new Path()); } // Check both radii if (double.IsNaN(radii.X) && double.IsNaN(radii.Y)) { radii.X = radii.Y = 0; } else if (double.IsNaN(radii.X)) { radii.X = radii.Y; } else if (double.IsNaN(radii.Y)) { radii.Y = radii.X; } // Take out the sign and clamp them radii.X = Math.Abs(radii.X); radii.Y = Math.Abs(radii.Y); if (radii.X > width / 2) { radii.X = width / 2; } if (radii.Y > height / 2) { radii.Y = height / 2; } // Now mount the path commands PathCommand[] pathCommands; if (radii.X == 0 || radii.Y == 0) { pathCommands = new[] { PathCommand.MoveTo(new Double2(x, y)), PathCommand.LineTo(new Double2(x + width, y)), PathCommand.LineTo(new Double2(x + width, y + height)), PathCommand.LineTo(new Double2(x, y + height)), PathCommand.ClosePath() } } ; else { pathCommands = new[] { PathCommand.MoveTo(new Double2(x + radii.X, y)), PathCommand.LineTo(new Double2(x + width - radii.X, y)), PathCommand.ArcTo(radii, 0, false, true, new Double2(x + width, y + radii.Y)), PathCommand.LineTo(new Double2(x + width, y + height - radii.Y)), PathCommand.ArcTo(radii, 0, false, true, new Double2(x + width - radii.X, y + height)), PathCommand.LineTo(new Double2(x + radii.X, y + height)), PathCommand.ArcTo(radii, 0, false, true, new Double2(x, y + height - radii.Y)), PathCommand.LineTo(new Double2(x, y + radii.Y)), PathCommand.ArcToClose(radii, 0, false, true) } }; // And finally return return(new Path(pathCommands)); } }