/// <summary>Closes the current path such that it forms a loop by drawing a line to the first node.</summary> public void closePath() { Path.ClosePath(); }
/// <summary> /// Gets the path representing this element. /// </summary> public override VectorPath GetPath(SVGElement context, RenderContext renderer) { Css.RenderableData rd = context.RenderData; // Get w/h: float width = Width.GetDecimal(rd, ViewportAxis.X); float height = Height.GetDecimal(rd, ViewportAxis.Y); if (width <= 0f && height > 0f) { return(null); } if (_Path == null) { _Path = new VectorPath(); // Get corner radius: float rx = CornerRadiusX.GetDecimal(rd, ViewportAxis.X); float ry = CornerRadiusY.GetDecimal(rd, ViewportAxis.Y); // Get x/y: float x = X.GetDecimal(rd, ViewportAxis.X); float y = Y.GetDecimal(rd, ViewportAxis.Y); // Note: This goes clockwise (like the other standard shapes). // If the corners aren't to be rounded just create a rectangle if (rx == 0f && ry == 0f) { // Ordinary rectangle. _Path.MoveTo(x, y); _Path.LineTo(x, y + height); _Path.LineTo(x + width, y + height); _Path.LineTo(x + width, y); _Path.ClosePath(); } else { // Clip the corner radius: rx = (float)Math.Min(rx * 2, width); ry = (float)Math.Min(ry * 2, height); // Get the C values (used to shape the 4 corners arcs - see CircleProvider for some clarity): float cx = (CircleProvider.BezierC * rx); float cy = (CircleProvider.BezierC * ry); float limit = x + width * 0.5f; // The start/ end of arcs from the left along x. float leftArcX = Math.Min(x + rx, limit); // The start/ end of arcs from the right along x. float rightArcX = Math.Max(x + width - rx, limit); limit = y + height * 0.5f; // The start/ end of arcs from the bottom along y. float bottomArcY = Math.Min(y + ry, limit); // The start/ end of arcs from the top along y. float topArcY = Math.Max(y + height - ry, limit); // Start from bottom left: _Path.MoveTo( leftArcX, y ); // First arc (bottom left): _Path.CurveTo( leftArcX - cx, y, x, bottomArcY - cy, x, bottomArcY ); // Up the left edge: _Path.LineTo(x, topArcY); // Top left arc: _Path.CurveTo( x, topArcY + cy, leftArcX - cx, y + height, leftArcX, y + height ); // Along the top edge: _Path.LineTo(rightArcX, y); // Top right arc: _Path.CurveTo( rightArcX + cx, y, x + width, topArcY + cy, x + width, topArcY ); // Down the right edge: _Path.LineTo(x + width, bottomArcY); // Bottom right arc: _Path.CurveTo( x + width, bottomArcY - cy, rightArcX + cx, y, rightArcX, y ); // Line along the bottom! _Path.ClosePath(); } } return(_Path); }
/// <summary>Closes the current path such that it forms a loop by drawing a line to the first node.</summary> public void closePath() { Path.ClosePath(); Clip_ = true; }
/// <summary>Adds the given parsed command into the given path.</summary> public static void AddCommand(VectorPath path, char command, float[] param, int currentLimit) { if (command == '\0') { return; } // Get the lc command: char lower = char.ToLower(command); // A lowercase char is relative // (and its lowercase if the lower one matches the original): bool isRelative = (command == lower); // Current point: float curX = 0f; float curY = 0f; float c1x = 0f; float c1y = 0f; if (path.LatestPathNode != null) { // Get current point: curX = path.LatestPathNode.X; curY = path.LatestPathNode.Y; } switch (lower) { case 'a': // Eliptical arc if (isRelative) { param[5] += curX; param[6] += curY; } path.EllipseArc(param[0], param[1], param[2], param[5], param[6], (param[3] == 1f), (param[4] == 1f)); break; case 'c': // Curve to if (isRelative) { param[0] += curX; param[1] += curY; param[2] += curX; param[3] += curY; param[4] += curX; param[5] += curY; } path.CurveTo(param[0], param[1], param[2], param[3], param[4], param[5]); break; case 'h': // Horizontal line to if (isRelative) { param[0] += curX; } path.LineTo(param[0], curY); break; case 'l': // Line to if (isRelative) { param[0] += curX; param[1] += curY; } path.LineTo(param[0], param[1]); break; case 'm': // Move to if (isRelative) { param[0] += curX; param[1] += curY; } path.MoveTo(param[0], param[1]); break; case 'q': // Quadratic bezier to if (isRelative) { param[0] += curX; param[1] += curY; param[2] += curX; param[3] += curY; } path.QuadraticCurveTo(param[0], param[1], param[2], param[3]); break; case 's': // Smooth curve to Reflect(path, out c1x, out c1y); if (isRelative) { param[0] += curX; param[1] += curY; param[2] += curX; param[3] += curY; } path.CurveTo(c1x, c1y, param[0], param[1], param[2], param[3]); break; case 't': // Smooth quadratic bezier to Reflect(path, out c1x, out c1y); if (isRelative) { param[0] += curX; param[1] += curY; } path.QuadraticCurveTo(c1x, c1y, param[0], param[1]); break; case 'v': // Vertical line to if (isRelative) { param[0] += curY; } path.LineTo(curX, param[0]); break; case 'z': // Close path path.ClosePath(); break; } }