Font PJW Portfolio

by drj

What if we took this …

The word 'Dolphins' in the pixel font Pellucida

… and this …

Face of Peter J Weinberger as a flat black-and-white art

… and combined them? We’d get this:

The word 'Dolphins' in the same pixel font, but each pixel is
  a tiny image of PJW’s face

Font PJW

Font PJW is something of a niche joke, and largely not one of mine. It’s a real font that you can download from my repo.

There is a tradition amongst the Unix old guard of putting the face of Peter J Weinberger on and in things. There's a whole web page dedicated to these antics.

Why not use PJW’s face as a pixel in a pixel font?

Why not use pelm from Plan 9 as the pixel font?

Why not indeed. So that’s what i did. There are two prongs of progress: one for the face, and one for the pixels; and a final step where they are combined together.

Face

Starting from a not brilliant scan on the spinroot page, i poked about in Inkscape until i had a reasonably thresholded and autotraced outline. Then i imported it into Glyphs and cleaned up all the contours by hand. There were so many points.

I exported this as a UFO, Unified Font Object, which is a pile of XML that’s not too cumbersome to process with “custom scripts”.

Pixels

I had already done much of the preparatory work. In the Python 2 era i had written priplan9topng, a rough implementation of Plan 9 image decoding, and had revived it in 2023 to run on Python 3. A Plan 9 font (subfont, strictly) is a Plan 9 image of all the glyphs packed left-to-right and an additional text meta block tacked on the end to describe the widths and bearings of each glyph.

Now i just had to track down pelm font from the Plan 9 sources, and decide which strike i was going to use.

Simple Combination

Combining these involves Custom Go Code that reads the PNG images for the source of the glyph pixel data, and the PJW face UFO object. The output of that is a font in UFO format.

This part was made not so simple because i had no familiarity with UFO. Although at least i used encoding/xml to write the XML out.

Aside: it turns out that Apple plist format is awkward to write from Go using encoding/xml because Go assumes you just want to write a struct with named fields, and the plist format is basically an ordered list of pairs (so that bit does not use encoding/xml).

There was quite a bit of head-scratching debugging. And some cursing when it seemed like my edits in the library i was trying to add debugging to had no effect. There were two almost identical functions and i was editing the wrong one, haha.

Also some cursing when fontmake correctly reported an error with my own XML, but the error was "obviously bogus" because the XML i was looking at was fine. It turns out that the XML i was looking at was indeed fine, but it is translated by my own code and put in a different XML file; that file is the one that fontmake is using and it does indeed have the error that fontmake was reporting.

Full vector component

The pixel in the font is technically a component in the TTF glyph outlines; it is stored in the font at full fidelity. This pixel component is the only thing that appears in all the other glyphs in the font: each glyph has one component per pixel with the pixel component positioned at the appropriate place in the grid.

It turns out that this broke the TTF format for this glyph:

A pixelly question mark inside a box

Which in Plan 9 was at code position 0x80 (not really assigned in Unicode); i suspect it was mostly useful for debugging.

This glyph has 49 pixels (that is, “turned on” pixels), which is the most pixels of any of the glyphs.

The problem was that in a TTF font the max number of nodes for a composite glyph cannot exceed 65535 because that value is stored in a 16-bit field in one of the header tables.

The face pixel has 1239 nodes in UFO format, and 49 × 1239 is 60711; which seems like it should be fine?

That UFO format represents the face with cubic Béziers. These are converted by fontmake to quadratic Béziers. In general using quadratic curves will require more segments compared to using cubics. But when i investigated, it looks like the pixel as stored in the TTF file has only 908 nodes. So maybe something else is going on.

In any case, i removed the offending glyph from the font, and fontmake then proceeded to correctly build the output TTF.

Recursive Edition

Now of course whoever put pelm into Plan 9 was not oblivious to the tradition of putting PJW’s image in things (in fact, i suspect they were There At The Beginning). Which explains why pelm from Plan 9 has a tiny picture of PJW (at code 0x00 meaning any unimplemented glyph will appear as a tiny picture of PJW). In Font PJW i moved a bunch of things from 0x00–0x1F to U+2400–U+241F.

I present to you U+2400 SYMBOL FOR NULL, aka PJW in PJW:

A lo-res pixelly image of PJW made of out hi-res vector copies of PJW!

Aside: this particular image required some circumlocution to produce, because at time of writing (2024-06-11) this glyph (along with others like /H and /dollar) didn’t render using harfbuzz because it had too many points; that’s now been fixed, but it may take a while for the fixed code to appear in any particular system.

Reflection

Yes, this is a silly joke.

Visually, the effect works better than i was expecting. At typical screen reading sizes, the font is about as reasonable as you would expect for a 1990s pixel font dragged into the 21st century; at larger sizes the face pixel is approximately a hemisphere lit from the left so gives a “font made from round bumps” effect. Zooming in or greatly enlarging the font gives the full PJW effect.

END