lgfx-font-tool
v0.1.0
Published
JavaScript toolkit for embedded bitmap fonts - decode, encode, convert, render and generate.
Maintainers
Readme
LGFX Font Tool JS
JavaScript toolkit for embedded bitmap fonts — decode, encode, convert, render and generate.
Decoders and encoders for u8g2 / GFXfont (Adafruit GFX) / BDF / VLW / BFF / FONTX2 / LovyanGFX internal formats, a text rendering engine that matches LovyanGFX pixel-for-pixel, and a bundled collection of all 186 fonts built into LovyanGFX v1.2.26. Plain ESM with zero runtime dependencies and no build step — runs in Node.js and the browser.
- Read — decode 11 formats, with auto-detection from magic numbers. A
.hyou found on GitHub (GFXfont / u8g2 C source) parses as-is - Render — a faithful port of LovyanGFX v1.2.26
drawString. Scaling, text datum and per-format quirks included: byte-exact against 1,860 cases drawn by the real thing - Convert — any format to any format through a neutral model. When something doesn't fit, it never silently truncates — you get a list of violations with stable codes
- Generate — rasterize TTF/OTF/WOFF in the browser into a new bitmap font, filling missing characters from fallback typefaces
- Shrink & grow — subsetting (a clock font can be 11 glyphs / 188 bytes), merging from other fonts, and text-coverage checks for CI
Web apps (no install)
| App | What it does |
| --- | --- |
| Viewer | Browse all 186 built-in fonts with pixel-exact preview |
| Generator | TTF / Google Fonts → u8g2 / GFXfont .h, with charset selection, fallback fill-in and automatic attribution |
| Converter | Drop a font file / C source, convert between formats |
| Inspector | Coverage, metrics, size comparison across every format, text checks |
Install
npm install lgfx-font-toolOr straight from a CDN in the browser:
<script type="module">
import { loadFont, drawString }
from 'https://cdn.jsdelivr.net/npm/lgfx-font-tool/dist/lgfx-font-tool.min.js';
</script>Ten lines to first pixels
import { loadFont, createBitmap, drawString, textWidth, fontHeight, bitmapToText }
from 'lgfx-font-tool';
const font = await loadFont('lgfxJapanGothic_16'); // from the bundled collection
const bmp = createBitmap(textWidth(font, 'Hello'), fontHeight(font), 1);
drawString(bmp, font, 'Hello', 0, 0);
console.log(bitmapToText(bmp)); // text-art dump
// bmp.data is a 1bpp bitmap you can send to a device as-isConversion is decode → encode:
import { decode, canEncode, encode } from 'lgfx-font-tool';
const font = decode(bytes); // format auto-detected
const check = canEncode(font, 'u8g2'); // ask before you write
const out = encode(font, { format: 'u8g2' }); // throws with issues if it won't fitSubset and emit an Arduino header:
import { loadFont, subset, encodeCSource } from 'lgfx-font-tool';
const clock = subset(await loadFont('lgfxJapanGothic_24'), '0123456789:./ ');
const header = encodeCSource(clock, { format: 'u8g2', symbolName: 'clockFont' });
// → #include "clockFont.h" and display.setFont(&clockFont);Supported formats
| Format | Decode | Encode | Used by |
| --- | :-: | :-: | --- |
| u8g2 | ✔ | ✔ | u8g2 / LovyanGFX (RLE-compressed, usually smallest) |
| GFXfont (GFX1) | ✔ | ✔ | Adafruit GFX / LovyanGFX |
| BDF | ✔ | ✔ | X11 / interchange (text format) |
| VLW | ✔ | ✔ | Processing / TFT_eSPI Smooth Font (8bpp anti-aliased) |
| BFF | ✔ | ✔ | LVGL lv_font_conv / LovyanGFX |
| FONTX2 | ✔ | ✔ | Japanese retro/embedded ecosystem (Shift_JIS mapping built in) |
| C source | ✔ | ✔ | Arduino .h files (extracts / emits GFXfont and u8g2) |
| GLCD / FixedBMP / LBMP / LRLE | ✔ | — | LovyanGFX internal formats |
Why you can trust the pixels
The renderer is not "close enough". It is verified byte-for-byte against the real
LovyanGFX (built natively with the lang-ship:host core) on 1,860 cases covering all
186 fonts and every drawing condition — plus 36 cases where fonts encoded by this
library are loaded and drawn by the real LovyanGFX, proving the encoders write what
LovyanGFX expects (oracle/). Fixtures are committed, so a
regular npm test needs no native build.
Bundled fonts and package size
All 186 fonts built into LovyanGFX v1.2.26 ship with a searchable catalog. The npm
package carries the 70 lightweight ones (~320KB); the large CJK fonts (42MB total) are
fetched automatically from GitHub Pages on first loadFont. The tarball is 562KB.
For offline use or a private mirror, point the loader elsewhere:
import { configureFontData } from 'lgfx-font-tool';
configureFontData({ baseUrl: 'https://intra.example.com/lgfx-fonts/' });
// In Node, file:///opt/lgfx-fonts/ works tooDocumentation
| Document | Contents | | --- | --- | | Beginner's guide (日本語) | Starts from "what is a font" | | Use-case guide (日本語) | Recipes: pick, render, generate, convert, CI checks… | | Advanced guide (日本語) | Internals, pixel-exactness, encoding constraints, extending | | Specification (日本語) | Normative spec (use cases, design decisions, format details) |
Minimal one-file samples live in examples/ (Node and browser).
Development
npm install
npm run check # tests + typecheck + layer lint + locale lint
npm test # node:test (includes the oracle exact-match suite)
npm run serve # web apps at http://localhost:8080/web/, samples at /examples/
npm run build # dist/ (bundle + bundled fonts)
npm run build:site # site/ (what GitHub Pages serves)
npm run extract-fonts # re-extract bundled fonts from LovyanGFX sources
npm run oracle # regenerate oracle fixtures with a native LovyanGFX buildDesign in one breath: plain ESM + JSDoc (no TypeScript syntax; npm run types emits
.d.ts), zero runtime dependencies, and no I/O inside src/ (two audited exceptions,
machine-checked in CI). See the specification for the rest.
License
MIT. See LICENSE. Attribution for bundled font data lives in NOTICE. Headers emitted by the Generator carry the source typeface's license and attribution automatically.
