chiark / gitweb /
Sort glyph names in compatcheck
authorBen Harris <bjh21@bjh21.me.uk>
Sun, 29 Dec 2024 18:45:47 +0000 (18:45 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Sun, 29 Dec 2024 18:50:52 +0000 (18:50 +0000)
compatcheck

index aa96dada140b09de8851792fd167081b96455815..c119693ee1bf4d2793350ee4acc6f517e7a57647 100755 (executable)
 # Vendor ID.  At least some versions of GNU Emacs like to use the
 # OS/2.achVendID field to select fonts.  So if that changes, Emacs
 # might not find your favourite font.
+#
+# Some 'GSUB' lookups.  For some features, the OpenType specification
+# says that the various outputs of an alternate lookup should match
+# across fonts in a family.  This suggests that it's reasonable to
+# depend on the behaviour of particular inputs to these lookups, and
+# that they should thus be consistent within major versions.  Unlike
+# for most features above, we'd like to check that the semantics of
+# the chosen glyphs haven't changed.  For now, we do that by checking
+# glyph names.  The only feature currently handled by this is 'aalt'
+# (Access All Alternates).
 
 from argparse import ArgumentParser
 from fontTools import ttLib
@@ -92,5 +102,26 @@ for oldname in ttold['name'].names:
 if ttold['OS/2'].achVendID != ttnew['OS/2'].achVendID:
     fail("Vendor ID mismatch")
 
+def feat_to_dict(gsub, tag):
+    # Assertions in this function trap various unhandled cases.
+    feature_records = [f for f in gsub.table.FeatureList.FeatureRecord
+                       if f.FeatureTag == tag]
+    assert(len(feature_records) == 1)
+    for fr in feature_records:
+        assert(len(fr.Feature.LookupListIndex) == 1)
+        for llix in fr.Feature.LookupListIndex:
+            lookup = gsub.table.LookupList.Lookup[llix]
+            assert(lookup.LookupType == 3)
+            assert(len(lookup.SubTable) == 1)
+            for st in lookup.SubTable:
+                return st.alternates
+
+for feat in ['aalt']:
+    oldalt = feat_to_dict(ttold['GSUB'], feat)
+    newalt = feat_to_dict(ttnew['GSUB'], feat)
+    for k in sorted(set(oldalt.keys()) & set(newalt.keys())):
+        if newalt[k][:len(oldalt[k])] != oldalt[k]:
+            fail(f"new '{feat}' lookup for {k} is not a prefix of old one")
+
 if failed:
     exit(1)