harfbuzz-world.cc

Your one-stop HarfBuzz shop

Try:
drop font file

Welcome

harfbuzz-world.cc is a single-file build of HarfBuzz that drops into your own C or C++ project without any build-system glue, plus a live playground for it right here in your browser.

Each tab has additional resources at the bottom.

Embedding

Add HarfBuzz to your project as a submodule (or vendor a checkout next to your code). Then point your build at one file inside it — src/harfbuzz-world.cc, the amalgamation that #includes every .cc in the library so the whole thing compiles as a single translation unit:

c++ -std=c++11 -O2 \
    -I third_party/harfbuzz/src \
    -c third_party/harfbuzz/src/harfbuzz-world.cc \
    -o harfbuzz-world.o

Link harfbuzz-world.o with the rest of your program and call the public C API as usual:

#include <hb.h>
#include <hb-ot.h>

hb_blob_t  *blob = hb_blob_create_from_file ("MyFont.ttf");
hb_face_t  *face = hb_face_create (blob, 0);
hb_font_t  *font = hb_font_create (face);
hb_buffer_t *buf = hb_buffer_create ();

hb_buffer_add_utf8 (buf, "Hello", -1, 0, -1);
hb_buffer_guess_segment_properties (buf);  /* toy: real apps set script/lang/dir explicitly */
hb_shape (font, buf, NULL, 0);

unsigned len;
hb_glyph_info_t      *info = hb_buffer_get_glyph_infos     (buf, &len);
hb_glyph_position_t  *pos  = hb_buffer_get_glyph_positions (buf, NULL);
/* …draw the glyphs… */

Customizing the build

HarfBuzz reads a handful of compile-time #defines when the amalgamation is compiled. Pass them on the command line (-DHB_TINY) or via a small wrapper header that #defines them and then #includes harfbuzz-world.cc.

  • HB_TINY — turn on every size-saving knob: drop deprecated APIs, variable fonts, AAT, legacy fallbacks, hinting, glyph names, math, name table, metrics, and a long etc., and switch the compiler to size optimization. All script shapers stay in. Combine with the HB_HAS_* flags below to add back the subsystems you need.
  • HB_HAS_SUBSET — pull in the font-subsetting subsystem (hb-subset).
  • HB_HAS_RASTER — pull in hb-raster for software pixel rendering.
  • HB_HAS_VECTOR — pull in hb-vector for SVG / PDF output.
  • HB_HAS_GPU — pull in hb-gpu for slug-based GPU shaders.
  • HB_HAS_FREETYPE, HB_HAS_GLIB, HB_HAS_ICU, HB_HAS_GRAPHITE, HB_HAS_CAIRO, etc. — opt into the matching system integration.

Under HB_TINY, a few subsystems are stripped out that you may want back. Undefine the corresponding HB_NO_* flag in your override header to opt them back in. Notable one: HB_NO_AAT — gates shaping for Apple Advanced Typography tables (morx, kerx, trak, …). If your input includes Mac system fonts, undefine it.

Building for the web (Emscripten)

The same amalgamation compiles to wasm via em++; this site's wasm bundle is built exactly this way, with shape, subset, raster, vector, and AAT all enabled. The GPU tab embeds the separate hb-gpu demo.

em++ -std=c++11 -Oz -flto \
     -I third_party/harfbuzz/src \
     -DHB_TINY -DHB_HAS_SUBSET -DHB_HAS_RASTER \
     -DHB_HAS_VECTOR -DHB_HAS_GPU \
     bindings.cc third_party/harfbuzz/src/harfbuzz-world.cc \
     -sMODULARIZE=1 -sALLOW_MEMORY_GROWTH=1 \
     -sEXPORTED_FUNCTIONS='["_my_shape_export","_malloc","_free"]' \
     -o myhb.js

See this site's scripts/build.sh and src/bindings.cc for a complete working example.

Resources

Other languages

If C/C++ isn't where you live, there are first-class HarfBuzz bindings for several other ecosystems:

  • uharfbuzz — Pythonic bindings, used by FontTools and friends.
  • harfbuzzjs — JS / wasm wrapper for web pages and Node.
  • harfrust — pure-Rust port, no C dependency.

Powered by HarfBuzz
the ffmpeg of text rendering
Feedback