googlefonts / glyphsLib

A bridge from Glyphs source files (.glyphs) to UFOs
Apache License 2.0
181 stars 51 forks source link

MissingComponentError in master when running `glyphs2ufo` #743

Open ctrlcctrlv opened 2 years ago

ctrlcctrlv commented 2 years ago

I was very curious what @clauseggers's new Playfair font looked like (the non Display version), and upon seeing he uploaded a few .glyphs files three days ago, endeavored to compile them. However, glyphsLib crashed:

...
Glyph 'Ushort-cy': All components of the background layer of 'Needlepoint SemiExpanded' will be decomposed.
Glyph 'Ushort-cy': All components of the background layer of 'Agate Black SemiExpanded' will be decomposed.
Glyph 'Ha-cy': All components of the background layer of 'Needlepoint SemiExpanded' will be decomposed.
Glyph 'Ha-cy': All components of the background layer of 'Agate Black SemiExpanded' will be decomposed.
Glyph 'Yeru-cy': All components of the background layer of 'Needlepoint SemiExpanded' will be decomposed.
Glyph 'Yeru-cy': All components of the background layer of 'Agate Black SemiExpanded' will be decomposed.
Glyph 'Nje-cy': All components of the background layer of 'Needlepoint Black SemiExpanded' will be decomposed.
Traceback (most recent call last):
  File "/home/fred/.local/lib/python3.9/site-packages/fontTools/pens/basePen.py", line 191, in addComponent
    glyph = self.glyphSet[glyphName]
KeyError: '__soft-cy.cap'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/components.py", line 132, in to_ufo_components_nonmaster_decompose
    component.draw(rpen)
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/classes.py", line 2590, in draw
    pen.addComponent(self.name, self.transform)
  File "/home/fred/.local/lib/python3.9/site-packages/fontTools/pens/basePen.py", line 194, in addComponent
    raise MissingComponentError(glyphName)
fontTools.pens.basePen.MissingComponentError: '__soft-cy.cap'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/fred/.local/bin/glyphs2ufo", line 8, in <module>
    sys.exit(_glyphs2ufo_entry_point())
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/cli.py", line 235, in _glyphs2ufo_entry_point
    return main(args)
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/cli.py", line 195, in main
    return options.func(options)
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/cli.py", line 214, in glyphs2ufo
    glyphsLib.build_masters(
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/__init__.py", line 117, in build_masters
    designspace = to_designspace(
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/__init__.py", line 119, in to_designspace
    return builder.designspace
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/builders.py", line 349, in designspace
    list(self.masters)  # Make sure that the UFOs are built
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/builders.py", line 212, in masters
    self.to_ufo_layers()
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/builders.py", line 276, in to_ufo_layers
    self.to_ufo_glyph(ufo_glyph, layer, glyph)
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/glyph.py", line 217, in to_ufo_glyph
    self.to_ufo_glyph_background(ufo_glyph, layer)
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/glyph.py", line 399, in to_ufo_glyph_background
    self.to_ufo_components(new_glyph, background)
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/components.py", line 45, in to_ufo_components
    to_ufo_components_nonmaster_decompose(self, ufo_glyph, layer)
  File "/home/fred/.local/lib/python3.9/site-packages/glyphsLib/builder/components.py", line 135, in to_ufo_components_nonmaster_decompose
    raise MissingComponentError(
fontTools.pens.basePen.MissingComponentError: "Glyph 'Nje-cy', background layer: component '__soft-cy.cap' points to a non-existent glyph."

I have no Macbook and no Glyphsapp, so this was my only way to see the font. I commented out the raise in components.py:135 and got a font from Playfair-2-Roman.glyphs:

image

I suggest demoting this from a hard error to a warning.

khaledhosny commented 2 years ago

Try with --minimal to skip background layers. Glyphs allow for components to non-existing glyphs and is a bit tolerant about it. glyphsLib is more strict (although one can make a case for skipping such components by default or under an option).

simoncozens commented 6 months ago

I know this is archaeologically old, but: today I went looking for why background layers are decomposed, and there's a good reason for it (since a component reference in a Glyphs background layer points to the a glyph in the default layer but component reference in a UFO background layer points to another glyph in the background layer, converting Glyphs->UFO would require creating additional background layers to be generated for referred glyphs, so we just decompose everything to make it easier.)

However when that was introduced in #610, it came with a LayerDecomposingPen which did just warn when non-existent glyphs were referred to as components; but this was quickly changed to use a standard pen, which errors when the referred glyph doesn't exist.

anthrotype commented 6 months ago

if we still want to just warn and drop missing components in backgrounds, we can easily make our own subclass:

class LayerDecomposingPen(DecomposingRecordingPen):
    skipMissingComponents = False
anthrotype commented 6 months ago

FYI, in a yet unreleased fonttools, all the decomposing pens come with an optional skipMissingComponents parameter to control this at the instance level (as opposed to subclassing and setting a class attribute like in the above example). There will also be a DecomposingRecordingPointPen (point pen equivalent to the DecomposingRecordingPen used here) https://github.com/fonttools/fonttools/pull/3460