diff --git a/Lib/fontTools/otlLib/builder.py b/Lib/fontTools/otlLib/builder.py
index e3f335514..cec1ec317 100644
--- a/Lib/fontTools/otlLib/builder.py
+++ b/Lib/fontTools/otlLib/builder.py
@@ -367,9 +367,15 @@ class ChainContextualBuilder(LookupBuilder):
contextual positioning lookup.
"""
subtables = []
- chaining = False
+
rulesets = self.rulesets()
chaining = any(ruleset.hasPrefixOrSuffix for ruleset in rulesets)
+ # Unfortunately, as of 2022-03-07, Apple's CoreText renderer does not
+ # correctly process GPOS7 lookups, so for now we force contextual
+ # positioning lookups to be chaining (GPOS8).
+ if self.subtable_type == "Pos": # horrible separation of concerns breach
+ chaining = True
+
for ruleset in rulesets:
# Determine format strategy. We try to build formats 1, 2 and 3
# subtables and then work out which is best. candidates list holds
diff --git a/Tests/feaLib/data/spec6h_ii.ttx b/Tests/feaLib/data/spec6h_ii.ttx
index 2f0efc6f2..e8ec85f28 100644
--- a/Tests/feaLib/data/spec6h_ii.ttx
+++ b/Tests/feaLib/data/spec6h_ii.ttx
@@ -112,23 +112,25 @@
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
+
+
+
@@ -137,7 +139,7 @@
-
+
diff --git a/Tests/feaLib/data/spec6h_iii_3d.ttx b/Tests/feaLib/data/spec6h_iii_3d.ttx
index 2335dd0b4..a608f0e62 100644
--- a/Tests/feaLib/data/spec6h_iii_3d.ttx
+++ b/Tests/feaLib/data/spec6h_iii_3d.ttx
@@ -30,23 +30,25 @@
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
+
+
-
+
diff --git a/Tests/varLib/data/test_results/InterpolateLayoutGPOS_7_diff.ttx b/Tests/varLib/data/test_results/InterpolateLayoutGPOS_8_diff.ttx
similarity index 87%
rename from Tests/varLib/data/test_results/InterpolateLayoutGPOS_7_diff.ttx
rename to Tests/varLib/data/test_results/InterpolateLayoutGPOS_8_diff.ttx
index 14e120979..0086ddc3c 100644
--- a/Tests/varLib/data/test_results/InterpolateLayoutGPOS_7_diff.ttx
+++ b/Tests/varLib/data/test_results/InterpolateLayoutGPOS_8_diff.ttx
@@ -83,21 +83,23 @@
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -106,9 +108,9 @@
-
-
-
+
+
+
diff --git a/Tests/varLib/data/test_results/InterpolateLayoutGPOS_7_same.ttx b/Tests/varLib/data/test_results/InterpolateLayoutGPOS_8_same.ttx
similarity index 87%
rename from Tests/varLib/data/test_results/InterpolateLayoutGPOS_7_same.ttx
rename to Tests/varLib/data/test_results/InterpolateLayoutGPOS_8_same.ttx
index eff24fc30..a32c94d03 100644
--- a/Tests/varLib/data/test_results/InterpolateLayoutGPOS_7_same.ttx
+++ b/Tests/varLib/data/test_results/InterpolateLayoutGPOS_8_same.ttx
@@ -83,21 +83,23 @@
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -106,9 +108,9 @@
-
-
-
+
+
+
diff --git a/Tests/varLib/interpolate_layout_test.py b/Tests/varLib/interpolate_layout_test.py
index 18dc3a752..219f087ff 100644
--- a/Tests/varLib/interpolate_layout_test.py
+++ b/Tests/varLib/interpolate_layout_test.py
@@ -746,8 +746,8 @@ class InterpolateLayoutTest(unittest.TestCase):
self.check_ttx_dump(instfont, expected_ttx_path, tables, suffix)
- def test_varlib_interpolate_layout_GPOS_only_LookupType_7_same_val_ttf(self):
- """Only GPOS; LookupType 7; same values in all masters.
+ def test_varlib_interpolate_layout_GPOS_only_LookupType_8_same_val_ttf(self):
+ """Only GPOS; LookupType 8; same values in all masters.
"""
suffix = '.ttf'
ds_path = self.get_test_input('InterpolateLayout.designspace')
@@ -779,13 +779,13 @@ class InterpolateLayoutTest(unittest.TestCase):
instfont = interpolate_layout(ds_path, {'weight': 500}, finder)
tables = ['GPOS']
- expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_7_same.ttx')
+ expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_8_same.ttx')
self.expect_ttx(instfont, expected_ttx_path, tables)
self.check_ttx_dump(instfont, expected_ttx_path, tables, suffix)
- def test_varlib_interpolate_layout_GPOS_only_LookupType_7_diff_val_ttf(self):
- """Only GPOS; LookupType 7; different values in each master.
+ def test_varlib_interpolate_layout_GPOS_only_LookupType_8_diff_val_ttf(self):
+ """Only GPOS; LookupType 8; different values in each master.
"""
suffix = '.ttf'
ds_path = self.get_test_input('InterpolateLayout.designspace')
@@ -831,7 +831,7 @@ class InterpolateLayoutTest(unittest.TestCase):
instfont = interpolate_layout(ds_path, {'weight': 500}, finder)
tables = ['GPOS']
- expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_7_diff.ttx')
+ expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_8_diff.ttx')
self.expect_ttx(instfont, expected_ttx_path, tables)
self.check_ttx_dump(instfont, expected_ttx_path, tables, suffix)