Skip to content

Text outline

Read as Markdown

Load an outline font, shape a text run, and paint its editable path with glyph metrics.

Plain source. Run as a browser module after the document body exists. TSX uses jsx: "react-jsx" and jsxImportSource: "@pibbl/core".

import { Path, pibbl, type PibblController } from '@pibbl/core';
import {
createTextGeometry,
loadOutlineFont,
type InkBounds,
type OutlineFont,
type OutlineFontOptions,
type TextGeometryOptions,
type TextGeometryResult,
type TextGlyph,
} from '@pibbl/text';
const canvas = document.createElement('canvas');
canvas.width = 440;
canvas.height = 230;
const status = document.createElement('p');
status.textContent = 'Loading outline font...';
document.body.append(canvas, status);
const abort = new AbortController();
const fontOptions: OutlineFontOptions = { signal: abort.signal };
const shapeOptions: TextGeometryOptions = {
fontSize: 72,
direction: 'ltr',
features: { kern: true, liga: true },
};
let font: OutlineFont | undefined;
let controller: PibblController | undefined;
let disposed = false;
function dispose() {
if (disposed) return;
disposed = true;
abort.abort();
controller?.dispose();
font?.dispose();
window.removeEventListener('pagehide', dispose);
}
window.addEventListener('pagehide', dispose);
void loadOutlineFont(new URL('/pibbl-text/ABeeZee-Regular.ttf', document.baseURI), fontOptions)
.then((loadedFont) => {
if (disposed) {
loadedFont.dispose();
return;
}
font = loadedFont;
const result: TextGeometryResult = createTextGeometry(font, 'Hello Pibbl', shapeOptions);
const firstGlyph: TextGlyph | undefined = result.glyphs[0];
const ink: Readonly<InkBounds> | null = result.inkBounds;
result.geometry.transform({ a: 1, d: 1, e: 24, f: 145 });
controller = pibbl(
canvas,
<Path style={{ d: result.geometry, fill: '#0f766e' }} />,
);
status.textContent = `${result.glyphs.length} glyphs; first cluster ${firstGlyph?.cluster ?? 'none'}; advance ${result.advance.x.toFixed(1)}; ink ${ink ? `${ink.width.toFixed(1)} x ${ink.height.toFixed(1)}` : 'empty'}`;
})
.catch((error: unknown) => {
if (!disposed) status.textContent = `Could not load font: ${String(error)}`;
});
  • The browser example requires the existing Studio /pibbl-text/ABeeZee-Regular.ttf asset and the @pibbl/text WASM loader asset; retain and dispose the font explicitly.

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.