Table of Contents
- Glyphs and metrics
- Loading
- load-glyph face glyph-index &key flags (target :normal) → glyph-index
- load-char face char &key flags (target :normal) → glyph-index
- Load flags
- Hinting targets
- Reading the slot
- glyph-index source → integer
- glyph-format source → keyword
- glyph-metrics source → glyph-metrics
- glyph-advance source → x, y
- glyph-linear-advance source → horizontal, vertical
- Advances without loading
- Kerning
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Glyphs and metrics
Each face has one glyph slot (see Core concepts). Loading a glyph replaces what was there, and the readers on this page report on the glyph loaded last.
Loading
load-glyph face glyph-index &key flags (target :normal) → glyph-index
Loads glyph glyph-index into the face's slot at the current size, transform and variation. Returns glyph-index.
An index outside 0 to face-num-glyphs − 1 signals :invalid-glyph-index before FreeType is called:
(ft2:load-glyph face 999999)
;; error: Glyph index 999999 is out of range: DejaVu Sans has 6253 glyphs.
;; Glyph indexes run from 0 below FACE-NUM-GLYPHS; CHAR-INDEX gives the
;; glyph for a character.
Use load-glyph for glyph indexes that come from a shaper such as HarfBuzz.
load-char face char &key flags (target :normal) → glyph-index
Loads the glyph for char, a character or an integer code in the current charmap. Returns the glyph index, which is 0 if the face lacks the character. In that case the .notdef glyph, often a box, is what gets loaded.
Load flags
flags is a list of keywords. An unknown keyword signals a type-error that lists the valid ones.
| Flag | Effect |
|---|---|
:no-scale |
Do not scale: metrics, advance and outline stay in font units. Implies :no-hinting and :no-bitmap. cl-ft2 reports font units for this glyph. |
:no-hinting |
Do not hint (grid-fit) the outline. |
:render |
Render to a bitmap right after loading, in the render mode that matches target. |
:no-bitmap |
Ignore embedded bitmap strikes and always load the outline. |
:vertical-layout |
Load for vertical text: glyph-advance is vertical. |
:force-autohint |
Use FreeType's auto-hinter even when the font has its own hints. |
:crop-bitmap |
Obsolete; ignored. |
:pedantic |
Treat minor font errors as errors. |
:ignore-global-advance-width |
Ignore the hhea advance for monospaced fonts. Rarely useful. |
:no-recurse |
Do not load the components of a composite glyph. The glyph format becomes :composite. |
:ignore-transform |
Ignore the face's transform (face-transform-matrix, face-transform-delta). |
:monochrome |
With :render, render a 1-bit bitmap. Prefer :target :mono. |
:linear-design |
Keep glyph-linear-advance in font units. |
:sbits-only |
Load embedded bitmaps only, never outlines. |
:no-autohint |
Never use the auto-hinter. |
:color |
Load color glyphs (COLRv0 layers, CBDT/sbix bitmaps) as :bgra bitmaps. |
:compute-metrics |
Compute metrics from the outline rather than trusting the font's. |
:bitmap-metrics-only |
Load only the metrics of a bitmap glyph, not its pixels. |
:no-svg |
Ignore SVG glyphs. |
Hinting targets
target selects the hinting algorithm. It is stored in bits 16–19 of the load flags (FT_LOAD_TARGET_…), and cl-ft2 combines the two for you:
| Target | Hinting |
|---|---|
:normal |
Default hinting for antialiased rendering. |
:light |
Light, vertical-only hinting. Glyph shapes and horizontal advances stay close to the unhinted design, so it matches unhinted layout from a shaper. |
:mono |
Strong hinting for 1-bit rendering. |
:lcd |
Hinting for horizontal LCD subpixel rendering. |
:lcd-v |
Hinting for vertical LCD subpixel rendering. |
These keywords make up the type hinting-target; anything else is a type-error. char-bitmap and glyph-index-bitmap choose the target that suits the render mode for you (see Rendering and bitmaps).
(ft2:load-char face #\A :target :light)
(ft2:load-char face #\A :flags '(:no-hinting))
(ft2:load-char face #\A :flags '(:no-scale)) ; design units
(ft2:load-char face #\😀 :flags '(:color)) ; color emoji fonts
Reading the slot
These readers are generic functions of a glyph source: a face, meaning the glyph in its slot, or a glyph object, which reports the values it was loaded with.
glyph-index source → integer
The glyph's index. Note that this does not look a character up; that is char-index.
glyph-format source → keyword
:outline, :bitmap, :composite, :svg or :plotter. A scalable font loads as :outline. After rendering, or for a bitmap font, it is :bitmap.
glyph-metrics source → glyph-metrics
The glyph's metrics, in pixels, or in font units after :no-scale. Bearings are measured from the pen position to the glyph's bounding box. All accessors return reals:
| Accessor | Meaning |
|---|---|
glyph-metrics-width, glyph-metrics-height |
size of the glyph's bounding box |
glyph-metrics-hori-bearing-x |
horizontal layout: pen x to the box's left edge |
glyph-metrics-hori-bearing-y |
horizontal layout: baseline to the box's top edge (up is positive) |
glyph-metrics-hori-advance |
horizontal advance |
glyph-metrics-vert-bearing-x |
vertical layout: pen x to the box's left edge |
glyph-metrics-vert-bearing-y |
vertical layout: pen y to the box's top edge |
glyph-metrics-vert-advance |
vertical advance |
(setf (ft2:face-size face) 32)
(ft2:load-char face #\A)
(ft2:glyph-metrics face)
;; => #S(GLYPH-METRICS :WIDTH 22 :HEIGHT 23 :HORI-BEARING-X 0 :HORI-BEARING-Y 23
;; :HORI-ADVANCE 22 :VERT-BEARING-X -11 :VERT-BEARING-Y 4
;; :VERT-ADVANCE 32)
(ft2:load-char face #\A :flags '(:no-scale))
(ft2:glyph-metrics face)
;; => #S(GLYPH-METRICS :WIDTH 1368 :HEIGHT 1493 :HORI-BEARING-X 16 :HORI-BEARING-Y 1493
;; :HORI-ADVANCE 1401 :VERT-BEARING-X -684 :VERT-BEARING-Y 277
;; :VERT-ADVANCE 2048)
With hinting (the default), FreeType rounds the metrics to whole pixels, so they come back as integers.
glyph-advance source → x, y
The advance vector, as two values. For the slot, this is after hinting and after the transform: with a 90° rotation, the advance of l changes from 9, 0 to 0, 9.
(ft2:load-char face #\A)
(ft2:glyph-advance face) ; => 22, 0
glyph-linear-advance source → horizontal, vertical
The unhinted advances, as two values: pixels, or font units if the glyph was loaded with :linear-design. Only meaningful for scalable faces. Use these to lay out unhinted text.
(ft2:glyph-linear-advance face) ; => 1401/64, 32
Advances without loading
glyph-index-advance face glyph-index &key flags (target :normal) → real
The advance of a glyph without loading it into the slot, which leaves the slot alone and is much faster when you only need widths. It is horizontal unless flags contains :vertical-layout, and in pixels unless flags contains :no-scale, which gives font units. flags and target are as for load-glyph, and hinting affects the result in the same way.
(ft2:glyph-index-advance face 36) ; => 22
(ft2:glyph-index-advance face 36 :flags '(:no-scale)) ; => 1401
(ft2:glyph-index-advance face 36 :flags '(:vertical-layout)) ; => 32
Measuring a string's width:
(loop for ch across "Hello" sum (ft2:glyph-index-advance face (ft2:char-index face ch)))
Kerning
kerning face left-glyph right-glyph &key (mode :default) → x, y
The kerning adjustment to add to the pen between two glyphs, as two values:
| Mode | Result |
|---|---|
:default |
grid-fitted pixels |
:unfitted |
unrounded pixels |
:unscaled |
font units |
The modes make up the type kerning-mode.
(let ((a (ft2:char-index face #\A)) (v (ft2:char-index face #\V)))
(list (ft2:kerning face a v)
(ft2:kerning face a v :mode :unfitted)
(ft2:kerning face a v :mode :unscaled)))
;; => (-2 -131/64 -131)
Faces without kerning data return 0, 0. Only the legacy TrueType kern table is read. Most modern OpenType fonts keep their kerning in the GPOS table, which only a shaper can apply. For real text, shape with HarfBuzz and render the glyph indexes and positions it produces (see Scope and limitations).
Both glyph indexes are range-checked like load-glyph's.