/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> public override GraphicsPath Path(ISvgRenderer renderer) { if (_path == null || IsPathDirty) { var halfStrokeWidth = base.StrokeWidth / 2; // If it is to render, don't need to consider stroke if (renderer != null) { halfStrokeWidth = 0; this.IsPathDirty = false; } // If the corners aren't to be rounded just create a rectangle if (CornerRadiusX.Value == 0.0f && CornerRadiusY.Value == 0.0f) { var loc_y = Location.Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); var loc_x = Location.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); // Starting location which take consideration of stroke width SvgPoint strokedLocation = new SvgPoint(loc_x - halfStrokeWidth, loc_y - halfStrokeWidth); var width = this.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) + halfStrokeWidth * 2; var height = this.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) + halfStrokeWidth * 2; var rectangle = new RectangleF(strokedLocation.ToDeviceValue(renderer, this), new SizeF(width, height)); _path = new GraphicsPath(); _path.StartFigure(); _path.AddRectangle(rectangle); _path.CloseFigure(); } else { _path = new GraphicsPath(); var arcBounds = new RectangleF(); var lineStart = new PointF(); var lineEnd = new PointF(); var width = Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); var height = Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); var rx = Math.Min(CornerRadiusX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) * 2, width); var ry = Math.Min(CornerRadiusY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) * 2, height); var location = Location.ToDeviceValue(renderer, this); // Start _path.StartFigure(); // Add first arc arcBounds.Location = location; arcBounds.Width = rx; arcBounds.Height = ry; _path.AddArc(arcBounds, 180, 90); // Add first line lineStart.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineStart.Y = location.Y; lineEnd.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add second arc arcBounds.Location = new PointF(location.X + width - rx, location.Y); _path.AddArc(arcBounds, 270, 90); // Add second line lineStart.X = location.X + width; lineStart.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(location.X + width - rx, location.Y + height - ry); _path.AddArc(arcBounds, 0, 90); // Add third line lineStart.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineStart.Y = location.Y + height; lineEnd.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(location.X, location.Y + height - ry); _path.AddArc(arcBounds, 90, 90); // Add fourth line lineStart.X = location.X; lineStart.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Close _path.CloseFigure(); } } return(_path); }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> public override GraphicsPath Path(ISvgRenderer renderer) { if (_path == null || IsPathDirty) { var halfStrokeWidth = base.StrokeWidth / 2; // If it is to render, don't need to consider stroke if (renderer != null) { halfStrokeWidth = 0; this.IsPathDirty = false; } // If the corners aren't to be rounded just create a rectangle if (renderer == null || (CornerRadiusX.Value == 0.0f && CornerRadiusY.Value == 0.0f)) { var loc_y = Location.Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); var loc_x = Location.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); // Starting location which take consideration of stroke width SvgPoint strokedLocation = new SvgPoint(loc_x - halfStrokeWidth, loc_y - halfStrokeWidth); var width = this.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) + halfStrokeWidth * 2; var height = this.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) + halfStrokeWidth * 2; var location = strokedLocation.ToDeviceValue(renderer, this); var size = new Vector2(width, height); _path = new GraphicsPath(); _path.StartFigure(); _path.AddElement(new RectangleElement(location, size)); _path.CloseFigure(); } else { _path = new GraphicsPath(); var lineStart = new Vector2(); var lineEnd = new Vector2(); var width = Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); var height = Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); var rx = Math.Min(CornerRadiusX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) * 2, width); var ry = Math.Min(CornerRadiusY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) * 2, height); var location = Location.ToDeviceValue(renderer, this); // Start _path.StartFigure(); var lines = new List <LineElement>(); var corners = new List <Vector2>(); // Add first line lineStart.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineStart.Y = location.Y; lineEnd.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; lines.Add(new LineElement(lineStart, lineEnd)); corners.Add(location); // Add second line lineStart.X = location.X + width; lineStart.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); lines.Add(new LineElement(lineStart, lineEnd)); corners.Add(new Vector2(location.X + width, location.Y)); // Add third line lineStart.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineStart.Y = location.Y + height; lineEnd.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; lines.Add(new LineElement(lineStart, lineEnd)); corners.Add(new Vector2(location.X + width, location.Y + height)); // Add fourth line lineStart.X = location.X; lineStart.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); lines.Add(new LineElement(lineStart, lineEnd)); corners.Add(new Vector2(location.X, location.Y + height)); _path.AddElement(lines[0]); _path.AddElement(lines[1]); _path.AddElement(lines[2]); _path.AddElement(lines[3]); addCorner(_path, lines[3].End, corners[0], lines[0].Start, rx, ry); addCorner(_path, lines[0].End, corners[1], lines[1].Start, rx, ry); addCorner(_path, lines[1].End, corners[2], lines[2].Start, rx, ry); addCorner(_path, lines[2].End, corners[3], lines[3].Start, rx, ry); // Close _path.CloseFigure(); } } return(_path); }