diff --git a/Lib/extractor/formats/opentype.py b/Lib/extractor/formats/opentype.py index 9a30bc3..ea4166d 100644 --- a/Lib/extractor/formats/opentype.py +++ b/Lib/extractor/formats/opentype.py @@ -1,3 +1,4 @@ + import time from fontTools.pens.boundsPen import ControlBoundsPen from fontTools.pens.hashPointPen import HashPointPen @@ -8,6 +9,7 @@ USE_MY_METRICS, ) from fontTools.ttLib.tables._h_e_a_d import mac_epoch_diff +from fontTools.varLib.mutator import instantiateVariableFont from extractor.exceptions import ExtractorError from extractor.stream import InstructionStream from extractor.tools import RelaxedInfo, copyAttr @@ -32,6 +34,23 @@ def isOpenType(pathOrFile): return False return True +def isVarFont(pathOrFile): + try: + font = TTFont(pathOrFile) + fvar = font["fvar"] + del font + except TTLibError: + return False + return True + +def locationToName(locations): + name = "" + for tag,val in locations.items(): + name += f"{tag}_{val};" + return name + +def getDefaultLocation(varFont): + return {axis.axisTag:axis.defaultValue for axis in varFont["fvar"].axes} def extractFontFromOpenType( pathOrFile, @@ -48,6 +67,19 @@ def extractFontFromOpenType( extractOpenTypeInfo(source, destination) if doGlyphs: extractOpenTypeGlyphs(source, destination) + if isVarFont: + ''' + Add Support for extracting Variable Instances as RLayer objects + Currently this is pulling the VFs instances but I think using the Sources is a better solution? + ''' + defLoc = getDefaultLocation(source) + locations = [instance.coordinates for instance in source["fvar"].instances] + for varLoc in locations: + if varLoc != defLoc: + instanceFont = instantiateVariableFont(source,varLoc) + layerName = locationToName(varLoc) + extractOpenTypeGlyphs(instanceFont, destination, layerName) + extractUnicodeVariationSequences(source, destination) if doGlyphOrder: extractGlyphOrder(source, destination) @@ -59,7 +91,11 @@ def extractFontFromOpenType( for function in customFunctions: function(source, destination) if doInstructions: - extractInstructions(source, destination) + if not isVarFont: + ''' + seems to run into issue with extracting VF component indentifier + ''' + extractInstructions(source, destination) source.close() @@ -522,19 +558,23 @@ def binaryToIntList(value, start=0): # -------- -def extractOpenTypeGlyphs(source, destination): +def extractOpenTypeGlyphs(source, destination, layerName="public.default"): # grab the cmap vmtx = source.get("vmtx") vorg = source.get("VORG") is_ttf = "glyf" in source reversedMapping = source.get("cmap").buildReversed() + # add layers + if layerName != destination.defaultLayerName: + destination.newLayer(layerName) # grab the glyphs glyphSet = source.getGlyphSet() for glyphName in glyphSet.keys(): sourceGlyph = glyphSet[glyphName] # make the new glyph - destination.newGlyph(glyphName) - destinationGlyph = destination[glyphName] + destinationLayer = destination.getLayer(layerName) + destinationLayer.newGlyph(glyphName) + destinationGlyph = destinationLayer[glyphName] # outlines if is_ttf: pen = destinationGlyph.getPointPen()