aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/otlLib/builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/otlLib/builder.py')
-rw-r--r--Lib/fontTools/otlLib/builder.py61
1 files changed, 40 insertions, 21 deletions
diff --git a/Lib/fontTools/otlLib/builder.py b/Lib/fontTools/otlLib/builder.py
index 029aa3fc..182f7da6 100644
--- a/Lib/fontTools/otlLib/builder.py
+++ b/Lib/fontTools/otlLib/builder.py
@@ -9,7 +9,9 @@ from fontTools.ttLib.tables.otBase import (
CountReference,
)
from fontTools.ttLib.tables import otBase
+from fontTools.feaLib.ast import STATNameStatement
from fontTools.otlLib.error import OpenTypeLibError
+from functools import reduce
import logging
import copy
@@ -94,9 +96,10 @@ def buildLookup(subtables, flags=0, markFilterSet=None):
subtables = [st for st in subtables if st is not None]
if not subtables:
return None
- assert all(t.LookupType == subtables[0].LookupType for t in subtables), (
- "all subtables must have the same LookupType; got %s"
- % repr([t.LookupType for t in subtables])
+ assert all(
+ t.LookupType == subtables[0].LookupType for t in subtables
+ ), "all subtables must have the same LookupType; got %s" % repr(
+ [t.LookupType for t in subtables]
)
self = ot.Lookup()
self.LookupType = subtables[0].LookupType
@@ -1027,7 +1030,7 @@ class MarkMarkPosBuilder(LookupBuilder):
builder.marks["acute"] = (0, a1)
builder.marks["grave"] = (0, a1)
builder.marks["cedilla"] = (1, a2)
- builder.baseMarks["acute"] = (0, a3)
+ builder.baseMarks["acute"] = {0: a3}
Attributes:
font (``fontTools.TTLib.TTFont``): A font object.
@@ -1035,8 +1038,8 @@ class MarkMarkPosBuilder(LookupBuilder):
source which produced this lookup.
marks: An dictionary mapping a glyph name to a two-element
tuple containing a mark class ID and ``otTables.Anchor`` object.
- baseMarks: An dictionary mapping a glyph name to a two-element
- tuple containing a mark class ID and ``otTables.Anchor`` object.
+ baseMarks: An dictionary mapping a glyph name to a dictionary
+ containing one item: a mark class ID and a ``otTables.Anchor`` object.
lookupflag (int): The lookup's flag
markFilterSet: Either ``None`` if no mark filtering set is used, or
an integer representing the filtering set to be used for this
@@ -2073,8 +2076,8 @@ def buildPairPosClassesSubtable(pairs, glyphMap, valueFormat1=None, valueFormat2
classDef2.add(gc2)
self = ot.PairPos()
self.Format = 2
- self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0)
- self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1)
+ valueFormat1 = self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0)
+ valueFormat2 = self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1)
self.Coverage = buildCoverage(coverage, glyphMap)
self.ClassDef1 = classDef1.build()
self.ClassDef2 = classDef2.build()
@@ -2087,7 +2090,9 @@ def buildPairPosClassesSubtable(pairs, glyphMap, valueFormat1=None, valueFormat2
self.Class1Record.append(rec1)
for c2 in classes2:
rec2 = ot.Class2Record()
- rec2.Value1, rec2.Value2 = pairs.get((c1, c2), (None, None))
+ val1, val2 = pairs.get((c1, c2), (None, None))
+ rec2.Value1 = ValueRecord(src=val1, valueFormat=valueFormat1) if valueFormat1 else None
+ rec2.Value2 = ValueRecord(src=val2, valueFormat=valueFormat2) if valueFormat2 else None
rec1.Class2Record.append(rec2)
self.Class1Count = len(self.Class1Record)
self.Class2Count = len(classes2)
@@ -2172,8 +2177,8 @@ def buildPairPosGlyphsSubtable(pairs, glyphMap, valueFormat1=None, valueFormat2=
"""
self = ot.PairPos()
self.Format = 1
- self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0)
- self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1)
+ valueFormat1 = self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0)
+ valueFormat2 = self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1)
p = {}
for (glyphA, glyphB), (valA, valB) in pairs.items():
p.setdefault(glyphA, []).append((glyphB, valA, valB))
@@ -2186,8 +2191,8 @@ def buildPairPosGlyphsSubtable(pairs, glyphMap, valueFormat1=None, valueFormat2=
for glyph2, val1, val2 in sorted(p[glyph], key=lambda x: glyphMap[x[0]]):
pvr = ot.PairValueRecord()
pvr.SecondGlyph = glyph2
- pvr.Value1 = val1 if val1 and val1.getFormat() != 0 else None
- pvr.Value2 = val2 if val2 and val2.getFormat() != 0 else None
+ pvr.Value1 = ValueRecord(src=val1, valueFormat=valueFormat1) if valueFormat1 else None
+ pvr.Value2 = ValueRecord(src=val2, valueFormat=valueFormat2) if valueFormat2 else None
ps.PairValueRecord.append(pvr)
ps.PairValueCount = len(ps.PairValueRecord)
self.PairSetCount = len(self.PairSet)
@@ -2308,10 +2313,8 @@ def buildSinglePosSubtable(values, glyphMap):
"""
self = ot.SinglePos()
self.Coverage = buildCoverage(values.keys(), glyphMap)
- valueRecords = [values[g] for g in self.Coverage.glyphs]
- self.ValueFormat = 0
- for v in valueRecords:
- self.ValueFormat |= v.getFormat()
+ valueFormat = self.ValueFormat = reduce(int.__or__, [v.getFormat() for v in values.values()], 0)
+ valueRecords = [ValueRecord(src=values[g], valueFormat=valueFormat) for g in self.Coverage.glyphs]
if all(v == valueRecords[0] for v in valueRecords):
self.Format = 1
if self.ValueFormat != 0:
@@ -2575,7 +2578,9 @@ class ClassDefBuilder(object):
self.classes_.add(glyphs)
for glyph in glyphs:
if glyph in self.glyphs_:
- raise OpenTypeLibError(f"Glyph {glyph} is already present in class.", None)
+ raise OpenTypeLibError(
+ f"Glyph {glyph} is already present in class.", None
+ )
self.glyphs_[glyph] = glyphs
def classes(self):
@@ -2687,8 +2692,8 @@ def buildStatTable(ttFont, axes, locations=None, elidedFallbackName=2):
]
The optional 'elidedFallbackName' argument can be a name ID (int),
- a string, or a dictionary containing multilingual names. It
- translates to the ElidedFallbackNameID field.
+ a string, a dictionary containing multilingual names, or a list of
+ STATNameStatements. It translates to the ElidedFallbackNameID field.
The 'ttFont' argument must be a TTFont instance that already has a
'name' table. If a 'STAT' table already exists, it will be
@@ -2797,6 +2802,20 @@ def _addName(nameTable, value, minNameID=0):
names = dict(en=value)
elif isinstance(value, dict):
names = value
+ elif isinstance(value, list):
+ nameID = nameTable._findUnusedNameID()
+ for nameRecord in value:
+ if isinstance(nameRecord, STATNameStatement):
+ nameTable.setName(
+ nameRecord.string,
+ nameID,
+ nameRecord.platformID,
+ nameRecord.platEncID,
+ nameRecord.langID,
+ )
+ else:
+ raise TypeError("value must be a list of STATNameStatements")
+ return nameID
else:
- raise TypeError("value must be int, str or dict")
+ raise TypeError("value must be int, str, dict or list")
return nameTable.addMultilingualName(names, minNameID=minNameID)