Writing a TrueType font renderer

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • SaaSHub - Software Alternatives and Reviews
  • libschrift

    A lightweight TrueType font rendering library

  • "Needed" is subjective. Libschrift[1] is an example of a TTF renderer that doesn't do any. I translated Libscrift to Ruby[2], and I considered whether to add support for it, and decided it wasn't worth it for my use. Maybe one day, but I'll note e.g. FreeType did a lot of work on auto-hinting because as it turns out the hinting in a lot of TTF files is pure garbage.

    [1] https://github.com/tomolt/libschrift

    [2] https://github.com/vidarh/skrift - X11 integration in https://github.com/vidarh/skrift-x11

  • skrift

    A pure Ruby conversion (*not* wrapper) of the libschrift TrueType font renderer

  • https://github.com/vidarh/skrift

    Libschrift is very readable.

    I did my Ruby rewrite basically just top to bottom before reorganizing it. Mine is... readable if you're well versed in Ruby, but still has some warts where it's less than idiomatic Ruby because I stuck closely to the original.

    Basically TTF has a crufty binary format, but the basic font data if you're willing to ignore ligatures, hinting, OpenType support and emoticons, is fairly simple (it's basically a bunch of polygons consisting of quadratic beziers and lines, and quadratic beziers are easy to tesselate into lines if you don't want to do a more complex curve renderer), just error-prone to figure out.

    If you want/need OpenType you need to support cubic beziers on top of that, which isn't that bad. If you want to support emoticons you need to support a subset of SVG (!)...

    So TTF without those bits is pretty much the halfway point.

    Also do look at the Canvas C++ header implementation linked in this comment[1]. It's readable, and more featureful than libschrift or my Ruby rewrite, and it's still small while packing a full rendering library in there not just the font renderer. I intend to pillage it (with credits) for ideas ;)

    [1] https://news.ycombinator.com/item?id=38839114

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • stb

    stb single-file public domain libraries for C/C++

  • Great to see more accessible references on font internals. I have dabbled on this a bit last year and managed to have a parser and render the points of a glyph's contour (I stopped before Bezier and shape filling stuff). I still have not considered hinting, so it's nice that it's covered. What helped me was an article from the Handmade Network [1] and the source of stb_truetype [2] (also used in Dear ImGUI).

    [1] https://handmade.network/forums/articles/t/7330-implementing....

    [2] https://github.com/nothings/stb/blob/master/stb_truetype.h

  • game_dev_pdfs

    Collection of game development related white papers

  • Here's a link to a Valve paper from 2007 Siggraph but certainly there's been a lot of dev since then but this is kind of cool still!

    https://github.com/Michaelangel007/game_dev_pdfs/blob/master...

    relevant: https://faultlore.com/blah/text-hates-you/ ("Text Rendering Hates You"; discussed quite a bit but under its old URL https://hn.algolia.com/?query=text%20rendering%20hates%20you... )

    It's not quite one of the "misconceptions programmers have about ..." but in the same vein, IMHO

  • canvas_ity

    A tiny, single-header <canvas>-like 2D rasterizer for C++

  • I have a small TTF implementation that's in the neighborhood of that size and is open source. It's part of my canvas_ity single-header library [0] that's around 2300 LOC / 36 KB object size and implements a C++ version of most of the 2D HTML5 canvas spec [1].

    The core implementation of the TTF parsing and drawing is in L1526-L1846 with another small bit at L3205-L3274 of src/canvas_ity.hpp.

    It's something of a toy implementation that only supports western left-to-right text, and doesn't do any hinting at all, nor kerning, nor shaping. But it's enough to draw a basic "Hello world!" using any typical TTF file.

    The test suite in test/test.cpp L84-304 embeds a few custom Base64-encoded TTF files. They're small and only have a few glyphs but they do exercise a number of interesting edge cases in the OpenType TTF spec [2]. Have a look at the HTML5 port of the test suite at test/test.html in different browsers to see how their canvas implementations render those fonts.

    [0] https://github.com/a-e-k/canvas_ity

    [1] https://www.w3.org/TR/2015/REC-2dcontext-20151119/

    [2] https://standards.iso.org/ittf/PubliclyAvailableStandards/c0...

  • Ultralight

    Lightweight, high-performance HTML renderer for game and app developers.

  • [2] https://ultralig.ht/

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts