From 971bcbff6f55b2478f22f775be9a7657b899d06c Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Thu, 12 Mar 2020 16:03:11 +0000 Subject: [PATCH] colorLib: allow color stops to be built from list of dicts as well as tuples --- Lib/fontTools/colorLib/builder.py | 24 +++++++-------- Tests/colorLib/builder_test.py | 51 ++++++++++++++----------------- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/Lib/fontTools/colorLib/builder.py b/Lib/fontTools/colorLib/builder.py index 499c54613..9fe7f203b 100644 --- a/Lib/fontTools/colorLib/builder.py +++ b/Lib/fontTools/colorLib/builder.py @@ -25,9 +25,9 @@ _ColorGlyphsDict = Dict[str, _LayersList] _ColorGlyphsV0Dict = Dict[str, Sequence[Tuple[str, int]]] _Number = Union[int, float] _ScalarInput = Union[_Number, VariableValue, Tuple[_Number, int]] -_ColorInput = Union[int, _Kwargs, ot.Color] -_ColorStopTuple = Tuple[_ScalarInput, _ColorInput] -_ColorStopsList = Sequence[Union[_ColorStopTuple, ot.ColorStop]] +_ColorStopTuple = Tuple[_ScalarInput, int] +_ColorStopInput = Union[_ColorStopTuple, _Kwargs, ot.ColorStop] +_ColorStopsList = Sequence[_ColorStopInput] _ExtendInput = Union[int, str, ExtendMode] _ColorLineInput = Union[_Kwargs, ot.ColorLine] _PointTuple = Tuple[_ScalarInput, _ScalarInput] @@ -337,16 +337,14 @@ def buildSolidColorPaint( return self -def buildColorStop(offset: _ScalarInput, color: _ColorInput) -> ot.ColorStop: +def buildColorStop( + offset: _ScalarInput, + paletteIndex: int, + transparency: _ScalarInput = _DEFAULT_TRANSPARENCY, +) -> ot.ColorStop: self = ot.ColorStop() self.StopOffset = _to_variable_float(offset) - - if isinstance(color, int): - color = buildColor(paletteIndex=color) - elif not isinstance(color, ot.Color): - color = buildColor(**color) - self.Color = color - + self.Color = buildColor(paletteIndex, transparency) return self @@ -370,7 +368,9 @@ def buildColorLine( self.ColorStop = [ stop if isinstance(stop, ot.ColorStop) - else buildColorStop(offset=stop[0], color=stop[1]) + else buildColorStop(**stop) + if isinstance(stop, collections.abc.Mapping) + else buildColorStop(*stop) for stop in stops ] return self diff --git a/Tests/colorLib/builder_test.py b/Tests/colorLib/builder_test.py index a6261c6fd..24cac8bec 100644 --- a/Tests/colorLib/builder_test.py +++ b/Tests/colorLib/builder_test.py @@ -228,20 +228,19 @@ def test_buildSolidColorPaint(): def test_buildColorStop(): - s = builder.buildColorStop(offset=0.1, color=2) + s = builder.buildColorStop(0.1, 2) assert s.StopOffset == builder.VariableFloat(0.1) assert s.Color.PaletteIndex == 2 assert s.Color.Transparency == builder._DEFAULT_TRANSPARENCY - c = builder.buildColor(3, transparency=0.4) - s = builder.buildColorStop(offset=0.2, color=c) + s = builder.buildColorStop(offset=0.2, paletteIndex=3, transparency=0.4) assert s.StopOffset == builder.VariableFloat(0.2) - assert s.Color.PaletteIndex == 3 - assert s.Color.Transparency == builder.VariableFloat(0.4) + assert s.Color == builder.buildColor(3, transparency=0.4) s = builder.buildColorStop( offset=builder.VariableFloat(0.0, varIdx=1), - color=builder.buildColor(0, transparency=builder.VariableFloat(0.3, varIdx=2)), + paletteIndex=0, + transparency=builder.VariableFloat(0.3, varIdx=2), ) assert s.StopOffset == builder.VariableFloat(0.0, varIdx=1) assert s.Color.PaletteIndex == 0 @@ -267,26 +266,22 @@ def test_buildColorLine(): cline = builder.buildColorLine(stops, extend=builder.ExtendMode.REFLECT) assert cline.Extend == builder.ExtendMode.REFLECT - cline = builder.buildColorLine( - [builder.buildColorStop(offset=s[0], color=s[1]) for s in stops] - ) + cline = builder.buildColorLine([builder.buildColorStop(*s) for s in stops]) assert [ (cs.StopOffset.value, cs.Color.PaletteIndex) for cs in cline.ColorStop ] == stops stops = [ - ((0.0, 1), {"paletteIndex": 0, "transparency": (0.5, 2)}), - ((1.0, 3), {"paletteIndex": 1, "transparency": (0.3, 4)}), + {"offset": (0.0, 1), "paletteIndex": 0, "transparency": (0.5, 2)}, + {"offset": (1.0, 3), "paletteIndex": 1, "transparency": (0.3, 4)}, ] cline = builder.buildColorLine(stops) assert [ - ( - cs.StopOffset, - { - "paletteIndex": cs.Color.PaletteIndex, - "transparency": cs.Color.Transparency, - }, - ) + { + "offset": cs.StopOffset, + "paletteIndex": cs.Color.PaletteIndex, + "transparency": cs.Color.Transparency, + } for cs in cline.ColorStop ] == stops @@ -323,9 +318,9 @@ def test_buildAffine2x2(): def test_buildLinearGradientPaint(): color_stops = [ - builder.buildColorStop(0.0, builder.buildColor(0)), - builder.buildColorStop(0.5, builder.buildColor(1)), - builder.buildColorStop(1.0, builder.buildColor(2, transparency=0.8)), + builder.buildColorStop(0.0, 0), + builder.buildColorStop(0.5, 1), + builder.buildColorStop(1.0, 2, transparency=0.8), ] color_line = builder.buildColorLine(color_stops, extend=builder.ExtendMode.REPEAT) p0 = builder.buildPoint(x=100, y=200) @@ -350,9 +345,9 @@ def test_buildLinearGradientPaint(): def test_buildRadialGradientPaint(): color_stops = [ - builder.buildColorStop(0.0, builder.buildColor(0)), - builder.buildColorStop(0.5, builder.buildColor(1)), - builder.buildColorStop(1.0, builder.buildColor(2, transparency=0.8)), + builder.buildColorStop(0.0, 0), + builder.buildColorStop(0.5, 1), + builder.buildColorStop(1.0, 2, transparency=0.8), ] color_line = builder.buildColorLine(color_stops, extend=builder.ExtendMode.REPEAT) c0 = builder.buildPoint(x=100, y=200) @@ -418,7 +413,7 @@ def test_buildLayerV1Record(): { "stops": [ (0.0, 5), - (0.5, {"paletteIndex": 6, "transparency": 0.8}), + {"offset": 0.5, "paletteIndex": 6, "transparency": 0.8}, (1.0, 7), ] }, @@ -496,9 +491,9 @@ def test_buildLayerV1Array(): "format": 3, "colorLine": { "stops": [ - (0.0, 5), - (0.5, {"paletteIndex": 6, "transparency": 0.8}), - (1.0, 7), + {"offset": 0.0, "paletteIndex": 5}, + {"offset": 0.5, "paletteIndex": 6, "transparency": 0.8}, + {"offset": 1.0, "paletteIndex": 7}, ] }, "c0": (50, 50),