opentype.js

repository·master·Indexed 26 days ago

https://github.com/opentypejs/opentype.js

An OpenType font parser for the browser and Node.js that allows developers to parse, manipulate, and create font files (WOFF, OTF, TTF) and extract Bézier paths from text. It includes tools for rendering text to 2D contexts, measuring text width, managing color glyph layers via COLR/CPAL tables, and handling variable font properties. The library also provides a CLI tool for font inspection and a test-render tool for SVG output compliance.

Tokens
4.8K
Snippets
8
Records
29
Agent score
89%

What's inside opentype.js

  1. Save a Font to a file

    master

    Once you have a Font object, you can export it using font.toArrayBuffer().

    Node.js:

    fs.writeFileSync("out.otf", Buffer.from(font.toArrayBuffer()));

    Browser (Download):

    const href = window.URL.createObjectURL(new Blob([font.toArrayBuffer()], {type: "font/opentype"}));
    Object.assign(document.createElement('a'), {download: "out.otf", href}).click();
    fs.writeFileSync("out.otf", Buffer.from(font.toArrayBuffer()));
  2. Load a WOFF, OTF, or TTF font

    master

    To use an existing font, you must first load the font file into an ArrayBuffer and then use opentype.parse() to create a Font instance.

    Browser (URL):

    const buffer = fetch('/fonts/my.woff').then(res => res.arrayBuffer());
    const font = opentype.parse(await buffer);

    Browser (File Input):

    const buffer = document.getElementById('myfile').files[0].arrayBuffer();
    const font = opentype.parse(await buffer);

    Node.js (Filesystem):

    const buffer = require('fs').promises.readFile('./my.woff');
    const font = opentype.parse(await buffer);
    const buffer = fetch('/fonts/my.woff').then(res => res.arrayBuffer());
    const font = opentype.parse(await buffer);
  3. Install opentype.js via CDN

    master

    You can include opentype.js in your web project using a <script> tag for global access or an import statement for module-based workflows.

    Available CDN sources:

    • https://opentype.js.org/dist/opentype.js
    • https://cdn.jsdelivr.net/npm/opentype.js
    • https://unpkg.com/opentype.js
    <!-- using global declaration -->
    <script src="https://your.favorite.cdn/opentype.js"></script>
    <script>opentype.parse(...)</script>
    
    <!-- using module declaration (need full path) -->
    <script type=module>
    import { parse } from "https://unpkg.com/opentype.js/dist/opentype.module.js";
    parse(...);
    </script>
  4. Install opentype.js via npm

    master

    To use opentype.js in a Node.js environment or with a bundler, install it using the npm package manager.

    Supported import patterns:

    • CommonJS: require('opentype.js')
    • ESM: import opentype from 'opentype.js'
    • Named import: import { load } from 'opentype.js'
    npm install opentype.js
    const opentype = require('opentype.js');
    
    import opentype from 'opentype.js'
    
    import { load } from 'opentype.js'
  5. Load and decompress a WOFF2 font

    master

    Since WOFF2 uses Brotli compression, opentype.js does not include a decompressor to keep the library size small. You must decompress the font beforehand using a library like wawoff2.

    Example workflow using wawoff2 via CDN:

    1. Load the wawoff2 script.
    2. Wait for window.Module to be initialized.
    3. Decompress the buffer using Module.decompress() before passing it to opentype.parse().
    const loadScript = (src) => new Promise((onload) => document.documentElement.append(
      Object.assign(document.createElement('script'), {src, onload})
    ));
    
    const buffer = //...fetch or read buffer...
    
    if (!window.Module) {
      const path = 'https://unpkg.com/wawoff2@2.0.1/build/decompress_binding.js'
      const init = new Promise((done) => window.Module = { onRuntimeInitialized: done});
      await loadScript(path).then(() => init);
    }
    
    const font = opentype.parse(Module.decompress(await buffer));
  6. Craft a font from scratch

    master

    You can create a new Font by manually defining Glyph objects and their Bézier paths.

    Important: A .notdef glyph is required for every font.

    1. Create a Path and add drawing commands (e.g., moveTo, lineTo).
    2. Create a Glyph using the path, a name, a unicode value, and an advanceWidth.
    3. Instantiate a Font with the glyphs and font metrics (familyName, styleName, unitsPerEm, ascender, descender).
    const notdefGlyph = new opentype.Glyph({
        name: '.notdef',
        advanceWidth: 650,
        path: new opentype.Path()
    });
    
    const aPath = new opentype.Path();
    aPath.moveTo(100, 0);
    aPath.lineTo(100, 700);
    
    const aGlyph = new opentype.Glyph({
        name: 'A',
        unicode: 65,
        advanceWidth: 650,
        path: aPath
    });
    
    const font = new opentype.Font({
        familyName: 'OpenTypeSans',
        styleName: 'Medium',
        unitsPerEm: 1000,
        ascender: 800,
        descender: -200,
        glyphs: [notdefGlyph, aGlyph]
    });
  7. Handle variable fonts with Font.variation

    master

    The Font.variation (VariationManager) handles variable font properties via OpenType variation tables.

    Key Methods:

    • activateDefaultVariation(): Sets the font's default render options to the default variation.
    • getDefaultCoordinates(): Returns an object mapping axis tags to default values.
    • getDefaultInstanceIndex(): Returns the index of the default variation instance (or -1).
    • getInstanceIndex(coordinates): Finds the index matching the provided axis coordinates.
    • getInstance(index): Retrieves a specific variation instance by index.
    • set(instanceIdOrObject): Sets the default variation coordinates (using an index or an axis-mapping object).
  8. Manipulate paths with Path object

    master

    The Path object represents a series of Bézier curves and lines.

    Key Properties:

    • commands: Array of command dictionaries (e.g., {type: 'M', x: 100, y: 200}).
    • fill: CSS color for filling (default: 'black').
    • stroke: CSS color for stroking (default: null).
    • strokeWidth: Thickness of the stroke (default: 1).

    Key Methods:

    • draw(ctx): Draws the path to a 2D context.
    • getBoundingBox(): Returns an opentype.BoundingBox (x1, y1, x2, y2).
    • toPathData(options): Converts to SVG path data string. Options include decimalPlaces, optimize, flipY, and flipYBase.
    • toSVG(options): Converts to an SVG <path> element string.
    • fromSVG(pathData, options): Creates/overwrites a path from SVG data.
  9. Manage color glyph layers with Font.layers

    master

    The Font.layers (LayerManager) manages color glyph layers in the COLR table.

    Key Methods:

    • add(glyphIndex, layers, position): Adds layers to a glyph. layers can be {glyph, paletteIndex} or {glyphID, paletteIndex}.
    • get(glyphIndex): Returns an array of {glyph, paletteIndex} objects for a glyph.
    • remove(glyphIndex, start, end): Removes layers from a glyph.
    • setPaletteIndex(glyphIndex, layerIndex, paletteIndex): Updates a layer's palette index.
  10. Render text using Font.draw and Font.drawPoints

    master

    Draw text directly onto a 2D drawing context (like HTML5 Canvas).

    Font.draw(ctx, text, x, y, fontSize, options) Draws the text using the path's fill and stroke properties.

    • ctx: The 2D drawing context.
    • x, y: Position (y is the baseline).
    • fontSize: Size in pixels.
    • options: GlyphRenderOptions object.

    Font.drawPoints(ctx, text, x, y, fontSize, options) Draws the control points of the glyphs. On-curve points are blue; off-curve points are red.

  11. Measure text width with Font.getAdvanceWidth

    master

    Returns the advance width of a text string in pixels. This is equivalent to canvas2dContext.measureText(text).width and accounts for kerning and whitespace.

    • text: The string to measure.
    • fontSize: Size in pixels (default: 72).
    • options: GlyphRenderOptions object.
  12. Render text using Font.getPath and Font.getPaths

    master

    Generate path data for text rendering.

    Font.getPath(text, x, y, fontSize, options) Returns a single Path object representing the text.

    • x: Horizontal position (default: 0).
    • y: Vertical position of the baseline (default: 0).
    • fontSize: Size in pixels (default: 72).
    • options: GlyphRenderOptions object.

    Font.getPaths(text, x, y, fontSize, options) Returns an array of Path objects (one for each glyph).