diff --git a/Lib/fontTools/cffLib/__init__.py b/Lib/fontTools/cffLib/__init__.py
index 06b4e8d19..2750c16d9 100644
--- a/Lib/fontTools/cffLib/__init__.py
+++ b/Lib/fontTools/cffLib/__init__.py
@@ -458,6 +458,11 @@ class CFFFontSet(object):
if hasattr(privateDict, key):
delattr(privateDict, key)
# print "Removing privateDict attr", key
+
+ # TODO(behdad): What does the following comment even mean? Both CFF and CFF2
+ # use the same T2Charstring class.
+ # What I see missing is dropping the endchar and return operators...
+
# At this point, the Subrs and Charstrings are all still T2Charstring class
# easiest to fix this by compiling, then decompiling again
file = BytesIO()
@@ -465,6 +470,42 @@ class CFFFontSet(object):
file.seek(0)
self.decompile(file, otFont, isCFF2=True)
+ def convertCFF2ToCFF(self, otFont):
+ """Converts this object from CFF2 format to CFF format. This conversion
+ is done 'in-place'. The conversion cannot be reversed.
+
+ The CFF2 font cannot be variable. This method will remove the VarStore,
+ but will not process the CharStrings in any way (TODO instantiate to default).
+
+ This assumes a decompiled CFF table. (i.e. that the object has been
+ filled via :meth:`decompile`.)"""
+ self.major = 1
+ topDictData = TopDictIndex(None)
+ topDictData.items = self.topDictIndex.items
+ self.topDictIndex = topDictData
+ topDict = topDictData[0]
+ if hasattr(topDict, "Private"):
+ privateDict = topDict.Private
+ else:
+ privateDict = None
+ opOrder = buildOrder(topDictOperators)
+ topDict.order = opOrder
+
+ fdArray = topDict.FDArray
+ charStrings = topDict.CharStrings
+
+ for cs in charStrings.values():
+ cs.program.append("endchar")
+
+ # TODO Add "return" to subrs that don't end in endchar?
+
+ # At this point, the Subrs and Charstrings are all still T2Charstring class
+ # easiest to fix this by compiling, then decompiling again
+ # file = BytesIO()
+ # self.compile(file, otFont, isCFF2=False)
+ # file.seek(0)
+ # self.decompile(file, otFont, isCFF2=False)
+
def desubroutinize(self):
for fontName in self.fontNames:
font = self[fontName]
diff --git a/Lib/fontTools/varLib/instancer/__init__.py b/Lib/fontTools/varLib/instancer/__init__.py
index 0952121c1..8d4d001dc 100644
--- a/Lib/fontTools/varLib/instancer/__init__.py
+++ b/Lib/fontTools/varLib/instancer/__init__.py
@@ -89,7 +89,7 @@ from fontTools.misc.fixedTools import (
otRound,
)
from fontTools.varLib.models import normalizeValue, piecewiseLinearMap
-from fontTools.ttLib import TTFont
+from fontTools.ttLib import TTFont, getTableClass
from fontTools.ttLib.tables.TupleVariation import TupleVariation
from fontTools.ttLib.tables import _g_l_y_f
from fontTools import varLib
@@ -574,7 +574,13 @@ def changeTupleVariationAxisLimit(var, axisTag, axisLimit):
def instantiateCFF2(
- varfont, axisLimits, *, round=round, specialize=True, generalize=False
+ varfont,
+ axisLimits,
+ *,
+ round=round,
+ specialize=True,
+ generalize=False,
+ downgrade=False,
):
# The algorithm here is rather simple:
#
@@ -594,7 +600,11 @@ def instantiateCFF2(
topDict = cff.topDictIndex[0]
varStore = topDict.VarStore.otVarStore
if not varStore:
- # TODO Downgrade to CFF if requested.
+ if downgrade:
+ table = varfont["CFF "] = getTableClass("CFF ")()
+ table.cff = cff
+ cff.convertCFF2ToCFF(varfont)
+ del varfont["CFF2"]
return
cff.desubroutinize()
@@ -653,7 +663,6 @@ def instantiateCFF2(
newDefaults = []
newDeltas = []
for i in range(count):
-
defaultValue = arg[i]
major = vsindex
@@ -804,12 +813,18 @@ def instantiateCFF2(
# Remove empty VarStore
if not varStore.VarData:
+ if "VarStore" in topDict.rawDict:
+ del topDict.rawDict["VarStore"]
del topDict.VarStore
del topDict.CharStrings.varStore
for private in privateDicts:
del private.vstore
- # TODO Downgrade to CFF if requested.
+ if downgrade:
+ table = varfont["CFF "] = getTableClass("CFF ")()
+ table.cff = cff
+ cff.convertCFF2ToCFF(varfont)
+ del varfont["CFF2"]
def _instantiateGvarGlyph(
diff --git a/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-1-instance-400.ttx b/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-1-instance-400.ttx
index fde30c8d5..44237b80c 100644
--- a/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-1-instance-400.ttx
+++ b/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-1-instance-400.ttx
@@ -208,27 +208,6 @@
256 70 -256 hlineto
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-3-instance-400.ttx b/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-3-instance-400.ttx
index bcc83baee..138cb1cce 100644
--- a/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-3-instance-400.ttx
+++ b/Tests/varLib/instancer/data/test_results/CFF2Instancer-VF-3-instance-400.ttx
@@ -234,27 +234,6 @@
-45 25 -14 -3 rlineto
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-