No results
5
Scope and Limitations
dxtr edited this page 2026-10-19 18:45:57 +02:00
Scope and limitations
What HarfBuzz does, and what it leaves to others
HarfBuzz shapes one run: text of one direction, one script, one language, in one font. A text stack needs several other steps around it:
| Step | Who does it |
|---|---|
| splitting text into paragraphs, resolving bidi levels, reordering runs per line (UAX #9) | cl-icu (bidi-runs) |
| splitting runs by script (UAX #24) | cl-icu (script-runs) |
| choosing a font per run (fallback) | your code, or cl-textrender |
| shaping each run | cl-harfbuzz |
| finding line break opportunities (UAX #14), grapheme boundaries for carets (UAX #29) | cl-icu |
| choosing line breaks, justification, alignment, tabs | your code, or cl-textrender |
| rasterizing glyphs (hinting, anti-aliasing, LCD, SDF) | cl-ft2 |
| rendering outlines or color paint on the GPU (MSDF, Slug) | your engine, from glyph-outline / glyph-paint |
| normalization, case mapping | cl-icu |
cl-textrender ties these together: layout on cl-icu and plain cl-harfbuzz, with an optional cl-ft2 raster backend.
Not covered by cl-harfbuzz
These HarfBuzz APIs have no idiomatic wrapper. Most are reachable through the C API with your own cl-ffi definitions alongside cl-harfbuzz/ffi.
- Subsetting (
hb-subset). It is a separate library (libharfbuzz-subset). - Custom font functions (
hb_font_funcs_t): supplying your own glyph lookup and metrics, and sub-fonts (hb_font_create_sub_font). - HarfBuzz's own Unicode functions and AAT APIs (
hb_aat_*); AAT shaping (morx,kerx,trak) is still applied by theotshaper. - Fine-grained OpenType layout queries: lookups, language systems, glyph classes, ligature carets (
hb_ot_layout_get_ligature_carets),GDEF,BASEandMATHtable APIs, feature names (hb_ot_layout_feature_get_name_ids). - Synthetic bold and slant (
hb_font_set_synthetic_bold,hb_font_set_synthetic_slant), and hb-ft load flags (hb_ft_font_set_load_flags). - Choosing a shaper list (
hb_shape_full), shape plans, and buffer serialization / message callbacks for debugging. - WOFF/WOFF2 input: HarfBuzz itself cannot read them.
make-facerecognises and reports them.
Design limits
- Positions are in the font's units, not in a separate float space. For pixels, use an
ft2-font, setfont-scale, or scale the results yourself. shaped-glyphis a copy. Each call tobuffer-glyphsallocates a fresh vector of structs. For code that shapes again and again, read the glyphs one at a time withbuffer-glyph, which allocates nothing: shaping into a reused buffer then allocates nothing at all.- No finalizers. Objects are released explicitly or by
with-macros. - Text is passed as code points, so clusters are character indexes into Lisp strings. There is no UTF-8 or UTF-16 cluster mode.