Building on the base documented in my previous post, it is time to refactor the first working model to allow for the font description to be separated from the utility itself. Let’s begin with a quick overview of the source code as it stands, and move on from there.
This post is one of several describing a utility that will read a variety of textual descriptions of characters and produce a usable TrueType font.
Roadmap
To follow along with this overview, refer to the tree view of files in the project, or clone and open your own working copy of the project.
The root of the repository has a general Readme.md
file, and folders named .fossil-settings
and src
.
The .fossil-settings
folder contains settings checked into the repository that modify the way fossil sees the files. Right now, that only includes the crnl-glob
setting, which is set to make fossil silently accept files with Windows conventional line endings. As soon as I am annoyed enough about the clutter in the output from fossil extra
, I will create an ignore-glob
file here as well.
The src
folder will collect all the source code of the dotfonter
utility, primarily written in Lua.
dotfonter.lua
The main program which loads a font description, uses features of thettfont
module to build a font, and writes a TTX file for TTX to compile.sevensegment.dotfont
A sample font description that includes segments and layout of a font based on a typical seven segment display.ttxml.lua
A module wrapping LuaXML and offering a function to create a TTX representation of a TTF table from a Lua table. TTX requires that the fields of a table be in the right order, have the right names, and all be present. This makes those details easier to maintain.ttfhead.lua
,ttfhhea.lua
,ttfmaxp.lua
,ttfname.lua
,ttfos_2.lua
,ttfpost.lua
These are modules that implement specifics related to the TTF tables mentioned in the file name. Not every table in the font has a module, but many do.ttfont.lua
This module provides an API to allow the main utility to create, extend, and save a.ttx
file. It manages a number of tables that are intricately involved in specifying glyph shape, metrics, and mapping. Call the functionPlaceGlyph()
to add a glyph to the font mapped to specified code point. Call the functionSetNames()
to provide the font name, version, and other strings. Call the functionGetFont()
to compute final statistics, build final versions of the tables, and return a LuaXML object containing the complete TTX of the finished font.Makefile
Provide a few handy build rules to compile a font and to get a PDF report showing all the glyphs and their outlines.
Playing Along at Home
Clone the public fossil repository.
The version of the code described in this post is from checkin [9a99a4c5e4].
There are a lot of features missing from the script, but the bones are there to build upon. dotfonter.lua
defers to an external file for both the shapes of the segments and the ROM image itself. The sample file is the same seven segment display font we’ve been discussing so far.
All of the code is licensed under the MIT license. Please do let me know if dotfonter
is useful to you, or if you find any issues.
Supporting Cast
Here’s some tools I’m using to develop this utility:
- Lua is a remarkably powerful programming language originally created to extend large applications through scripting and data representation. Modern versions are stable, free, perform well, and are suitable for constructing complete programs, with supporting libraries written in C.
-
The usual Lua IDE with highlighting, debugging, and many other features is ZeroBrane Studio. Unlike most IDEs, it treats the file system as the only metadata it needs about a project, which makes it trivial to work with any version control system desired. This project will use fossil, as is my habit.
-
While Lua doesn’t require a build step in general, distributing our utility will mean building a release
.exe
file along with a.zip
containing that along with some documentation. Since our needs are simple, the classic make will do all that we need. -
fontTools is a library for manipulating fonts, written in Python. TTX is a font conversion tool based on the library that can convert a variety of fonts into an XML form, and convert the XML back into a font in a variety of formats.
-
FontUtils is a collection of font manipulation utilities written in Perl that includes fret, which draws nice reports showing detailed views of all glyphs in a font.
When working with TrueType at this level, having documentation to refer to that can unambiguously answer detailed questions will be handy. Resources that were helpful include:
- ISO/IEC 14496-22:2015(E) OpenType, standardized as Open Font Format. Since OTF shares many details with TTF, this covers many details of TrueType as well as OTF. The link is to the ISO/IEC directory of free standards, search that page for 14496-22 and collect everything that seems relevant.
-
TrueType according to Apple The TrueType Reference Manual from Apple. It covers most details of TTF, with strong recommendations for keeping Apple systems happy.
-
OpenType according to Microsoft All things OpenType, references, links, and recommendations from a Microsoft and Windows point of view..
Foreshadowing
Watch this space for more articles about work in progress on the utility.
The code I have running today has created a TTF font from scratch covering only the digits, and a few letters. The output is styled after a seven segment display and is a fixed pitch font.
The next step is to build a collection of contours for a dot matrix display, and a ROM image that uses them.
Summary
After making a dot matrix display font by hand using the impressive capabilities of FontStruct, I decided I wanted a tool to make the whole process easier. The result is the work in progress currently named dotfonter
.
If you have a project involving embedded systems, micro-controllers, electronics design, audio, video, or more we can help. Check out our main site and call or email us with your needs. No project is too small!
+1 626 303-1602
Cheshire Engineering Corp.
710 S Myrtle Ave, #315
Monrovia, CA 91016
(Written with StackEdit.)