Add PaintScale* and Paint{Rotate,Skew}* variants

This updates fonttools to match the latest draft COLRv1 spec at https://github.com/googlefonts/colr-gradients-spec/pull/290

Summary of changes:
- Added 8 new PaintScale* tables: with/without centers, uniform vs non-uniform
- Added *AroundCenter variants to PaintRotate and PaintSkew (default versions no longer have centerX/Y defaulting to origin)
- PaintRotate, PaintSkew and PaintComposite formats re-numbered
This commit is contained in:
Cosimo Lupo 2021-06-28 18:38:47 +01:00
parent e3630ac3ac
commit d0d59d2f2c
6 changed files with 312 additions and 71 deletions

View File

@ -1764,36 +1764,128 @@ otData = [
('VarFixed', 'dy', None, None, 'Translation in y direction.'), ('VarFixed', 'dy', None, None, 'Translation in y direction.'),
]), ]),
# PaintRotate # PaintScale
('PaintFormat16', [ ('PaintFormat16', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 16'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 16'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintScale table) to Paint subtable.'),
('Fixed', 'scaleX', None, None, ''),
('Fixed', 'scaleY', None, None, ''),
]),
# PaintVarScale
('PaintFormat17', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 17'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScale table) to Paint subtable.'),
('VarFixed', 'scaleX', None, None, ''),
('VarFixed', 'scaleY', None, None, ''),
]),
# PaintScaleAroundCenter
('PaintFormat18', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 18'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable.'),
('Fixed', 'scaleX', None, None, ''),
('Fixed', 'scaleY', None, None, ''),
('Fixed', 'centerX', None, None, ''),
('Fixed', 'centerY', None, None, ''),
]),
# PaintVarScaleAroundCenter
('PaintFormat19', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 19'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleAroundCenter table) to Paint subtable.'),
('VarFixed', 'scaleX', None, None, ''),
('VarFixed', 'scaleY', None, None, ''),
('VarFixed', 'centerX', None, None, ''),
('VarFixed', 'centerY', None, None, ''),
]),
# PaintScaleUniform
('PaintFormat20', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 20'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintScaleUniform table) to Paint subtable.'),
('Fixed', 'scale', None, None, ''),
]),
# PaintVarScaleUniform
('PaintFormat21', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 21'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleUniform table) to Paint subtable.'),
('VarFixed', 'scale', None, None, ''),
]),
# PaintScaleUniformAroundCenter
('PaintFormat22', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 22'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable.'),
('Fixed', 'scale', None, None, ''),
('Fixed', 'centerX', None, None, ''),
('Fixed', 'centerY', None, None, ''),
]),
# PaintVarScaleUniformAroundCenter
('PaintFormat23', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 23'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleUniformAroundCenter table) to Paint subtable.'),
('VarFixed', 'scale', None, None, ''),
('VarFixed', 'centerX', None, None, ''),
('VarFixed', 'centerY', None, None, ''),
]),
# PaintRotate
('PaintFormat24', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 24'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintRotate table) to Paint subtable.'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintRotate table) to Paint subtable.'),
('Fixed', 'angle', None, None, ''), ('Fixed', 'angle', None, None, ''),
]),
# PaintVarRotate
('PaintFormat25', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 25'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotate table) to Paint subtable.'),
('VarFixed', 'angle', None, None, ''),
]),
# PaintRotateAroundCenter
('PaintFormat26', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 26'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable.'),
('Fixed', 'angle', None, None, ''),
('Fixed', 'centerX', None, None, ''), ('Fixed', 'centerX', None, None, ''),
('Fixed', 'centerY', None, None, ''), ('Fixed', 'centerY', None, None, ''),
]), ]),
# PaintVarRotate # PaintVarRotateAroundCenter
('PaintFormat17', [ ('PaintFormat27', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 17'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 27'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotate table) to Paint subtable.'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotateAroundCenter table) to Paint subtable.'),
('VarFixed', 'angle', None, None, ''), ('VarFixed', 'angle', None, None, ''),
('VarFixed', 'centerX', None, None, ''), ('VarFixed', 'centerX', None, None, ''),
('VarFixed', 'centerY', None, None, ''), ('VarFixed', 'centerY', None, None, ''),
]), ]),
# PaintSkew # PaintSkew
('PaintFormat18', [ ('PaintFormat28', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 18'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 28'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintSkew table) to Paint subtable.'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintSkew table) to Paint subtable.'),
('Fixed', 'xSkewAngle', None, None, ''), ('Fixed', 'xSkewAngle', None, None, ''),
('Fixed', 'ySkewAngle', None, None, ''), ('Fixed', 'ySkewAngle', None, None, ''),
]),
# PaintVarSkew
('PaintFormat29', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 29'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkew table) to Paint subtable.'),
('VarFixed', 'xSkewAngle', None, None, ''),
('VarFixed', 'ySkewAngle', None, None, ''),
]),
# PaintSkewAroundCenter
('PaintFormat30', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 30'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable.'),
('Fixed', 'xSkewAngle', None, None, ''),
('Fixed', 'ySkewAngle', None, None, ''),
('Fixed', 'centerX', None, None, ''), ('Fixed', 'centerX', None, None, ''),
('Fixed', 'centerY', None, None, ''), ('Fixed', 'centerY', None, None, ''),
]), ]),
# PaintVarSkew # PaintVarSkewAroundCenter
('PaintFormat19', [ ('PaintFormat31', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 19'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 31'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkew table) to Paint subtable.'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkewAroundCenter table) to Paint subtable.'),
('VarFixed', 'xSkewAngle', None, None, ''), ('VarFixed', 'xSkewAngle', None, None, ''),
('VarFixed', 'ySkewAngle', None, None, ''), ('VarFixed', 'ySkewAngle', None, None, ''),
('VarFixed', 'centerX', None, None, ''), ('VarFixed', 'centerX', None, None, ''),
@ -1801,8 +1893,8 @@ otData = [
]), ]),
# PaintComposite # PaintComposite
('PaintFormat20', [ ('PaintFormat32', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 20'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 32'),
('LOffset24To(Paint)', 'SourcePaint', None, None, 'Offset (from beginning of PaintComposite table) to source Paint subtable.'), ('LOffset24To(Paint)', 'SourcePaint', None, None, 'Offset (from beginning of PaintComposite table) to source Paint subtable.'),
('CompositeMode', 'CompositeMode', None, None, 'A CompositeMode enumeration value.'), ('CompositeMode', 'CompositeMode', None, None, 'A CompositeMode enumeration value.'),
('LOffset24To(Paint)', 'BackdropPaint', None, None, 'Offset (from beginning of PaintComposite table) to backdrop Paint subtable.'), ('LOffset24To(Paint)', 'BackdropPaint', None, None, 'Offset (from beginning of PaintComposite table) to backdrop Paint subtable.'),

View File

@ -1346,11 +1346,23 @@ class PaintFormat(IntEnum):
PaintVarTransform = 13 PaintVarTransform = 13
PaintTranslate = 14 PaintTranslate = 14
PaintVarTranslate = 15 PaintVarTranslate = 15
PaintRotate = 16 PaintScale = 16
PaintVarRotate = 17 PaintVarScale = 17
PaintSkew = 18 PaintScaleAroundCenter = 18
PaintVarSkew = 19 PaintVarScaleAroundCenter = 19
PaintComposite = 20 PaintScaleUniform = 20
PaintVarScaleUniform = 21
PaintScaleUniformAroundCenter = 22
PaintVarScaleUniformAroundCenter = 23
PaintRotate = 24
PaintVarRotate = 25
PaintRotateAroundCenter = 26
PaintVarRotateAroundCenter = 27
PaintSkew = 28
PaintVarSkew = 29
PaintSkewAroundCenter = 30
PaintVarSkewAroundCenter = 31
PaintComposite = 32
class Paint(getFormatSwitchingBaseTableClass("uint8")): class Paint(getFormatSwitchingBaseTableClass("uint8")):

View File

@ -394,6 +394,14 @@ def _is_var(fmt):
return fmt.name.startswith("PaintVar") return fmt.name.startswith("PaintVar")
def _is_around_center(fmt):
return fmt.name.endswith("AroundCenter")
def _is_uniform_scale(fmt):
return "ScaleUniform" in fmt.name
def checkBuildPaintLinearGradient(fmt): def checkBuildPaintLinearGradient(fmt):
if _is_var(fmt): if _is_var(fmt):
inputMapFn = builder.VariableInt inputMapFn = builder.VariableInt
@ -855,86 +863,214 @@ def test_buildPaintVarTranslate():
checkBuildPaintTranslate(ot.PaintFormat.PaintVarTranslate) checkBuildPaintTranslate(ot.PaintFormat.PaintVarTranslate)
def checkBuildPaintScale(fmt):
if _is_var(fmt):
inputMapFn = builder.VariableInt
outputMapFn = lambda v: v.value
else:
inputMapFn = outputMapFn = lambda v: v
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:
source["scaleX"] = 1.0
source["scaleY"] = 2.0
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
if uniform:
assert outputMapFn(paint.scale) == 1.5
else:
assert outputMapFn(paint.scaleX) == 1.0
assert outputMapFn(paint.scaleY) == 2.0
if around_center:
assert outputMapFn(paint.centerX) == 127
assert outputMapFn(paint.centerY) == 129
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): def checkBuildPaintRotate(fmt):
if _is_var(fmt): if _is_var(fmt):
inputMapFn = builder.VariableInt inputMapFn = builder.VariableInt
outputMapFn = lambda v: v.value outputMapFn = lambda v: v.value
else: else:
inputMapFn = outputMapFn = lambda v: v inputMapFn = outputMapFn = lambda v: v
around_center = _is_around_center(fmt)
paint = _build( source = {
ot.Paint, "Format": fmt,
{ "Paint": (
"Format": fmt, ot.PaintFormat.PaintGlyph,
"Paint": ( (ot.PaintFormat.PaintSolid, (0, 1.0)),
ot.PaintFormat.PaintGlyph, "a",
(ot.PaintFormat.PaintSolid, (0, 1.0)), ),
"a", "angle": 15,
), }
"angle": 15, if around_center:
"centerX": 127, source["centerX"] = 127
"centerY": 129, source["centerY"] = 129
},
) paint = _build(ot.Paint, source)
assert paint.Format == fmt assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
assert outputMapFn(paint.angle) == 15 assert outputMapFn(paint.angle) == 15
assert outputMapFn(paint.centerX) == 127 if around_center:
assert outputMapFn(paint.centerY) == 129 assert outputMapFn(paint.centerX) == 127
assert outputMapFn(paint.centerY) == 129
def test_buildPaintRotate(): def test_buildPaintRotate():
assert not _is_var(ot.PaintFormat.PaintRotate) assert not _is_var(ot.PaintFormat.PaintRotate)
assert not _is_around_center(ot.PaintFormat.PaintRotate)
checkBuildPaintRotate(ot.PaintFormat.PaintRotate) checkBuildPaintRotate(ot.PaintFormat.PaintRotate)
def test_buildPaintVarRotate(): def test_buildPaintVarRotate():
assert _is_var(ot.PaintFormat.PaintVarRotate) assert _is_var(ot.PaintFormat.PaintVarRotate)
assert not _is_around_center(ot.PaintFormat.PaintVarRotate)
checkBuildPaintRotate(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): def checkBuildPaintSkew(fmt):
if _is_var(fmt): if _is_var(fmt):
inputMapFn = builder.VariableInt inputMapFn = builder.VariableInt
outputMapFn = lambda v: v.value outputMapFn = lambda v: v.value
else: else:
inputMapFn = outputMapFn = lambda v: v inputMapFn = outputMapFn = lambda v: v
around_center = _is_around_center(fmt)
paint = _build( source = {
ot.Paint, "Format": fmt,
{ "Paint": (
"Format": fmt, ot.PaintFormat.PaintGlyph,
"Paint": ( (ot.PaintFormat.PaintSolid, (0, 1.0)),
ot.PaintFormat.PaintGlyph, "a",
(ot.PaintFormat.PaintSolid, (0, 1.0)), ),
"a", "xSkewAngle": 15,
), "ySkewAngle": 42,
"xSkewAngle": 15, }
"ySkewAngle": 42, if around_center:
"centerX": 127, source["centerX"] = 127
"centerY": 129, source["centerY"] = 129
},
) paint = _build(ot.Paint, source)
assert paint.Format == fmt assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
assert outputMapFn(paint.xSkewAngle) == 15 assert outputMapFn(paint.xSkewAngle) == 15
assert outputMapFn(paint.ySkewAngle) == 42 assert outputMapFn(paint.ySkewAngle) == 42
assert outputMapFn(paint.centerX) == 127 if around_center:
assert outputMapFn(paint.centerY) == 129 assert outputMapFn(paint.centerX) == 127
assert outputMapFn(paint.centerY) == 129
def test_buildPaintSkew(): def test_buildPaintSkew():
assert not _is_var(ot.PaintFormat.PaintSkew) assert not _is_var(ot.PaintFormat.PaintSkew)
assert not _is_around_center(ot.PaintFormat.PaintSkew)
checkBuildPaintSkew(ot.PaintFormat.PaintSkew) checkBuildPaintSkew(ot.PaintFormat.PaintSkew)
def test_buildPaintVarSkew(): def test_buildPaintVarSkew():
assert _is_var(ot.PaintFormat.PaintVarSkew) assert _is_var(ot.PaintFormat.PaintVarSkew)
assert not _is_around_center(ot.PaintFormat.PaintVarSkew)
checkBuildPaintSkew(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(): def test_buildColrV1():
colorGlyphs = { colorGlyphs = {
"a": ( "a": (
@ -1039,7 +1175,8 @@ def test_buildColrV1_more_than_255_paints():
assert baseGlyphs.BaseGlyphCount == len(colorGlyphs) assert baseGlyphs.BaseGlyphCount == len(colorGlyphs)
assert baseGlyphs.BaseGlyphPaintRecord[0].BaseGlyph == "a" assert baseGlyphs.BaseGlyphPaintRecord[0].BaseGlyph == "a"
assert ( assert (
baseGlyphs.BaseGlyphPaintRecord[0].Paint.Format == ot.PaintFormat.PaintColrLayers baseGlyphs.BaseGlyphPaintRecord[0].Paint.Format
== ot.PaintFormat.PaintColrLayers
) )
assert baseGlyphs.BaseGlyphPaintRecord[0].Paint.FirstLayerIndex == 255 assert baseGlyphs.BaseGlyphPaintRecord[0].Paint.FirstLayerIndex == 255
assert baseGlyphs.BaseGlyphPaintRecord[0].Paint.NumLayers == num_paints + 1 - 255 assert baseGlyphs.BaseGlyphPaintRecord[0].Paint.NumLayers == num_paints + 1 - 255

View File

@ -99,12 +99,8 @@ TEST_COLOR_GLYPHS = {
}, },
"xSkewAngle": (-11.0, 0), "xSkewAngle": (-11.0, 0),
"ySkewAngle": (5.0, 0), "ySkewAngle": (5.0, 0),
"centerX": (253.0, 0),
"centerY": (254.0, 0),
}, },
"angle": 45.0, "angle": 45.0,
"centerX": 255.0,
"centerY": 256.0,
}, },
"dx": (257.0, 0), "dx": (257.0, 0),
"dy": (258.0, 0), "dy": (258.0, 0),

View File

@ -1078,7 +1078,7 @@ def colrv1_path(tmp_path):
], ],
), ),
"uniE003": { "uniE003": {
"Format": ot.PaintFormat.PaintRotate, "Format": ot.PaintFormat.PaintRotateAroundCenter,
"Paint": { "Paint": {
"Format": ot.PaintFormat.PaintColrGlyph, "Format": ot.PaintFormat.PaintColrGlyph,
"Glyph": "uniE001", "Glyph": "uniE001",

View File

@ -50,7 +50,9 @@ def diff_binary_fragments(font_bytes, expected_fragments):
for expected_bytes, description in expected_fragments: for expected_bytes, description in expected_fragments:
actual_bytes = font_bytes[pos : pos + len(expected_bytes)] actual_bytes = font_bytes[pos : pos + len(expected_bytes)]
if actual_bytes != expected_bytes: if actual_bytes != expected_bytes:
print(f'{description} (previous "{prev_desc}", actual_bytes: {"".join("%02x" % v for v in actual_bytes)} bytes: {str(font_bytes[pos:pos+16])}') print(
f'{description} (previous "{prev_desc}", actual_bytes: {"".join("%02x" % v for v in actual_bytes)} bytes: {str(font_bytes[pos:pos+16])}'
)
errors += 1 errors += 1
pos += len(expected_bytes) pos += len(expected_bytes)
prev_desc = description prev_desc = description
@ -141,7 +143,7 @@ COLR_V1_SAMPLE = (
(b"\x04", "BaseGlyphPaintRecord[0].Paint.NumLayers (4)"), (b"\x04", "BaseGlyphPaintRecord[0].Paint.NumLayers (4)"),
(b"\x00\x00\x00\x00", "BaseGlyphPaintRecord[0].Paint.FirstLayerIndex (0)"), (b"\x00\x00\x00\x00", "BaseGlyphPaintRecord[0].Paint.FirstLayerIndex (0)"),
# BaseGlyphPaintRecord[1] # BaseGlyphPaintRecord[1]
(b"\x14", "BaseGlyphPaintRecord[1].Paint.Format (20)"), (b"\x20", "BaseGlyphPaintRecord[1].Paint.Format (32)"),
(b"\x00\x00<", "Offset to SourcePaint from beginning of PaintComposite (60)"), (b"\x00\x00<", "Offset to SourcePaint from beginning of PaintComposite (60)"),
(b"\x03", "BaseGlyphPaintRecord[1].Paint.CompositeMode [SRC_OVER] (3)"), (b"\x03", "BaseGlyphPaintRecord[1].Paint.CompositeMode [SRC_OVER] (3)"),
(b"\x00\x00\x08", "Offset to BackdropPaint from beginning of PaintComposite (8)"), (b"\x00\x00\x08", "Offset to BackdropPaint from beginning of PaintComposite (8)"),
@ -256,19 +258,23 @@ COLR_V1_SAMPLE = (
(b"\x00\x00\x0c", "Offset to Paint subtable from beginning of PaintTranslate (12)"), (b"\x00\x00\x0c", "Offset to Paint subtable from beginning of PaintTranslate (12)"),
(b"\x01\x01\x00\x00", "dx (257)"), (b"\x01\x01\x00\x00", "dx (257)"),
(b"\x01\x02\x00\x00", "dy (258)"), (b"\x01\x02\x00\x00", "dy (258)"),
# PaintRotate # PaintRotateAroundCenter
(b"\x10", "LayerList.Paint[3].Paint.Format (16)"), (b"\x1a", "LayerList.Paint[3].Paint.Format (26)"),
(b"\x00\x00\x10", "Offset to Paint subtable from beginning of PaintRotate (16)"), (
b"\x00\x00\x10",
"Offset to Paint subtable from beginning of PaintRotateAroundCenter (16)",
),
(b"\x00\x2d\x00\x00", "angle (45)"), (b"\x00\x2d\x00\x00", "angle (45)"),
(b"\x00\xff\x00\x00", "centerX (255)"), (b"\x00\xff\x00\x00", "centerX (255)"),
(b"\x01\x00\x00\x00", "centerY (256)"), (b"\x01\x00\x00\x00", "centerY (256)"),
# PaintSkew # PaintSkew
(b"\x12", "LayerList.Paint[3].Paint.Paint.Format (18)"), (b"\x1c", "LayerList.Paint[3].Paint.Paint.Format (28)"),
(b"\x00\x00\x14", "Offset to Paint subtable from beginning of PaintSkew (20)"), (
b"\x00\x00\x0c",
"Offset to Paint subtable from beginning of PaintSkew (12)",
),
(b"\xff\xf5\x00\x00", "xSkewAngle (-11)"), (b"\xff\xf5\x00\x00", "xSkewAngle (-11)"),
(b"\x00\x05\x00\x00", "ySkewAngle (5)"), (b"\x00\x05\x00\x00", "ySkewAngle (5)"),
(b"\x00\xfd\x00\x00", "centerX.value (253)"),
(b"\x00\xfe\x00\x00", "centerY.value (254)"),
# PaintGlyph # PaintGlyph
(b"\x0a", "LayerList.Paint[3].Paint.Paint.Paint.Format (10)"), (b"\x0a", "LayerList.Paint[3].Paint.Paint.Paint.Format (10)"),
(b"\x00\x00\x06", "Offset to Paint subtable from beginning of PaintGlyph (6)"), (b"\x00\x00\x06", "Offset to Paint subtable from beginning of PaintGlyph (6)"),
@ -317,7 +323,7 @@ COLR_V1_XML = [
" </BaseGlyphPaintRecord>", " </BaseGlyphPaintRecord>",
' <BaseGlyphPaintRecord index="1">', ' <BaseGlyphPaintRecord index="1">',
' <BaseGlyph value="glyph00014"/>', ' <BaseGlyph value="glyph00014"/>',
' <Paint Format="20"><!-- PaintComposite -->', ' <Paint Format="32"><!-- PaintComposite -->',
' <SourcePaint Format="11"><!-- PaintColrGlyph -->', ' <SourcePaint Format="11"><!-- PaintColrGlyph -->',
' <Glyph value="glyph00010"/>', ' <Glyph value="glyph00010"/>',
" </SourcePaint>", " </SourcePaint>",
@ -455,8 +461,8 @@ COLR_V1_XML = [
' <Glyph value="glyph00013"/>', ' <Glyph value="glyph00013"/>',
" </Paint>", " </Paint>",
' <Paint index="3" Format="14"><!-- PaintTranslate -->', ' <Paint index="3" Format="14"><!-- PaintTranslate -->',
' <Paint Format="16"><!-- PaintRotate -->', ' <Paint Format="26"><!-- PaintRotateAroundCenter -->',
' <Paint Format="18"><!-- PaintSkew -->', ' <Paint Format="28"><!-- PaintSkew -->',
' <Paint Format="10"><!-- PaintGlyph -->', ' <Paint Format="10"><!-- PaintGlyph -->',
' <Paint Format="2"><!-- PaintSolid -->', ' <Paint Format="2"><!-- PaintSolid -->',
" <Color>", " <Color>",
@ -468,8 +474,6 @@ COLR_V1_XML = [
" </Paint>", " </Paint>",
' <xSkewAngle value="-11.0"/>', ' <xSkewAngle value="-11.0"/>',
' <ySkewAngle value="5.0"/>', ' <ySkewAngle value="5.0"/>',
' <centerX value="253.0"/>',
' <centerY value="254.0"/>',
" </Paint>", " </Paint>",
' <angle value="45.0"/>', ' <angle value="45.0"/>',
' <centerX value="255.0"/>', ' <centerX value="255.0"/>',