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

CFF2 workflow issues w/ intermediate master #1475

Open
frankrolf opened this issue Feb 25, 2022 · 1 comment
Open

CFF2 workflow issues w/ intermediate master #1475

frankrolf opened this issue Feb 25, 2022 · 1 comment

Comments

@frankrolf
Copy link
Member

frankrolf commented Feb 25, 2022

The attached project illustrates a problem with the current CFF2 building workflow.

background

At this moment, CFF2 building requires two steps:

  • buildmasterotfs, to build dummy OTF files from UFO masters
  • buildcff2vf, to merge those OTFs into a variable CFF2 OTF

setup

The prepared project uses an intermediate master for a single letter e.
The glyphs available in the extreme masters are a e o and .notdef.

the issue at hand

  • The fact that complete OTFs are built as an intermediate step requires these files to be relatively spec-compliant. Since a .notdef does not exist in the intermediate master, makeotf generates a generic glyph.
  • buildcff2vf fails since the three masters no longer are compatible (with custom .notdefs in the extremes, and a generic .notdef in the intermediate)
$ buildmasterotfs -d dummy.designspace

tx: --- interpolation dummy/pole_0.ufo
makeotfexe processing font <Dummy-0>
Built release mode font 'interpolation dummy/pole_0.otf' Revision 1.000
tx: --- interpolation dummy/pole_0.otf

tx: --- interpolation dummy/intermediate.ufo
   NOTE: Adding glyph .notdef, SID 0.
makeotfexe processing font <Dummy-Intermediate>
Built release mode font 'interpolation dummy/intermediate.otf' Revision 1.000
tx: --- interpolation dummy/intermediate.otf

tx: --- interpolation dummy/pole_1.ufo
makeotfexe processing font <Dummy-1>
Built release mode font 'interpolation dummy/pole_1.otf' Revision 1.000
tx: --- interpolation dummy/pole_1.otf

$ buildcff2vf -d dummy.designspace

Reading source fonts...
Building variable OTF (CFF2) font...
Traceback (most recent call last):
  File "~/.pyenv/versions/3.9.9/bin/buildcff2vf", line 8, in <module>
    sys.exit(main())
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/afdko/buildcff2vf.py", line 571, in main
    varFont, _, _ = varLib.build(designspace, otfFinder)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/varLib/__init__.py", line 938, in build
    _add_CFF2(vf, model, master_fonts)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/varLib/__init__.py", line 708, in _add_CFF2
    merge_region_fonts(varFont, model, ordered_fonts_list, glyphOrder)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/varLib/cff.py", line 333, in merge_region_fonts
    cvData = merge_charstrings(glyphOrder, num_masters, top_dicts, model)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/varLib/cff.py", line 389, in merge_charstrings
    region_charstring.draw(var_pen)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/misc/psCharStrings.py", line 982, in draw
    extractor.execute(self)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/misc/psCharStrings.py", line 300, in execute
    rv = handler(index)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/varLib/cff.py", line 465, in op_hstem
    self._hint_op('hstem', args)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/varLib/cff.py", line 461, in _hint_op
    self.pen.add_hint(type, args)
  File "~/.pyenv/versions/3.9.9/lib/python3.9/site-packages/fontTools/varLib/cff.py", line 538, in add_hint
    raise VarLibCFFHintTypeMergeError(hint_type, self.pt_index, len(cmd[1]),
fontTools.varLib.errors.VarLibCFFHintTypeMergeError: Glyph '.notdef': 'hstem' at index 0 in master index 1 differs from the default font hint type 'rmoveto'

workaround

  • add .notdef to intermediate master

suggestion

In my opinion, the current workflow is a little confusing since it relies on .otf files, which are mostly seen as end products.
However, the OTF files generated are not fit for use because they do contain overlapping paths. I suggest the following:

  • use a different file format for the files resulting from buildmasterotfs. Even if just the extension is different, it would make clear that those files are not for use beyond the build workflow.
  • clean up intermediate binaries (OTFs or new extension) upon successful CFF2 build
  • (main suggestion) build a file that contains only the tables necessary for merging the CFF2 file. This might mean a CFF table without .notdef (and therefore avoid the above issue).

An update to this workflow might help with creating fewer error messages as mentioned in #1312.

intermediate without .notdef.zip

@skef
Copy link
Collaborator

skef commented Mar 25, 2022

use a different file format for the files resulting from buildmasterotfs. Even if just the extension is different, it would make clear that those files are not for use beyond the build workflow.

Related to this, for the tools to support FDArray/FDSelect we'll either have to abuse the CID operators for the intermediate single-instance OTFs or just build single-instance CFF2 otfs to start with. Unless our tools can't manage it now the idea of using CFF2 all the way through is looking better to me. (For one thing it gets the choice of data to include in the file right from the start, and if features get added to CFF2 it won't be necessary to play games to support them during the merging process.) The "different file format"/extension could also indicate the use of CFF2.

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

No branches or pull requests

2 participants