Welcome back to “Una Makes Fonts for Some Reason,” this is probably the third
installment, which is cool. Today, we’re once again aiming to complete the
styling on una-ada.github.io, particularly regarding code blocks
and
their need for a monospace font. I want to try to keep this consistent with Una
Script stylistically, but with enough distinction that you can tell there’s a
difference. Before I get to that, though, there’s some minor technical details
I want to address regarding Una Script, but after that I’ll be making a whole
new font. This time I might even try to be a bit more thorough in the design
process… like, actually use the scanner I have access to.1
Something I’ve sort of been struggling with for a while now: what is normal
for an EM square? Like, what’s the typical position of the baseline? Currently,
Una Script has ascent and descent metrics at
I couldn’t find anything when searching for references on “typical” sizes here, so I’ve decided to go back to basics. First, returning to the Design with FontForge tutorial’s Font Info & Metadata page. I had high hopes for this one, honestly, but it’s only a brief coverage of how to edit the metadata of your font, which does include overall metrics but not any sort of guidelines for them. Similarly, The EM Square only goes over the various heights and a brief reference to the existence of Blue values. A bit more digging brought me around to another site, Font Development Best Practices, which has a section on metadata that has the design metrics guideline I’d been looking for.
It doesn’t give a “use these values for this style of font” or anything like
that, only recommends comparing to similar (or competing) fonts, which is a
good strategy here. There is some discussion on the UPM (units-per-em), which
should be either
“Note that glyphs can freely extend beyond the EM square if the font designer wants this. The EM is used as a convenience, and is a valuable convenience from traditional typography.”
What I’ve learned here is that the next step is to find other fonts that might have similar metrics to what I’m aiming for and see what those numbers look like. Then I resize the glyphs in Una Script, allowing the long descenders to pass beyond the descent ruler.
My first thought was that some of Google’s fonts (namely Noto as used
here) likely have documentation on their metrics. This brought me to a fair bit
of other documentation on the googlefonts/gf-docs repo that will be more
useful in a later section, but not what I’m looking for at the moment. I did
eventually find the FONT_CONTRIBUTION file for Noto, which lists the Noto UI font metrics, which are Roboto Regular’s metrics translated to a UPM of
OS/2 | Noto UI | Open Sans |
---|---|---|
TypoAscent |
1069 | 1056 |
TypoDescent |
-293 | -271 |
TypoLinegap |
0 | 0 |
WinAscent |
1069 | 1056 |
WinDescent |
293 | 271 |
Then I spent several more hours trying to find some other metrics to reference, mostly dead ends, but apparently the Liberation font collection’s source uses FontForge so the metrics are fairly easy to find by reading the project file code:
OS/2 | Serif | Sans | Mono |
---|---|---|---|
TypoAscent |
1420 | 1491 | 1255 |
TypoDescent |
-442 | -431 | -386 |
TypoLinegap |
307 | 307 | 0 |
WinAscent |
1825 | 1854 | 1705 |
WinDescent |
443 | 434 | 615 |
While it’s best ignored, the “General” values for ascent and descent in these
files are all
What am I going to be using then? I still have no clue, so I’m going to do some testing. I spent a whole night doing this research and I wanted to get this all done in a single day, but if running a whole bunch of tests is what it takes to do this right then that’s what’s going to have to happen. I still want someone to guide me here, but the Glyphs docs just say:
“Different type designers employ different strategies on how to find the best values for the vertical metrics. But beware: amongst font nerds, there are fierce disputes going on about what is the best strategy.”
and that doesn’t help me at all! There is some good stuff about setting up the
values for webfonts. So I’ll try to use that methodology throughout my testing.
I don’t want to use the actual descenders as a reference point here, since they
are so long, so I’m going to start with things like the swash on the “Q,” which
comes off as pretty extreme when you look at the current scaling which round to
about
Updating all the glyphs will require a bit more than simply setting new metrics, the outlines will also need to be adjusted in both size and position. Size is rather easy, it’s really just doubled here, but position is difficult as apparently not everything transforms correctly. The first error in this was me transforming from center rather from the left, so I needed to fix the bearings. Easy as that was, I tested the metrics and found that glyphs with long descenders were higher up than the rest, and checking the positions of those others showed that nothing was on the proper baseline… attempts to adjust everything at once didn’t seem to work for some reason, so I’m going to have to go through them all and make manual adjustments. Fun!
While I’m at it, I figure I’ll go through and make the font slightly more
aligned to the BlueValues
, do some simplification, and run some other checks
to clean up the vectors. Again, for the new font and for additional glyphs to
this one, I really want to figure out how to make sure this is all done before
the vectors are even imported into FontForge (will discuss this later when
working on exporting).
When I finally reached the lowercase letters, I did notice a small issue: my
ascender height is absolutely higher than my cap height! I’m going to have to
adjust the values here: BlueValues
is
The other little setup step I wanted to do before I really get started on this font has to do with file structures and repositories. Foolishly, I’d previously combined my two existing fonts into the same family (Una) and the same repo (una-fonts), this is bad! First off, font families are just a collection of “subfamilies” or styles, like bold, thin, regular, italic, et cetera. “Una” is not a font family but a collection of families (tho each family currently only has a “Regular”). This needs to be changed in the metadata, no big deal, just keep it in mind going forwards and update them as I get around to it.
The repository thing is really just a choice of how one wants their content organized, but keeping them in the same repo is a bit iffy when they’re not even the same family. So I’m going thru and undoing that whole complicated merge thing I did to combine the previously separate repos. But this brings about the question of how each of these repos should be structured.
Currently, there’s a /scans
directory which contains the “scans” of the
original designs, /src
for the vectors produced from those, fontForge
which
just holds the FontForge project file, and finally /build
for all the
finished builds (in subdirectories by version). This isn’t too far off from
what the Google Fonts docs state as the required repo structure:
.
├── AUTHORS.txt
├── CONTRIBUTORS.txt
├── OFL.txt
├── README.md
├── documentation
│ ├── DESCRIPTION.en_us.html
│ └── promo.png
├── fonts
│ ├── ttf
│ │ └── FontFamily-Regular.ttf
│ └── variable
│ └── FontFamily-[wdth,wght].ttf
├── sources
│ ├── FontFamily-sources.ext
│ └── build.sh
├── requirements.txt
└── .gitignore
This wouldn’t require a huge refactor or anything, just some moving and renaming of some files. This is a good thing to decide on here and now when I only have a couple repos with a few builds to comb through, and then try to keep to the structure for future projects (e.g. this one).
I’m going to keep this one simple, just get the basics down for now at least,
and only cover 0000 C0 Controls and Basic Latin. Doing something a bit
different this time and using a template. Having this printed out makes
it pretty easy to make sure the glyphs fit into the intended metrics (vertical
metrics were previously discussed, horizontal were decided to be
As for the concept of the design, I’m trying to maintain a consistent style with Una Script (my handwriting) while also adopting a few adjustments to make the letters fit more into the intended width. This doesn’t really show all that much beyond adding crossbars and serifs here and there, since I really just want it to be a metrically consistent alternative version… oh, there is the thing with how all the descenders are different, that one’s pretty obvious since the ones on Una Script are pretty long, lol.
Continuing on with attempts to do things more “properly,” this time I’m going to actually use a scanner instead of just taking a picture. This should help with keeping the metrics all consistent… though, given that the template has guidelines for them, it wouldn’t be too absurd to correct them later, but again that would be deferring issues until later when they can be avoided now. Only saying this because of some technical issues with getting scanners to work, but managed to resolve that and now have the scan.
I did put in all this effort just to write out new glyphs, I realized along the
way that I could just copy the vectors of Una Script and adjust them to the
intended metrics for this new font… this is for stylistic consistency and not
because I’m already tired of working on this. Other than that this follows the
typical Una formula for tracing with vectors in Illustrator: draw points
with the pen tool (P), curve the lines with the anchor point tool (⇧C),
direct selection tool (A) to fix up any curve lines and anchor points,
rinse, repeat, on and on… it’s a very repetitive process. But I got through
it eventually!
Then these vectors need to be cleaned up, which doesn’t require too much
creativity or guessing this time around on account of the consistent metrics. I
set up a new Illustrator document as 1000 x 1000 and put guidelines down for
the baseline and x-height, calculated the amount I would have to scale the
vectors up by dividing my UPM by the height of the scanned templates, and
guessed the stroke width I could get away with here (
Cool Illustrator Trick 1: Rather than using a transform on the whole layer of glyphs and making the layer fucking massive, I can use
Object > Transform > Transform Each
to resize each path or group without changing their position and thus keeping them more or less in reach for later editing!
Cool Illustrator Trick 2: These glyphs are all currently either simple paths or groups in the same layer, but later I will want to export them all using a script that exports separate layers.2 This means moving each and every one of them into its own layer, which can be a real drag. Since I already have all the layers I want the objects to be in, I can select the object in the editor, select the layer for it in Layers, then use
Object > Arrange > Send to Current Layer
.
This isn’t exactly normal for a monospace font, but along the way I decided
that some glyphs, particularly capitals and similarly sized glyphs, would
actually have their strokes meet the path guideline for the ascender.
Essentially, making my cap height
Cool Illustrator Trick 3: If you transform an object with something like a rotation, the bounding box will no longer be orthogonal to the grid, which is inconvenient for sizing relative to guidelines! There is a tool to fix this which you can access with
Object > Transform > Reset Bounding Box
.
After another grind through all 944 glyphs, I managed to survive this step as well. It is Monday already and I wanted this whole font done Saturday, so I’m not exactly happy with my progress!
That’s most of the design-oriented steps of the digitization done! Now I’m
moving on to more technical parts. These glyphs are all paths at the moment,
which theoretically could be imported into FontForge as is, then use the
Expand Stroke facility in there. I’m considering switching my workflow
over to this as it would allow for variations in font weight, theoretically,
but that is an experiment for a later time. For now, I’m sticking to doing the
expansions within Illustrator because I adjusted these glyphs based on the
strokes they have now, removing the strokes and adding them back in later could
lead to some deviations and errors. That said, I just need to unlock and unhide
all my layers and apply Object > Expand...
to every object.
Cool Illustrator Trick 4: Clicking on the visibility toggle and dragging down a long list of layers is annoying at best. If you just want to hide all layers except for one, then hold Alt/क when clicking on the toggle for the layer you want to work on and it will hide all the others!
Expanding does most of the work, but it does (sometimes) keep the original
stroke and overlapping strokes will just be overlapping outlines now, so I need
to do another pass through using the Unite
function in the Pathfinder
. I
would love to just apply this to all layers at once, but having multiple glyphs
selected when running this function would just unite them all into one object!
Cool Illustrator Trick 5: Is expanding your strokes not working? Are your nice, rounded caps defaulting to boring flat ends? Then you need
Object > Flatten Transparency
! This fun little function is significantly worse than expanding and will need to be cleaned up with a bit ofShape Builder Tool
(⇧M) andObject > Path > Simplify
, but it’ll still do the job!
Since this is completely routine, with the steps the exact same for each layer (toggle visibility, select all, unite, toggle visibility, repeat…) I would really like to just automate it, but I do not know how! Wll, since I’m probably going to be doing this a lot in the future, might as well put the effort in now.
Ok, detour time, automating this annoying thing. First off, this doesn’t seem possible to be done with actions, so it’s going to have to be a script. Also, this doesn’t seem super uncommon a thing to do, so there’s probably already one made for it. I found some blog post in my initial search, which seems to be just someone saving a reply from the Adobe Support Community, and it doesn’t work. Looking into why it doesn’t made it obvious that this weird single-line snippet was all lowercase? So I searched for the original thread and found not only the properly formatted reply, but another more complete script by the user zertle:
function MergeAllLayers() {
// exit early if there are no files open
if (!app.documents.length) return;
var doc = app.activeDocument;
// clear selection
doc.selection = null;
// loop through all layers
var layers = doc.layers;
for (var i = 0, ii = layers.length; i < ii; i++) {
// select everything on the current layer
layers.hasSelectedArtwork = true;
app.executeMenuCommand("group");
app.executeMenuCommand("Live Pathfinder Add");
app.executeMenuCommand("expandStyle");
// clear selection
doc.selection = null;
}
}
MergeAllLayers();
… and … it didn’t work! Let’s figure out why. First, strip this all down to just what’s inside the loop, replace variables with their definitions, and try that. Nothing. Line by line then, does the selection trick work? No. According to an answer to a similar problem, what actually needs to run is:
app.activeDocument.activeLayer.hasSelectedArtwork = true;
So, how do I change the active layer when looping? Or can I just select each layer from an array while looping? Reading into a thread on a similar topic implies that’s what I should do:
for(var i = 0; i < layers.length; i++){
// select everything on the current layer
var layer = layers[i];
layer.hasSelectedArtwork = true;
// ...
}
I’d also like to throw the expansion step into this script so I can avoid doing that one manually in the future as well (even though it’s trivial), but there’s a dialog for it so it would actually be worse to do it that way. There is a way to circumvent this, but it requires setting options for Actions, so it isn’t all handled in the script (I want to avoid doing that). Anyway, for safety, I’ll also throw in a little guard for locked layers:
if(layer.locked) continue;
Now the script is all working! This will be excellent for future work, even though in this instance it probably took up more time to write and debug. 😅
Now back to same old same old: using Tom Byrne’s MultiExporter.jsx
to export all these layers as SVGs. When running this script, remember to
deselect the “Trim Edges” option. I foolishly forgot to do this the first
time around and it cuts all the exported SVGs down to just the size of the
glyphs themselves rather than the whole em square!5 For organization, I’m
creating a new directory, /sources/vectors
in the repo, and putting
everything here in a subdirectory for the Unicode block in case I want to
expand the coverage of this font later on: /sources/vectors/0000
.
That’s it for this section, I now have a folder containing all my vectorized glyphs, individually, properly positioned. 🎉
Finally, I get to open up FontForge. Yay! I don’t need to do anything to the settings on encoding opening the font, I’m only doing the ASCII characters here, so there isn’t really any need to change the character set from the default. Importing is straightforward with hotkeys: ⌘⇧I on each glyph. Selection for imports is pretty easy, since all the files are named after the glyph name, I really wish I could automate this, though. I swear I’m not going to detour for that this time.
It isn’t super important for the end product to set the ascent and descent
values, but I need to do it so that the imports are properly positioned with a
baseline at zero (and also so the previews look better). As previously
mentioned, these values are
Now that all the vectors are imported, it’s time for some cleanup! Just
going to run Element > Validate
to get a quick rundown of what might need to
be fixed before probably just running through the motions I’m already used
to… okay, so it kind of crashed when I did that. It’s to be expected that
there would be some weird issues, this is my first time running this on a Mac.
So let’s just do the basics then:
Element > Add Extrema
(⌘⇧X)Element > Round > To Int
(⌘⇧_)Element > Correct Direction
(⌘⇧D)Then I’ll run a manual Element > Validate > Find Problems
, and see what it
comes up with. Which seems to be some “the paths that make up this glyph
intersect one another,” and I need to remember how to fix that. A comment
on GitHub recommends Element > Overlap > Remove Overlap
(⌘⇧O),
which seems to work.
I’m also getting a lot more missing extrema errors than I’d expect, and checking the glyphs doesn’t really show any obvious problems. According to a thread I found about this, it’s okay to ignore these in instances like this, or just in general apparently.
Calling it good for the vector issues at this point. Onto metrics!
Luckily, since this is a monospace font, I don’t have to bother with kerning
this time! I do still need to do a little bit of horizontal metrics,
specifically with bearings and thus width. I’ve decided to keep similar to Una
Script spacing where the default bearings are Metrics > Set Width
(⌘⇧L) then
Metrics > Center in Width
, and that’s my horizontal metrics done!
Vertical metrics is where I actually have to start trying 😭. Starting with the
basics, none of these should go past the em square so my typo
, hhea
, and
win
values should be the same as my ascent and descent. Easy. My capital
height is
Then there’s the BlueValues
and BlueScale
properties in the PS Private
table… the automated guess for these was
All that’s left here is to set the rest of the metadata: the PS Names
table.
Sticking to a better format for this stuff this time, the Family Name
is “Una
Mono,” the Fontname
then is UnaMono-Regular
, but still naming the versions
by the date (2021.05.31
). Now there’s only one more step for this
section!
Time to export the font with File > Generate Fonts...
(⌘⇧G)! From
here on, I will only be generating the TrueType (.ttf) files in FontForge, to
keep with the simplest repo structure. I’m selecting both “Apple” and
“OpenType” formats in the options, since that seems to be the best way to do
it, and just leaving everything else as default. This gets exported8 into a
new directory, /old/[version]
, and then copied to the /font
directory. Et
voila, font done! 🔥
Theoretically, this font works just fine, I did check the metrics in FontForge after all. However, how does it feel in context? How does it look in the “real world?” Time to find out! First, this was meant for code, so here’s some typical sort of code:
So far, this looks fine, not a huge fan of how the =
and >
align, but I can
live with it until I decide something bigger needs to be changed. But code is
usually multiple lines, and the point of monospace fonts is to be consistently
wide so characters line up, how does that look? Here:
Okay, so it looks alright on its own, how about next to another font? Specifically, how does it look with Una Script?
First thing to note here: the sizes are similar enough to not really complain about! This would have been a huge problem if not for the work I did in Section I, so hooray for that. Other than that, the weight has a huge contrast, and this was noted when I was discussing the stroke widths in Section III; heavier would not work at all with the font, so if I want them to be the same weight, that will be something to work on for Una Script.
Again, the issues here are mostly Script’s fault, not this font, but there is also the x-height inconsistency to note. It looks like Script has much taller lowercase letters here, because they tend to be higher up while also being very inconsistent between glyphs. I don’t know if I want to go through and change this, but it’s a big consideration with respect to future work on that font.
What if we use Una Mono alongside another font like Noto Sans? Then we see a better consistency in size, but there is still a slight difference in weight between “Regular” fonts:
However, in this case we can reduce that contrast significantly by choosing a different weight for Noto Sans, such as SemiBold:
It’s safe to say, from these tests, that Una Mono Regular is actually more of a SemiBold weight; though, as far as I know, there is no standard for what each font weight looks like. I may consider for future work, on both Una Mono and Script, adding variable weights, and aiming to create more consistent styling across them in that regard.
That was everything I wanted to test, at least with the design itself, I’ll save the work of using it as a web font on una-ada.github.io for a later time.9 Cheers all around, patting myself on the back, go me! See you next time on “Una Makes Fonts for Some Reason” when I’ll “probably” continue to try to make better things in better ways (I’ll at least try)!
In the process of writing out this paragraph, I got distracted by attempting to fix my VS Code settings to add word wrap to Markdown language files. Here’s a useful link about that. ↩︎
Note about my methodology with this, I decided back when working on Una Script that the exported vectors should all be named as their Unicode character name in camel case. This makes it easier to find them later when importing into FontForge. ↩︎
It was at this point that I once again started caring about how VS Code
works. Specifically, I ended up having to correct a lot of typos, so I
wanted some sort of spellchecker. Looking for one in the marketplace, I
came across Code Spell Checker by Street Side Software
which not only will do spellchecking for articles like this one, but
also can handle camelCase
words in code! Big fan! ↩︎
But there’s 95 characters in U0000! Well, one of those is the space, which doesn’t have any vectors and will be constructed entirely out of bearings in FontForge. ↩︎
Not only can this be a huge pain in the ass when it comes time to import the vectors to FontForge, it also slows the script way down as it has to determine the trim sizes for nearly a hundred layers and it tends to stop if you click away from the window unlike when it’s deselected. ↩︎
This was more complicated in previous fonts because they weren’t designed to be as metrically consistent, whereas the glyphs in this instance were meant to stay around the guidelines. ↩︎
It crashed again! Last time I ran the validation check it didn’t, so I was hoping I could get away with it again. Whatever, I’d probably just ignore the errors at this point anyway, lol. ↩︎
Validation ran just fine on the exporter. Confusingly, a few new issues popped up: new non-integer values and a self-intersecting glyph. Those were pretty easy fixes, but still weird to see at this point. ↩︎
Probably later tonight, if I’m being honest. ↩︎