views:

2459

answers:

2

I have a method that draws a rounded rectangle with a border. The border can be any width, so the problem I'm having is the border is extending past the given bounds when it's thick because it's drawn from the center of a path.

How would I include the width of the border so that it fits perfectly in the given bounds?

Here's the code I'm using to draw the rounded rectangle.

private void DrawRoundedRectangle(Graphics gfx, Rectangle Bounds, int CornerRadius, Pen DrawPen, Color FillColor)
{
    GraphicsPath gfxPath = new GraphicsPath();

    DrawPen.EndCap = DrawPen.StartCap = LineCap.Round;

    gfxPath.AddArc(Bounds.X, Bounds.Y, CornerRadius, CornerRadius, 180, 90);
    gfxPath.AddArc(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y, CornerRadius, CornerRadius, 270, 90);
    gfxPath.AddArc(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
    gfxPath.AddArc(Bounds.X, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);
    gfxPath.CloseAllFigures();

    gfx.FillPath(new SolidBrush(FillColor), gfxPath);
    gfx.DrawPath(DrawPen, gfxPath);
}
+1  A: 

Alright guys, I figured it out! Just need to shrink the bounds to take into account the width of the pen. I kind of knew this was the answer I was just wondering if there was a way to draw a line on the inside of a path. This works good though.

private void DrawRoundedRectangle(Graphics gfx, Rectangle Bounds, int CornerRadius, Pen DrawPen, Color FillColor)
{
    int strokeOffset = Convert.ToInt32(Math.Ceiling(DrawPen.Width));
    Bounds = Rectangle.Inflate(Bounds, -strokeOffset, -strokeOffset);

    DrawPen.EndCap = DrawPen.StartCap = LineCap.Round;

    GraphicsPath gfxPath = new GraphicsPath();
    gfxPath.AddArc(Bounds.X, Bounds.Y, CornerRadius, CornerRadius, 180, 90);
    gfxPath.AddArc(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y, CornerRadius, CornerRadius, 270, 90);
    gfxPath.AddArc(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
    gfxPath.AddArc(Bounds.X, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);
    gfxPath.CloseAllFigures();

    gfx.FillPath(new SolidBrush(FillColor), gfxPath);
    gfx.DrawPath(DrawPen, gfxPath);
}
Dylan Vester
A: 

Thank you, it helped me, but this code has a little bug(try very small or even 0 width or height). I changed your code alittle.

 private void DrawRoundedRectangle(Graphics gfx, Rectangle Bounds, int CornerRadius, Pen DrawPen, Color FillColor)
    {
        int strokeOffset = Convert.ToInt32(Math.Ceiling(DrawPen.Width));
        Bounds = Rectangle.Inflate(Bounds, -strokeOffset, -strokeOffset);
        if (Bounds.Width < 1)
            Bounds.Width = 1;
        if (Bounds.Height < 1)
            Bounds.Height = 1;
        if (Bounds.Width / 2 < CornerRadius)
            CornerRadius = Bounds.Width / 2;
        if (Bounds.Height / 2 < CornerRadius)
            CornerRadius = Bounds.Height / 2;
        DrawPen.EndCap = DrawPen.StartCap = LineCap.Round;

        GraphicsPath gfxPath = new GraphicsPath();
        gfxPath.AddArc(Bounds.X, Bounds.Y, CornerRadius, CornerRadius, 180, 90);
        gfxPath.AddArc(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y, CornerRadius, CornerRadius, 270, 90);
        gfxPath.AddArc(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
        gfxPath.AddArc(Bounds.X, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);
        gfxPath.CloseAllFigures();

        gfx.FillPath(new SolidBrush(FillColor), gfxPath);
        gfx.DrawPath(DrawPen, gfxPath);
    }

Simple, but effective, ...and without bugs(I Think)))

Yuriy Flyud