Same classDef issue, but now as result of unparse()
yanone opened this issue · 5 comments
I found another one, but now in another package:
In [1]: import babelfont
In [2]: font = babelfont.load("ofl/carlito/Carlito-Regular.ttf")
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[2], line 1
----> 1 font = babelfont.load("ofl/carlito/Carlito-Regular.ttf")
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/babelfont/__init__.py:17, in load(filename)
16 def load(filename):
---> 17 return Convert(filename).load()
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/babelfont/convertors/__init__.py:70, in Convert.load(self, **kwargs)
68 for c in self.convertors:
69 if c.can_load(self, **kwargs):
---> 70 return c.load(self, **kwargs)
71 raise NotImplementedError
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/babelfont/convertors/__init__.py:26, in BaseConvertor.load(cls, convertor)
24 self.filename = convertor.filename
25 self.scratch = convertor.scratch
---> 26 return self._load()
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/babelfont/convertors/truetype.py:48, in TrueType._load(self)
46 self._load_names()
47 self._load_glyphs()
---> 48 self._load_features()
49 return self.font
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/babelfont/convertors/truetype.py:342, in TrueType._load_features(self)
341 def _load_features(self):
--> 342 self.font.features = unparse(self.tt)
343 # Load anchors
344 for routine in self.font.features.routines:
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/fontFeatures/ttLib/__init__.py:63, in unparse(font, do_gdef, doLookups, config)
58 languageSystems = unparseLanguageSystems(gsub_gpos)
60 if "GSUB" in font:
61 GSUBUnparser(
62 font["GSUB"], ff, languageSystems, font=font, config=config
---> 63 ).unparse(doLookups=doLookups)
65 if "GPOS" in font:
66 GPOSUnparser(
67 font["GPOS"], ff, languageSystems, font=font, config=config
68 ).unparse(doLookups=doLookups)
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/fontFeatures/ttLib/GTableUnparser.py:98, in GTableUnparser.unparse(self, doLookups)
96 if not self.table.ScriptList:
97 return
---> 98 self.unparseLookups()
99 self.collectFeatures()
100 self.fontFeatures.resolveAllRoutines()
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/fontFeatures/ttLib/GTableUnparser.py:191, in GTableUnparser.unparseLookups(self)
188 self.fontFeatures.routines.append(r)
190 for lookupIdx, lookup in enumerate(self.table.LookupList.Lookup):
--> 191 routine, deps = self.unparseLookup(lookup, lookupIdx)
192 debug = self.getDebugInfo(self._table, lookupIdx)
193 if debug:
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/fontFeatures/ttLib/GTableUnparser.py:216, in GTableUnparser.unparseLookup(self, lookup, lookupIdx)
214 self.currentLookup = lookupIdx
215 unparser = getattr(self, "unparse" + self.lookupTypes[lookup.LookupType])
--> 216 return unparser(lookup)
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/fontFeatures/ttLib/GSUBUnparser.py:144, in GSUBUnparser.unparseSingleSubstitution(self, lookup)
140 """Turn a GPOS1 (single substitution) subtable into a fontFeatures Routine."""
141 b = fontFeatures.Routine(
142 name=self.getname("SingleSubstitution" + self.gensym())
143 )
--> 144 self._fix_flags(b, lookup)
145 for sub in lookup.SubTable:
146 for k, v in sub.mapping.items():
File ~/.pyenv/versions/3.11.1/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/fontFeatures/ttLib/GTableUnparser.py:273, in GTableUnparser._fix_flags(self, routine, lookup)
271 if mat:
272 mat = mat >> 8
--> 273 classDefs = self.font["GDEF"].table.MarkAttachClassDef.classDefs
274 glyphs = [g for g in classDefs.keys() if classDefs[g] == mat]
275 routine.markAttachmentSet = glyphs
AttributeError: 'NoneType' object has no attribute 'classDefs'
Wondering whether this should be fixed here or there...
Info: This occurred on 5 fonts out of half of the GF library before I cancelled the test.
If it's failing in fontFeatures, that's a fontFeatures bug... Will fix it there.
I mean to be honest it's a font bug. From the spec, my emphasis:
If MARK_ATTACHMENT_TYPE_MASK is non-zero, then mark attachment classes must be defined in the Mark Attachment Class Definition Table in the GDEF table.
Carlito has a lookup:
<LookupFlag value="256"/><!-- markAttachmentType[1] -->
but no Mark Attachment Class Definition Table in the GDEF table.
That's why I added that it's only for 5 fonts of the first half that I checked. I would be okay if you didn't fix that in fontFeatures, even though you already fixed the same thing here. Close this issue at your own will.