[cffLib] Add a simple (and quite possibly incomplete) convertCFF2ToCFF()
This commit is contained in:
parent
c06e8ba1e8
commit
60e30fe008
@ -458,6 +458,11 @@ class CFFFontSet(object):
|
|||||||
if hasattr(privateDict, key):
|
if hasattr(privateDict, key):
|
||||||
delattr(privateDict, key)
|
delattr(privateDict, key)
|
||||||
# print "Removing privateDict attr", 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
|
# At this point, the Subrs and Charstrings are all still T2Charstring class
|
||||||
# easiest to fix this by compiling, then decompiling again
|
# easiest to fix this by compiling, then decompiling again
|
||||||
file = BytesIO()
|
file = BytesIO()
|
||||||
@ -465,6 +470,42 @@ class CFFFontSet(object):
|
|||||||
file.seek(0)
|
file.seek(0)
|
||||||
self.decompile(file, otFont, isCFF2=True)
|
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):
|
def desubroutinize(self):
|
||||||
for fontName in self.fontNames:
|
for fontName in self.fontNames:
|
||||||
font = self[fontName]
|
font = self[fontName]
|
||||||
|
@ -89,7 +89,7 @@ from fontTools.misc.fixedTools import (
|
|||||||
otRound,
|
otRound,
|
||||||
)
|
)
|
||||||
from fontTools.varLib.models import normalizeValue, piecewiseLinearMap
|
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.TupleVariation import TupleVariation
|
||||||
from fontTools.ttLib.tables import _g_l_y_f
|
from fontTools.ttLib.tables import _g_l_y_f
|
||||||
from fontTools import varLib
|
from fontTools import varLib
|
||||||
@ -574,7 +574,13 @@ def changeTupleVariationAxisLimit(var, axisTag, axisLimit):
|
|||||||
|
|
||||||
|
|
||||||
def instantiateCFF2(
|
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:
|
# The algorithm here is rather simple:
|
||||||
#
|
#
|
||||||
@ -594,7 +600,11 @@ def instantiateCFF2(
|
|||||||
topDict = cff.topDictIndex[0]
|
topDict = cff.topDictIndex[0]
|
||||||
varStore = topDict.VarStore.otVarStore
|
varStore = topDict.VarStore.otVarStore
|
||||||
if not varStore:
|
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
|
return
|
||||||
|
|
||||||
cff.desubroutinize()
|
cff.desubroutinize()
|
||||||
@ -653,7 +663,6 @@ def instantiateCFF2(
|
|||||||
newDefaults = []
|
newDefaults = []
|
||||||
newDeltas = []
|
newDeltas = []
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
|
|
||||||
defaultValue = arg[i]
|
defaultValue = arg[i]
|
||||||
|
|
||||||
major = vsindex
|
major = vsindex
|
||||||
@ -804,12 +813,18 @@ def instantiateCFF2(
|
|||||||
|
|
||||||
# Remove empty VarStore
|
# Remove empty VarStore
|
||||||
if not varStore.VarData:
|
if not varStore.VarData:
|
||||||
|
if "VarStore" in topDict.rawDict:
|
||||||
|
del topDict.rawDict["VarStore"]
|
||||||
del topDict.VarStore
|
del topDict.VarStore
|
||||||
del topDict.CharStrings.varStore
|
del topDict.CharStrings.varStore
|
||||||
for private in privateDicts:
|
for private in privateDicts:
|
||||||
del private.vstore
|
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(
|
def _instantiateGvarGlyph(
|
||||||
|
@ -208,27 +208,6 @@
|
|||||||
256 70 -256 hlineto
|
256 70 -256 hlineto
|
||||||
</CharString>
|
</CharString>
|
||||||
</CharStrings>
|
</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>
|
</CFFFont>
|
||||||
|
|
||||||
<GlobalSubrs>
|
<GlobalSubrs>
|
||||||
|
@ -234,27 +234,6 @@
|
|||||||
-45 25 -14 -3 rlineto
|
-45 25 -14 -3 rlineto
|
||||||
</CharString>
|
</CharString>
|
||||||
</CharStrings>
|
</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>
|
</CFFFont>
|
||||||
|
|
||||||
<GlobalSubrs>
|
<GlobalSubrs>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user