aboutsummaryrefslogtreecommitdiff
path: root/Tests/colorLib/builder_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/colorLib/builder_test.py')
-rw-r--r--Tests/colorLib/builder_test.py850
1 files changed, 523 insertions, 327 deletions
diff --git a/Tests/colorLib/builder_test.py b/Tests/colorLib/builder_test.py
index 81da2818..7259db4d 100644
--- a/Tests/colorLib/builder_test.py
+++ b/Tests/colorLib/builder_test.py
@@ -1,8 +1,9 @@
+from copy import deepcopy
from fontTools.ttLib import newTable
from fontTools.ttLib.tables import otTables as ot
from fontTools.colorLib import builder
from fontTools.colorLib.geometry import round_start_circle_stable_containment, Circle
-from fontTools.colorLib.builder import LayerV1ListBuilder, _build_n_ary_tree
+from fontTools.colorLib.builder import LayerListBuilder, _build_n_ary_tree
from fontTools.colorLib.table_builder import TableBuilder
from fontTools.colorLib.errors import ColorLibError
import pytest
@@ -10,11 +11,11 @@ from typing import List
def _build(cls, source):
- return LayerV1ListBuilder().tableBuilder.build(cls, source)
+ return LayerListBuilder().tableBuilder.build(cls, source)
def _buildPaint(source):
- return LayerV1ListBuilder().buildPaint(source)
+ return LayerListBuilder().buildPaint(source)
def test_buildCOLR_v0():
@@ -231,92 +232,63 @@ def test_buildCPAL_invalid_color():
builder.buildCPAL([[(0, 0, 0, 0)], [(1, 1, -1, 2)]])
-def test_buildColorIndex_Minimal():
- c = _build(ot.ColorIndex, 1)
- assert c.PaletteIndex == 1
- assert c.Alpha == 1.0
-
-
-def test_buildVarColorIndex_Minimal():
- c = _build(ot.VarColorIndex, 1)
- assert c.PaletteIndex == 1
- assert c.Alpha.value == 1.0
- assert c.Alpha.varIdx == 0
-
-
-def test_buildColorIndex():
- c = _build(ot.ColorIndex, (1, 0.5))
- assert c.PaletteIndex == 1
- assert c.Alpha == 0.5
-
-
-def test_buildVarColorIndex():
- c = _build(ot.VarColorIndex, (3, builder.VariableFloat(0.5, varIdx=2)))
- assert c.PaletteIndex == 3
- assert c.Alpha.value == 0.5
- assert c.Alpha.varIdx == 2
-
-
def test_buildPaintSolid():
p = _buildPaint((ot.PaintFormat.PaintSolid, 0))
assert p.Format == ot.PaintFormat.PaintSolid
- assert p.Color.PaletteIndex == 0
- assert p.Color.Alpha == 1.0
+ assert p.PaletteIndex == 0
+ assert p.Alpha == 1.0
def test_buildPaintSolid_Alpha():
- p = _buildPaint((ot.PaintFormat.PaintSolid, (1, 0.5)))
+ p = _buildPaint((ot.PaintFormat.PaintSolid, 1, 0.5))
assert p.Format == ot.PaintFormat.PaintSolid
- assert p.Color.PaletteIndex == 1
- assert p.Color.Alpha == 0.5
+ assert p.PaletteIndex == 1
+ assert p.Alpha == 0.5
def test_buildPaintVarSolid():
- p = _buildPaint(
- (ot.PaintFormat.PaintVarSolid, (3, builder.VariableFloat(0.5, varIdx=2)))
- )
+ p = _buildPaint((ot.PaintFormat.PaintVarSolid, 3, 0.5, 2))
assert p.Format == ot.PaintFormat.PaintVarSolid
- assert p.Color.PaletteIndex == 3
- assert p.Color.Alpha.value == 0.5
- assert p.Color.Alpha.varIdx == 2
+ assert p.PaletteIndex == 3
+ assert p.Alpha == 0.5
+ assert p.VarIndexBase == 2
def test_buildVarColorStop_DefaultAlpha():
s = _build(ot.ColorStop, (0.1, 2))
assert s.StopOffset == 0.1
- assert s.Color.PaletteIndex == 2
- assert s.Color.Alpha == builder._DEFAULT_ALPHA.value
+ assert s.PaletteIndex == 2
+ assert s.Alpha == builder._DEFAULT_ALPHA
def test_buildVarColorStop_DefaultAlpha():
s = _build(ot.VarColorStop, (0.1, 2))
- assert s.StopOffset == builder.VariableFloat(0.1)
- assert s.Color.PaletteIndex == 2
- assert s.Color.Alpha == builder._DEFAULT_ALPHA
+ assert s.StopOffset == 0.1
+ assert s.PaletteIndex == 2
+ assert s.Alpha == builder._DEFAULT_ALPHA
def test_buildColorStop():
- s = _build(
- ot.ColorStop, {"StopOffset": 0.2, "Color": {"PaletteIndex": 3, "Alpha": 0.4}}
- )
+ s = _build(ot.ColorStop, {"StopOffset": 0.2, "PaletteIndex": 3, "Alpha": 0.4})
assert s.StopOffset == 0.2
- assert s.Color == _build(ot.ColorIndex, (3, 0.4))
+ assert s.PaletteIndex == 3
+ assert s.Alpha == 0.4
def test_buildColorStop_Variable():
s = _build(
ot.VarColorStop,
{
- "StopOffset": builder.VariableFloat(0.0, varIdx=1),
- "Color": {
- "PaletteIndex": 0,
- "Alpha": builder.VariableFloat(0.3, varIdx=2),
- },
+ "StopOffset": 0.0,
+ "PaletteIndex": 0,
+ "Alpha": 0.3,
+ "VarIndexBase": 1,
},
)
- assert s.StopOffset == builder.VariableFloat(0.0, varIdx=1)
- assert s.Color.PaletteIndex == 0
- assert s.Color.Alpha == builder.VariableFloat(0.3, varIdx=2)
+ assert s.StopOffset == 0.0
+ assert s.PaletteIndex == 0
+ assert s.Alpha == 0.3
+ assert s.VarIndexBase == 1
def test_buildColorLine_StopList():
@@ -325,7 +297,7 @@ def test_buildColorLine_StopList():
cline = _build(ot.ColorLine, {"ColorStop": stops})
assert cline.Extend == builder.ExtendMode.PAD
assert cline.StopCount == 3
- assert [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
+ assert [(cs.StopOffset, cs.PaletteIndex) for cs in cline.ColorStop] == stops
cline = _build(ot.ColorLine, {"Extend": "pad", "ColorStop": stops})
assert cline.Extend == builder.ExtendMode.PAD
@@ -343,86 +315,98 @@ def test_buildColorLine_StopList():
cline = _build(
ot.ColorLine, {"ColorStop": [_build(ot.ColorStop, s) for s in stops]}
)
- assert [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
+ assert [(cs.StopOffset, cs.PaletteIndex) for cs in cline.ColorStop] == stops
def test_buildVarColorLine_StopMap():
stops = [
- {"StopOffset": (0.0, (1,)), "Color": {"PaletteIndex": 0, "Alpha": (0.5, 2)}},
- {"StopOffset": (1.0, (3,)), "Color": {"PaletteIndex": 1, "Alpha": (0.3, 4)}},
+ {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 0.5, "VarIndexBase": 1},
+ {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 0.3, "VarIndexBase": 3},
]
cline = _build(ot.VarColorLine, {"ColorStop": stops})
assert [
{
"StopOffset": cs.StopOffset,
- "Color": {
- "PaletteIndex": cs.Color.PaletteIndex,
- "Alpha": cs.Color.Alpha,
- },
+ "PaletteIndex": cs.PaletteIndex,
+ "Alpha": cs.Alpha,
+ "VarIndexBase": cs.VarIndexBase,
}
for cs in cline.ColorStop
] == stops
-def checkBuildAffine2x3(cls, resultMapFn):
+def checkBuildAffine2x3(cls, variable=False):
matrix = _build(cls, (1.5, 0, 0.5, 2.0, 1.0, -3.0))
- assert matrix.xx == resultMapFn(1.5)
- assert matrix.yx == resultMapFn(0.0)
- assert matrix.xy == resultMapFn(0.5)
- assert matrix.yy == resultMapFn(2.0)
- assert matrix.dx == resultMapFn(1.0)
- assert matrix.dy == resultMapFn(-3.0)
+ assert matrix.xx == 1.5
+ assert matrix.yx == 0.0
+ assert matrix.xy == 0.5
+ assert matrix.yy == 2.0
+ assert matrix.dx == 1.0
+ assert matrix.dy == -3.0
+ if variable:
+ assert matrix.VarIndexBase == 0xFFFFFFFF
def test_buildAffine2x3():
- checkBuildAffine2x3(ot.Affine2x3, lambda v: v)
+ checkBuildAffine2x3(ot.Affine2x3)
def test_buildVarAffine2x3():
- checkBuildAffine2x3(ot.VarAffine2x3, builder.VariableFloat)
+ checkBuildAffine2x3(ot.VarAffine2x3, variable=True)
-def _sample_stops(cls):
- return [
- _build(cls, (0.0, 0)),
- _build(cls, (0.5, 1)),
- _build(cls, (1.0, (2, 0.8))),
+def _sample_stops(variable):
+ cls = ot.ColorStop if not variable else ot.VarColorStop
+ stop_sources = [
+ {"StopOffset": 0.0, "PaletteIndex": 0},
+ {"StopOffset": 0.5, "PaletteIndex": 1},
+ {"StopOffset": 1.0, "PaletteIndex": 2, "Alpha": 0.8},
]
+ if variable:
+ for i, src in enumerate(stop_sources, start=123):
+ src["VarIndexBase"] = i
+ return [_build(cls, src) for src in stop_sources]
def _is_var(fmt):
return fmt.name.startswith("PaintVar")
-def checkBuildPaintLinearGradient(fmt):
- if _is_var(fmt):
- inputMapFn = builder.VariableInt
- outputMapFn = lambda v: v.value
- color_stops = _sample_stops(ot.VarColorStop)
- else:
- inputMapFn = outputMapFn = lambda v: v
- color_stops = _sample_stops(ot.ColorStop)
+def _is_around_center(fmt):
+ return fmt.name.endswith("AroundCenter")
- x0, y0, x1, y1, x2, y2 = tuple(inputMapFn(v) for v in (1, 2, 3, 4, 5, 6))
- gradient = _buildPaint(
- {
- "Format": fmt,
- "ColorLine": {"ColorStop": color_stops},
- "x0": x0,
- "y0": y0,
- "x1": x1,
- "y1": y1,
- "x2": x2,
- "y2": y2,
- },
- )
+
+def _is_uniform_scale(fmt):
+ return "ScaleUniform" in fmt.name
+
+
+def checkBuildPaintLinearGradient(fmt):
+ variable = _is_var(fmt)
+ color_stops = _sample_stops(variable)
+
+ x0, y0, x1, y1, x2, y2 = (1, 2, 3, 4, 5, 6)
+ source = {
+ "Format": fmt,
+ "ColorLine": {"ColorStop": color_stops},
+ "x0": x0,
+ "y0": y0,
+ "x1": x1,
+ "y1": y1,
+ "x2": x2,
+ "y2": y2,
+ }
+ if variable:
+ source["VarIndexBase"] = 7
+ gradient = _buildPaint(source)
assert gradient.ColorLine.Extend == builder.ExtendMode.PAD
assert gradient.ColorLine.ColorStop == color_stops
gradient = _buildPaint(gradient)
- assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == (1, 2)
- assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == (3, 4)
- assert (outputMapFn(gradient.x2), outputMapFn(gradient.y2)) == (5, 6)
+ assert (gradient.x0, gradient.y0) == (1, 2)
+ assert (gradient.x1, gradient.y1) == (3, 4)
+ assert (gradient.x2, gradient.y2) == (5, 6)
+ if variable:
+ assert gradient.VarIndexBase == 7
def test_buildPaintLinearGradient():
@@ -430,57 +414,60 @@ def test_buildPaintLinearGradient():
checkBuildPaintLinearGradient(ot.PaintFormat.PaintLinearGradient)
-def test_buildVarPaintLinearGradient():
+def test_buildPaintVarLinearGradient():
assert _is_var(ot.PaintFormat.PaintVarLinearGradient)
checkBuildPaintLinearGradient(ot.PaintFormat.PaintVarLinearGradient)
def checkBuildPaintRadialGradient(fmt):
- if _is_var(fmt):
- inputMapFn = builder.VariableInt
- outputMapFn = lambda v: v
- color_stops = _sample_stops(ot.VarColorStop)
- line_cls = ot.VarColorLine
- else:
- inputMapFn = outputMapFn = lambda v: v
- color_stops = _sample_stops(ot.ColorStop)
- line_cls = ot.ColorLine
+ variable = _is_var(fmt)
+ color_stops = _sample_stops(variable)
+ line_cls = ot.VarColorLine if variable else ot.ColorLine
color_line = _build(
line_cls, {"ColorStop": color_stops, "Extend": builder.ExtendMode.REPEAT}
)
- c0 = (inputMapFn(100), inputMapFn(200))
- c1 = (inputMapFn(150), inputMapFn(250))
- r0 = inputMapFn(10)
- r1 = inputMapFn(5)
+ c0 = (100, 200)
+ c1 = (150, 250)
+ r0 = 10
+ r1 = 5
+ varIndexBase = 0
+
+ source = [fmt, color_line, *c0, r0, *c1, r1]
+ if variable:
+ source.append(varIndexBase)
- gradient = _build(ot.Paint, (fmt, color_line, *c0, r0, *c1, r1))
+ gradient = _build(ot.Paint, tuple(source))
assert gradient.Format == fmt
assert gradient.ColorLine == color_line
- assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == c0
- assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == c1
- assert outputMapFn(gradient.r0) == r0
- assert outputMapFn(gradient.r1) == r1
-
- gradient = _build(
- ot.Paint,
- {
- "Format": fmt,
- "ColorLine": {"ColorStop": color_stops},
- "x0": c0[0],
- "y0": c0[1],
- "x1": c1[0],
- "y1": c1[1],
- "r0": r0,
- "r1": r1,
- },
- )
+ assert (gradient.x0, gradient.y0) == c0
+ assert (gradient.x1, gradient.y1) == c1
+ assert gradient.r0 == r0
+ assert gradient.r1 == r1
+ if variable:
+ assert gradient.VarIndexBase == varIndexBase
+
+ source = {
+ "Format": fmt,
+ "ColorLine": {"ColorStop": color_stops},
+ "x0": c0[0],
+ "y0": c0[1],
+ "x1": c1[0],
+ "y1": c1[1],
+ "r0": r0,
+ "r1": r1,
+ }
+ if variable:
+ source["VarIndexBase"] = varIndexBase
+ gradient = _build(ot.Paint, source)
assert gradient.ColorLine.Extend == builder.ExtendMode.PAD
assert gradient.ColorLine.ColorStop == color_stops
- assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == c0
- assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == c1
- assert outputMapFn(gradient.r0) == r0
- assert outputMapFn(gradient.r1) == r1
+ assert (gradient.x0, gradient.y0) == c0
+ assert (gradient.x1, gradient.y1) == c1
+ assert gradient.r0 == r0
+ assert gradient.r1 == r1
+ if variable:
+ assert gradient.VarIndexBase == varIndexBase
def test_buildPaintRadialGradient():
@@ -494,33 +481,26 @@ def test_buildPaintVarRadialGradient():
def checkPaintSweepGradient(fmt):
- if _is_var(fmt):
- outputMapFn = lambda v: v.value
- else:
- outputMapFn = lambda v: v
-
- paint = _buildPaint(
- {
- "Format": fmt,
- "ColorLine": {
- "ColorStop": (
- (0.0, 0),
- (0.5, 1),
- (1.0, (2, 0.8)),
- )
- },
- "centerX": 127,
- "centerY": 129,
- "startAngle": 15,
- "endAngle": 42,
- }
- )
+ variable = _is_var(fmt)
+ source = {
+ "Format": fmt,
+ "ColorLine": {"ColorStop": _sample_stops(variable)},
+ "centerX": 127,
+ "centerY": 129,
+ "startAngle": 15,
+ "endAngle": 42,
+ }
+ if variable:
+ source["VarIndexBase"] = 666
+ paint = _buildPaint(source)
assert paint.Format == fmt
- assert outputMapFn(paint.centerX) == 127
- assert outputMapFn(paint.centerY) == 129
- assert outputMapFn(paint.startAngle) == 15
- assert outputMapFn(paint.endAngle) == 42
+ assert paint.centerX == 127
+ assert paint.centerY == 129
+ assert paint.startAngle == 15
+ assert paint.endAngle == 42
+ if variable:
+ assert paint.VarIndexBase == 666
def test_buildPaintSweepGradient():
@@ -548,22 +528,19 @@ def test_buildPaintGlyph_Solid():
assert layer.Format == ot.PaintFormat.PaintGlyph
assert layer.Glyph == "a"
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
- assert layer.Paint.Color.PaletteIndex == 2
+ assert layer.Paint.PaletteIndex == 2
layer = _build(
ot.Paint,
(
ot.PaintFormat.PaintGlyph,
- (
- ot.PaintFormat.PaintSolid,
- (3, 0.9),
- ),
+ (ot.PaintFormat.PaintSolid, 3, 0.9),
"a",
),
)
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
- assert layer.Paint.Color.PaletteIndex == 3
- assert layer.Paint.Color.Alpha == 0.9
+ assert layer.Paint.PaletteIndex == 3
+ assert layer.Paint.Alpha == 0.9
def test_buildPaintGlyph_VarLinearGradient():
@@ -586,14 +563,14 @@ def test_buildPaintGlyph_VarLinearGradient():
assert layer.Format == ot.PaintFormat.PaintGlyph
assert layer.Glyph == "a"
assert layer.Paint.Format == ot.PaintFormat.PaintVarLinearGradient
- assert layer.Paint.ColorLine.ColorStop[0].StopOffset.value == 0.0
- 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.x0.value == 100
- assert layer.Paint.y0.value == 200
- assert layer.Paint.x1.value == 150
- assert layer.Paint.y1.value == 250
+ assert layer.Paint.ColorLine.ColorStop[0].StopOffset == 0.0
+ assert layer.Paint.ColorLine.ColorStop[0].PaletteIndex == 3
+ assert layer.Paint.ColorLine.ColorStop[1].StopOffset == 1.0
+ assert layer.Paint.ColorLine.ColorStop[1].PaletteIndex == 4
+ assert layer.Paint.x0 == 100
+ assert layer.Paint.y0 == 200
+ assert layer.Paint.x1 == 150
+ assert layer.Paint.y1 == 250
def test_buildPaintGlyph_RadialGradient():
@@ -607,7 +584,7 @@ def test_buildPaintGlyph_RadialGradient():
"pad",
[
(0.0, 5),
- {"StopOffset": 0.5, "Color": {"PaletteIndex": 6, "Alpha": 0.8}},
+ {"StopOffset": 0.5, "PaletteIndex": 6, "Alpha": 0.8},
(1.0, 7),
],
),
@@ -624,12 +601,12 @@ def test_buildPaintGlyph_RadialGradient():
assert layer.Format == ot.PaintFormat.PaintGlyph
assert layer.Paint.Format == ot.PaintFormat.PaintRadialGradient
assert layer.Paint.ColorLine.ColorStop[0].StopOffset == 0.0
- assert layer.Paint.ColorLine.ColorStop[0].Color.PaletteIndex == 5
+ assert layer.Paint.ColorLine.ColorStop[0].PaletteIndex == 5
assert layer.Paint.ColorLine.ColorStop[1].StopOffset == 0.5
- assert layer.Paint.ColorLine.ColorStop[1].Color.PaletteIndex == 6
- assert layer.Paint.ColorLine.ColorStop[1].Color.Alpha == 0.8
+ assert layer.Paint.ColorLine.ColorStop[1].PaletteIndex == 6
+ assert layer.Paint.ColorLine.ColorStop[1].Alpha == 0.8
assert layer.Paint.ColorLine.ColorStop[2].StopOffset == 1.0
- assert layer.Paint.ColorLine.ColorStop[2].Color.PaletteIndex == 7
+ assert layer.Paint.ColorLine.ColorStop[2].PaletteIndex == 7
assert layer.Paint.x0 == 50
assert layer.Paint.y0 == 50
assert layer.Paint.r0 == 30
@@ -651,7 +628,7 @@ def test_buildPaintGlyph_Dict_Solid():
assert layer.Format == ot.PaintFormat.PaintGlyph
assert layer.Glyph == "a"
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
- assert layer.Paint.Color.PaletteIndex == 1
+ assert layer.Paint.PaletteIndex == 1
def test_buildPaintGlyph_Dict_VarLinearGradient():
@@ -673,7 +650,7 @@ def test_buildPaintGlyph_Dict_VarLinearGradient():
assert layer.Format == ot.PaintFormat.PaintGlyph
assert layer.Glyph == "a"
assert layer.Paint.Format == ot.PaintFormat.PaintVarLinearGradient
- assert layer.Paint.ColorLine.ColorStop[0].StopOffset.value == 0.0
+ assert layer.Paint.ColorLine.ColorStop[0].StopOffset == 0.0
def test_buildPaintGlyph_Dict_RadialGradient():
@@ -704,19 +681,21 @@ def test_buildPaintColrGlyph():
def checkBuildPaintTransform(fmt):
- if _is_var(fmt):
- inputMapFn = builder.VariableFloat
- outputMapFn = lambda v: v.value
+ variable = _is_var(fmt)
+ if variable:
affine_cls = ot.VarAffine2x3
else:
- inputMapFn = outputMapFn = lambda v: v
affine_cls = ot.Affine2x3
+ affine_src = [1, 2, 3, 4, 5, 6]
+ if variable:
+ affine_src.append(7)
+
paint = _buildPaint(
(
int(fmt),
- (ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, (0, 1.0)), "a"),
- _build(affine_cls, (1, 2, 3, 4, 5, 6)),
+ (ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, 0, 1.0), "a"),
+ _build(affine_cls, tuple(affine_src)),
),
)
@@ -724,18 +703,23 @@ def checkBuildPaintTransform(fmt):
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
assert paint.Paint.Paint.Format == ot.PaintFormat.PaintSolid
- assert outputMapFn(paint.Transform.xx) == 1.0
- assert outputMapFn(paint.Transform.yx) == 2.0
- assert outputMapFn(paint.Transform.xy) == 3.0
- assert outputMapFn(paint.Transform.yy) == 4.0
- assert outputMapFn(paint.Transform.dx) == 5.0
- assert outputMapFn(paint.Transform.dy) == 6.0
-
+ assert paint.Transform.xx == 1.0
+ assert paint.Transform.yx == 2.0
+ assert paint.Transform.xy == 3.0
+ assert paint.Transform.yy == 4.0
+ assert paint.Transform.dx == 5.0
+ assert paint.Transform.dy == 6.0
+ if variable:
+ assert paint.Transform.VarIndexBase == 7
+
+ affine_src = [1, 2, 3, 0.3333, 10, 10]
+ if variable:
+ affine_src.append(456) # VarIndexBase
paint = _build(
ot.Paint,
{
"Format": fmt,
- "Transform": (1, 2, 3, 0.3333, 10, 10),
+ "Transform": tuple(affine_src),
"Paint": {
"Format": int(ot.PaintFormat.PaintRadialGradient),
"ColorLine": {"ColorStop": [(0.0, 0), (1.0, 1)]},
@@ -750,12 +734,14 @@ def checkBuildPaintTransform(fmt):
)
assert paint.Format == fmt
- assert outputMapFn(paint.Transform.xx) == 1.0
- assert outputMapFn(paint.Transform.yx) == 2.0
- assert outputMapFn(paint.Transform.xy) == 3.0
- assert outputMapFn(paint.Transform.yy) == 0.3333
- assert outputMapFn(paint.Transform.dx) == 10
- assert outputMapFn(paint.Transform.dy) == 10
+ assert paint.Transform.xx == 1.0
+ assert paint.Transform.yx == 2.0
+ assert paint.Transform.xy == 3.0
+ assert paint.Transform.yy == 0.3333
+ assert paint.Transform.dx == 10
+ assert paint.Transform.dy == 10
+ if variable:
+ assert paint.Transform.VarIndexBase == 456
assert paint.Paint.Format == ot.PaintFormat.PaintRadialGradient
@@ -794,7 +780,8 @@ def test_buildPaintComposite():
"Glyph": "a",
"Paint": {
"Format": ot.PaintFormat.PaintSolid,
- "Color": (0, 1.0),
+ "PaletteIndex": 0,
+ "Alpha": 0.5,
},
},
},
@@ -805,44 +792,44 @@ def test_buildPaintComposite():
assert composite.SourcePaint.SourcePaint.Format == ot.PaintFormat.PaintGlyph
assert composite.SourcePaint.SourcePaint.Glyph == "c"
assert composite.SourcePaint.SourcePaint.Paint.Format == ot.PaintFormat.PaintSolid
- assert composite.SourcePaint.SourcePaint.Paint.Color.PaletteIndex == 2
+ assert composite.SourcePaint.SourcePaint.Paint.PaletteIndex == 2
assert composite.SourcePaint.CompositeMode == ot.CompositeMode.SRC_OVER
assert composite.SourcePaint.BackdropPaint.Format == ot.PaintFormat.PaintGlyph
assert composite.SourcePaint.BackdropPaint.Glyph == "b"
assert composite.SourcePaint.BackdropPaint.Paint.Format == ot.PaintFormat.PaintSolid
- assert composite.SourcePaint.BackdropPaint.Paint.Color.PaletteIndex == 1
+ assert composite.SourcePaint.BackdropPaint.Paint.PaletteIndex == 1
assert composite.CompositeMode == ot.CompositeMode.SRC_OVER
assert composite.BackdropPaint.Format == ot.PaintFormat.PaintGlyph
assert composite.BackdropPaint.Glyph == "a"
assert composite.BackdropPaint.Paint.Format == ot.PaintFormat.PaintSolid
- assert composite.BackdropPaint.Paint.Color.PaletteIndex == 0
+ assert composite.BackdropPaint.Paint.PaletteIndex == 0
+ assert composite.BackdropPaint.Paint.Alpha == 0.5
def checkBuildPaintTranslate(fmt):
- if _is_var(fmt):
- inputMapFn = builder.VariableInt
- outputMapFn = lambda v: v.value
- else:
- inputMapFn = outputMapFn = lambda v: v
+ variable = _is_var(fmt)
- paint = _build(
- ot.Paint,
- {
- "Format": fmt,
- "Paint": (
- ot.PaintFormat.PaintGlyph,
- (ot.PaintFormat.PaintSolid, (0, 1.0)),
- "a",
- ),
- "dx": 123,
- "dy": -345,
- },
- )
+ source = {
+ "Format": fmt,
+ "Paint": (
+ ot.PaintFormat.PaintGlyph,
+ (ot.PaintFormat.PaintSolid, 0, 1.0),
+ "a",
+ ),
+ "dx": 123,
+ "dy": -345,
+ }
+ if variable:
+ source["VarIndexBase"] = 678
+
+ paint = _build(ot.Paint, source)
assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
- assert outputMapFn(paint.dx) == 123
- assert outputMapFn(paint.dy) == -345
+ assert paint.dx == 123
+ assert paint.dy == -345
+ if variable:
+ assert paint.VarIndexBase == 678
def test_buildPaintTranslate():
@@ -855,86 +842,212 @@ def test_buildPaintVarTranslate():
checkBuildPaintTranslate(ot.PaintFormat.PaintVarTranslate)
-def checkBuildPaintRotate(fmt):
- if _is_var(fmt):
- inputMapFn = builder.VariableInt
- outputMapFn = lambda v: v.value
+def checkBuildPaintScale(fmt):
+ variable = _is_var(fmt)
+ around_center = _is_around_center(fmt)
+ uniform = _is_uniform_scale(fmt)
+
+ source = {
+ "Format": fmt,
+ "Paint": (
+ ot.PaintFormat.PaintGlyph,
+ (ot.PaintFormat.PaintSolid, 0, 1.0),
+ "a",
+ ),
+ }
+ if uniform:
+ source["scale"] = 1.5
else:
- inputMapFn = outputMapFn = lambda v: v
+ source["scaleX"] = 1.0
+ source["scaleY"] = 2.0
+ if around_center:
+ source["centerX"] = 127
+ source["centerY"] = 129
+ if variable:
+ source["VarIndexBase"] = 666
- paint = _build(
- ot.Paint,
- {
- "Format": fmt,
- "Paint": (
- ot.PaintFormat.PaintGlyph,
- (ot.PaintFormat.PaintSolid, (0, 1.0)),
- "a",
- ),
- "angle": 15,
- "centerX": 127,
- "centerY": 129,
- },
- )
+ paint = _build(ot.Paint, source)
+
+ assert paint.Format == fmt
+ assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
+ if uniform:
+ assert paint.scale == 1.5
+ else:
+ assert paint.scaleX == 1.0
+ assert paint.scaleY == 2.0
+ if around_center:
+ assert paint.centerX == 127
+ assert paint.centerY == 129
+ if variable:
+ assert paint.VarIndexBase == 666
+
+
+def test_buildPaintScale():
+ assert not _is_var(ot.PaintFormat.PaintScale)
+ assert not _is_uniform_scale(ot.PaintFormat.PaintScale)
+ assert not _is_around_center(ot.PaintFormat.PaintScale)
+ checkBuildPaintScale(ot.PaintFormat.PaintScale)
+
+
+def test_buildPaintVarScale():
+ assert _is_var(ot.PaintFormat.PaintVarScale)
+ assert not _is_uniform_scale(ot.PaintFormat.PaintVarScale)
+ assert not _is_around_center(ot.PaintFormat.PaintVarScale)
+ checkBuildPaintScale(ot.PaintFormat.PaintVarScale)
+
+
+def test_buildPaintScaleAroundCenter():
+ assert not _is_var(ot.PaintFormat.PaintScaleAroundCenter)
+ assert not _is_uniform_scale(ot.PaintFormat.PaintScaleAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintScaleAroundCenter)
+ checkBuildPaintScale(ot.PaintFormat.PaintScaleAroundCenter)
+
+
+def test_buildPaintVarScaleAroundCenter():
+ assert _is_var(ot.PaintFormat.PaintVarScaleAroundCenter)
+ assert not _is_uniform_scale(ot.PaintFormat.PaintScaleAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintVarScaleAroundCenter)
+ checkBuildPaintScale(ot.PaintFormat.PaintVarScaleAroundCenter)
+
+
+def test_buildPaintScaleUniform():
+ assert not _is_var(ot.PaintFormat.PaintScaleUniform)
+ assert _is_uniform_scale(ot.PaintFormat.PaintScaleUniform)
+ assert not _is_around_center(ot.PaintFormat.PaintScaleUniform)
+ checkBuildPaintScale(ot.PaintFormat.PaintScaleUniform)
+
+
+def test_buildPaintVarScaleUniform():
+ assert _is_var(ot.PaintFormat.PaintVarScaleUniform)
+ assert _is_uniform_scale(ot.PaintFormat.PaintVarScaleUniform)
+ assert not _is_around_center(ot.PaintFormat.PaintVarScaleUniform)
+ checkBuildPaintScale(ot.PaintFormat.PaintVarScaleUniform)
+
+
+def test_buildPaintScaleUniformAroundCenter():
+ assert not _is_var(ot.PaintFormat.PaintScaleUniformAroundCenter)
+ assert _is_uniform_scale(ot.PaintFormat.PaintScaleUniformAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintScaleUniformAroundCenter)
+ checkBuildPaintScale(ot.PaintFormat.PaintScaleUniformAroundCenter)
+
+
+def test_buildPaintVarScaleUniformAroundCenter():
+ assert _is_var(ot.PaintFormat.PaintVarScaleUniformAroundCenter)
+ assert _is_uniform_scale(ot.PaintFormat.PaintVarScaleUniformAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintVarScaleUniformAroundCenter)
+ checkBuildPaintScale(ot.PaintFormat.PaintVarScaleUniformAroundCenter)
+
+
+def checkBuildPaintRotate(fmt):
+ variable = _is_var(fmt)
+ around_center = _is_around_center(fmt)
+
+ source = {
+ "Format": fmt,
+ "Paint": (
+ ot.PaintFormat.PaintGlyph,
+ (ot.PaintFormat.PaintSolid, 0, 1.0),
+ "a",
+ ),
+ "angle": 15,
+ }
+ if around_center:
+ source["centerX"] = 127
+ source["centerY"] = 129
+
+ paint = _build(ot.Paint, source)
assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
- assert outputMapFn(paint.angle) == 15
- assert outputMapFn(paint.centerX) == 127
- assert outputMapFn(paint.centerY) == 129
+ assert paint.angle == 15
+ if around_center:
+ assert paint.centerX == 127
+ assert paint.centerY == 129
+ if variable:
+ assert paint.VarIndexBase == 0xFFFFFFFF
def test_buildPaintRotate():
assert not _is_var(ot.PaintFormat.PaintRotate)
+ assert not _is_around_center(ot.PaintFormat.PaintRotate)
checkBuildPaintRotate(ot.PaintFormat.PaintRotate)
def test_buildPaintVarRotate():
assert _is_var(ot.PaintFormat.PaintVarRotate)
+ assert not _is_around_center(ot.PaintFormat.PaintVarRotate)
checkBuildPaintRotate(ot.PaintFormat.PaintVarRotate)
+def test_buildPaintRotateAroundCenter():
+ assert not _is_var(ot.PaintFormat.PaintRotateAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintRotateAroundCenter)
+ checkBuildPaintRotate(ot.PaintFormat.PaintRotateAroundCenter)
+
+
+def test_buildPaintVarRotateAroundCenter():
+ assert _is_var(ot.PaintFormat.PaintVarRotateAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintVarRotateAroundCenter)
+ checkBuildPaintRotate(ot.PaintFormat.PaintVarRotateAroundCenter)
+
+
def checkBuildPaintSkew(fmt):
- if _is_var(fmt):
- inputMapFn = builder.VariableInt
- outputMapFn = lambda v: v.value
- else:
- inputMapFn = outputMapFn = lambda v: v
+ variable = _is_var(fmt)
+ around_center = _is_around_center(fmt)
- paint = _build(
- ot.Paint,
- {
- "Format": fmt,
- "Paint": (
- ot.PaintFormat.PaintGlyph,
- (ot.PaintFormat.PaintSolid, (0, 1.0)),
- "a",
- ),
- "xSkewAngle": 15,
- "ySkewAngle": 42,
- "centerX": 127,
- "centerY": 129,
- },
- )
+ source = {
+ "Format": fmt,
+ "Paint": (
+ ot.PaintFormat.PaintGlyph,
+ (ot.PaintFormat.PaintSolid, 0, 1.0),
+ "a",
+ ),
+ "xSkewAngle": 15,
+ "ySkewAngle": 42,
+ }
+ if around_center:
+ source["centerX"] = 127
+ source["centerY"] = 129
+ if variable:
+ source["VarIndexBase"] = 0
+
+ paint = _build(ot.Paint, source)
assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
- assert outputMapFn(paint.xSkewAngle) == 15
- assert outputMapFn(paint.ySkewAngle) == 42
- assert outputMapFn(paint.centerX) == 127
- assert outputMapFn(paint.centerY) == 129
+ assert paint.xSkewAngle == 15
+ assert paint.ySkewAngle == 42
+ if around_center:
+ assert paint.centerX == 127
+ assert paint.centerY == 129
+ if variable:
+ assert paint.VarIndexBase == 0
def test_buildPaintSkew():
assert not _is_var(ot.PaintFormat.PaintSkew)
+ assert not _is_around_center(ot.PaintFormat.PaintSkew)
checkBuildPaintSkew(ot.PaintFormat.PaintSkew)
def test_buildPaintVarSkew():
assert _is_var(ot.PaintFormat.PaintVarSkew)
+ assert not _is_around_center(ot.PaintFormat.PaintVarSkew)
checkBuildPaintSkew(ot.PaintFormat.PaintVarSkew)
+def test_buildPaintSkewAroundCenter():
+ assert not _is_var(ot.PaintFormat.PaintSkewAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintSkewAroundCenter)
+ checkBuildPaintSkew(ot.PaintFormat.PaintSkewAroundCenter)
+
+
+def test_buildPaintVarSkewAroundCenter():
+ assert _is_var(ot.PaintFormat.PaintVarSkewAroundCenter)
+ assert _is_around_center(ot.PaintFormat.PaintVarSkewAroundCenter)
+ checkBuildPaintSkew(ot.PaintFormat.PaintVarSkewAroundCenter)
+
+
def test_buildColrV1():
colorGlyphs = {
"a": (
@@ -951,7 +1064,8 @@ def test_buildColrV1():
ot.PaintFormat.PaintGlyph,
{
"Format": int(ot.PaintFormat.PaintSolid),
- "Color": {"PaletteIndex": 2, "Alpha": 0.8},
+ "PaletteIndex": 2,
+ "Alpha": 0.8,
},
"e",
),
@@ -994,15 +1108,15 @@ def test_buildColrV1():
# TODO(anthrotype) should we split into two tests? - seems two distinct validations
layers, baseGlyphs = builder.buildColrV1(colorGlyphs, glyphMap)
assert baseGlyphs.BaseGlyphCount == len(colorGlyphs)
- assert baseGlyphs.BaseGlyphV1Record[0].BaseGlyph == "d"
- assert baseGlyphs.BaseGlyphV1Record[1].BaseGlyph == "a"
- assert baseGlyphs.BaseGlyphV1Record[2].BaseGlyph == "g"
+ assert baseGlyphs.BaseGlyphPaintRecord[0].BaseGlyph == "d"
+ assert baseGlyphs.BaseGlyphPaintRecord[1].BaseGlyph == "a"
+ assert baseGlyphs.BaseGlyphPaintRecord[2].BaseGlyph == "g"
layers, baseGlyphs = builder.buildColrV1(colorGlyphs)
assert baseGlyphs.BaseGlyphCount == len(colorGlyphs)
- assert baseGlyphs.BaseGlyphV1Record[0].BaseGlyph == "a"
- assert baseGlyphs.BaseGlyphV1Record[1].BaseGlyph == "d"
- assert baseGlyphs.BaseGlyphV1Record[2].BaseGlyph == "g"
+ assert baseGlyphs.BaseGlyphPaintRecord[0].BaseGlyph == "a"
+ assert baseGlyphs.BaseGlyphPaintRecord[1].BaseGlyph == "d"
+ assert baseGlyphs.BaseGlyphPaintRecord[2].BaseGlyph == "g"
def test_buildColrV1_more_than_255_paints():
@@ -1037,16 +1151,17 @@ def test_buildColrV1_more_than_255_paints():
)
assert baseGlyphs.BaseGlyphCount == len(colorGlyphs)
- assert baseGlyphs.BaseGlyphV1Record[0].BaseGlyph == "a"
+ assert baseGlyphs.BaseGlyphPaintRecord[0].BaseGlyph == "a"
assert (
- baseGlyphs.BaseGlyphV1Record[0].Paint.Format == ot.PaintFormat.PaintColrLayers
+ baseGlyphs.BaseGlyphPaintRecord[0].Paint.Format
+ == ot.PaintFormat.PaintColrLayers
)
- assert baseGlyphs.BaseGlyphV1Record[0].Paint.FirstLayerIndex == 255
- assert baseGlyphs.BaseGlyphV1Record[0].Paint.NumLayers == num_paints + 1 - 255
+ assert baseGlyphs.BaseGlyphPaintRecord[0].Paint.FirstLayerIndex == 255
+ assert baseGlyphs.BaseGlyphPaintRecord[0].Paint.NumLayers == num_paints + 1 - 255
def test_split_color_glyphs_by_version():
- layerBuilder = LayerV1ListBuilder()
+ layerBuilder = LayerListBuilder()
colorGlyphs = {
"a": [
("b", 0),
@@ -1113,7 +1228,7 @@ def test_build_layerv1list_empty():
# BaseGlyph, tuple form
"a": (
int(ot.PaintFormat.PaintGlyph),
- (2, (2, 0.8)),
+ (int(ot.PaintFormat.PaintSolid), 2, 0.8),
"b",
),
# BaseGlyph, map form
@@ -1141,16 +1256,15 @@ def test_build_layerv1list_empty():
assertIsColrV1(colr)
assertNoV0Content(colr)
- # 2 v1 glyphs, none in LayerV1List
- assert colr.table.BaseGlyphV1List.BaseGlyphCount == 2
- assert len(colr.table.BaseGlyphV1List.BaseGlyphV1Record) == 2
- assert colr.table.LayerV1List.LayerCount == 0
- assert len(colr.table.LayerV1List.Paint) == 0
+ # 2 v1 glyphs, none in LayerList
+ assert colr.table.BaseGlyphList.BaseGlyphCount == 2
+ assert len(colr.table.BaseGlyphList.BaseGlyphPaintRecord) == 2
+ assert colr.table.LayerList is None
def _paint_names(paints) -> List[str]:
# prints a predictable string from a paint list to enable
- # semi-readable assertions on a LayerV1List order.
+ # semi-readable assertions on a LayerList order.
result = []
for paint in paints:
if paint.Format == int(ot.PaintFormat.PaintGlyph):
@@ -1165,7 +1279,11 @@ def _paint_names(paints) -> List[str]:
def test_build_layerv1list_simple():
# Two colr glyphs, each with two layers the first of which is common
# All layers use the same solid paint
- solid_paint = {"Format": 2, "Color": {"PaletteIndex": 2, "Alpha": 0.8}}
+ solid_paint = {
+ "Format": int(ot.PaintFormat.PaintSolid),
+ "PaletteIndex": 2,
+ "Alpha": 0.8,
+ }
backdrop = {
"Format": int(ot.PaintFormat.PaintGlyph),
"Paint": solid_paint,
@@ -1182,7 +1300,7 @@ def test_build_layerv1list_simple():
"Glyph": "b_fore",
}
- # list => PaintColrLayers, contents should land in LayerV1List
+ # list => PaintColrLayers, contents should land in LayerList
colr = builder.buildCOLR(
{
"a": (
@@ -1206,12 +1324,12 @@ def test_build_layerv1list_simple():
assertIsColrV1(colr)
assertNoV0Content(colr)
- # 2 v1 glyphs, 4 paints in LayerV1List
+ # 2 v1 glyphs, 4 paints in LayerList
# A single shared backdrop isn't worth accessing by slice
- assert colr.table.BaseGlyphV1List.BaseGlyphCount == 2
- assert len(colr.table.BaseGlyphV1List.BaseGlyphV1Record) == 2
- assert colr.table.LayerV1List.LayerCount == 4
- assert _paint_names(colr.table.LayerV1List.Paint) == [
+ assert colr.table.BaseGlyphList.BaseGlyphCount == 2
+ assert len(colr.table.BaseGlyphList.BaseGlyphPaintRecord) == 2
+ assert colr.table.LayerList.LayerCount == 4
+ assert _paint_names(colr.table.LayerList.Paint) == [
"back",
"a_fore",
"back",
@@ -1221,7 +1339,11 @@ def test_build_layerv1list_simple():
def test_build_layerv1list_with_sharing():
# Three colr glyphs, each with two layers in common
- solid_paint = {"Format": 2, "Color": (2, 0.8)}
+ solid_paint = {
+ "Format": int(ot.PaintFormat.PaintSolid),
+ "PaletteIndex": 2,
+ "Alpha": 0.8,
+ }
backdrop = [
{
"Format": int(ot.PaintFormat.PaintGlyph),
@@ -1255,7 +1377,7 @@ def test_build_layerv1list_with_sharing():
"Glyph": "c_back",
}
- # list => PaintColrLayers, which means contents should be in LayerV1List
+ # list => PaintColrLayers, which means contents should be in LayerList
colr = builder.buildCOLR(
{
"a": (ot.PaintFormat.PaintColrLayers, backdrop + [a_foreground]),
@@ -1271,17 +1393,17 @@ def test_build_layerv1list_with_sharing():
assertIsColrV1(colr)
assertNoV0Content(colr)
- # 2 v1 glyphs, 4 paints in LayerV1List
+ # 2 v1 glyphs, 4 paints in LayerList
# A single shared backdrop isn't worth accessing by slice
- baseGlyphs = colr.table.BaseGlyphV1List.BaseGlyphV1Record
- assert colr.table.BaseGlyphV1List.BaseGlyphCount == 3
+ baseGlyphs = colr.table.BaseGlyphList.BaseGlyphPaintRecord
+ assert colr.table.BaseGlyphList.BaseGlyphCount == 3
assert len(baseGlyphs) == 3
assert _paint_names([b.Paint for b in baseGlyphs]) == [
"Layers[0:3]",
"Layers[3:6]",
"Layers[6:8]",
]
- assert _paint_names(colr.table.LayerV1List.Paint) == [
+ assert _paint_names(colr.table.LayerList.Paint) == [
"back1",
"back2",
"a_fore",
@@ -1291,7 +1413,7 @@ def test_build_layerv1list_with_sharing():
"c_back",
"Layers[0:2]",
]
- assert colr.table.LayerV1List.LayerCount == 8
+ assert colr.table.LayerList.LayerCount == 8
def test_build_layerv1list_with_overlaps():
@@ -1300,14 +1422,15 @@ def test_build_layerv1list_with_overlaps():
"Format": ot.PaintFormat.PaintGlyph,
"Paint": {
"Format": ot.PaintFormat.PaintSolid,
- "Color": {"PaletteIndex": 2, "Alpha": 0.8},
+ "PaletteIndex": 2,
+ "Alpha": 0.8,
},
"Glyph": c,
}
for c in "abcdefghi"
]
- # list => PaintColrLayers, which means contents should be in LayerV1List
+ # list => PaintColrLayers, which means contents should be in LayerList
colr = builder.buildCOLR(
{
"a": (ot.PaintFormat.PaintColrLayers, paints[0:4]),
@@ -1320,10 +1443,10 @@ def test_build_layerv1list_with_overlaps():
assertIsColrV1(colr)
assertNoV0Content(colr)
- baseGlyphs = colr.table.BaseGlyphV1List.BaseGlyphV1Record
- # assert colr.table.BaseGlyphV1List.BaseGlyphCount == 2
+ baseGlyphs = colr.table.BaseGlyphList.BaseGlyphPaintRecord
+ # assert colr.table.BaseGlyphList.BaseGlyphCount == 2
- assert _paint_names(colr.table.LayerV1List.Paint) == [
+ assert _paint_names(colr.table.LayerList.Paint) == [
"a",
"b",
"c",
@@ -1341,7 +1464,7 @@ def test_build_layerv1list_with_overlaps():
"Layers[4:7]",
"Layers[7:11]",
]
- assert colr.table.LayerV1List.LayerCount == 11
+ assert colr.table.LayerList.LayerCount == 11
def test_explicit_version_1():
@@ -1397,7 +1520,11 @@ class BuildCOLRTest(object):
),
(
ot.PaintFormat.PaintGlyph,
- {"Format": 2, "Color": {"PaletteIndex": 2, "Alpha": 0.8}},
+ {
+ "Format": ot.PaintFormat.PaintSolid,
+ "PaletteIndex": 2,
+ "Alpha": 0.8,
+ },
"c",
),
],
@@ -1455,7 +1582,7 @@ class BuildCOLRTest(object):
),
(
ot.PaintFormat.PaintGlyph,
- (ot.PaintFormat.PaintSolid, (2, 0.8)),
+ (ot.PaintFormat.PaintSolid, 2, 0.8),
"f",
),
],
@@ -1470,14 +1597,14 @@ class BuildCOLRTest(object):
assert colr.table.LayerRecordCount == 2
assert isinstance(colr.table.LayerRecordArray, ot.LayerRecordArray)
- assert isinstance(colr.table.BaseGlyphV1List, ot.BaseGlyphV1List)
- assert colr.table.BaseGlyphV1List.BaseGlyphCount == 1
+ assert isinstance(colr.table.BaseGlyphList, ot.BaseGlyphList)
+ assert colr.table.BaseGlyphList.BaseGlyphCount == 1
assert isinstance(
- colr.table.BaseGlyphV1List.BaseGlyphV1Record[0], ot.BaseGlyphV1Record
+ colr.table.BaseGlyphList.BaseGlyphPaintRecord[0], ot.BaseGlyphPaintRecord
)
- assert colr.table.BaseGlyphV1List.BaseGlyphV1Record[0].BaseGlyph == "d"
- assert isinstance(colr.table.LayerV1List, ot.LayerV1List)
- assert colr.table.LayerV1List.Paint[0].Glyph == "e"
+ assert colr.table.BaseGlyphList.BaseGlyphPaintRecord[0].BaseGlyph == "d"
+ assert isinstance(colr.table.LayerList, ot.LayerList)
+ assert colr.table.LayerList.Paint[0].Glyph == "e"
def test_explicit_version_0(self):
colr = builder.buildCOLR({"a": [("b", 0), ("c", 1)]}, version=0)
@@ -1528,12 +1655,71 @@ class BuildCOLRTest(object):
},
)
- assert len(colr.table.LayerV1List.Paint) == 0, "PaintColrLayers should be gone"
- assert colr.table.BaseGlyphV1List.BaseGlyphCount == 1
- paint = colr.table.BaseGlyphV1List.BaseGlyphV1Record[0].Paint
+ assert colr.table.LayerList is None, "PaintColrLayers should be gone"
+ assert colr.table.BaseGlyphList.BaseGlyphCount == 1
+ paint = colr.table.BaseGlyphList.BaseGlyphPaintRecord[0].Paint
assert paint.Format == ot.PaintFormat.PaintGlyph
assert paint.Paint.Format == ot.PaintFormat.PaintSolid
+ def test_build_clip_list(self):
+ colr = builder.buildCOLR(
+ {
+ "a": (
+ ot.PaintFormat.PaintGlyph,
+ (ot.PaintFormat.PaintSolid, 0),
+ "b",
+ ),
+ "c": (
+ ot.PaintFormat.PaintGlyph,
+ (ot.PaintFormat.PaintSolid, 1),
+ "d",
+ ),
+ },
+ clipBoxes={
+ "a": (0, 0, 1000, 1000, 0), # optional 5th: varIndexBase
+ "c": (-100.8, -200.4, 1100.1, 1200.5), # floats get rounded
+ "e": (0, 0, 10, 10), # missing base glyph 'e' is ignored
+ },
+ )
+
+ assert colr.table.ClipList.Format == 1
+ clipBoxes = colr.table.ClipList.clips
+ assert [
+ (baseGlyph, clipBox.as_tuple()) for baseGlyph, clipBox in clipBoxes.items()
+ ] == [
+ ("a", (0, 0, 1000, 1000, 0)),
+ ("c", (-101, -201, 1101, 1201)),
+ ]
+ assert clipBoxes["a"].Format == 2
+ assert clipBoxes["c"].Format == 1
+
+ def test_duplicate_base_glyphs(self):
+ # If > 1 base glyphs refer to equivalent list of layers we expect them to share
+ # the same PaintColrLayers.
+ layers = {
+ "Format": ot.PaintFormat.PaintColrLayers,
+ "Layers": [
+ (ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, 0), "d"),
+ (ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, 1), "e"),
+ ],
+ }
+ # I copy the layers to ensure equality is by content, not by identity
+ colr = builder.buildCOLR(
+ {"a": layers, "b": deepcopy(layers), "c": deepcopy(layers)}
+ ).table
+
+ baseGlyphs = colr.BaseGlyphList.BaseGlyphPaintRecord
+ assert len(baseGlyphs) == 3
+
+ assert baseGlyphs[0].BaseGlyph == "a"
+ assert baseGlyphs[1].BaseGlyph == "b"
+ assert baseGlyphs[2].BaseGlyph == "c"
+
+ expected = {"Format": 1, "FirstLayerIndex": 0, "NumLayers": 2}
+ assert baseGlyphs[0].Paint.__dict__ == expected
+ assert baseGlyphs[1].Paint.__dict__ == expected
+ assert baseGlyphs[2].Paint.__dict__ == expected
+
class TrickyRadialGradientTest:
@staticmethod
@@ -1561,6 +1747,16 @@ class TrickyRadialGradientTest:
r1 = 260.0072
assert self.round_start_circle(c0, r0, c1, r1, inside=True) == ((386, 71), 0)
+ def test_noto_emoji_horns_sign_u1f918_1f3fc(self):
+ # This radial gradient is taken from noto-emoji's 'SIGNS OF THE HORNS'
+ # (1f918_1f3fc). We check that c0 is inside c1 both before and after rounding.
+ c0 = (-437.6789059060543, -2116.9237094478003)
+ r0 = 0.0
+ c1 = (-488.7330118252256, -1876.5036857045086)
+ r1 = 245.77147821915673
+ assert self.circle_inside_circle(c0, r0, c1, r1)
+ assert self.circle_inside_circle(c0, r0, c1, r1, rounded=True)
+
@pytest.mark.parametrize(
"c0, r0, c1, r1, inside, expected",
[