A technical history and practical summary of how glyphs, fonts, and signed distance fields for vector maps were created back in the Mapbox days and how things look today after the MapLibre fork.

Mapbox introduced signed distance field (SDF) glyphs for efficient GPU text rendering in Mapbox GL; glyphs are packaged as small protobuf (.pbf) files indexed by Unicode ranges and served from a “glyphs” URL in the style.

The first blog post I see on this topic from Mapbox was on Jun 16, 2014 by Konstantin Käfer (PDF).

Jeshurun Hembd has a good write up on the history and nitty gritty on how to parse the protobuf. (PDF)

Mapbox era… how and why it worked that way (~ 2014)

  1. Why SDFs: WebGL (and mobile GL) don’t have native variable font text rendering. Mapbox adopted signed distance fields (SDF) so glyphs can be scaled, blurred (for halos), rotated, and rendered sharply by fragment shaders at many sizes without raster artifacts. This approach was explained early by Mapbox engineers and adopted across the GL renderer.

  2. How glyphs were packaged: Rather than shipping raw true type font (TTF) to the GPU, Mapbox converted font glyph outlines to SDF tile images and encoded them in small protobuf files. Files are grouped by Unicode ranges (0–255, 256–511, etc.) and addressed with a /fontstack/{range}.pbf URL pattern referenced in the style’s glyphs property. The GL runtime requests only the ranges it needs.

  3. Server side hosting and the Fonts API: Mapbox ran a Fonts API / font hosting service (and Mapbox Studio to manage fonts/styles) so styles could reference mapbox://fonts/… and the hosted service returned PBF glyphs on demand. This simplified things for users but created a hosted dependency and licensing considerations for some proprietary fonts.

Post MapLibre Fork Landscape (~ Dec 2020)

  1. Compatibility first:. When MapLibre forked Mapbox GL JS, it kept the style spec and the glyphs/PBF approach (MapLibre style spec uses the same glyphs RFC). That meant existing styles and glyph servers stayed usable. https://maplibre.org/maplibre-style-spec/glyphs

  2. Community tooling & open font push: Without Mapbox hosted fonts, the community built tools and hosted fonts itself. MapLibre Font Maker is an easy way to convert TTF/OTF to MapLibre compatible glyph PBFs (makes fontstacks and ranges)

  3. Open font stacks & licensing: The MapLibre ecosystem has pushed to rely on open fonts (Noto, DejaVu, Open Sans, etc.) and remove proprietary fonts from example repos. Several community repos publish ready made glyph PBFs and font stacks so users can self host. (There are ongoing issues/pulls to remove non OSS fonts from examples.) https://github.com/UNDP-Data/fonts

  4. Better tooling for global scripts and shaping: Handling Chinese, Japanese, Korean (CJK) or complex scripts required attention: CJK ranges are huge, and complex shaping (Arabic, Indic scripts) requires proper shaping engines (HarfBuzz) before rasterization. Community tools have been evolving to include shaping and multi font fallback strategies. There are still active discussions and enhancements to support universal fallback fontpacks. https://github.com/maplibre/font-maker/issues/16

How to Make and Host Glyphs Today (~2023)

  1. Pick fonts (open source recommended). Choose primary + fallbacks (e.g., Noto Sans, Noto Sans CJK, DejaVu)
  2. Generate them with MapLibre Font Maker
  3. Host them (any static server/CDN). Arrange files as http://font.example.com/{fonstack}/{range}.pbf?key={key} and make sure your style’s glyphs value points at that template. MapLibre will request ranges on demand.
  4. Careful with CJK / ideographs. For CJK heavy maps, either, use localIdeographFontFamily to rely on local OS fonts for large CJK ranges (Mapbox provides this option), or generate huge range PBFs for CJK (but be mindful: very large download sizes). https://docs.mapbox.com/mapbox-gl-js/example/local-ideographs

References: