Rounded Corners: Techie Talk

Rounded Corners

Powwownow is available in so many countries that we offer comprehensive lists of dial-in numbers in PDF form. There are a great many combinations of services and languages, and new access numbers can be added over time, so generating these documents automatically makes far more sense than maintaining every version by hand.

While updating the PDFs, I noticed that the rounded corners weren’t printing properly. We had been using four small background images with the corners drawn on them, but background images could sometimes disappear when customers printed the PDF. That wasn’t ideal, particularly when the marketing department expected everything to look exactly as intended.

It immediately occurred to me that drawing the corners using vector graphics would make more sense. Vector elements are part of the PDF itself rather than separate background images, making them much more suitable for something that needs to print consistently.

At the time, the PDF generator we were using, FPDF, didn’t provide the rounded-corner behaviour we needed directly in our implementation, so I started looking at how the effect could be created mathematically.

I needed trigonometry. It was just like being back in maths class at school. I flicked ink at the boy next to me, blew spit balls at the office manager when his back was turned and stared at the clock. Then I did some trigonometry.

I initially tried to work out a formula for moving from one point on a circle to another, but then realised that would simply leave me with the outline of a circle rather than the solid shape I needed. So I changed tack and realised the solution was much simpler.

If you start from the centre point, the coordinates of points around a circle can be calculated using sine and cosine. PHP provides both sin() and cos(), with angles supplied in radians.

My plan was to start from the corner I wanted to round and draw a series of lines inward towards the boundary of an imaginary circle. If enough lines were drawn closely together, they would cover the unwanted part of the rectangle and visually create a smooth rounded corner.

Corner Range in degrees Range in π radians
Bottom right 0 to 90 0 to 0.5
Bottom left 90 to 180 0.5 to 1
Top left 180 to 270 1 to 1.5
Top right 270 to 360 1.5 to 2

PHP’s trigonometric functions work in radians rather than degrees. A full circle contains 2π radians, meaning each quarter-circle occupies a range of 0.5π radians. PHP also provides a useful deg2rad() function when converting degree values into radians.

Once the ranges were defined, all I needed to do was specify which corner I wanted to create and calculate the appropriate start and end angles. I could then move through that range in small increments, calculating each point around the imaginary circle and drawing the corresponding lines.

And you know what? It worked.

The next step was to make the lines dense enough that the result appeared to be a solid shape rather than a collection of individual strokes. Instead of using a fixed interval, the spacing could be related to the radius so that larger corners automatically generated more lines.

There was another challenge when applying the technique to all four corners. The imaginary circle needed to sit inside the main coloured area, offset by one radius in the appropriate X and Y directions.

Corner X offset Y offset
Bottom right – –
Bottom left + –
Top left + +
Top right – +

Once the correct offset and angle range were combined, the same underlying approach could generate each of the four corners.

One final issue was a slightly ragged edge where the straight ends of the individual lines could still be seen. Moving the imaginary circle a tiny distance beyond its theoretical position hid those ends outside the coloured area and produced a much cleaner result.

Today there are easier ways to achieve the same result. The official FPDF site includes a rounded rectangle implementation that draws the curves directly, so there is generally no need to recreate this particular workaround from scratch. :contentReference[oaicite:0]{index=0}

Still, it was a satisfying reminder that a little geometry can solve surprisingly practical programming problems.

But of course I’m forgetting the most important stage: messing around with the settings until the international dial-in PDF turns into a collection of beautiful moiré patterns.

A vast improvement, I’m sure you’ll agree.

Leave a Comment

Your email address will not be published. Required fields are marked *