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

View File

@ -59,14 +59,20 @@ def buildConverters(tableSpec, tableNamespace):
converterClass = Struct
else:
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)
else:
tableClass = tableNamespace.get(tableName)
if tableClass is not None:
conv = converterClass(name, repeat, aux, tableClass=tableClass)
else:
conv = converterClass(name, repeat, aux)
if not conv.tableClass:
conv.tableClass = tableClass
if name in ["SubTable", "ExtSubTable", "SubStruct"]:
conv.lookupTypes = tableNamespace['lookupTypes']
# also create reverse mapping

View File

@ -1598,6 +1598,14 @@ otData = [
# basis vector.
# See https://github.com/googlefonts/colr-gradients-spec/pull/85
('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', 'yx', None, None, 'y-part of x basis vector'),
('VarFixed', 'xy', None, None, 'x-part of y basis vector'),
@ -1607,35 +1615,67 @@ otData = [
]),
('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.'),
('VarF2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved'),
]),
('ColorStop', [
('VarF2Dot14', 'StopOffset', None, None, ''),
('F2Dot14', 'StopOffset', None, None, ''),
('ColorIndex', 'Color', None, None, ''),
]),
('VarColorStop', [
('VarF2Dot14', 'StopOffset', None, None, ''),
('VarColorIndex', 'Color', None, None, ''),
]),
('ColorLine', [
('ExtendMode', 'Extend', None, None, 'Enum {PAD = 0, REPEAT = 1, REFLECT = 2}'),
('uint16', 'StopCount', None, None, 'Number 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
('PaintFormat1', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 1'),
('uint8', 'NumLayers', None, None, 'Number of offsets to Paint to read from LayerV1List.'),
('uint32', 'FirstLayerIndex', None, None, 'Index into LayerV1List.'),
]),
# PaintSolid
('PaintFormat2', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 2'),
('ColorIndex', 'Color', None, None, 'A solid color paint.'),
]),
# PaintLinearGradient
# PaintVarSolid
('PaintFormat3', [
('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.'),
('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', 'y0', None, None, ''),
('VarInt16', 'x1', None, None, ''),
@ -1643,10 +1683,22 @@ otData = [
('VarInt16', 'x2', None, None, ''),
('VarInt16', 'y2', None, None, ''),
]),
# PaintRadialGradient
('PaintFormat4', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 4'),
('PaintFormat6', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 6'),
('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', 'y0', None, None, ''),
('VarUInt16', 'r0', None, None, ''),
@ -1654,59 +1706,106 @@ otData = [
('VarInt16', 'y1', None, None, ''),
('VarUInt16', 'r1', None, None, ''),
]),
# PaintSweepGradient
('PaintFormat5', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 5'),
('PaintFormat8', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 8'),
('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', 'centerY', None, None, 'Center y coordinate.'),
('VarFixed', 'startAngle', None, None, 'Start of the angular range of the gradient.'),
('VarFixed', 'endAngle', None, None, 'End of the angular range of the gradient.'),
]),
# PaintGlyph
('PaintFormat6', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 6'),
('PaintFormat10', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 10'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintGlyph table) to Paint subtable.'),
('GlyphID', 'Glyph', None, None, 'Glyph ID for the source outline.'),
]),
# PaintColrGlyph
('PaintFormat7', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 7'),
('PaintFormat11', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 11'),
('GlyphID', 'Glyph', None, None, 'Virtual glyph ID for a BaseGlyphV1List base glyph.'),
]),
# PaintTransform
('PaintFormat8', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 8'),
('PaintFormat12', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 12'),
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintTransform table) to Paint subtable.'),
('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
('PaintFormat9', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 9'),
('PaintFormat14', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 14'),
('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', 'dy', None, None, 'Translation in y direction.'),
]),
# PaintRotate
('PaintFormat10', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 10'),
('PaintFormat16', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 16'),
('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', 'centerX', None, None, ''),
('VarFixed', 'centerY', None, None, ''),
]),
# PaintSkew
('PaintFormat11', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 11'),
('PaintFormat18', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 18'),
('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', 'ySkewAngle', None, None, ''),
('VarFixed', 'centerX', None, None, ''),
('VarFixed', 'centerY', None, None, ''),
]),
# PaintComposite
('PaintFormat12', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 12'),
('PaintFormat20', [
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 20'),
('LOffset24To(Paint)', 'SourcePaint', None, None, 'Offset (from beginning of PaintComposite table) to source Paint subtable.'),
('CompositeMode', 'CompositeMode', None, None, 'A CompositeMode enumeration value.'),
('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):
PaintColrLayers = 1
PaintSolid = 2
PaintLinearGradient = 3
PaintRadialGradient = 4
PaintSweepGradient = 5
PaintGlyph = 6
PaintColrGlyph = 7
PaintTransform = 8
PaintTranslate = 9
PaintRotate = 10
PaintSkew = 11
PaintComposite = 12
PaintVarSolid = 3,
PaintLinearGradient = 4
PaintVarLinearGradient = 5
PaintRadialGradient = 6
PaintVarRadialGradient = 7
PaintSweepGradient = 8
PaintVarSweepGradient = 9
PaintGlyph = 10
PaintColrGlyph = 11
PaintTransform = 12
PaintVarTransform = 13
PaintTranslate = 14
PaintVarTranslate = 15
PaintRotate = 16
PaintVarRotate = 17
PaintSkew = 18
PaintVarSkew = 19
PaintComposite = 20
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)]])
def test_buildColorIndex():
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_Alpha():
def test_buildColorIndex():
c = _build(ot.ColorIndex, (1, 0.5))
assert c.PaletteIndex == 1
assert c.Alpha.value == 0.5
assert c.Alpha.varIdx == 0
assert c.Alpha == 0.5
def test_buildColorIndex_Variable():
c = _build(ot.ColorIndex, (3, builder.VariableFloat(0.5, varIdx=2)))
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
@ -256,30 +261,35 @@ def test_buildPaintSolid():
p = _buildPaint((ot.PaintFormat.PaintSolid, 0))
assert p.Format == ot.PaintFormat.PaintSolid
assert p.Color.PaletteIndex == 0
assert p.Color.Alpha.value == 1.0
assert p.Color.Alpha.varIdx == 0
assert p.Color.Alpha == 1.0
def test_buildPaintSolid_Alpha():
p = _buildPaint((ot.PaintFormat.PaintSolid, (1, 0.5)))
assert p.Format == ot.PaintFormat.PaintSolid
assert p.Color.PaletteIndex == 1
assert p.Color.Alpha.value == 0.5
assert p.Color.Alpha.varIdx == 0
assert p.Color.Alpha == 0.5
def test_buildPaintSolid_Variable():
def test_buildPaintVarSolid():
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.Alpha.value == 0.5
assert p.Color.Alpha.varIdx == 2
def test_buildColorStop_DefaultAlpha():
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
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
@ -289,13 +299,13 @@ def test_buildColorStop():
s = _build(
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))
def test_buildColorStop_Variable():
s = _build(
ot.ColorStop,
ot.VarColorStop,
{
"StopOffset": builder.VariableFloat(0.0, varIdx=1),
"Color": {
@ -315,9 +325,7 @@ def test_buildColorLine_StopList():
cline = _build(ot.ColorLine, {"ColorStop": stops})
assert cline.Extend == builder.ExtendMode.PAD
assert cline.StopCount == 3
assert [
(cs.StopOffset.value, cs.Color.PaletteIndex) for cs in cline.ColorStop
] == stops
assert [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
cline = _build(ot.ColorLine, {"Extend": "pad", "ColorStop": stops})
assert cline.Extend == builder.ExtendMode.PAD
@ -335,17 +343,15 @@ def test_buildColorLine_StopList():
cline = _build(
ot.ColorLine, {"ColorStop": [_build(ot.ColorStop, s) for s in stops]}
)
assert [
(cs.StopOffset.value, cs.Color.PaletteIndex) for cs in cline.ColorStop
] == stops
assert [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
def test_buildColorLine_StopMap_Variations():
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)}},
]
cline = _build(ot.ColorLine, {"ColorStop": stops})
cline = _build(ot.VarColorLine, {"ColorStop": stops})
assert [
{
"StopOffset": cs.StopOffset,
@ -358,30 +364,49 @@ def test_buildColorLine_StopMap_Variations():
] == 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():
matrix = _build(ot.Affine2x3, (1.5, 0, 0.5, 2.0, 1.0, -3.0))
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)
checkBuildAffine2x3(ot.Affine2x3, lambda v: v)
def _sample_stops():
def test_buildVarAffine2x3():
checkBuildAffine2x3(ot.VarAffine2x3, builder.VariableFloat)
def _sample_stops(cls):
return [
_build(ot.ColorStop, (0.0, 0)),
_build(ot.ColorStop, (0.5, 1)),
_build(ot.ColorStop, (1.0, (2, 0.8))),
_build(cls, (0.0, 0)),
_build(cls, (0.5, 1)),
_build(cls, (1.0, (2, 0.8))),
]
def test_buildPaintLinearGradient():
color_stops = _sample_stops()
x0, y0, x1, y1, x2, y2 = tuple(builder.VariableInt(v) for v in (1, 2, 3, 4, 5, 6))
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)
x0, y0, x1, y1, x2, y2 = tuple(inputMapFn(v) for v in (1, 2, 3, 4, 5, 6))
gradient = _buildPaint(
{
"Format": ot.PaintFormat.PaintLinearGradient,
"Format": fmt,
"ColorLine": {"ColorStop": color_stops},
"x0": x0,
"y0": y0,
@ -395,39 +420,52 @@ def test_buildPaintLinearGradient():
assert gradient.ColorLine.ColorStop == color_stops
gradient = _buildPaint(gradient)
assert (gradient.x0.value, gradient.y0.value) == (1, 2)
assert (gradient.x1.value, gradient.y1.value) == (3, 4)
assert (gradient.x2.value, gradient.y2.value) == (5, 6)
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)
def test_buildPaintRadialGradient():
color_stops = [
_build(ot.ColorStop, (0.0, (0,))),
_build(ot.ColorStop, (0.5, 1)),
_build(ot.ColorStop, (1.0, (2, 0.8))),
]
def test_buildPaintLinearGradient():
assert not _is_var(ot.PaintFormat.PaintLinearGradient)
checkBuildPaintLinearGradient(ot.PaintFormat.PaintLinearGradient)
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(
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))
c1 = (builder.VariableInt(150), builder.VariableInt(250))
r0 = builder.VariableInt(10)
r1 = builder.VariableInt(5)
c0 = (inputMapFn(100), inputMapFn(200))
c1 = (inputMapFn(150), inputMapFn(250))
r0 = inputMapFn(10)
r1 = inputMapFn(5)
gradient = _build(
ot.Paint, (ot.PaintFormat.PaintRadialGradient, color_line, *c0, r0, *c1, r1)
)
assert gradient.Format == ot.PaintFormat.PaintRadialGradient
gradient = _build(ot.Paint, (fmt, color_line, *c0, r0, *c1, r1))
assert gradient.Format == fmt
assert gradient.ColorLine == color_line
assert (gradient.x0, gradient.y0) == c0
assert (gradient.x1, gradient.y1) == c1
assert gradient.r0 == r0
assert gradient.r1 == r1
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": ot.PaintFormat.PaintRadialGradient,
"Format": fmt,
"ColorLine": {"ColorStop": color_stops},
"x0": c0[0],
"y0": c0[1],
@ -439,16 +477,31 @@ def test_buildPaintRadialGradient():
)
assert gradient.ColorLine.Extend == builder.ExtendMode.PAD
assert gradient.ColorLine.ColorStop == color_stops
assert (gradient.x0, gradient.y0) == c0
assert (gradient.x1, gradient.y1) == c1
assert gradient.r0 == r0
assert gradient.r1 == r1
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
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(
{
"Format": ot.PaintFormat.PaintSweepGradient,
"Format": fmt,
"ColorLine": {
"ColorStop": (
(0.0, 0),
@ -463,11 +516,21 @@ def test_buildPaintSweepGradient():
}
)
assert paint.Format == ot.PaintFormat.PaintSweepGradient
assert paint.centerX.value == 127
assert paint.centerY.value == 129
assert paint.startAngle.value == 15
assert paint.endAngle.value == 42
assert paint.Format == fmt
assert outputMapFn(paint.centerX) == 127
assert outputMapFn(paint.centerY) == 129
assert outputMapFn(paint.startAngle) == 15
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():
@ -500,17 +563,17 @@ def test_buildPaintGlyph_Solid():
)
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
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(
ot.Paint,
{
"Format": ot.PaintFormat.PaintGlyph,
"Glyph": "a",
"Paint": {
"Format": ot.PaintFormat.PaintLinearGradient,
"Format": ot.PaintFormat.PaintVarLinearGradient,
"ColorLine": {"ColorStop": [(0.0, 3), (1.0, 4)]},
"x0": 100,
"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].Color.PaletteIndex == 3
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.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[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.Alpha.value == 0.8
assert layer.Paint.ColorLine.ColorStop[2].StopOffset.value == 1.0
assert layer.Paint.ColorLine.ColorStop[1].Color.Alpha == 0.8
assert layer.Paint.ColorLine.ColorStop[2].StopOffset == 1.0
assert layer.Paint.ColorLine.ColorStop[2].Color.PaletteIndex == 7
assert layer.Paint.x0.value == 50
assert layer.Paint.y0.value == 50
assert layer.Paint.r0.value == 30
assert layer.Paint.x1.value == 75
assert layer.Paint.y1.value == 75
assert layer.Paint.r1.value == 10
assert layer.Paint.x0 == 50
assert layer.Paint.y0 == 50
assert layer.Paint.r0 == 30
assert layer.Paint.x1 == 75
assert layer.Paint.y1 == 75
assert layer.Paint.r1 == 10
def test_buildPaintGlyph_Dict_Solid():
@ -588,14 +654,14 @@ def test_buildPaintGlyph_Dict_Solid():
assert layer.Paint.Color.PaletteIndex == 1
def test_buildPaintGlyph_Dict_LinearGradient():
def test_buildPaintGlyph_Dict_VarLinearGradient():
layer = _build(
ot.Paint,
{
"Format": ot.PaintFormat.PaintGlyph,
"Glyph": "a",
"Paint": {
"Format": 3,
"Format": int(ot.PaintFormat.PaintVarLinearGradient),
"ColorLine": {"ColorStop": [(0.0, 0), (1.0, 1)]},
"x0": 0,
"y0": 0,
@ -606,7 +672,7 @@ def test_buildPaintGlyph_Dict_LinearGradient():
)
assert layer.Format == ot.PaintFormat.PaintGlyph
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
@ -628,7 +694,7 @@ def test_buildPaintGlyph_Dict_RadialGradient():
},
)
assert layer.Paint.Format == ot.PaintFormat.PaintRadialGradient
assert layer.Paint.r0.value == 4
assert layer.Paint.r0 == 4
def test_buildPaintColrGlyph():
@ -637,30 +703,38 @@ def test_buildPaintColrGlyph():
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(
(
int(ot.PaintFormat.PaintTransform),
int(fmt),
(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.Paint.Format == ot.PaintFormat.PaintSolid
assert paint.Transform.xx.value == 1.0
assert paint.Transform.yx.value == 2.0
assert paint.Transform.xy.value == 3.0
assert paint.Transform.yy.value == 4.0
assert paint.Transform.dx.value == 5.0
assert paint.Transform.dy.value == 6.0
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
paint = _build(
ot.Paint,
{
"Format": ot.PaintFormat.PaintTransform,
"Format": fmt,
"Transform": (1, 2, 3, 0.3333, 10, 10),
"Paint": {
"Format": int(ot.PaintFormat.PaintRadialGradient),
@ -675,16 +749,26 @@ def test_buildPaintTransform():
},
)
assert paint.Format == ot.PaintFormat.PaintTransform
assert paint.Transform.xx.value == 1.0
assert paint.Transform.yx.value == 2.0
assert paint.Transform.xy.value == 3.0
assert paint.Transform.yy.value == 0.3333
assert paint.Transform.dx.value == 10
assert paint.Transform.dy.value == 10
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.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():
composite = _build(
ot.Paint,
@ -734,11 +818,17 @@ def test_buildPaintComposite():
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(
ot.Paint,
{
"Format": ot.PaintFormat.PaintTranslate,
"Format": fmt,
"Paint": (
ot.PaintFormat.PaintGlyph,
(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.dx.value == 123
assert paint.dy.value == -345
assert outputMapFn(paint.dx) == 123
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(
ot.Paint,
{
"Format": ot.PaintFormat.PaintRotate,
"Format": fmt,
"Paint": (
ot.PaintFormat.PaintGlyph,
(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.angle.value == 15
assert paint.centerX.value == 127
assert paint.centerY.value == 129
assert outputMapFn(paint.angle) == 15
assert outputMapFn(paint.centerX) == 127
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(
ot.Paint,
{
"Format": ot.PaintFormat.PaintSkew,
"Format": fmt,
"Paint": (
ot.PaintFormat.PaintGlyph,
(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.xSkewAngle.value == 15
assert paint.ySkewAngle.value == 42
assert paint.centerX.value == 127
assert paint.centerY.value == 129
assert outputMapFn(paint.xSkewAngle) == 15
assert outputMapFn(paint.ySkewAngle) == 42
assert outputMapFn(paint.centerX) == 127
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():
@ -809,7 +941,7 @@ def test_buildColrV1():
ot.PaintFormat.PaintColrLayers,
[
(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": (
@ -817,13 +949,16 @@ def test_buildColrV1():
[
(
ot.PaintFormat.PaintGlyph,
{"Format": 2, "Color": {"PaletteIndex": 2, "Alpha": 0.8}},
{
"Format": int(ot.PaintFormat.PaintSolid),
"Color": {"PaletteIndex": 2, "Alpha": 0.8},
},
"e",
),
(
ot.PaintFormat.PaintGlyph,
{
"Format": 4,
"Format": int(ot.PaintFormat.PaintVarRadialGradient),
"ColorLine": {
"ColorStop": [(0.0, 3), (1.0, 4)],
"Extend": "reflect",

View File

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

View File

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