diff --git a/Lib/fontTools/colorLib/builder.py b/Lib/fontTools/colorLib/builder.py index a76992489..b6a54eae5 100644 --- a/Lib/fontTools/colorLib/builder.py +++ b/Lib/fontTools/colorLib/builder.py @@ -493,10 +493,23 @@ def buildPaintGlyph(glyph: str, paint: _PaintInput) -> ot.Paint: return self -def buildPaintColorGlyph(glyph: str) -> ot.Paint: +def buildPaintColorGlyph( + glyph: str, firstLayerIndex: int = 0, lastLayerIndex: int = 255 +) -> ot.Paint: self = ot.Paint() self.Format = int(ot.Paint.Format.PaintColorGlyph) self.Glyph = glyph + if firstLayerIndex > lastLayerIndex: + raise ValueError( + f"Expected first <= last index, found: {firstLayerIndex} > {lastLayerIndex}" + ) + for prefix in ("first", "last"): + indexName = f"{prefix}LayerIndex" + index = locals()[indexName] + if index < 0 or index > 255: + raise OverflowError(f"{indexName} ({index}) out of range [0..255]") + self.FirstLayerIndex = firstLayerIndex + self.LastLayerIndex = lastLayerIndex return self diff --git a/Lib/fontTools/ttLib/tables/otData.py b/Lib/fontTools/ttLib/tables/otData.py index e30b24f7f..360bb58f3 100755 --- a/Lib/fontTools/ttLib/tables/otData.py +++ b/Lib/fontTools/ttLib/tables/otData.py @@ -1646,6 +1646,8 @@ otData = [ ('PaintFormat5', [ ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 5'), ('GlyphID', 'Glyph', None, None, 'Virtual glyph ID for a BaseGlyphV1List base glyph.'), + ('uint8', 'FirstLayerIndex', None, None, 'First layer index to reuse'), + ('uint8', 'LastLayerIndex', None, None, 'Last layer index to reuse, inclusive'), ]), ('PaintFormat6', [ ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 6'), diff --git a/Tests/colorLib/builder_test.py b/Tests/colorLib/builder_test.py index 016c2f277..c91e85418 100644 --- a/Tests/colorLib/builder_test.py +++ b/Tests/colorLib/builder_test.py @@ -441,6 +441,19 @@ def test_buildPaintColorGlyph(): paint = builder.buildPaintColorGlyph("a") assert paint.Format == ot.Paint.Format.PaintColorGlyph assert paint.Glyph == "a" + assert paint.FirstLayerIndex == 0 + assert paint.LastLayerIndex == 255 + + paint = builder.buildPaintColorGlyph("a", firstLayerIndex=1, lastLayerIndex=254) + assert paint.FirstLayerIndex == 1 + assert paint.LastLayerIndex == 254 + + with pytest.raises(ValueError, match="Expected first <= last index"): + builder.buildPaintColorGlyph("a", 255, 0) + with pytest.raises(OverflowError, match="firstLayerIndex .* out of range"): + builder.buildPaintColorGlyph("a", -1, 255) + with pytest.raises(OverflowError, match="lastLayerIndex .* out of range"): + builder.buildPaintColorGlyph("a", 0, 256) def test_buildPaintTransform(): diff --git a/Tests/ttLib/tables/C_O_L_R_test.py b/Tests/ttLib/tables/C_O_L_R_test.py index 4b5c4d8ea..67811f7f5 100644 --- a/Tests/ttLib/tables/C_O_L_R_test.py +++ b/Tests/ttLib/tables/C_O_L_R_test.py @@ -197,6 +197,8 @@ COLR_V1_DATA = ( b"\x00\x00\x00\x00" b"\x05" # Paint[0].SourcePaint.Format (5) b"\x00\n" # Paint[0].SourcePaint.Glyph (10) + b"\x00" # Paint[0].SourcePaint.FirstLayerIndex (0) + b"\xff" # Paint[0].SourcePaint.LastLayerIndex (255) ) @@ -324,11 +326,15 @@ COLR_V1_XML = [ ' ', ' ', ' ', + ' ', + ' ', " ", ' ', ' ', ' ', ' ', + ' ', + ' ', " ", " ", ' ',