From 3801c17e6e48f0526137469bff6ba0f6236fac19 Mon Sep 17 00:00:00 2001
From: Connor_Davenport <info@connordavenport.com>
Date: Tue, 4 May 2021 21:02:33 -0400
Subject: [PATCH 1/2] added VF extracting support

---
 Lib/extractor/formats/opentype.py | 49 ++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 4 deletions(-)

diff --git a/Lib/extractor/formats/opentype.py b/Lib/extractor/formats/opentype.py
index 9a30bc3..24fc735 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 = varFont["fvar"]
+        del varFont
+    except TTLibError:
+        return False
+    return True
+
+def locationToName(locDict):
+    name = ""
+    for tag,val in locDict.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,20 @@ 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]
+            # sourceFonts = [instantiateVariableFont(source,loc,True,True) for loc in locations]
+            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 +92,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 +559,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()

From f7a6d81525ef04f515f82b085c33f7d8f5289348 Mon Sep 17 00:00:00 2001
From: Connor_Davenport <info@connordavenport.com>
Date: Wed, 5 May 2021 08:53:05 -0400
Subject: [PATCH 2/2] fixed varFont object naming

---
 Lib/extractor/formats/opentype.py | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Lib/extractor/formats/opentype.py b/Lib/extractor/formats/opentype.py
index 24fc735..ea4166d 100644
--- a/Lib/extractor/formats/opentype.py
+++ b/Lib/extractor/formats/opentype.py
@@ -37,15 +37,15 @@ def isOpenType(pathOrFile):
 def isVarFont(pathOrFile):
     try:
         font = TTFont(pathOrFile)
-        fvar = varFont["fvar"]
-        del varFont
+        fvar = font["fvar"]
+        del font
     except TTLibError:
         return False
     return True
 
-def locationToName(locDict):
+def locationToName(locations):
     name = ""
-    for tag,val in locDict.items():
+    for tag,val in locations.items():
         name += f"{tag}_{val};"
     return name
 
@@ -74,7 +74,6 @@ def extractFontFromOpenType(
             '''
             defLoc = getDefaultLocation(source)
             locations = [instance.coordinates for instance in source["fvar"].instances]
-            # sourceFonts = [instantiateVariableFont(source,loc,True,True) for loc in locations]
             for varLoc in locations:
                 if varLoc != defLoc:
                     instanceFont = instantiateVariableFont(source,varLoc)