[cffLib] Add a simple (and quite possibly incomplete) convertCFF2ToCFF()

This commit is contained in:
Behdad Esfahbod 2024-05-15 17:22:24 -07:00
parent c06e8ba1e8
commit 60e30fe008
4 changed files with 61 additions and 47 deletions

View File

@ -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]

View File

@ -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(

View File

@ -208,27 +208,6 @@
256 70 -256 hlineto
</CharString>
</CharStrings>
<VarStore Format="1">
<Format value="1"/>
<VarRegionList>
<!-- RegionAxisCount=1 -->
<!-- RegionCount=1 -->
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
</VarRegionList>
<!-- VarDataCount=1 -->
<VarData index="0">
<!-- ItemCount=0 -->
<NumShorts value="0"/>
<!-- VarRegionCount=1 -->
<VarRegionIndex index="0" value="0"/>
</VarData>
</VarStore>
</CFFFont>
<GlobalSubrs>

View File

@ -234,27 +234,6 @@
-45 25 -14 -3 rlineto
</CharString>
</CharStrings>
<VarStore Format="1">
<Format value="1"/>
<VarRegionList>
<!-- RegionAxisCount=1 -->
<!-- RegionCount=1 -->
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
</VarRegionList>
<!-- VarDataCount=1 -->
<VarData index="0">
<!-- ItemCount=0 -->
<NumShorts value="0"/>
<!-- VarRegionCount=1 -->
<VarRegionIndex index="0" value="0"/>
</VarData>
</VarStore>
</CFFFont>
<GlobalSubrs>