@zakkster/lite-bmfont
v1.1.0
Published
Zero-GC bitmap font canvas renderer. O(1) kerning via 64K Int16 LUT, multi-line alignment without string splitting.
Maintainers
Readme
@zakkster/lite-bmfont
🔤 What is lite-bmfont?
@zakkster/lite-bmfont renders BMFont-format bitmap text to Canvas2D with zero allocations.
It gives you:
- 🔤 BMFont JSON format support
- ⚡ O(1) kerning lookup via 64K Int16Array LUT
- 📏 Multi-line text with left/center/right alignment
- 📐
measure()for text width calculation - 🔢
drawFast()for zero-alloc number rendering (1 decimal place) — perfect for HUDs, scores, timers - 🧹 Zero allocation during
draw()anddrawFast()— no string splitting, no array creation - 🎯 Pixel-snapped rendering for crisp pixel fonts
- 🪶 < 1.5 KB minified
Note: Supports ASCII characters 0–255. Unicode is intentionally excluded for zero-GC performance.
Part of the @zakkster/lite-* ecosystem — micro-libraries built for deterministic, cache-friendly game development.
🚀 Install
npm i @zakkster/lite-bmfont🕹️ Quick Start
import { BitmapFont } from '@zakkster/lite-bmfont';
const font = new BitmapFont(atlasImage, fontJson);
// Draw left-aligned
font.draw(ctx, 'SCORE: 1000', 10, 30);
// Draw centered (align: 0=left, 1=center, 2=right)
font.draw(ctx, 'GAME OVER', canvas.width / 2, 200, 2.0, 1);
// Measure width
const w = font.measure('Hello', 1.5);
// Zero-alloc number drawing — ideal for per-frame HUDs (FPS counters, timers, scores)
font.drawFast(ctx, fps, 10, 20); // "60.0"
font.drawFast(ctx, 33.49, 10, 40); // "33.5" (rounded)
font.drawFast(ctx, score, canvas.width / 2, 60, 1, 1); // centered🧠 Why This Exists
Existing BMFont renderers allocate line arrays and substring objects per draw call. lite-bmfont uses charCodeAt() to index directly into an Int16Array glyph table — 7 values per glyph, accessed via id * 7 + offset. The 64K kerning LUT trades 128KB of memory for O(1) lookup speed.
drawFast() extends the same philosophy to numeric output: it converts a number to ASCII char codes inside a pre-allocated Uint8Array scratch buffer, never producing a string. Drawing value.toFixed(1) per frame in a HUD allocates a fresh string every call; drawFast() allocates nothing.
📊 Comparison
| Library | Size | Allocations | Kerning | Multi-line | Install |
|---------|------|-------------|---------|------------|---------|
| bmfont-text | ~4 KB | Arrays per draw | Slow | Basic | npm i bmfont-text |
| msdf-bmfont-xml | ~8 KB | High | Yes | Yes | npm i msdf-bmfont-xml |
| lite-bmfont | < 1.5 KB | Zero | O(1) LUT | Yes + alignment | npm i @zakkster/lite-bmfont |
⚙️ API
new BitmapFont(imageAtlas, fontJson)
imageAtlas: LoadedHTMLImageElementorHTMLCanvasElementfontJson: Standard BMFont JSON withcommon,chars, and optionalkernings
measure(text, scale?) — Returns pixel width
draw(ctx, text, x, y, scale?, align?)
Renders text to canvas. Align: 0=left, 1=center, 2=right.
drawFast(ctx, value, x, y, scale?, align?)
Zero-alloc number renderer. Draws value with one decimal place (e.g. 33.4).
NaN,+Infinity,-Infinity→ silently skipped (returns).- Negative values → clamped to
0. - Decimal → rounded to nearest tenth (
33.49 → "33.5"). - Requires the font atlas to contain glyphs for
'0'–'9'(codes 48–57) and'.'(code 46). - Align:
0=left,1=center,2=right.
destroy()
Releases the atlas reference and typed arrays.
🧪 Benchmark
Rendering 1000 characters per frame:
bmfont-text: Allocates line arrays per draw
lite-bmfont: Zero allocation, charCodeAt() + Int16Array lookup per glyph
Rendering 60 numeric HUD values per frame:
value.toFixed(1) + draw(): allocates a new String each call
drawFast(value): zero allocation — char codes go into a reused Uint8Array📦 TypeScript
Full TypeScript declarations included in BitmapFont.d.ts.
📚 LLM-Friendly Documentation
See llms.txt for AI-optimized metadata and usage examples.
🗒️ Changelog
1.1.0
- Added:
drawFast(ctx, value, x, y, scale?, align?)— zero-alloc number renderer with one decimal place. Built for per-frame HUD output (FPS, score, time) without producing GC pressure. - Internal: scratch buffer for
drawFastis allocated once in the constructor and released bydestroy().
1.0.x
- Initial release:
draw,measure, multi-line alignment, O(1) kerning LUT.
License
MIT
