ExtensionMethod.NET Home of 880 C#, Visual Basic, F# and Javascript extension methods

DrawAndFillRoundedRectangle

Draw and fill a rectangle with some (or all) the angles rounded.

Source

using System.Drawing.Drawing2D;

/// <summary>
/// Angles of a rectangle.
/// </summary>
public enum RectAngles
{
    None = 0,
    TopLeft = 1,
    TopRight = 2,
    BottomLeft = 4,
    BottomRight = 8,
    All = TopLeft | TopRight | BottomLeft | BottomRight
}

/// <summary>
/// Draw and fill a rounded rectangle.
/// </summary>
/// <param name="g">The graphics object to use.</param>
/// <param name="p">The pen to use to draw the rounded rectangle. If <code>null</code>, the border is not drawn.</param>
/// <param name="b">The brush to fill the rounded rectangle. If <code>null</code>, the internal is not filled.</param>
/// <param name="r">The rectangle to draw.</param>
/// <param name="horizontalDiameter">Horizontal diameter for the rounded angles.</param>
/// <param name="verticalDiameter">Vertical diameter for the rounded angles.</param>
/// <param name="rectAngles">Angles to round.</param>
public static void DrawAndFillRoundedRectangle(this Graphics g, Pen p, Brush b, Rectangle r, int horizontalDiameter, int verticalDiameter, RectAngles rectAngles)
{
    // get out data
    int x = r.X;
    int y = r.Y;
    int width = r.Width;
    int height = r.Height;
    // adapt horizontal and vertical diameter if the rectangle is too little
    if (width < horizontalDiameter)
        horizontalDiameter = width;
    if (height < verticalDiameter)
        verticalDiameter = height;
    /*
     * The drawing is the following:
     *
     *             a
     *      P______________Q
     *    h /              \ b
     *   W /                \R
     *    |                  |
     *  g |                  | c
     *   V|                  |S
     *    f\                / d
     *     U\______________/T
     *             e
     */
    bool tl = (rectAngles & RectAngles.TopLeft) != 0,
        tr = (rectAngles & RectAngles.TopRight) != 0,
        br = (rectAngles & RectAngles.BottomRight) != 0,
        bl = (rectAngles & RectAngles.BottomLeft) != 0;
    Point pointP = tl ?
        new Point(x + horizontalDiameter / 2, y) :
        new Point(x, y);
    Point pointQ = tr ?
        new Point(x + width - horizontalDiameter / 2 - 1, y) :
        new Point(x + width - 1, y);
    Point pointR = tr ?
        new Point(x + width - 1, y + verticalDiameter / 2) :
        pointQ;
    Point pointS = br ?
        new Point(x + width - 1, y + height - verticalDiameter / 2 - 1) :
        new Point(x + width - 1, y + height - 1);
    Point pointT = br ?
        new Point(x + width - horizontalDiameter / 2 - 1) :
        pointS;
    Point pointU = bl ?
        new Point(x + horizontalDiameter / 2, y + height - 1) :
        new Point(x, y + height - 1);
    Point pointV = bl ?
        new Point(x, y + height - verticalDiameter / 2 - 1) :
        pointU;
    Point pointW = tl ?
        new Point(x, y + verticalDiameter / 2) :
        pointP;
    using (GraphicsPath gp = new GraphicsPath())
    {
        // a
        gp.AddLine(pointP, pointQ);
        // b
        if (tr)
            gp.AddArc(x + width - horizontalDiameter - 1, y, horizontalDiameter, verticalDiameter, 270, 90);
        // c
        gp.AddLine(pointR, pointS);
        // d
        if (br)
            gp.AddArc(x + width - horizontalDiameter - 1, y + height - verticalDiameter - 1, horizontalDiameter, verticalDiameter, 0, 90);
        // e
        gp.AddLine(pointT, pointU);
        // f
        if (bl)
            gp.AddArc(x, y + height - verticalDiameter - 1, horizontalDiameter, verticalDiameter, 90, 90);
        // g
        gp.AddLine(pointV, pointW);
        // h
        if (tl)
            gp.AddArc(x, y, horizontalDiameter, verticalDiameter, 180, 90);
        // end
        gp.CloseFigure();
        // draw
        if (b != null)
            g.FillPath(b, gp);
        if (p != null)
            g.DrawPath(p, gp);
    }
}

Example

protected override void OnPaint(PaintEventArgs e)
{
  // draw a rounded rectangle in the control area
  e.Graphics.DrawAndFillRoundedRectangle(Pens.Black, Brushes.Yellow, new Rectangle(0, 0, Width, Height), 5, 5, RectAngles.All);
}

Author: Mattia Belletti

Submitted on: 26 aug. 2010

Language: C#

Type: System.Drawing.Graphics

Views: 9618