Table of Contents
FFI layer
cl-harfbuzz/ffi is a direct transcription, on cl-ffi, of the part of the HarfBuzz C API that cl-harfbuzz uses. Names are the C names in Lisp spelling: hb_buffer_add_codepoints → hb-buffer-add-codepoints, hb_glyph_info_t → hb-glyph-info.
It does no error checking, no lifetime tracking and no conversion beyond cl-ffi's own (enums and bitfields become keywords). Use it for HarfBuzz features the idiomatic layer does not wrap, and see the HarfBuzz API reference for the semantics.
Connecting the layers
| Function | Returns |
|---|---|
hb:face-handle face |
the hb_face_t* |
hb:font-handle font |
the hb_font_t* |
hb:buffer-handle buffer |
the hb_buffer_t* |
The pointers are owned by the Lisp objects and valid until they are destroyed. If you keep a pointer beyond that, take your own reference with hb-face-reference (for fonts and buffers, bind hb_font_reference or hb_buffer_reference yourself) and release it with the matching hb-*-destroy.
;; Read the raw glyph infos of a shaped buffer without copying into structs.
(hb:with-buffer (buffer)
(hb:buffer-add-text buffer "office")
(hb:guess-buffer-properties buffer)
(hb:shape font buffer)
(cl-ffi:with-foreign-object (n :uint)
(let ((infos (cl-harfbuzz/ffi:hb-buffer-get-glyph-infos (hb:buffer-handle buffer) n)))
(loop for i below (cl-ffi:mem-ref n :uint)
collect (cl-ffi:foreign-slot-value
(cl-ffi:mem-aptr infos '(:struct cl-harfbuzz/ffi:hb-glyph-info) i)
'(:struct cl-harfbuzz/ffi:hb-glyph-info) 'cl-harfbuzz/ffi:codepoint)))))
;; => (82 5044 70 72)
The library
libharfbuzz is the cl-ffi foreign library, loaded when the system loads:
| Platform | Tried in order |
|---|---|
| Linux and other Unix | libharfbuzz.so.0, libharfbuzz.so |
| macOS | libharfbuzz.0.dylib, libharfbuzz.dylib |
| Windows | native/windows-x64/harfbuzz.dll by full path, then harfbuzz.dll by name |
To bind more functions, use cl-ffi:defcfun in your own package; they resolve against the loaded library. hb_ft_* functions are only in builds with FreeType support (the Debian package and the bundled DLL both have it).
Types
| Type | C type | Notes |
|---|---|---|
hb-bool |
hb_bool_t |
:int; 0 is false |
hb-codepoint |
hb_codepoint_t |
:uint32; a character or, after shaping, a glyph |
hb-position |
hb_position_t |
:int32, in scale units |
hb-mask |
hb_mask_t |
:uint32 |
hb-tag |
hb_tag_t |
:uint32, four bytes big-endian |
hb-color |
hb_color_t |
:uint32, B G R A from the most significant byte |
hb-ot-name-id |
hb_ot_name_id_t |
:uint |
Enums (keywords): hb-memory-mode (:duplicate :readonly :writable :readonly-may-make-writable), hb-direction (:invalid :ltr :rtl :ttb :btt), hb-buffer-content-type (:invalid :unicode :glyphs), hb-buffer-cluster-level (:monotone-graphemes :monotone-characters :characters), hb-paint-extend (:pad :repeat :reflect), hb-paint-composite-mode (:clear … :hsl-luminosity), hb-ot-name-id-predefined (the standard name IDs of hb_ot_name_id_predefined_t, :copyright for 0 … :variations-ps-prefix for 25), hb-ot-metrics-tag (hb_ot_metrics_tag_t, :horizontal-ascender … :underline-offset, each the tag HarfBuzz gives the metric).
Bitfields (lists of keywords): hb-buffer-flags, hb-glyph-flags, hb-ot-var-axis-flags (:hidden).
Scripts (hb_script_t) and languages (hb_language_t) are passed as integers and pointers; convert with hb-script-from-string or hb-script-from-iso15924-tag, hb-language-from-string, hb-language-to-string.
Structs
| Struct | Slots |
|---|---|
hb-glyph-info |
codepoint mask cluster var1 var2 |
hb-glyph-position |
x-advance y-advance x-offset y-offset var |
hb-feature |
tag value start end |
hb-variation |
tag value |
hb-glyph-extents |
x-bearing y-bearing width height |
hb-font-extents |
ascender descender line-gap reserved |
hb-ot-name-entry |
name-id var language |
hb-ot-color-layer |
glyph color-index |
hb-ot-var-axis-info |
axis-index tag name-id flags min-value default-value max-value reserved |
hb-color-stop |
offset is-foreground color |
Slot names are exported symbols of cl-harfbuzz/ffi. Use them as (:struct cl-harfbuzz/ffi:hb-glyph-info).
Functions
| Area | Functions |
|---|---|
| version, shapers | hb-version, hb-version-string, hb-shape-list-shapers |
| tags, scripts, languages | hb-tag-from-string, hb-script-from-string, hb-script-from-iso15924-tag, hb-script-get-horizontal-direction, hb-language-from-string, hb-language-to-string, hb-language-get-default |
| blobs | hb-blob-create, hb-blob-create-from-file-or-fail, hb-blob-destroy, hb-blob-get-data, hb-blob-get-length |
| faces | hb-face-count, hb-face-create, hb-face-reference, hb-face-destroy, hb-face-get-index, hb-face-get-upem, hb-face-get-glyph-count, hb-face-get-table-tags, hb-face-reference-table |
| fonts | hb-font-create, hb-font-destroy, hb-font-get-face, hb-font-get-scale, hb-font-set-scale, hb-font-get-ppem, hb-font-set-ppem, hb-font-get-ptem, hb-font-set-ptem, hb-font-get-nominal-glyph, hb-font-get-glyph-h-advance, hb-font-get-glyph-v-advance, hb-font-get-glyph-extents, hb-font-get-glyph-name, hb-font-get-glyph-from-name, hb-font-get-h-extents, hb-font-get-v-extents |
| variations | hb-font-set-variations, hb-font-get-var-coords-design, hb-font-get-var-coords-normalized, hb-font-set-var-named-instance, hb-font-get-var-named-instance, hb-ot-var-has-data, hb-ot-var-get-axis-count, hb-ot-var-get-axis-infos, hb-ot-var-get-named-instance-count, hb-ot-var-named-instance-get-design-coords, hb-ot-var-named-instance-get-subfamily-name-id, hb-ot-var-named-instance-get-postscript-name-id |
| buffers | hb-buffer-create, hb-buffer-destroy, hb-buffer-reset, hb-buffer-clear-contents, hb-buffer-allocation-successful, hb-buffer-add-codepoints, hb-buffer-get-length, hb-buffer-get-content-type, hb-buffer-get/set-direction, hb-buffer-get/set-script, hb-buffer-get/set-language, hb-buffer-get/set-cluster-level, hb-buffer-get/set-flags, hb-buffer-guess-segment-properties, hb-buffer-get-glyph-infos, hb-buffer-get-glyph-positions |
| shaping | hb-shape, hb-feature-from-string, hb-feature-to-string |
| drawing | hb-draw-funcs-create, hb-draw-funcs-destroy, hb-draw-funcs-set-move-to-func, -line-to-func, -quadratic-to-func, -cubic-to-func, -close-path-func, hb-font-draw-glyph |
| painting | hb-paint-funcs-create, hb-paint-funcs-destroy, hb-paint-funcs-set-push-transform-func, -pop-transform-func, -push-clip-glyph-func, -push-clip-rectangle-func, -pop-clip-func, -color-func, -image-func, -linear-gradient-func, -radial-gradient-func, -sweep-gradient-func, -push-group-func, -pop-group-func, -color-glyph-func, hb-font-paint-glyph, hb-color-line-get-color-stops, hb-color-line-get-extend |
| OpenType names, metrics, layout | hb-ot-name-list-names, hb-ot-name-get-utf8, hb-ot-metrics-get-position, hb-ot-layout-table-get-script-tags, hb-ot-layout-table-get-feature-tags |
| OpenType color | hb-ot-color-has-palettes, hb-ot-color-palette-get-count, hb-ot-color-palette-get-colors, hb-ot-color-has-layers, hb-ot-color-glyph-get-layers, hb-ot-color-has-paint, hb-ot-color-glyph-has-paint, hb-ot-color-has-svg, hb-ot-color-glyph-reference-svg, hb-ot-color-has-png, hb-ot-color-glyph-reference-png |
| FreeType (hb-ft) | hb-ft-font-create-referenced, hb-ft-font-changed |
get/set means both hb-…-get-… and hb-…-set-…; a leading - continues the prefix of the row's first name.
Things to know
- Array queries follow HarfBuzz's "start offset, count in/out, array out" convention; call once with a null array to learn the total.
- Blobs returned by
hb-face-reference-table,hb-ot-color-glyph-reference-svg/pngmust be released withhb-blob-destroy. - Callbacks (draw, paint) must not unwind through HarfBuzz frames: catch errors inside them. cl-harfbuzz defines its callbacks once, statically, and passes each call's results out through a special variable bound around the call.
- Buffer flags set through the FFI are not checked against the known flags.
- Metrics:
hb-ot-metrics-get-positiontakes its metric as anhb-ot-metrics-tagkeyword, such as:x-height, or the tag as an integer.