def fromValidatedFontWorkerSource(cls, fws, **kwArgs): """ Creates and returns a new GDEF from the specified FontWorker Source code with extensive validation via the logging module (the client should have done a logging.basicConfig call prior to calling this method, unless a logger is passed in via the 'logger' keyword argument). >>> _test_FW_fws.goto(1) # go back to first line >>> logger = utilities.makeDoctestLogger('test_FW') >>> fvfws = GDEF.fromValidatedFontWorkerSource >>> gdef = fvfws(_test_FW_fws, namer=_test_FW_namer, ... logger=logger, editor=None) >>> gdef.pprint() Version: Major version: 1 Minor version: 3 Glyph Classes: Base glyph: 5 Ligature glyph: 7 Mark glyph: 11 Attachment Points: 5: [23] 7: [29, 31] 11: [37, 41, 43] Ligature Caret Points: 5: CaretValue #1: Simple caret value in FUnits: 42 7: CaretValue #1: Simple caret value in FUnits: 50 CaretValue #2: Simple caret value in FUnits: 55 11: CaretValue #1: Simple caret value in FUnits: 12 CaretValue #2: Simple caret value in FUnits: 17 CaretValue #3: Simple caret value in FUnits: 37 Mark Classes: Mark class 8: 5 Mark class 10: 7 Mark class 12: 11 Mark Sets: Mark Glyph Set 0: 5, 7 Mark Glyph Set 1: 5 Mark Glyph Set 2: 11 >>> gdef2 = fvfws(_test_FW_fws2, namer=_test_FW_namer, ... logger=logger, editor=None) test_FW.GDEF.classDef - WARNING - line 8 -- glyph 'w' not found test_FW.GDEF.attachlist - WARNING - line 13 -- missing attachment points test_FW.GDEF.attachlist - WARNING - line 16 -- glyph 'x' not found test_FW.GDEF.ligcaret - ERROR - line 21 -- mismatch between caret count (2);and number of carets actually listed (3); discarding. test_FW.GDEF.ligcaret - ERROR - line 23 -- mismatch between caret count (3);and number of carets actually listed (2); discarding. test_FW.GDEF.ligcaret - WARNING - line 24 -- glyph 'y' not found test_FW.GDEF.classDef - WARNING - line 31 -- incorrect number of tokens, expected 2, found 1 test_FW.GDEF.classDef - WARNING - line 32 -- glyph 'z' not found test_FW.GDEF.markset - WARNING - line 40 -- glyph 'asdfjkl' not found test_FW.GDEF.markset - WARNING - MarkFilterSet 1 will be renumbered to 0 test_FW.GDEF.markset - WARNING - MarkFilterSet 99 will be renumbered to 1 >>> gdef2.pprint() Version: Major version: 1 Minor version: 3 Glyph Classes: Base glyph: 5 Ligature glyph: 7 Mark glyph: 11 Attachment Points: 5: [23] 11: [37, 41, 43] Ligature Caret Points: 5: CaretValue #1: Simple caret value in FUnits: 42 Mark Classes: Mark class 1: 5 Mark class 2: 7 Mark Sets: Mark Glyph Set 0: 5, 11 Mark Glyph Set 1: 5, 7 """ editor = kwArgs['editor'] namer = kwArgs['namer'] logger = kwArgs.pop('logger', None) if logger is None: logger = logging.getLogger().getChild('GDEF') else: logger = logger.getChild('GDEF') # create empty versions of these tables for now, # replace them with full versions later if the data is available glyphClasses = glyphclass.GlyphClassTable() attachments = attachlist.AttachListTable() ligCarets = ligcaret.LigCaretTable() markClasses = markclass.MarkClassTable() markSets = markset.MarkSetTable() firstLine = 'FontDame GDEF table' line = next(fws) if line != firstLine: logger.error(( 'V0958', (firstLine,), "Expected '%s' in first line.")) return None for line in fws: if len(line) != 0: if line.lower() == 'class definition begin': glyphClasses = \ glyphclass.GlyphClassTable.fromValidatedFontWorkerSource( fws, namer=namer, logger=logger) elif line.lower() == 'attachment list begin': attachments = \ attachlist.AttachListTable.fromValidatedFontWorkerSource( fws, namer=namer, logger=logger) elif line.lower() == 'carets begin': ligCarets = \ ligcaret.LigCaretTable.fromValidatedFontWorkerSource( fws, namer=namer, logger=logger, editor=editor) elif line.lower() == 'mark attachment class definition begin': markClasses = \ markclass.MarkClassTable.fromValidatedFontWorkerSource( fws, namer=namer, logger=logger) elif line.lower() == 'markfilter set definition begin': markSets = \ markset.MarkSetTable.fromValidatedFontWorkerSource( fws, namer=namer, logger=logger) else: logger.warning(( 'V0960', (fws.lineNumber, line), 'line %d -- unexpected token: \'%s\'')) return cls( attachments=attachments, glyphClasses=glyphClasses, ligCarets=ligCarets, markClasses=markClasses, markSets=markSets)
def frommtxxtables(cls, editor, **kwArgs): """ Returns a GDEF object initialized via the MTxx (and other) tables in the specified editor. """ if editor is None: return cls() hm = editor.get(b'hmtx') if not hm: return cls() sf = editor.get(b'MTsf', {}) # when there's a MTxx table for marksets, add that here glyphClasses = glyphclass.GlyphClassTable() attachments = attachlist.AttachListTable() ligCarets = ligcaret.LigCaretTable() markClasses = markclass.MarkClassTable() markSets = markset.MarkSetTable() excluded = frozenset([0xFFFF, 0xFFFE]) for glyphIndex, mtapRecord in editor.get(b'MTap', {}).items(): # glyph class glyphClass = mtapRecord.glyphClass if glyphClass: glyphClasses[glyphIndex] = glyphClass # attachments anchor = mtapRecord.anchorData t1 = ( () if anchor is None else tuple(anchor.pointGenerator(excludeFFFx=True))) conn = mtapRecord.connectionData if conn is None: t2 = () else: it = conn.pointGenerator() t2 = tuple( c.pointIndex for c in it if c.pointIndex not in excluded) if t1 or t2: attachments[glyphIndex] = attachlist.AttachPointTable(t1 + t2) # lig carets if glyphClass == 2: # ligature caretValues = mtapRecord.caretValuesFromMetrics( hm[glyphIndex][0]) if caretValues: ligCarets[glyphIndex] = ligcaret.LigGlyphTable(caretValues) # marks elif glyphClass == 3 and sf: # mark markClass = sf[glyphIndex].originalClassIndex markClasses[glyphIndex] = ( 0 if markClass == 0xFFFF else markClass + 1) return cls( attachments=attachments, glyphClasses=glyphClasses, ligCarets=ligCarets, markClasses=markClasses, markSets=markSets)