From 538528d5a1f202e0fc38846cf69c01c2cda40da2 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Tue, 15 Dec 2020 16:51:08 +0000 Subject: [PATCH] COLRv1: Implement PaintTranslate https://github.com/googlefonts/colr-gradients-spec/pull/163 --- Lib/fontTools/colorLib/builder.py | 10 +++++ Lib/fontTools/ttLib/tables/otData.py | 17 ++++++--- Lib/fontTools/ttLib/tables/otTables.py | 7 ++-- Tests/colorLib/builder_test.py | 20 +++++++++- Tests/ttLib/tables/C_O_L_R_test.py | 51 +++++++++++++++----------- 5 files changed, 74 insertions(+), 31 deletions(-) diff --git a/Lib/fontTools/colorLib/builder.py b/Lib/fontTools/colorLib/builder.py index 74abb8afd..724136ab1 100644 --- a/Lib/fontTools/colorLib/builder.py +++ b/Lib/fontTools/colorLib/builder.py @@ -557,6 +557,16 @@ class LayerV1ListBuilder: ot_paint.Paint = self.buildPaint(paint) return ot_paint + def buildPaintTranslate( + self, paint: _PaintInput, dx: _ScalarInput, dy: _ScalarInput + ): + ot_paint = ot.Paint() + ot_paint.Format = int(ot.Paint.Format.PaintTranslate) + ot_paint.Paint = self.buildPaint(paint) + ot_paint.dx = _to_variable_f16dot16_float(dx) + ot_paint.dy = _to_variable_f16dot16_float(dy) + return ot_paint + def buildPaintRotate( self, paint: _PaintInput, diff --git a/Lib/fontTools/ttLib/tables/otData.py b/Lib/fontTools/ttLib/tables/otData.py index 776cf75ba..a6f9619e6 100755 --- a/Lib/fontTools/ttLib/tables/otData.py +++ b/Lib/fontTools/ttLib/tables/otData.py @@ -1665,23 +1665,30 @@ otData = [ ('PaintFormat8', [ ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 8'), + ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintTranslate table) to Paint subtable.'), + ('VarFixed', 'dx', None, None, 'Translation in x direction.'), + ('VarFixed', 'dy', None, None, 'Translation in y direction.'), + ]), + + ('PaintFormat9', [ + ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 9'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintRotate table) to Paint subtable.'), ('VarFixed', 'angle', None, None, ''), ('VarFixed', 'centerX', None, None, ''), ('VarFixed', 'centerY', None, None, ''), ]), - ('PaintFormat9', [ - ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 9'), - ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintRotate table) to Paint subtable.'), + ('PaintFormat10', [ + ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 10'), + ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintSkew table) to Paint subtable.'), ('VarFixed', 'xSkewAngle', None, None, ''), ('VarFixed', 'ySkewAngle', None, None, ''), ('VarFixed', 'centerX', None, None, ''), ('VarFixed', 'centerY', None, None, ''), ]), - ('PaintFormat10', [ - ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 8'), + ('PaintFormat11', [ + ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 11'), ('LOffset24To(Paint)', 'SourcePaint', None, None, 'Offset (from beginning of PaintComposite table) to source Paint subtable.'), ('CompositeMode', 'CompositeMode', None, None, 'A CompositeMode enumeration value.'), ('LOffset24To(Paint)', 'BackdropPaint', None, None, 'Offset (from beginning of PaintComposite table) to backdrop Paint subtable.'), diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index c4208a55f..7f42921d7 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -1334,9 +1334,10 @@ class Paint(getFormatSwitchingBaseTableClass("uint8")): PaintGlyph = 5 PaintColrGlyph = 6 PaintTransform = 7 - PaintRotate = 8 - PaintSkew = 9 - PaintComposite = 10 + PaintTranslate = 8 + PaintRotate = 9 + PaintSkew = 10 + PaintComposite = 11 def getFormatName(self): try: diff --git a/Tests/colorLib/builder_test.py b/Tests/colorLib/builder_test.py index 152e16e08..d1e94df93 100644 --- a/Tests/colorLib/builder_test.py +++ b/Tests/colorLib/builder_test.py @@ -544,7 +544,7 @@ def test_buildPaintComposite(): composite = layerBuilder.buildPaintComposite( mode=ot.CompositeMode.SRC_OVER, source={ - "format": 10, + "format": 11, "mode": "src_over", "source": {"format": 5, "glyph": "c", "paint": 2}, "backdrop": {"format": 5, "glyph": "b", "paint": 1}, @@ -574,6 +574,22 @@ def test_buildPaintComposite(): assert composite.BackdropPaint.Paint.Color.PaletteIndex == 0 +def test_buildPaintTranslate(): + layerBuilder = LayerV1ListBuilder() + paint = layerBuilder.buildPaintTranslate( + paint=layerBuilder.buildPaintGlyph( + "a", layerBuilder.buildPaintSolid(paletteIndex=0, alpha=1.0) + ), + dx=123, + dy=-345, + ) + + assert paint.Format == ot.Paint.Format.PaintTranslate + assert paint.Paint.Format == ot.Paint.Format.PaintGlyph + assert paint.dx.value == 123 + assert paint.dy.value == -345 + + def test_buildPaintRotate(): layerBuilder = LayerV1ListBuilder() paint = layerBuilder.buildPaintRotate( @@ -592,7 +608,7 @@ def test_buildPaintRotate(): assert paint.centerY.value == 129 -def test_buildPaintRotate(): +def test_buildPaintSkew(): layerBuilder = LayerV1ListBuilder() paint = layerBuilder.buildPaintSkew( paint=layerBuilder.buildPaintGlyph( diff --git a/Tests/ttLib/tables/C_O_L_R_test.py b/Tests/ttLib/tables/C_O_L_R_test.py index 76e9e61a1..7f3f71ea2 100644 --- a/Tests/ttLib/tables/C_O_L_R_test.py +++ b/Tests/ttLib/tables/C_O_L_R_test.py @@ -131,7 +131,7 @@ COLR_V1_SAMPLE = ( (b"\x01", "BaseGlyphV1Record[0].Paint.Format (1)"), (b"\x04", "BaseGlyphV1Record[0].Paint.NumLayers (4)"), (b"\x00\x00\x00\x00", "BaseGlyphV1Record[0].Paint.FirstLayerIndex (0)"), - (b"\x0A", "BaseGlyphV1Record[1].Paint.Format (10)"), + (b"\x0B", "BaseGlyphV1Record[1].Paint.Format (11)"), (b"\x00\x00<", "Offset to SourcePaint from beginning of PaintComposite (60)"), (b"\x03", "BaseGlyphV1Record[1].Paint.CompositeMode [SRC_OVER] (3)"), (b"\x00\x00\x08", "Offset to BackdropPaint from beginning of PaintComposite (8)"), @@ -164,7 +164,7 @@ COLR_V1_SAMPLE = ( ), # PaintGlyph glyph00011 (b"\x05", "LayerV1List.Paint[0].Format (5)"), - (b"\x00\x01\x28", "Offset24 to Paint subtable from beginning of PaintGlyph (296)"), + (b"\x00\x01<", "Offset24 to Paint subtable from beginning of PaintGlyph (316)"), (b"\x00\x0b", "LayerV1List.Paint[0].Glyph (glyph00011)"), # PaintGlyph glyph00012 (b"\x05", "LayerV1List.Paint[1].Format (5)"), @@ -229,14 +229,19 @@ COLR_V1_SAMPLE = ( (b"@\x00\x00\x00\x00\x00", "ColorLine.ColorStop[1].StopOffset.value (1.0)"), (b"\x00\x07", "ColorLine.ColorStop[1].Color.PaletteIndex (7)"), (b"\x19\x9a\x00\x00\x00\x00", "ColorLine.ColorStop[1].Color.Alpha.value (0.4)"), - # PaintRotate + # PaintTranslate (b"\x08", "LayerV1List.Paint[3].Format (8)"), + (b"\x00\x00\x14", "Offset to Paint subtable from beginning of PaintTranslate (20)"), + (b"\x01\x01\x00\x00\x00\x00\x00\x00", "dx.value (257)"), + (b"\x01\x02\x00\x00\x00\x00\x00\x00", "dy.value (258)"), + # PaintRotate + (b"\x09", "LayerV1List.Paint[3].Paint.Format (9)"), (b"\x00\x00\x1c", "Offset to Paint subtable from beginning of PaintRotate (28)"), (b"\x00\x2d\x00\x00\x00\x00\x00\x00", "angle.value (45)"), (b"\x00\xff\x00\x00\x00\x00\x00\x00", "centerX.value (255)"), (b"\x01\x00\x00\x00\x00\x00\x00\x00", "centerY.value (256)"), # PaintSkew - (b"\x09", "LayerV1List.Paint[3].Format (9)"), + (b"\x0a", "LayerV1List.Paint[3].Paint.Paint.Format (10)"), (b"\x00\x00\x24", "Offset to Paint subtable from beginning of PaintSkew (36)"), (b"\xff\xf5\x00\x00\x00\x00\x00\x00", "xSkewAngle (-11)"), (b"\x00\x05\x00\x00\x00\x00\x00\x00", "ySkewAngle (5)"), @@ -291,7 +296,7 @@ COLR_V1_XML = [ " ", ' ', ' ', - ' ', + ' ', ' ', ' ', " ", @@ -398,25 +403,29 @@ COLR_V1_XML = [ " ", ' ', " ", - ' ', - ' ', - ' ', - ' ', - " ", - ' ', - ' ', - " ", + ' ', + ' ', + ' ', + ' ', + ' ', + " ", + ' ', + ' ', + " ", + " ", + ' ', " ", - ' ', + ' ', + ' ', + ' ', + ' ', " ", - ' ', - ' ', - ' ', - ' ', + ' ', + ' ', + ' ', " ", - ' ', - ' ', - ' ', + ' ', + ' ', " ", "", ]