Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fi & ffi glyph widths to match non-ligated sequences; set other ligatures to non-exporting glyphs #431

Closed
arrowtype opened this issue Jan 4, 2021 · 6 comments

Comments

@arrowtype
Copy link
Owner

Problem description

In Sans Linear Light Italic, the fi ligature is a different width than f + i (800 vs 750). For fl, the width is different from f + l across all Sans styles.

It is likely that this discrepancy may exist in other ligatures, like ffl and ffi. It should be fixes.

Expected behavior

Recursive Sans is meant to be superplexed/multiplexed – words should have the exact same width regardless of weight or style. So, a word like "fly" should be exactly the same width whether upright or slanted. Currently, it is just slightly wider when slanted, because the slant axis activates the fl ligature.

Additional Context

There is already a script to check for widths of glyphs being the same across sources (permalink). I will likely start from this in the ligature check.

@arrowtype
Copy link
Owner Author

I’ve discovered/realized another two issues which I might as well fix at the same time:

  1. The fl and ffl ligatures aren’t working in the variable font for Italic styles, as it should (even though fi & ffi are)
  2. I am no longer convinced that this fl ligature is even a good shape for it. It looks bad, and it is less legible than no ligature.

image

Solutions:

  1. I will more closely copy whatever feature code is written for fi/ffi to make sure fl/ffl works similarly.
  2. I will change the shaping of the fl ligature to be more similar to the fi ligature – connecting at the middle, rather than at the top.

@arrowtype arrowtype changed the title Check fonts for other ligature width discrepancies Check ligature widths; fix up fl & ffl ligature shapes & feature code Jan 8, 2021
@arrowtype arrowtype self-assigned this Jan 8, 2021
@arrowtype
Copy link
Owner Author

I made a script (permalink) to quickly check ligature widths vs expected widths. Caveat: this script is somewhat simple, because it doesn’t check for kerning – because Recursive doesn’t have kerning for ff, fi, fl pairs. But, if a font had a similar goal of multiplexing, it might need to check for kerning.

Here are the current issues to fix:

  • Recursive Sans Casual A Slanted

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Casual A

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Casual B Slanted

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Casual B

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Casual C Slanted

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Casual C

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Linear A Slanted

    • fi is 800, should be 750
    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Linear Light

    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Linear B Slanted

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Linear B

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Linear C Slanted

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150
  • Recursive Sans Linear C

    • fl is 800, should be 750
    • f_f_i is 1100, should be 1150
    • f_f_l is 1200, should be 1150

@arrowtype
Copy link
Owner Author

Helpful way to work on this: use “Overlay UFOs” extension to place f and l/i over current glyph, to better match/adjust proportions:

image

@arrowtype
Copy link
Owner Author

arrowtype commented Jan 19, 2021

Okay, so the issue of having a long-running project is that it’s possible to forget certain things. In testing the variable font again, I’ve remembered the the ligature feature is set up so that only the fi and ffi are actually active, and only in Sans Italic styles. So, the fl, ff, and ffl aren’t actually used in practice, because they tend to damage readability more than they improve spacing or aesthetics.

So, I after finishing with basic ligature caret & width fixes, I will set the fl, ff, and ffl as non-exporting glyphs. (Along with the .mono and .italic versions of all ligatures, as these also don’t get used).

@arrowtype arrowtype changed the title Check ligature widths; fix up fl & ffl ligature shapes & feature code Fix fi & ffi glyph widths to match non-ligated sequences; set other ligatures to non-exporting glyphs Jan 19, 2021
@arrowtype
Copy link
Owner Author

arrowtype commented Jan 19, 2021

Build issues that I’ve had to resolve:

  • fl and ffl were in the liga feature, blocking the build (even though they were unused because the l doesn’t sub for l.italic if MONO<0.5). Removed.
  • several ligatures were in the aalt feature, blocking the build. Removed.
  • The f_f_l was blocking ttFont, with the error below. Removed f_f_l, fi, and fl from the designspace rules in the Mono rule, where not needed.
Traceback (Click to expand)

🏗 Constructing variable font
Traceback (most recent call last):
File "build.py", line 69, in
f"Recursive_VF_{version}.ttf"))
File "/Users/stephennixon/type-repos/recursive/mastering/build_variable.py", line 135, in build_variable
useProductionNames=True)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontmake/font_project.py", line 328, in build_variable_font
inplace=True,
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/init.py", line 602, in compileVariableTTF
notdefGlyph=notdefGlyph,
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/init.py", line 422, in compileInterpolatableTTFsFromDS
for source, ttf in zip(result.sources, ttfs):
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/init.py", line 326, in compileInterpolatableTTFs
debugFeatureFile=debugFeatureFile,
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/init.py", line 550, in compileFeatures
otFont = featureCompiler.compile()
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/featureCompiler.py", line 125, in compile
self.setupFeatures()
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/featureCompiler.py", line 220, in setupFeatures
featureFile = parseLayoutFeatures(self.ufo)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/featureCompiler.py", line 48, in parseLayoutFeatures
doc = parser.parse()
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/feaLib/parser.py", line 100, in parse
statements.append(self.parse_feature_block_())
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/feaLib/parser.py", line 1320, in parse_feature_block_
cv_feature)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/feaLib/parser.py", line 1488, in parse_block_
statements.append(self.parse_substitute_())
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/feaLib/parser.py", line 756, in parse_substitute_
self.parse_glyph_pattern_(vertical=False)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/feaLib/parser.py", line 415, in parse_glyph_pattern_
gc = self.parse_glyphclass_(accept_glyphname=True)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/feaLib/parser.py", line 306, in parse_glyphclass_
self.check_glyph_name_in_glyph_set(glyph)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/feaLib/parser.py", line 1605, in check_glyph_name_in_glyph_set
self.cur_token_location_
fontTools.feaLib.error.FeatureLibError: /Users/stephennixon/type-repos/recursive/mastering/build/src/./features/aalt.fea:272:9: The following glyph names are referenced but are missing from the glyph set: f_f
(venv)
type-repos/recursive/mastering fix-ligature-widths ✗ 32m ⚑ ⍉
▶ version=1.071 # (replace version number)
python build.py --varfiles --version $version
python build.py --variable --version $version
🚚 Building files for mastering

🚚 Generating sources
🏗 Copying files
🏗 Opening sources
🏗 Checking family name
🏗 Removing non-exporting glyphs
🏗 Decomposing scaled, flipped, and nested components
🏗 Clearing guides
🏗 Removing glyphs that aren't in every font
🏗 Removing non-compatible glyphs
[]
🏗 Making kerning compatible
🏗 Sorting glyph order to be common
🏗 Setting production names
🏗 Setting version
🏗 Closing and saving sources
🏗 Checking full design space
🏗 Writing report
✅ Done preparing sources
🏗 Moved features into UFOs
🏗 Constructing variable font
Traceback (most recent call last):
File "build.py", line 69, in
f"Recursive_VF_{version}.ttf"))
File "/Users/stephennixon/type-repos/recursive/mastering/build_variable.py", line 135, in build_variable
useProductionNames=True)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontmake/font_project.py", line 328, in build_variable_font
inplace=True,
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/init.py", line 611, in compileVariableTTF
postProcessor = PostProcessor(varfont, baseUfo)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/ufo2ft/postProcessor.py", line 46, in init
otf.save(stream)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/ttFont.py", line 172, in save
writer_reordersTables = self._save(tmp)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/ttFont.py", line 211, in _save
self._writeTable(tag, writer, done, tableCache)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/ttFont.py", line 632, in _writeTable
tabledata = self.getTableData(tag)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/ttFont.py", line 650, in getTableData
return self.tables[tag].compile(self)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otBase.py", line 69, in compile
self.table.compile(writer, font)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otBase.py", line 717, in compile
conv.write(writer, font, table, value)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otConverters.py", line 563, in write
value.compile(subWriter, font)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otBase.py", line 680, in compile
conv.write(writer, font, table, value, i)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otConverters.py", line 563, in write
value.compile(subWriter, font)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otBase.py", line 680, in compile
conv.write(writer, font, table, value, i)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otConverters.py", line 563, in write
value.compile(subWriter, font)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otBase.py", line 640, in compile
table = self.preWrite(font)
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otTables.py", line 745, in preWrite
gidItems = [(getGlyphID(a), getGlyphID(b)) for a,b in items]
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otTables.py", line 745, in
gidItems = [(getGlyphID(a), getGlyphID(b)) for a,b in items]
File "/Users/stephennixon/type-repos/recursive/venv/lib/python3.7/site-packages/fontTools/ttLib/ttFont.py", line 601, in getGlyphID
glyphID = d[glyphName]
KeyError: ('f_f_l', 'SingleSubst[0]', 'Lookup[232]', 'LookupList')

@arrowtype
Copy link
Owner Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant