Repository: googlefonts/ufo2ft
Pull request #771 (2023-07-31 14:55:04)

set OVERLAP_SIMPLE when public.truetype.overlap key set on simple glyph
It turns out we were only reading the UFO `public.truetype.overlap` key for composite glyphs, but not also for simple contour glyphs.
This PRs adds support for that as well.

Fixes/supersedes Fixes https://github.com/googlefonts/ufo2ft/pull/615

https://unifiedfontobject.org/versions/ufo3/glyphs/glif/#publictruetypeoverlap

/cc @jenskutilek @m4rc1e 


Patch:
diff --git a/Lib/ufo2ft/filters/__main__.py b/Lib/ufo2ft/filters/__main__.py
index 6704057..3e6c78b 100644
--- a/Lib/ufo2ft/filters/__main__.py
+++ b/Lib/ufo2ft/filters/__main__.py
@@ -34,8 +34,6 @@ if not args.output:
 
 ufo = loader(args.ufo)
 
-include = None
-
 if args.include:
     include_set = set(args.include.split(","))
 
@@ -48,6 +46,9 @@ elif args.exclude:
     def include(g):
         return g.name not in exclude_set
 
+else:
+    include = None
+
 
 for filtername in args.filters:
     f = loadFilterFromString(filtername)
diff --git a/Lib/ufo2ft/instructionCompiler.py b/Lib/ufo2ft/instructionCompiler.py
index 82f0e63..32ed8fb 100644
--- a/Lib/ufo2ft/instructionCompiler.py
+++ b/Lib/ufo2ft/instructionCompiler.py
@@ -11,6 +11,7 @@ from fontTools.ttLib.tables._g_l_y_f import (
     OVERLAP_COMPOUND,
     ROUND_XY_TO_GRID,
     USE_MY_METRICS,
+    flagOverlapSimple,
 )
 
 from ufo2ft.constants import (
@@ -121,6 +122,8 @@ class InstructionCompiler:
             self._compile_tt_glyph_program(glyph, ttGlyph, ttdata)
         if ttGlyph.isComposite():
             self._set_composite_flags(glyph, ttGlyph)
+        else:
+            self._set_simple_flags(glyph, ttGlyph)
 
     def _compile_tt_glyph_program(
         self, glyph: Glyph, ttglyph: TTGlyph, ttdata: dict
@@ -253,6 +256,19 @@ class InstructionCompiler:
         if not lib_contains_use_my_metrics_key:
             self.autoUseMyMetrics(ttglyph, glyph.name)
 
+    def _set_simple_flags(self, glyph: Glyph, ttglyph: TTGlyph) -> None:
+        # Set simple glyph flags
+
+        if ttglyph.numberOfContours < 1 or not ttglyph.flags:
+            return
+
+        # Set OVERLAP_SIMPLE
+        if TRUETYPE_OVERLAP_KEY in glyph.lib:
+            if glyph.lib[TRUETYPE_OVERLAP_KEY]:
+                ttglyph.flags[0] |= flagOverlapSimple
+            else:
+                ttglyph.flags[0] &= ~flagOverlapSimple
+
     def update_maxp(self) -> None:
         """Update the maxp table with relevant values from the UFO and compiled
         font.


Test patch:
diff --git a/tests/instructionCompiler_test.py b/tests/instructionCompiler_test.py
index a25b7e4..00a2c75 100644
--- a/tests/instructionCompiler_test.py
+++ b/tests/instructionCompiler_test.py
@@ -7,6 +7,7 @@ from fontTools.ttLib.tables._g_l_y_f import (
     OVERLAP_COMPOUND,
     ROUND_XY_TO_GRID,
     USE_MY_METRICS,
+    flagOverlapSimple,
 )
 from fontTools.ttLib.ttFont import TTFont
 
@@ -584,6 +585,23 @@ class InstructionCompilerTest:
 
         assert "Number of components differ" in caplog.text
 
+    @pytest.mark.parametrize("overlap", [None, False, True])
+    def test_set_simple_flags(self, quadufo, quadfont, overlap):
+        ic = InstructionCompiler(quadufo, quadfont)
+        name = "a"
+
+        glyph = quadufo[name]
+        if overlap is not None:
+            glyph.lib = {"public.truetype.overlap": overlap}
+        ttglyph = quadfont["glyf"][name]
+
+        ic._set_simple_flags(glyph=glyph, ttglyph=ttglyph)
+
+        if overlap:
+            assert ttglyph.flags[0] & flagOverlapSimple
+        else:
+            assert not ttglyph.flags[0] & flagOverlapSimple
+
     # update_maxp
 
     def test_update_maxp_no_ttdata(self, quaduforeversed, quadfont):
diff --git a/tests/integration_test.py b/tests/integration_test.py
index 06bc90a..4bdbd7b 100644
--- a/tests/integration_test.py
+++ b/tests/integration_test.py
@@ -7,6 +7,7 @@ from pathlib import Path
 
 import pytest
 from fontTools.pens.boundsPen import BoundsPen
+from fontTools.ttLib.tables._g_l_y_f import OVERLAP_COMPOUND, flagOverlapSimple
 
 from ufo2ft import (
     compileInterpolatableTTFs,
@@ -17,7 +18,7 @@ from ufo2ft import (
     compileVariableTTF,
     compileVariableTTFs,
 )
-from ufo2ft.constants import KEEP_GLYPH_NAMES
+from ufo2ft.constants import KEEP_GLYPH_NAMES, TRUETYPE_OVERLAP_KEY
 from ufo2ft.errors import InvalidFontData
 from ufo2ft.filters import TransformationsFilter
 
@@ -466,6 +467,19 @@ class IntegrationTest:
 
         assert vf["head"].glyphDataFormat == 1
 
+    def test_compileTTF_overlap_simple_flag(self, testufo):
+        """Test that the OVERLAP_{SIMPLE,COMPOUND} are set on glyphs that have it"""
+        testufo["a"].lib = {TRUETYPE_OVERLAP_KEY: True}
+        testufo["h"].lib = {TRUETYPE_OVERLAP_KEY: True}
+        ttf = compileTTF(testufo, useProductionNames=False)
+
+        # OVERLAP_SIMPLE is set on 'a' but not on 'b'
+        assert ttf["glyf"]["a"].flags[0] & flagOverlapSimple
+        assert not ttf["glyf"]["b"].flags[0] & flagOverlapSimple
+        # OVERLAP_COMPOUND is set on 'h' but not on 'g'
+        assert not ttf["glyf"]["g"].components[0].flags & OVERLAP_COMPOUND
+        assert ttf["glyf"]["h"].components[0].flags & OVERLAP_COMPOUND
+
 
 if __name__ == "__main__":
     sys.exit(pytest.main(sys.argv))