### Install node-fontnik Source: https://github.com/mapbox/node-fontnik/blob/master/README.md Run this command to install node-fontnik. It installs pre-built binaries on supported platforms. ```bash npm install ``` -------------------------------- ### Install Fontnik Dependencies Manually Source: https://github.com/mapbox/node-fontnik/blob/master/README.md Manually install the required dependencies for building node-fontnik from source by running this script. ```bash ./scripts/install_deps.sh ``` -------------------------------- ### Build node-fontnik from Source Source: https://github.com/mapbox/node-fontnik/blob/master/README.md Use this command to build node-fontnik from source, which is necessary for unsupported platforms. It automatically installs dependencies like boost, freetype, and protozero using mason. ```bash npm install --build-from-source ``` -------------------------------- ### Generate All PBF Glyph Files with build-glyphs CLI Source: https://context7.com/mapbox/node-fontnik/llms.txt The `build-glyphs` CLI tool generates 256 PBF glyph files for a given font stack path, covering the full Unicode range in 256-codepoint blocks. It writes files named `{start}-{end}.pbf` to the specified output directory and runs tasks in parallel. ```bash # Install fontnik globally or use npx npm install -g fontnik # Generate all glyph PBFs for Open Sans Regular mkdir -p ./glyphs/open-sans-regular build-glyphs ./fonts/open-sans/OpenSans-Regular.ttf ./glyphs/open-sans-regular # Output directory will contain 256 files: # ./glyphs/open-sans-regular/0-255.pbf # ./glyphs/open-sans-regular/256-511.pbf # ... # ./glyphs/open-sans-regular/65280-65535.pbf # Error case — invalid font file exits with code 1: ``` -------------------------------- ### range(options, callback) Source: https://github.com/mapbox/node-fontnik/blob/master/API.md Retrieves a range of glyphs from a font as a protocol buffer. The options include the font buffer, and the start and end points for the range. ```APIDOC ## `range(options: object, callback: function)` ### Description Get a range of glyphs as a protocol buffer. ### Parameters #### Options - **font** (buffer) - Required - The actual font file. - **start** (number) - Required - The starting point of the glyph range. - **end** (number) - Required - The ending point of the glyph range. ### Callback The callback function will be invoked with `callback(err, res)`, where `res` is the protocol buffer result. ``` -------------------------------- ### Generate SDF glyphs for a Unicode codepoint range Source: https://context7.com/mapbox/node-fontnik/llms.txt Use this function to rasterize a range of glyphs from a font buffer, generate signed distance fields, and return the result as a gzip-deflated protocol buffer. Ensure `start` and `end` are integers between 0 and 65535 with `start <= end`. The output buffer conforms to the `llmr.glyphs` protobuf schema. ```javascript const fontnik = require('fontnik'); const fs = require('fs'); const font = fs.readFileSync('./fonts/open-sans/OpenSans-Regular.ttf'); // Generate glyphs for ASCII printable characters (codepoints 32–127) fontnik.range({ font: font, start: 32, end: 127 }, function(err, pbfBuffer) { if (err) { console.error('Error generating glyph range:', err.message); // e.g. "could not open font" or "font does not have family_name" return; } // pbfBuffer is a deflated protobuf Buffer fs.writeFileSync('./glyphs/32-127.pbf', pbfBuffer); console.log('Written 32-127.pbf, size:', pbfBuffer.length, 'bytes'); // => Written 32-127.pbf, size: ~12400 bytes // Decode to inspect glyph metadata const zlib = require('zlib'); const Protobuf = require('pbf'); // (using a glyphs decoder built from proto/glyphs.proto) zlib.inflate(pbfBuffer, function(err, inflated) { // inflated contains the raw protobuf bytes // Decoded structure: // { // stacks: { // 'Open Sans Regular': { // name: 'Open Sans Regular', // range: '32-127', // glyphs: { // '65': { id: 65, width: 14, height: 15, left: 1, top: 14, advance: 15 }, // ... // } // } // } // } }); }); // Validation — these throw synchronously: // fontnik.range(); // Error: First argument must be an object of options // fontnik.range({ font: 'not a buffer' }, cb); // Error: Font buffer is not an object // fontnik.range({ font: buf, start: -1, end: 256 }, cb); // Error: option `start` must be a number from 0-65535 // fontnik.range({ font: buf, start: 256, end: 0 }, cb); // Error: `start` must be less than or equal to `end` // fontnik.range({ font: buf, start: 0, end: 256 }); // Error: Callback must be a function ``` -------------------------------- ### Get Glyph Range with fontnik Source: https://github.com/mapbox/node-fontnik/blob/master/API.md Retrieves a range of glyphs from a font file as a protocol buffer. Requires the font data, start and end unicode points, and a callback function. ```javascript fontnik.range(options, function(err, res) { // ... }); ``` -------------------------------- ### Load Font Metadata and Unicode Coverage with fontnik.load Source: https://context7.com/mapbox/node-fontnik/llms.txt Use `fontnik.load` to read font file buffers and get metadata like family name, style name, and supported Unicode codepoints. This is useful for inspecting font coverage before generating glyphs or building font registries. Ensure the first argument is a valid font buffer and the second is a callback function. ```javascript const fontnik = require('fontnik'); const fs = require('fs'); const opensans = fs.readFileSync('./fonts/open-sans/OpenSans-Regular.ttf'); const firasans = fs.readFileSync('./fonts/firasans-medium/FiraSans-Medium.ttf'); // Inspect a single font face fontnik.load(opensans, function(err, faces) { if (err) { console.error('Failed to load font:', err.message); // e.g. "Font buffer is not an object" or "font does not have family_name" return; } // faces is an array of font face objects (one per face in the font file) console.log(faces[0].family_name); // => 'Open Sans' console.log(faces[0].style_name); // => 'Regular' console.log(faces[0].points.length); // => 882 (number of supported codepoints) console.log(faces[0].points.slice(0, 5)); // => [32, 33, 34, 35, 36] (space, !, ", #, $) }); // Inspect multiple fonts and build a coverage report const fonts = [ { path: './fonts/open-sans/OpenSans-Regular.ttf' }, { path: './fonts/firasans-medium/FiraSans-Medium.ttf' } ]; fonts.forEach(function(f) { const buf = fs.readFileSync(f.path); fontnik.load(buf, function(err, faces) { if (err) return console.error(f.path, err.message); faces.forEach(function(face) { console.log(`${face.family_name} ${face.style_name}: ${face.points.length} codepoints`); // => 'Open Sans Regular: 882 codepoints' // => 'Fira Sans Medium: 789 codepoints' }); }); }); // Validation — these throw synchronously: // fontnik.load(); // Error: First argument must be a font buffer // fontnik.load({}); // Error: First argument must be a font buffer // fontnik.load(buf); // Error: Callback must be a function ``` -------------------------------- ### Publishing Binaries Workflow Source: https://github.com/mapbox/node-fontnik/blob/master/DEV.md Follow these steps to publish binaries. Ensure you have incremented the version number and amended the commit message to include '[publish binary]'. Push the commit and tags to the remote repository. ```bash git checkout master # increment version number # https://docs.npmjs.com/cli/version npm version major | minor | patch # amend commit to include "[publish binary]" git commit --amend "x.y.z" -> "x.y.z [publish binary]" # push commit and tag to remote git push git push --tags # make a sandwich, check travis console for build successes # test published binary (should install from remote) npm install && npm test # Make sure that the GHA workflow is successful. Download the artifacts npm run download-binaries # publish to npm npm publish ``` -------------------------------- ### Run Local Tests Source: https://github.com/mapbox/node-fontnik/blob/master/README.md Execute this command to run the test suite for node-fontnik. ```bash npm test ``` -------------------------------- ### build-glyphs Source: https://context7.com/mapbox/node-fontnik/llms.txt A command-line tool that generates all 256 PBF glyph files for a given font stack. It iterates over the full Unicode range in 256-codepoint blocks and writes the resulting PBF files to a specified output directory. ```APIDOC ## CLI Tool: `build-glyphs ` Iterates over the full Unicode range (0–65535) in 256-codepoint blocks, calling `fontnik.range` for each, and writes the resulting PBF files to the output directory. Produces 256 files named `{start}-{end}.pbf` (e.g. `0-255.pbf`, `256-511.pbf`, …, `65280-65535.pbf`). Runs range tasks in parallel using a concurrency equal to the CPU count (minimum 4). ### Usage ```bash # Install fontnik globally or use npx npm install -g fontnik # Generate all glyph PBFs for Open Sans Regular mkdir -p ./glyphs/open-sans-regular build-glyphs ./fonts/open-sans/OpenSans-Regular.ttf ./glyphs/open-sans-regular ``` ### Output The output directory will contain 256 files, each representing a 256-codepoint range: ``` ./glyphs/open-sans-regular/0-255.pbf ./glyphs/open-sans-regular/256-511.pbf ... ./glyphs/open-sans-regular/65280-65535.pbf ``` ### Error Handling - Invalid font file: Exits with code 1. ``` -------------------------------- ### Recompile Node Bindings Source: https://github.com/mapbox/node-fontnik/blob/master/README.md If you modify the C++ files in the src/ directory, recompile the node bindings using this command before running tests. ```bash make ``` -------------------------------- ### Decode Protobuf Glyphs Data with Node.js Source: https://context7.com/mapbox/node-fontnik/llms.txt This JavaScript snippet demonstrates how to decode PBF glyph data using the `protocol-buffers` npm package. It reads a `.pbf` file and logs decoded information about font stacks and glyphs. ```javascript // Decoding a PBF output with the protocol-buffers npm package const protobuf = require('protocol-buffers'); const fs = require('fs'); const path = require('path'); const messages = protobuf(fs.readFileSync(path.join(__dirname, 'proto/glyphs.proto'))); const pbfBuffer = fs.readFileSync('./glyphs/open-sans-regular/0-255.pbf'); const decoded = messages.glyphs.decode(pbfBuffer); console.log(decoded.stacks.length); // => 1 console.log(decoded.stacks[0].name); // => 'Open Sans Regular' console.log(decoded.stacks[0].range); // => '0-255' console.log(decoded.stacks[0].glyphs[0]); // => { id: 32, width: 0, height: 0, left: 0, top: 0, advance: 8 } (space char) console.log(decoded.stacks[0].glyphs[1]); // => { id: 33, bitmap: , width: 5, height: 13, left: 1, top: 12, advance: 7 } (!) ``` -------------------------------- ### Protobuf Schema for Glyphs Data Source: https://context7.com/mapbox/node-fontnik/llms.txt The `llmr.glyphs` protobuf schema defines the wire format for SDF glyph data, used by `fontnik.range` and `fontnik.composite`. It includes messages for individual glyphs, font stacks, and the overall glyphs container. ```protobuf // proto/glyphs.proto syntax "proto2"; package llmr.glyphs; message glyph { required uint32 id = 1; // Unicode codepoint optional bytes bitmap = 2; // SDF bitmap with 3px border (absent for whitespace/empty glyphs) required uint32 width = 3; // Glyph width in pixels required uint32 height = 4; // Glyph height in pixels required sint32 left = 5; // Horizontal bearing required sint32 top = 6; // Vertical bearing required uint32 advance = 7; // Horizontal advance } message fontstack { required string name = 1; // e.g. "Open Sans Regular" required string range = 2; // e.g. "0-255" repeated glyph glyphs = 3; } message glyphs { repeated fontstack stacks = 1; extensions 16 to 8191; } ``` -------------------------------- ### load(font, callback) Source: https://github.com/mapbox/node-fontnik/blob/master/API.md Reads a font's metadata, returning information such as the font family name, style name, and an array of unicode points for which the font has coverage. ```APIDOC ## `load(font: buffer, callback: function)` ### Description Read a font's metadata. ### Parameters #### Font - **font** (buffer) - Required - The font file buffer. ### Response Returns an object with font metadata, including: - **family_name** (string) - The name of the font family. - **style_name** (string) - The style name of the font. - **points** (array of numbers) - An array of unicode points where this font face has coverage. ### Callback The callback function will be invoked with `callback(err, res)`, where `res` is an array of font style object metadata. ``` -------------------------------- ### composite(buffers, callback) Source: https://github.com/mapbox/node-fontnik/blob/master/API.md Combines multiple glyph (SDF) PBFs into a single re-encoded PBF. Glyphs are composited based on their order in the input array, determining priority. ```APIDOC ## `composite(buffers: [buffer], callback: function)` ### Description Combine any number of glyph (SDF) PBFs. ### Parameters #### Buffers - **buffers** (array of buffers) - Required - An array of glyph (SDF) PBF buffers to combine. ### Response Returns a re-encoded PBF with the combined font faces. ### Callback The callback function will be invoked with `callback(err, res)`, where `res` is the composited protocol buffer result. ``` -------------------------------- ### fontnik.composite(buffers, callback) Source: https://context7.com/mapbox/node-fontnik/llms.txt Combines multiple Signed Distance Field (SDF) glyph Protocol Buffer (PBF) buffers into a single composited PBF. Glyph priority is determined by array order, allowing for font stack fallback. ```APIDOC ## `fontnik.composite(buffers, callback)` — Merge multiple SDF glyph PBFs Combines an array of glyph PBF buffers (each produced by `fontnik.range`) into a single composited PBF. Glyph priority is determined by array order — the first buffer's glyphs take precedence. This is used to implement font stack fallback: if the primary font lacks a glyph for a codepoint, the next font in the array provides it. The output is a re-encoded PBF with a single merged `fontstack`. ### Parameters - **buffers** (Array) - Required - An array of PBF buffers, where each buffer represents glyphs from a single font. - **callback** (Function) - Required - A callback function that receives an error object (if any) and the composited PBF buffer. ### Callback Arguments - **err** (Error) - An error object if compositing fails, otherwise null. - **compositePbf** (Buffer) - A Buffer containing the merged PBF data. ### Request Example ```javascript const fontnik = require('fontnik'); const fs = require('fs'); const openSansPbf = fs.readFileSync('./glyphs/OpenSans-Regular/512-767.pbf'); const arialUnicodePbf = fs.readFileSync('./glyphs/ArialUnicode/512-767.pbf'); fontnik.composite([openSansPbf, arialUnicodePbf], function(err, compositePbf) { if (err) { console.error('Composite failed:', err.message); return; } fs.writeFileSync('./glyphs/OpenSans,ArialUnicode/512-767.pbf', compositePbf); }); ``` ### Output Structure (of `compositePbf`) The resulting PBF contains a `fontstack` object with: - **stacks[0].name** (string) - Combined stack name. - **stacks[0].range** (string) - The codepoint range covered (e.g., '512-767'). - **stacks[0].glyphs** (Array) - Merged glyph list with priority determined by the input array order. ``` -------------------------------- ### fontnik.load(fontBuffer, callback) Source: https://context7.com/mapbox/node-fontnik/llms.txt Reads a font file buffer to extract metadata for each font face, including family name, style name, and supported Unicode codepoints. Useful for inspecting font coverage and building font registries. ```APIDOC ## `fontnik.load(fontBuffer, callback)` — Read font metadata and Unicode coverage Reads a font file buffer and returns metadata for each font face found within it, including the family name, style name, and the complete list of Unicode codepoints the font covers. This is useful for inspecting font coverage before generating glyph ranges, or for building a font registry. The `points` array contains raw Unicode codepoint integers indicating every character the font can render. ### Parameters - **fontBuffer** (Buffer) - Required - A buffer containing the font file data. - **callback** (Function) - Required - A callback function that receives an error object (if any) and an array of font face objects. ### Callback Arguments - **err** (Error) - An error object if loading fails, otherwise null. - **faces** (Array) - An array of font face objects. Each object has: - **family_name** (string) - The name of the font family. - **style_name** (string) - The style of the font (e.g., 'Regular', 'Bold'). - **points** (Array) - An array of Unicode codepoint integers covered by the font. ### Request Example ```javascript const fontnik = require('fontnik'); const fs = require('fs'); const opensans = fs.readFileSync('./fonts/open-sans/OpenSans-Regular.ttf'); fontnik.load(opensans, function(err, faces) { if (err) { console.error('Failed to load font:', err.message); return; } console.log(faces[0].family_name); console.log(faces[0].style_name); console.log(faces[0].points.length); console.log(faces[0].points.slice(0, 5)); }); ``` ### Validation These throw synchronously: - `fontnik.load()`: Error: First argument must be a font buffer - `fontnik.load({})`: Error: First argument must be a font buffer - `fontnik.load(buf)`: Error: Callback must be a function ``` -------------------------------- ### Inspect Font Unicode Coverage with font-inspect Source: https://context7.com/mapbox/node-fontnik/llms.txt Use `font-inspect` to analyze font files for family name, style, and Unicode codepoint coverage. It can inspect single files or entire directories. The `--verbose` flag outputs resolved paths to stderr. ```bash # Inspect a single font face font-inspect --face=./fonts/open-sans/OpenSans-Regular.ttf # Output (stdout): # [ # { # "face": "Open Sans Regular", # "coverage": [32, 33, 34, 35, 36, ...] // 882 codepoints # } # ] ``` ```bash # Inspect all fonts in a directory font-inspect --register=./fonts/ # Output (stdout): # [ # { # "face": "Fira Sans Medium", # "coverage": [32, 33, 34, ...] // 789 codepoints # }, # { # "face": "Open Sans Regular", # "coverage": [32, 33, 34, ...] // 882 codepoints # } # ] ``` ```bash # Verbose mode — resolved paths written to stderr, coverage to stdout font-inspect --verbose --register=./fonts/ # stderr: resolved [ './fonts/FiraSans-Medium.ttf', './fonts/OpenSans-Regular.ttf' ] # stdout: [ { "face": "...", "coverage": [...] }, ... ] ``` ```bash # Save coverage report to file font-inspect --register=./fonts/ > font-coverage.json ``` ```bash # Error case — font without family_name exits with error on stderr: # font-inspect --register=./fonts-invalid/ # => font does not have family_name or style_name ``` -------------------------------- ### fontnik.range(options, callback) Source: https://context7.com/mapbox/node-fontnik/llms.txt Rasterizes a range of glyphs from a font buffer, generates signed distance fields, and returns the result encoded as a gzip-deflated protocol buffer. The output follows the `llmr.glyphs` protobuf schema. ```APIDOC ## fontnik.range(options, callback) ### Description Rasterizes a range of glyphs from a font buffer using Freetype, generates signed distance fields for each glyph, and returns the result encoded as a gzip-deflated protocol buffer. The `start` and `end` values must be integers between 0 and 65535 with `start <= end`. The returned buffer follows the `llmr.glyphs` protobuf schema containing a `fontstack` with glyph metrics (`id`, `width`, `height`, `left`, `top`, `advance`) and an optional SDF `bitmap` for each glyph. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **options** (object) - Required - An object containing font data and codepoint range. - **font** (Buffer) - Required - The font file content as a Buffer. - **start** (number) - Required - The starting Unicode codepoint of the range (0-65535). - **end** (number) - Required - The ending Unicode codepoint of the range (0-65535). - **callback** (function) - Required - A callback function that receives an error object (if any) and the PBF glyph buffer. - **err** (Error) - An error object if rasterization fails. - **pbfBuffer** (Buffer) - A gzip-deflated protocol buffer containing the glyphs. ### Request Example ```javascript const fontnik = require('fontnik'); const fs = require('fs'); const font = fs.readFileSync('./fonts/open-sans/OpenSans-Regular.ttf'); fontnik.range({ font: font, start: 32, end: 127 }, function(err, pbfBuffer) { if (err) { console.error('Error generating glyph range:', err.message); return; } fs.writeFileSync('./glyphs/32-127.pbf', pbfBuffer); console.log('Written 32-127.pbf, size:', pbfBuffer.length, 'bytes'); }); ``` ### Response #### Success Response (200) - **pbfBuffer** (Buffer) - A gzip-deflated protocol buffer containing glyph metrics and SDF bitmaps. #### Response Example ```javascript // pbfBuffer is a deflated protobuf Buffer // After inflation and decoding, the structure might look like: // { // stacks: { // 'Open Sans Regular': { // name: 'Open Sans Regular', // range: '32-127', // glyphs: { // '65': { id: 65, width: 14, height: 15, left: 1, top: 14, advance: 15 }, // ... // } // } // } // } ``` ### Error Handling Synchronous errors are thrown for invalid input parameters, such as incorrect types, out-of-range values, or missing callback functions. ``` -------------------------------- ### Load Font Metadata with fontnik Source: https://github.com/mapbox/node-fontnik/blob/master/API.md Reads and returns metadata for a given font file. The metadata includes the font family name, style name, and an array of supported unicode points. ```javascript fontnik.load(font, function(err, res) { // ... }); ``` -------------------------------- ### Combine Glyphs with fontnik Source: https://github.com/mapbox/node-fontnik/blob/master/API.md Composites multiple glyph (SDF) PBFs into a single re-encoded PBF. Glyph priority is determined by their order in the input array. ```javascript fontnik.composite(buffers, function(err, res) { // ... }); ``` -------------------------------- ### Composite Multiple SDF Glyph PBFs with fontnik.composite Source: https://context7.com/mapbox/node-fontnik/llms.txt Use `fontnik.composite` to merge multiple glyph PBF buffers into a single one, prioritizing glyphs based on array order. This is essential for implementing font stack fallback. The output is a re-encoded PBF with a single merged `fontstack`. ```javascript const fontnik = require('fontnik'); const fs = require('fs'); // Pre-built PBF files for codepoint range 512–767 for two fonts const openSansPbf = fs.readFileSync('./glyphs/OpenSans-Regular/512-767.pbf'); const arialUnicodePbf = fs.readFileSync('./glyphs/ArialUnicode/512-767.pbf'); const notoSansPbf = fs.readFileSync('./glyphs/NotoSans/512-767.pbf'); // Composite two fonts: OpenSans takes priority, Arial Unicode fills gaps fontnik.composite([openSansPbf, arialUnicodePbf], function(err, compositePbf) { if (err) { console.error('Composite failed:', err.message); return; } // compositePbf is a merged PBF Buffer with one fontstack fs.writeFileSync('./glyphs/OpenSans,ArialUnicode/512-767.pbf', compositePbf); // Chain compositing to add a third font (e.g. for CJK fallback) fontnik.composite([notoSansPbf, compositePbf], function(err, triplePbf) { if (err) return console.error(err); fs.writeFileSync('./glyphs/NotoSans,OpenSans,ArialUnicode/512-767.pbf', triplePbf); console.log('Three-font stack composited successfully'); // The resulting PBF has: // stacks[0].name => combined stack name // stacks[0].range => '512-767' // stacks[0].glyphs => merged glyph list with priority from array order }); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.