Worklog, Libre Caslon

394 views
Skip to first unread message

Stephen Nixon

unread,
Oct 25, 2018, 12:09:29 PM10/25/18
to Google Fonts Discussions
I have been doing some analysis and early work on Libre Caslon, originally started by Pablo Impallari (repos on GitHub: Libre Caslon Text and Libre Caslon Display).

I have combined these font projects into a single repository, with the near-term goal of master LC Text as a variable font for publication on Gfonts. Long-term, I hope to add style masters in order to have a fuller family:
  • LC Text Bold Italic
  • LC Display Light
  • LC Display Black
  • LC Display Light Italic
  • LC Display Black Italic
I will primarily document my work at https://github.com/thundernixon/Libre-Caslon-Text/tree/master/docs, so you can check that source for the most up-to-date progress. However, I will also post updates here for greater visibility in the community.


Stephen Nixon

unread,
Oct 25, 2018, 12:35:14 PM10/25/18
to Google Fonts Discussions

General Evaluation of Libre Caslon, as of October 2018

As of Oct 2018, Libre Caslon Text has relatively-complete character sets in Regular, Bold, and Regular Italic masters. These fonts have been converted from .vfb (FontLab) files into .ufo, then .glyphs.

I am now proofing them to judge roughly how much effort it would be to complete the family and publish them.

It’s an inviting basis for a typeface. It’s crisp and looks relatively modern, and it some three styles already drawn: Regular to Bold basis in the romans, and has an italic with a very heavy slant and cursive forms. However, like any work, it has some issues that could be improved. I'll go through the ones I notice first, as a basis for potential improvment work.

Without knowing exactly the sources Pablo Impallari used for the work so far, I am basing some of my critique on this Caslon specimen: Archive.org: A specimen of printing types by Caslon, William, 1754-1833

Technical Issues

Uneven widths

The n in the roman appears overly-narrow, in comparison to other letters. This means, by extension, that the spacing is called into question (because spacing tends to be based on the width of the n and o).

Inconsistent letterforms

Most of the serifs are "wedge-style" serifs, with sharp angles connecting serifs to stems. However, most of the diagonal letters, A, K, V, W, X, Y in regular, Italic, and Bold and the v, w, x, y in regular and Bold have smooth serif brackets.

inconsistent serif brackets

Letters with smooth vs sharp brackets

The design could also be thought of as a collection of smooth and sharp connections with more details taken in mind, such as the ball terminals of letters. If the scope is broadened like this, the design is slightly more balanced, though still, I would argue, could benefit from a more consistent approach to details. However, the consistency of serif brackets is an obvious detail to be harmonized, whereas terminals are separate enough visually, they can probably be safe to leave as-is.

Letters with smooth vs sharp details

There's no rule saying a typeface can't have different forms of serif brackets, but the inconsistency seems arbitrary. If a typeface is going to be a modern spin on a classic style by sharpening brackets, it makes more sense to be consistent, as Spectral is to the original model of Plantin type.

libre caslon vs spectral

Some drawings need revision

The A has an odd top notch which doesn't meet up. Additionally, this is much more accentuated than Caslon A notches that I have seen in historical references.

The thin legs are lined up in the wrong way – they should be offset in the opposite direction

The thin legs are lined up in the wrong way – they should be offset in the opposite direction]

Why doesn’t the top of the A align? This could be decomposed to work better.

Why doesn’t the top of the A align? This could be two contours in order to work better.

These ogoneks should be less “stuck on”

The X and x have misaligned thin legs.

Uneven slopes in Italic

The *f* is too visually sloped overall, because at its minimum slope, it matches the slope of straight stems in letters like *l*, whereas in historical sources, the midpoint is at a more gradual slope so that the overall shape matches the flow of surrounding letters.

These fs are overly slanted

The Regular & Italic styles seems overly light and thin for a "Text" typeface

When compared to an original specimen of text type from Caslon, Libre Caslon is much lighter and higher-contrast.

libre caslon vs original

There is also a regular weight of Libre Caslon Display, so it may be possible to extrapolate a roman with lower contrast. However, a quick test of this shows that the extrapolated "caption" style gets a massive x-height, revealing that one of the biggest differences in the original Text and Dispaly was a different x-height.

However, there is no Libre Caslon Display Italic, so this font would have to be corrected entirely by hand if we wish to adjust the contrast.

I was curious about the narrow ns and the sharp contrast of Libre Caslon Text, and wondered how it might compare against something like Times New Roman. A comparison shows:

  • The "regular" of Libre Caslon is a bit lighter
  • Overall, the letter shapes are noticeably more condensed.
  • The contrast in Libre Caslon is higher – thin strokes and serifs are more thin/delicate.

Libre Caslon vs Times New Roman

Is the italic overly sterilized?

Compared to the original Caslon, the existing Libre Caslon Italic has too symmetrical of stroke contrast from top to bottom. It's closer to "expansion" models of contrast, from fonts like Didot or Century Old Style, whereas Caslon was closer to a flat-pen, transitional-contrast model.

In addition, Libre Caslon Italic is very smooth, and lacks the sharp turns from the corners of the original, especially visible in the shoulders and bowls of letters like t, n, e, b.

Finally, Libre Caslon Italic is missing many of the warm details of the original cuts. Not only are swash caps J, Q, Tmissing, but other things have been lost, as well, such as the rotation of the o, the turning-in of the h, the elegant leaning-back curve of the f, and the hard angle of the A (pictured above). Finally, this may be partly a result of the overly-light contrast in Libre Caslon, but the joints / ink traps of letters like n, u, r, d appear to be much more aggressive in the original.

Italics

Odd font metrics

When compared to other fonts, including Libre Caslon Display, Libre Caslon Text has a much larger overall body size. This would be helpful to normalize before publication as a web font, in order to make font loading smoother from system fonts, as well as to make this an easier and more-predictable font to design with.

One positive thing shown when cap heights are matched: the stroke contrast of the Libre Caslon Text isn't quite as problematically high as I first thought. It's close to being the same as TNR and Times, and if the regular is interpolated to be just slightly bolder, the color of it might work decently well in text sizes.

This image compares the current Libre Caslon Regular against default "serif" fonts across several OSes and browsers, as they are according to this resource. It also compares LC Display for a look at the relative metrics. It shows things at the same point size to show how LC is abnormal, then at a "normalized" size, to better compare actual font sizing for x-height and overall weight.

relative-size-analysis.png

Some glyphs incompatible

Some glyphs are incompatible and currently preventing a variable font export. However, in most glyphs this seems to be only due to the bold master lacking anchors for diacritics, which will be relatively quick to solve.

incompatible-glyphs

Work needed

To make it good and useful:

  • Font metrics should be adjusted so that the text style is closer in body size to common fallback fonts
  • The regular weight instance should have a little more weight so that the text style is closer in body size to common fallback fonts
  • The character set will probably need to be expanded somewhat in order to meet Adobe Latin 3 or 4 (need to find current gfonts expectation).
  • A Bold Italic will need to be added, with care taken to make the weight properly match the upright Bold.
  • Letters will need to be given overlaps and made compatible for interpolation where they aren’t yet.
  • Anchors will need to be added to the bold in order to properly compose diacritics and allow interpolation.

To make it even better:

  • Ideally, I would be able to see the historical resources used by Pablo Impallari in the existing design.
  • Some of the letterforms will need to be optically corrected (e.g. x, italic f).
    • A full check should happen to determine all the spots that should be corrected.
  • We could experiment with how the font might look with sharper details in the ball terminals, and whether serif brackets should be all sharp or all smooth.

To make it really good, we might eventually do a few more things:

  • The weight range could be expanded (Light to Bold, or even Thin to Heavy)
  • Libre Caslon Display could be built out with Bold, Italic, and Bold Italic, to create a 3-axis variable font
  • Swash italics could be added
  • Greek, Hebrew, and Arabic letters from fonts by Caslon could eventually be added

Stephen Nixon

unread,
Oct 25, 2018, 1:04:06 PM10/25/18
to Google Fonts Discussions

Experiments / Early work

Normalizing Metrics

Metrics

Goal: get Libre Caslon Text to be similar in size to the most common default "serif" web fallbacks: Times New Roman, Times, and Tinos. This doesn't need to be exact (every font is a little bit different in body size, and that's fine) but it will be useful to designers to have it in the same ballpark.

Question: should we normalize vertical metrics or horizontal metrics?

The primary purposes of matching metrics are:

  1. Making Libre Caslon match the appearance of size of fallback fonts so that users aren't overly jarred by changing sizes of fonts as they load
  2. Making Libre Caslon predictable to design with, so web developers can try it in place of other fonts
  3. Preventing excessive text reflow when the font is loaded or used

If we wanted to prevent reflow as much as possible, we could match the width metrics of Times New Roman. However, because the overall width will change with the design of each letter (e.g. I intend to re-look at the widths of letters n, u, h, m), this is a very "slippery" goal. If users want an exact match, they can use Tinos.

Tinos, with exact same width metrics as Times New Roman

Instead of making the design completely subservient to matching TNR, I will blend the two approaches: I will roughly match vertical metrics, choosing the matching method based on what causes the least overall reflow from Times New Roman.

Process: opening font files in Glyphs to find metrics. Multiplying by .48828125 and rounding to compute from 2048 to 1000 UPM.

FontAscCapxHghtDscUPM (normalized)Asc+dsc
Libre Caslon Text Regular820770530-25010001070
Libre Caslon Text Bold820770530-25010001070
Libre Caslon Display734690424-26610001000
Times New Roman1420 (693)1356 (662)916 (447)-442 (216)2048 (1000)1862 (909)
Times (can't find file)------
Tinos1420 (693)1341 (655)940 (459)-442 (216)2048 (1000)1862 (909)

Matching: In matching the overall visual size of Libre Caslon to Times New Roman and other common fonts, there are three obvious ways to match the visual sizes with vertical metrics: by matching ascender-to-descender height, by matching x-height, or by matching cap height.

Matching full ascender-to-descender height makes fallback fonts look clearly bigger.

Most design manuals advise matching the visual sizes of different fonts by matching x-heights. This makes sense, because the large majority of letters in most text are lowercase.

However, a quick (approximate) test of matching the cap heights of Libre Caslon with the cap height of Times New Roman shows that it comes remarkably close to matching line-lengths:

checking line lengths

...so, I'll scale Libre Caslon so that the cap height matches Times New Roman. Some simple math:

LCcap = 770 * 2.048 # 1576.96, set to 2048 UPM

TNRcap = 1356

capDiff = LCcap/TNRcap # 0.8598823051948051

This tells me I should scale all letters and all metrics in Libre Caslon on the (0,0) point by 85.8598823051948051%.

I'll do this with Georg's recommended technique, scaling to 860, then changing back to 1000:

Scale it to a smaller UPM in Font Info > Font (the the arrow button next to the UPM value). Then set the UPM back to 1000 by typing in the text field.

With a quick export and check of this scaled version, it is clear that this sizing approach works better than the prior version alongside other fonts.

Alternative scaling approach

As a secondary approach to give points a better chance to avoid rounding problems, I have also tried scaling up to about 85.859% of 2048. 2048 is also a valid UPM setting, and scaling up will mean that points are jostled less by rounding to integer coordinates (because there will essentially be a higher resolution for outlines). For simplicity, I scaled the UPM to 1760, then changed the UPM to 2048. I repeated this process for the Text Italic to match vertical metrics there, as well.

checking scaled version

How might I test to check that point structures haven't been distorted by scaling?

When glyphs are scaled, points usually move from integer coordinates (e.g. x: 128, y: 540) to floating-point numbers (e.g. x: 109.89952, y: 463.6386). These must then be rounded to the nearest integer coordinates in order to export at a reasonable file size, resulting in slight shifts to points.

To check that that things haven't been distorted too badly, I could make a script to scale without rounding, then check differences with the version which was scaled and rounded. However, I believe that work would be mostly pointless, because:

  • Rounding, by its nature, will only move a point by less tha 1 unit x & y, unless GlyphsApp is doing some very unexpected math.
  • The main concerns of rounding after transformation is that things will no longer line up as needed. This is most impactful if
    • Points are suddenly missing a key alignment zone such as the baseline, x-height, cap height, ascender height, or hinting blue zone. This is not the case.
    • If a very thin stroke on a diagonal letter such as K is suddenly misaligned on either side of an intersection. A spot check shows that this is not the case in the scaled versions. I will have to be more cautious when working in the Libre Caslon Display masters, where thin strokes are thinner, and thus have a smaller margin of acceptable error.

Italic

It appears that some of the italic may have been created by half-rotating, half-slanting the romans.

Above, from left to right:

  • the existing italic g
  • g rotated 15° and skewed 5°
  • g rotated 10° and skewed 10° (this one looks pretty close to the current real version)
  • g rotated 5° and skewed 15°
  • g skewed 20°

This approach could be a quick starting point for the Bold Italic. On the other hand, it might mean that we should throw out much of what currently exists for the regular Italic, in order to do it better…

Dave Crossland

unread,
Oct 25, 2018, 1:29:37 PM10/25/18
to googlefon...@googlegroups.com
On Thu, 25 Oct 2018 at 12:09, Stephen Nixon <ste...@thundernixon.com> wrote:
I will primarily document my work at https://github.com/thundernixon/Libre-Caslon-Text/tree/master/docs, so you can check that source for the most up-to-date progress. However, I will also post updates here for greater visibility in the community.

Love it! :) Thank you Stephen 

Stephen Nixon

unread,
Oct 29, 2018, 4:59:18 PM10/29/18
to Google Fonts Discussions

I've done more work to scale Libre Caslon Display to better match Libre Caslon Text. Because it isn't as high a priority to ship as the Text styles, I will leave the work where it is, for now. This documentation is an update to the Experiments doc on GitHub.


Scaling Libre Caslon Display

I've tried the same approach to scaling the Display, scaling it to 1760 UPM, then changing the UPM to 2048. However, due to its original major difference in Cap Height and x-Height from LC Text, it is again way too small:

So, LC Display should have its own scaling approach. But should it again try to match the cap height of Times New Roman, or should it be based off of the sizing of LC Text? Because it should work best with its own family members, it seems obvious that it needs to be scaled based off of the LC Text.

But how, exactly, should the metrics of a display font related to the metrics of a text font, if they are set at the same point size? Should the cap height be matched, allowing the x-height to change? Or should the x-height be matched, allowing the Cap height to change? I lean towards the latter, because caps appear less frequently in most text, and I therefor consider them to be less of a foundation of a font's size than the x-height. However, is there an industry standard for how font metrics should relate between text and display versions?

Seeking a standard of opsz

I took my question to v-fonts.com to see what other type designers are doing for opsz font metrics. I updated the text areas to hold the following HTML, to prevent reflow of lines while scaling opsz, and also to get a good sense of the relative heights between capital and lowercase letters.

<p>AaBbCcDdEeFfGgHh</p>
<p>IiJjKkLlMmNnOoPp</p>
<p>QqRrSsTtUuVvWwXx</p>
<p>YyZz 0123456789</p>

OHno Blazeface keeps the x-height consistent and scales capitals

DJR Bradley is a bit hard to see, but seems to keep x-height consistent while moving capitals

Adobe Minion scales x-height while maintaining cap height

Underware Zeitung is very subtle, mostly changing spacing, but also keeps cap-height consistent while scaling the x-height

Clearly, there is no single definition of what Optical Size is or should be. Though most typefaces do use it to define the amount of thick/thin contrast in letterforms as well as overall letter spacing, it doesn't have a consistent, obvious meaning in terms of how vertical metrics are related. This probably means it's an open question that requires some design thought.

Here's a quick, rough comparison of LC Text & Display, matched either by cap height or x-height:

It seems clear that the first example changes overall visual size, including line-length, dramatically. Meanwhile, the second example (matching x-height) feels more like the same size of typeface – just with a few changed proportions, and doesn't change line length quite so dramatically.

Two possible exceptions come to mind:

  • What about when the type is set with more caps than lowercase?
    • While text is occasionally set in all-caps, observation of typography across websites and publications shows that text is set in mostly-lowercase letters, most of the time. Therefore, matching lowercase sizing will disrupt most text less than matching uppercase.
  • What if this shifts the baseline of text, relative to the top of the body? Could that cause problems with a shifting baseline if people are setting or testing this as a variable font?
    • In Adobe software, the top of a textbox is dictated by the top point of a lowercase /d.I don't know offhand what dictates text positioning on the web...
    • However, these styles will eventually be put into a single source file, which should match their baseline, even while other proportions change. Therefor, I don't think I have to worry about some arbitrary item changing baseline alignment between these styles.

With the decision to match x-height between Text and Display sizes, I simply have to compute the scaling factor to match the Display x-height to Text.

Libre Caslon Text's x-height is now 933 after previous scaling. Before scaling, LC Display's x-height is 424933 / 424 = 2.200471698. So, I'll scale LC Display to 2200 UPM, then change it to 2048 UPM. It seems to work well to match the x-Height:

...and a quick InDesign test of both fonts exported, then at the same font size, shows that things are matching up pretty well:

Importing the Display into the Libre Caslon Text GlyphsApp source

I suspected that the baseline wouldn't change in InDesign if the fonts were exported from the same GlyphsApp source. So, I imported LC Display into the LC Text source file, then exported these.

Unfortunately, InDesign is computing the text box sizing based on the height of the lowercase /d in each font style ... so the baseline does shift when the style is changed.

Additionally, putting LC Display into the GlyphsApp source file prevents successful FontMake exports, even though I have only set up Text instances.

As a side-effect, the imported Display seems to lose its former kerning between /v and /e.

However, for now, my objective is simply to make the text styles publishable. So, I'll keep the Display out of the Text GlyhpsApp source, then fix these issues in the future.

Stephen Nixon

unread,
Oct 29, 2018, 5:01:14 PM10/29/18
to Google Fonts Discussions

UPDATE, Oct 29: In regards to historical inspiration and my earlier evaluation, I should have first read the original repo's README more closely. -_-

As it says:

When we were faced with the challenge of making a new Caslon, we asked ourselves: How can we make them different, to bring something new to the table? We realized that most Caslon revivals were based on 18 Century's specimens, and that there was a whole genre of Caslons that has been so far ignored: The alluring hand-lettered American Caslons of 1960's.

This was a captivating subject to investigate. Caslon was the very first alphabet that lettering artists learned to draw, so they all were very familiar with it. Our wonder led us to find countless examples of beautifully crafted and elegant vintage ads and hand lettering books. Among those many books, there were two that outshine the rest: One is "Lettering for Advertising" by Mortimer Leach, and the other one is "How to Render Roman Letter Forms" by Tommy Thompson. Both of these books are excellent, highly recommended for all those who want to learn lettering.

So ... I will search for copies of these books (they aren't easily found online), and reserve most of my design judgments or visual changes for when I am able to see and better understand the source material.

Stephen Nixon

unread,
Oct 29, 2018, 5:09:21 PM10/29/18
to Google Fonts Discussions
If anyone who comes across this does have access to "Lettering for Advertising" by Mortimer Leach or "How to Render Roman Letter Forms" by Tommy Thompson, I'd love to borrow it or see the Caslons inside. Please let me know!

Stephen Nixon

unread,
Nov 9, 2018, 3:39:07 PM11/9/18
to Google Fonts Discussions
As a quick update to my immediate previous question, the New York Public Library has copies of both books in their reading room. 

For now, on Dave's recommendation, I will avoid changing letterforms of Libre Caslon Text, in favor of mastering it to be published, first. When these fonts are continued in the future, these books should be consulted before too many changes are made.

This week has largely consisted of methodically working through QA checks flagged by FontBakery in Libre Caslon Text. Below is the latest work detailed in my GitHub repo's docs: 2018-10-29-fixing-fontbakery-errors. It's somewhat a stream-of-consciousness, as these are the notes I take as I work. As always, I hope that posted them online helps others to come to answers if they're Googling errors or problems.

Fixing FontBakery Errors w/ updated build script & source QA fixes


I'll be logging my progress in getting through Failures & Errors caught by FontBakery on [this GitHub issue])(https://github.com/thundernixon/Libre-Caslon-Text/issues/2).


In this doc, I will go through setting up my build.sh script to handle Libre Caslon Text (which I'll call LC).



I'm using a build.sh set of scripts inherited from @mjlagattuta, then customized and updated for Encode Sans. This includes fixes for several of the problems that are flagged by FontBakery.


This script allows me to add fixes to the font export workflow, which can add up as I learn new fix methods, to gradually make exports better and better.

Here, I'll go through the changes I make to suit this build script to my needs for LC. With each change, I'll run the build script to make sure things are still working as expected.


Remove fix designspace script

This font will be only a 1-dimensional VF for now (with a wght axis), so I don't need to morph the designspace to be rectangular.


Automatically set font name, to avoid errors


It's deleting the ttf folder before it can move the file ... my guess is, the VF file might be getting a name different from what I expect. So, I'll comment-out the rm lines of the build script, to see why the file can't be moved.


My master_ufo folder shows that the name of the font is LibreCaslonText2048, which is left over from earlier experiments with font scaling. I could update my variable in the build script, but that is a hacky solution. Instead, I'll make a helper script using glyphsLib to grab the font name.

Turns out, it's extremely simple. The shell script just needed to set a variable, feeding the source file into a Python helper script.

build.sh:


VFname=`python2 scripts/helpers/get-font-name.py ${glyphsSource}`

get-font-name.py:


import sys
from glyphsLib import GSFont

filename = sys.argv[-1]
font = GSFont(filename)

# get font name, remove spaces
varFontName = font.familyName.replace(' ','') + '-VF'

print(varFontName)

sys.exit(0)


Fun fact: I tested that the variable was being set in the shell script by following that with banner ${VFname}, which prints variables in vertical ASCII art.


Update (maybe remove?) Name Patch


Right now, the font is preview as if it had both wdth and wght axes, but it only has wght. Most likely, this is because the NAMEpatch.xml and STATpatch.xml files are still customized for Encode Sans.



To start, I'll comment-out the sed-based name and STAT patches, then see if this causes problems in FontBakery.

This doesn't solve the two-axis problem, so I'll need to ttx the VF and see more clearly what the name and STAT tables look like.


From this, I can see that the STAT table is showing two axes.


<STAT>
    <Version value="0x00010002"/>
    <DesignAxisRecordSize value="8"/>
    <!-- DesignAxisCount=2 -->
    <DesignAxisRecord>
      <Axis index="0">
        <AxisTag value="wght"/>
        <AxisNameID value="256"/>  <!-- Weight -->
        <AxisOrdering value="0"/>
      </Axis>
      <Axis index="1">
        <AxisTag value="wdth"/>
        <AxisNameID value="257"/>  <!-- Width -->
        <AxisOrdering value="1"/>
      </Axis>
    </DesignAxisRecord>
    <!-- AxisValueCount=0 -->
    <ElidedFallbackNameID value="2"/>  <!-- Regular -->
</STAT>


Similar issues also exist in the name table:


<namerecord nameID="256" platformID="1" platEncID="0" langID="0x0" unicode="True">
    Weight
</namerecord>
<namerecord nameID="257" platformID="1" platEncID="0" langID="0x0" unicode="True">
    Width
</namerecord>


This is probably due to GlyphsApp having both Weight and Width information for each instance, by default:



Because of this, I will try two things:

  1. Adding a "Custom Parameter" of axes for wght to the GlyphsApp Font Into
  2. If the first step doesn't work, I'll also update the NAMEpatch and STATpatch files to remove the unnecessary The first step seems to have worked!

To fix

  •  For starters, I get this error when I build the VF: WARNING:fontTools.varLib:glyph agrave has incompatible masters; skipping

(This was easily fixed by reordering contours in /agrave).

  •  Once I deleted the "patch" files, there was trouble using ttx on the build.sh outputs.

(This was fixed by simplifying the build script, and making sure my path names were all correct).

  •  🔥 FAIL: Checking file is named canonically.

(Made "Regular" instance 400 weight, added " and "SemiBold" weights at 500 and 600 weights). This didn't do the trick.

...after some digging, I eventually found that I was using an old version of FontBakery. I think this is because I used pip2 to update FontBakery earlier in the day, but this seems to have pulled a year-old version of FB into my py2 environment. In any case, this shows that I should probably just be using py3, aside from maybe with glyphsLib, which I think might be py2-only.

Plus, I have lots of FontBakery issues to resolve. I'm keeping a full log of these in Issue #2, but here are the others high-weight issues:

  •  Checking with ots-sanitize. * ERROR: Failed with ModuleNotFoundError: No module named 'ots'

I found that "opentype sanitizer" was just updated to be a Python module and updated in the FB checks.

I had to install it with pip install opentype-sanitizer. (More info here).

  •  FAIL: Checking OS/2 usWinAscent & usWinDescent. – FAIL OS/2.usWinAscent value should be equal or greater than 1708, but got 1707 instead [code: ascent].
  •  FAIL: Checking OS/2 Metrics match hhea Metrics. – FAIL OS/2 sTypoAscender and hhea ascent must be equal. [code: ascender]

These errors seem related, and may be coming from my earlier re-adjustment of the overall scaling of this font. I wanted to check where these numbers are coming from, so I opened the ttx version of the VF.


The <head> table contains <yMax value="1708"/>, the <hhea> table contains <ascent value="1707"/>, and the <OS_2> table contains <usWinAscent value="1707"/>. What is at first also strange is that the Glyphs source actually puts the ascender height of both masters at 1443.

The MS Typography OpenType spec on hhea defines acent as "Distance from baseline of highest ascender." Meanwhile, the head table spec defines ymax as "For all glyph bounding boxes." This leads me to believe that it might include not just ascenders in the typical sense, but also accent marks.

And sure enough! The ring accent has a point at 1707.


I didn't know if there was any other glyph taller than the ring, so I used a script to print a list of glyphs with an ascent of more than 1700:

font = Glyphs.font

for glyph in font.glyphs:
	for layer in glyph.layers:
		ascent = layer.bounds.size.height + layer.bounds.origin.y		
		if ascent >= 1705:
			print(glyph.name, layer.name, ascent)


It showed me that caps with a caron.cap accent all had an ascent of 1708. This was surprising, as the caron.cap itself only had and ascent of 1690. However, I realized by decomposing the Rcaron that the anchor was positioning the caron.cap higher in caps than it was drawn.



It seems probable that the head must be getting derived from the highest point in the font, including in composed glyphs, while the hhea table is derived from the highest-drawn point in the font, not counting composed glyphs. And now to resolve that mismatch...


I'll try moving the caron.cap to it's "natural" position, against the _topcap anchor, so that its height matches the composed height. I'm doing this in both Regular and Bold masters, and making sure to go through all the cap caron diacritics to delete and re-add the caron.cap to ensure that it's at the right height.

Finally, after adjusting those details, I've discovered what is probably the real problem: the GlyphsApp source masters have custom parameters of hheaAscender = 1707 and winAscent = 1707.


When I remove these custom parameters altogether, I get the following FB error:

FAIL OS/2.usWinAscent value should be equal or greater than 1708, but got 1443 instead [code: ascent]

So now, it's confusing the font metric ascender and the highest point in the font. I believe I could pass this error by simply placing 1708 as a custom property, but this seems like a bit of a hack. Where is the 1708 coming from?

The FontBakery check details are pretty informative about this:

A font's winAscent and winDescent values should be greater than the head table's yMax, abs(yMin) values. If they are less than these values, clipping can occur on Windows platforms, https://github.com/RedHatBrand/Overpass/issues/33

Further, a look at Roboto shows that it uses a script to force the yMin and yMax valutes, and a look at Montserrat's GlyphsApp source shows that the winAscent and winDescent values are set as custom parameters. So, while setting these feels a bit manual / hacky, it's not unprecedented. However, to stay flexible and to know that I'm setting these correctly, I'll write a GlyphsApp script.


__doc__="""
	Assumes the masters keep the same vertical metrics. I am not sure whether winAscent and winDescent should be different between masters, otherwise, but you should check if that's the case before using this script on a font where min/max heights are different between styles. 
"""

font = Glyphs.font

# starter values
maxDescent = 0
maxAscent = 0

# find highest and lowest point in font
for glyph in font.glyphs:
	for layer in glyph.layers:
		
		# get descender of current layer
		descent = layer.bounds.origin.y
		
		# get ascender of current layer
		ascent = layer.bounds.size.height + descent	

		# if descent/ascent of current layer is greater than previous max descents/ascents, update the max descent/ascent
		if descent <= maxDescent:
			maxDescent = descent
			
		if ascent >= maxAscent:
			maxAscent = ascent
			

# check values for sanity
print(maxDescent, maxAscent)

# use highest/lowest points to set custom parameters for winAscent and winDescent
for master in font.masters:
	master.customParameters["winDescent"] = maxDescent
	master.customParameters["winAscent"] = maxAscent

			


And this fixes one of the metrics issues!

PASS OS/2 usWinAscent & usWinDescent values look good!

The other issue may require further work in the same direction.


Now, however, the values don't match between OS_2 table's <sTypoDescender value="-440"/> andhhea table's <descent value="-458"/>.

This error is about making vertical metrics match on different platforms. From the FB check:

OS/2 and hhea vertical metric values should match. This will produce the same linespacing on Mac, GNU/Linux and Windows.

This will simply require more vertical metric custom parameter setting.


The MS OpenType spec recommendation on vertical metrics says that:

The sTypoLineGap value will often be set such that the default baseline-to-baseline distance is approximately 120% of the em.

I've added some code to my metrics script so that the line gap can be automatically set to the correct size to achieve a 120% line height.


~~See the script here (and check for newer versions, too!):https://github.com/thundernixon/glyphs_scripts/blob/2da061ae3dd1c568955acfbf2c3b76968ab3a110/setVerticalMetricParams.py ~~


Nevermind – I should have simply been using the Google Fonts fixfonts.py script



I'm still having errors, which led me to finally find the GF-docs documentation on Vertical Metrics.


I've updated the script to the metrics specification there. It was still showing issues from FontVal, which led me to file an issue at https://github.com/googlefonts/fontbakery/issues/2148.


This is inconclusive so far on the FontVal front, but pointed out to me that I had missed the very good advice to set the custom parameter "Use Typo Metrics" to True. This, in turn, pointed out that I should use the gfonts Glyphs script "QA," to solve this and other issues. ...and this in turn pointed out that most (if not all?) of these metrics issues can be fixed with the Google Fonts fixfonts.py script. Nice!


Keeping Python modules up-to-date

It's weirdly hard to keep Python modules predictably up-to-date. Pip install seems to fail half the time, and seems to maybe be stuck on old versions. I've realized that I can pip install directly from the latest code on a GitHub repo, however, with this format:


pip install "git+https://github.com/googlefonts/fontbakery"


This probably isn't the best option for most Python libraries, as it probably has a higher potential of pulling in WIP code than installing released versions. Still, it's a useful technique for now.


Final FontBakery issues

Irrelevant

  •  ⚠️ WARN: Check if each glyph has the recommended amount of contours.
    • Nope, it's a variable font.
  •  ⚠️ WARN: Is font em size (ideally) equal to 1000?
    • Nope, it's 2048. 2048 is fine, as it's so common in TTF fonts.

Completed (more information documented further below)

  •  ⚠️ WARN: Are there caret positions declared for every ligature?
  •  ⚠️ WARN: Checking Vertical Metric Linegaps.
    • This warns "WARN hhea lineGap is not equal to 0. [code: hhea]." In GF-docs, the line gap is specified to be Typo LineGap = 0.25 * UPMHhea LineGap = Typo LineGap. Asking in a FontBakery Issue. Result: not irrelevant. lineGap should be 0, and value should be added to typo and hhea ascenders to keep line spacing correct.
  •  ⚠️ WARN: Checking OS/2 achVendID.
  •  ⚠️ WARN: Checking with Microsoft Font Validator.
    • Have to go through this step-by-step.
  •  ⚠️ WARN: Is there kerning info for non-ligated sequences?
    • I need to look at this
    • Yes, this should be added. It won't take long to make a few of these better.

Waiting on VF hinting

  •  🔥 FAIL: Is 'gasp' table set to optimize rendering?
    • Autohinting is not quite stable for VFs yet. Will need to try WIP version from Marc.
  •  🔥 FAIL: Font enables smart dropout control in "prep" table instructions?
    • Autohinting is not quite stable for VFs yet. Will need to try WIP version from Marc.

⚠️ WARN: Checking Vertical Metric Linegaps.

This warns "WARN hhea lineGap is not equal to 0. [code: hhea]." In GF-docs, the line gap is specified to be Typo LineGap = 0.25 * UPMHhea LineGap = Typo LineGap. Asking in a FontBakery Issue.

Result: LineGap should be 0, and value should be added to typo and hhea ascenders to keep line spacing correct.

I updated my vertical metrics script in my Glyphs Scripts repo to set these, until the gf fix-fonts.py script is updated.


Setting caret position for ligatures

Process described on page 27 of the GlyphsApp handbook. It suggests using Set Anchors, but this adds a bunch of anchors to every ligature, and I don't want to add anchors that aren't necessary. I'll add these myself and arrange them.

I wrote a simple script to help me add caret anchors, then manually repositioned the added anchors to be in-between the letters of each ligature. I also used another simple script, made earlier, to copy anchors from the regular to bold master, then repeated the process.

Pass!


Kerning for non-ligated sequences


Most are fairly fine, as the f overlaps its right boundary. A couple do have kerning, such as the positive kerning for /f/iand /f/j to avoid a crash. Things I will fix:

  • /f/t
  • /k/f
  • /k/l

Overall, k was too-open on the right side. I reduced its right sidebearing, and kerned it a bit more tightly against glyphs /a /f /t.




Before:

 

After (kerned in different lowercase combinations, mostly based on "nn" and "oo" spacing): 


I also reduced sidebearings in diagonals: /y/v/w, as these were all quite loosely-spaced.

This font could probably benefit from a more-methodical overall spacing upgrade, but that goes beyond the scope of this "just get it published" project, as it might also call into question the overall widths of some letters.



Microsoft Font Validator checks

  •  Glyph index 1 Test: ValidateSimpContMisor

Digging into the fontval code, I see that the function for this check contains another variable, isMisoriented. So, it sounds like maybe it's about glyph path direction? Several glyphs marked here (e.g. /A and /E) appear to have counter-clockwise outer paths, which I believe are correct, and match glyphs that aren't in the "ContMisor" list.

To check whether this is actually the problem, I've used GlyphsApp's function Correct Path Direction for All Masters on the /A and /E, and rebuilt. The issue was still present.

I am seeing that the glyphs listed with this error message are all glyphs with multiple contours, which would be single contours in a non-variable font. So, I believe this is just another check that doesn't apply to variable fonts.

Adding information to Microsoft/Font-Validator/issues/65: Skip overlapping contour check for variable fonts, as it seems to be closely related. In response, HinTak advised running FontVal without FontBakery. This is more easily said than done, but I eventually found a double-clickable GUI app from this TypeDrawers thread and this SourceForge download page – confusingly titled "HP JetReady - Color Laserjet 3500/3550" but resulting in an actual FontVal GUI when the "FontValGUI-Seifert-2.1.1.zip" link is clicked.

I ran the "Correct Path Direction" on all glyphs in the Roman source file, then fixed the three glyph contours that were made incompatible by the function.


It didn't clear up many of these errors, but it did clear up quite a few. These were oriented clockwise, when outer paths should be counter-clockwise (according to this GlyphsApp Tutorial – I can't find )


 

  •  *** ℹ️ INFO MS-FonVal: Descender should be greater than or equal to head.yMin DETAILS: Descender = -605, head.yMin = -458**

I'm not sure where the 605 descender value was derived from in the GF Glyphs font-fix.py script, but I've temporarily set to equal the yMin.

It's getting me close. The error is now: MS-FonVal: Descender should be greater than or equal to head.yMin DETAILS: Descender = -462, head.yMin = -458


I'm a bit confused about why the head.yMin is 458 when my vertical metrics script finds a point at -462 ... but after seeing the glyph name for the lowest value, I see that it's /rcommaaccent. The head is likely derived from the lowest y point in the basic /a-/z alphabet.

For now, I'll just set these values manually. This should be fixed in the fix-fonts.py script, so I won't duplicate effort here.

Pass! MS-FonVal: Descender is greater than or equal to head.yMin


Remaining fontVal checks


Done

  • ℹ️ INFO MS-FonVal: No string for Typographic Family name (Name ID 16)

From the MS OpenType Docs:

Typographic Family name: The typographic family grouping doesn’t impose any constraints on the number of faces within it, in contrast with the 4-style family grouping (ID 1), which is present both for historical reasons and to express style linking groups. If name ID 16 is absent, then name ID 1 is considered to be the typographic family name. (In earlier versions of the specification, name ID 16 was known as “Preferred Family”.)

This is what I want it to be (for now):

<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
      Libre Caslon Text
    </namerecord>
  • ℹ️ INFO MS-FonVal: The post name does not match the name in the Adobe Glyph List DETAILS:
    • glyph = 442, char = U+02BC, name = apostrophe # also has proper 'quoteright' glyph
    • glyph = 478, char = U+00B5, name = uni03BC.1 # also has proper 'uni03BC' glyph

To ask about in Pull Request

  • ℹ️ INFO MS-FonVal: Loca references a zero-length entry in the glyf table DETAILS: Number of glyphs that are empty = 5

  • ℹ️ INFO MS-FonVal: maxSizeOfInstructions via method #1 DETAILS: maxSizeOfInstructions=0, computed from the glyf table

  • ℹ️ INFO MS-FonVal: No string for Typographic Subfamily name (Name ID 17)

From the MS OpenType Docs:

If it is absent, then name ID 2 is considered to be the typographic subfamily name.

Name ID 2 is "Regular", and I'm not quite sure that is the right name. Is there anything better?

  • ℹ️ INFO MS-FonVal: The post name isn't in uniXXXX or uXXXXX format and there is no Adobe Glyph List entry DETAILS:

    • glyph = 319, char = U+FB06, name = s_t
    • glyph = 454, char = U+000D, name = CR
    • glyph = 535, char = U+0000, name = NULL
  • ℹ️ INFO MS-FonVal: The post name has an unexpected value DETAILS: glyph = 509, char = U+F6C3, name = uni0326

  • ℹ️ INFO MS-FonVal: Rasterization not selected for validation


Remaining family to-do items

In Roman

  •  match updated spacing and kerning from diagonals to their accented variants – probably a script would work well for this (skipping the i-based letters)

Stephen Nixon

unread,
Nov 26, 2018, 1:25:53 PM11/26/18
to googlefon...@googlegroups.com
It's been a while since my last post to the Google Groups worklogs, but I've been hard at work, documenting my progress on the GitHub repos. 

Instead of copy-pasting everything to here, trying to fix the formatting, and then worrying about sending everyone megabytes of GIF files over email, I'll summarize and link to the docs on GitHub.

Dave Crossland

unread,
Nov 26, 2018, 7:17:39 PM11/26/18
to googlefon...@googlegroups.com
Great stuff!
Reply all
Reply to author
Forward
0 new messages