Overview
This blog post details the creation of an online tool called FontForge. The goal was to provide users with a flexible platform where they could experiment and build unique font files by either writing individual letters by hand, uploading their own image-based fonts, or doodling directly on the site.
Background
The project began as a simple idea: to create a web application that allows users to generate custom fonts. The initial requirements were straightforward—users should be able to draw characters, upload images, and export the generated fonts in various image formats (PNG, SVG, JPG). However, the scope evolved based on clarifications and decisions made during development.
How It Works
Project Structure
The project was built using a simple web-based approach with HTML, CSS, and JavaScript for the frontend. The backend is handled by Node.js with Express to manage file uploads and serve static content. For font generation, we leveraged FontForge via its Python bindings (PyFontForge), but ultimately decided against this due to the clarified scope.
Key Features
- Drawing Tools: Users can draw individual characters on a 300x300 canvas.
- File Uploads: Users can upload their own images for custom fonts.
- Export Functionality: The application supports exporting generated fonts in PNG, SVG, and JPG formats. Exported SVG files embed the glyph raster as an
<svg><image>element.
Backend
The backend is minimal, handling file uploads and serving static content. It also manages project persistence by saving and loading glyph sets as JSON to the server.
Results
Implementation Steps
- Setup Project Structure: Set up a basic Node.js and Express project.
- Create Layout: Developed a simple HTML/CSS layout for the main page with drawing tools.
- Implement Drawing Functionality: Added basic drawing functionality in JavaScript, allowing users to draw on the canvas.
- File Uploads: Implemented file upload functionality to allow users to import their own images.
- Client-Side Export: Integrated the drawing tool with the backend for image uploads and generated fonts client-side using
FileReader. - Export Functionality: Added a basic UI for exporting generated fonts in PNG, SVG, and JPG formats.
Decisions Log
- Dropped PyFontForge: The application now uses pure JavaScript/Node.js to handle font generation, focusing on image-based exports rather than real font-binary generation.
- SVG Export Embeds Raster: Freehand strokes and uploaded images are rasterized. SVG export wraps the glyph's PNG in
<svg><image href="data:..."/></svg>. - Character Set: Implemented a default character set of 67 glyphs (A–Z, a–z, 0–9, plus
. , ! ?and space). - Client-Side Handling: All uploads are handled entirely client-side to simplify the server implementation.
- Persistence: Glyph edits auto-save to
localStorage, with an explicit "Save/Load Project" feature for persistent storage on the server.
Verification
The full application was verified via a scripted Playwright run against the live server, ensuring all features worked as expected.
Lessons Learned
- Scope Management: Clearly defining and understanding the scope of a project is crucial to avoid unnecessary complexity.
- Client-Side vs Server-Side: Client-side handling can simplify development but may limit certain functionalities.
- User Experience: Prioritizing user experience over advanced features ensures a more accessible tool.
What's Built / What's Left
Built
- Full working application in
code/—run withnpm install && npm startand openhttp://localhost:3000. - Drawing, upload, save, export PNG/SVG/JPG, export-all zip, type tester, save/load project, persistence across reload.
Left for Future Passes
- Real installable font file (.ttf/.otf) generation.
- True vector tracing for SVG export.
- Shape-drawing tools (lines/curves) beyond freehand.
- User accounts and authentication.
- Text wrapping/kerning refinements in the Type Tester.