protected void ClearCachePath() { if (myCachedPath != null) { myCachedPath.Dispose(); myCachedPath = null; } }
public override void ReEvaluateComputeValue(ref ReEvaluateArgs args) { var myspec = this.imageSpec; this.fillColor = myspec.ActualColor; this.strokeColor = myspec.StrokeColor; this.ActualX = ConvertToPx(myspec.X, ref args); this.ActualY = ConvertToPx(myspec.Y, ref args); this.ActualWidth = ConvertToPx(myspec.Width, ref args); this.ActualHeight = ConvertToPx(myspec.Height, ref args); this.ActualStrokeWidth = ConvertToPx(myspec.StrokeWidth, ref args); this._path = CreateRectGraphicPath( this.ActualX, this.ActualY, this.ActualWidth, this.ActualHeight); if (this._imgRun.ImageBinder == null) { this._imgRun.ImageBinder = new SvgImageBinder(myspec.ImageSrc); } ValidatePath(); }
static GraphicsPath CreateRectGraphicPath(float x, float y, float w, float h) { var _path = new GraphicsPath(); _path.StartFigure(); _path.AddRectangle(new RectangleF(x, y, w, h)); _path.CloseFigure(); return _path; }
public static void GetPathData(GraphicsPath p, out List<float> points, out List<PathCommand> cmds) { points = p.points; cmds = p.cmds; }
/// <summary> /// Creates a rounded rectangle using the specified corner radius /// </summary> /// <param name="rect">Rectangle to round</param> /// <param name="nwRadius">Radius of the north east corner</param> /// <param name="neRadius">Radius of the north west corner</param> /// <param name="seRadius">Radius of the south east corner</param> /// <param name="swRadius">Radius of the south west corner</param> /// <returns>GraphicsPath with the lines of the rounded rectangle ready to be painted</returns> public static GraphicsPath GetRoundRect(RectangleF rect, float nwRadius, float neRadius, float seRadius, float swRadius) { // NW-----NE // | | // | | // SW-----SE var path = new GraphicsPath(); nwRadius *= 2; neRadius *= 2; seRadius *= 2; swRadius *= 2; //NW ---- NE path.AddLine(rect.X + nwRadius, rect.Y, rect.Right - neRadius, rect.Y); //NE Arc if (neRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Right - neRadius, rect.Top, rect.Right, rect.Top + neRadius), -90, 90); } // NE // | // SE path.AddLine(rect.Right, rect.Top + neRadius, rect.Right, rect.Bottom - seRadius); //SE Arc if (seRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Right - seRadius, rect.Bottom - seRadius, rect.Right, rect.Bottom), 0, 90); } // SW --- SE path.AddLine(rect.Right - seRadius, rect.Bottom, rect.Left + swRadius, rect.Bottom); //SW Arc if (swRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Left, rect.Bottom - swRadius, rect.Left + swRadius, rect.Bottom), 90, 90); } // NW // | // SW path.AddLine(rect.Left, rect.Bottom - swRadius, rect.Left, rect.Top + nwRadius); //NW Arc if (nwRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Left, rect.Top, rect.Left + nwRadius, rect.Top + nwRadius), 180, 90); } path.CloseFigure(); return path; }
/// <summary> /// Makes a border path for rounded borders.<br/> /// To support rounded dotted/dashed borders we need to use arc in the border path.<br/> /// Return null if the border is not rounded.<br/> /// </summary> /// <param name="border">Desired border</param> /// <param name="b">Box which the border corresponds</param> /// <param name="r">the rectangle the border is enclosing</param> /// <returns>Beveled border path, null if there is no rounded corners</returns> static GraphicsPath GetRoundedBorderPath(PaintVisitor p, CssSide border, CssBox b, RectangleF r) { GraphicsPath path = null; switch (border) { case CssSide.Top: if (b.ActualCornerNW > 0 || b.ActualCornerNE > 0) { path = new GraphicsPath(); if (b.ActualCornerNW > 0) path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNW * 2, b.ActualCornerNW * 2, 180f, 90f); else path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, r.Left + b.ActualBorderLeftWidth, r.Top + b.ActualBorderTopWidth / 2); if (b.ActualCornerNE > 0) path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNE * 2, b.ActualCornerNE * 2, 270f, 90f); else path.AddLine(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth, r.Top + b.ActualBorderTopWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2); } break; case CssSide.Bottom: if (b.ActualCornerSW > 0 || b.ActualCornerSE > 0) { path = new GraphicsPath(); if (b.ActualCornerSE > 0) path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSE * 2, b.ActualCornerSE * 2, 0f, 90f); else path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - .1f); if (b.ActualCornerSW > 0) path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSW * 2, b.ActualCornerSW * 2, 90f, 90f); else path.AddLine(r.Left + b.ActualBorderLeftWidth / 2 + .1f, r.Bottom - b.ActualBorderBottomWidth / 2, r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2); } break; case CssSide.Right: if (b.ActualCornerNE > 0 || b.ActualCornerSE > 0) { path = new GraphicsPath(); if (b.ActualCornerNE > 0 && b.BorderTopStyle >= CssBorderStyle.Visible) { path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNE * 2, b.ActualCornerNE * 2, 270f, 90f); } else { path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualCornerNE + b.ActualBorderTopWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualCornerNE + b.ActualBorderTopWidth / 2 + .1f); } if (b.ActualCornerSE > 0 && b.BorderBottomStyle >= CssBorderStyle.Visible) { path.AddArc(r.Right - b.ActualCornerSE * 2 - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSE * 2, b.ActualCornerSE * 2, 0f, 90f); } else { path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE - b.ActualBorderBottomWidth / 2 - .1f, r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE - b.ActualBorderBottomWidth / 2); } } break; case CssSide.Left: if (b.ActualCornerNW > 0 || b.ActualCornerSW > 0) { path = new GraphicsPath(); if (b.ActualCornerSW > 0 && b.BorderTopStyle >= CssBorderStyle.Visible)//(b.BorderTopStyle == CssConstants.None || b.BorderTopStyle == CssConstants.Hidden)) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSW * 2, b.ActualCornerSW * 2, 90f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW - b.ActualBorderBottomWidth / 2, r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW - b.ActualBorderBottomWidth / 2 - .1f); } if (b.ActualCornerNW > 0 && b.BorderBottomStyle >= CssBorderStyle.Visible) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNW * 2, b.ActualCornerNW * 2, 180f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualCornerNW + b.ActualBorderTopWidth / 2 + .1f, r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualCornerNW + b.ActualBorderTopWidth / 2); } } break; } return path; }
//---------------------------- public override void ReEvaluateComputeValue(ref ReEvaluateArgs args) { var myspec = this.spec; this.fillColor = myspec.ActualColor; this.strokeColor = myspec.StrokeColor; this.ActualX = ConvertToPx(myspec.X, ref args); this.ActualY = ConvertToPx(myspec.Y, ref args); this.ActualRadius = ConvertToPx(myspec.Radius, ref args); this.ActualStrokeWidth = ConvertToPx(myspec.StrokeWidth, ref args); //create new path if (this.IsPathValid) { return; } ClearCachePath(); myCachedPath = new GraphicsPath(); myCachedPath.StartFigure(); myCachedPath.AddEllipse(this.ActualX - this.ActualRadius, this.ActualY - this.ActualRadius, 2 * this.ActualRadius, 2 * ActualRadius); myCachedPath.CloseFigure(); ValidatePath(); }
static GraphicsPath CreateRoundRectGraphicPath(float x, float y, float w, float h, float c_rx, float c_ry) { var _path = new GraphicsPath(); var arcBounds = new RectangleF(); var lineStart = new PointF(); var lineEnd = new PointF(); var width = w; var height = h; var rx = c_rx * 2; var ry = c_ry * 2; // Start _path.StartFigure(); // Add first arc arcBounds.Location = new PointF(x, y); arcBounds.Width = rx; arcBounds.Height = ry; _path.AddArc(arcBounds, 180, 90); // Add first line lineStart.X = Math.Min(x + rx, x + width * 0.5f); lineStart.Y = y; lineEnd.X = Math.Max(x + width - rx, x + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add second arc arcBounds.Location = new PointF(x + width - rx, y); _path.AddArc(arcBounds, 270, 90); // Add second line lineStart.X = x + width; lineStart.Y = Math.Min(y + ry, y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Max(y + height - ry, y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(x + width - rx, y + height - ry); _path.AddArc(arcBounds, 0, 90); // Add third line lineStart.X = Math.Max(x + width - rx, x + width * 0.5f); lineStart.Y = y + height; lineEnd.X = Math.Min(x + rx, x + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(x, y + height - ry); _path.AddArc(arcBounds, 90, 90); // Add fourth line lineStart.X = x; lineStart.Y = Math.Max(y + height - ry, y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Min(y + ry, y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Close _path.CloseFigure(); return _path; }
public void DrawPath(GraphicsPath path, Color strokeColor, float strokeW) { var g = this.canvas; var prevW = g.StrokeWidth; var prevColor = g.StrokeColor; g.StrokeColor = strokeColor; g.StrokeWidth = strokeW; g.DrawPath(path); g.StrokeWidth = prevW; g.StrokeColor = prevColor; }
//------- public void FillPath(GraphicsPath path, Color fillColor) { this.canvas.FillPath(fillColor, path); }