Bézier Curves and Type Design: A Tutorial

[2026/09/14]: This article became the most popular I've ever written. Since it was written a long time ago, I decided to rework it: polishing the wording to facilitate comprehension, fixing dead links and typos, and adding interactivity. Still, it remains faithful to the original — a lot of people discussed it and helped me flesh it out into what it became, and I want it to continue reflecting that process. Enjoy!

Whenever I am asked to assess the quality of a typeface or logotype, or when someone asks me for help with their typefaces, one of the most common problems I find is bad Bézier curve design.

And every single time this happens, it’s not people’s fault. It is a fatalism of existence: if people knew better, they’d do better. Surprisingly, it seems that a lot of people have trouble wrapping their heads around this: students struggle with it, fellow lecturers despair.

And then there’s that heart-stabbing situation when someone drops by and says “Hey, I just finished this font, can you have a look and see if something’s missing?” and I feel obliged to say, with grief, “You have to redesign it all over: it’s poorly designed, Bézier-wise”.

So, in order to save some people from this hassle, read along.

1. Problems

First of all, we should understand that each piece of desktop publishing software is going to compile the font files in its own way. Moreover, each one of them is going to convert the curves through its unique algorithm, sometimes unleashing hell.

Flash IDE [now Adobe Animate], for example, is notorious for wrecking curves. It does so based on the size of your vector artwork in order to keep the file as small as possible. If fonts are not embedded, the same happens.

Some programs, like 3D applications, simply break the curve into several facets. So even if you are doing something in Illustrator to use in 3DS Max, for example, read on; it might save you some trouble.

2. Reasons

Usually, all of this revolves around how PostScript and TrueType deal with outlines: TrueType uses quadratic Bézier curves, and PostScript uses cubic Bézier curves.

I know, I know, geek stuff. Here’s the simple explanation:

And for the visual type of person, here’s an image:

So, if we were to draw a circle in both curve equations, they would be drawn the following way:

Let’s count the number of points needed for each circle:

Counting points might seem unpractical and silly, but it can tell you a couple of things right away:

If this is so, it seems that cubic curves win over quadratic ones; so why aren’t quadratic curves obsolete?

3. Digging deeper

But how are Bézier curves calculated? Let’s start with quadratic curves.

3.1 Quadratic Curve rasterization

We have our three points: two anchors (in and out) and one control point. Let’s call the anchors A1 and A2, and call the control point C. Next, let’s connect A1 to C and C to A2 with straight lines, as shown below:

Drag the orange points to reposition them.

Now, we’ll add two points: one that travels from A1 to C and another that travels from C to A2, and they’ll take exactly the same time to make their trip. And for the sake of this exercise, we’ll also add a straight line that connects the two traveling points (shown in black, below):

Drag the orange points to reposition them.

Again, let’s add a new point, one that travels between the two black points, taking the same time to travel from one point to another (shown below in white). If we track its path while traveling, voilà, we have our quadratic curve rasterized:

Drag the orange points to reposition them.

OK, so now you know how a computer renders a Bézier curve:

3.2 Cubic Curve rasterization

So, what about cubic curves? Is the rasterization done the same way?

Well, yes, sort of. It just adds another level of our “traveling points”. Have a look:

Drag the orange points to reposition them.

See what they did there? Right, a moving quadratic curve inside a cubic one!2 Here’s some deductions on cubic curve rasterization:

3.3 Going back and forth

The addition of multi-order intermediate points can go down to infinity, and it’s possible to break cubic curves into quadratic with minimal loss in quality. The other way around, well… it gets tricky.

Quadratic curves are always conic sections, while Bézier curves that have more than one level are a result of curve funkiness, meaning, a collage of cone sections’ sections.

So if we were to write an algorithm to convert cubic curves to quadratic, we would have no problem: we would just check for cone sections that would fit on that curve.

But if we were to write one to convert quadratic to cubic, the best the program could do is an approximation of the original outline, usually keeping the anchor points it already had, but adding one more control point per anchor. So, file size wise, not a good idea; processing power wise, even worse.

Edit: As it was stated over at Hacker News by simias and jacobolus, and kindly explained by nanofortnight, the above statements are wrong — in fact, the truth is the very opposite.

If we were to convert a quadratic curve to cubic, it would be the exact same curve, as nanofortnight demonstrated. But, as jacobolus pointed out, due to the integer structure of font compiling, this conversion might not be exact.

And when we go to convert cubic curves to quadratic, it’s not as easy-peasy as I stated above. For further reading on this, check this out.

Is this a problem, then? Well, these conversion issues are the reason why DTP software and printers favour PostScript, i.e., cubic Bézier curves. If the drawing was provided in quadratic curves, the software could easily convert them to cubic; if it was already in cubic, it would simply keep it that way.

So, while designing type, you opt either for TrueType or PostScript. And, while this makes me favour PostScript, if you start with one, stick with it.

But why do type design applications offer cubic curves only or have them as default, as a drawing method? Well, as debated, conversion from TrueType to PostScript is optimal and the other way around is not. And the third reason comes next.

4. File Size

We already know that you can draw the same thing with cubic curves using fewer points, but there are also some other things that we can take into consideration, regarding file size.

4.1 Always work with integers

FontLab [Studio3], for example, doesn’t even let you use decimal coordinate data, and no sane developer will build a vector drawing application that would allow point data to infinity. Since we still need a worldwide network of computers just to find some more pi digits, no one gets to treat themselves to perfect circles.

But then again, if your eye can’t tell the difference and, in fact, you still have to cheat the circle to make it look like a circle (when you adjust forms optically), using decimal numbers on type design is just some sort of geek stubbornness.

And there’s the workflow issue: ask any professional type designer if they use Illustrator — or another vector drawing application that uses decimal numbers by default — and you’ll find that very few say yes; and even those who do still have to adjust their drawings in a font editor.

It’s way easier to nudge with the keyboard arrows than to use a text box to input integer values. On the other hand, a lot algorithms used for font handling in DTP software simply round the points to integers, so they can handle them with less storage and processing resources.

Edit: And, as Pomax kindly pointed out, the OpenType specs only allow for integer point coordinates anyway.

But the big issue here is file size: if you have a file with integers and 4 points, it will be smaller than a file with two decimal figures and 2 points. Make some thousands of points and the difference in file size balloons, as well as processing requirements.

5. Always work with cubic curves

Cubic curves win, for all the reasons mentioned above: easier to draw with [there are more reasons for this, keep reading], better conversion to quadratic than the other way around, smaller file size. You know the drill.

But it is also worthy of note that this is why cubic is the safe default when we start drawing fonts — conversion to quadratic is lossless, so your outlines are always reproducible by other tools and designers.

6. Keep anchor points at extrema – and handles straight

This is a big one. Most of the time, the most common problem I see is that the anchor points are haphazardly positioned, spread all over the place. This results in jagged lines, poor rasterization, bigger file sizes (who hasn’t tried to fix something by adding more, right?), increased difficulty in drawing, and the list goes on.

If you want to draw a smooth curve, having the anchor points at the horizontal and vertical extrema and keeping the handles vertical or horizontal is enough. It gives you better control over the curve path and less stuff to adjust: it keeps most of your curve segments under 90º and transitions predictable.

Edit: And, although implied above, is good to mention: do not invert the path direction with your handles (thanks to Pedro Amado for pointing that out). Here’s what I mean:

Keep in mind that we’re talking about what should be in your final output. Although I recommend keeping your placements tidy and as close as possible to what it should be, inverting the direction like in the image above can be a way to draft quickly4.

Edit: 7. Explicit Inflection Points

Hrant Papazian made me notice, on Twitter, that I’ve missed a point (pun intended!). The example above, on the right, lacks an explicit inflection point.

“What the hell is that?”, you may ask. Well, in an ideal scenario, all points should alternate between vertical and horizontal handle position. Why? Because we want to keep each curve segment without inflection points, in order to have an optimal conversion from cubic to quadratic.

“OK, lovely, but you haven’t explained what an inflection point is”. True. Here it is: the inflection point is where the curve changes direction. So, if you’re walking from left to right and start leaning to the left, the place where you start doing so is your path’s inflection point5. Simple.

So, in the example in §6, the curve changes paths between the two horizontal handles, creating an inflection point. How to avoid it? Well, make it explicit; i.e., add an anchor point in that location. This way, the curve is split into one-direction-only segments:

bezier010

For more  information on inflection points, have a read here.

Edit: Also worthy of note, pay attention to how the handles retract at every step of the way. Even if you thought “Yeah, of course it does” — kudos to you, tap yourself in the back on my behalf — the bounding box for coordinate control also got smaller. This makes our life easier while editing: we get a better view to what we’re doing.

8. Final considerations

I know this was lengthy and somewhat technical, but I believe it’s important to know why instead of just how. Computers have limitations – and will always have – so it’s important to make the best of it; and for that, knowledge is key.

I hope you had as much fun reading this as I had making this article. Thanks for your time!


References:

  1. Anchor node is a general term for insertion and end points of a curve segment. Since the curve always goes through these, they “anchor” the curve to it. ↩︎
  2. This algorithm for drawing/splitting curves is de Casteljau’s algorithm. ↩︎
  3. FontLab has supported floating point coordinates since version VI. But it still compiles to integers. Just a relic of how long ago this was written. ↩︎
  4. Let me also state that whenever I do this, I add the extrema points right away: there’s not much control in drawing such a huge angle and inversion with just two points, especially when it comes to curve tension. ↩︎
  5. I encourage you to go back to §3.2, where you have the interactive cubic curve animation. Drag points around so that you have a curve and countercurve and pay attention to the gray line — you can see exactly when the curve “flips” direction. ↩︎