Skip to content

Interface Text Output

Blender draws text in the interface using the FreeType library.

We typically output text using a simplified public API. The following will print out some text using the default font:

const int id = BLF_default();
BLF_size(id, 20.0f);
BLF_position(id, 100.0f, 10.0f, 0.0f);
BLF_draw(id, "Test", 5);

Internally the code is much more complex:

Font Stack & Fallback

The latin range is convered by DejaVuSans, so that can be considered the font used for the Blender interface.

Besides that Blender ships with 24 different fonts (in release/datafiles/fonts). These range from regular Latin text to symbols, emojis, many languages, and a "last resort" font. They act together as a fallback stack, so if the requested glyph is not found in one the system looks in the others (narrowing down the search by using each font's OS/2 Unicode range coverage bits) - see blf_glyph_index_from_charcode. Fonts that are unused (like languages you don't know) are never loaded. And since we use the FreeType Caching subsystem fonts are also unloaded if not used for a while or if we get low on resources.

Font

The FontBLF struct encapsulates everything needed to draw with a font file. It includes the path (or memory pointer), FreeType library handle, FreeType face pointer, flags, positioning information, a kerning_cache for doing simple (old-style) "kern" table pair kerning, information about variable font axes, and a list of GlyphCacheBLF glyph caches.

Outputted strings are processed one Unicode character code at a time. We therefore cannot yet do complex shaping as that requires processing strings together for context (differing glyphs depending on word position, for example). Glyphs are placed at truncated positions at an advancing pen position that is also integer truncated, so our spacing is 1/2 pixel too close - but that is unscaled so it becomes less apparent as the text size increases. Kerning (old style using the "kern" table) is currently disabled on our main font because the too-close spacing plus kerning can result in glyphs that touch. We have plans to address these issues.

Glyph Cache

The GlyphCacheBLF struct contains a cache of glyphs, rendered at a particular size and with specific attributes and properties. This cache must be acquired and released as that also locks and unlocks a mutex for concurrency protection.

  GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
  blf_font_draw_ex(font, gc, str, str_len, r_info, 0);
  blf_glyph_cache_release(font);

Glyphs

The GlyphBLF struct contains information about a singular glyph, created with specific attributes, from a Unicode codepoint. It includes the dimensions, bounding box, bitmap, hinting correction, and more.

By default glyphs are loaded with FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING, although we might change to a default of BLF_HINTING_SLIGHT. We currently only use a render mode of FT_RENDER_MODE_NORMAL (or FT_RENDER_MODE_MONO to turn off antialiasing), but have plans to support all render modes including FT_RENDER_MODE_SDF. We currently only output bitmaps in FT_PIXEL_MODE_GRAY, but have plans to support all formats including FT_PIXEL_MODE_BGRA.

Glyphs can be altered before rendering by Variation axes and transformed (emboldened, slanted, translated), but these are largely hidden from users for now.

API

For more specific information, look at these files:

source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf.cc
source/blender/blenfont/intern/blf_internal.h
source/blender/blenfont/intern/blf_internal_types.h
source/blender/blenfont/intern/blf_font.cc
source/blender/blenfont/intern/blf_glyph.cc