Skip to main content
Use createFontGlyphSource from @groundsgg/motd/fonts to combine decoded local glyphs into one lookup. You supply layers in the precedence you want; the first layer defining a code point wins. The source keeps each selected glyph’s metrics and raster access together without React, a DOM or Portal.
This is an unreleased addition after 0.3.0. It is a standalone runtime data source, not a FontProfile or an option accepted by the viewer/editor yet. Layout, visible rendering, obfuscation and the inline-editor caret/IME bridge remain under integration issue #120. Do not infer native rendered parity from successful composition.

Compose decoded layers

Decode your selected local resources with the bitmap and Unihex APIs first. A space layer accepts scalar-keyed advances, including the advances returned by provider inspection.
compose-font.mjs
Layer order is explicit host input. This function does not merge resource-pack stacks, reverse a provider graph, select a client version, add bundled fallback glyphs or verify that your source is Vanilla-complete. Duplicate declarations within one supplied layer also keep the first entry; the decoders have already resolved their own input duplicates before this step. An explicit space or transparent bitmap in an earlier layer hides later glyphs. A blank Unihex glyph keeps its decoded width and half-pixel offsets. Neither is treated as a missing glyph. U+0000 is retained if supplied by Unihex; importing it does not change text control-character handling elsewhere in the library.

Read metrics and pixels together

The frozen FontGlyphSource has schemaVersion: 1, sorted numeric codePoints and glyphFor(codePoint). Unknown code points return undefined. Each selected FontSourceGlyph is frozen and contains: A bitmap has pixelWidth, pixelHeight, oversample, bearingLeft, bearingTop and pixels(). pixels() returns the normal Outcome<Uint8Array> with fresh row-major, unpremultiplied RGBA bytes. Successful calls preserve all channel values, including partial alpha and RGB under transparent pixels. Check value and diagnostics before using the data. Space advances are rounded to Java float32 precision. Zero, negative zero and negative finite advances are preserved. A space has no bitmap; its bold/shadow offsets are 1. The source does not flatten glyph-specific offsets into a single global font setting or normalize scalar sequences into graphemes. Composition snapshots metadata and the selected provider method. It does not request pixel buffers. Every later pixels() call invokes that method with the original provider receiver, validates the result and copies its fixed byte extent. Mutating a returned copy does not affect subsequent reads.

Bound work and own the resource lifetime

The optional second argument accepts positive integer limits up to fixed ceilings. Invalid options are errors rather than silent defaults. Layer and glyph-array lengths are captured before visiting their entries, so getter-driven growth cannot extend the selected arrays beyond their budgets. Space processing counts own enumerable entries and ignores inherited entries. Invalid metadata is rejected even when an earlier layer hides that glyph. The source keeps references to selected decoded providers but adds no retained RGBA cache. Separate sources have separate lookup metadata. Release your source and any retained glyph handles when you no longer need their providers. A host renderer can add a bounded cache keyed by the source identity and its own lifetime; do not key only by character or font name. The supplied decoder outputs are stable snapshots. If you supply structural provider objects of your own, keep their pixel contents, callback behavior and version stable for the source’s lifetime. JavaScript callbacks remain trusted host code: this API cannot limit allocation inside them or isolate arbitrary code execution. Budget input decoding separately. Fixed byte extents prevent backing-buffer growth from enlarging a selected read; they do not make shared contents atomic or establish version consistency. Do not persist the source, its functions or pixel buffers inside a ServerListDocument. Keep resource selection, loading, rights and disposal in your host. No original font files, textures, automatic downloads, archive extractor or upload service are added by this API.

Handle errors and check coverage

Construction errors return value: null with no partial source. Lazy raster errors return value: null for that pixel request; they do not invalidate the already composed source or silently select a lower layer. Paths use zero-based dotted indices such as layers.1.glyphs.0. Callback exception details are replaced with fixed messages. Use the normal localization API for translated diagnostics. Tests use real decoder outputs from original synthetic data and cover mixed sources, precedence, blank glyphs, supplementary characters, frozen metadata, independent pixel copies, lazy failures, getter mutation and fixed byte bounds. Node and packed-package consumers exercise the same public export without React or browser globals. The decoders have separate numeric native-provider references; this composition layer has no rendered-client calibration yet.