make linear/radial gradient 'point-less', inline x0,y0,x1,y1,...

https://github.com/googlefonts/colr-gradients-spec/issues/21
This commit is contained in:
Cosimo Lupo 2020-07-02 12:11:40 +01:00
parent dea9896421
commit ac0a755d20
No known key found for this signature in database
GPG Key ID: 179A8F0895A02F4F
4 changed files with 68 additions and 117 deletions

View File

@ -35,7 +35,6 @@ _ColorStopsList = Sequence[_ColorStopInput]
_ExtendInput = Union[int, str, ExtendMode]
_ColorLineInput = Union[_Kwargs, ot.ColorLine]
_PointTuple = Tuple[_ScalarInput, _ScalarInput]
_PointInput = Union[_PointTuple, ot.Point]
_AffineTuple = Tuple[_ScalarInput, _ScalarInput, _ScalarInput, _ScalarInput]
_AffineInput = Union[_AffineTuple, ot.Affine2x2]
@ -380,20 +379,6 @@ def buildColorLine(
return self
def buildPoint(x: _ScalarInput, y: _ScalarInput) -> ot.Point:
self = ot.Point()
# positions are encoded as Int16 so round to int
self.x = _to_variable_int(x)
self.y = _to_variable_int(y)
return self
def _to_variable_point(pt: _PointInput) -> ot.Point:
if isinstance(pt, ot.Point):
return pt
return buildPoint(*pt)
def _to_color_line(obj):
if isinstance(obj, ot.ColorLine):
return obj
@ -404,9 +389,9 @@ def _to_color_line(obj):
def buildLinearGradientPaint(
colorLine: _ColorLineInput,
p0: _PointInput,
p1: _PointInput,
p2: Optional[_PointInput] = None,
p0: _PointTuple,
p1: _PointTuple,
p2: Optional[_PointTuple] = None,
) -> ot.Paint:
self = ot.Paint()
self.Format = 2
@ -414,8 +399,9 @@ def buildLinearGradientPaint(
if p2 is None:
p2 = copy.copy(p1)
for i, pt in enumerate((p0, p1, p2)):
setattr(self, f"p{i}", _to_variable_point(pt))
for i, (x, y) in enumerate((p0, p1, p2)):
setattr(self, f"x{i}", _to_variable_int(x))
setattr(self, f"y{i}", _to_variable_int(y))
return self
@ -433,8 +419,8 @@ def buildAffine2x2(
def buildRadialGradientPaint(
colorLine: _ColorLineInput,
c0: _PointInput,
c1: _PointInput,
c0: _PointTuple,
c1: _PointTuple,
r0: _ScalarInput,
r1: _ScalarInput,
affine: Optional[_AffineInput] = None,
@ -444,11 +430,9 @@ def buildRadialGradientPaint(
self.Format = 3
self.ColorLine = _to_color_line(colorLine)
for i, pt in [(0, c0), (1, c1)]:
setattr(self, f"c{i}", _to_variable_point(pt))
for i, r in [(0, r0), (1, r1)]:
# distances are encoded as UShort so we round to int
for i, (x, y), r in [(0, c0, r0), (1, c1, r1)]:
setattr(self, f"x{i}", _to_variable_int(x))
setattr(self, f"y{i}", _to_variable_int(y))
setattr(self, f"r{i}", _to_variable_int(r))
if affine is not None and not isinstance(affine, ot.Affine2x2):

View File

@ -1599,11 +1599,6 @@ otData = [
('VarFixed', 'yy', None, None, ''),
]),
('Point', [
('VarInt16', 'x', None, None, ''),
('VarInt16', 'y', None, None, ''),
]),
('ColorIndex', [
('uint16', 'PaletteIndex', None, None, 'Index value to use with a selected color palette.'),
('VarF2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved'),
@ -1628,17 +1623,22 @@ otData = [
('PaintFormat2', [
('uint16', 'PaintFormat', None, None, 'Format identifier-format = 2'),
('LOffset', 'ColorLine', None, None, 'Offset (from beginning of Paint table) to ColorLine subtable.'),
('Point', 'p0', None, None, ''),
('Point', 'p1', None, None, ''),
('Point', 'p2', None, None, 'Normal; equal to p1 in simple cases.'),
('VarInt16', 'x0', None, None, ''),
('VarInt16', 'y0', None, None, ''),
('VarInt16', 'x1', None, None, ''),
('VarInt16', 'y1', None, None, ''),
('VarInt16', 'x2', None, None, ''),
('VarInt16', 'y2', None, None, ''),
]),
('PaintFormat3', [
('uint16', 'PaintFormat', None, None, 'Format identifier-format = 3'),
('LOffset', 'ColorLine', None, None, 'Offset (from beginning of Paint table) to ColorLine subtable.'),
('Point', 'c0', None, None, ''),
('Point', 'c1', None, None, ''),
('VarInt16', 'x0', None, None, ''),
('VarInt16', 'y0', None, None, ''),
('VarUInt16', 'r0', None, None, ''),
('VarInt16', 'x1', None, None, ''),
('VarInt16', 'y1', None, None, ''),
('VarUInt16', 'r1', None, None, ''),
('LOffsetTo(Affine2x2)', 'Affine', None, None, 'Offset (from beginning of Paint table) to Affine2x2 subtable.'),
]),

View File

@ -284,28 +284,6 @@ def test_buildColorLine():
] == stops
def test_buildPoint():
pt = builder.buildPoint(0, 1)
assert pt.x == builder.VariableInt(0)
assert pt.y == builder.VariableInt(1)
pt = builder.buildPoint(
builder.VariableInt(2, varIdx=1), builder.VariableInt(3, varIdx=2)
)
assert pt.x == builder.VariableInt(2, varIdx=1)
assert pt.y == builder.VariableInt(3, varIdx=2)
# float coords are rounded
pt = builder.buildPoint(x=-2.5, y=3.5)
assert pt.x == builder.VariableInt(-2)
assert pt.y == builder.VariableInt(4)
# tuple args are cast to VariableInt namedtuple
pt = builder.buildPoint((1, 2), (3, 4))
assert pt.x == builder.VariableInt(1, varIdx=2)
assert pt.y == builder.VariableInt(3, varIdx=4)
def test_buildAffine2x2():
matrix = builder.buildAffine2x2(1.5, 0, 0.5, 2.0)
assert matrix.xx == builder.VariableFloat(1.5)
@ -321,24 +299,23 @@ def test_buildLinearGradientPaint():
builder.buildColorStop(1.0, 2, alpha=0.8),
]
color_line = builder.buildColorLine(color_stops, extend=builder.ExtendMode.REPEAT)
p0 = builder.buildPoint(x=100, y=200)
p1 = builder.buildPoint(x=150, y=250)
p0 = (builder.VariableInt(100), builder.VariableInt(200))
p1 = (builder.VariableInt(150), builder.VariableInt(250))
gradient = builder.buildLinearGradientPaint(color_line, p0, p1)
assert gradient.Format == 2
assert gradient.ColorLine == color_line
assert gradient.p0 == p0
assert gradient.p1 == p1
assert gradient.p2 == gradient.p1
assert gradient.p2 is not gradient.p1
assert (gradient.x0, gradient.y0) == p0
assert (gradient.x1, gradient.y1) == p1
assert (gradient.x2, gradient.y2) == p1
gradient = builder.buildLinearGradientPaint({"stops": color_stops}, p0, p1)
assert gradient.ColorLine.Extend == builder.ExtendMode.PAD
assert gradient.ColorLine.ColorStop == color_stops
gradient = builder.buildLinearGradientPaint(color_line, p0, p1, p2=(150, 230))
assert gradient.p2 == builder.buildPoint(x=150, y=230)
assert gradient.p2 != gradient.p1
assert (gradient.x2.value, gradient.y2.value) == (150, 230)
assert (gradient.x2, gradient.y2) != (gradient.x1, gradient.y1)
def test_buildRadialGradientPaint():
@ -348,16 +325,16 @@ def test_buildRadialGradientPaint():
builder.buildColorStop(1.0, 2, alpha=0.8),
]
color_line = builder.buildColorLine(color_stops, extend=builder.ExtendMode.REPEAT)
c0 = builder.buildPoint(x=100, y=200)
c1 = builder.buildPoint(x=150, y=250)
c0 = (builder.VariableInt(100), builder.VariableInt(200))
c1 = (builder.VariableInt(150), builder.VariableInt(250))
r0 = builder.VariableInt(10)
r1 = builder.VariableInt(5)
gradient = builder.buildRadialGradientPaint(color_line, c0, c1, r0, r1)
assert gradient.Format == 3
assert gradient.ColorLine == color_line
assert gradient.c0 == c0
assert gradient.c1 == c1
assert (gradient.x0, gradient.y0) == c0
assert (gradient.x1, gradient.y1) == c1
assert gradient.r0 == r0
assert gradient.r1 == r1
assert gradient.Affine is None
@ -400,10 +377,10 @@ def test_buildLayerV1Record():
assert layer.Paint.ColorLine.ColorStop[0].Color.PaletteIndex == 3
assert layer.Paint.ColorLine.ColorStop[1].StopOffset.value == 1.0
assert layer.Paint.ColorLine.ColorStop[1].Color.PaletteIndex == 4
assert layer.Paint.p0.x.value == 100
assert layer.Paint.p0.y.value == 200
assert layer.Paint.p1.x.value == 150
assert layer.Paint.p1.y.value == 250
assert layer.Paint.x0.value == 100
assert layer.Paint.y0.value == 200
assert layer.Paint.x1.value == 150
assert layer.Paint.y1.value == 250
layer = builder.buildLayerV1Record(
"a",
@ -429,11 +406,11 @@ def test_buildLayerV1Record():
assert layer.Paint.ColorLine.ColorStop[1].Color.Alpha.value == 0.8
assert layer.Paint.ColorLine.ColorStop[2].StopOffset.value == 1.0
assert layer.Paint.ColorLine.ColorStop[2].Color.PaletteIndex == 7
assert layer.Paint.c0.x.value == 50
assert layer.Paint.c0.y.value == 50
assert layer.Paint.c1.x.value == 75
assert layer.Paint.c1.y.value == 75
assert layer.Paint.x0.value == 50
assert layer.Paint.y0.value == 50
assert layer.Paint.r0.value == 30
assert layer.Paint.x1.value == 75
assert layer.Paint.y1.value == 75
assert layer.Paint.r1.value == 10

View File

@ -98,18 +98,18 @@ COLR_V1_DATA = (
b"\x00\x00\x00\x00" # Paint.Color.Alpha.varIdx (0)
b"\x00\x02" # Paint.Format (2)
b"\x00\x00\x00*" # Offset to ColorLine from beginning of Paint (42)
b"\x00\x01" # Paint.p0.x.value (1)
b"\x00\x00\x00\x00" # Paint.p0.x.varIdx (0)
b"\x00\x02" # Paint.p0.y.value (2)
b"\x00\x00\x00\x00" # Paint.p0.y.varIdx (0)
b"\xff\xfd" # Paint.p1.x.value (-3)
b"\x00\x00\x00\x00" # Paint.p1.x.varIdx (0)
b"\xff\xfc" # Paint.p1.y.value (-4)
b"\x00\x00\x00\x00" # Paint.p1.y.varIdx (0)
b"\x00\x05" # Paint.p2.x.value (5)
b"\x00\x00\x00\x00" # Paint.p2.y.varIdx (0)
b"\x00\x06" # Paint.p2.y.value (5)
b"\x00\x00\x00\x00" # Paint.p2.y.varIdx (0)
b"\x00\x01" # Paint.x0.value (1)
b"\x00\x00\x00\x00" # Paint.x0.varIdx (0)
b"\x00\x02" # Paint.y0.value (2)
b"\x00\x00\x00\x00" # Paint.y0.varIdx (0)
b"\xff\xfd" # Paint.x1.value (-3)
b"\x00\x00\x00\x00" # Paint.x1.varIdx (0)
b"\xff\xfc" # Paint.y1.value (-4)
b"\x00\x00\x00\x00" # Paint.y1.varIdx (0)
b"\x00\x05" # Paint.x2.value (5)
b"\x00\x00\x00\x00" # Paint.x2.varIdx (0)
b"\x00\x06" # Paint.y2.value (5)
b"\x00\x00\x00\x00" # Paint.y2.varIdx (0)
b"\x00\x01" # ColorLine.Extend (1 or "repeat")
b"\x00\x03" # ColorLine.StopCount (3)
b"\x00\x00" # ColorLine.ColorStop[0].StopOffset.value (0.0)
@ -129,15 +129,15 @@ COLR_V1_DATA = (
b"\x00\x00\x00\x00" # ColorLine.ColorStop[2].Color.Alpha.varIdx (0)
b"\x00\x03" # Paint.Format (3)
b"\x00\x00\x00." # Offset to ColorLine from beginning of Paint (46)
b"\x00\x07" # Paint.c0.x.value (7)
b"\x00\x07" # Paint.x0.value (7)
b"\x00\x00\x00\x00"
b"\x00\x08" # Paint.c0.y.value (8)
b"\x00\x08" # Paint.y0.value (8)
b"\x00\x00\x00\x00"
b"\x00\t" # Paint.c1.x.value (9)
b"\x00\t" # Paint.r0.value (9)
b"\x00\x00\x00\x00"
b"\x00\n" # Paint.c1.y.value (10)
b"\x00\n" # Paint.x1.value (10)
b"\x00\x00\x00\x00"
b"\x00\x0b" # Paint.r0.value (11)
b"\x00\x0b" # Paint.y1.value (11)
b"\x00\x00\x00\x00"
b"\x00\x0c" # Paint.r1.value (12)
b"\x00\x00\x00\x00"
@ -233,18 +233,12 @@ COLR_V1_XML = [
" </Color>",
" </ColorStop>",
" </ColorLine>",
" <p0>",
' <x value="1"/>',
' <y value="2"/>',
" </p0>",
" <p1>",
' <x value="-3"/>',
' <y value="-4"/>',
" </p1>",
" <p2>",
' <x value="5"/>',
' <y value="6"/>',
" </p2>",
' <x0 value="1"/>',
' <y0 value="2"/>',
' <x1 value="-3"/>',
' <y1 value="-4"/>',
' <x2 value="5"/>',
' <y2 value="6"/>',
" </Paint>",
" </LayerV1Record>",
' <LayerV1Record index="2">',
@ -268,15 +262,11 @@ COLR_V1_XML = [
" </Color>",
" </ColorStop>",
" </ColorLine>",
" <c0>",
' <x value="7"/>',
' <y value="8"/>',
" </c0>",
" <c1>",
' <x value="9"/>',
' <y value="10"/>',
" </c1>",
' <r0 value="11"/>',
' <x0 value="7"/>',
' <y0 value="8"/>',
' <r0 value="9"/>',
' <x1 value="10"/>',
' <y1 value="11"/>',
' <r1 value="12"/>',
" <Affine>",
' <xx value="-13.0"/>',