MCPcopy Index your code
hub / github.com/alibaba/font-toolkit

github.com/alibaba/font-toolkit @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
325 symbols 765 edges 16 files 19 documented · 6%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

fontkit-rs

GitHub CI Status fontkit-rs npm version fontkit-rs downloads

Toolkit used to load, match, measure and render texts.

NOTE: This project is a work in progress. Text measuring and positioning is a complex topic. A more mature library is a sensible choice.

Installation

npm i fontkit-rs

Compile the module:

npm run build
npm run build:wasi
node examples/node.mjs

Build WASI

rustup target add wasm32-wasi
npm run build:wasi

Font querying

This module uses a special font matching logic. A font's identity contains the font family (name), weight, italic, and stretch (font width). When querying, any subset of the memtioned information is allowed except that the font family is required.

The query is then splitted into 4 filters, in the order of family -> weight -> italic -> stretch. Each filter could strim the result set, and:

  • If after any filter the result contains only one font, it is immediately returned.
  • If after all filters, 0 or more than 1 font are left, the query fails

General API (WASM API)

new FontKit()

Create a new font registry

fontkit.add_font_from_buffer(buffer: Uint8Array) -> FontKey

Add a font from a buffer, return the standard key of this font

fontkit.query(key: FontKey) -> Font | undefined

Query a font

font.has_glyph(c: char) -> boolean

Check if the font contains glyph for a given char

font.ascender() -> number

The ascender metric of the font

font.descender() -> number

The descender metric of the font

font.units_per_em() -> number

The units of metrics of this font

font.glyph_path(c: char) -> GlyphPath | undefined

Get the glyph path of a char, if any

glyphPath.scale(scaleFactor: number)

The glyph of font is very large (by the unit of units_per_em), the method could scale the path for convenience

glyphPath.translate(x: number, y: number)

Translate the path

glyphPath.to_string() -> string

Export the glyph path as an SVG path string

Node.js Support

Currently this module supports Node.js via WASI API. This requires the --experimental-wasi-unstable-preview1 flag and only limited APIs are provided.

Example

import { dirname } from 'path';
import { fileURLToPath } from 'url';

// Import the Node.js specific entry module
import { FontKitIndex } from '../node.js';

// Get current path, or you could use any path containing font files
const __dirname = dirname(fileURLToPath(import.meta.url));

// Create an instance of `FontKitIndex`, which is generally a font registry.
// By doing this, an object is created in Rust. So be sure to call `.free()`
// later
const fontkit = new FontKitIndex();

// Await here is needed as it initiate the WASM module
await fontkit.initiate();

// Add a search path, fonts are recursively indexed. This method could
// be called multiple times
fontkit.addSearchPath(__dirname);

// Query a font, additional params including weight, stretch, italic are supported
const font = fontkit.font('Open Sans');

// Get the actual path of the font
console.log(font.path());

// Free the memory of the registry
fontkit.free();

Being a minimal API, after getting the actual path of the font, you could load the file into a Uint8Array buffer, and use the normal WASM APIs to load / use the font. So basically the Node.js API here is only for indexing and querying fonts.

API

new FontKitIndex()

Create a new font registry only for indexing. Holding the info (not the actual buffers) of the fonts it found.

fontkitIndex.addSearchPath(path: string)

Search recursively in a path for new fonts. Supports ttf/otf/woff/woff2 fonts. The fonts are loaded to grab their info, and then immediately released.

fontkitIndex.query(family: string, weight?=400, italic?=false, strech?=5) -> Font | undefined

Query a font. Check querying for details

fontkitIndex.free()

Free the registry. Further calls will panic the program

font.path() -> string

Get the path of the font

Extension points exported contracts — how you extend this code

AsI32 (Interface)
(no doc) [9 implementers]
src/bindings.rs
Metrics (Interface)
(no doc) [1 implementers]
src/metrics/compose.rs
FontKit (Interface)
(no doc)
index.d.ts
WasmResource (Interface)
(no doc) [4 implementers]
src/bindings.rs
AsF32 (Interface)
(no doc) [2 implementers]
src/bindings.rs
Guest (Interface)
(no doc) [1 implementers]
src/bindings.rs
GuestTextMetrics (Interface)
(no doc) [1 implementers]
src/bindings.rs

Core symbols most depended-on inside this repo

len
called by 61
src/lib.rs
get
called by 61
src/bindings.rs
run_ctors_once
called by 54
src/bindings.rs
cabi_dealloc
called by 36
src/bindings.rs
as_i32
called by 27
src/bindings.rs
as_ptr
called by 21
src/bindings.rs
string_lift
called by 17
src/bindings.rs
invalid_enum_discriminant
called by 17
src/bindings.rs

Shape

Method 172
Function 102
Class 38
Interface 10
Enum 3

Languages

Rust100%
TypeScript1%

Modules by API surface

src/bindings.rs120 symbols
src/wit.rs48 symbols
src/font.rs35 symbols
src/ras.rs31 symbols
src/metrics/compose.rs28 symbols
src/metrics.rs23 symbols
src/lib.rs17 symbols
src/metrics/arabic.rs8 symbols
src/conv/woff.rs7 symbols
tests/basic.rs6 symbols
src/error.rs1 symbols
index.d.ts1 symbols

For agents

$ claude mcp add font-toolkit \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact