logoalt Hacker News

Font Rendering from First Principles

200 pointsby krapplast Sunday at 12:58 AM38 commentsview on HN

Comments

necovektoday at 7:50 AM

It's wonderful to see someone dive into this as deep. A simpler way to understand the complexity might be to try designing your own font.

Pick up a book on type and start up Fontforge, and off you go.

Be careful though, make an early choice if you are going with 3rd order curves or 2nd order (Bezier) curves.

Going through TeXbook and MetaFont books by DEK is also a brilliant way to learn about all this, with note that they do have an explicit bitmap step in.

One correction though:

  Without it, you wouldn't be reading this right now.
Computers started with bitmap fonts of different pixel sizes. Your console terminal in Linux is still using that, and nothing stops you from using them ("Fixed" has large Unicode coverage and is usually preinstalled) elsewhere too.

So no, none of this tech is necessary for us to read text on computer screens.

show 1 reply
AxiomLabtoday at 2:38 AM

Fascinating read. Font rendering perfectly encapsulates the conflict between continuous mathematical curves and discrete pixel grids.

I run into similar 'quantization' challenges when building generative design systems in Python. Sometimes a mathematically 'perfect' alignment on the grid looks optically wrong to the human eye. The anti-aliasing logic described here is a great mental model for handling those edge cases.

show 1 reply
oxoniayesterday at 11:24 PM

Too long an article (about type!) to be in white monospace text on a black background.

show 5 replies
evikstoday at 9:40 AM

> MSDF was another option I considered, you could also look at sub-pixel rendering

Seems like a much superior tech due the ability to reproduce sharp corners, would be interesting to read why the regular SDF was chosen (there are some reasons, but it's not clear which of those wouldn't apply to MSDF)

yellowsinktoday at 3:19 PM

This appears to be just Sebastian Lague's coding adventure video, copied.

show 1 reply
skobesyesterday at 11:53 PM

Why is the whole implementation in header files?

show 3 replies
_HMCB_yesterday at 11:33 PM

In the comparisons, there’s no indication which is created with his/her rendering “engine.”

akoboldfryingtoday at 2:51 AM

This was interesting, thanks. Was hoping to see a bit more about type hinting, but there's already a lot here.

A question about efficiency: IIUC, in your initial bitmap rastering implementation, you process a row of target bitmap pixels at once, accumulating a winding number count to know whether the pen should be up or down at each x position. It sounds like you are solving for t given the known x and y positions on every curve segment at every target pixel, and then checking whether t is in the valid range [0, 1). Is that right?

Because if so, I think you could avoid doing most of this computation by using an active edge list. Basically, in an initial step, compute bounds on the y extents of each curve segment -- upper bounds for the max y, lower bounds for the min y. (The max and min y values of all 3 points work fine for these, since a quadratic Bezier curve is fully inside the triangle they form.) For each of the two extents of each curve segment, add a (y position, reference to curve segment, isMin) triple to an array -- so twice as many array elements as curve segments. Then sort the array by y position. Now during the outer rendering loop that steps through increasing y positions, you can maintain an index in this list that steps forward whenever the next element crosses the new y value: Whenever this new element has isMin=true, add the corresponding curve segment to the set of "active segments" that you will solve for; whenever it's false, remove it from this set. This way, you never need to solve for t on the "inactive segments" that you know are bounded out on the y axis, which is probably most of them.

show 2 replies
gethlytoday at 7:28 AM

I'm working on my own text editor and have ventured into font rendering as well. The main thing to understand about fonts and font rendering is that they are just bitmap images and the program just puts them together with simple XY+WH from a pre-rendered square image(square because GPUs like squares), called atlas, which in CSS would be called a sprite. It's really that simple.

show 1 reply
joshmarinacciyesterday at 10:35 PM

Hugged to death?

show 1 reply
heliumteratoday at 12:29 PM

>Text can be rendered at arbitrary sizes

Fixed width monospaced, bitmap fonts.

>Fonts are generally curved, pixels are not. How should we anti-alias glyphs to keep text visually appealing?

Consolas, terminus, unscii, IBM 437 fonts...are implying they are not appealing?

>How should we design a system that respects the different layout rules of different languages (e.g. English vs. Arabic)?

Why?

7etoday at 1:38 AM

[flagged]