black
This commit is contained in:
parent
6389385813
commit
6ba1302ce4
@ -16,6 +16,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
from .otBase import BaseTTXConverter
|
||||
|
||||
|
||||
class table__a_v_a_r(BaseTTXConverter):
|
||||
"""Axis Variations Table
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,10 @@ from collections import defaultdict, namedtuple
|
||||
from fontTools.misc.roundTools import otRound
|
||||
from fontTools.misc.textTools import bytesjoin, pad, safeEval
|
||||
from .otBase import (
|
||||
BaseTable, FormatSwitchingBaseTable, ValueRecord, CountReference,
|
||||
BaseTable,
|
||||
FormatSwitchingBaseTable,
|
||||
ValueRecord,
|
||||
CountReference,
|
||||
getFormatSwitchingBaseTableClass,
|
||||
)
|
||||
from fontTools.feaLib.lookupDebugInfo import LookupDebugInfo, LOOKUP_DEBUG_INFO_KEY
|
||||
@ -48,9 +51,7 @@ class AATAction(object):
|
||||
xmlWriter.simpletag("Flags", value=",".join(flags))
|
||||
xmlWriter.newline()
|
||||
if self.ReservedFlags != 0:
|
||||
xmlWriter.simpletag(
|
||||
"ReservedFlags",
|
||||
value='0x%04X' % self.ReservedFlags)
|
||||
xmlWriter.simpletag("ReservedFlags", value="0x%04X" % self.ReservedFlags)
|
||||
xmlWriter.newline()
|
||||
|
||||
def _setFlag(self, flag):
|
||||
@ -95,9 +96,12 @@ class RearrangementMorphAction(AATAction):
|
||||
writer.writeUShort(self.NewState)
|
||||
assert self.Verb >= 0 and self.Verb <= 15, self.Verb
|
||||
flags = self.Verb | self.ReservedFlags
|
||||
if self.MarkFirst: flags |= 0x8000
|
||||
if self.DontAdvance: flags |= 0x4000
|
||||
if self.MarkLast: flags |= 0x2000
|
||||
if self.MarkFirst:
|
||||
flags |= 0x8000
|
||||
if self.DontAdvance:
|
||||
flags |= 0x4000
|
||||
if self.MarkLast:
|
||||
flags |= 0x2000
|
||||
writer.writeUShort(flags)
|
||||
|
||||
def decompile(self, reader, font, actionReader):
|
||||
@ -155,8 +159,10 @@ class ContextualMorphAction(AATAction):
|
||||
assert actionIndex is None
|
||||
writer.writeUShort(self.NewState)
|
||||
flags = self.ReservedFlags
|
||||
if self.SetMark: flags |= 0x8000
|
||||
if self.DontAdvance: flags |= 0x4000
|
||||
if self.SetMark:
|
||||
flags |= 0x8000
|
||||
if self.DontAdvance:
|
||||
flags |= 0x4000
|
||||
writer.writeUShort(flags)
|
||||
writer.writeUShort(self.MarkIndex)
|
||||
writer.writeUShort(self.CurrentIndex)
|
||||
@ -179,8 +185,7 @@ class ContextualMorphAction(AATAction):
|
||||
self._writeFlagsToXML(xmlWriter)
|
||||
xmlWriter.simpletag("MarkIndex", value=self.MarkIndex)
|
||||
xmlWriter.newline()
|
||||
xmlWriter.simpletag("CurrentIndex",
|
||||
value=self.CurrentIndex)
|
||||
xmlWriter.simpletag("CurrentIndex", value=self.CurrentIndex)
|
||||
xmlWriter.newline()
|
||||
xmlWriter.endtag(name)
|
||||
xmlWriter.newline()
|
||||
@ -237,9 +242,12 @@ class LigatureMorphAction(AATAction):
|
||||
assert actionIndex is not None
|
||||
writer.writeUShort(self.NewState)
|
||||
flags = self.ReservedFlags
|
||||
if self.SetComponent: flags |= 0x8000
|
||||
if self.DontAdvance: flags |= 0x4000
|
||||
if len(self.Actions) > 0: flags |= 0x2000
|
||||
if self.SetComponent:
|
||||
flags |= 0x8000
|
||||
if self.DontAdvance:
|
||||
flags |= 0x4000
|
||||
if len(self.Actions) > 0:
|
||||
flags |= 0x2000
|
||||
writer.writeUShort(flags)
|
||||
if len(self.Actions) > 0:
|
||||
actions = self.compileLigActions()
|
||||
@ -262,8 +270,7 @@ class LigatureMorphAction(AATAction):
|
||||
self.ReservedFlags = flags & 0x1FFF
|
||||
actionIndex = reader.readUShort()
|
||||
if performAction:
|
||||
self.Actions = self._decompileLigActions(
|
||||
actionReader, actionIndex)
|
||||
self.Actions = self._decompileLigActions(actionReader, actionIndex)
|
||||
else:
|
||||
self.Actions = []
|
||||
|
||||
@ -289,8 +296,7 @@ class LigatureMorphAction(AATAction):
|
||||
for i in range(0, len(a), 4):
|
||||
suffix = a[i:]
|
||||
suffixIndex = (len(result) + i) // 4
|
||||
actionIndex.setdefault(
|
||||
suffix, suffixIndex)
|
||||
actionIndex.setdefault(suffix, suffixIndex)
|
||||
result += a
|
||||
result = pad(result, 4)
|
||||
return (result, actionIndex)
|
||||
@ -298,7 +304,7 @@ class LigatureMorphAction(AATAction):
|
||||
def compileLigActions(self):
|
||||
result = []
|
||||
for i, action in enumerate(self.Actions):
|
||||
last = (i == len(self.Actions) - 1)
|
||||
last = i == len(self.Actions) - 1
|
||||
value = action.GlyphIndexDelta & 0x3FFFFFFF
|
||||
value |= 0x80000000 if last else 0
|
||||
value |= 0x40000000 if action.Store else 0
|
||||
@ -308,8 +314,7 @@ class LigatureMorphAction(AATAction):
|
||||
def _decompileLigActions(self, actionReader, actionIndex):
|
||||
actions = []
|
||||
last = False
|
||||
reader = actionReader.getSubReader(
|
||||
actionReader.pos + actionIndex * 4)
|
||||
reader = actionReader.getSubReader(actionReader.pos + actionIndex * 4)
|
||||
while not last:
|
||||
value = reader.readULong()
|
||||
last = bool(value & 0x80000000)
|
||||
@ -341,8 +346,7 @@ class LigatureMorphAction(AATAction):
|
||||
flags = eltAttrs.get("Flags", "").split(",")
|
||||
flags = [f.strip() for f in flags]
|
||||
action.Store = "Store" in flags
|
||||
action.GlyphIndexDelta = safeEval(
|
||||
eltAttrs["GlyphIndexDelta"])
|
||||
action.GlyphIndexDelta = safeEval(eltAttrs["GlyphIndexDelta"])
|
||||
self.Actions.append(action)
|
||||
|
||||
def toXML(self, xmlWriter, font, attrs, name):
|
||||
@ -364,9 +368,14 @@ class LigatureMorphAction(AATAction):
|
||||
class InsertionMorphAction(AATAction):
|
||||
staticSize = 8
|
||||
actionHeaderSize = 4 # 4 bytes for actionOffset
|
||||
_FLAGS = ["SetMark", "DontAdvance",
|
||||
"CurrentIsKashidaLike", "MarkedIsKashidaLike",
|
||||
"CurrentInsertBefore", "MarkedInsertBefore"]
|
||||
_FLAGS = [
|
||||
"SetMark",
|
||||
"DontAdvance",
|
||||
"CurrentIsKashidaLike",
|
||||
"MarkedIsKashidaLike",
|
||||
"CurrentInsertBefore",
|
||||
"MarkedInsertBefore",
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self.NewState = 0
|
||||
@ -379,24 +388,28 @@ class InsertionMorphAction(AATAction):
|
||||
assert actionIndex is not None
|
||||
writer.writeUShort(self.NewState)
|
||||
flags = self.ReservedFlags
|
||||
if self.SetMark: flags |= 0x8000
|
||||
if self.DontAdvance: flags |= 0x4000
|
||||
if self.CurrentIsKashidaLike: flags |= 0x2000
|
||||
if self.MarkedIsKashidaLike: flags |= 0x1000
|
||||
if self.CurrentInsertBefore: flags |= 0x0800
|
||||
if self.MarkedInsertBefore: flags |= 0x0400
|
||||
if self.SetMark:
|
||||
flags |= 0x8000
|
||||
if self.DontAdvance:
|
||||
flags |= 0x4000
|
||||
if self.CurrentIsKashidaLike:
|
||||
flags |= 0x2000
|
||||
if self.MarkedIsKashidaLike:
|
||||
flags |= 0x1000
|
||||
if self.CurrentInsertBefore:
|
||||
flags |= 0x0800
|
||||
if self.MarkedInsertBefore:
|
||||
flags |= 0x0400
|
||||
flags |= len(self.CurrentInsertionAction) << 5
|
||||
flags |= len(self.MarkedInsertionAction)
|
||||
writer.writeUShort(flags)
|
||||
if len(self.CurrentInsertionAction) > 0:
|
||||
currentIndex = actionIndex[
|
||||
tuple(self.CurrentInsertionAction)]
|
||||
currentIndex = actionIndex[tuple(self.CurrentInsertionAction)]
|
||||
else:
|
||||
currentIndex = 0xFFFF
|
||||
writer.writeUShort(currentIndex)
|
||||
if len(self.MarkedInsertionAction) > 0:
|
||||
markedIndex = actionIndex[
|
||||
tuple(self.MarkedInsertionAction)]
|
||||
markedIndex = actionIndex[tuple(self.MarkedInsertionAction)]
|
||||
else:
|
||||
markedIndex = 0xFFFF
|
||||
writer.writeUShort(markedIndex)
|
||||
@ -412,19 +425,16 @@ class InsertionMorphAction(AATAction):
|
||||
self.CurrentInsertBefore = bool(flags & 0x0800)
|
||||
self.MarkedInsertBefore = bool(flags & 0x0400)
|
||||
self.CurrentInsertionAction = self._decompileInsertionAction(
|
||||
actionReader, font,
|
||||
index=reader.readUShort(),
|
||||
count=((flags & 0x03E0) >> 5))
|
||||
actionReader, font, index=reader.readUShort(), count=((flags & 0x03E0) >> 5)
|
||||
)
|
||||
self.MarkedInsertionAction = self._decompileInsertionAction(
|
||||
actionReader, font,
|
||||
index=reader.readUShort(),
|
||||
count=(flags & 0x001F))
|
||||
actionReader, font, index=reader.readUShort(), count=(flags & 0x001F)
|
||||
)
|
||||
|
||||
def _decompileInsertionAction(self, actionReader, font, index, count):
|
||||
if index == 0xFFFF or count == 0:
|
||||
return []
|
||||
reader = actionReader.getSubReader(
|
||||
actionReader.pos + index * 2)
|
||||
reader = actionReader.getSubReader(actionReader.pos + index * 2)
|
||||
return font.getGlyphNameMany(reader.readUShortArray(count))
|
||||
|
||||
def toXML(self, xmlWriter, font, attrs, name):
|
||||
@ -452,11 +462,9 @@ class InsertionMorphAction(AATAction):
|
||||
for flag in eltAttrs["value"].split(","):
|
||||
self._setFlag(flag.strip())
|
||||
elif eltName == "CurrentInsertionAction":
|
||||
self.CurrentInsertionAction.append(
|
||||
eltAttrs["glyph"])
|
||||
self.CurrentInsertionAction.append(eltAttrs["glyph"])
|
||||
elif eltName == "MarkedInsertionAction":
|
||||
self.MarkedInsertionAction.append(
|
||||
eltAttrs["glyph"])
|
||||
self.MarkedInsertionAction.append(eltAttrs["glyph"])
|
||||
else:
|
||||
assert False, eltName
|
||||
|
||||
@ -493,29 +501,37 @@ class InsertionMorphAction(AATAction):
|
||||
|
||||
|
||||
class FeatureParams(BaseTable):
|
||||
|
||||
def compile(self, writer, font):
|
||||
assert featureParamTypes.get(writer['FeatureTag']) == self.__class__, "Wrong FeatureParams type for feature '%s': %s" % (writer['FeatureTag'], self.__class__.__name__)
|
||||
assert (
|
||||
featureParamTypes.get(writer["FeatureTag"]) == self.__class__
|
||||
), "Wrong FeatureParams type for feature '%s': %s" % (
|
||||
writer["FeatureTag"],
|
||||
self.__class__.__name__,
|
||||
)
|
||||
BaseTable.compile(self, writer, font)
|
||||
|
||||
def toXML(self, xmlWriter, font, attrs=None, name=None):
|
||||
BaseTable.toXML(self, xmlWriter, font, attrs, name=self.__class__.__name__)
|
||||
|
||||
|
||||
class FeatureParamsSize(FeatureParams):
|
||||
pass
|
||||
|
||||
|
||||
class FeatureParamsStylisticSet(FeatureParams):
|
||||
pass
|
||||
|
||||
|
||||
class FeatureParamsCharacterVariants(FeatureParams):
|
||||
pass
|
||||
|
||||
|
||||
class Coverage(FormatSwitchingBaseTable):
|
||||
|
||||
# manual implementation to get rid of glyphID dependencies
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'glyphs'):
|
||||
if not hasattr(self, "glyphs"):
|
||||
self.glyphs = []
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
@ -606,14 +622,13 @@ NO_VARIATION_INDEX = 0xFFFFFFFF
|
||||
|
||||
|
||||
class DeltaSetIndexMap(getFormatSwitchingBaseTableClass("uint8")):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'mapping'):
|
||||
if not hasattr(self, "mapping"):
|
||||
self.mapping = []
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
assert (rawTable['EntryFormat'] & 0xFFC0) == 0
|
||||
self.mapping = rawTable['mapping']
|
||||
assert (rawTable["EntryFormat"] & 0xFFC0) == 0
|
||||
self.mapping = rawTable["mapping"]
|
||||
|
||||
@staticmethod
|
||||
def getEntryFormat(mapping):
|
||||
@ -647,24 +662,24 @@ class DeltaSetIndexMap(getFormatSwitchingBaseTableClass("uint8")):
|
||||
mapping = self.mapping = []
|
||||
self.Format = 1 if len(mapping) > 0xFFFF else 0
|
||||
rawTable = self.__dict__.copy()
|
||||
rawTable['MappingCount'] = len(mapping)
|
||||
rawTable['EntryFormat'] = self.getEntryFormat(mapping)
|
||||
rawTable["MappingCount"] = len(mapping)
|
||||
rawTable["EntryFormat"] = self.getEntryFormat(mapping)
|
||||
return rawTable
|
||||
|
||||
def toXML2(self, xmlWriter, font):
|
||||
# Make xml dump less verbose, by omitting no-op entries like:
|
||||
# <Map index="..." outer="65535" inner="65535"/>
|
||||
xmlWriter.comment(
|
||||
"Omitted values default to 0xFFFF/0xFFFF (no variations)"
|
||||
)
|
||||
xmlWriter.comment("Omitted values default to 0xFFFF/0xFFFF (no variations)")
|
||||
xmlWriter.newline()
|
||||
for i, value in enumerate(getattr(self, "mapping", [])):
|
||||
attrs = [('index', i)]
|
||||
attrs = [("index", i)]
|
||||
if value != NO_VARIATION_INDEX:
|
||||
attrs.extend([
|
||||
('outer', value >> 16),
|
||||
('inner', value & 0xFFFF),
|
||||
])
|
||||
attrs.extend(
|
||||
[
|
||||
("outer", value >> 16),
|
||||
("inner", value & 0xFFFF),
|
||||
]
|
||||
)
|
||||
xmlWriter.simpletag("Map", attrs)
|
||||
xmlWriter.newline()
|
||||
|
||||
@ -672,23 +687,22 @@ class DeltaSetIndexMap(getFormatSwitchingBaseTableClass("uint8")):
|
||||
mapping = getattr(self, "mapping", None)
|
||||
if mapping is None:
|
||||
self.mapping = mapping = []
|
||||
index = safeEval(attrs['index'])
|
||||
outer = safeEval(attrs.get('outer', '0xFFFF'))
|
||||
inner = safeEval(attrs.get('inner', '0xFFFF'))
|
||||
index = safeEval(attrs["index"])
|
||||
outer = safeEval(attrs.get("outer", "0xFFFF"))
|
||||
inner = safeEval(attrs.get("inner", "0xFFFF"))
|
||||
assert inner <= 0xFFFF
|
||||
mapping.insert(index, (outer << 16) | inner)
|
||||
|
||||
|
||||
class VarIdxMap(BaseTable):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'mapping'):
|
||||
if not hasattr(self, "mapping"):
|
||||
self.mapping = {}
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
assert (rawTable['EntryFormat'] & 0xFFC0) == 0
|
||||
assert (rawTable["EntryFormat"] & 0xFFC0) == 0
|
||||
glyphOrder = font.getGlyphOrder()
|
||||
mapList = rawTable['mapping']
|
||||
mapList = rawTable["mapping"]
|
||||
mapList.extend([mapList[-1]] * (len(glyphOrder) - len(mapList)))
|
||||
self.mapping = dict(zip(glyphOrder, mapList))
|
||||
|
||||
@ -703,17 +717,17 @@ class VarIdxMap(BaseTable):
|
||||
while len(mapping) > 1 and mapping[-2] == mapping[-1]:
|
||||
del mapping[-1]
|
||||
|
||||
rawTable = {'mapping': mapping}
|
||||
rawTable['MappingCount'] = len(mapping)
|
||||
rawTable['EntryFormat'] = DeltaSetIndexMap.getEntryFormat(mapping)
|
||||
rawTable = {"mapping": mapping}
|
||||
rawTable["MappingCount"] = len(mapping)
|
||||
rawTable["EntryFormat"] = DeltaSetIndexMap.getEntryFormat(mapping)
|
||||
return rawTable
|
||||
|
||||
def toXML2(self, xmlWriter, font):
|
||||
for glyph, value in sorted(getattr(self, "mapping", {}).items()):
|
||||
attrs = (
|
||||
('glyph', glyph),
|
||||
('outer', value >> 16),
|
||||
('inner', value & 0xFFFF),
|
||||
("glyph", glyph),
|
||||
("outer", value >> 16),
|
||||
("inner", value & 0xFFFF),
|
||||
)
|
||||
xmlWriter.simpletag("Map", attrs)
|
||||
xmlWriter.newline()
|
||||
@ -724,17 +738,16 @@ class VarIdxMap(BaseTable):
|
||||
mapping = {}
|
||||
self.mapping = mapping
|
||||
try:
|
||||
glyph = attrs['glyph']
|
||||
glyph = attrs["glyph"]
|
||||
except: # https://github.com/fonttools/fonttools/commit/21cbab8ce9ded3356fef3745122da64dcaf314e9#commitcomment-27649836
|
||||
glyph = font.getGlyphOrder()[attrs['index']]
|
||||
outer = safeEval(attrs['outer'])
|
||||
inner = safeEval(attrs['inner'])
|
||||
glyph = font.getGlyphOrder()[attrs["index"]]
|
||||
outer = safeEval(attrs["outer"])
|
||||
inner = safeEval(attrs["inner"])
|
||||
assert inner <= 0xFFFF
|
||||
mapping[glyph] = (outer << 16) | inner
|
||||
|
||||
|
||||
class VarRegionList(BaseTable):
|
||||
|
||||
def preWrite(self, font):
|
||||
# The OT spec says VarStore.VarRegionList.RegionAxisCount should always
|
||||
# be equal to the fvar.axisCount, and OTS < v8.0.0 enforces this rule
|
||||
@ -748,14 +761,13 @@ class VarRegionList(BaseTable):
|
||||
self.RegionAxisCount = len(fvarTable.axes)
|
||||
return {
|
||||
**self.__dict__,
|
||||
"RegionAxisCount": CountReference(self.__dict__, "RegionAxisCount")
|
||||
"RegionAxisCount": CountReference(self.__dict__, "RegionAxisCount"),
|
||||
}
|
||||
|
||||
|
||||
class SingleSubst(FormatSwitchingBaseTable):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'mapping'):
|
||||
if not hasattr(self, "mapping"):
|
||||
self.mapping = {}
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
@ -769,8 +781,9 @@ class SingleSubst(FormatSwitchingBaseTable):
|
||||
for inp, out in zip(input, outNames):
|
||||
mapping[inp] = out
|
||||
elif self.Format == 2:
|
||||
assert len(input) == rawTable["GlyphCount"], \
|
||||
"invalid SingleSubstFormat2 table"
|
||||
assert (
|
||||
len(input) == rawTable["GlyphCount"]
|
||||
), "invalid SingleSubstFormat2 table"
|
||||
subst = rawTable["Substitute"]
|
||||
for inp, sub in zip(input, subst):
|
||||
mapping[inp] = sub
|
||||
@ -821,8 +834,7 @@ class SingleSubst(FormatSwitchingBaseTable):
|
||||
def toXML2(self, xmlWriter, font):
|
||||
items = sorted(self.mapping.items())
|
||||
for inGlyph, outGlyph in items:
|
||||
xmlWriter.simpletag("Substitution",
|
||||
[("in", inGlyph), ("out", outGlyph)])
|
||||
xmlWriter.simpletag("Substitution", [("in", inGlyph), ("out", outGlyph)])
|
||||
xmlWriter.newline()
|
||||
|
||||
def fromXML(self, name, attrs, content, font):
|
||||
@ -834,9 +846,8 @@ class SingleSubst(FormatSwitchingBaseTable):
|
||||
|
||||
|
||||
class MultipleSubst(FormatSwitchingBaseTable):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'mapping'):
|
||||
if not hasattr(self, "mapping"):
|
||||
self.mapping = {}
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
@ -859,8 +870,7 @@ class MultipleSubst(FormatSwitchingBaseTable):
|
||||
self.Format = 1
|
||||
rawTable = {
|
||||
"Coverage": cov,
|
||||
"Sequence": [self.makeSequence_(mapping[glyph])
|
||||
for glyph in cov.glyphs],
|
||||
"Sequence": [self.makeSequence_(mapping[glyph]) for glyph in cov.glyphs],
|
||||
}
|
||||
return rawTable
|
||||
|
||||
@ -868,8 +878,7 @@ class MultipleSubst(FormatSwitchingBaseTable):
|
||||
items = sorted(self.mapping.items())
|
||||
for inGlyph, outGlyphs in items:
|
||||
out = ",".join(outGlyphs)
|
||||
xmlWriter.simpletag("Substitution",
|
||||
[("in", inGlyph), ("out", out)])
|
||||
xmlWriter.simpletag("Substitution", [("in", inGlyph), ("out", out)])
|
||||
xmlWriter.newline()
|
||||
|
||||
def fromXML(self, name, attrs, content, font):
|
||||
@ -912,9 +921,8 @@ class MultipleSubst(FormatSwitchingBaseTable):
|
||||
|
||||
|
||||
class ClassDef(FormatSwitchingBaseTable):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'classDefs'):
|
||||
if not hasattr(self, "classDefs"):
|
||||
self.classDefs = {}
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
@ -1019,9 +1027,8 @@ class ClassDef(FormatSwitchingBaseTable):
|
||||
|
||||
|
||||
class AlternateSubst(FormatSwitchingBaseTable):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'alternates'):
|
||||
if not hasattr(self, "alternates"):
|
||||
self.alternates = {}
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
@ -1090,9 +1097,8 @@ class AlternateSubst(FormatSwitchingBaseTable):
|
||||
|
||||
|
||||
class LigatureSubst(FormatSwitchingBaseTable):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, 'ligatures'):
|
||||
if not hasattr(self, "ligatures"):
|
||||
self.ligatures = {}
|
||||
|
||||
def postRead(self, rawTable, font):
|
||||
@ -1120,7 +1126,9 @@ class LigatureSubst(FormatSwitchingBaseTable):
|
||||
|
||||
# ligatures is map from components-sequence to lig-glyph
|
||||
newLigatures = dict()
|
||||
for comps,lig in sorted(ligatures.items(), key=lambda item: (-len(item[0]), item[0])):
|
||||
for comps, lig in sorted(
|
||||
ligatures.items(), key=lambda item: (-len(item[0]), item[0])
|
||||
):
|
||||
ligature = Ligature()
|
||||
ligature.Component = comps[1:]
|
||||
ligature.CompCount = len(comps)
|
||||
@ -1156,8 +1164,9 @@ class LigatureSubst(FormatSwitchingBaseTable):
|
||||
xmlWriter.begintag("LigatureSet", glyph=glyphName)
|
||||
xmlWriter.newline()
|
||||
for lig in ligSets:
|
||||
xmlWriter.simpletag("Ligature", glyph=lig.LigGlyph,
|
||||
components=",".join(lig.Component))
|
||||
xmlWriter.simpletag(
|
||||
"Ligature", glyph=lig.LigGlyph, components=",".join(lig.Component)
|
||||
)
|
||||
xmlWriter.newline()
|
||||
xmlWriter.endtag("LigatureSet")
|
||||
xmlWriter.newline()
|
||||
@ -1183,7 +1192,6 @@ class LigatureSubst(FormatSwitchingBaseTable):
|
||||
|
||||
|
||||
class COLR(BaseTable):
|
||||
|
||||
def decompile(self, reader, font):
|
||||
# COLRv0 is exceptional in that LayerRecordCount appears *after* the
|
||||
# LayerRecordArray it counts, but the parser logic expects Count fields
|
||||
@ -1208,7 +1216,7 @@ class COLR(BaseTable):
|
||||
self.LayerRecordCount = None
|
||||
return {
|
||||
**self.__dict__,
|
||||
"LayerRecordCount": CountReference(self.__dict__, "LayerRecordCount")
|
||||
"LayerRecordCount": CountReference(self.__dict__, "LayerRecordCount"),
|
||||
}
|
||||
|
||||
|
||||
@ -1224,7 +1232,11 @@ class LookupList(BaseTable):
|
||||
raise ValueError
|
||||
|
||||
def toXML2(self, xmlWriter, font):
|
||||
if not font or "Debg" not in font or LOOKUP_DEBUG_INFO_KEY not in font["Debg"].data:
|
||||
if (
|
||||
not font
|
||||
or "Debg" not in font
|
||||
or LOOKUP_DEBUG_INFO_KEY not in font["Debg"].data
|
||||
):
|
||||
return super().toXML2(xmlWriter, font)
|
||||
debugData = font["Debg"].data[LOOKUP_DEBUG_INFO_KEY][self.table]
|
||||
for conv in self.getConverters():
|
||||
@ -1235,37 +1247,37 @@ class LookupList(BaseTable):
|
||||
info = LookupDebugInfo(*debugData[str(lookupIndex)])
|
||||
tag = info.location
|
||||
if info.name:
|
||||
tag = f'{info.name}: {tag}'
|
||||
tag = f"{info.name}: {tag}"
|
||||
if info.feature:
|
||||
script, language, feature = info.feature
|
||||
tag = f'{tag} in {feature} ({script}/{language})'
|
||||
tag = f"{tag} in {feature} ({script}/{language})"
|
||||
xmlWriter.comment(tag)
|
||||
xmlWriter.newline()
|
||||
|
||||
conv.xmlWrite(xmlWriter, font, item, conv.name,
|
||||
[("index", lookupIndex)])
|
||||
conv.xmlWrite(
|
||||
xmlWriter, font, item, conv.name, [("index", lookupIndex)]
|
||||
)
|
||||
else:
|
||||
if conv.aux and not eval(conv.aux, None, vars(self)):
|
||||
continue
|
||||
value = getattr(self, conv.name, None) # TODO Handle defaults instead of defaulting to None!
|
||||
value = getattr(
|
||||
self, conv.name, None
|
||||
) # TODO Handle defaults instead of defaulting to None!
|
||||
conv.xmlWrite(xmlWriter, font, value, conv.name, [])
|
||||
|
||||
class BaseGlyphRecordArray(BaseTable):
|
||||
|
||||
class BaseGlyphRecordArray(BaseTable):
|
||||
def preWrite(self, font):
|
||||
self.BaseGlyphRecord = sorted(
|
||||
self.BaseGlyphRecord,
|
||||
key=lambda rec: font.getGlyphID(rec.BaseGlyph)
|
||||
self.BaseGlyphRecord, key=lambda rec: font.getGlyphID(rec.BaseGlyph)
|
||||
)
|
||||
return self.__dict__.copy()
|
||||
|
||||
|
||||
class BaseGlyphList(BaseTable):
|
||||
|
||||
def preWrite(self, font):
|
||||
self.BaseGlyphPaintRecord = sorted(
|
||||
self.BaseGlyphPaintRecord,
|
||||
key=lambda rec: font.getGlyphID(rec.BaseGlyph)
|
||||
self.BaseGlyphPaintRecord, key=lambda rec: font.getGlyphID(rec.BaseGlyph)
|
||||
)
|
||||
return self.__dict__.copy()
|
||||
|
||||
@ -1292,7 +1304,6 @@ class ClipBox(getFormatSwitchingBaseTableClass("uint8")):
|
||||
|
||||
|
||||
class ClipList(getFormatSwitchingBaseTableClass("uint8")):
|
||||
|
||||
def populateDefaults(self, propagator=None):
|
||||
if not hasattr(self, "clips"):
|
||||
self.clips = {}
|
||||
@ -1333,8 +1344,7 @@ class ClipList(getFormatSwitchingBaseTableClass("uint8")):
|
||||
)
|
||||
if missingGlyphs:
|
||||
log.warning(
|
||||
"ClipRecord[%i] range references missing "
|
||||
"glyph IDs: [%i-%i]",
|
||||
"ClipRecord[%i] range references missing " "glyph IDs: [%i-%i]",
|
||||
i,
|
||||
min(missingGlyphs),
|
||||
max(missingGlyphs),
|
||||
@ -1350,8 +1360,7 @@ class ClipList(getFormatSwitchingBaseTableClass("uint8")):
|
||||
if key not in uniqueClips:
|
||||
uniqueClips[key] = clipBox
|
||||
return {
|
||||
frozenset(glyphs): uniqueClips[key]
|
||||
for key, glyphs in glyphsByClip.items()
|
||||
frozenset(glyphs): uniqueClips[key] for key, glyphs in glyphsByClip.items()
|
||||
}
|
||||
|
||||
def preWrite(self, font):
|
||||
@ -1361,8 +1370,7 @@ class ClipList(getFormatSwitchingBaseTableClass("uint8")):
|
||||
glyphMap = font.getReverseGlyphMap()
|
||||
for glyphs, clipBox in self.groups().items():
|
||||
glyphIDs = sorted(
|
||||
glyphMap[glyphName] for glyphName in glyphs
|
||||
if glyphName in glyphMap
|
||||
glyphMap[glyphName] for glyphName in glyphs if glyphName in glyphMap
|
||||
)
|
||||
if not glyphIDs:
|
||||
continue
|
||||
@ -1486,7 +1494,7 @@ class CompositeMode(IntEnum):
|
||||
class PaintFormat(IntEnum):
|
||||
PaintColrLayers = 1
|
||||
PaintSolid = 2
|
||||
PaintVarSolid = 3,
|
||||
PaintVarSolid = (3,)
|
||||
PaintLinearGradient = 4
|
||||
PaintVarLinearGradient = 5
|
||||
PaintRadialGradient = 6
|
||||
@ -1556,9 +1564,7 @@ class Paint(getFormatSwitchingBaseTableClass("uint8")):
|
||||
layers = []
|
||||
if colr.LayerList is not None:
|
||||
layers = colr.LayerList.Paint
|
||||
return layers[
|
||||
self.FirstLayerIndex : self.FirstLayerIndex + self.NumLayers
|
||||
]
|
||||
return layers[self.FirstLayerIndex : self.FirstLayerIndex + self.NumLayers]
|
||||
|
||||
if self.Format == PaintFormat.PaintColrGlyph:
|
||||
for record in colr.BaseGlyphList.BaseGlyphPaintRecord:
|
||||
@ -1596,30 +1602,82 @@ class Paint(getFormatSwitchingBaseTableClass("uint8")):
|
||||
# subclass for each alternate field name.
|
||||
#
|
||||
_equivalents = {
|
||||
'MarkArray': ("Mark1Array",),
|
||||
'LangSys': ('DefaultLangSys',),
|
||||
'Coverage': ('MarkCoverage', 'BaseCoverage', 'LigatureCoverage', 'Mark1Coverage',
|
||||
'Mark2Coverage', 'BacktrackCoverage', 'InputCoverage',
|
||||
'LookAheadCoverage', 'VertGlyphCoverage', 'HorizGlyphCoverage',
|
||||
'TopAccentCoverage', 'ExtendedShapeCoverage', 'MathKernCoverage'),
|
||||
'ClassDef': ('ClassDef1', 'ClassDef2', 'BacktrackClassDef', 'InputClassDef',
|
||||
'LookAheadClassDef', 'GlyphClassDef', 'MarkAttachClassDef'),
|
||||
'Anchor': ('EntryAnchor', 'ExitAnchor', 'BaseAnchor', 'LigatureAnchor',
|
||||
'Mark2Anchor', 'MarkAnchor'),
|
||||
'Device': ('XPlaDevice', 'YPlaDevice', 'XAdvDevice', 'YAdvDevice',
|
||||
'XDeviceTable', 'YDeviceTable', 'DeviceTable'),
|
||||
'Axis': ('HorizAxis', 'VertAxis',),
|
||||
'MinMax': ('DefaultMinMax',),
|
||||
'BaseCoord': ('MinCoord', 'MaxCoord',),
|
||||
'JstfLangSys': ('DefJstfLangSys',),
|
||||
'JstfGSUBModList': ('ShrinkageEnableGSUB', 'ShrinkageDisableGSUB', 'ExtensionEnableGSUB',
|
||||
'ExtensionDisableGSUB',),
|
||||
'JstfGPOSModList': ('ShrinkageEnableGPOS', 'ShrinkageDisableGPOS', 'ExtensionEnableGPOS',
|
||||
'ExtensionDisableGPOS',),
|
||||
'JstfMax': ('ShrinkageJstfMax', 'ExtensionJstfMax',),
|
||||
'MathKern': ('TopRightMathKern', 'TopLeftMathKern', 'BottomRightMathKern',
|
||||
'BottomLeftMathKern'),
|
||||
'MathGlyphConstruction': ('VertGlyphConstruction', 'HorizGlyphConstruction'),
|
||||
"MarkArray": ("Mark1Array",),
|
||||
"LangSys": ("DefaultLangSys",),
|
||||
"Coverage": (
|
||||
"MarkCoverage",
|
||||
"BaseCoverage",
|
||||
"LigatureCoverage",
|
||||
"Mark1Coverage",
|
||||
"Mark2Coverage",
|
||||
"BacktrackCoverage",
|
||||
"InputCoverage",
|
||||
"LookAheadCoverage",
|
||||
"VertGlyphCoverage",
|
||||
"HorizGlyphCoverage",
|
||||
"TopAccentCoverage",
|
||||
"ExtendedShapeCoverage",
|
||||
"MathKernCoverage",
|
||||
),
|
||||
"ClassDef": (
|
||||
"ClassDef1",
|
||||
"ClassDef2",
|
||||
"BacktrackClassDef",
|
||||
"InputClassDef",
|
||||
"LookAheadClassDef",
|
||||
"GlyphClassDef",
|
||||
"MarkAttachClassDef",
|
||||
),
|
||||
"Anchor": (
|
||||
"EntryAnchor",
|
||||
"ExitAnchor",
|
||||
"BaseAnchor",
|
||||
"LigatureAnchor",
|
||||
"Mark2Anchor",
|
||||
"MarkAnchor",
|
||||
),
|
||||
"Device": (
|
||||
"XPlaDevice",
|
||||
"YPlaDevice",
|
||||
"XAdvDevice",
|
||||
"YAdvDevice",
|
||||
"XDeviceTable",
|
||||
"YDeviceTable",
|
||||
"DeviceTable",
|
||||
),
|
||||
"Axis": (
|
||||
"HorizAxis",
|
||||
"VertAxis",
|
||||
),
|
||||
"MinMax": ("DefaultMinMax",),
|
||||
"BaseCoord": (
|
||||
"MinCoord",
|
||||
"MaxCoord",
|
||||
),
|
||||
"JstfLangSys": ("DefJstfLangSys",),
|
||||
"JstfGSUBModList": (
|
||||
"ShrinkageEnableGSUB",
|
||||
"ShrinkageDisableGSUB",
|
||||
"ExtensionEnableGSUB",
|
||||
"ExtensionDisableGSUB",
|
||||
),
|
||||
"JstfGPOSModList": (
|
||||
"ShrinkageEnableGPOS",
|
||||
"ShrinkageDisableGPOS",
|
||||
"ExtensionEnableGPOS",
|
||||
"ExtensionDisableGPOS",
|
||||
),
|
||||
"JstfMax": (
|
||||
"ShrinkageJstfMax",
|
||||
"ExtensionJstfMax",
|
||||
),
|
||||
"MathKern": (
|
||||
"TopRightMathKern",
|
||||
"TopLeftMathKern",
|
||||
"BottomRightMathKern",
|
||||
"BottomLeftMathKern",
|
||||
),
|
||||
"MathGlyphConstruction": ("VertGlyphConstruction", "HorizGlyphConstruction"),
|
||||
}
|
||||
|
||||
#
|
||||
@ -1627,6 +1685,7 @@ _equivalents = {
|
||||
# XXX This should probably move to otBase.py
|
||||
#
|
||||
|
||||
|
||||
def fixLookupOverFlows(ttf, overflowRecord):
|
||||
"""Either the offset from the LookupList to a lookup overflowed, or
|
||||
an offset from a lookup to a subtable overflowed.
|
||||
@ -1653,13 +1712,13 @@ def fixLookupOverFlows(ttf, overflowRecord):
|
||||
"""
|
||||
ok = 0
|
||||
lookupIndex = overflowRecord.LookupListIndex
|
||||
if (overflowRecord.SubTableIndex is None):
|
||||
if overflowRecord.SubTableIndex is None:
|
||||
lookupIndex = lookupIndex - 1
|
||||
if lookupIndex < 0:
|
||||
return ok
|
||||
if overflowRecord.tableType == 'GSUB':
|
||||
if overflowRecord.tableType == "GSUB":
|
||||
extType = 7
|
||||
elif overflowRecord.tableType == 'GPOS':
|
||||
elif overflowRecord.tableType == "GPOS":
|
||||
extType = 9
|
||||
|
||||
lookups = ttf[overflowRecord.tableType].table.LookupList.Lookup
|
||||
@ -1685,17 +1744,18 @@ def fixLookupOverFlows(ttf, overflowRecord):
|
||||
ok = 1
|
||||
return ok
|
||||
|
||||
|
||||
def splitMultipleSubst(oldSubTable, newSubTable, overflowRecord):
|
||||
ok = 1
|
||||
oldMapping = sorted(oldSubTable.mapping.items())
|
||||
oldLen = len(oldMapping)
|
||||
|
||||
if overflowRecord.itemName in ['Coverage', 'RangeRecord']:
|
||||
if overflowRecord.itemName in ["Coverage", "RangeRecord"]:
|
||||
# Coverage table is written last. Overflow is to or within the
|
||||
# the coverage table. We will just cut the subtable in half.
|
||||
newLen = oldLen // 2
|
||||
|
||||
elif overflowRecord.itemName == 'Sequence':
|
||||
elif overflowRecord.itemName == "Sequence":
|
||||
# We just need to back up by two items from the overflowed
|
||||
# Sequence index to make sure the offset to the Coverage table
|
||||
# doesn't overflow.
|
||||
@ -1710,20 +1770,21 @@ def splitMultipleSubst(oldSubTable, newSubTable, overflowRecord):
|
||||
|
||||
return ok
|
||||
|
||||
|
||||
def splitAlternateSubst(oldSubTable, newSubTable, overflowRecord):
|
||||
ok = 1
|
||||
if hasattr(oldSubTable, 'sortCoverageLast'):
|
||||
if hasattr(oldSubTable, "sortCoverageLast"):
|
||||
newSubTable.sortCoverageLast = oldSubTable.sortCoverageLast
|
||||
|
||||
oldAlts = sorted(oldSubTable.alternates.items())
|
||||
oldLen = len(oldAlts)
|
||||
|
||||
if overflowRecord.itemName in [ 'Coverage', 'RangeRecord']:
|
||||
if overflowRecord.itemName in ["Coverage", "RangeRecord"]:
|
||||
# Coverage table is written last. overflow is to or within the
|
||||
# the coverage table. We will just cut the subtable in half.
|
||||
newLen = oldLen // 2
|
||||
|
||||
elif overflowRecord.itemName == 'AlternateSet':
|
||||
elif overflowRecord.itemName == "AlternateSet":
|
||||
# We just need to back up by two items
|
||||
# from the overflowed AlternateSet index to make sure the offset
|
||||
# to the Coverage table doesn't overflow.
|
||||
@ -1744,12 +1805,12 @@ def splitLigatureSubst(oldSubTable, newSubTable, overflowRecord):
|
||||
oldLigs = sorted(oldSubTable.ligatures.items())
|
||||
oldLen = len(oldLigs)
|
||||
|
||||
if overflowRecord.itemName in [ 'Coverage', 'RangeRecord']:
|
||||
if overflowRecord.itemName in ["Coverage", "RangeRecord"]:
|
||||
# Coverage table is written last. overflow is to or within the
|
||||
# the coverage table. We will just cut the subtable in half.
|
||||
newLen = oldLen // 2
|
||||
|
||||
elif overflowRecord.itemName == 'LigatureSet':
|
||||
elif overflowRecord.itemName == "LigatureSet":
|
||||
# We just need to back up by two items
|
||||
# from the overflowed AlternateSet index to make sure the offset
|
||||
# to the Coverage table doesn't overflow.
|
||||
@ -1770,7 +1831,7 @@ def splitPairPos(oldSubTable, newSubTable, overflowRecord):
|
||||
ok = False
|
||||
newSubTable.Format = oldSubTable.Format
|
||||
if oldSubTable.Format == 1 and len(oldSubTable.PairSet) > 1:
|
||||
for name in 'ValueFormat1', 'ValueFormat2':
|
||||
for name in "ValueFormat1", "ValueFormat2":
|
||||
setattr(newSubTable, name, getattr(oldSubTable, name))
|
||||
|
||||
# Move top half of coverage to new subtable
|
||||
@ -1794,9 +1855,9 @@ def splitPairPos(oldSubTable, newSubTable, overflowRecord):
|
||||
ok = True
|
||||
|
||||
elif oldSubTable.Format == 2 and len(oldSubTable.Class1Record) > 1:
|
||||
if not hasattr(oldSubTable, 'Class2Count'):
|
||||
if not hasattr(oldSubTable, "Class2Count"):
|
||||
oldSubTable.Class2Count = len(oldSubTable.Class1Record[0].Class2Record)
|
||||
for name in 'Class2Count', 'ClassDef2', 'ValueFormat1', 'ValueFormat2':
|
||||
for name in "Class2Count", "ClassDef2", "ValueFormat1", "ValueFormat2":
|
||||
setattr(newSubTable, name, getattr(oldSubTable, name))
|
||||
|
||||
# The two subtables will still have the same ClassDef2 and the table
|
||||
@ -1817,11 +1878,15 @@ def splitPairPos(oldSubTable, newSubTable, overflowRecord):
|
||||
newGlyphs = set(k for k, v in classDefs.items() if v >= oldCount)
|
||||
|
||||
oldSubTable.Coverage.glyphs = [g for g in coverage if g not in newGlyphs]
|
||||
oldSubTable.ClassDef1.classDefs = {k:v for k,v in classDefs.items() if v < oldCount}
|
||||
oldSubTable.ClassDef1.classDefs = {
|
||||
k: v for k, v in classDefs.items() if v < oldCount
|
||||
}
|
||||
oldSubTable.Class1Record = records[:oldCount]
|
||||
|
||||
newSubTable.Coverage.glyphs = [g for g in coverage if g in newGlyphs]
|
||||
newSubTable.ClassDef1.classDefs = {k:(v-oldCount) for k,v in classDefs.items() if v > oldCount}
|
||||
newSubTable.ClassDef1.classDefs = {
|
||||
k: (v - oldCount) for k, v in classDefs.items() if v > oldCount
|
||||
}
|
||||
newSubTable.Class1Record = records[oldCount:]
|
||||
|
||||
oldSubTable.Class1Count = len(oldSubTable.Class1Record)
|
||||
@ -1845,8 +1910,7 @@ def splitMarkBasePos(oldSubTable, newSubTable, overflowRecord):
|
||||
oldMarkCoverage, oldMarkRecords = [], []
|
||||
newMarkCoverage, newMarkRecords = [], []
|
||||
for glyphName, markRecord in zip(
|
||||
oldSubTable.MarkCoverage.glyphs,
|
||||
oldSubTable.MarkArray.MarkRecord
|
||||
oldSubTable.MarkCoverage.glyphs, oldSubTable.MarkArray.MarkRecord
|
||||
):
|
||||
if markRecord.Class < oldClassCount:
|
||||
oldMarkCoverage.append(glyphName)
|
||||
@ -1893,7 +1957,8 @@ def splitMarkBasePos(oldSubTable, newSubTable, overflowRecord):
|
||||
return True
|
||||
|
||||
|
||||
splitTable = { 'GSUB': {
|
||||
splitTable = {
|
||||
"GSUB": {
|
||||
# 1: splitSingleSubst,
|
||||
2: splitMultipleSubst,
|
||||
3: splitAlternateSubst,
|
||||
@ -1903,7 +1968,7 @@ splitTable = { 'GSUB': {
|
||||
# 7: splitExtensionSubst,
|
||||
# 8: splitReverseChainSingleSubst,
|
||||
},
|
||||
'GPOS': {
|
||||
"GPOS": {
|
||||
# 1: splitSinglePos,
|
||||
2: splitPairPos,
|
||||
# 3: splitCursivePos,
|
||||
@ -1913,9 +1978,9 @@ splitTable = { 'GSUB': {
|
||||
# 7: splitContextPos,
|
||||
# 8: splitChainContextPos,
|
||||
# 9: splitExtensionPos,
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def fixSubTableOverFlows(ttf, overflowRecord):
|
||||
"""
|
||||
@ -1931,14 +1996,16 @@ def fixSubTableOverFlows(ttf, overflowRecord):
|
||||
subtable.DontShare = True
|
||||
return True
|
||||
|
||||
if hasattr(subtable, 'ExtSubTable'):
|
||||
if hasattr(subtable, "ExtSubTable"):
|
||||
# We split the subtable of the Extension table, and add a new Extension table
|
||||
# to contain the new subtable.
|
||||
|
||||
subTableType = subtable.ExtSubTable.__class__.LookupType
|
||||
extSubTable = subtable
|
||||
subtable = extSubTable.ExtSubTable
|
||||
newExtSubTableClass = lookupTypes[overflowRecord.tableType][extSubTable.__class__.LookupType]
|
||||
newExtSubTableClass = lookupTypes[overflowRecord.tableType][
|
||||
extSubTable.__class__.LookupType
|
||||
]
|
||||
newExtSubTable = newExtSubTableClass()
|
||||
newExtSubTable.Format = extSubTable.Format
|
||||
toInsert = newExtSubTable
|
||||
@ -1952,7 +2019,7 @@ def fixSubTableOverFlows(ttf, overflowRecord):
|
||||
newSubTable = newSubTableClass()
|
||||
toInsert = newSubTable
|
||||
|
||||
if hasattr(lookup, 'SubTableCount'): # may not be defined yet.
|
||||
if hasattr(lookup, "SubTableCount"): # may not be defined yet.
|
||||
lookup.SubTableCount = lookup.SubTableCount + 1
|
||||
|
||||
try:
|
||||
@ -1970,6 +2037,7 @@ def fixSubTableOverFlows(ttf, overflowRecord):
|
||||
lookup.SubTable.insert(subIndex + 1, toInsert)
|
||||
return ok
|
||||
|
||||
|
||||
# End of OverFlow logic
|
||||
|
||||
|
||||
@ -1995,7 +2063,7 @@ def _buildClasses():
|
||||
if name not in namespace:
|
||||
# the class doesn't exist yet, so the base implementation is used.
|
||||
cls = type(name, (baseClass,), {})
|
||||
if name in ('GSUB', 'GPOS'):
|
||||
if name in ("GSUB", "GPOS"):
|
||||
cls.DontShare = True
|
||||
namespace[name] = cls
|
||||
|
||||
@ -2014,7 +2082,7 @@ def _buildClasses():
|
||||
|
||||
global lookupTypes
|
||||
lookupTypes = {
|
||||
'GSUB': {
|
||||
"GSUB": {
|
||||
1: SingleSubst,
|
||||
2: MultipleSubst,
|
||||
3: AlternateSubst,
|
||||
@ -2024,7 +2092,7 @@ def _buildClasses():
|
||||
7: ExtensionSubst,
|
||||
8: ReverseChainSingleSubst,
|
||||
},
|
||||
'GPOS': {
|
||||
"GPOS": {
|
||||
1: SinglePos,
|
||||
2: PairPos,
|
||||
3: CursivePos,
|
||||
@ -2035,10 +2103,10 @@ def _buildClasses():
|
||||
8: ChainContextPos,
|
||||
9: ExtensionPos,
|
||||
},
|
||||
'mort': {
|
||||
"mort": {
|
||||
4: NoncontextualMorph,
|
||||
},
|
||||
'morx': {
|
||||
"morx": {
|
||||
0: RearrangementMorph,
|
||||
1: ContextualMorph,
|
||||
2: LigatureMorph,
|
||||
@ -2047,22 +2115,23 @@ def _buildClasses():
|
||||
5: InsertionMorph,
|
||||
},
|
||||
}
|
||||
lookupTypes['JSTF'] = lookupTypes['GPOS'] # JSTF contains GPOS
|
||||
lookupTypes["JSTF"] = lookupTypes["GPOS"] # JSTF contains GPOS
|
||||
for lookupEnum in lookupTypes.values():
|
||||
for enum, cls in lookupEnum.items():
|
||||
cls.LookupType = enum
|
||||
|
||||
global featureParamTypes
|
||||
featureParamTypes = {
|
||||
'size': FeatureParamsSize,
|
||||
"size": FeatureParamsSize,
|
||||
}
|
||||
for i in range(1, 20 + 1):
|
||||
featureParamTypes['ss%02d' % i] = FeatureParamsStylisticSet
|
||||
featureParamTypes["ss%02d" % i] = FeatureParamsStylisticSet
|
||||
for i in range(1, 99 + 1):
|
||||
featureParamTypes['cv%02d' % i] = FeatureParamsCharacterVariants
|
||||
featureParamTypes["cv%02d" % i] = FeatureParamsCharacterVariants
|
||||
|
||||
# add converters to classes
|
||||
from .otConverters import buildConverters
|
||||
|
||||
for name, table in otData:
|
||||
m = formatPat.match(name)
|
||||
if m:
|
||||
|
Loading…
x
Reference in New Issue
Block a user