Text geometry
The optional @pibbl/text package converts one text run into editable
PathGeometry. HarfBuzz shapes the whole run,
including kerning, ligatures, and mark positioning, before Pibbl copies its outlines
into independent geometry. Importing the package does not initialize WASM.
import { loadOutlineFont, createTextGeometry } from "@pibbl/text";
async function label(bytes: Uint8Array) { using font = await loadOutlineFont(bytes); return createTextGeometry(font, "Hello Pibbl", { fontSize: 96, features: { kern: true, liga: true }, });}The returned geometry remains usable after the font is disposed. Pass it to
<Path style={{ d: result.geometry, fill: "teal" }} />, inspect its segments,
or edit its control points. Geometry mutation does not schedule a repaint;
update a signal or state after editing, as in the
editable text example.
Load and own a font
Section titled “Load and own a font”loadOutlineFont(source, options?) accepts a URL string, URL, ArrayBuffer,
or Uint8Array. Strings mean URLs; Node callers read filesystem bytes themselves.
An offset typed-array view is respected and copied before asynchronous work.
OutlineFontOptions.signal cancels a download. Failed or canceled acquisition
returns no font owner.
OutlineFont implements dispose() and [Symbol.dispose]() with the same
synchronous, idempotent cleanup. Use using font = await loadOutlineFont(...)
for a local conversion or retain one font across edits and call dispose() on
teardown. A retained font must outlive every conversion that uses it. Loading
belongs outside Pibbl’s synchronous component evaluation.
using requires runtime Symbol.dispose support and a compatible syntax target
or compiler transform. TypeScript consumers include ESNext.Disposable (or
ESNext) in their configured libraries. Pibbl does not install a global polyfill. Explicit
dispose() works without using syntax. Generated paths and metrics hold no
borrowed WASM views. Disposing a font releases its native resources; the shared
WASM memory may retain its high-water capacity for later reuse.
Supported containers are outline TTF and OTF (quadratic TrueType and cubic CFF outlines). WOFF, WOFF2, collections, and system-font/CSS lookup are not supported. No font fallback is performed. Variable fonts use their default instance; there is no axis or face-selection API in this release.
Fonts declaring COLR, SVG, sbix, CBDT, or EBDT presentation tables are rejected by
default. Set monochromeFallback: true to explicitly request their ordinary
outlines. This does not convert colors, bitmap images, or SVG artwork; a usable
outline is still required. The check is conservative for the entire font.
Convert one run
Section titled “Convert one run”createTextGeometry(font, text, options) is synchronous. TextGeometryOptions
requires a finite positive fontSize in logical units. Optional fields are:
| Option | Meaning |
|---|---|
features |
Up to 64 four-character OpenType tags mapped to booleans, such as { liga: false }. |
direction |
"ltr" or "rtl"; otherwise inferred by HarfBuzz. |
script |
Four-character ISO 15924 script tag, such as "Arab". |
language |
ASCII language tag, such as "ar" or "en-US", up to 63 characters. |
missingGlyphs |
"error" (default) or explicit "notdef" substitution. |
maxSegments |
Integer output limit from 1 to 1,000,000; default 1,000,000. |
The origin is baseline (0, 0), with positive Y down. Negative bearings are
preserved. RTL glyphs remain in HarfBuzz’s output order. There is no paragraph
bidi algorithm, line wrapping, vertical layout, rich text, caret mapping, or
font fallback. Tabs and line breaks are rejected.
Results and editing
Section titled “Results and editing”TextGeometryResult contains:
geometry: a new mutablePathGeometry, preserving curves and closed contours.advance: readonly X/Y layout advance, including whitespace.inkBounds: readonlyInkBounds(x,y,width,height) using curve extrema, ornullfor empty ink. This differs from the advance.glyphs: readonlyTextGlyphrecords withglyphId, UTF-16cluster,segmentStart,segmentCount,x,y,xAdvance, andyAdvance.
Clusters are source string indices, not character, grapheme, or caret indices. Several glyphs may share a cluster, and RTL cluster indices can descend. Whitespace may have advance and zero segments. Metadata describes the initial conversion: later edits do not update its segment ranges, metrics, or bounds. No per-glyph path copies are created eagerly.
Font inputs are limited to 32 MiB, text to 100,000 UTF-16 units, shaped output to 200,000 glyphs, and extraction to a shared 2²⁴ native work-unit budget. Malformed inputs, missing glyphs, nonfinite results, and exceeded limits throw without returning partial geometry. These bounds do not guarantee a shaping timeout. Reuse fonts and generated paths; do not reshape static text every frame.
Browser assets
Section titled “Browser assets”The published package includes precompiled WASM; consumers need no native SDK.
Browser bundlers select browser-only loader code. Bundlers that process
new URL(..., import.meta.url) should emit the WASM asset. For a plain esbuild
pipeline, copy dist/engine.wasm from the installed package beside the emitted
engine chunk and serve it as application/wasm. Test the production output,
including any application base path. Node loading resolves the packaged binary
relative to the installed loader.
Build-time generation is a planned follow-up; the runtime package does not yet provide a generator or compressed-webfont decoder.
HarfBuzz interns language tags for the shared engine lifetime. To bound that memory, an engine accepts at most 256 distinct explicit language tags, compared case-insensitively. Existing tags and inferred language remain usable after that limit; disposing a font does not reset it.
API details from source
Section titled “API details from source”
InkBounds
Section titled “InkBounds”Axis-aligned bounds of visible glyph outlines in logical output coordinates.
interface InkBoundsRelated API: InkBounds.
See also
Section titled “See also”View source — packages/text/src/lib/bounds.ts:8
Properties and methods
Section titled “Properties and methods”
x
readonly x: numberHorizontal coordinate or displacement in the containing coordinate system. See InkBounds.
y
readonly y: numberVertical coordinate or displacement in the containing coordinate system. See InkBounds .
width
readonly width: numberHorizontal extent in the units of the containing geometry or surface. See InkBounds.
height
readonly height: numberVertical extent in the units of the containing geometry or surface. See InkBounds.
OutlineFont
Section titled “OutlineFont”An explicitly owned native font loaded for text shaping. Dispose it when no more geometry will be created from it; disposal is idempotent.
interface OutlineFont extends DisposableRelated API: OutlineFont.
See also
Section titled “See also”View source — packages/text/src/index.ts:16
Properties and methods
Section titled “Properties and methods”
dispose
dispose: () => voidReleases the native font owner; repeated calls are harmless and later shaping with this font fails. See OutlineFont.
OutlineFontOptions
Section titled “OutlineFontOptions”Cancellation and monochrome-fallback policy used when loading an outline font.
interface OutlineFontOptionsRelated API: OutlineFontOptions.
See also
Section titled “See also”View source — packages/text/src/index.ts:28
Properties and methods
Section titled “Properties and methods”
signal (optional)
signal?: AbortSignal | undefinedRelated API: signal.
Abort signal for font loading and validation. See OutlineFontOptions.
monochromeFallback (optional)
monochromeFallback?: boolean | undefinedAllows supported monochrome outlines when the font includes color glyph data. See OutlineFontOptions.
TextGeometryOptions
Section titled “TextGeometryOptions”Font size, shaping direction, OpenType features, and work limits for one text run.
interface TextGeometryOptionsRelated API: TextGeometryOptions.
See also
Section titled “See also”View source — packages/text/src/index.ts:42
Properties and methods
Section titled “Properties and methods”
fontSize
fontSize: numberPositive finite output font size in logical units. See TextGeometryOptions.
maxSegments (optional)
maxSegments?: number | undefinedUpper bound on the number of output path segments. See TextGeometryOptions.
missingGlyphs (optional)
missingGlyphs?: "error" | "notdef" | undefinedWhether an absent glyph fails shaping or uses the font’s .notdef glyph. See TextGeometryOptions.
direction (optional)
direction?: "ltr" | "rtl" | undefinedExplicit left-to-right or right-to-left shaping direction; omitted direction is inferred. See TextGeometryOptions.
script (optional)
script?: string | undefinedFour-character OpenType script tag overriding script inference. See TextGeometryOptions.
language (optional)
language?: string | undefinedLanguage tag used for shaping; distinct interned tags are bounded by the engine. See TextGeometryOptions.
features (optional)
features?: Readonly<Record<string, boolean>> | undefinedOpenType feature overrides keyed by four-character tags. See TextGeometryOptions.
TextGlyph
Section titled “TextGlyph”Shaped glyph identity, UTF-16 source cluster, outline segment range, and scaled placement metrics.
interface TextGlyphRelated API: TextGlyph.
See also
Section titled “See also”View source — packages/text/src/index.ts:75
Properties and methods
Section titled “Properties and methods”
glyphId
readonly glyphId: numberFont-specific identifier of the shaped glyph. See TextGlyph.
cluster
readonly cluster: numberUTF-16 offset of the source cluster associated with this glyph. See TextGlyph.
segmentStart
readonly segmentStart: numberIndex of the glyph’s first segment in the returned geometry. See TextGlyph.
segmentCount
readonly segmentCount: numberNumber of outline segments belonging to this glyph. See TextGlyph.
x
readonly x: numberHorizontal coordinate or displacement in the containing coordinate system. See TextGlyph.
y
readonly y: numberVertical coordinate or displacement in the containing coordinate system. See TextGlyph .
xAdvance
readonly xAdvance: numberHorizontal pen advance in scaled logical units. See TextGlyph.
yAdvance
readonly yAdvance: numberVertical pen advance in Canvas-oriented logical units. See TextGlyph.
TextGeometryResult
Section titled “TextGeometryResult”Independent path geometry, optional ink bounds, advances, and glyph metadata for a shaped text run.
interface TextGeometryResultRelated API: TextGeometryResult.
See also
Section titled “See also”View source — packages/text/src/index.ts:107
Properties and methods
Section titled “Properties and methods”
geometry
readonly geometry: PathGeometryRelated API: PathGeometry.
Independent mutable outline geometry in Canvas-oriented output coordinates. See PathGeometry.
inkBounds
readonly inkBounds: Readonly<InkBounds> | nullRelated API: InkBounds.
Bounds of visible outlines, or null when the run has no ink. See InkBounds.
advance
readonly advance: Readonly<{ x: number; y: number; }>Final pen displacement, including glyph advances even when no ink is drawn. See TextGeometryResult.
glyphs
readonly glyphs: readonly TextGlyph[]Related API: TextGlyph.
Ordered shaped-glyph metadata corresponding to the returned outline segments. See TextGlyph.
loadOutlineFont
Section titled “loadOutlineFont”Loads and validates font bytes from a URL or buffer and returns an explicitly disposable font. Rejects on cancellation, unsupported font data, or allocation failure.
loadOutlineFont: (source: string | URL | ArrayBuffer | Uint8Array, options?: OutlineFontOptions) => Promise<OutlineFont>Related API: loadOutlineFont, OutlineFontOptions, OutlineFont.
Parameters
Section titled “Parameters”-
source— Font URL to fetch, or in-memory font bytes to copy into the shaping engine. -
options— Cancellation signal and explicit monochrome fallback policy. See OutlineFontOptions .
Returns
Section titled “Returns”A promise for an owned font; dispose it when no further shaping will use it. See OutlineFont .
See also
Section titled “See also”View source — packages/text/src/index.ts:157
createTextGeometry
Section titled “createTextGeometry”Synchronously shapes a single text run into independent Canvas-oriented outlines. The font must be live, fontSize positive and finite, and text must not contain line breaks or tabs.
createTextGeometry: (font: OutlineFont, text: string, options: TextGeometryOptions) => TextGeometryResultRelated API: createTextGeometry, OutlineFont, TextGeometryOptions, TextGeometryResult.
Parameters
Section titled “Parameters”-
font— Live font returned by loadOutlineFont; it must not have been disposed. See OutlineFont . -
text— Text to shape as one run. -
options— Font size, shaping overrides, missing-glyph policy, and work limits. See TextGeometryOptions .
Returns
Section titled “Returns”Independent mutable path geometry plus glyph placements, ink bounds, and advances; the result remains usable after font disposal. See TextGeometryResult .
See also
Section titled “See also”View source — packages/text/src/index.ts:226
Implementation guidance for agents
Section titled “Implementation guidance for agents”Read the Text outlines and typography companion for ownership, adaptation, failure modes, and verification. Agent start provides the version-selection workflow.
Complete minimal examples
Section titled “Complete minimal examples”- Text outline: Load an outline font, shape a text run, and paint its editable path with glyph metrics. Plain source
Interactive examples
Section titled “Interactive examples”Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.