Real-time font rendering comparison for fonts.sanchaya.net
Compare how your Kannada fonts render across HarfBuzz and your browser, in real-time.
Upload a .ttf or .otf font and instantly see:
- Native browser rendering (your platform: Safari, Chrome, Firefox, Edge)
- HarfBuzz reference rendering (ground-truth text shaping engine)
- Side-by-side comparison with overlay/diff modes
- Raw glyph metrics (advances, offsets, clusters) for debugging
No pre-generation, no static images β pure on-demand rendering.
- Node.js 16+
- Python 3.10+
- npm or yarn
-
Clone the repo
git clone https://github.com/sanchaya/font-engine-inspector.git cd font-engine-inspector -
Install dependencies
npm install pip install -r requirements.txt --break-system-packages
-
Run
npm start # Server running on http://localhost:3000 # View: http://localhost:3000/engine-inspector
-
Test
- Upload a Kannada
.ttffont - Enter test text (try:
ΰ²ΰ²°ΰ³ΰ²¨ΰ²Ύΰ²ΰ²orΰ²ΰ³ΰ²·) - Click Render
- See results instantly
- Upload a Kannada
.
βββ src/
β βββ app.js # Express.js main app
βββ routes/
β βββ engine-inspector.js # API endpoints (/api/render/hb, /api/test-strings)
βββ public/
β βββ index.html # Sanchaya-branded viewer UI
β βββ css/
β β βββ sanchaya-theme.css # Deep blue, gold, Kannada-inspired styling
β βββ js/ # (future: client-side utilities)
β βββ fonts/ # (optional: reference fonts)
βββ bin/
β βββ render-harfbuzz.py # Python worker: HarfBuzz + FreeType rendering
βββ docs/ # Documentation
βββ tests/ # Unit tests
βββ package.json
- Drag-and-drop font upload (or file picker)
- Live text input β modify test string, see results
- Font size slider (12pxβ200px)
- OpenType feature toggle β enable/disable
kern,liga, etc. in JSON format - Multiple view modes:
- Side-by-side β browser native vs HarfBuzz
- Overlay β red/blue fringing to spot positioning drift
- Glyph inspector table β see advances, offsets, cluster IDs
-
POST /api/render/hbβ Render text with HarfBuzz + FreeType- Accepts multipart font upload or reference to existing font
- Returns PNG as base64 + raw glyph metrics
-
GET /api/test-stringsβ Curated Kannada test cases- 7 categories: conjuncts, reph, vattu, matras, punctuation, mixed text, long passage
- ~31 test strings targeting real-world kerning trouble spots
- Deep blue & gold color palette (Indian heritage aesthetic)
- Kannada typography integrated in headers
- Professional UI β matches fonts.sanchaya.net design language
- Responsive design β works on mobile, tablet, desktop
Create a .env file:
# Port to run on (default: 3000)
PORT=3000
# Environment (development or production)
NODE_ENV=development
# Path to fonts directory (optional)
FONTS_DIR=./public/fontsThe bin/render-harfbuzz.py script is called by Node via subprocess. It:
- Loads a font with HarfBuzz
- Shapes text (produces glyph IDs, advances, offsets)
- Rasterizes glyphs with FreeType
- Outputs PNG + JSON glyph data
Usage directly:
python3 bin/render-harfbuzz.py <font.ttf> <text> <output.png> [size] [script] [language] [features]Example:
python3 bin/render-harfbuzz.py fonts/Kannada.ttf "ΰ²ΰ²¨ΰ³ΰ²¨ΰ²‘" /tmp/out.png 64 "Knda" "kan" '{"kern": 1}'Multipart file upload:
curl -X POST http://localhost:3000/api/render/hb \
-F "fontFile=@font.ttf" \
-F "text=ΰ²ΰ²¨ΰ³ΰ²¨ΰ²‘" \
-F "fontSize=72" \
-F "features={\"kern\": 1}"JSON (for existing fonts):
curl -X POST http://localhost:3000/api/render/hb \
-H "Content-Type: application/json" \
-d '{
"fontPath": "Kannada.ttf",
"text": "ΰ²ΰ²¨ΰ³ΰ²¨ΰ²‘",
"fontSize": 72,
"script": "Knda",
"language": "kan",
"features": {"kern": 1, "liga": 0}
}'Response:
{
"ok": true,
"image": "data:image/png;base64,...",
"width": 320,
"height": 100,
"glyph_count": 5,
"font_size": 72,
"padding": 20,
"glyphs": [
{
"glyph_id": 12,
"cluster": 0,
"x_advance": 450,
"y_advance": 0,
"x_offset": 0,
"y_offset": 0
},
...
]
}Returns curated Kannada test strings organized by category.
curl http://localhost:3000/api/test-stringsResponse:
{
"sets": [
{
"id": "conjuncts",
"label": "Conjuncts (Ottakshara)",
"note": "Full ligature conjuncts...",
"strings": ["ΰ²ΰ³ΰ²·", "ΰ²ΰ³ΰ²", "ΰ²€ΰ³ΰ²°", ...]
},
...
]
}- First render: ~500ms (Python startup overhead)
- Subsequent renders: ~200ms (fast shaping/rasterization)
- Browser native render: <50ms (Canvas 2D)
- Total UI response: <1 second per render
For production with heavy load, consider:
- Caching renders by font MD5 + text hash
- Worker pool to keep Python processes warm
- Rate limiting to prevent abuse (e.g., 1 render per user per 500ms)
FROM node:18-bullseye
RUN apt-get update && apt-get install -y python3 python3-pip
WORKDIR /app
COPY . .
RUN npm install
RUN pip install -r requirements.txt
EXPOSE 3000
CMD ["npm", "start"]- Set
NODE_ENV=production - Configure
PORTin environment - Enable CORS if serving on different domain
- Add rate limiting middleware
- Enable request logging
- Set up error monitoring (e.g., Sentry)
- Cache renders (Redis or in-memory)
- Test with real-world font files
# Run Node tests
npm test
# Lint code
npm run lint
# Test Python render script directly
python3 bin/render-harfbuzz.py public/fonts/Kannada.ttf "ΰ²ΰ²¨ΰ³ΰ²¨ΰ²‘" /tmp/test.png 72Contributions welcome! Areas for improvement:
- Add more test strings for other Indic scripts
- Support for macOS CoreText / Windows DirectWrite rendering
- Caching layer for high-traffic deployments
- WebSocket support for real-time font editing
- Support for variable fonts (wght, wdth axes)
- Export comparison reports as PDF
Please open issues on GitHub.
MIT License β Free for commercial and non-commercial use.
Uses open-source libraries:
- HarfBuzz β OFL (text shaping)
- FreeType β FTL/GPL (font rasterization)
- fontTools β MIT
- Express.js β MIT
- Pillow β HPND (image processing)
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: Sanchaya contact
Happy font testing! π¨