Thanks to visit codestin.com
Credit goes to github.com

Skip to content

almanaclabs/ttf-parser-node

Repository files navigation

ttf-parser-node

Node.js bindings for ttf-parser, a high-level, safe, zero-allocation TrueType font parser written in Rust.

Features

  • 🚀 Fast native performance using Rust
  • 🔒 Memory-safe with zero-allocation parsing
  • 📦 Support for TrueType (.ttf) and OpenType (.otf) fonts
  • 🎨 Extract font metrics, glyph information, and more
  • 💪 Built on the battle-tested ttf-parser library

Prerequisites

  • Node.js 14 or higher

Note for developers: If you want to build from source, you'll need the Rust toolchain (https://rustup.rs/)

Installation

As a dependency in your project

npm install ttf-parser-node
# or
pnpm add ttf-parser-node
# or
yarn add ttf-parser-node

The package includes a pre-built native module that works out of the box - no Rust installation required!

Current platform support: macOS ARM64 (Apple Silicon)

For other platforms, see the "Multi-Platform Support" section below.

For development

pnpm install
pnpm run build

For development builds:

pnpm run build-debug

Usage

Basic Example (JavaScript)

const Font = require('ttf-parser-node');

// Load font from file
const font = Font.fromFile('path/to/font.ttf');

// Get font information
console.log(font.familyName);        // e.g., "Arial"
console.log(font.unitsPerEm);        // e.g., 2048
console.log(font.numberOfGlyphs);    // e.g., 1234
console.log(font.ascender);          // e.g., 1854
console.log(font.descender);         // e.g., -434

Load from Buffer

const fs = require('fs');
const Font = require('ttf-parser-node');

const buffer = fs.readFileSync('path/to/font.ttf');
const font = new Font(buffer);

Get Glyph Information

// Get glyph ID for a character
const glyphId = font.glyphIndex('A');  // or font.glyphIndex(65)
console.log(glyphId);  // e.g., 36

// Get horizontal advance width for a glyph
const advance = font.glyphHorAdvance(glyphId);
console.log(advance);  // e.g., 1479 (in font units)

// Get all glyph advances at once
const advances = font.getAllAdvances();
console.log(advances.length);  // Same as numberOfGlyphs

Font Properties

The Font object provides access to various font properties:

font.familyName       // Font family name (e.g., "Arial")
font.postScriptName   // PostScript name (e.g., "ArialMT")
font.unitsPerEm       // Units per EM square
font.numberOfGlyphs   // Total number of glyphs
font.ascender         // Typographic ascender
font.descender        // Typographic descender
font.lineGap          // Line gap (may be undefined)
font.isBold           // Whether font is bold
font.isItalic         // Whether font is italic
font.isMonospaced     // Whether font is monospaced
font.isVariable       // Whether font is a variable font
font.underline        // Underline metrics {position, thickness}

Export Font Info

const fontInfo = font.toJSON();
console.log(JSON.stringify(fontInfo, null, 2));

TypeScript Support

This library includes full TypeScript type definitions. All APIs are fully typed for TypeScript projects:

import Font from 'ttf-parser-node';

const font = Font.fromFile('./font.ttf');

// All properties are properly typed
const name: string | undefined = font.familyName;
const glyphs: number = font.numberOfGlyphs;
const isBold: boolean = font.isBold;

// Methods have type-safe signatures
const glyphId: number | null = font.glyphIndex('A');
if (glyphId !== null) {
  const advance: number = font.glyphHorAdvance(glyphId);
}

// Optional properties are typed correctly
if (font.underline) {
  console.log(font.underline.position);  // number
  console.log(font.underline.thickness); // number
}

See example.ts for a complete TypeScript example.

API Reference

Font.fromFile(path)

Load a font from a file path.

  • Parameters:
    • path (string): Path to the font file
  • Returns: Font instance
  • Throws: Error if file cannot be read or parsed

new Font(buffer)

Create a font instance from a buffer.

  • Parameters:
    • buffer (Buffer): Font file data
  • Returns: Font instance
  • Throws: TypeError if not a Buffer, Error if parsing fails

font.glyphIndex(char)

Get the glyph ID for a character.

  • Parameters:
    • char (string|number): Character or character code
  • Returns: number|null - Glyph ID or null if not found

font.glyphHorAdvance(glyphId)

Get the horizontal advance width for a glyph.

  • Parameters:
    • glyphId (number): The glyph ID
  • Returns: number - Advance width in font units

font.getAllAdvances()

Get all glyph horizontal advance widths.

  • Returns: number[] - Array of advance widths

font.toJSON()

Get all font information as a plain JavaScript object.

  • Returns: Object - Font properties

Testing

Run the included test:

# Test with default system font
node test.js

# Test with specific font
node test.js /path/to/your/font.ttf

Example Output

Font Information:
  Family Name: DejaVu Sans
  PostScript Name: DejaVuSans
  Units per EM: 2048
  Number of Glyphs: 6253
  Ascender: 1901
  Descender: -483
  Line Gap: 0
  Bold: false
  Italic: false
  Monospaced: false
  Variable: false

Character | Glyph ID | Advance Width
--------------------------------------------------
    A     |      36    |     1479
    B     |      37    |     1479
    C     |      38    |     1405

Building from Source

# Clone the repository
git clone <your-repo-url>
cd ttf-parser-node

# Install dependencies
pnpm install

# Build the native module (builds automatically during install)
pnpm run build

# Run tests
pnpm test

Performance

ttf-parser-node leverages Rust's zero-allocation parsing, making it extremely fast:

  • ⚡ Parsing a font: ~500 nanoseconds
  • ⚡ Getting glyph advance: ~2 nanoseconds
  • ⚡ Getting glyph index: ~16 nanoseconds

Comparison with Other Libraries

Feature ttf-parser-node opentype.js fontkit
Language Rust + Node.js JavaScript JavaScript
Performance ⚡ Fastest Fast Fast
Memory Safety ✓ (Rust) ~ ~
Zero Allocation
Variable Fonts

Limitations

Current bindings expose basic font information and glyph metrics. Future versions may include:

  • Glyph outline extraction
  • Font subsetting
  • Advanced OpenType features
  • Table-level access

Multi-Platform Support

The package currently includes a pre-built binary for macOS ARM64. To support multiple platforms, you have several options:

Option 1: Use in CI/CD

Build binaries for different platforms in your CI pipeline:

# On each platform (Linux, macOS x64, macOS ARM64, Windows)
pnpm run build-release
# Commit the index.node for that platform

Option 2: Use prebuildify (Recommended for production)

Install prebuildify for cross-platform support:

pnpm add -D prebuildify

Update package.json:

{
  "scripts": {
    "prebuild": "prebuildify --napi --strip",
    "install": "node-gyp-build"
  }
}

Then build for multiple platforms and publish pre-built binaries.

Option 3: Build from source

If consumers have Rust installed, they can build from source:

# In the consuming project
cd node_modules/ttf-parser-node
pnpm run build-release

For more information on native module distribution, see:

Contributing

Contributions are welcome! To add new features:

  1. Add the Rust function in src/lib.rs
  2. Export it in the main function
  3. Add a JavaScript wrapper method in index.js
  4. Update tests and documentation

License

MIT

Credits

This project uses:

Troubleshooting

Error: "Failed to parse font"

Make sure the font file is:

  • A valid TrueType (.ttf) or OpenType (.otf) font
  • Not corrupted
  • Readable by your application

Module not found: './index.node'

Run npm run build to compile the native module.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors