Tags

, , , , ,

After using dotfonter to put together several demonstration fonts, each of which had quirks when installed on Windows that took some effort to untangle, it seems like a useful time to post a list of things to verify about a new font.

Unlike the last several posts, we wont be adding any fonts or capabilities to the tool, or really even using the tool.

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.

A Usable Font

What makes a font useful?

It has to have character forms that meet some purpose and that has to be valuable enough to justify the time and effort spent on creating a new font instead of locating an existing one that does the job. One could digress into many volumes about this, but nearly all of that discussion would be about aesthetics, art, and design. Any technological issues would perhaps center around measurable details like legibility, or definitions like “sans serif” and “fixed pitch”. From an engineering perspective, this is interesting to learn about, but has little impact on the form of a TrueType font itself.

Unless you are designing entirely for artistic or personal use, it likely has to comply with some standards for what actual glyphs are present, what they are called, and what character coding is used to find them. In the past, once you ventured very far away from American English and ASCII character codes then things got complicated. (Go read about [] if you want a taste of how bad things were.) These days we have Unicode which has room for coding about a million different glyphs, all arranged in a single encoding so that it is possible to use many different writing systems and many different languages in a single document. This helps because with Unicode, a LATIN CAPITAL LETTER A will always have code U+0041 regardless of what font is used or what platform or application is used.

Unicode has also set standard codes for a large number of printer's dingbats and even most of the emoji used in text messaging.

And it has to "work" in your platform, with your application, to achieve your purpose.

But regardless of why you want a new font, let's assume that you have a reason that is good enough for you. You have done the design. You have thought about the subtle issues. You understand the x height, the em width, and the rest of the quirky jargon of font design, or at least enough to get by.

Now we reach the technical side.

All of that design work has to be represented in a way that can be simply called up and used by your software. The prettiest headline font in the world is useless if Word can't style a headline with it. The craziest art font is worthless if Inkscape can't style text with it.

The usual answer to that is to use a dedicated tool for font design, such as fontforge. The best of these will let you draw the outlines, copy them from letter to letter, and otherwise do all of the graphical tasks in a GUI environment. Most of the rest of the details of the font are either set by markers in that GUI, or by direct entry of metadata in forms. The advance width of each character is usually a marker you position along with the outlines, while the copyright notice is entered on a form. The details a lot by program, of course.

Our dotfonter utility is just another font editor, albeit one that is intended to be driven by simple tabular data such as a character generator ROM.

At the end of the day, the result is a TrueType Font in a .TTF file that should be immediately usable by Windows and other platforms, or possibly even loaded directly in page layout programs that can work with fonts that are not installed on the system. (LuaLaTeX is one example, it can load and use a TrueType font given just its file name.)

Checklist

Windows (and I presume other platforms that use TrueType and OpenType) has some quirks related to how fonts are designed and specified in detail. A font that addresses all of the quirks will work without trouble in nearly any version of Windows. I'm not sure it is possible, however, to even know what all the quirks are, let alone how to properly address them.

This is a list of things to verify when building a font with dotfonter for use with Windows. It may not be complete. Many of these have sensible defaults (and likely lack an official way to adjust) in dotfonter, but I'm listing them here because finding those sensible defaults in some cases took effort.

  1. Define some glyphs. A font without glyphs is not particularly useful.
  2. Define name strings 1 (ffam), 3 (ufid), 5 (vers), and 6 (PSnm) at minimum.
  3. Set name string 19 (demo) so that it uses only characters present in the font.
  4. Verify that name strings 3 and 6 are defined.
  5. Verify that name string 5 matches fontRevision set in the head table.
  6. Make sure your advance width and left side bearing are sensible.
  7. Make sure the tables agree if your font is fixed pitch. FontValidator has a test for this.
  8. For sanity, set bit 0 in both ulUnicodeRange and ulCodePageRange in the OS/2 table and map at minimum the letters needed to spell your font name.
  9. Best practice is to set the PANOSE fields of the OS/2 table per specification.
  10. Get FontValidator mostly happy.

Notes

According to this answer at Stack Overflow strings 3 and 6 are mandatory for a font to be installed (or even Previewed) in Windows, which was not clear from any text in any of the TTF or OTF documentation. Without them, Windows will pop up a cryptic error message instead of previewing or installing the font.

dotfonter will provide or compute default values for strings 2 (fsub), 5 (vers), 8 (manf), and 19 (demo). It will also supply a value for string 256 noting that the font was compiled by dotfonter.

Name string 19 will default to "Mix Zapf with Veljovic and get quirky Beziers" which is a pangram (if you ignore letter case) of the Roman alphabet, and pays tribute to two important font designers and the mathematician whose spline curves formulation is used in TrueType.

Some applications (Microsoft Word, for example) will attempt to use each font to display its own name. This is great for fonts that are proportioned and scaled similar to the normal GUI font used in menus. To support that, include enough letters to spell the font name sanely and set bit 0 in both ulUnicodeRange and ulCodePageRange. Unless you also fully cover the 200-odd characters of Latin 1, that will cause a FontValidator warning, which you may safely ignore.

A font is fixed pitch in practice if every printable character has identical advance widths. Windows likes to know this so that it can avoid substituting a fixed pitch font for a variable pitch, or vice-versa. In order to know this, it looks at the isFixedPitch field in the post table and at the PANOSE kind and proportion digits. Even if you code nothing else about a font, specify the PANOSE "Family Kind", "Serif Style", and "Proportion". If the PANOSE proportion is set to monospaced, then make sure that every character width is identical, and that isFixedPitch is non-zero.

Panose and Family Class

PANOSE is an elaborate specification for a classification system for font shapes. If fully implemented by both font designers are software, it allows a specified font to be replaced at point of use by a "similar" font. Full execution involves making as many as 65 specified measurements of details of certain character shapes, and calculating a further 39 values from the measurements. Ratios of measured and calculated values are then used to drive selection among a small number of choices for each category. While most of this process could be automated, there remain a number of subjective judgments.

dotfonter fills in a default PANOSE table that is likely not a complete lie for the sorts of monospaced fonts the tool is designed to easily build: 2, 0, 6, 9, 0, 0, 0, 0, 0, 0 or monospaced medium weight Latin Text with all other details unspecified. The default weight class of 6 is a "sensible" assumption.

According to Microsoft's OS/2 table documentation, Windows wants "sensible" values for PANOSE family type, serif style, and proportion to use for categorizing fonts, and in particular it wants symbol fonts to set the family type to 5 instead of one of text-oriented values.

Actual measurements of both the five by seven dot matrix (WeightRat = 7.98) and seven segment (WeightRat = 6.84) sample fonts reveal the dot matrix should be classed as 5 or Book Weight instead, while the seven segment is correct at 6 for Medium weight. A strong case could be made for both being classed as family type 4 (Latin Decorative) instead of the default type 2 (Latin Text).

The punched paper tape font somewhat outside the normal practices of font design, but PANOSE would likely consider it either type 5 (Latin Symbols, better fit) or type 4 (Latin Decoritive, a bit of a stretch). Assuming type 5, then the PANOSE classification would be (5, 8, 1, 3, 1, 9, 9, 2, 2, 2) which labels it as a symbolic monospaced pattern with very narrow (true aspect ratio is 10:1) characters. Setting that might stop Word from displaying the font name in the font itself.

The OS/2 table also includes sFamilyClass (a two-byte field defined by IBM) to serve a similar purpose to PANOSE. dotfonter filled it in with 0, meaning "unclassified". No harm seems to be done to the usability by this, but it might be more sensible to pick a default that is a better match to the PANOSE default at minimum, or otherwise set the two fields in ways that agree.

The five by seven dot matrix font might be better assigned sFamilyClass 0x080A, or Class 8 "Sans Serif", Subclass 10 "Matrix". That would seem to be direct match to that particular font's design and purpose. It is actually tempting to make 0x080A be the default value of sFamilyClass in dotfonter. Both the seven segment and paper tape fonts somewhat defy description, but could be plausibly classed as miscellaneous ornamental (0x090f) and miscellaneous symbolic (0x0c0f), respectively.

FontValidator

FontValidator is a worthy tool that examines all of the standard tables that make up a TrueType font for internal inconsistencies and errors. While it is true that a highly usable font can fail many of its tests, a font that passes all of them will likely work well. This is especially important for hinted fonts (which dotfonter can't do and likely never will do), for which FontValidator renders the font at many sizes and verifies that the rendering worked. It does tend to warn about things that just don't matter, and even many of its "errors" could probably be better called warnings.

Recently, the Microsoft team that built FontValidator has released most of its source kit for ongoing support. Newer releases are available via their github project, but I haven't yet evaluated them as they appear to be primarily released in source code form intended to build with the open source mono project instead of Microsoft's Visual Studio C# compiler.

Playing Along at Home

Clone the public fossil repository.

The version of the code described in this post is from checkin [5d5253b6].

There are still 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. This post shows that the external file alone had enough power to define a five by seven dot matrix font.

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 are some tools I'm using to develop this utility:

Documentation and references:

Foreshadowing

Watch this space for more articles about work in progress on the utility.

The utility is usable to me, but is far from ready to ship to others.

: https://en.wikipedia.org/wiki/Code_page (Wikipedia)

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.)