Create rectangles with rounded corners

Create rectangles with rounded corners

A Rectangle with rounded corners is not a standard shape. However it is easy to create these.

Using four freehand line segments you can create a normal rectangle. To create rectangles with rounded corners just add bezier segments, one for each corner:

// Rounded rectangle class that can be added to an overlay
public class RoundedRectangle : FreeHandShape
{
    public RoundedRectangle(double x1, double y1, double x2, double y2, double r)
    {
        base.Pen = new Pen(Color.Black); // default pen
        base.Brush = new SolidBrush(Color.White); // default brush
        r = System.Math.Min(r, System.Math.Abs(x2 - x1) / 2);
        r = System.Math.Min(r, System.Math.Abs(y2 - y1) / 2);
        var path = new FreeHandPath();
        path.Closed = true;
        path.Segments.Add(new FreeHandStartSegment(x1 + r, y1));
        path.Segments.Add(new FreeHandLineSegment(x2 - r, y1));
        path.Segments.Add(new FreeHandBezierSegment(x2 - r, y1, x2, y1, x2, y1 + r));
        path.Segments.Add(new FreeHandLineSegment(x2, y2 - r));
        path.Segments.Add(new FreeHandBezierSegment(x2, y2 - r, x2, y2, x2 - r, y2));
        path.Segments.Add(new FreeHandLineSegment(x1 + r, y2));
        path.Segments.Add(new FreeHandBezierSegment(x1 + r, y2, x1, y2, x1, y2 - r));
        path.Segments.Add(new FreeHandLineSegment(x1, y1 + r));
        path.Segments.Add(new FreeHandBezierSegment(x1, y1 + r, x1, y1, x1 + r, y1));
        this.Paths.Add(path);
    }
}
Public Class RoundedRectangle
    Inherits FreeHandShape
    Public Sub New(x1 As Double, y1 As Double, x2 As Double, y2 As Double, r As Double)
        MyBase.Pen = New Pen(Color.Black)
        ' default pen
        MyBase.Brush = New SolidBrush(Color.White)
        ' defualt brush
        r = System.Math.Min(r, System.Math.Abs(x2 - x1) / 2)
        r = System.Math.Min(r, System.Math.Abs(y2 - y1) / 2)
        Dim path = New FreeHandPath()
        path.Closed = True
        path.Segments.Add(New FreeHandStartSegment(x1 + r, y1))
        path.Segments.Add(New FreeHandLineSegment(x2 - r, y1))
        path.Segments.Add(New FreeHandBezierSegment(x2 - r, y1, x2, y1, x2, y1 + r))
        path.Segments.Add(New FreeHandLineSegment(x2, y2 - r))
        path.Segments.Add(New FreeHandBezierSegment(x2, y2 - r, x2, y2, x2 - r, y2))
        path.Segments.Add(New FreeHandLineSegment(x1 + r, y2))
        path.Segments.Add(New FreeHandBezierSegment(x1 + r, y2, x1, y2, x1, y2 - r))
        path.Segments.Add(New FreeHandLineSegment(x1, y1 + r))
        path.Segments.Add(New FreeHandBezierSegment(x1, y1 + r, x1, y1, x1 + r, y1))
        Me.Paths.Add(path)
    End Sub
End Class

Which draws a rectangle like this:

Rectangle

double width = 121.35;
double height = 75.00;
double x = 30.00;
double y = 570.00;
var r1 = new RoundedRectangle(x, y, x + width, y + height, 14);
r1.Pen = new Pen(Color.Black, 2, new DashPattern(1, new double[] { 3, 1 }));
r1.Brush = new AxialGradientBrush(Color.PeachPuff, Color.Purple, x, y + height, x, y);
page.Overlay.Add(r1);
Dim width As Double = 121.35
Dim height As Double = 75.0
Dim x As Double = 30.0
Dim y As Double = 570.0
Dim r1 = New RoundedRectangle(x, y, x + width, y + height, 14)
r1.Pen = New Pen(Color.Black, 2, New DashPattern(1, New Double() {3, 1}))
r1.Brush = New AxialGradientBrush(Color.PeachPuff, Color.Purple, x, y + height, x, y)
page.Overlay.Add(r1)

It is of course possible to make variations in the color, pen-size and other parameters. This code will demonstrate it:

// draw a couple of colored rectangles on the PDF document, 
// demonstrating variations in color, rounding and line width
double x = 0;
double y = 0;
double width = 161.80 * 0.75;
double height = 100.00 * 0.75;
for (x = 30.00; x < 600.00 - width; x += width + 20)
{
   for (y = 130.00; y < 500.00 - height; y += height + 20)
   {
      double line = (x + y) / 80; // the linewidth
      double r = (x + y) / 20;    // radius of the rounded corners
      int grad1 = (int)x / 2;     // color each rectangle different
      int grad2 = (int)y / 2;
      int grad3 = 100;

      // create rounded rectangles, one at the time
      var rectangle = new RoundedRectangle(x, y, x + width, y + height, r);
      rectangle.Pen = new Pen(Color.FromArgb(grad1, grad2, grad3), line);
      rectangle.Brush = new SolidBrush(Color.FromArgb(grad3, grad1, grad2));
      page.Overlay.Add(rectangle);
   }
}
' demonstrating variations in color, rounding and line width
Dim x As Double = 0
Dim y As Double = 0
Dim width As Double = 161.8 * 0.75
Dim height As Double = 100.0 * 0.75
x = 30.0
While x < 600.0 - width
	y = 130.0
	While y < 500.0 - height
		Dim line As Double = (x + y) / 80
		' the linewidth
		Dim r As Double = (x + y) / 20
		' radius of the rounded corners
		Dim grad1 As Integer = CInt(x) / 2
		' color each rectangle different
		Dim grad2 As Integer = CInt(y) / 2
		Dim grad3 As Integer = 100

		' create rounded rectangles, one at the time
		Dim rectangle = New RoundedRectangle(x, y, x + width, y + height, r)
		rectangle.Pen = New Pen(Color.FromArgb(grad1, grad2, grad3), line)
		rectangle.Brush = New SolidBrush(Color.FromArgb(grad3, grad1, grad2))
		page.Overlay.Add(rectangle)
		y += height + 20
	End While
	x += width + 20
End While

Which will give the following result:

Rectangles