Merge pull request #2182 from fonttools/colrv1_static

Update otData for static vs variable formats of COLR v1
This commit is contained in:
Cosimo Lupo 2021-02-15 11:00:01 +00:00 committed by GitHub
commit 7878c32a85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 573 additions and 312 deletions

View File

@ -56,7 +56,7 @@ _DEFAULT_ALPHA = VariableFloat(1.0)
_MAX_REUSE_LEN = 32 _MAX_REUSE_LEN = 32
def _beforeBuildPaintRadialGradient(paint, source): def _beforeBuildPaintVarRadialGradient(paint, source, srcMapFn=lambda v: v):
# normalize input types (which may or may not specify a varIdx) # normalize input types (which may or may not specify a varIdx)
x0 = convertTupleClass(VariableFloat, source["x0"]) x0 = convertTupleClass(VariableFloat, source["x0"])
y0 = convertTupleClass(VariableFloat, source["y0"]) y0 = convertTupleClass(VariableFloat, source["y0"])
@ -75,18 +75,28 @@ def _beforeBuildPaintRadialGradient(paint, source):
r0 = r0._replace(value=c.radius) r0 = r0._replace(value=c.radius)
# update source to ensure paint is built with corrected values # update source to ensure paint is built with corrected values
source["x0"] = x0 source["x0"] = srcMapFn(x0)
source["y0"] = y0 source["y0"] = srcMapFn(y0)
source["r0"] = r0 source["r0"] = srcMapFn(r0)
source["x1"] = x1 source["x1"] = srcMapFn(x1)
source["y1"] = y1 source["y1"] = srcMapFn(y1)
source["r1"] = r1 source["r1"] = srcMapFn(r1)
return paint, source return paint, source
def _beforeBuildPaintRadialGradient(paint, source):
return _beforeBuildPaintVarRadialGradient(paint, source, lambda v: v.value)
def _defaultColorIndex(): def _defaultColorIndex():
colorIndex = ot.ColorIndex() colorIndex = ot.ColorIndex()
colorIndex.Alpha = _DEFAULT_ALPHA.value
return colorIndex
def _defaultVarColorIndex():
colorIndex = ot.VarColorIndex()
colorIndex.Alpha = _DEFAULT_ALPHA colorIndex.Alpha = _DEFAULT_ALPHA
return colorIndex return colorIndex
@ -97,6 +107,12 @@ def _defaultColorLine():
return colorLine return colorLine
def _defaultVarColorLine():
colorLine = ot.VarColorLine()
colorLine.Extend = ExtendMode.PAD
return colorLine
def _buildPaintCallbacks(): def _buildPaintCallbacks():
return { return {
( (
@ -104,8 +120,15 @@ def _buildPaintCallbacks():
ot.Paint, ot.Paint,
ot.PaintFormat.PaintRadialGradient, ot.PaintFormat.PaintRadialGradient,
): _beforeBuildPaintRadialGradient, ): _beforeBuildPaintRadialGradient,
(
BuildCallback.BEFORE_BUILD,
ot.Paint,
ot.PaintFormat.PaintVarRadialGradient,
): _beforeBuildPaintVarRadialGradient,
(BuildCallback.CREATE_DEFAULT, ot.ColorIndex): _defaultColorIndex, (BuildCallback.CREATE_DEFAULT, ot.ColorIndex): _defaultColorIndex,
(BuildCallback.CREATE_DEFAULT, ot.VarColorIndex): _defaultVarColorIndex,
(BuildCallback.CREATE_DEFAULT, ot.ColorLine): _defaultColorLine, (BuildCallback.CREATE_DEFAULT, ot.ColorLine): _defaultColorLine,
(BuildCallback.CREATE_DEFAULT, ot.VarColorLine): _defaultVarColorLine,
} }

View File

@ -59,14 +59,20 @@ def buildConverters(tableSpec, tableNamespace):
converterClass = Struct converterClass = Struct
else: else:
converterClass = eval(tp, tableNamespace, converterMapping) converterClass = eval(tp, tableNamespace, converterMapping)
if tp in ('MortChain', 'MortSubtable', 'MorxChain'):
conv = converterClass(name, repeat, aux)
if conv.tableClass:
# A "template" such as OffsetTo(AType) knowss the table class already
tableClass = conv.tableClass
elif tp in ('MortChain', 'MortSubtable', 'MorxChain'):
tableClass = tableNamespace.get(tp) tableClass = tableNamespace.get(tp)
else: else:
tableClass = tableNamespace.get(tableName) tableClass = tableNamespace.get(tableName)
if tableClass is not None:
conv = converterClass(name, repeat, aux, tableClass=tableClass) if not conv.tableClass:
else: conv.tableClass = tableClass
conv = converterClass(name, repeat, aux)
if name in ["SubTable", "ExtSubTable", "SubStruct"]: if name in ["SubTable", "ExtSubTable", "SubStruct"]:
conv.lookupTypes = tableNamespace['lookupTypes'] conv.lookupTypes = tableNamespace['lookupTypes']
# also create reverse mapping # also create reverse mapping

View File

@ -1598,6 +1598,14 @@ otData = [
# basis vector. # basis vector.
# See https://github.com/googlefonts/colr-gradients-spec/pull/85 # See https://github.com/googlefonts/colr-gradients-spec/pull/85
('Affine2x3', [ ('Affine2x3', [
('Fixed', 'xx', None, None, 'x-part of x basis vector'),
('Fixed', 'yx', None, None, 'y-part of x basis vector'),
('Fixed', 'xy', None, None, 'x-part of y basis vector'),
('Fixed', 'yy', None, None, 'y-part of y basis vector'),
('Fixed', 'dx', None, None, 'Translation in x direction'),
('Fixed', 'dy', None, None, 'Translation in y direction'),
]),
('VarAffine2x3', [
('VarFixed', 'xx', None, None, 'x-part of x basis vector'), ('VarFixed', 'xx', None, None, 'x-part of x basis vector'),
('VarFixed', 'yx', None, None, 'y-part of x basis vector'), ('VarFixed', 'yx', None, None, 'y-part of x basis vector'),
('VarFixed', 'xy', None, None, 'x-part of y basis vector'), ('VarFixed', 'xy', None, None, 'x-part of y basis vector'),
@ -1607,35 +1615,67 @@ otData = [
]), ]),
('ColorIndex', [ ('ColorIndex', [
('uint16', 'PaletteIndex', None, None, 'Index value to use with a selected color palette.'),
('F2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved'),
]),
('VarColorIndex', [
('uint16', 'PaletteIndex', None, None, 'Index value to use with a selected color palette.'), ('uint16', 'PaletteIndex', None, None, 'Index value to use with a selected color palette.'),
('VarF2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved'), ('VarF2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved'),
]), ]),
('ColorStop', [ ('ColorStop', [
('VarF2Dot14', 'StopOffset', None, None, ''), ('F2Dot14', 'StopOffset', None, None, ''),
('ColorIndex', 'Color', None, None, ''), ('ColorIndex', 'Color', None, None, ''),
]), ]),
('VarColorStop', [
('VarF2Dot14', 'StopOffset', None, None, ''),
('VarColorIndex', 'Color', None, None, ''),
]),
('ColorLine', [ ('ColorLine', [
('ExtendMode', 'Extend', None, None, 'Enum {PAD = 0, REPEAT = 1, REFLECT = 2}'), ('ExtendMode', 'Extend', None, None, 'Enum {PAD = 0, REPEAT = 1, REFLECT = 2}'),
('uint16', 'StopCount', None, None, 'Number of Color stops.'), ('uint16', 'StopCount', None, None, 'Number of Color stops.'),
('ColorStop', 'ColorStop', 'StopCount', 0, 'Array of Color stops.'), ('ColorStop', 'ColorStop', 'StopCount', 0, 'Array of Color stops.'),
]), ]),
('VarColorLine', [
('ExtendMode', 'Extend', None, None, 'Enum {PAD = 0, REPEAT = 1, REFLECT = 2}'),
('uint16', 'StopCount', None, None, 'Number of Color stops.'),
('VarColorStop', 'ColorStop', 'StopCount', 0, 'Array of Color stops.'),
]),
# PaintColrLayers # PaintColrLayers
('PaintFormat1', [ ('PaintFormat1', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 1'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 1'),
('uint8', 'NumLayers', None, None, 'Number of offsets to Paint to read from LayerV1List.'), ('uint8', 'NumLayers', None, None, 'Number of offsets to Paint to read from LayerV1List.'),
('uint32', 'FirstLayerIndex', None, None, 'Index into LayerV1List.'), ('uint32', 'FirstLayerIndex', None, None, 'Index into LayerV1List.'),
]), ]),
# PaintSolid # PaintSolid
('PaintFormat2', [ ('PaintFormat2', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 2'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 2'),
('ColorIndex', 'Color', None, None, 'A solid color paint.'), ('ColorIndex', 'Color', None, None, 'A solid color paint.'),
]), ]),
# PaintLinearGradient # PaintVarSolid
('PaintFormat3', [ ('PaintFormat3', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 3'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 3'),
('VarColorIndex', 'Color', None, None, 'A solid color paint.'),
]),
# PaintLinearGradient
('PaintFormat4', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 4'),
('Offset24', 'ColorLine', None, None, 'Offset (from beginning of PaintLinearGradient table) to ColorLine subtable.'), ('Offset24', 'ColorLine', None, None, 'Offset (from beginning of PaintLinearGradient table) to ColorLine subtable.'),
('int16', 'x0', None, None, ''),
('int16', 'y0', None, None, ''),
('int16', 'x1', None, None, ''),
('int16', 'y1', None, None, ''),
('int16', 'x2', None, None, ''),
('int16', 'y2', None, None, ''),
]),
# PaintVarLinearGradient
('PaintFormat5', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 5'),
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarLinearGradient table) to VarColorLine subtable.'),
('VarInt16', 'x0', None, None, ''), ('VarInt16', 'x0', None, None, ''),
('VarInt16', 'y0', None, None, ''), ('VarInt16', 'y0', None, None, ''),
('VarInt16', 'x1', None, None, ''), ('VarInt16', 'x1', None, None, ''),
@ -1643,10 +1683,22 @@ otData = [
('VarInt16', 'x2', None, None, ''), ('VarInt16', 'x2', None, None, ''),
('VarInt16', 'y2', None, None, ''), ('VarInt16', 'y2', None, None, ''),
]), ]),
# PaintRadialGradient # PaintRadialGradient
('PaintFormat4', [ ('PaintFormat6', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 4'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 6'),
('Offset24', 'ColorLine', None, None, 'Offset (from beginning of PaintRadialGradient table) to ColorLine subtable.'), ('Offset24', 'ColorLine', None, None, 'Offset (from beginning of PaintRadialGradient table) to ColorLine subtable.'),
('int16', 'x0', None, None, ''),
('int16', 'y0', None, None, ''),
('uint16', 'r0', None, None, ''),
('int16', 'x1', None, None, ''),
('int16', 'y1', None, None, ''),
('uint16', 'r1', None, None, ''),
]),
# PaintVarRadialGradient
('PaintFormat7', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 7'),
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarRadialGradient table) to VarColorLine subtable.'),
('VarInt16', 'x0', None, None, ''), ('VarInt16', 'x0', None, None, ''),
('VarInt16', 'y0', None, None, ''), ('VarInt16', 'y0', None, None, ''),
('VarUInt16', 'r0', None, None, ''), ('VarUInt16', 'r0', None, None, ''),
@ -1654,59 +1706,106 @@ otData = [
('VarInt16', 'y1', None, None, ''), ('VarInt16', 'y1', None, None, ''),
('VarUInt16', 'r1', None, None, ''), ('VarUInt16', 'r1', None, None, ''),
]), ]),
# PaintSweepGradient # PaintSweepGradient
('PaintFormat5', [ ('PaintFormat8', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 5'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 8'),
('Offset24', 'ColorLine', None, None, 'Offset (from beginning of PaintSweepGradient table) to ColorLine subtable.'), ('Offset24', 'ColorLine', None, None, 'Offset (from beginning of PaintSweepGradient table) to ColorLine subtable.'),
('int16', 'centerX', None, None, 'Center x coordinate.'),
('int16', 'centerY', None, None, 'Center y coordinate.'),
('Fixed', 'startAngle', None, None, 'Start of the angular range of the gradient.'),
('Fixed', 'endAngle', None, None, 'End of the angular range of the gradient.'),
]),
# PaintVarSweepGradient
('PaintFormat9', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 9'),
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarSweepGradient table) to VarColorLine subtable.'),
('VarInt16', 'centerX', None, None, 'Center x coordinate.'), ('VarInt16', 'centerX', None, None, 'Center x coordinate.'),
('VarInt16', 'centerY', None, None, 'Center y coordinate.'), ('VarInt16', 'centerY', None, None, 'Center y coordinate.'),
('VarFixed', 'startAngle', None, None, 'Start of the angular range of the gradient.'), ('VarFixed', 'startAngle', None, None, 'Start of the angular range of the gradient.'),
('VarFixed', 'endAngle', None, None, 'End of the angular range of the gradient.'), ('VarFixed', 'endAngle', None, None, 'End of the angular range of the gradient.'),
]), ]),
# PaintGlyph # PaintGlyph
('PaintFormat6', [ ('PaintFormat10', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 6'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 10'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintGlyph table) to Paint subtable.'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintGlyph table) to Paint subtable.'),
('GlyphID', 'Glyph', None, None, 'Glyph ID for the source outline.'), ('GlyphID', 'Glyph', None, None, 'Glyph ID for the source outline.'),
]), ]),
# PaintColrGlyph # PaintColrGlyph
('PaintFormat7', [ ('PaintFormat11', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 7'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 11'),
('GlyphID', 'Glyph', None, None, 'Virtual glyph ID for a BaseGlyphV1List base glyph.'), ('GlyphID', 'Glyph', None, None, 'Virtual glyph ID for a BaseGlyphV1List base glyph.'),
]), ]),
# PaintTransform # PaintTransform
('PaintFormat8', [ ('PaintFormat12', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 8'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 12'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintTransform table) to Paint subtable.'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintTransform table) to Paint subtable.'),
('Affine2x3', 'Transform', None, None, '2x3 matrix for 2D affine transformations.'), ('Affine2x3', 'Transform', None, None, '2x3 matrix for 2D affine transformations.'),
]), ]),
# PaintVarTransform
('PaintFormat13', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 13'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarTransform table) to Paint subtable.'),
('VarAffine2x3', 'Transform', None, None, '2x3 matrix for 2D affine transformations.'),
]),
# PaintTranslate # PaintTranslate
('PaintFormat9', [ ('PaintFormat14', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 9'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 14'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintTranslate table) to Paint subtable.'), ('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintTranslate table) to Paint subtable.'),
('Fixed', 'dx', None, None, 'Translation in x direction.'),
('Fixed', 'dy', None, None, 'Translation in y direction.'),
]),
# PaintVarTranslate
('PaintFormat15', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 15'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarTranslate table) to Paint subtable.'),
('VarFixed', 'dx', None, None, 'Translation in x direction.'), ('VarFixed', 'dx', None, None, 'Translation in x direction.'),
('VarFixed', 'dy', None, None, 'Translation in y direction.'), ('VarFixed', 'dy', None, None, 'Translation in y direction.'),
]), ]),
# PaintRotate # PaintRotate
('PaintFormat10', [ ('PaintFormat16', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 10'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 16'),
('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', 'centerX', None, None, ''),
('Fixed', 'centerY', None, None, ''),
]),
# PaintVarRotate
('PaintFormat17', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 17'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotate 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
('PaintFormat11', [ ('PaintFormat18', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 11'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 18'),
('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', 'ySkewAngle', None, None, ''),
('Fixed', 'centerX', None, None, ''),
('Fixed', 'centerY', None, None, ''),
]),
# PaintVarSkew
('PaintFormat19', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 19'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkew 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, ''),
('VarFixed', 'centerY', None, None, ''), ('VarFixed', 'centerY', None, None, ''),
]), ]),
# PaintComposite # PaintComposite
('PaintFormat12', [ ('PaintFormat20', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 12'), ('uint8', 'PaintFormat', None, None, 'Format identifier-format = 20'),
('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

@ -1327,16 +1327,24 @@ class CompositeMode(IntEnum):
class PaintFormat(IntEnum): class PaintFormat(IntEnum):
PaintColrLayers = 1 PaintColrLayers = 1
PaintSolid = 2 PaintSolid = 2
PaintLinearGradient = 3 PaintVarSolid = 3,
PaintRadialGradient = 4 PaintLinearGradient = 4
PaintSweepGradient = 5 PaintVarLinearGradient = 5
PaintGlyph = 6 PaintRadialGradient = 6
PaintColrGlyph = 7 PaintVarRadialGradient = 7
PaintTransform = 8 PaintSweepGradient = 8
PaintTranslate = 9 PaintVarSweepGradient = 9
PaintRotate = 10 PaintGlyph = 10
PaintSkew = 11 PaintColrGlyph = 11
PaintComposite = 12 PaintTransform = 12
PaintVarTransform = 13
PaintTranslate = 14
PaintVarTranslate = 15
PaintRotate = 16
PaintVarRotate = 17
PaintSkew = 18
PaintVarSkew = 19
PaintComposite = 20
class Paint(getFormatSwitchingBaseTableClass("uint8")): class Paint(getFormatSwitchingBaseTableClass("uint8")):

View File

@ -231,22 +231,27 @@ def test_buildCPAL_invalid_color():
builder.buildCPAL([[(0, 0, 0, 0)], [(1, 1, -1, 2)]]) builder.buildCPAL([[(0, 0, 0, 0)], [(1, 1, -1, 2)]])
def test_buildColorIndex(): def test_buildColorIndex_Minimal():
c = _build(ot.ColorIndex, 1) c = _build(ot.ColorIndex, 1)
assert c.PaletteIndex == 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.value == 1.0
assert c.Alpha.varIdx == 0 assert c.Alpha.varIdx == 0
def test_buildColorIndex_Alpha(): def test_buildColorIndex():
c = _build(ot.ColorIndex, (1, 0.5)) c = _build(ot.ColorIndex, (1, 0.5))
assert c.PaletteIndex == 1 assert c.PaletteIndex == 1
assert c.Alpha.value == 0.5 assert c.Alpha == 0.5
assert c.Alpha.varIdx == 0
def test_buildColorIndex_Variable(): def test_buildVarColorIndex():
c = _build(ot.ColorIndex, (3, builder.VariableFloat(0.5, varIdx=2))) c = _build(ot.VarColorIndex, (3, builder.VariableFloat(0.5, varIdx=2)))
assert c.PaletteIndex == 3 assert c.PaletteIndex == 3
assert c.Alpha.value == 0.5 assert c.Alpha.value == 0.5
assert c.Alpha.varIdx == 2 assert c.Alpha.varIdx == 2
@ -256,30 +261,35 @@ def test_buildPaintSolid():
p = _buildPaint((ot.PaintFormat.PaintSolid, 0)) p = _buildPaint((ot.PaintFormat.PaintSolid, 0))
assert p.Format == ot.PaintFormat.PaintSolid assert p.Format == ot.PaintFormat.PaintSolid
assert p.Color.PaletteIndex == 0 assert p.Color.PaletteIndex == 0
assert p.Color.Alpha.value == 1.0 assert p.Color.Alpha == 1.0
assert p.Color.Alpha.varIdx == 0
def test_buildPaintSolid_Alpha(): 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.Format == ot.PaintFormat.PaintSolid
assert p.Color.PaletteIndex == 1 assert p.Color.PaletteIndex == 1
assert p.Color.Alpha.value == 0.5 assert p.Color.Alpha == 0.5
assert p.Color.Alpha.varIdx == 0
def test_buildPaintSolid_Variable(): def test_buildPaintVarSolid():
p = _buildPaint( p = _buildPaint(
(ot.PaintFormat.PaintSolid, (3, builder.VariableFloat(0.5, varIdx=2))) (ot.PaintFormat.PaintVarSolid, (3, builder.VariableFloat(0.5, varIdx=2)))
) )
assert p.Format == ot.PaintFormat.PaintSolid assert p.Format == ot.PaintFormat.PaintVarSolid
assert p.Color.PaletteIndex == 3 assert p.Color.PaletteIndex == 3
assert p.Color.Alpha.value == 0.5 assert p.Color.Alpha.value == 0.5
assert p.Color.Alpha.varIdx == 2 assert p.Color.Alpha.varIdx == 2
def test_buildColorStop_DefaultAlpha(): def test_buildVarColorStop_DefaultAlpha():
s = _build(ot.ColorStop, (0.1, 2)) 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
def test_buildVarColorStop_DefaultAlpha():
s = _build(ot.VarColorStop, (0.1, 2))
assert s.StopOffset == builder.VariableFloat(0.1) assert s.StopOffset == builder.VariableFloat(0.1)
assert s.Color.PaletteIndex == 2 assert s.Color.PaletteIndex == 2
assert s.Color.Alpha == builder._DEFAULT_ALPHA assert s.Color.Alpha == builder._DEFAULT_ALPHA
@ -289,13 +299,13 @@ def test_buildColorStop():
s = _build( s = _build(
ot.ColorStop, {"StopOffset": 0.2, "Color": {"PaletteIndex": 3, "Alpha": 0.4}} ot.ColorStop, {"StopOffset": 0.2, "Color": {"PaletteIndex": 3, "Alpha": 0.4}}
) )
assert s.StopOffset == builder.VariableFloat(0.2) assert s.StopOffset == 0.2
assert s.Color == _build(ot.ColorIndex, (3, 0.4)) assert s.Color == _build(ot.ColorIndex, (3, 0.4))
def test_buildColorStop_Variable(): def test_buildColorStop_Variable():
s = _build( s = _build(
ot.ColorStop, ot.VarColorStop,
{ {
"StopOffset": builder.VariableFloat(0.0, varIdx=1), "StopOffset": builder.VariableFloat(0.0, varIdx=1),
"Color": { "Color": {
@ -315,9 +325,7 @@ def test_buildColorLine_StopList():
cline = _build(ot.ColorLine, {"ColorStop": stops}) cline = _build(ot.ColorLine, {"ColorStop": stops})
assert cline.Extend == builder.ExtendMode.PAD assert cline.Extend == builder.ExtendMode.PAD
assert cline.StopCount == 3 assert cline.StopCount == 3
assert [ assert [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
(cs.StopOffset.value, cs.Color.PaletteIndex) for cs in cline.ColorStop
] == stops
cline = _build(ot.ColorLine, {"Extend": "pad", "ColorStop": stops}) cline = _build(ot.ColorLine, {"Extend": "pad", "ColorStop": stops})
assert cline.Extend == builder.ExtendMode.PAD assert cline.Extend == builder.ExtendMode.PAD
@ -335,17 +343,15 @@ def test_buildColorLine_StopList():
cline = _build( cline = _build(
ot.ColorLine, {"ColorStop": [_build(ot.ColorStop, s) for s in stops]} ot.ColorLine, {"ColorStop": [_build(ot.ColorStop, s) for s in stops]}
) )
assert [ assert [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
(cs.StopOffset.value, cs.Color.PaletteIndex) for cs in cline.ColorStop
] == stops
def test_buildColorLine_StopMap_Variations(): def test_buildVarColorLine_StopMap():
stops = [ stops = [
{"StopOffset": (0.0, (1,)), "Color": {"PaletteIndex": 0, "Alpha": (0.5, 2)}}, {"StopOffset": (0.0, (1,)), "Color": {"PaletteIndex": 0, "Alpha": (0.5, 2)}},
{"StopOffset": (1.0, (3,)), "Color": {"PaletteIndex": 1, "Alpha": (0.3, 4)}}, {"StopOffset": (1.0, (3,)), "Color": {"PaletteIndex": 1, "Alpha": (0.3, 4)}},
] ]
cline = _build(ot.ColorLine, {"ColorStop": stops}) cline = _build(ot.VarColorLine, {"ColorStop": stops})
assert [ assert [
{ {
"StopOffset": cs.StopOffset, "StopOffset": cs.StopOffset,
@ -358,30 +364,49 @@ def test_buildColorLine_StopMap_Variations():
] == stops ] == stops
def checkBuildAffine2x3(cls, resultMapFn):
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)
def test_buildAffine2x3(): def test_buildAffine2x3():
matrix = _build(ot.Affine2x3, (1.5, 0, 0.5, 2.0, 1.0, -3.0)) checkBuildAffine2x3(ot.Affine2x3, lambda v: v)
assert matrix.xx == builder.VariableFloat(1.5)
assert matrix.yx == builder.VariableFloat(0.0)
assert matrix.xy == builder.VariableFloat(0.5)
assert matrix.yy == builder.VariableFloat(2.0)
assert matrix.dx == builder.VariableFloat(1.0)
assert matrix.dy == builder.VariableFloat(-3.0)
def _sample_stops(): def test_buildVarAffine2x3():
checkBuildAffine2x3(ot.VarAffine2x3, builder.VariableFloat)
def _sample_stops(cls):
return [ return [
_build(ot.ColorStop, (0.0, 0)), _build(cls, (0.0, 0)),
_build(ot.ColorStop, (0.5, 1)), _build(cls, (0.5, 1)),
_build(ot.ColorStop, (1.0, (2, 0.8))), _build(cls, (1.0, (2, 0.8))),
] ]
def test_buildPaintLinearGradient(): def _is_var(fmt):
color_stops = _sample_stops() return fmt.name.startswith("PaintVar")
x0, y0, x1, y1, x2, y2 = tuple(builder.VariableInt(v) for v in (1, 2, 3, 4, 5, 6))
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)
x0, y0, x1, y1, x2, y2 = tuple(inputMapFn(v) for v in (1, 2, 3, 4, 5, 6))
gradient = _buildPaint( gradient = _buildPaint(
{ {
"Format": ot.PaintFormat.PaintLinearGradient, "Format": fmt,
"ColorLine": {"ColorStop": color_stops}, "ColorLine": {"ColorStop": color_stops},
"x0": x0, "x0": x0,
"y0": y0, "y0": y0,
@ -395,39 +420,52 @@ def test_buildPaintLinearGradient():
assert gradient.ColorLine.ColorStop == color_stops assert gradient.ColorLine.ColorStop == color_stops
gradient = _buildPaint(gradient) gradient = _buildPaint(gradient)
assert (gradient.x0.value, gradient.y0.value) == (1, 2) assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == (1, 2)
assert (gradient.x1.value, gradient.y1.value) == (3, 4) assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == (3, 4)
assert (gradient.x2.value, gradient.y2.value) == (5, 6) assert (outputMapFn(gradient.x2), outputMapFn(gradient.y2)) == (5, 6)
def test_buildPaintRadialGradient(): def test_buildPaintLinearGradient():
color_stops = [ assert not _is_var(ot.PaintFormat.PaintLinearGradient)
_build(ot.ColorStop, (0.0, (0,))), checkBuildPaintLinearGradient(ot.PaintFormat.PaintLinearGradient)
_build(ot.ColorStop, (0.5, 1)),
_build(ot.ColorStop, (1.0, (2, 0.8))),
] def test_buildVarPaintLinearGradient():
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
color_line = _build( color_line = _build(
ot.ColorLine, {"ColorStop": color_stops, "Extend": builder.ExtendMode.REPEAT} line_cls, {"ColorStop": color_stops, "Extend": builder.ExtendMode.REPEAT}
) )
c0 = (builder.VariableInt(100), builder.VariableInt(200)) c0 = (inputMapFn(100), inputMapFn(200))
c1 = (builder.VariableInt(150), builder.VariableInt(250)) c1 = (inputMapFn(150), inputMapFn(250))
r0 = builder.VariableInt(10) r0 = inputMapFn(10)
r1 = builder.VariableInt(5) r1 = inputMapFn(5)
gradient = _build( gradient = _build(ot.Paint, (fmt, color_line, *c0, r0, *c1, r1))
ot.Paint, (ot.PaintFormat.PaintRadialGradient, color_line, *c0, r0, *c1, r1) assert gradient.Format == fmt
)
assert gradient.Format == ot.PaintFormat.PaintRadialGradient
assert gradient.ColorLine == color_line assert gradient.ColorLine == color_line
assert (gradient.x0, gradient.y0) == c0 assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == c0
assert (gradient.x1, gradient.y1) == c1 assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == c1
assert gradient.r0 == r0 assert outputMapFn(gradient.r0) == r0
assert gradient.r1 == r1 assert outputMapFn(gradient.r1) == r1
gradient = _build( gradient = _build(
ot.Paint, ot.Paint,
{ {
"Format": ot.PaintFormat.PaintRadialGradient, "Format": fmt,
"ColorLine": {"ColorStop": color_stops}, "ColorLine": {"ColorStop": color_stops},
"x0": c0[0], "x0": c0[0],
"y0": c0[1], "y0": c0[1],
@ -439,16 +477,31 @@ def test_buildPaintRadialGradient():
) )
assert gradient.ColorLine.Extend == builder.ExtendMode.PAD assert gradient.ColorLine.Extend == builder.ExtendMode.PAD
assert gradient.ColorLine.ColorStop == color_stops assert gradient.ColorLine.ColorStop == color_stops
assert (gradient.x0, gradient.y0) == c0 assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == c0
assert (gradient.x1, gradient.y1) == c1 assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == c1
assert gradient.r0 == r0 assert outputMapFn(gradient.r0) == r0
assert gradient.r1 == r1 assert outputMapFn(gradient.r1) == r1
def test_buildPaintSweepGradient(): def test_buildPaintRadialGradient():
assert not _is_var(ot.PaintFormat.PaintRadialGradient)
checkBuildPaintRadialGradient(ot.PaintFormat.PaintRadialGradient)
def test_buildPaintVarRadialGradient():
assert _is_var(ot.PaintFormat.PaintVarRadialGradient)
checkBuildPaintRadialGradient(ot.PaintFormat.PaintVarRadialGradient)
def checkPaintSweepGradient(fmt):
if _is_var(fmt):
outputMapFn = lambda v: v.value
else:
outputMapFn = lambda v: v
paint = _buildPaint( paint = _buildPaint(
{ {
"Format": ot.PaintFormat.PaintSweepGradient, "Format": fmt,
"ColorLine": { "ColorLine": {
"ColorStop": ( "ColorStop": (
(0.0, 0), (0.0, 0),
@ -463,11 +516,21 @@ def test_buildPaintSweepGradient():
} }
) )
assert paint.Format == ot.PaintFormat.PaintSweepGradient assert paint.Format == fmt
assert paint.centerX.value == 127 assert outputMapFn(paint.centerX) == 127
assert paint.centerY.value == 129 assert outputMapFn(paint.centerY) == 129
assert paint.startAngle.value == 15 assert outputMapFn(paint.startAngle) == 15
assert paint.endAngle.value == 42 assert outputMapFn(paint.endAngle) == 42
def test_buildPaintSweepGradient():
assert not _is_var(ot.PaintFormat.PaintSweepGradient)
checkPaintSweepGradient(ot.PaintFormat.PaintSweepGradient)
def test_buildPaintVarSweepGradient():
assert _is_var(ot.PaintFormat.PaintVarSweepGradient)
checkPaintSweepGradient(ot.PaintFormat.PaintVarSweepGradient)
def test_buildPaintGlyph_Solid(): def test_buildPaintGlyph_Solid():
@ -500,17 +563,17 @@ def test_buildPaintGlyph_Solid():
) )
assert layer.Paint.Format == ot.PaintFormat.PaintSolid assert layer.Paint.Format == ot.PaintFormat.PaintSolid
assert layer.Paint.Color.PaletteIndex == 3 assert layer.Paint.Color.PaletteIndex == 3
assert layer.Paint.Color.Alpha.value == 0.9 assert layer.Paint.Color.Alpha == 0.9
def test_buildPaintGlyph_LinearGradient(): def test_buildPaintGlyph_VarLinearGradient():
layer = _build( layer = _build(
ot.Paint, ot.Paint,
{ {
"Format": ot.PaintFormat.PaintGlyph, "Format": ot.PaintFormat.PaintGlyph,
"Glyph": "a", "Glyph": "a",
"Paint": { "Paint": {
"Format": ot.PaintFormat.PaintLinearGradient, "Format": ot.PaintFormat.PaintVarLinearGradient,
"ColorLine": {"ColorStop": [(0.0, 3), (1.0, 4)]}, "ColorLine": {"ColorStop": [(0.0, 3), (1.0, 4)]},
"x0": 100, "x0": 100,
"y0": 200, "y0": 200,
@ -519,7 +582,10 @@ def test_buildPaintGlyph_LinearGradient():
}, },
}, },
) )
assert layer.Paint.Format == ot.PaintFormat.PaintLinearGradient
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.value == 0.0
assert layer.Paint.ColorLine.ColorStop[0].Color.PaletteIndex == 3 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].StopOffset.value == 1.0
@ -557,19 +623,19 @@ def test_buildPaintGlyph_RadialGradient():
) )
assert layer.Format == ot.PaintFormat.PaintGlyph assert layer.Format == ot.PaintFormat.PaintGlyph
assert layer.Paint.Format == ot.PaintFormat.PaintRadialGradient assert layer.Paint.Format == ot.PaintFormat.PaintRadialGradient
assert layer.Paint.ColorLine.ColorStop[0].StopOffset.value == 0.0 assert layer.Paint.ColorLine.ColorStop[0].StopOffset == 0.0
assert layer.Paint.ColorLine.ColorStop[0].Color.PaletteIndex == 5 assert layer.Paint.ColorLine.ColorStop[0].Color.PaletteIndex == 5
assert layer.Paint.ColorLine.ColorStop[1].StopOffset.value == 0.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.PaletteIndex == 6
assert layer.Paint.ColorLine.ColorStop[1].Color.Alpha.value == 0.8 assert layer.Paint.ColorLine.ColorStop[1].Color.Alpha == 0.8
assert layer.Paint.ColorLine.ColorStop[2].StopOffset.value == 1.0 assert layer.Paint.ColorLine.ColorStop[2].StopOffset == 1.0
assert layer.Paint.ColorLine.ColorStop[2].Color.PaletteIndex == 7 assert layer.Paint.ColorLine.ColorStop[2].Color.PaletteIndex == 7
assert layer.Paint.x0.value == 50 assert layer.Paint.x0 == 50
assert layer.Paint.y0.value == 50 assert layer.Paint.y0 == 50
assert layer.Paint.r0.value == 30 assert layer.Paint.r0 == 30
assert layer.Paint.x1.value == 75 assert layer.Paint.x1 == 75
assert layer.Paint.y1.value == 75 assert layer.Paint.y1 == 75
assert layer.Paint.r1.value == 10 assert layer.Paint.r1 == 10
def test_buildPaintGlyph_Dict_Solid(): def test_buildPaintGlyph_Dict_Solid():
@ -588,14 +654,14 @@ def test_buildPaintGlyph_Dict_Solid():
assert layer.Paint.Color.PaletteIndex == 1 assert layer.Paint.Color.PaletteIndex == 1
def test_buildPaintGlyph_Dict_LinearGradient(): def test_buildPaintGlyph_Dict_VarLinearGradient():
layer = _build( layer = _build(
ot.Paint, ot.Paint,
{ {
"Format": ot.PaintFormat.PaintGlyph, "Format": ot.PaintFormat.PaintGlyph,
"Glyph": "a", "Glyph": "a",
"Paint": { "Paint": {
"Format": 3, "Format": int(ot.PaintFormat.PaintVarLinearGradient),
"ColorLine": {"ColorStop": [(0.0, 0), (1.0, 1)]}, "ColorLine": {"ColorStop": [(0.0, 0), (1.0, 1)]},
"x0": 0, "x0": 0,
"y0": 0, "y0": 0,
@ -606,7 +672,7 @@ def test_buildPaintGlyph_Dict_LinearGradient():
) )
assert layer.Format == ot.PaintFormat.PaintGlyph assert layer.Format == ot.PaintFormat.PaintGlyph
assert layer.Glyph == "a" assert layer.Glyph == "a"
assert layer.Paint.Format == ot.PaintFormat.PaintLinearGradient assert layer.Paint.Format == ot.PaintFormat.PaintVarLinearGradient
assert layer.Paint.ColorLine.ColorStop[0].StopOffset.value == 0.0 assert layer.Paint.ColorLine.ColorStop[0].StopOffset.value == 0.0
@ -628,7 +694,7 @@ def test_buildPaintGlyph_Dict_RadialGradient():
}, },
) )
assert layer.Paint.Format == ot.PaintFormat.PaintRadialGradient assert layer.Paint.Format == ot.PaintFormat.PaintRadialGradient
assert layer.Paint.r0.value == 4 assert layer.Paint.r0 == 4
def test_buildPaintColrGlyph(): def test_buildPaintColrGlyph():
@ -637,30 +703,38 @@ def test_buildPaintColrGlyph():
assert paint.Glyph == "a" assert paint.Glyph == "a"
def test_buildPaintTransform(): def checkBuildPaintTransform(fmt):
if _is_var(fmt):
inputMapFn = builder.VariableFloat
outputMapFn = lambda v: v.value
affine_cls = ot.VarAffine2x3
else:
inputMapFn = outputMapFn = lambda v: v
affine_cls = ot.Affine2x3
paint = _buildPaint( paint = _buildPaint(
( (
int(ot.PaintFormat.PaintTransform), int(fmt),
(ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, (0, 1.0)), "a"), (ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, (0, 1.0)), "a"),
_build(ot.Affine2x3, (1, 2, 3, 4, 5, 6)), _build(affine_cls, (1, 2, 3, 4, 5, 6)),
), ),
) )
assert paint.Format == ot.PaintFormat.PaintTransform assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
assert paint.Paint.Paint.Format == ot.PaintFormat.PaintSolid assert paint.Paint.Paint.Format == ot.PaintFormat.PaintSolid
assert paint.Transform.xx.value == 1.0 assert outputMapFn(paint.Transform.xx) == 1.0
assert paint.Transform.yx.value == 2.0 assert outputMapFn(paint.Transform.yx) == 2.0
assert paint.Transform.xy.value == 3.0 assert outputMapFn(paint.Transform.xy) == 3.0
assert paint.Transform.yy.value == 4.0 assert outputMapFn(paint.Transform.yy) == 4.0
assert paint.Transform.dx.value == 5.0 assert outputMapFn(paint.Transform.dx) == 5.0
assert paint.Transform.dy.value == 6.0 assert outputMapFn(paint.Transform.dy) == 6.0
paint = _build( paint = _build(
ot.Paint, ot.Paint,
{ {
"Format": ot.PaintFormat.PaintTransform, "Format": fmt,
"Transform": (1, 2, 3, 0.3333, 10, 10), "Transform": (1, 2, 3, 0.3333, 10, 10),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintRadialGradient), "Format": int(ot.PaintFormat.PaintRadialGradient),
@ -675,16 +749,26 @@ def test_buildPaintTransform():
}, },
) )
assert paint.Format == ot.PaintFormat.PaintTransform assert paint.Format == fmt
assert paint.Transform.xx.value == 1.0 assert outputMapFn(paint.Transform.xx) == 1.0
assert paint.Transform.yx.value == 2.0 assert outputMapFn(paint.Transform.yx) == 2.0
assert paint.Transform.xy.value == 3.0 assert outputMapFn(paint.Transform.xy) == 3.0
assert paint.Transform.yy.value == 0.3333 assert outputMapFn(paint.Transform.yy) == 0.3333
assert paint.Transform.dx.value == 10 assert outputMapFn(paint.Transform.dx) == 10
assert paint.Transform.dy.value == 10 assert outputMapFn(paint.Transform.dy) == 10
assert paint.Paint.Format == ot.PaintFormat.PaintRadialGradient assert paint.Paint.Format == ot.PaintFormat.PaintRadialGradient
def test_buildPaintTransform():
assert not _is_var(ot.PaintFormat.PaintTransform)
checkBuildPaintTransform(ot.PaintFormat.PaintTransform)
def test_buildPaintVarTransform():
assert _is_var(ot.PaintFormat.PaintVarTransform)
checkBuildPaintTransform(ot.PaintFormat.PaintVarTransform)
def test_buildPaintComposite(): def test_buildPaintComposite():
composite = _build( composite = _build(
ot.Paint, ot.Paint,
@ -734,11 +818,17 @@ def test_buildPaintComposite():
assert composite.BackdropPaint.Paint.Color.PaletteIndex == 0 assert composite.BackdropPaint.Paint.Color.PaletteIndex == 0
def test_buildPaintTranslate(): def checkBuildPaintTranslate(fmt):
if _is_var(fmt):
inputMapFn = builder.VariableInt
outputMapFn = lambda v: v.value
else:
inputMapFn = outputMapFn = lambda v: v
paint = _build( paint = _build(
ot.Paint, ot.Paint,
{ {
"Format": ot.PaintFormat.PaintTranslate, "Format": fmt,
"Paint": ( "Paint": (
ot.PaintFormat.PaintGlyph, ot.PaintFormat.PaintGlyph,
(ot.PaintFormat.PaintSolid, (0, 1.0)), (ot.PaintFormat.PaintSolid, (0, 1.0)),
@ -749,17 +839,33 @@ def test_buildPaintTranslate():
}, },
) )
assert paint.Format == ot.PaintFormat.PaintTranslate assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
assert paint.dx.value == 123 assert outputMapFn(paint.dx) == 123
assert paint.dy.value == -345 assert outputMapFn(paint.dy) == -345
def test_buildPaintRotate(): def test_buildPaintTranslate():
assert not _is_var(ot.PaintFormat.PaintTranslate)
checkBuildPaintTranslate(ot.PaintFormat.PaintTranslate)
def test_buildPaintVarTranslate():
assert _is_var(ot.PaintFormat.PaintVarTranslate)
checkBuildPaintTranslate(ot.PaintFormat.PaintVarTranslate)
def checkBuildPaintRotate(fmt):
if _is_var(fmt):
inputMapFn = builder.VariableInt
outputMapFn = lambda v: v.value
else:
inputMapFn = outputMapFn = lambda v: v
paint = _build( paint = _build(
ot.Paint, ot.Paint,
{ {
"Format": ot.PaintFormat.PaintRotate, "Format": fmt,
"Paint": ( "Paint": (
ot.PaintFormat.PaintGlyph, ot.PaintFormat.PaintGlyph,
(ot.PaintFormat.PaintSolid, (0, 1.0)), (ot.PaintFormat.PaintSolid, (0, 1.0)),
@ -771,18 +877,34 @@ def test_buildPaintRotate():
}, },
) )
assert paint.Format == ot.PaintFormat.PaintRotate assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
assert paint.angle.value == 15 assert outputMapFn(paint.angle) == 15
assert paint.centerX.value == 127 assert outputMapFn(paint.centerX) == 127
assert paint.centerY.value == 129 assert outputMapFn(paint.centerY) == 129
def test_buildPaintSkew(): def test_buildPaintRotate():
assert not _is_var(ot.PaintFormat.PaintRotate)
checkBuildPaintRotate(ot.PaintFormat.PaintRotate)
def test_buildPaintVarRotate():
assert _is_var(ot.PaintFormat.PaintVarRotate)
checkBuildPaintRotate(ot.PaintFormat.PaintVarRotate)
def checkBuildPaintSkew(fmt):
if _is_var(fmt):
inputMapFn = builder.VariableInt
outputMapFn = lambda v: v.value
else:
inputMapFn = outputMapFn = lambda v: v
paint = _build( paint = _build(
ot.Paint, ot.Paint,
{ {
"Format": ot.PaintFormat.PaintSkew, "Format": fmt,
"Paint": ( "Paint": (
ot.PaintFormat.PaintGlyph, ot.PaintFormat.PaintGlyph,
(ot.PaintFormat.PaintSolid, (0, 1.0)), (ot.PaintFormat.PaintSolid, (0, 1.0)),
@ -795,12 +917,22 @@ def test_buildPaintSkew():
}, },
) )
assert paint.Format == ot.PaintFormat.PaintSkew assert paint.Format == fmt
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
assert paint.xSkewAngle.value == 15 assert outputMapFn(paint.xSkewAngle) == 15
assert paint.ySkewAngle.value == 42 assert outputMapFn(paint.ySkewAngle) == 42
assert paint.centerX.value == 127 assert outputMapFn(paint.centerX) == 127
assert paint.centerY.value == 129 assert outputMapFn(paint.centerY) == 129
def test_buildPaintSkew():
assert not _is_var(ot.PaintFormat.PaintSkew)
checkBuildPaintSkew(ot.PaintFormat.PaintSkew)
def test_buildPaintVarSkew():
assert _is_var(ot.PaintFormat.PaintVarSkew)
checkBuildPaintSkew(ot.PaintFormat.PaintVarSkew)
def test_buildColrV1(): def test_buildColrV1():
@ -809,7 +941,7 @@ def test_buildColrV1():
ot.PaintFormat.PaintColrLayers, ot.PaintFormat.PaintColrLayers,
[ [
(ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, 0), "b"), (ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, 0), "b"),
(ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, 1), "c"), (ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintVarSolid, 1), "c"),
], ],
), ),
"d": ( "d": (
@ -817,13 +949,16 @@ def test_buildColrV1():
[ [
( (
ot.PaintFormat.PaintGlyph, ot.PaintFormat.PaintGlyph,
{"Format": 2, "Color": {"PaletteIndex": 2, "Alpha": 0.8}}, {
"Format": int(ot.PaintFormat.PaintSolid),
"Color": {"PaletteIndex": 2, "Alpha": 0.8},
},
"e", "e",
), ),
( (
ot.PaintFormat.PaintGlyph, ot.PaintFormat.PaintGlyph,
{ {
"Format": 4, "Format": int(ot.PaintFormat.PaintVarRadialGradient),
"ColorLine": { "ColorLine": {
"ColorStop": [(0.0, 3), (1.0, 4)], "ColorStop": [(0.0, 3), (1.0, 4)],
"Extend": "reflect", "Extend": "reflect",

View File

@ -12,14 +12,14 @@ TEST_COLOR_GLYPHS = {
"Format": int(ot.PaintFormat.PaintGlyph), "Format": int(ot.PaintFormat.PaintGlyph),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintSolid), "Format": int(ot.PaintFormat.PaintSolid),
"Color": {"PaletteIndex": 2, "Alpha": (0.5, 0)}, "Color": {"PaletteIndex": 2, "Alpha": 0.5},
}, },
"Glyph": "glyph00011", "Glyph": "glyph00011",
}, },
{ {
"Format": int(ot.PaintFormat.PaintGlyph), "Format": int(ot.PaintFormat.PaintGlyph),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintLinearGradient), "Format": int(ot.PaintFormat.PaintVarLinearGradient),
"ColorLine": { "ColorLine": {
"Extend": "repeat", "Extend": "repeat",
"ColorStop": [ "ColorStop": [
@ -49,28 +49,28 @@ TEST_COLOR_GLYPHS = {
{ {
"Format": int(ot.PaintFormat.PaintGlyph), "Format": int(ot.PaintFormat.PaintGlyph),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintTransform), "Format": int(ot.PaintFormat.PaintVarTransform),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintRadialGradient), "Format": int(ot.PaintFormat.PaintRadialGradient),
"ColorLine": { "ColorLine": {
"Extend": "pad", "Extend": "pad",
"ColorStop": [ "ColorStop": [
{ {
"StopOffset": (0.0, 0), "StopOffset": 0,
"Color": {"PaletteIndex": 6, "Alpha": (1.0, 0)}, "Color": {"PaletteIndex": 6, "Alpha": 1.0},
}, },
{ {
"StopOffset": (1.0, 0), "StopOffset": 1.0,
"Color": {"PaletteIndex": 7, "Alpha": (0.4, 0)}, "Color": {"PaletteIndex": 7, "Alpha": 0.4},
}, },
], ],
}, },
"x0": (7, 0), "x0": 7,
"y0": (8, 0), "y0": 8,
"r0": (9, 0), "r0": 9,
"x1": (10, 0), "x1": 10,
"y1": (11, 0), "y1": 11,
"r1": (12, 0), "r1": 12,
}, },
"Transform": { "Transform": {
"xx": (-13.0, 0), "xx": (-13.0, 0),
@ -84,16 +84,16 @@ TEST_COLOR_GLYPHS = {
"Glyph": "glyph00013", "Glyph": "glyph00013",
}, },
{ {
"Format": int(ot.PaintFormat.PaintTranslate), "Format": int(ot.PaintFormat.PaintVarTranslate),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintRotate), "Format": int(ot.PaintFormat.PaintRotate),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintSkew), "Format": int(ot.PaintFormat.PaintVarSkew),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintGlyph), "Format": int(ot.PaintFormat.PaintGlyph),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintSolid), "Format": int(ot.PaintFormat.PaintSolid),
"Color": {"PaletteIndex": 2, "Alpha": (0.5, 0)}, "Color": {"PaletteIndex": 2, "Alpha": 0.5},
}, },
"Glyph": "glyph00011", "Glyph": "glyph00011",
}, },
@ -102,9 +102,9 @@ TEST_COLOR_GLYPHS = {
"centerX": (253.0, 0), "centerX": (253.0, 0),
"centerY": (254.0, 0), "centerY": (254.0, 0),
}, },
"angle": (45.0, 0), "angle": 45.0,
"centerX": (255.0, 0), "centerX": 255.0,
"centerY": (256.0, 0), "centerY": 256.0,
}, },
"dx": (257.0, 0), "dx": (257.0, 0),
"dy": (258.0, 0), "dy": (258.0, 0),
@ -125,12 +125,12 @@ TEST_COLOR_GLYPHS = {
"Glyph": "glyph00010", "Glyph": "glyph00010",
}, },
"Transform": { "Transform": {
"xx": (1.0, 0), "xx": 1.0,
"yx": (0.0, 0), "yx": 0.0,
"xy": (0.0, 0), "xy": 0.0,
"yy": (1.0, 0), "yy": 1.0,
"dx": (300.0, 0), "dx": 300.0,
"dy": (0.0, 0), "dy": 0.0,
}, },
}, },
}, },
@ -142,19 +142,19 @@ TEST_COLOR_GLYPHS = {
"Extend": "pad", "Extend": "pad",
"ColorStop": [ "ColorStop": [
{ {
"StopOffset": (0.0, 0), "StopOffset": 0.0,
"Color": {"PaletteIndex": 3, "Alpha": (1.0, 0)}, "Color": {"PaletteIndex": 3, "Alpha": 1.0},
}, },
{ {
"StopOffset": (1.0, 0), "StopOffset": 1.0,
"Color": {"PaletteIndex": 5, "Alpha": (1.0, 0)}, "Color": {"PaletteIndex": 5, "Alpha": 1.0},
}, },
], ],
}, },
"centerX": (259, 0), "centerX": 259,
"centerY": (300, 0), "centerY": 300,
"startAngle": (45.0, 0), "startAngle": 45.0,
"endAngle": (135.0, 0), "endAngle": 135.0,
}, },
"Glyph": "glyph00011", "Glyph": "glyph00011",
}, },
@ -164,7 +164,7 @@ TEST_COLOR_GLYPHS = {
{ {
"Format": int(ot.PaintFormat.PaintGlyph), "Format": int(ot.PaintFormat.PaintGlyph),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintSolid), "Format": int(ot.PaintFormat.PaintVarSolid),
"Color": {"PaletteIndex": 2, "Alpha": (0.5, 0)}, "Color": {"PaletteIndex": 2, "Alpha": (0.5, 0)},
}, },
"Glyph": "glyph00011", "Glyph": "glyph00011",
@ -172,7 +172,7 @@ TEST_COLOR_GLYPHS = {
{ {
"Format": int(ot.PaintFormat.PaintGlyph), "Format": int(ot.PaintFormat.PaintGlyph),
"Paint": { "Paint": {
"Format": int(ot.PaintFormat.PaintLinearGradient), "Format": int(ot.PaintFormat.PaintVarLinearGradient),
"ColorLine": { "ColorLine": {
"Extend": "repeat", "Extend": "repeat",
"ColorStop": [ "ColorStop": [

View File

@ -46,13 +46,15 @@ def dump(table, ttFont=None):
def diff_binary_fragments(font_bytes, expected_fragments): def diff_binary_fragments(font_bytes, expected_fragments):
pos = 0 pos = 0
prev_desc = "" prev_desc = ""
errors = 0
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)]
assert ( if actual_bytes != expected_bytes:
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])}')
), f'{description} (previous "{prev_desc}", bytes: {str(font_bytes[pos:pos+16])}' errors += 1
pos += len(expected_bytes) pos += len(expected_bytes)
prev_desc = description prev_desc = description
assert errors == 0
assert pos == len( assert pos == len(
font_bytes font_bytes
), f"Leftover font bytes, used {pos} of {len(font_bytes)}" ), f"Leftover font bytes, used {pos} of {len(font_bytes)}"
@ -106,7 +108,7 @@ COLR_V1_SAMPLE = (
(b"\x00\x00\x00 ", "Offset to LayerRecordArray from beginning of table (32)"), (b"\x00\x00\x00 ", "Offset to LayerRecordArray from beginning of table (32)"),
(b"\x00\x03", "LayerRecordCount (3)"), (b"\x00\x03", "LayerRecordCount (3)"),
(b"\x00\x00\x00,", "Offset to BaseGlyphV1List from beginning of table (44)"), (b"\x00\x00\x00,", "Offset to BaseGlyphV1List from beginning of table (44)"),
(b"\x00\x00\x00\xcc", "Offset to LayerV1List from beginning of table (204)"), (b"\x00\x00\x00\xac", "Offset to LayerV1List from beginning of table (172)"),
(b"\x00\x00\x00\x00", "Offset to VarStore (NULL)"), (b"\x00\x00\x00\x00", "Offset to VarStore (NULL)"),
(b"\x00\x06", "BaseGlyphRecord[0].BaseGlyph (6)"), (b"\x00\x06", "BaseGlyphRecord[0].BaseGlyph (6)"),
(b"\x00\x00", "BaseGlyphRecord[0].FirstLayerIndex (0)"), (b"\x00\x00", "BaseGlyphRecord[0].FirstLayerIndex (0)"),
@ -139,42 +141,38 @@ COLR_V1_SAMPLE = (
(b"\x04", "BaseGlyphV1Record[0].Paint.NumLayers (4)"), (b"\x04", "BaseGlyphV1Record[0].Paint.NumLayers (4)"),
(b"\x00\x00\x00\x00", "BaseGlyphV1Record[0].Paint.FirstLayerIndex (0)"), (b"\x00\x00\x00\x00", "BaseGlyphV1Record[0].Paint.FirstLayerIndex (0)"),
# BaseGlyphV1Record[1] # BaseGlyphV1Record[1]
(b"\x0C", "BaseGlyphV1Record[1].Paint.Format (12)"), (b"\x14", "BaseGlyphV1Record[1].Paint.Format (20)"),
(b"\x00\x00<", "Offset to SourcePaint from beginning of PaintComposite (60)"), (b"\x00\x00<", "Offset to SourcePaint from beginning of PaintComposite (60)"),
(b"\x03", "BaseGlyphV1Record[1].Paint.CompositeMode [SRC_OVER] (3)"), (b"\x03", "BaseGlyphV1Record[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)"),
(b"\x08", "BaseGlyphV1Record[1].Paint.BackdropPaint.Format (8)"), (b"\x0d", "BaseGlyphV1Record[1].Paint.BackdropPaint.Format (13)"),
(b"\x00\x00\x34", "Offset to Paint from beginning of PaintTransform (52)"), (b"\x00\x00\x34", "Offset to Paint from beginning of PaintVarTransform (52)"),
(b"\x00\x01\x00\x00\x00\x00\x00\x00", "Affine2x3.xx.value (1.0)"), (b"\x00\x01\x00\x00\x00\x00\x00\x00", "Affine2x3.xx.value (1.0)"),
(b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.xy.value (0.0)"), (b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.xy.value (0.0)"),
(b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.yx.value (0.0)"), (b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.yx.value (0.0)"),
(b"\x00\x01\x00\x00\x00\x00\x00\x00", "Affine2x3.yy.value (1.0)"), (b"\x00\x01\x00\x00\x00\x00\x00\x00", "Affine2x3.yy.value (1.0)"),
(b"\x01\x2c\x00\x00\x00\x00\x00\x00", "Affine2x3.dx.value (300.0)"), (b"\x01\x2c\x00\x00\x00\x00\x00\x00", "Affine2x3.dx.value (300.0)"),
(b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.dy.value (0.0)"), (b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.dy.value (0.0)"),
(b"\x07", "BaseGlyphV1Record[1].Paint.SourcePaint.Format (7)"), (b"\x0b", "BaseGlyphV1Record[1].Paint.SourcePaint.Format (11)"),
(b"\x00\n", "BaseGlyphV1Record[1].Paint.SourcePaint.Glyph (10)"), (b"\x00\n", "BaseGlyphV1Record[1].Paint.SourcePaint.Glyph (10)"),
# BaseGlyphV1Record[2] # BaseGlyphV1Record[2]
(b"\x06", "BaseGlyphV1Record[2].Paint.Format (6)"), (b"\x0a", "BaseGlyphV1Record[2].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)"),
(b"\x00\x0b", "BaseGlyphV1Record[2].Paint.Glyph (11)"), (b"\x00\x0b", "BaseGlyphV1Record[2].Paint.Glyph (11)"),
(b"\x05", "BaseGlyphV1Record[2].Paint.Paint.Format (5)"), (b"\x08", "BaseGlyphV1Record[2].Paint.Paint.Format (8)"),
(b"\x00\x00 ", "Offset to ColorLine from beginning of PaintSweepGradient (32)"), (b"\x00\x00\x10", "Offset to ColorLine from beginning of PaintSweepGradient (16)"),
(b"\x01\x03\x00\x00\x00\x00", "centerX.value (259)"), (b"\x01\x03", "centerX (259)"),
(b"\x01\x2c\x00\x00\x00\x00", "centerY.value (300)"), (b"\x01\x2c", "centerY (300)"),
(b"\x00\x2d\x00\x00\x00\x00\x00\x00", "startAngle (45.0)"), (b"\x00\x2d\x00\x00", "startAngle (45.0)"),
(b"\x00\x87\x00\x00\x00\x00\x00\x00", "endAngle (135.0)"), (b"\x00\x87\x00\x00", "endAngle (135.0)"),
(b"\x00", "ColorLine.Extend (0; pad)"), (b"\x00", "ColorLine.Extend (0; pad)"),
(b"\x00\x02", "ColorLine.StopCount (2)"), (b"\x00\x02", "ColorLine.StopCount (2)"),
(b"\x00\x00", "ColorLine.ColorStop[0].StopOffset.value (0.0)"), (b"\x00\x00", "ColorLine.ColorStop[0].StopOffset (0.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[0].StopOffset.varIdx (0)"),
(b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"), (b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"),
(b"@\x00", "ColorLine.ColorStop[0].Color.Alpha.value (1.0)"), (b"@\x00", "ColorLine.ColorStop[0].Color.Alpha (1.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[0].Color.Alpha.varIdx (0)"), (b"@\x00", "ColorLine.ColorStop[1].StopOffset (1.0)"),
(b"@\x00", "ColorLine.ColorStop[1].StopOffset.value (1.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[1].StopOffset.varIdx (0)"),
(b"\x00\x05", "ColorLine.ColorStop[1].Color.PaletteIndex (5)"), (b"\x00\x05", "ColorLine.ColorStop[1].Color.PaletteIndex (5)"),
(b"@\x00", "ColorLine.ColorStop[1].Color.Alpha.value (1.0)"), (b"@\x00", "ColorLine.ColorStop[1].Color.Alpha (1.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[1].Color.Alpha.varIdx (0)"),
# LayerV1List # LayerV1List
(b"\x00\x00\x00\x04", "LayerV1List.LayerCount (4)"), (b"\x00\x00\x00\x04", "LayerV1List.LayerCount (4)"),
( (
@ -182,70 +180,63 @@ COLR_V1_SAMPLE = (
"First Offset to Paint table from beginning of LayerV1List (20)", "First Offset to Paint table from beginning of LayerV1List (20)",
), ),
( (
b"\x00\x00\x00\x1a", b"\x00\x00\x00\x23",
"Second Offset to Paint table from beginning of LayerV1List (26)", "Second Offset to Paint table from beginning of LayerV1List (35)",
), ),
( (
b"\x00\x00\x00u", b"\x00\x00\x00\x4e",
"Third Offset to Paint table from beginning of LayerV1List (117)", "Third Offset to Paint table from beginning of LayerV1List (78)",
), ),
( (
b"\x00\x00\x00\xf6", b"\x00\x00\x00\xb7",
"Fourth Offset to Paint table from beginning of LayerV1List (246)", "Fourth Offset to Paint table from beginning of LayerV1List (183)",
), ),
# PaintGlyph glyph00011 # PaintGlyph glyph00011
(b"\x06", "LayerV1List.Paint[0].Format (6)"), (b"\x0a", "LayerV1List.Paint[0].Format (10)"),
(b"\x00\x01<", "Offset24 to Paint subtable from beginning of PaintGlyph (316)"), (b"\x00\x00\x06", "Offset24 to Paint subtable from beginning of PaintGlyph (6)"),
(b"\x00\x0b", "LayerV1List.Paint[0].Glyph (glyph00011)"), (b"\x00\x0b", "LayerV1List.Paint[0].Glyph (glyph00011)"),
# PaintVarSolid
(b"\x03", "LayerV1List.Paint[0].Paint.Format (3)"),
(b"\x00\x02", "Paint.Color.PaletteIndex (2)"),
(b" \x00", "Paint.Color.Alpha.value (0.5)"),
(b"\x00\x00\x00\x00", "Paint.Color.Alpha.varIdx (0)"),
# PaintGlyph glyph00012 # PaintGlyph glyph00012
(b"\x06", "LayerV1List.Paint[1].Format (6)"), (b"\x0a", "LayerV1List.Paint[1].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)"),
(b"\x00\x0c", "LayerV1List.Paint[1].Glyph (glyph00012)"), (b"\x00\x0c", "LayerV1List.Paint[1].Glyph (glyph00012)"),
(b"\x03", "LayerV1List.Paint[1].Paint.Format (3)"), (b"\x04", "LayerV1List.Paint[1].Paint.Format (4)"),
(b"\x00\x00(", "Offset to ColorLine from beginning of PaintLinearGradient (40)"), (b"\x00\x00\x10", "Offset to ColorLine from beginning of PaintLinearGradient (16)"),
(b"\x00\x01", "Paint.x0.value (1)"), (b"\x00\x01", "Paint.x0 (1)"),
(b"\x00\x00\x00\x00", "Paint.x0.varIdx (0)"), (b"\x00\x02", "Paint.y0 (2)"),
(b"\x00\x02", "Paint.y0.value (2)"), (b"\xff\xfd", "Paint.x1 (-3)"),
(b"\x00\x00\x00\x00", "Paint.y0.varIdx (0)"), (b"\xff\xfc", "Paint.y1 (-4)"),
(b"\xff\xfd", "Paint.x1.value (-3)"), (b"\x00\x05", "Paint.x2 (5)"),
(b"\x00\x00\x00\x00", "Paint.x1.varIdx (0)"), (b"\x00\x06", "Paint.y2 (6)"),
(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 (6)"),
(b"\x00\x00\x00\x00", "Paint.y2.varIdx (0)"),
(b"\x01", "ColorLine.Extend (1; repeat)"), (b"\x01", "ColorLine.Extend (1; repeat)"),
(b"\x00\x03", "ColorLine.StopCount (3)"), (b"\x00\x03", "ColorLine.StopCount (3)"),
(b"\x00\x00", "ColorLine.ColorStop[0].StopOffset.value (0.0)"), (b"\x00\x00", "ColorLine.ColorStop[0].StopOffset (0.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[0].StopOffset.varIdx (0)"),
(b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"), (b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"),
(b"@\x00", "ColorLine.ColorStop[0].Color.Alpha.value (1.0)"), (b"@\x00", "ColorLine.ColorStop[0].Color.Alpha (1.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[0].Color.Alpha.varIdx (0)"), (b" \x00", "ColorLine.ColorStop[1].StopOffset (0.5)"),
(b" \x00", "ColorLine.ColorStop[1].StopOffset.value (0.5)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[1].StopOffset.varIdx (0)"),
(b"\x00\x04", "ColorLine.ColorStop[1].Color.PaletteIndex (4)"), (b"\x00\x04", "ColorLine.ColorStop[1].Color.PaletteIndex (4)"),
(b"@\x00", "ColorLine.ColorStop[1].Color.Alpha.value (1.0)"), (b"@\x00", "ColorLine.ColorStop[1].Color.Alpha (1.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[1].Color.Alpha.varIdx (0)"), (b"@\x00", "ColorLine.ColorStop[2].StopOffset (1.0)"),
(b"@\x00", "ColorLine.ColorStop[2].StopOffset.value (1.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[2].StopOffset.varIdx (0)"),
(b"\x00\x05", "ColorLine.ColorStop[2].Color.PaletteIndex (5)"), (b"\x00\x05", "ColorLine.ColorStop[2].Color.PaletteIndex (5)"),
(b"@\x00", "ColorLine.ColorStop[2].Color.Alpha.value (1.0)"), (b"@\x00", "ColorLine.ColorStop[2].Color.Alpha (1.0)"),
(b"\x00\x00\x00\x00", "ColorLine.ColorStop[2].Color.Alpha.varIdx (0)"),
# PaintGlyph glyph00013 # PaintGlyph glyph00013
(b"\x06", "LayerV1List.Paint[2].Format (6)"), (b"\x0a", "LayerV1List.Paint[2].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)"),
(b"\x00\r", "LayerV1List.Paint[2].Glyph (13)"), (b"\x00\r", "LayerV1List.Paint[2].Glyph (13)"),
(b"\x08", "LayerV1List.Paint[2].Paint.Format (8)"), (b"\x0c", "LayerV1List.Paint[2].Paint.Format (12)"),
(b"\x00\x00\x34", "Offset to Paint subtable from beginning of PaintTransform (52)"), (b"\x00\x00\x1c", "Offset to Paint subtable from beginning of PaintTransform (28)"),
(b"\xff\xf3\x00\x00\x00\x00\x00\x00", "Affine2x3.xx.value (-13)"), (b"\xff\xf3\x00\x00", "Affine2x3.xx (-13)"),
(b"\x00\x0e\x00\x00\x00\x00\x00\x00", "Affine2x3.xy.value (14)"), (b"\x00\x0e\x00\x00", "Affine2x3.xy (14)"),
(b"\x00\x0f\x00\x00\x00\x00\x00\x00", "Affine2x3.yx.value (15)"), (b"\x00\x0f\x00\x00", "Affine2x3.yx (15)"),
(b"\xff\xef\x00\x00\x00\x00\x00\x00", "Affine2x3.yy.value (-17)"), (b"\xff\xef\x00\x00", "Affine2x3.yy (-17)"),
(b"\x00\x12\x00\x00\x00\x00\x00\x00", "Affine2x3.yy.value (18)"), (b"\x00\x12\x00\x00", "Affine2x3.yy (18)"),
(b"\x00\x13\x00\x00\x00\x00\x00\x00", "Affine2x3.yy.value (19)"), (b"\x00\x13\x00\x00", "Affine2x3.yy (19)"),
(b"\x04", "LayerV1List.Paint[2].Paint.Paint.Format (4)"), (b"\x07", "LayerV1List.Paint[2].Paint.Paint.Format (7)"),
(b"\x00\x00(", "Offset to ColorLine from beginning of PaintRadialGradient (40)"), (b"\x00\x00(", "Offset to ColorLine from beginning of PaintVarRadialGradient (40)"),
(b"\x00\x07\x00\x00\x00\x00", "Paint.x0.value (7)"), (b"\x00\x07\x00\x00\x00\x00", "Paint.x0.value (7)"),
(b"\x00\x08\x00\x00\x00\x00", "Paint.y0.value (8)"), (b"\x00\x08\x00\x00\x00\x00", "Paint.y0.value (8)"),
(b"\x00\t\x00\x00\x00\x00", "Paint.r0.value (9)"), (b"\x00\t\x00\x00\x00\x00", "Paint.r0.value (9)"),
@ -261,32 +252,31 @@ COLR_V1_SAMPLE = (
(b"\x00\x07", "ColorLine.ColorStop[1].Color.PaletteIndex (7)"), (b"\x00\x07", "ColorLine.ColorStop[1].Color.PaletteIndex (7)"),
(b"\x19\x9a\x00\x00\x00\x00", "ColorLine.ColorStop[1].Color.Alpha.value (0.4)"), (b"\x19\x9a\x00\x00\x00\x00", "ColorLine.ColorStop[1].Color.Alpha.value (0.4)"),
# PaintTranslate # PaintTranslate
(b"\x09", "LayerV1List.Paint[3].Format (9)"), (b"\x0e", "LayerV1List.Paint[3].Format (14)"),
(b"\x00\x00\x14", "Offset to Paint subtable from beginning of PaintTranslate (20)"), (b"\x00\x00\x0c", "Offset to Paint subtable from beginning of PaintTranslate (12)"),
(b"\x01\x01\x00\x00\x00\x00\x00\x00", "dx.value (257)"), (b"\x01\x01\x00\x00", "dx (257)"),
(b"\x01\x02\x00\x00\x00\x00\x00\x00", "dy.value (258)"), (b"\x01\x02\x00\x00", "dy (258)"),
# PaintRotate # PaintRotate
(b"\x0a", "LayerV1List.Paint[3].Paint.Format (10)"), (b"\x10", "LayerV1List.Paint[3].Paint.Format (16)"),
(b"\x00\x00\x1c", "Offset to Paint subtable from beginning of PaintRotate (28)"), (b"\x00\x00\x10", "Offset to Paint subtable from beginning of PaintRotate (16)"),
(b"\x00\x2d\x00\x00\x00\x00\x00\x00", "angle.value (45)"), (b"\x00\x2d\x00\x00", "angle (45)"),
(b"\x00\xff\x00\x00\x00\x00\x00\x00", "centerX.value (255)"), (b"\x00\xff\x00\x00", "centerX (255)"),
(b"\x01\x00\x00\x00\x00\x00\x00\x00", "centerY.value (256)"), (b"\x01\x00\x00\x00", "centerY (256)"),
# PaintSkew # PaintSkew
(b"\x0b", "LayerV1List.Paint[3].Paint.Paint.Format (11)"), (b"\x12", "LayerV1List.Paint[3].Paint.Paint.Format (18)"),
(b"\x00\x00\x24", "Offset to Paint subtable from beginning of PaintSkew (36)"), (b"\x00\x00\x14", "Offset to Paint subtable from beginning of PaintSkew (20)"),
(b"\xff\xf5\x00\x00\x00\x00\x00\x00", "xSkewAngle (-11)"), (b"\xff\xf5\x00\x00", "xSkewAngle (-11)"),
(b"\x00\x05\x00\x00\x00\x00\x00\x00", "ySkewAngle (5)"), (b"\x00\x05\x00\x00", "ySkewAngle (5)"),
(b"\x00\xfd\x00\x00\x00\x00\x00\x00", "centerX.value (253)"), (b"\x00\xfd\x00\x00", "centerX.value (253)"),
(b"\x00\xfe\x00\x00\x00\x00\x00\x00", "centerY.value (254)"), (b"\x00\xfe\x00\x00", "centerY.value (254)"),
# PaintGlyph # PaintGlyph
(b"\x06", "LayerV1List.Paint[2].Format (6)"), (b"\x0a", "LayerV1List.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)"),
(b"\x00\x0b", "LayerV1List.Paint[2].Glyph (11)"), (b"\x00\x0b", "LayerV1List.Paint[2].Glyph (11)"),
# PaintSolid # PaintSolid
(b"\x02", "LayerV1List.Paint[0].Paint.Format (2)"), (b"\x02", "LayerV1List.Paint[0].Paint.Paint.Paint.Paint.Format (2)"),
(b"\x00\x02", "Paint.Color.PaletteIndex (2)"), (b"\x00\x02", "Paint.Color.PaletteIndex (2)"),
(b" \x00", "Paint.Color.Alpha.value (0.5)"), (b" \x00", "Paint.Color.Alpha (0.5)"),
(b"\x00\x00\x00\x00", "Paint.Color.Alpha.varIdx (0)"),
) )
COLR_V1_DATA = b"".join(t[0] for t in COLR_V1_SAMPLE) COLR_V1_DATA = b"".join(t[0] for t in COLR_V1_SAMPLE)
@ -327,13 +317,13 @@ COLR_V1_XML = [
" </BaseGlyphV1Record>", " </BaseGlyphV1Record>",
' <BaseGlyphV1Record index="1">', ' <BaseGlyphV1Record index="1">',
' <BaseGlyph value="glyph00014"/>', ' <BaseGlyph value="glyph00014"/>',
' <Paint Format="12"><!-- PaintComposite -->', ' <Paint Format="20"><!-- PaintComposite -->',
' <SourcePaint Format="7"><!-- PaintColrGlyph -->', ' <SourcePaint Format="11"><!-- PaintColrGlyph -->',
' <Glyph value="glyph00010"/>', ' <Glyph value="glyph00010"/>',
" </SourcePaint>", " </SourcePaint>",
' <CompositeMode value="src_over"/>', ' <CompositeMode value="src_over"/>',
' <BackdropPaint Format="8"><!-- PaintTransform -->', ' <BackdropPaint Format="13"><!-- PaintVarTransform -->',
' <Paint Format="7"><!-- PaintColrGlyph -->', ' <Paint Format="11"><!-- PaintColrGlyph -->',
' <Glyph value="glyph00010"/>', ' <Glyph value="glyph00010"/>',
" </Paint>", " </Paint>",
" <Transform>", " <Transform>",
@ -349,8 +339,8 @@ COLR_V1_XML = [
" </BaseGlyphV1Record>", " </BaseGlyphV1Record>",
' <BaseGlyphV1Record index="2">', ' <BaseGlyphV1Record index="2">',
' <BaseGlyph value="glyph00015"/>', ' <BaseGlyph value="glyph00015"/>',
' <Paint Format="6"><!-- PaintGlyph -->', ' <Paint Format="10"><!-- PaintGlyph -->',
' <Paint Format="5"><!-- PaintSweepGradient -->', ' <Paint Format="8"><!-- PaintSweepGradient -->',
" <ColorLine>", " <ColorLine>",
' <Extend value="pad"/>', ' <Extend value="pad"/>',
" <!-- StopCount=2 -->", " <!-- StopCount=2 -->",
@ -380,8 +370,8 @@ COLR_V1_XML = [
"</BaseGlyphV1List>", "</BaseGlyphV1List>",
"<LayerV1List>", "<LayerV1List>",
" <!-- LayerCount=4 -->", " <!-- LayerCount=4 -->",
' <Paint index="0" Format="6"><!-- PaintGlyph -->', ' <Paint index="0" Format="10"><!-- PaintGlyph -->',
' <Paint Format="2"><!-- PaintSolid -->', ' <Paint Format="3"><!-- PaintVarSolid -->',
" <Color>", " <Color>",
' <PaletteIndex value="2"/>', ' <PaletteIndex value="2"/>',
' <Alpha value="0.5"/>', ' <Alpha value="0.5"/>',
@ -389,8 +379,8 @@ COLR_V1_XML = [
" </Paint>", " </Paint>",
' <Glyph value="glyph00011"/>', ' <Glyph value="glyph00011"/>',
" </Paint>", " </Paint>",
' <Paint index="1" Format="6"><!-- PaintGlyph -->', ' <Paint index="1" Format="10"><!-- PaintGlyph -->',
' <Paint Format="3"><!-- PaintLinearGradient -->', ' <Paint Format="4"><!-- PaintLinearGradient -->',
" <ColorLine>", " <ColorLine>",
' <Extend value="repeat"/>', ' <Extend value="repeat"/>',
" <!-- StopCount=3 -->", " <!-- StopCount=3 -->",
@ -425,9 +415,9 @@ COLR_V1_XML = [
" </Paint>", " </Paint>",
' <Glyph value="glyph00012"/>', ' <Glyph value="glyph00012"/>',
" </Paint>", " </Paint>",
' <Paint index="2" Format="6"><!-- PaintGlyph -->', ' <Paint index="2" Format="10"><!-- PaintGlyph -->',
' <Paint Format="8"><!-- PaintTransform -->', ' <Paint Format="12"><!-- PaintTransform -->',
' <Paint Format="4"><!-- PaintRadialGradient -->', ' <Paint Format="7"><!-- PaintVarRadialGradient -->',
" <ColorLine>", " <ColorLine>",
' <Extend value="pad"/>', ' <Extend value="pad"/>',
" <!-- StopCount=2 -->", " <!-- StopCount=2 -->",
@ -464,10 +454,10 @@ COLR_V1_XML = [
" </Paint>", " </Paint>",
' <Glyph value="glyph00013"/>', ' <Glyph value="glyph00013"/>',
" </Paint>", " </Paint>",
' <Paint index="3" Format="9"><!-- PaintTranslate -->', ' <Paint index="3" Format="14"><!-- PaintTranslate -->',
' <Paint Format="10"><!-- PaintRotate -->', ' <Paint Format="16"><!-- PaintRotate -->',
' <Paint Format="11"><!-- PaintSkew -->', ' <Paint Format="18"><!-- PaintSkew -->',
' <Paint Format="6"><!-- PaintGlyph -->', ' <Paint Format="10"><!-- PaintGlyph -->',
' <Paint Format="2"><!-- PaintSolid -->', ' <Paint Format="2"><!-- PaintSolid -->',
" <Color>", " <Color>",
' <PaletteIndex value="2"/>', ' <PaletteIndex value="2"/>',