diff --git a/Lib/fontTools/feaLib/builder.py b/Lib/fontTools/feaLib/builder.py
index 05a15173f..9ff49b29e 100644
--- a/Lib/fontTools/feaLib/builder.py
+++ b/Lib/fontTools/feaLib/builder.py
@@ -714,14 +714,7 @@ class LookupBuilder(object):
return {}
def buildLookup_(self, subtables):
- lookup = otTables.Lookup()
- lookup.LookupFlag = self.lookupflag
- lookup.LookupType = self.lookup_type
- lookup.SubTable = subtables
- lookup.SubTableCount = len(subtables)
- if self.markFilterSet is not None:
- lookup.MarkFilteringSet = self.markFilterSet
- return lookup
+ return otl.buildLookup(subtables, self.lookupflag, self.markFilterSet)
def buildMarkClasses_(self, marks):
"""{"cedilla": ("BOTTOM", ast.Anchor), ...} --> {"BOTTOM":0, "TOP":1}
diff --git a/Lib/fontTools/otlLib/builder.py b/Lib/fontTools/otlLib/builder.py
index 01643dcfa..2bbb45186 100644
--- a/Lib/fontTools/otlLib/builder.py
+++ b/Lib/fontTools/otlLib/builder.py
@@ -10,6 +10,37 @@ def buildCoverage(glyphs, glyphMap):
return self
+LOOKUP_FLAG_RIGHT_TO_LEFT = 0x0001
+LOOKUP_FLAG_IGNORE_BASE_GLYPHS = 0x0002
+LOOKUP_FLAG_IGNORE_LIGATURES = 0x0004
+LOOKUP_FLAG_IGNORE_MARKS = 0x0008
+LOOKUP_FLAG_USE_MARK_FILTERING_SET = 0x0010
+
+
+def buildLookup(subtables, flags=0, markFilterSet=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]))
+ self = ot.Lookup()
+ self.LookupType = subtables[0].LookupType
+ self.LookupFlag = flags
+ self.SubTable = subtables
+ self.SubTableCount = len(subtables)
+ if markFilterSet is not None:
+ assert self.LookupFlag & LOOKUP_FLAG_USE_MARK_FILTERING_SET, \
+ ("if markFilterSet is not None, flags must set "
+ "LOOKUP_FLAG_USE_MARK_FILTERING_SET; flags=0x%04x" % flags)
+ assert isinstance(markFilterSet, int), markFilterSet
+ self.MarkFilteringSet = markFilterSet
+ else:
+ assert (self.LookupFlag & LOOKUP_FLAG_USE_MARK_FILTERING_SET) == 0, \
+ ("if markFilterSet is None, flags must not set "
+ "LOOKUP_FLAG_USE_MARK_FILTERING_SET; flags=0x%04x" % flags)
+ return self
+
+
# GSUB
diff --git a/Lib/fontTools/otlLib/builder_test.py b/Lib/fontTools/otlLib/builder_test.py
index 3238c71a8..eb7b2eab6 100644
--- a/Lib/fontTools/otlLib/builder_test.py
+++ b/Lib/fontTools/otlLib/builder_test.py
@@ -14,6 +14,13 @@ class BuilderTest(unittest.TestCase):
ANCHOR2 = builder.buildAnchor(22, -22)
ANCHOR3 = builder.buildAnchor(33, -33)
+ def __init__(self, methodName):
+ unittest.TestCase.__init__(self, methodName)
+ # Python 3 renamed assertRaisesRegexp to assertRaisesRegex,
+ # and fires deprecation warnings if a program uses the old name.
+ if not hasattr(self, "assertRaisesRegex"):
+ self.assertRaisesRegex = self.assertRaisesRegexp
+
def test_buildAnchor_format1(self):
anchor = builder.buildAnchor(23, 42)
self.assertEqual(getXML(anchor.toXML),
@@ -256,6 +263,65 @@ class BuilderTest(unittest.TestCase):
' '
'')
+ def test_buildLookup(self):
+ s1 = builder.buildSingleSubst({"one": "two"})
+ s2 = builder.buildSingleSubst({"three": "four"})
+ lookup = builder.buildLookup([s1, s2], flags=7)
+ self.assertEqual(getXML(lookup.toXML),
+ ''
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ '')
+
+ def test_buildLookup_badFlags(self):
+ s = builder.buildSingleSubst({"one": "two"})
+ self.assertRaisesRegex(
+ AssertionError, "if markFilterSet is None, "
+ "flags must not set LOOKUP_FLAG_USE_MARK_FILTERING_SET; "
+ "flags=0x0010",
+ builder.buildLookup, [s],
+ builder.LOOKUP_FLAG_USE_MARK_FILTERING_SET, None)
+ self.assertRaisesRegex(
+ AssertionError, "if markFilterSet is not None, "
+ "flags must set LOOKUP_FLAG_USE_MARK_FILTERING_SET; "
+ "flags=0x0004",
+ builder.buildLookup, [s],
+ builder.LOOKUP_FLAG_IGNORE_LIGATURES, 777)
+
+ def test_buildLookup_conflictingSubtableTypes(self):
+ s1 = builder.buildSingleSubst({"one": "two"})
+ s2 = builder.buildAlternateSubst({"one": ["two", "three"]})
+ self.assertRaisesRegex(
+ AssertionError, "all subtables must have the same LookupType",
+ builder.buildLookup, [s1, s2])
+
+ def test_buildLookup_noSubtables(self):
+ self.assertIsNone(builder.buildLookup([]))
+ self.assertIsNone(builder.buildLookup(None))
+
+ def test_buildLookup_markFilterSet(self):
+ s = builder.buildSingleSubst({"one": "two"})
+ flags = (builder.LOOKUP_FLAG_RIGHT_TO_LEFT |
+ builder.LOOKUP_FLAG_USE_MARK_FILTERING_SET)
+ lookup = builder.buildLookup([s], flags, markFilterSet=999)
+ self.assertEqual(getXML(lookup.toXML),
+ ''
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ ' '
+ '')
+
def test_buildMarkGlyphSetsDef(self):
marksets = builder.buildMarkGlyphSetsDef(
[{"acute", "grave"}, {"cedilla", "grave"}], self.GLYPHMAP)