Merge pull request #2372 from fonttools/colrv1-var-idx-map
[COLRv1] add DeltaSetIndexMap, remove ColorIndex
This commit is contained in:
commit
2f1fbd6374
@ -26,20 +26,10 @@ from fontTools.ttLib.tables import C_O_L_R_
|
|||||||
from fontTools.ttLib.tables import C_P_A_L_
|
from fontTools.ttLib.tables import C_P_A_L_
|
||||||
from fontTools.ttLib.tables import _n_a_m_e
|
from fontTools.ttLib.tables import _n_a_m_e
|
||||||
from fontTools.ttLib.tables import otTables as ot
|
from fontTools.ttLib.tables import otTables as ot
|
||||||
from fontTools.ttLib.tables.otTables import (
|
from fontTools.ttLib.tables.otTables import ExtendMode, CompositeMode
|
||||||
ExtendMode,
|
|
||||||
CompositeMode,
|
|
||||||
VariableValue,
|
|
||||||
VariableFloat,
|
|
||||||
VariableInt,
|
|
||||||
)
|
|
||||||
from .errors import ColorLibError
|
from .errors import ColorLibError
|
||||||
from .geometry import round_start_circle_stable_containment
|
from .geometry import round_start_circle_stable_containment
|
||||||
from .table_builder import (
|
from .table_builder import BuildCallback, TableBuilder
|
||||||
convertTupleClass,
|
|
||||||
BuildCallback,
|
|
||||||
TableBuilder,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO move type aliases to colorLib.types?
|
# TODO move type aliases to colorLib.types?
|
||||||
@ -52,53 +42,46 @@ _ColorGlyphsV0Dict = Dict[str, Sequence[Tuple[str, int]]]
|
|||||||
|
|
||||||
|
|
||||||
MAX_PAINT_COLR_LAYER_COUNT = 255
|
MAX_PAINT_COLR_LAYER_COUNT = 255
|
||||||
_DEFAULT_ALPHA = VariableFloat(1.0)
|
_DEFAULT_ALPHA = 1.0
|
||||||
_MAX_REUSE_LEN = 32
|
_MAX_REUSE_LEN = 32
|
||||||
|
|
||||||
|
|
||||||
def _beforeBuildPaintVarRadialGradient(paint, source, srcMapFn=lambda v: v):
|
def _beforeBuildPaintRadialGradient(paint, source):
|
||||||
# normalize input types (which may or may not specify a varIdx)
|
x0 = source["x0"]
|
||||||
x0 = convertTupleClass(VariableFloat, source["x0"])
|
y0 = source["y0"]
|
||||||
y0 = convertTupleClass(VariableFloat, source["y0"])
|
r0 = source["r0"]
|
||||||
r0 = convertTupleClass(VariableFloat, source["r0"])
|
x1 = source["x1"]
|
||||||
x1 = convertTupleClass(VariableFloat, source["x1"])
|
y1 = source["y1"]
|
||||||
y1 = convertTupleClass(VariableFloat, source["y1"])
|
r1 = source["r1"]
|
||||||
r1 = convertTupleClass(VariableFloat, source["r1"])
|
|
||||||
|
|
||||||
# TODO apparently no builder_test confirms this works (?)
|
# TODO apparently no builder_test confirms this works (?)
|
||||||
|
|
||||||
# avoid abrupt change after rounding when c0 is near c1's perimeter
|
# avoid abrupt change after rounding when c0 is near c1's perimeter
|
||||||
c = round_start_circle_stable_containment(
|
c = round_start_circle_stable_containment((x0, y0), r0, (x1, y1), r1)
|
||||||
(x0.value, y0.value), r0.value, (x1.value, y1.value), r1.value
|
x0, y0 = c.centre
|
||||||
)
|
r0 = c.radius
|
||||||
x0, y0 = x0._replace(value=c.centre[0]), y0._replace(value=c.centre[1])
|
|
||||||
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"] = srcMapFn(x0)
|
source["x0"] = x0
|
||||||
source["y0"] = srcMapFn(y0)
|
source["y0"] = y0
|
||||||
source["r0"] = srcMapFn(r0)
|
source["r0"] = r0
|
||||||
source["x1"] = srcMapFn(x1)
|
source["x1"] = x1
|
||||||
source["y1"] = srcMapFn(y1)
|
source["y1"] = y1
|
||||||
source["r1"] = srcMapFn(r1)
|
source["r1"] = r1
|
||||||
|
|
||||||
return paint, source
|
return paint, source
|
||||||
|
|
||||||
|
|
||||||
def _beforeBuildPaintRadialGradient(paint, source):
|
def _defaultColorStop():
|
||||||
return _beforeBuildPaintVarRadialGradient(paint, source, lambda v: v.value)
|
colorStop = ot.ColorStop()
|
||||||
|
colorStop.Alpha = _DEFAULT_ALPHA
|
||||||
|
return colorStop
|
||||||
|
|
||||||
|
|
||||||
def _defaultColorIndex():
|
def _defaultVarColorStop():
|
||||||
colorIndex = ot.ColorIndex()
|
colorStop = ot.VarColorStop()
|
||||||
colorIndex.Alpha = _DEFAULT_ALPHA.value
|
colorStop.Alpha = _DEFAULT_ALPHA
|
||||||
return colorIndex
|
return colorStop
|
||||||
|
|
||||||
|
|
||||||
def _defaultVarColorIndex():
|
|
||||||
colorIndex = ot.VarColorIndex()
|
|
||||||
colorIndex.Alpha = _DEFAULT_ALPHA
|
|
||||||
return colorIndex
|
|
||||||
|
|
||||||
|
|
||||||
def _defaultColorLine():
|
def _defaultColorLine():
|
||||||
@ -113,6 +96,12 @@ def _defaultVarColorLine():
|
|||||||
return colorLine
|
return colorLine
|
||||||
|
|
||||||
|
|
||||||
|
def _defaultPaintSolid():
|
||||||
|
paint = ot.Paint()
|
||||||
|
paint.Alpha = _DEFAULT_ALPHA
|
||||||
|
return paint
|
||||||
|
|
||||||
|
|
||||||
def _buildPaintCallbacks():
|
def _buildPaintCallbacks():
|
||||||
return {
|
return {
|
||||||
(
|
(
|
||||||
@ -124,11 +113,21 @@ def _buildPaintCallbacks():
|
|||||||
BuildCallback.BEFORE_BUILD,
|
BuildCallback.BEFORE_BUILD,
|
||||||
ot.Paint,
|
ot.Paint,
|
||||||
ot.PaintFormat.PaintVarRadialGradient,
|
ot.PaintFormat.PaintVarRadialGradient,
|
||||||
): _beforeBuildPaintVarRadialGradient,
|
): _beforeBuildPaintRadialGradient,
|
||||||
(BuildCallback.CREATE_DEFAULT, ot.ColorIndex): _defaultColorIndex,
|
(BuildCallback.CREATE_DEFAULT, ot.ColorStop): _defaultColorStop,
|
||||||
(BuildCallback.CREATE_DEFAULT, ot.VarColorIndex): _defaultVarColorIndex,
|
(BuildCallback.CREATE_DEFAULT, ot.VarColorStop): _defaultVarColorStop,
|
||||||
(BuildCallback.CREATE_DEFAULT, ot.ColorLine): _defaultColorLine,
|
(BuildCallback.CREATE_DEFAULT, ot.ColorLine): _defaultColorLine,
|
||||||
(BuildCallback.CREATE_DEFAULT, ot.VarColorLine): _defaultVarColorLine,
|
(BuildCallback.CREATE_DEFAULT, ot.VarColorLine): _defaultVarColorLine,
|
||||||
|
(
|
||||||
|
BuildCallback.CREATE_DEFAULT,
|
||||||
|
ot.Paint,
|
||||||
|
ot.PaintFormat.PaintSolid,
|
||||||
|
): _defaultPaintSolid,
|
||||||
|
(
|
||||||
|
BuildCallback.CREATE_DEFAULT,
|
||||||
|
ot.Paint,
|
||||||
|
ot.PaintFormat.PaintVarSolid,
|
||||||
|
): _defaultPaintSolid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -183,6 +182,7 @@ def buildCOLR(
|
|||||||
version: Optional[int] = None,
|
version: Optional[int] = None,
|
||||||
glyphMap: Optional[Mapping[str, int]] = None,
|
glyphMap: Optional[Mapping[str, int]] = None,
|
||||||
varStore: Optional[ot.VarStore] = None,
|
varStore: Optional[ot.VarStore] = None,
|
||||||
|
varIndexMap: Optional[ot.DeltaSetIndexMap] = None,
|
||||||
) -> C_O_L_R_.table_C_O_L_R_:
|
) -> C_O_L_R_.table_C_O_L_R_:
|
||||||
"""Build COLR table from color layers mapping.
|
"""Build COLR table from color layers mapping.
|
||||||
Args:
|
Args:
|
||||||
@ -196,6 +196,7 @@ def buildCOLR(
|
|||||||
glyphMap: a map from glyph names to glyph indices, as returned from
|
glyphMap: a map from glyph names to glyph indices, as returned from
|
||||||
TTFont.getReverseGlyphMap(), to optionally sort base records by GID.
|
TTFont.getReverseGlyphMap(), to optionally sort base records by GID.
|
||||||
varStore: Optional ItemVarationStore for deltas associated with v1 layer.
|
varStore: Optional ItemVarationStore for deltas associated with v1 layer.
|
||||||
|
varIndexMap: Optional DeltaSetIndexMap for deltas associated with v1 layer.
|
||||||
Return:
|
Return:
|
||||||
A new COLR table.
|
A new COLR table.
|
||||||
"""
|
"""
|
||||||
@ -229,6 +230,7 @@ def buildCOLR(
|
|||||||
if version == 0:
|
if version == 0:
|
||||||
self.ColorLayers = self._decompileColorLayersV0(colr)
|
self.ColorLayers = self._decompileColorLayersV0(colr)
|
||||||
else:
|
else:
|
||||||
|
colr.VarIndexMap = varIndexMap
|
||||||
colr.VarStore = varStore
|
colr.VarStore = varStore
|
||||||
self.table = colr
|
self.table = colr
|
||||||
|
|
||||||
|
@ -17,10 +17,9 @@ from fontTools.ttLib.tables.otConverters import (
|
|||||||
Short,
|
Short,
|
||||||
UInt8,
|
UInt8,
|
||||||
UShort,
|
UShort,
|
||||||
VarInt16,
|
|
||||||
VarUInt16,
|
|
||||||
IntValue,
|
IntValue,
|
||||||
FloatValue,
|
FloatValue,
|
||||||
|
OptionalValue,
|
||||||
)
|
)
|
||||||
from fontTools.misc.roundTools import otRound
|
from fontTools.misc.roundTools import otRound
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ class BuildCallback(enum.Enum):
|
|||||||
"""
|
"""
|
||||||
AFTER_BUILD = enum.auto()
|
AFTER_BUILD = enum.auto()
|
||||||
|
|
||||||
"""Keyed on (CREATE_DEFAULT, class).
|
"""Keyed on (CREATE_DEFAULT, class[, Format if available]).
|
||||||
Receives no arguments.
|
Receives no arguments.
|
||||||
Should return a new instance of class.
|
Should return a new instance of class.
|
||||||
"""
|
"""
|
||||||
@ -50,37 +49,29 @@ def _assignable(convertersByName):
|
|||||||
return {k: v for k, v in convertersByName.items() if not isinstance(v, ComputedInt)}
|
return {k: v for k, v in convertersByName.items() if not isinstance(v, ComputedInt)}
|
||||||
|
|
||||||
|
|
||||||
def convertTupleClass(tupleClass, value):
|
|
||||||
if isinstance(value, tupleClass):
|
|
||||||
return value
|
|
||||||
if isinstance(value, tuple):
|
|
||||||
return tupleClass(*value)
|
|
||||||
return tupleClass(value)
|
|
||||||
|
|
||||||
|
|
||||||
def _isNonStrSequence(value):
|
def _isNonStrSequence(value):
|
||||||
return isinstance(value, collections.abc.Sequence) and not isinstance(value, str)
|
return isinstance(value, collections.abc.Sequence) and not isinstance(value, str)
|
||||||
|
|
||||||
|
|
||||||
def _set_format(dest, source):
|
def _split_format(cls, source):
|
||||||
if _isNonStrSequence(source):
|
if _isNonStrSequence(source):
|
||||||
assert len(source) > 0, f"{type(dest)} needs at least format from {source}"
|
assert len(source) > 0, f"{cls} needs at least format from {source}"
|
||||||
dest.Format = source[0]
|
fmt, remainder = source[0], source[1:]
|
||||||
source = source[1:]
|
|
||||||
elif isinstance(source, collections.abc.Mapping):
|
elif isinstance(source, collections.abc.Mapping):
|
||||||
assert "Format" in source, f"{type(dest)} needs at least Format from {source}"
|
assert "Format" in source, f"{cls} needs at least Format from {source}"
|
||||||
dest.Format = source["Format"]
|
remainder = source.copy()
|
||||||
|
fmt = remainder.pop("Format")
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Not sure how to populate {type(dest)} from {source}")
|
raise ValueError(f"Not sure how to populate {cls} from {source}")
|
||||||
|
|
||||||
assert isinstance(
|
assert isinstance(
|
||||||
dest.Format, collections.abc.Hashable
|
fmt, collections.abc.Hashable
|
||||||
), f"{type(dest)} Format is not hashable: {dest.Format}"
|
), f"{cls} Format is not hashable: {fmt!r}"
|
||||||
assert (
|
assert (
|
||||||
dest.Format in dest.convertersByName
|
fmt in cls.convertersByName
|
||||||
), f"{dest.Format} invalid Format of {cls}"
|
), f"{cls} invalid Format: {fmt!r}"
|
||||||
|
|
||||||
return source
|
return fmt, remainder
|
||||||
|
|
||||||
|
|
||||||
class TableBuilder:
|
class TableBuilder:
|
||||||
@ -97,13 +88,9 @@ class TableBuilder:
|
|||||||
self._callbackTable = callbackTable
|
self._callbackTable = callbackTable
|
||||||
|
|
||||||
def _convert(self, dest, field, converter, value):
|
def _convert(self, dest, field, converter, value):
|
||||||
tupleClass = getattr(converter, "tupleClass", None)
|
|
||||||
enumClass = getattr(converter, "enumClass", None)
|
enumClass = getattr(converter, "enumClass", None)
|
||||||
|
|
||||||
if tupleClass:
|
if enumClass:
|
||||||
value = convertTupleClass(tupleClass, value)
|
|
||||||
|
|
||||||
elif enumClass:
|
|
||||||
if isinstance(value, enumClass):
|
if isinstance(value, enumClass):
|
||||||
pass
|
pass
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
@ -140,6 +127,11 @@ class TableBuilder:
|
|||||||
return source
|
return source
|
||||||
|
|
||||||
callbackKey = (cls,)
|
callbackKey = (cls,)
|
||||||
|
fmt = None
|
||||||
|
if issubclass(cls, FormatSwitchingBaseTable):
|
||||||
|
fmt, source = _split_format(cls, source)
|
||||||
|
callbackKey = (cls, fmt)
|
||||||
|
|
||||||
dest = self._callbackTable.get(
|
dest = self._callbackTable.get(
|
||||||
(BuildCallback.CREATE_DEFAULT,) + callbackKey, lambda: cls()
|
(BuildCallback.CREATE_DEFAULT,) + callbackKey, lambda: cls()
|
||||||
)()
|
)()
|
||||||
@ -150,11 +142,9 @@ class TableBuilder:
|
|||||||
|
|
||||||
# For format switchers we need to resolve converters based on format
|
# For format switchers we need to resolve converters based on format
|
||||||
if issubclass(cls, FormatSwitchingBaseTable):
|
if issubclass(cls, FormatSwitchingBaseTable):
|
||||||
source = _set_format(dest, source)
|
dest.Format = fmt
|
||||||
|
|
||||||
convByName = _assignable(convByName[dest.Format])
|
convByName = _assignable(convByName[dest.Format])
|
||||||
skippedFields.add("Format")
|
skippedFields.add("Format")
|
||||||
callbackKey = (cls, dest.Format)
|
|
||||||
|
|
||||||
# Convert sequence => mapping so before thunk only has to handle one format
|
# Convert sequence => mapping so before thunk only has to handle one format
|
||||||
if _isNonStrSequence(source):
|
if _isNonStrSequence(source):
|
||||||
@ -182,6 +172,10 @@ class TableBuilder:
|
|||||||
# let's try as a 1-tuple
|
# let's try as a 1-tuple
|
||||||
dest = self.build(cls, (source,))
|
dest = self.build(cls, (source,))
|
||||||
|
|
||||||
|
for field, conv in convByName.items():
|
||||||
|
if not hasattr(dest, field) and isinstance(conv, OptionalValue):
|
||||||
|
setattr(dest, field, conv.DEFAULT)
|
||||||
|
|
||||||
dest = self._callbackTable.get(
|
dest = self._callbackTable.get(
|
||||||
(BuildCallback.AFTER_BUILD,) + callbackKey, lambda d: d
|
(BuildCallback.AFTER_BUILD,) + callbackKey, lambda d: d
|
||||||
)(dest)
|
)(dest)
|
||||||
@ -210,11 +204,8 @@ class TableUnbuilder:
|
|||||||
continue
|
continue
|
||||||
value = getattr(table, converter.name)
|
value = getattr(table, converter.name)
|
||||||
|
|
||||||
tupleClass = getattr(converter, "tupleClass", None)
|
|
||||||
enumClass = getattr(converter, "enumClass", None)
|
enumClass = getattr(converter, "enumClass", None)
|
||||||
if tupleClass:
|
if enumClass:
|
||||||
source[converter.name] = tuple(value)
|
|
||||||
elif enumClass:
|
|
||||||
source[converter.name] = value.name.lower()
|
source[converter.name] = value.name.lower()
|
||||||
elif isinstance(converter, Struct):
|
elif isinstance(converter, Struct):
|
||||||
if converter.repeat:
|
if converter.repeat:
|
||||||
|
@ -2117,11 +2117,11 @@ def prune_post_subset(self, font, options):
|
|||||||
colors_by_index = defaultdict(list)
|
colors_by_index = defaultdict(list)
|
||||||
|
|
||||||
def collect_colors_by_index(paint):
|
def collect_colors_by_index(paint):
|
||||||
if hasattr(paint, "Color"): # either solid colors...
|
if hasattr(paint, "PaletteIndex"): # either solid colors...
|
||||||
colors_by_index[paint.Color.PaletteIndex].append(paint.Color)
|
colors_by_index[paint.PaletteIndex].append(paint)
|
||||||
elif hasattr(paint, "ColorLine"): # ... or gradient color stops
|
elif hasattr(paint, "ColorLine"): # ... or gradient color stops
|
||||||
for stop in paint.ColorLine.ColorStop:
|
for stop in paint.ColorLine.ColorStop:
|
||||||
colors_by_index[stop.Color.PaletteIndex].append(stop.Color)
|
colors_by_index[stop.PaletteIndex].append(stop)
|
||||||
|
|
||||||
if colr.version == 0:
|
if colr.version == 0:
|
||||||
for layers in colr.ColorLayers.values():
|
for layers in colr.ColorLayers.values():
|
||||||
|
@ -14,8 +14,8 @@ from .otBase import (CountReference, FormatSwitchingBaseTable,
|
|||||||
OTTableReader, OTTableWriter, ValueRecordFactory)
|
OTTableReader, OTTableWriter, ValueRecordFactory)
|
||||||
from .otTables import (lookupTypes, AATStateTable, AATState, AATAction,
|
from .otTables import (lookupTypes, AATStateTable, AATState, AATAction,
|
||||||
ContextualMorphAction, LigatureMorphAction,
|
ContextualMorphAction, LigatureMorphAction,
|
||||||
InsertionMorphAction, MorxSubtable, VariableFloat,
|
InsertionMorphAction, MorxSubtable,
|
||||||
VariableInt, ExtendMode as _ExtendMode,
|
ExtendMode as _ExtendMode,
|
||||||
CompositeMode as _CompositeMode)
|
CompositeMode as _CompositeMode)
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@ -226,6 +226,18 @@ class SimpleValue(BaseConverter):
|
|||||||
def xmlRead(self, attrs, content, font):
|
def xmlRead(self, attrs, content, font):
|
||||||
return self.fromString(attrs["value"])
|
return self.fromString(attrs["value"])
|
||||||
|
|
||||||
|
class OptionalValue(SimpleValue):
|
||||||
|
DEFAULT = None
|
||||||
|
def xmlWrite(self, xmlWriter, font, value, name, attrs):
|
||||||
|
if value != self.DEFAULT:
|
||||||
|
attrs.append(("value", self.toString(value)))
|
||||||
|
xmlWriter.simpletag(name, attrs)
|
||||||
|
xmlWriter.newline()
|
||||||
|
def xmlRead(self, attrs, content, font):
|
||||||
|
if "value" in attrs:
|
||||||
|
return self.fromString(attrs["value"])
|
||||||
|
return self.DEFAULT
|
||||||
|
|
||||||
class IntValue(SimpleValue):
|
class IntValue(SimpleValue):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fromString(value):
|
def fromString(value):
|
||||||
@ -258,6 +270,9 @@ class Flags32(ULong):
|
|||||||
def toString(value):
|
def toString(value):
|
||||||
return "0x%08X" % value
|
return "0x%08X" % value
|
||||||
|
|
||||||
|
class VarIndex(OptionalValue, ULong):
|
||||||
|
DEFAULT = 0xFFFFFFFF
|
||||||
|
|
||||||
class Short(IntValue):
|
class Short(IntValue):
|
||||||
staticSize = 2
|
staticSize = 2
|
||||||
def read(self, reader, font, tableDict):
|
def read(self, reader, font, tableDict):
|
||||||
@ -1700,104 +1715,6 @@ class LookupFlag(UShort):
|
|||||||
xmlWriter.comment(" ".join(flags))
|
xmlWriter.comment(" ".join(flags))
|
||||||
xmlWriter.newline()
|
xmlWriter.newline()
|
||||||
|
|
||||||
def _issubclass_namedtuple(x):
|
|
||||||
return (
|
|
||||||
issubclass(x, tuple)
|
|
||||||
and getattr(x, "_fields", None) is not None
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class _NamedTupleConverter(BaseConverter):
|
|
||||||
# subclasses must override this
|
|
||||||
tupleClass = NotImplemented
|
|
||||||
# List[SimpleValue]
|
|
||||||
converterClasses = NotImplemented
|
|
||||||
|
|
||||||
def __init__(self, name, repeat, aux, tableClass=None):
|
|
||||||
# we expect all converters to be subclasses of SimpleValue
|
|
||||||
assert all(issubclass(klass, SimpleValue) for klass in self.converterClasses)
|
|
||||||
assert _issubclass_namedtuple(self.tupleClass), repr(self.tupleClass)
|
|
||||||
assert len(self.tupleClass._fields) == len(self.converterClasses)
|
|
||||||
assert tableClass is None # tableClass is unused by SimplValues
|
|
||||||
BaseConverter.__init__(self, name, repeat, aux)
|
|
||||||
self.converters = [
|
|
||||||
klass(name=name, repeat=None, aux=None)
|
|
||||||
for name, klass in zip(self.tupleClass._fields, self.converterClasses)
|
|
||||||
]
|
|
||||||
self.convertersByName = {conv.name: conv for conv in self.converters}
|
|
||||||
# returned by getRecordSize method
|
|
||||||
self.staticSize = sum(c.staticSize for c in self.converters)
|
|
||||||
|
|
||||||
def read(self, reader, font, tableDict):
|
|
||||||
kwargs = {
|
|
||||||
conv.name: conv.read(reader, font, tableDict)
|
|
||||||
for conv in self.converters
|
|
||||||
}
|
|
||||||
return self.tupleClass(**kwargs)
|
|
||||||
|
|
||||||
def write(self, writer, font, tableDict, value, repeatIndex=None):
|
|
||||||
for conv in self.converters:
|
|
||||||
v = getattr(value, conv.name)
|
|
||||||
# repeatIndex is unused for SimpleValues
|
|
||||||
conv.write(writer, font, tableDict, v, repeatIndex=None)
|
|
||||||
|
|
||||||
def xmlWrite(self, xmlWriter, font, value, name, attrs):
|
|
||||||
assert value is not None
|
|
||||||
defaults = value.__new__.__defaults__ or ()
|
|
||||||
assert len(self.converters) >= len(defaults)
|
|
||||||
values = {}
|
|
||||||
required = object()
|
|
||||||
for conv, default in zip_longest(
|
|
||||||
reversed(self.converters),
|
|
||||||
reversed(defaults),
|
|
||||||
fillvalue=required,
|
|
||||||
):
|
|
||||||
v = getattr(value, conv.name)
|
|
||||||
if default is required or v != default:
|
|
||||||
values[conv.name] = conv.toString(v)
|
|
||||||
if attrs is None:
|
|
||||||
attrs = []
|
|
||||||
attrs.extend(
|
|
||||||
(conv.name, values[conv.name])
|
|
||||||
for conv in self.converters
|
|
||||||
if conv.name in values
|
|
||||||
)
|
|
||||||
xmlWriter.simpletag(name, attrs)
|
|
||||||
xmlWriter.newline()
|
|
||||||
|
|
||||||
def xmlRead(self, attrs, content, font):
|
|
||||||
converters = self.convertersByName
|
|
||||||
kwargs = {
|
|
||||||
k: converters[k].fromString(v)
|
|
||||||
for k, v in attrs.items()
|
|
||||||
}
|
|
||||||
return self.tupleClass(**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class VarFixed(_NamedTupleConverter):
|
|
||||||
tupleClass = VariableFloat
|
|
||||||
converterClasses = [Fixed, ULong]
|
|
||||||
|
|
||||||
|
|
||||||
class VarF2Dot14(_NamedTupleConverter):
|
|
||||||
tupleClass = VariableFloat
|
|
||||||
converterClasses = [F2Dot14, ULong]
|
|
||||||
|
|
||||||
|
|
||||||
class VarInt16(_NamedTupleConverter):
|
|
||||||
tupleClass = VariableInt
|
|
||||||
converterClasses = [Short, ULong]
|
|
||||||
|
|
||||||
|
|
||||||
class VarUInt16(_NamedTupleConverter):
|
|
||||||
tupleClass = VariableInt
|
|
||||||
converterClasses = [UShort, ULong]
|
|
||||||
|
|
||||||
|
|
||||||
class VarAngle(_NamedTupleConverter):
|
|
||||||
tupleClass = VariableFloat
|
|
||||||
converterClasses = [F2Dot14, ULong]
|
|
||||||
|
|
||||||
|
|
||||||
class _UInt8Enum(UInt8):
|
class _UInt8Enum(UInt8):
|
||||||
enumClass = NotImplemented
|
enumClass = NotImplemented
|
||||||
@ -1830,6 +1747,7 @@ converterMapping = {
|
|||||||
"uint32": ULong,
|
"uint32": ULong,
|
||||||
"char64": Char64,
|
"char64": Char64,
|
||||||
"Flags32": Flags32,
|
"Flags32": Flags32,
|
||||||
|
"VarIndex": VarIndex,
|
||||||
"Version": Version,
|
"Version": Version,
|
||||||
"Tag": Tag,
|
"Tag": Tag,
|
||||||
"GlyphID": GlyphID,
|
"GlyphID": GlyphID,
|
||||||
@ -1867,11 +1785,4 @@ converterMapping = {
|
|||||||
"OffsetTo": lambda C: partial(Table, tableClass=C),
|
"OffsetTo": lambda C: partial(Table, tableClass=C),
|
||||||
"LOffsetTo": lambda C: partial(LTable, tableClass=C),
|
"LOffsetTo": lambda C: partial(LTable, tableClass=C),
|
||||||
"LOffset24To": lambda C: partial(Table24, tableClass=C),
|
"LOffset24To": lambda C: partial(Table24, tableClass=C),
|
||||||
|
|
||||||
# Variable types
|
|
||||||
"VarFixed": VarFixed,
|
|
||||||
"VarF2Dot14": VarF2Dot14,
|
|
||||||
"VarInt16": VarInt16,
|
|
||||||
"VarUInt16": VarUInt16,
|
|
||||||
"VarAngle": VarAngle,
|
|
||||||
}
|
}
|
||||||
|
@ -988,6 +988,20 @@ otData = [
|
|||||||
('VarIdxMapValue', 'mapping', '', 0, 'Array of compressed data'),
|
('VarIdxMapValue', 'mapping', '', 0, 'Array of compressed data'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
('DeltaSetIndexMapFormat0', [
|
||||||
|
('uint8', 'Format', None, None, 'Format of the DeltaSetIndexMap = 0'),
|
||||||
|
('uint8', 'EntryFormat', None, None, ''), # Automatically computed
|
||||||
|
('uint16', 'MappingCount', None, None, ''), # Automatically computed
|
||||||
|
('VarIdxMapValue', 'mapping', '', 0, 'Array of compressed data'),
|
||||||
|
]),
|
||||||
|
|
||||||
|
('DeltaSetIndexMapFormat1', [
|
||||||
|
('uint8', 'Format', None, None, 'Format of the DeltaSetIndexMap = 1'),
|
||||||
|
('uint8', 'EntryFormat', None, None, ''), # Automatically computed
|
||||||
|
('uint32', 'MappingCount', None, None, ''), # Automatically computed
|
||||||
|
('VarIdxMapValue', 'mapping', '', 0, 'Array of compressed data'),
|
||||||
|
]),
|
||||||
|
|
||||||
# Glyph advance variations
|
# Glyph advance variations
|
||||||
|
|
||||||
('HVAR', [
|
('HVAR', [
|
||||||
@ -1548,6 +1562,7 @@ otData = [
|
|||||||
('uint16', 'LayerRecordCount', None, None, 'Number of Layer Records.'),
|
('uint16', 'LayerRecordCount', None, None, 'Number of Layer Records.'),
|
||||||
('LOffset', 'BaseGlyphList', None, 'Version >= 1', 'Offset (from beginning of COLR table) to array of Version-1 Base Glyph records.'),
|
('LOffset', 'BaseGlyphList', None, 'Version >= 1', 'Offset (from beginning of COLR table) to array of Version-1 Base Glyph records.'),
|
||||||
('LOffset', 'LayerList', None, 'Version >= 1', 'Offset (from beginning of COLR table) to LayerList.'),
|
('LOffset', 'LayerList', None, 'Version >= 1', 'Offset (from beginning of COLR table) to LayerList.'),
|
||||||
|
('LOffsetTo(DeltaSetIndexMap)', 'VarIndexMap', None, 'Version >= 1', 'Offset to DeltaSetIndexMap table (may be NULL)'),
|
||||||
('LOffset', 'VarStore', None, 'Version >= 1', 'Offset to variation store (may be NULL)'),
|
('LOffset', 'VarStore', None, 'Version >= 1', 'Offset to variation store (may be NULL)'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
@ -1603,30 +1618,25 @@ otData = [
|
|||||||
('Fixed', 'dy', None, None, 'Translation in y direction'),
|
('Fixed', 'dy', None, None, 'Translation in y direction'),
|
||||||
]),
|
]),
|
||||||
('VarAffine2x3', [
|
('VarAffine2x3', [
|
||||||
('VarFixed', 'xx', None, None, 'x-part of x basis vector'),
|
('Fixed', 'xx', None, None, 'x-part of x basis vector'),
|
||||||
('VarFixed', 'yx', None, None, 'y-part of x basis vector'),
|
('Fixed', 'yx', None, None, 'y-part of x basis vector'),
|
||||||
('VarFixed', 'xy', None, None, 'x-part of y basis vector'),
|
('Fixed', 'xy', None, None, 'x-part of y basis vector'),
|
||||||
('VarFixed', 'yy', None, None, 'y-part of y basis vector'),
|
('Fixed', 'yy', None, None, 'y-part of y basis vector'),
|
||||||
('VarFixed', 'dx', None, None, 'Translation in x direction'),
|
('Fixed', 'dx', None, None, 'Translation in x direction'),
|
||||||
('VarFixed', 'dy', None, None, 'Translation in y direction'),
|
('Fixed', 'dy', None, None, 'Translation in y direction'),
|
||||||
]),
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
|
|
||||||
('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', [
|
('ColorStop', [
|
||||||
('F2Dot14', 'StopOffset', None, None, ''),
|
('F2Dot14', 'StopOffset', None, None, ''),
|
||||||
('ColorIndex', 'Color', None, None, ''),
|
('uint16', 'PaletteIndex', None, None, 'Index for a CPAL palette entry.'),
|
||||||
|
('F2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved'),
|
||||||
]),
|
]),
|
||||||
('VarColorStop', [
|
('VarColorStop', [
|
||||||
('VarF2Dot14', 'StopOffset', None, None, ''),
|
('F2Dot14', 'StopOffset', None, None, 'VarIndexBase + 0'),
|
||||||
('VarColorIndex', 'Color', None, None, ''),
|
('uint16', 'PaletteIndex', None, None, 'Index for a CPAL palette entry.'),
|
||||||
|
('F2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved. VarIndexBase + 1'),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
('ColorLine', [
|
('ColorLine', [
|
||||||
@ -1650,12 +1660,15 @@ otData = [
|
|||||||
# 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.'),
|
('uint16', 'PaletteIndex', None, None, 'Index for a CPAL palette entry.'),
|
||||||
|
('F2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved'),
|
||||||
]),
|
]),
|
||||||
# PaintVarSolid
|
# 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.'),
|
('uint16', 'PaletteIndex', None, None, 'Index for a CPAL palette entry.'),
|
||||||
|
('F2Dot14', 'Alpha', None, None, 'Values outsided [0.,1.] reserved. VarIndexBase + 0'),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintLinearGradient
|
# PaintLinearGradient
|
||||||
@ -1673,12 +1686,13 @@ otData = [
|
|||||||
('PaintFormat5', [
|
('PaintFormat5', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 5'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 5'),
|
||||||
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarLinearGradient table) to VarColorLine subtable.'),
|
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarLinearGradient table) to VarColorLine subtable.'),
|
||||||
('VarInt16', 'x0', None, None, ''),
|
('int16', 'x0', None, None, ''),
|
||||||
('VarInt16', 'y0', None, None, ''),
|
('int16', 'y0', None, None, ''),
|
||||||
('VarInt16', 'x1', None, None, ''),
|
('int16', 'x1', None, None, ''),
|
||||||
('VarInt16', 'y1', None, None, ''),
|
('int16', 'y1', None, None, ''),
|
||||||
('VarInt16', 'x2', None, None, ''),
|
('int16', 'x2', None, None, ''),
|
||||||
('VarInt16', 'y2', None, None, ''),
|
('int16', 'y2', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintRadialGradient
|
# PaintRadialGradient
|
||||||
@ -1696,12 +1710,13 @@ otData = [
|
|||||||
('PaintFormat7', [
|
('PaintFormat7', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 7'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 7'),
|
||||||
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarRadialGradient table) to VarColorLine subtable.'),
|
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarRadialGradient table) to VarColorLine subtable.'),
|
||||||
('VarInt16', 'x0', None, None, ''),
|
('int16', 'x0', None, None, ''),
|
||||||
('VarInt16', 'y0', None, None, ''),
|
('int16', 'y0', None, None, ''),
|
||||||
('VarUInt16', 'r0', None, None, ''),
|
('uint16', 'r0', None, None, ''),
|
||||||
('VarInt16', 'x1', None, None, ''),
|
('int16', 'x1', None, None, ''),
|
||||||
('VarInt16', 'y1', None, None, ''),
|
('int16', 'y1', None, None, ''),
|
||||||
('VarUInt16', 'r1', None, None, ''),
|
('uint16', 'r1', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintSweepGradient
|
# PaintSweepGradient
|
||||||
@ -1717,10 +1732,11 @@ otData = [
|
|||||||
('PaintFormat9', [
|
('PaintFormat9', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 9'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 9'),
|
||||||
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarSweepGradient table) to VarColorLine subtable.'),
|
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarSweepGradient table) to VarColorLine subtable.'),
|
||||||
('VarInt16', 'centerX', None, None, 'Center x coordinate.'),
|
('int16', 'centerX', None, None, 'Center x coordinate.'),
|
||||||
('VarInt16', 'centerY', None, None, 'Center y coordinate.'),
|
('int16', 'centerY', None, None, 'Center y coordinate.'),
|
||||||
('VarAngle', 'startAngle', None, None, 'Start of the angular range of the gradient.'),
|
('Angle', 'startAngle', None, None, 'Start of the angular range of the gradient.'),
|
||||||
('VarAngle', 'endAngle', None, None, 'End of the angular range of the gradient.'),
|
('Angle', 'endAngle', None, None, 'End of the angular range of the gradient.'),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintGlyph
|
# PaintGlyph
|
||||||
@ -1760,8 +1776,9 @@ otData = [
|
|||||||
('PaintFormat15', [
|
('PaintFormat15', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 15'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 15'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarTranslate table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarTranslate table) to Paint subtable.'),
|
||||||
('VarInt16', 'dx', None, None, 'Translation in x direction.'),
|
('int16', 'dx', None, None, 'Translation in x direction.'),
|
||||||
('VarInt16', 'dy', None, None, 'Translation in y direction.'),
|
('int16', 'dy', None, None, 'Translation in y direction.'),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintScale
|
# PaintScale
|
||||||
@ -1775,8 +1792,9 @@ otData = [
|
|||||||
('PaintFormat17', [
|
('PaintFormat17', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 17'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 17'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScale table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScale table) to Paint subtable.'),
|
||||||
('VarF2Dot14', 'scaleX', None, None, ''),
|
('F2Dot14', 'scaleX', None, None, ''),
|
||||||
('VarF2Dot14', 'scaleY', None, None, ''),
|
('F2Dot14', 'scaleY', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintScaleAroundCenter
|
# PaintScaleAroundCenter
|
||||||
@ -1792,10 +1810,11 @@ otData = [
|
|||||||
('PaintFormat19', [
|
('PaintFormat19', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 19'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 19'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleAroundCenter table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleAroundCenter table) to Paint subtable.'),
|
||||||
('VarF2Dot14', 'scaleX', None, None, ''),
|
('F2Dot14', 'scaleX', None, None, ''),
|
||||||
('VarF2Dot14', 'scaleY', None, None, ''),
|
('F2Dot14', 'scaleY', None, None, ''),
|
||||||
('VarInt16', 'centerX', None, None, ''),
|
('int16', 'centerX', None, None, ''),
|
||||||
('VarInt16', 'centerY', None, None, ''),
|
('int16', 'centerY', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintScaleUniform
|
# PaintScaleUniform
|
||||||
@ -1808,7 +1827,8 @@ otData = [
|
|||||||
('PaintFormat21', [
|
('PaintFormat21', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 21'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 21'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleUniform table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleUniform table) to Paint subtable.'),
|
||||||
('VarF2Dot14', 'scale', None, None, ''),
|
('F2Dot14', 'scale', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintScaleUniformAroundCenter
|
# PaintScaleUniformAroundCenter
|
||||||
@ -1823,9 +1843,10 @@ otData = [
|
|||||||
('PaintFormat23', [
|
('PaintFormat23', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 23'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 23'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleUniformAroundCenter table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarScaleUniformAroundCenter table) to Paint subtable.'),
|
||||||
('VarF2Dot14', 'scale', None, None, ''),
|
('F2Dot14', 'scale', None, None, ''),
|
||||||
('VarInt16', 'centerX', None, None, ''),
|
('int16', 'centerX', None, None, ''),
|
||||||
('VarInt16', 'centerY', None, None, ''),
|
('int16', 'centerY', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintRotate
|
# PaintRotate
|
||||||
@ -1838,7 +1859,8 @@ otData = [
|
|||||||
('PaintFormat25', [
|
('PaintFormat25', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 25'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 25'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotate table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotate table) to Paint subtable.'),
|
||||||
('VarAngle', 'angle', None, None, ''),
|
('Angle', 'angle', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintRotateAroundCenter
|
# PaintRotateAroundCenter
|
||||||
@ -1853,9 +1875,10 @@ otData = [
|
|||||||
('PaintFormat27', [
|
('PaintFormat27', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 27'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 27'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotateAroundCenter table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarRotateAroundCenter table) to Paint subtable.'),
|
||||||
('VarAngle', 'angle', None, None, ''),
|
('Angle', 'angle', None, None, ''),
|
||||||
('VarInt16', 'centerX', None, None, ''),
|
('int16', 'centerX', None, None, ''),
|
||||||
('VarInt16', 'centerY', None, None, ''),
|
('int16', 'centerY', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintSkew
|
# PaintSkew
|
||||||
@ -1869,8 +1892,9 @@ otData = [
|
|||||||
('PaintFormat29', [
|
('PaintFormat29', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 29'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 29'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkew table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkew table) to Paint subtable.'),
|
||||||
('VarAngle', 'xSkewAngle', None, None, ''),
|
('Angle', 'xSkewAngle', None, None, ''),
|
||||||
('VarAngle', 'ySkewAngle', None, None, ''),
|
('Angle', 'ySkewAngle', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintSkewAroundCenter
|
# PaintSkewAroundCenter
|
||||||
@ -1886,10 +1910,11 @@ otData = [
|
|||||||
('PaintFormat31', [
|
('PaintFormat31', [
|
||||||
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 31'),
|
('uint8', 'PaintFormat', None, None, 'Format identifier-format = 31'),
|
||||||
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkewAroundCenter table) to Paint subtable.'),
|
('Offset24', 'Paint', None, None, 'Offset (from beginning of PaintVarSkewAroundCenter table) to Paint subtable.'),
|
||||||
('VarAngle', 'xSkewAngle', None, None, ''),
|
('Angle', 'xSkewAngle', None, None, ''),
|
||||||
('VarAngle', 'ySkewAngle', None, None, ''),
|
('Angle', 'ySkewAngle', None, None, ''),
|
||||||
('VarInt16', 'centerX', None, None, ''),
|
('int16', 'centerX', None, None, ''),
|
||||||
('VarInt16', 'centerY', None, None, ''),
|
('int16', 'centerY', None, None, ''),
|
||||||
|
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
# PaintComposite
|
# PaintComposite
|
||||||
|
@ -618,6 +618,73 @@ class Coverage(FormatSwitchingBaseTable):
|
|||||||
glyphs.append(attrs["value"])
|
glyphs.append(attrs["value"])
|
||||||
|
|
||||||
|
|
||||||
|
class DeltaSetIndexMap(getFormatSwitchingBaseTableClass("uint8")):
|
||||||
|
|
||||||
|
def populateDefaults(self, propagator=None):
|
||||||
|
if not hasattr(self, 'mapping'):
|
||||||
|
self.mapping = []
|
||||||
|
|
||||||
|
def postRead(self, rawTable, font):
|
||||||
|
assert (rawTable['EntryFormat'] & 0xFFC0) == 0
|
||||||
|
self.mapping = rawTable['mapping']
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getEntryFormat(mapping):
|
||||||
|
ored = 0
|
||||||
|
for idx in mapping:
|
||||||
|
ored |= idx
|
||||||
|
|
||||||
|
inner = ored & 0xFFFF
|
||||||
|
innerBits = 0
|
||||||
|
while inner:
|
||||||
|
innerBits += 1
|
||||||
|
inner >>= 1
|
||||||
|
innerBits = max(innerBits, 1)
|
||||||
|
assert innerBits <= 16
|
||||||
|
|
||||||
|
ored = (ored >> (16-innerBits)) | (ored & ((1<<innerBits)-1))
|
||||||
|
if ored <= 0x000000FF:
|
||||||
|
entrySize = 1
|
||||||
|
elif ored <= 0x0000FFFF:
|
||||||
|
entrySize = 2
|
||||||
|
elif ored <= 0x00FFFFFF:
|
||||||
|
entrySize = 3
|
||||||
|
else:
|
||||||
|
entrySize = 4
|
||||||
|
|
||||||
|
return ((entrySize - 1) << 4) | (innerBits - 1)
|
||||||
|
|
||||||
|
def preWrite(self, font):
|
||||||
|
mapping = getattr(self, "mapping", None)
|
||||||
|
if mapping is None:
|
||||||
|
mapping = self.mapping = []
|
||||||
|
self.Format = 1 if len(mapping) > 0xFFFF else 0
|
||||||
|
rawTable = self.__dict__.copy()
|
||||||
|
rawTable['MappingCount'] = len(mapping)
|
||||||
|
rawTable['EntryFormat'] = self.getEntryFormat(mapping)
|
||||||
|
return rawTable
|
||||||
|
|
||||||
|
def toXML2(self, xmlWriter, font):
|
||||||
|
for i, value in enumerate(getattr(self, "mapping", [])):
|
||||||
|
attrs = (
|
||||||
|
('index', i),
|
||||||
|
('outer', value >> 16),
|
||||||
|
('inner', value & 0xFFFF),
|
||||||
|
)
|
||||||
|
xmlWriter.simpletag("Map", attrs)
|
||||||
|
xmlWriter.newline()
|
||||||
|
|
||||||
|
def fromXML(self, name, attrs, content, font):
|
||||||
|
mapping = getattr(self, "mapping", None)
|
||||||
|
if mapping is None:
|
||||||
|
self.mapping = mapping = []
|
||||||
|
index = safeEval(attrs['index'])
|
||||||
|
outer = safeEval(attrs['outer'])
|
||||||
|
inner = safeEval(attrs['inner'])
|
||||||
|
assert inner <= 0xFFFF
|
||||||
|
mapping.insert(index, (outer << 16) | inner)
|
||||||
|
|
||||||
|
|
||||||
class VarIdxMap(BaseTable):
|
class VarIdxMap(BaseTable):
|
||||||
|
|
||||||
def populateDefaults(self, propagator=None):
|
def populateDefaults(self, propagator=None):
|
||||||
@ -641,34 +708,9 @@ class VarIdxMap(BaseTable):
|
|||||||
while len(mapping) > 1 and mapping[-2] == mapping[-1]:
|
while len(mapping) > 1 and mapping[-2] == mapping[-1]:
|
||||||
del mapping[-1]
|
del mapping[-1]
|
||||||
|
|
||||||
rawTable = { 'mapping': mapping }
|
rawTable = {'mapping': mapping}
|
||||||
rawTable['MappingCount'] = len(mapping)
|
rawTable['MappingCount'] = len(mapping)
|
||||||
|
rawTable['EntryFormat'] = DeltaSetIndexMap.getEntryFormat(mapping)
|
||||||
ored = 0
|
|
||||||
for idx in mapping:
|
|
||||||
ored |= idx
|
|
||||||
|
|
||||||
inner = ored & 0xFFFF
|
|
||||||
innerBits = 0
|
|
||||||
while inner:
|
|
||||||
innerBits += 1
|
|
||||||
inner >>= 1
|
|
||||||
innerBits = max(innerBits, 1)
|
|
||||||
assert innerBits <= 16
|
|
||||||
|
|
||||||
ored = (ored >> (16-innerBits)) | (ored & ((1<<innerBits)-1))
|
|
||||||
if ored <= 0x000000FF:
|
|
||||||
entrySize = 1
|
|
||||||
elif ored <= 0x0000FFFF:
|
|
||||||
entrySize = 2
|
|
||||||
elif ored <= 0x00FFFFFF:
|
|
||||||
entrySize = 3
|
|
||||||
else:
|
|
||||||
entrySize = 4
|
|
||||||
|
|
||||||
entryFormat = ((entrySize - 1) << 4) | (innerBits - 1)
|
|
||||||
|
|
||||||
rawTable['EntryFormat'] = entryFormat
|
|
||||||
return rawTable
|
return rawTable
|
||||||
|
|
||||||
def toXML2(self, xmlWriter, font):
|
def toXML2(self, xmlWriter, font):
|
||||||
@ -1255,43 +1297,6 @@ class BaseGlyphList(BaseTable):
|
|||||||
return self.__dict__.copy()
|
return self.__dict__.copy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class VariableValue(namedtuple("VariableValue", ["value", "varIdx"])):
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
_value_mapper = None
|
|
||||||
|
|
||||||
def __new__(cls, value, varIdx=0xFFFFFFFF):
|
|
||||||
return super().__new__(
|
|
||||||
cls,
|
|
||||||
cls._value_mapper(value) if cls._value_mapper else value,
|
|
||||||
varIdx
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _make(cls, iterable):
|
|
||||||
if cls._value_mapper:
|
|
||||||
it = iter(iterable)
|
|
||||||
try:
|
|
||||||
value = next(it)
|
|
||||||
except StopIteration:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
value = cls._value_mapper(value)
|
|
||||||
iterable = itertools.chain((value,), it)
|
|
||||||
return super()._make(iterable)
|
|
||||||
|
|
||||||
|
|
||||||
class VariableFloat(VariableValue):
|
|
||||||
__slots__ = ()
|
|
||||||
_value_mapper = float
|
|
||||||
|
|
||||||
|
|
||||||
class VariableInt(VariableValue):
|
|
||||||
__slots__ = ()
|
|
||||||
_value_mapper = otRound
|
|
||||||
|
|
||||||
|
|
||||||
class ExtendMode(IntEnum):
|
class ExtendMode(IntEnum):
|
||||||
PAD = 0
|
PAD = 0
|
||||||
REPEAT = 1
|
REPEAT = 1
|
||||||
|
@ -121,6 +121,14 @@ def buildVarIdxMap(varIdxes, glyphOrder):
|
|||||||
self.mapping = {g:v for g,v in zip(glyphOrder, varIdxes)}
|
self.mapping = {g:v for g,v in zip(glyphOrder, varIdxes)}
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
def buildDeltaSetIndexMap(varIdxes):
|
||||||
|
self = ot.DeltaSetIndexMap()
|
||||||
|
self.mapping = list(varIdxes)
|
||||||
|
self.Format = 1 if len(varIdxes) > 0xFFFF else 0
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
def buildVarDevTable(varIdx):
|
def buildVarDevTable(varIdx):
|
||||||
self = ot.Device()
|
self = ot.Device()
|
||||||
self.DeltaFormat = 0x8000
|
self.DeltaFormat = 0x8000
|
||||||
|
@ -231,92 +231,63 @@ 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_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 == 0xFFFFFFFF
|
|
||||||
|
|
||||||
|
|
||||||
def test_buildColorIndex():
|
|
||||||
c = _build(ot.ColorIndex, (1, 0.5))
|
|
||||||
assert c.PaletteIndex == 1
|
|
||||||
assert c.Alpha == 0.5
|
|
||||||
|
|
||||||
|
|
||||||
def test_buildVarColorIndex():
|
|
||||||
c = _build(ot.VarColorIndex, (3, builder.VariableFloat(0.5, varIdx=2)))
|
|
||||||
assert c.PaletteIndex == 3
|
|
||||||
assert c.Alpha.value == 0.5
|
|
||||||
assert c.Alpha.varIdx == 2
|
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintSolid():
|
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.PaletteIndex == 0
|
||||||
assert p.Color.Alpha == 1.0
|
assert p.Alpha == 1.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.PaletteIndex == 1
|
||||||
assert p.Color.Alpha == 0.5
|
assert p.Alpha == 0.5
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintVarSolid():
|
def test_buildPaintVarSolid():
|
||||||
p = _buildPaint(
|
p = _buildPaint((ot.PaintFormat.PaintVarSolid, 3, 0.5, 2))
|
||||||
(ot.PaintFormat.PaintVarSolid, (3, builder.VariableFloat(0.5, varIdx=2)))
|
|
||||||
)
|
|
||||||
assert p.Format == ot.PaintFormat.PaintVarSolid
|
assert p.Format == ot.PaintFormat.PaintVarSolid
|
||||||
assert p.Color.PaletteIndex == 3
|
assert p.PaletteIndex == 3
|
||||||
assert p.Color.Alpha.value == 0.5
|
assert p.Alpha == 0.5
|
||||||
assert p.Color.Alpha.varIdx == 2
|
assert p.VarIndexBase == 2
|
||||||
|
|
||||||
|
|
||||||
def test_buildVarColorStop_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.StopOffset == 0.1
|
||||||
assert s.Color.PaletteIndex == 2
|
assert s.PaletteIndex == 2
|
||||||
assert s.Color.Alpha == builder._DEFAULT_ALPHA.value
|
assert s.Alpha == builder._DEFAULT_ALPHA
|
||||||
|
|
||||||
|
|
||||||
def test_buildVarColorStop_DefaultAlpha():
|
def test_buildVarColorStop_DefaultAlpha():
|
||||||
s = _build(ot.VarColorStop, (0.1, 2))
|
s = _build(ot.VarColorStop, (0.1, 2))
|
||||||
assert s.StopOffset == builder.VariableFloat(0.1)
|
assert s.StopOffset == 0.1
|
||||||
assert s.Color.PaletteIndex == 2
|
assert s.PaletteIndex == 2
|
||||||
assert s.Color.Alpha == builder._DEFAULT_ALPHA
|
assert s.Alpha == builder._DEFAULT_ALPHA
|
||||||
|
|
||||||
|
|
||||||
def test_buildColorStop():
|
def test_buildColorStop():
|
||||||
s = _build(
|
s = _build(ot.ColorStop, {"StopOffset": 0.2, "PaletteIndex": 3, "Alpha": 0.4})
|
||||||
ot.ColorStop, {"StopOffset": 0.2, "Color": {"PaletteIndex": 3, "Alpha": 0.4}}
|
|
||||||
)
|
|
||||||
assert s.StopOffset == 0.2
|
assert s.StopOffset == 0.2
|
||||||
assert s.Color == _build(ot.ColorIndex, (3, 0.4))
|
assert s.PaletteIndex == 3
|
||||||
|
assert s.Alpha == 0.4
|
||||||
|
|
||||||
|
|
||||||
def test_buildColorStop_Variable():
|
def test_buildColorStop_Variable():
|
||||||
s = _build(
|
s = _build(
|
||||||
ot.VarColorStop,
|
ot.VarColorStop,
|
||||||
{
|
{
|
||||||
"StopOffset": builder.VariableFloat(0.0, varIdx=1),
|
"StopOffset": 0.0,
|
||||||
"Color": {
|
|
||||||
"PaletteIndex": 0,
|
"PaletteIndex": 0,
|
||||||
"Alpha": builder.VariableFloat(0.3, varIdx=2),
|
"Alpha": 0.3,
|
||||||
},
|
"VarIndexBase": 1,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assert s.StopOffset == builder.VariableFloat(0.0, varIdx=1)
|
assert s.StopOffset == 0.0
|
||||||
assert s.Color.PaletteIndex == 0
|
assert s.PaletteIndex == 0
|
||||||
assert s.Color.Alpha == builder.VariableFloat(0.3, varIdx=2)
|
assert s.Alpha == 0.3
|
||||||
|
assert s.VarIndexBase == 1
|
||||||
|
|
||||||
|
|
||||||
def test_buildColorLine_StopList():
|
def test_buildColorLine_StopList():
|
||||||
@ -325,7 +296,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 [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
|
assert [(cs.StopOffset, cs.PaletteIndex) for cs in cline.ColorStop] == stops
|
||||||
|
|
||||||
cline = _build(ot.ColorLine, {"Extend": "pad", "ColorStop": stops})
|
cline = _build(ot.ColorLine, {"Extend": "pad", "ColorStop": stops})
|
||||||
assert cline.Extend == builder.ExtendMode.PAD
|
assert cline.Extend == builder.ExtendMode.PAD
|
||||||
@ -343,51 +314,57 @@ 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 [(cs.StopOffset, cs.Color.PaletteIndex) for cs in cline.ColorStop] == stops
|
assert [(cs.StopOffset, cs.PaletteIndex) for cs in cline.ColorStop] == stops
|
||||||
|
|
||||||
|
|
||||||
def test_buildVarColorLine_StopMap():
|
def test_buildVarColorLine_StopMap():
|
||||||
stops = [
|
stops = [
|
||||||
{"StopOffset": (0.0, (1,)), "Color": {"PaletteIndex": 0, "Alpha": (0.5, 2)}},
|
{"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 0.5, "VarIndexBase": 1},
|
||||||
{"StopOffset": (1.0, (3,)), "Color": {"PaletteIndex": 1, "Alpha": (0.3, 4)}},
|
{"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 0.3, "VarIndexBase": 3},
|
||||||
]
|
]
|
||||||
cline = _build(ot.VarColorLine, {"ColorStop": stops})
|
cline = _build(ot.VarColorLine, {"ColorStop": stops})
|
||||||
assert [
|
assert [
|
||||||
{
|
{
|
||||||
"StopOffset": cs.StopOffset,
|
"StopOffset": cs.StopOffset,
|
||||||
"Color": {
|
"PaletteIndex": cs.PaletteIndex,
|
||||||
"PaletteIndex": cs.Color.PaletteIndex,
|
"Alpha": cs.Alpha,
|
||||||
"Alpha": cs.Color.Alpha,
|
"VarIndexBase": cs.VarIndexBase,
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for cs in cline.ColorStop
|
for cs in cline.ColorStop
|
||||||
] == stops
|
] == stops
|
||||||
|
|
||||||
|
|
||||||
def checkBuildAffine2x3(cls, resultMapFn):
|
def checkBuildAffine2x3(cls, variable=False):
|
||||||
matrix = _build(cls, (1.5, 0, 0.5, 2.0, 1.0, -3.0))
|
matrix = _build(cls, (1.5, 0, 0.5, 2.0, 1.0, -3.0))
|
||||||
assert matrix.xx == resultMapFn(1.5)
|
assert matrix.xx == 1.5
|
||||||
assert matrix.yx == resultMapFn(0.0)
|
assert matrix.yx == 0.0
|
||||||
assert matrix.xy == resultMapFn(0.5)
|
assert matrix.xy == 0.5
|
||||||
assert matrix.yy == resultMapFn(2.0)
|
assert matrix.yy == 2.0
|
||||||
assert matrix.dx == resultMapFn(1.0)
|
assert matrix.dx == 1.0
|
||||||
assert matrix.dy == resultMapFn(-3.0)
|
assert matrix.dy == -3.0
|
||||||
|
if variable:
|
||||||
|
assert matrix.VarIndexBase == 0xFFFFFFFF
|
||||||
|
|
||||||
|
|
||||||
def test_buildAffine2x3():
|
def test_buildAffine2x3():
|
||||||
checkBuildAffine2x3(ot.Affine2x3, lambda v: v)
|
checkBuildAffine2x3(ot.Affine2x3)
|
||||||
|
|
||||||
|
|
||||||
def test_buildVarAffine2x3():
|
def test_buildVarAffine2x3():
|
||||||
checkBuildAffine2x3(ot.VarAffine2x3, builder.VariableFloat)
|
checkBuildAffine2x3(ot.VarAffine2x3, variable=True)
|
||||||
|
|
||||||
|
|
||||||
def _sample_stops(cls):
|
def _sample_stops(variable):
|
||||||
return [
|
cls = ot.ColorStop if not variable else ot.VarColorStop
|
||||||
_build(cls, (0.0, 0)),
|
stop_sources = [
|
||||||
_build(cls, (0.5, 1)),
|
{"StopOffset": 0.0, "PaletteIndex": 0},
|
||||||
_build(cls, (1.0, (2, 0.8))),
|
{"StopOffset": 0.5, "PaletteIndex": 1},
|
||||||
|
{"StopOffset": 1.0, "PaletteIndex": 2, "Alpha": 0.8},
|
||||||
]
|
]
|
||||||
|
if variable:
|
||||||
|
for i, src in enumerate(stop_sources, start=123):
|
||||||
|
src["VarIndexBase"] = i
|
||||||
|
return [_build(cls, src) for src in stop_sources]
|
||||||
|
|
||||||
|
|
||||||
def _is_var(fmt):
|
def _is_var(fmt):
|
||||||
@ -403,17 +380,11 @@ def _is_uniform_scale(fmt):
|
|||||||
|
|
||||||
|
|
||||||
def checkBuildPaintLinearGradient(fmt):
|
def checkBuildPaintLinearGradient(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
inputMapFn = builder.VariableInt
|
color_stops = _sample_stops(variable)
|
||||||
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))
|
x0, y0, x1, y1, x2, y2 = (1, 2, 3, 4, 5, 6)
|
||||||
gradient = _buildPaint(
|
source = {
|
||||||
{
|
|
||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"ColorLine": {"ColorStop": color_stops},
|
"ColorLine": {"ColorStop": color_stops},
|
||||||
"x0": x0,
|
"x0": x0,
|
||||||
@ -422,15 +393,19 @@ def checkBuildPaintLinearGradient(fmt):
|
|||||||
"y1": y1,
|
"y1": y1,
|
||||||
"x2": x2,
|
"x2": x2,
|
||||||
"y2": y2,
|
"y2": y2,
|
||||||
},
|
}
|
||||||
)
|
if variable:
|
||||||
|
source["VarIndexBase"] = 7
|
||||||
|
gradient = _buildPaint(source)
|
||||||
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
|
||||||
|
|
||||||
gradient = _buildPaint(gradient)
|
gradient = _buildPaint(gradient)
|
||||||
assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == (1, 2)
|
assert (gradient.x0, gradient.y0) == (1, 2)
|
||||||
assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == (3, 4)
|
assert (gradient.x1, gradient.y1) == (3, 4)
|
||||||
assert (outputMapFn(gradient.x2), outputMapFn(gradient.y2)) == (5, 6)
|
assert (gradient.x2, gradient.y2) == (5, 6)
|
||||||
|
if variable:
|
||||||
|
assert gradient.VarIndexBase == 7
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintLinearGradient():
|
def test_buildPaintLinearGradient():
|
||||||
@ -438,41 +413,40 @@ def test_buildPaintLinearGradient():
|
|||||||
checkBuildPaintLinearGradient(ot.PaintFormat.PaintLinearGradient)
|
checkBuildPaintLinearGradient(ot.PaintFormat.PaintLinearGradient)
|
||||||
|
|
||||||
|
|
||||||
def test_buildVarPaintLinearGradient():
|
def test_buildPaintVarLinearGradient():
|
||||||
assert _is_var(ot.PaintFormat.PaintVarLinearGradient)
|
assert _is_var(ot.PaintFormat.PaintVarLinearGradient)
|
||||||
checkBuildPaintLinearGradient(ot.PaintFormat.PaintVarLinearGradient)
|
checkBuildPaintLinearGradient(ot.PaintFormat.PaintVarLinearGradient)
|
||||||
|
|
||||||
|
|
||||||
def checkBuildPaintRadialGradient(fmt):
|
def checkBuildPaintRadialGradient(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
inputMapFn = builder.VariableInt
|
color_stops = _sample_stops(variable)
|
||||||
outputMapFn = lambda v: v
|
line_cls = ot.VarColorLine if variable else ot.ColorLine
|
||||||
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(
|
||||||
line_cls, {"ColorStop": color_stops, "Extend": builder.ExtendMode.REPEAT}
|
line_cls, {"ColorStop": color_stops, "Extend": builder.ExtendMode.REPEAT}
|
||||||
)
|
)
|
||||||
c0 = (inputMapFn(100), inputMapFn(200))
|
c0 = (100, 200)
|
||||||
c1 = (inputMapFn(150), inputMapFn(250))
|
c1 = (150, 250)
|
||||||
r0 = inputMapFn(10)
|
r0 = 10
|
||||||
r1 = inputMapFn(5)
|
r1 = 5
|
||||||
|
varIndexBase = 0
|
||||||
|
|
||||||
gradient = _build(ot.Paint, (fmt, color_line, *c0, r0, *c1, r1))
|
source = [fmt, color_line, *c0, r0, *c1, r1]
|
||||||
|
if variable:
|
||||||
|
source.append(varIndexBase)
|
||||||
|
|
||||||
|
gradient = _build(ot.Paint, tuple(source))
|
||||||
assert gradient.Format == fmt
|
assert gradient.Format == fmt
|
||||||
assert gradient.ColorLine == color_line
|
assert gradient.ColorLine == color_line
|
||||||
assert (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == c0
|
assert (gradient.x0, gradient.y0) == c0
|
||||||
assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == c1
|
assert (gradient.x1, gradient.y1) == c1
|
||||||
assert outputMapFn(gradient.r0) == r0
|
assert gradient.r0 == r0
|
||||||
assert outputMapFn(gradient.r1) == r1
|
assert gradient.r1 == r1
|
||||||
|
if variable:
|
||||||
|
assert gradient.VarIndexBase == varIndexBase
|
||||||
|
|
||||||
gradient = _build(
|
source = {
|
||||||
ot.Paint,
|
|
||||||
{
|
|
||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"ColorLine": {"ColorStop": color_stops},
|
"ColorLine": {"ColorStop": color_stops},
|
||||||
"x0": c0[0],
|
"x0": c0[0],
|
||||||
@ -481,14 +455,18 @@ def checkBuildPaintRadialGradient(fmt):
|
|||||||
"y1": c1[1],
|
"y1": c1[1],
|
||||||
"r0": r0,
|
"r0": r0,
|
||||||
"r1": r1,
|
"r1": r1,
|
||||||
},
|
}
|
||||||
)
|
if variable:
|
||||||
|
source["VarIndexBase"] = varIndexBase
|
||||||
|
gradient = _build(ot.Paint, source)
|
||||||
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 (outputMapFn(gradient.x0), outputMapFn(gradient.y0)) == c0
|
assert (gradient.x0, gradient.y0) == c0
|
||||||
assert (outputMapFn(gradient.x1), outputMapFn(gradient.y1)) == c1
|
assert (gradient.x1, gradient.y1) == c1
|
||||||
assert outputMapFn(gradient.r0) == r0
|
assert gradient.r0 == r0
|
||||||
assert outputMapFn(gradient.r1) == r1
|
assert gradient.r1 == r1
|
||||||
|
if variable:
|
||||||
|
assert gradient.VarIndexBase == varIndexBase
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintRadialGradient():
|
def test_buildPaintRadialGradient():
|
||||||
@ -502,33 +480,26 @@ def test_buildPaintVarRadialGradient():
|
|||||||
|
|
||||||
|
|
||||||
def checkPaintSweepGradient(fmt):
|
def checkPaintSweepGradient(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
outputMapFn = lambda v: v.value
|
source = {
|
||||||
else:
|
|
||||||
outputMapFn = lambda v: v
|
|
||||||
|
|
||||||
paint = _buildPaint(
|
|
||||||
{
|
|
||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"ColorLine": {
|
"ColorLine": {"ColorStop": _sample_stops(variable)},
|
||||||
"ColorStop": (
|
|
||||||
(0.0, 0),
|
|
||||||
(0.5, 1),
|
|
||||||
(1.0, (2, 0.8)),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
"centerX": 127,
|
"centerX": 127,
|
||||||
"centerY": 129,
|
"centerY": 129,
|
||||||
"startAngle": 15,
|
"startAngle": 15,
|
||||||
"endAngle": 42,
|
"endAngle": 42,
|
||||||
}
|
}
|
||||||
)
|
if variable:
|
||||||
|
source["VarIndexBase"] = 666
|
||||||
|
paint = _buildPaint(source)
|
||||||
|
|
||||||
assert paint.Format == fmt
|
assert paint.Format == fmt
|
||||||
assert outputMapFn(paint.centerX) == 127
|
assert paint.centerX == 127
|
||||||
assert outputMapFn(paint.centerY) == 129
|
assert paint.centerY == 129
|
||||||
assert outputMapFn(paint.startAngle) == 15
|
assert paint.startAngle == 15
|
||||||
assert outputMapFn(paint.endAngle) == 42
|
assert paint.endAngle == 42
|
||||||
|
if variable:
|
||||||
|
assert paint.VarIndexBase == 666
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintSweepGradient():
|
def test_buildPaintSweepGradient():
|
||||||
@ -556,22 +527,19 @@ def test_buildPaintGlyph_Solid():
|
|||||||
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.PaintSolid
|
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
|
||||||
assert layer.Paint.Color.PaletteIndex == 2
|
assert layer.Paint.PaletteIndex == 2
|
||||||
|
|
||||||
layer = _build(
|
layer = _build(
|
||||||
ot.Paint,
|
ot.Paint,
|
||||||
(
|
(
|
||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
(
|
(ot.PaintFormat.PaintSolid, 3, 0.9),
|
||||||
ot.PaintFormat.PaintSolid,
|
|
||||||
(3, 0.9),
|
|
||||||
),
|
|
||||||
"a",
|
"a",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
|
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
|
||||||
assert layer.Paint.Color.PaletteIndex == 3
|
assert layer.Paint.PaletteIndex == 3
|
||||||
assert layer.Paint.Color.Alpha == 0.9
|
assert layer.Paint.Alpha == 0.9
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintGlyph_VarLinearGradient():
|
def test_buildPaintGlyph_VarLinearGradient():
|
||||||
@ -594,14 +562,14 @@ def test_buildPaintGlyph_VarLinearGradient():
|
|||||||
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.PaintVarLinearGradient
|
assert layer.Paint.Format == ot.PaintFormat.PaintVarLinearGradient
|
||||||
assert layer.Paint.ColorLine.ColorStop[0].StopOffset.value == 0.0
|
assert layer.Paint.ColorLine.ColorStop[0].StopOffset == 0.0
|
||||||
assert layer.Paint.ColorLine.ColorStop[0].Color.PaletteIndex == 3
|
assert layer.Paint.ColorLine.ColorStop[0].PaletteIndex == 3
|
||||||
assert layer.Paint.ColorLine.ColorStop[1].StopOffset.value == 1.0
|
assert layer.Paint.ColorLine.ColorStop[1].StopOffset == 1.0
|
||||||
assert layer.Paint.ColorLine.ColorStop[1].Color.PaletteIndex == 4
|
assert layer.Paint.ColorLine.ColorStop[1].PaletteIndex == 4
|
||||||
assert layer.Paint.x0.value == 100
|
assert layer.Paint.x0 == 100
|
||||||
assert layer.Paint.y0.value == 200
|
assert layer.Paint.y0 == 200
|
||||||
assert layer.Paint.x1.value == 150
|
assert layer.Paint.x1 == 150
|
||||||
assert layer.Paint.y1.value == 250
|
assert layer.Paint.y1 == 250
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintGlyph_RadialGradient():
|
def test_buildPaintGlyph_RadialGradient():
|
||||||
@ -615,7 +583,7 @@ def test_buildPaintGlyph_RadialGradient():
|
|||||||
"pad",
|
"pad",
|
||||||
[
|
[
|
||||||
(0.0, 5),
|
(0.0, 5),
|
||||||
{"StopOffset": 0.5, "Color": {"PaletteIndex": 6, "Alpha": 0.8}},
|
{"StopOffset": 0.5, "PaletteIndex": 6, "Alpha": 0.8},
|
||||||
(1.0, 7),
|
(1.0, 7),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -632,12 +600,12 @@ 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 == 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].PaletteIndex == 5
|
||||||
assert layer.Paint.ColorLine.ColorStop[1].StopOffset == 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].PaletteIndex == 6
|
||||||
assert layer.Paint.ColorLine.ColorStop[1].Color.Alpha == 0.8
|
assert layer.Paint.ColorLine.ColorStop[1].Alpha == 0.8
|
||||||
assert layer.Paint.ColorLine.ColorStop[2].StopOffset == 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].PaletteIndex == 7
|
||||||
assert layer.Paint.x0 == 50
|
assert layer.Paint.x0 == 50
|
||||||
assert layer.Paint.y0 == 50
|
assert layer.Paint.y0 == 50
|
||||||
assert layer.Paint.r0 == 30
|
assert layer.Paint.r0 == 30
|
||||||
@ -659,7 +627,7 @@ def test_buildPaintGlyph_Dict_Solid():
|
|||||||
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.PaintSolid
|
assert layer.Paint.Format == ot.PaintFormat.PaintSolid
|
||||||
assert layer.Paint.Color.PaletteIndex == 1
|
assert layer.Paint.PaletteIndex == 1
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintGlyph_Dict_VarLinearGradient():
|
def test_buildPaintGlyph_Dict_VarLinearGradient():
|
||||||
@ -681,7 +649,7 @@ def test_buildPaintGlyph_Dict_VarLinearGradient():
|
|||||||
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.PaintVarLinearGradient
|
assert layer.Paint.Format == ot.PaintFormat.PaintVarLinearGradient
|
||||||
assert layer.Paint.ColorLine.ColorStop[0].StopOffset.value == 0.0
|
assert layer.Paint.ColorLine.ColorStop[0].StopOffset == 0.0
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintGlyph_Dict_RadialGradient():
|
def test_buildPaintGlyph_Dict_RadialGradient():
|
||||||
@ -712,19 +680,21 @@ def test_buildPaintColrGlyph():
|
|||||||
|
|
||||||
|
|
||||||
def checkBuildPaintTransform(fmt):
|
def checkBuildPaintTransform(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
inputMapFn = builder.VariableFloat
|
if variable:
|
||||||
outputMapFn = lambda v: v.value
|
|
||||||
affine_cls = ot.VarAffine2x3
|
affine_cls = ot.VarAffine2x3
|
||||||
else:
|
else:
|
||||||
inputMapFn = outputMapFn = lambda v: v
|
|
||||||
affine_cls = ot.Affine2x3
|
affine_cls = ot.Affine2x3
|
||||||
|
|
||||||
|
affine_src = [1, 2, 3, 4, 5, 6]
|
||||||
|
if variable:
|
||||||
|
affine_src.append(7)
|
||||||
|
|
||||||
paint = _buildPaint(
|
paint = _buildPaint(
|
||||||
(
|
(
|
||||||
int(fmt),
|
int(fmt),
|
||||||
(ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, (0, 1.0)), "a"),
|
(ot.PaintFormat.PaintGlyph, (ot.PaintFormat.PaintSolid, 0, 1.0), "a"),
|
||||||
_build(affine_cls, (1, 2, 3, 4, 5, 6)),
|
_build(affine_cls, tuple(affine_src)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -732,18 +702,23 @@ def checkBuildPaintTransform(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 outputMapFn(paint.Transform.xx) == 1.0
|
assert paint.Transform.xx == 1.0
|
||||||
assert outputMapFn(paint.Transform.yx) == 2.0
|
assert paint.Transform.yx == 2.0
|
||||||
assert outputMapFn(paint.Transform.xy) == 3.0
|
assert paint.Transform.xy == 3.0
|
||||||
assert outputMapFn(paint.Transform.yy) == 4.0
|
assert paint.Transform.yy == 4.0
|
||||||
assert outputMapFn(paint.Transform.dx) == 5.0
|
assert paint.Transform.dx == 5.0
|
||||||
assert outputMapFn(paint.Transform.dy) == 6.0
|
assert paint.Transform.dy == 6.0
|
||||||
|
if variable:
|
||||||
|
assert paint.Transform.VarIndexBase == 7
|
||||||
|
|
||||||
|
affine_src = [1, 2, 3, 0.3333, 10, 10]
|
||||||
|
if variable:
|
||||||
|
affine_src.append(456) # VarIndexBase
|
||||||
paint = _build(
|
paint = _build(
|
||||||
ot.Paint,
|
ot.Paint,
|
||||||
{
|
{
|
||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"Transform": (1, 2, 3, 0.3333, 10, 10),
|
"Transform": tuple(affine_src),
|
||||||
"Paint": {
|
"Paint": {
|
||||||
"Format": int(ot.PaintFormat.PaintRadialGradient),
|
"Format": int(ot.PaintFormat.PaintRadialGradient),
|
||||||
"ColorLine": {"ColorStop": [(0.0, 0), (1.0, 1)]},
|
"ColorLine": {"ColorStop": [(0.0, 0), (1.0, 1)]},
|
||||||
@ -758,12 +733,14 @@ def checkBuildPaintTransform(fmt):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert paint.Format == fmt
|
assert paint.Format == fmt
|
||||||
assert outputMapFn(paint.Transform.xx) == 1.0
|
assert paint.Transform.xx == 1.0
|
||||||
assert outputMapFn(paint.Transform.yx) == 2.0
|
assert paint.Transform.yx == 2.0
|
||||||
assert outputMapFn(paint.Transform.xy) == 3.0
|
assert paint.Transform.xy == 3.0
|
||||||
assert outputMapFn(paint.Transform.yy) == 0.3333
|
assert paint.Transform.yy == 0.3333
|
||||||
assert outputMapFn(paint.Transform.dx) == 10
|
assert paint.Transform.dx == 10
|
||||||
assert outputMapFn(paint.Transform.dy) == 10
|
assert paint.Transform.dy == 10
|
||||||
|
if variable:
|
||||||
|
assert paint.Transform.VarIndexBase == 456
|
||||||
assert paint.Paint.Format == ot.PaintFormat.PaintRadialGradient
|
assert paint.Paint.Format == ot.PaintFormat.PaintRadialGradient
|
||||||
|
|
||||||
|
|
||||||
@ -802,7 +779,8 @@ def test_buildPaintComposite():
|
|||||||
"Glyph": "a",
|
"Glyph": "a",
|
||||||
"Paint": {
|
"Paint": {
|
||||||
"Format": ot.PaintFormat.PaintSolid,
|
"Format": ot.PaintFormat.PaintSolid,
|
||||||
"Color": (0, 1.0),
|
"PaletteIndex": 0,
|
||||||
|
"Alpha": 0.5,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -813,44 +791,44 @@ def test_buildPaintComposite():
|
|||||||
assert composite.SourcePaint.SourcePaint.Format == ot.PaintFormat.PaintGlyph
|
assert composite.SourcePaint.SourcePaint.Format == ot.PaintFormat.PaintGlyph
|
||||||
assert composite.SourcePaint.SourcePaint.Glyph == "c"
|
assert composite.SourcePaint.SourcePaint.Glyph == "c"
|
||||||
assert composite.SourcePaint.SourcePaint.Paint.Format == ot.PaintFormat.PaintSolid
|
assert composite.SourcePaint.SourcePaint.Paint.Format == ot.PaintFormat.PaintSolid
|
||||||
assert composite.SourcePaint.SourcePaint.Paint.Color.PaletteIndex == 2
|
assert composite.SourcePaint.SourcePaint.Paint.PaletteIndex == 2
|
||||||
assert composite.SourcePaint.CompositeMode == ot.CompositeMode.SRC_OVER
|
assert composite.SourcePaint.CompositeMode == ot.CompositeMode.SRC_OVER
|
||||||
assert composite.SourcePaint.BackdropPaint.Format == ot.PaintFormat.PaintGlyph
|
assert composite.SourcePaint.BackdropPaint.Format == ot.PaintFormat.PaintGlyph
|
||||||
assert composite.SourcePaint.BackdropPaint.Glyph == "b"
|
assert composite.SourcePaint.BackdropPaint.Glyph == "b"
|
||||||
assert composite.SourcePaint.BackdropPaint.Paint.Format == ot.PaintFormat.PaintSolid
|
assert composite.SourcePaint.BackdropPaint.Paint.Format == ot.PaintFormat.PaintSolid
|
||||||
assert composite.SourcePaint.BackdropPaint.Paint.Color.PaletteIndex == 1
|
assert composite.SourcePaint.BackdropPaint.Paint.PaletteIndex == 1
|
||||||
assert composite.CompositeMode == ot.CompositeMode.SRC_OVER
|
assert composite.CompositeMode == ot.CompositeMode.SRC_OVER
|
||||||
assert composite.BackdropPaint.Format == ot.PaintFormat.PaintGlyph
|
assert composite.BackdropPaint.Format == ot.PaintFormat.PaintGlyph
|
||||||
assert composite.BackdropPaint.Glyph == "a"
|
assert composite.BackdropPaint.Glyph == "a"
|
||||||
assert composite.BackdropPaint.Paint.Format == ot.PaintFormat.PaintSolid
|
assert composite.BackdropPaint.Paint.Format == ot.PaintFormat.PaintSolid
|
||||||
assert composite.BackdropPaint.Paint.Color.PaletteIndex == 0
|
assert composite.BackdropPaint.Paint.PaletteIndex == 0
|
||||||
|
assert composite.BackdropPaint.Paint.Alpha == 0.5
|
||||||
|
|
||||||
|
|
||||||
def checkBuildPaintTranslate(fmt):
|
def checkBuildPaintTranslate(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
inputMapFn = builder.VariableInt
|
|
||||||
outputMapFn = lambda v: v.value
|
|
||||||
else:
|
|
||||||
inputMapFn = outputMapFn = lambda v: v
|
|
||||||
|
|
||||||
paint = _build(
|
source = {
|
||||||
ot.Paint,
|
|
||||||
{
|
|
||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"Paint": (
|
"Paint": (
|
||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
(ot.PaintFormat.PaintSolid, (0, 1.0)),
|
(ot.PaintFormat.PaintSolid, 0, 1.0),
|
||||||
"a",
|
"a",
|
||||||
),
|
),
|
||||||
"dx": 123,
|
"dx": 123,
|
||||||
"dy": -345,
|
"dy": -345,
|
||||||
},
|
}
|
||||||
)
|
if variable:
|
||||||
|
source["VarIndexBase"] = 678
|
||||||
|
|
||||||
|
paint = _build(ot.Paint, source)
|
||||||
|
|
||||||
assert paint.Format == fmt
|
assert paint.Format == fmt
|
||||||
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
||||||
assert outputMapFn(paint.dx) == 123
|
assert paint.dx == 123
|
||||||
assert outputMapFn(paint.dy) == -345
|
assert paint.dy == -345
|
||||||
|
if variable:
|
||||||
|
assert paint.VarIndexBase == 678
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintTranslate():
|
def test_buildPaintTranslate():
|
||||||
@ -864,11 +842,7 @@ def test_buildPaintVarTranslate():
|
|||||||
|
|
||||||
|
|
||||||
def checkBuildPaintScale(fmt):
|
def checkBuildPaintScale(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
inputMapFn = builder.VariableInt
|
|
||||||
outputMapFn = lambda v: v.value
|
|
||||||
else:
|
|
||||||
inputMapFn = outputMapFn = lambda v: v
|
|
||||||
around_center = _is_around_center(fmt)
|
around_center = _is_around_center(fmt)
|
||||||
uniform = _is_uniform_scale(fmt)
|
uniform = _is_uniform_scale(fmt)
|
||||||
|
|
||||||
@ -876,7 +850,7 @@ def checkBuildPaintScale(fmt):
|
|||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"Paint": (
|
"Paint": (
|
||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
(ot.PaintFormat.PaintSolid, (0, 1.0)),
|
(ot.PaintFormat.PaintSolid, 0, 1.0),
|
||||||
"a",
|
"a",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -888,19 +862,23 @@ def checkBuildPaintScale(fmt):
|
|||||||
if around_center:
|
if around_center:
|
||||||
source["centerX"] = 127
|
source["centerX"] = 127
|
||||||
source["centerY"] = 129
|
source["centerY"] = 129
|
||||||
|
if variable:
|
||||||
|
source["VarIndexBase"] = 666
|
||||||
|
|
||||||
paint = _build(ot.Paint, source)
|
paint = _build(ot.Paint, source)
|
||||||
|
|
||||||
assert paint.Format == fmt
|
assert paint.Format == fmt
|
||||||
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
||||||
if uniform:
|
if uniform:
|
||||||
assert outputMapFn(paint.scale) == 1.5
|
assert paint.scale == 1.5
|
||||||
else:
|
else:
|
||||||
assert outputMapFn(paint.scaleX) == 1.0
|
assert paint.scaleX == 1.0
|
||||||
assert outputMapFn(paint.scaleY) == 2.0
|
assert paint.scaleY == 2.0
|
||||||
if around_center:
|
if around_center:
|
||||||
assert outputMapFn(paint.centerX) == 127
|
assert paint.centerX == 127
|
||||||
assert outputMapFn(paint.centerY) == 129
|
assert paint.centerY == 129
|
||||||
|
if variable:
|
||||||
|
assert paint.VarIndexBase == 666
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintScale():
|
def test_buildPaintScale():
|
||||||
@ -960,18 +938,14 @@ def test_buildPaintVarScaleUniformAroundCenter():
|
|||||||
|
|
||||||
|
|
||||||
def checkBuildPaintRotate(fmt):
|
def checkBuildPaintRotate(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
inputMapFn = builder.VariableInt
|
|
||||||
outputMapFn = lambda v: v.value
|
|
||||||
else:
|
|
||||||
inputMapFn = outputMapFn = lambda v: v
|
|
||||||
around_center = _is_around_center(fmt)
|
around_center = _is_around_center(fmt)
|
||||||
|
|
||||||
source = {
|
source = {
|
||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"Paint": (
|
"Paint": (
|
||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
(ot.PaintFormat.PaintSolid, (0, 1.0)),
|
(ot.PaintFormat.PaintSolid, 0, 1.0),
|
||||||
"a",
|
"a",
|
||||||
),
|
),
|
||||||
"angle": 15,
|
"angle": 15,
|
||||||
@ -984,10 +958,12 @@ def checkBuildPaintRotate(fmt):
|
|||||||
|
|
||||||
assert paint.Format == fmt
|
assert paint.Format == fmt
|
||||||
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
||||||
assert outputMapFn(paint.angle) == 15
|
assert paint.angle == 15
|
||||||
if around_center:
|
if around_center:
|
||||||
assert outputMapFn(paint.centerX) == 127
|
assert paint.centerX == 127
|
||||||
assert outputMapFn(paint.centerY) == 129
|
assert paint.centerY == 129
|
||||||
|
if variable:
|
||||||
|
assert paint.VarIndexBase == 0xFFFFFFFF
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintRotate():
|
def test_buildPaintRotate():
|
||||||
@ -1015,18 +991,14 @@ def test_buildPaintVarRotateAroundCenter():
|
|||||||
|
|
||||||
|
|
||||||
def checkBuildPaintSkew(fmt):
|
def checkBuildPaintSkew(fmt):
|
||||||
if _is_var(fmt):
|
variable = _is_var(fmt)
|
||||||
inputMapFn = builder.VariableInt
|
|
||||||
outputMapFn = lambda v: v.value
|
|
||||||
else:
|
|
||||||
inputMapFn = outputMapFn = lambda v: v
|
|
||||||
around_center = _is_around_center(fmt)
|
around_center = _is_around_center(fmt)
|
||||||
|
|
||||||
source = {
|
source = {
|
||||||
"Format": fmt,
|
"Format": fmt,
|
||||||
"Paint": (
|
"Paint": (
|
||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
(ot.PaintFormat.PaintSolid, (0, 1.0)),
|
(ot.PaintFormat.PaintSolid, 0, 1.0),
|
||||||
"a",
|
"a",
|
||||||
),
|
),
|
||||||
"xSkewAngle": 15,
|
"xSkewAngle": 15,
|
||||||
@ -1035,16 +1007,20 @@ def checkBuildPaintSkew(fmt):
|
|||||||
if around_center:
|
if around_center:
|
||||||
source["centerX"] = 127
|
source["centerX"] = 127
|
||||||
source["centerY"] = 129
|
source["centerY"] = 129
|
||||||
|
if variable:
|
||||||
|
source["VarIndexBase"] = 0
|
||||||
|
|
||||||
paint = _build(ot.Paint, source)
|
paint = _build(ot.Paint, source)
|
||||||
|
|
||||||
assert paint.Format == fmt
|
assert paint.Format == fmt
|
||||||
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
assert paint.Paint.Format == ot.PaintFormat.PaintGlyph
|
||||||
assert outputMapFn(paint.xSkewAngle) == 15
|
assert paint.xSkewAngle == 15
|
||||||
assert outputMapFn(paint.ySkewAngle) == 42
|
assert paint.ySkewAngle == 42
|
||||||
if around_center:
|
if around_center:
|
||||||
assert outputMapFn(paint.centerX) == 127
|
assert paint.centerX == 127
|
||||||
assert outputMapFn(paint.centerY) == 129
|
assert paint.centerY == 129
|
||||||
|
if variable:
|
||||||
|
assert paint.VarIndexBase == 0
|
||||||
|
|
||||||
|
|
||||||
def test_buildPaintSkew():
|
def test_buildPaintSkew():
|
||||||
@ -1087,7 +1063,8 @@ def test_buildColrV1():
|
|||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
{
|
{
|
||||||
"Format": int(ot.PaintFormat.PaintSolid),
|
"Format": int(ot.PaintFormat.PaintSolid),
|
||||||
"Color": {"PaletteIndex": 2, "Alpha": 0.8},
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.8,
|
||||||
},
|
},
|
||||||
"e",
|
"e",
|
||||||
),
|
),
|
||||||
@ -1250,7 +1227,7 @@ def test_build_layerv1list_empty():
|
|||||||
# BaseGlyph, tuple form
|
# BaseGlyph, tuple form
|
||||||
"a": (
|
"a": (
|
||||||
int(ot.PaintFormat.PaintGlyph),
|
int(ot.PaintFormat.PaintGlyph),
|
||||||
(2, (2, 0.8)),
|
(int(ot.PaintFormat.PaintSolid), 2, 0.8),
|
||||||
"b",
|
"b",
|
||||||
),
|
),
|
||||||
# BaseGlyph, map form
|
# BaseGlyph, map form
|
||||||
@ -1301,7 +1278,11 @@ def _paint_names(paints) -> List[str]:
|
|||||||
def test_build_layerv1list_simple():
|
def test_build_layerv1list_simple():
|
||||||
# Two colr glyphs, each with two layers the first of which is common
|
# Two colr glyphs, each with two layers the first of which is common
|
||||||
# All layers use the same solid paint
|
# All layers use the same solid paint
|
||||||
solid_paint = {"Format": 2, "Color": {"PaletteIndex": 2, "Alpha": 0.8}}
|
solid_paint = {
|
||||||
|
"Format": int(ot.PaintFormat.PaintSolid),
|
||||||
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.8,
|
||||||
|
}
|
||||||
backdrop = {
|
backdrop = {
|
||||||
"Format": int(ot.PaintFormat.PaintGlyph),
|
"Format": int(ot.PaintFormat.PaintGlyph),
|
||||||
"Paint": solid_paint,
|
"Paint": solid_paint,
|
||||||
@ -1357,7 +1338,11 @@ def test_build_layerv1list_simple():
|
|||||||
|
|
||||||
def test_build_layerv1list_with_sharing():
|
def test_build_layerv1list_with_sharing():
|
||||||
# Three colr glyphs, each with two layers in common
|
# Three colr glyphs, each with two layers in common
|
||||||
solid_paint = {"Format": 2, "Color": (2, 0.8)}
|
solid_paint = {
|
||||||
|
"Format": int(ot.PaintFormat.PaintSolid),
|
||||||
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.8,
|
||||||
|
}
|
||||||
backdrop = [
|
backdrop = [
|
||||||
{
|
{
|
||||||
"Format": int(ot.PaintFormat.PaintGlyph),
|
"Format": int(ot.PaintFormat.PaintGlyph),
|
||||||
@ -1436,7 +1421,8 @@ def test_build_layerv1list_with_overlaps():
|
|||||||
"Format": ot.PaintFormat.PaintGlyph,
|
"Format": ot.PaintFormat.PaintGlyph,
|
||||||
"Paint": {
|
"Paint": {
|
||||||
"Format": ot.PaintFormat.PaintSolid,
|
"Format": ot.PaintFormat.PaintSolid,
|
||||||
"Color": {"PaletteIndex": 2, "Alpha": 0.8},
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.8,
|
||||||
},
|
},
|
||||||
"Glyph": c,
|
"Glyph": c,
|
||||||
}
|
}
|
||||||
@ -1533,7 +1519,11 @@ class BuildCOLRTest(object):
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
{"Format": 2, "Color": {"PaletteIndex": 2, "Alpha": 0.8}},
|
{
|
||||||
|
"Format": ot.PaintFormat.PaintSolid,
|
||||||
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.8,
|
||||||
|
},
|
||||||
"c",
|
"c",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1591,7 +1581,7 @@ class BuildCOLRTest(object):
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
ot.PaintFormat.PaintGlyph,
|
ot.PaintFormat.PaintGlyph,
|
||||||
(ot.PaintFormat.PaintSolid, (2, 0.8)),
|
(ot.PaintFormat.PaintSolid, 2, 0.8),
|
||||||
"f",
|
"f",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -12,7 +12,8 @@ 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},
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.5,
|
||||||
},
|
},
|
||||||
"Glyph": "glyph00011",
|
"Glyph": "glyph00011",
|
||||||
},
|
},
|
||||||
@ -24,25 +25,32 @@ TEST_COLOR_GLYPHS = {
|
|||||||
"Extend": "repeat",
|
"Extend": "repeat",
|
||||||
"ColorStop": [
|
"ColorStop": [
|
||||||
{
|
{
|
||||||
"StopOffset": (0.0, 0),
|
"StopOffset": 0.0,
|
||||||
"Color": {"PaletteIndex": 3, "Alpha": (1.0, 0)},
|
"PaletteIndex": 3,
|
||||||
|
"Alpha": 1.0,
|
||||||
|
"VarIndexBase": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"StopOffset": (0.5, 0),
|
"StopOffset": 0.5,
|
||||||
"Color": {"PaletteIndex": 4, "Alpha": (1.0, 0)},
|
"PaletteIndex": 4,
|
||||||
|
"Alpha": 1.0,
|
||||||
|
"VarIndexBase": 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"StopOffset": (1.0, 0),
|
"StopOffset": 1.0,
|
||||||
"Color": {"PaletteIndex": 5, "Alpha": (1.0, 0)},
|
"PaletteIndex": 5,
|
||||||
|
"Alpha": 1.0,
|
||||||
|
"VarIndexBase": 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"x0": (1, 0),
|
"x0": 1,
|
||||||
"y0": (2, 0),
|
"y0": 2,
|
||||||
"x1": (-3, 0),
|
"x1": -3,
|
||||||
"y1": (-4, 0),
|
"y1": -4,
|
||||||
"x2": (5, 0),
|
"x2": 5,
|
||||||
"y2": (6, 0),
|
"y2": 6,
|
||||||
|
"VarIndexBase": 0xFFFFFFFF,
|
||||||
},
|
},
|
||||||
"Glyph": "glyph00012",
|
"Glyph": "glyph00012",
|
||||||
},
|
},
|
||||||
@ -57,11 +65,13 @@ TEST_COLOR_GLYPHS = {
|
|||||||
"ColorStop": [
|
"ColorStop": [
|
||||||
{
|
{
|
||||||
"StopOffset": 0,
|
"StopOffset": 0,
|
||||||
"Color": {"PaletteIndex": 6, "Alpha": 1.0},
|
"PaletteIndex": 6,
|
||||||
|
"Alpha": 1.0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"StopOffset": 1.0,
|
"StopOffset": 1.0,
|
||||||
"Color": {"PaletteIndex": 7, "Alpha": 0.4},
|
"PaletteIndex": 7,
|
||||||
|
"Alpha": 0.4,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -73,12 +83,13 @@ TEST_COLOR_GLYPHS = {
|
|||||||
"r1": 12,
|
"r1": 12,
|
||||||
},
|
},
|
||||||
"Transform": {
|
"Transform": {
|
||||||
"xx": (-13.0, 0),
|
"xx": -13.0,
|
||||||
"yx": (14.0, 0),
|
"yx": 14.0,
|
||||||
"xy": (15.0, 0),
|
"xy": 15.0,
|
||||||
"yy": (-17.0, 0),
|
"yy": -17.0,
|
||||||
"dx": (18.0, 0),
|
"dx": 18.0,
|
||||||
"dy": (19.0, 0),
|
"dy": 19.0,
|
||||||
|
"VarIndexBase": 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Glyph": "glyph00013",
|
"Glyph": "glyph00013",
|
||||||
@ -93,17 +104,20 @@ 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},
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.5,
|
||||||
},
|
},
|
||||||
"Glyph": "glyph00011",
|
"Glyph": "glyph00011",
|
||||||
},
|
},
|
||||||
"xSkewAngle": (-11.0, 0),
|
"xSkewAngle": -11.0,
|
||||||
"ySkewAngle": (5.0, 0),
|
"ySkewAngle": 5.0,
|
||||||
|
"VarIndexBase": 4,
|
||||||
},
|
},
|
||||||
"angle": 45.0,
|
"angle": 45.0,
|
||||||
},
|
},
|
||||||
"dx": (257.0, 0),
|
"dx": 257.0,
|
||||||
"dy": (258.0, 0),
|
"dy": 258.0,
|
||||||
|
"VarIndexBase": 5,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -139,11 +153,13 @@ TEST_COLOR_GLYPHS = {
|
|||||||
"ColorStop": [
|
"ColorStop": [
|
||||||
{
|
{
|
||||||
"StopOffset": 0.0,
|
"StopOffset": 0.0,
|
||||||
"Color": {"PaletteIndex": 3, "Alpha": 1.0},
|
"PaletteIndex": 3,
|
||||||
|
"Alpha": 1.0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"StopOffset": 1.0,
|
"StopOffset": 1.0,
|
||||||
"Color": {"PaletteIndex": 5, "Alpha": 1.0},
|
"PaletteIndex": 5,
|
||||||
|
"Alpha": 1.0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -161,7 +177,9 @@ TEST_COLOR_GLYPHS = {
|
|||||||
"Format": int(ot.PaintFormat.PaintGlyph),
|
"Format": int(ot.PaintFormat.PaintGlyph),
|
||||||
"Paint": {
|
"Paint": {
|
||||||
"Format": int(ot.PaintFormat.PaintVarSolid),
|
"Format": int(ot.PaintFormat.PaintVarSolid),
|
||||||
"Color": {"PaletteIndex": 2, "Alpha": (0.5, 0)},
|
"PaletteIndex": 2,
|
||||||
|
"Alpha": 0.5,
|
||||||
|
"VarIndexBase": 6,
|
||||||
},
|
},
|
||||||
"Glyph": "glyph00011",
|
"Glyph": "glyph00011",
|
||||||
},
|
},
|
||||||
@ -173,25 +191,32 @@ TEST_COLOR_GLYPHS = {
|
|||||||
"Extend": "repeat",
|
"Extend": "repeat",
|
||||||
"ColorStop": [
|
"ColorStop": [
|
||||||
{
|
{
|
||||||
"StopOffset": (0.0, 0),
|
"StopOffset": 0.0,
|
||||||
"Color": {"PaletteIndex": 3, "Alpha": (1.0, 0)},
|
"PaletteIndex": 3,
|
||||||
|
"Alpha": 1.0,
|
||||||
|
"VarIndexBase": 7,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"StopOffset": (0.5, 0),
|
"StopOffset": 0.5,
|
||||||
"Color": {"PaletteIndex": 4, "Alpha": (1.0, 0)},
|
"PaletteIndex": 4,
|
||||||
|
"Alpha": 1.0,
|
||||||
|
"VarIndexBase": 8,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"StopOffset": (1.0, 0),
|
"StopOffset": 1.0,
|
||||||
"Color": {"PaletteIndex": 5, "Alpha": (1.0, 0)},
|
"PaletteIndex": 5,
|
||||||
|
"Alpha": 1.0,
|
||||||
|
"VarIndexBase": 9,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"x0": (1, 0),
|
"x0": 1,
|
||||||
"y0": (2, 0),
|
"y0": 2,
|
||||||
"x1": (-3, 0),
|
"x1": -3,
|
||||||
"y1": (-4, 0),
|
"y1": -4,
|
||||||
"x2": (5, 0),
|
"x2": 5,
|
||||||
"y2": (6, 0),
|
"y2": 6,
|
||||||
|
"VarIndexBase": 0xFFFFFFFF,
|
||||||
},
|
},
|
||||||
"Glyph": "glyph00012",
|
"Glyph": "glyph00012",
|
||||||
},
|
},
|
||||||
|
@ -1013,7 +1013,7 @@ def colrv1_path(tmp_path):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Format": ot.PaintFormat.PaintGlyph,
|
"Format": ot.PaintFormat.PaintGlyph,
|
||||||
"Paint": (ot.PaintFormat.PaintSolid, (2, 0.3)),
|
"Paint": (ot.PaintFormat.PaintSolid, 2, 0.3),
|
||||||
"Glyph": "glyph00011",
|
"Glyph": "glyph00011",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -1044,7 +1044,7 @@ def colrv1_path(tmp_path):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Format": ot.PaintFormat.PaintGlyph,
|
"Format": ot.PaintFormat.PaintGlyph,
|
||||||
"Paint": (ot.PaintFormat.PaintSolid, (1, 0.5)),
|
"Paint": (ot.PaintFormat.PaintSolid, 1, 0.5),
|
||||||
"Glyph": "glyph00013",
|
"Glyph": "glyph00013",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -1159,9 +1159,9 @@ def test_subset_COLRv1_and_CPAL(colrv1_path):
|
|||||||
]
|
]
|
||||||
assert len(layers) == 2
|
assert len(layers) == 2
|
||||||
# check v1 palette indices were remapped
|
# check v1 palette indices were remapped
|
||||||
assert layers[0].Paint.Paint.ColorLine.ColorStop[0].Color.PaletteIndex == 0
|
assert layers[0].Paint.Paint.ColorLine.ColorStop[0].PaletteIndex == 0
|
||||||
assert layers[0].Paint.Paint.ColorLine.ColorStop[1].Color.PaletteIndex == 1
|
assert layers[0].Paint.Paint.ColorLine.ColorStop[1].PaletteIndex == 1
|
||||||
assert layers[1].Paint.Color.PaletteIndex == 0
|
assert layers[1].Paint.PaletteIndex == 0
|
||||||
|
|
||||||
baseRecV0 = colr.BaseGlyphRecordArray.BaseGlyphRecord[0]
|
baseRecV0 = colr.BaseGlyphRecordArray.BaseGlyphRecord[0]
|
||||||
assert baseRecV0.BaseGlyph == "uniE004"
|
assert baseRecV0.BaseGlyph == "uniE004"
|
||||||
|
@ -104,13 +104,14 @@ COLR_V1_SAMPLE = (
|
|||||||
(b"\x00\x01", "Version (1)"),
|
(b"\x00\x01", "Version (1)"),
|
||||||
(b"\x00\x01", "BaseGlyphRecordCount (1)"),
|
(b"\x00\x01", "BaseGlyphRecordCount (1)"),
|
||||||
(
|
(
|
||||||
b"\x00\x00\x00\x1a",
|
b"\x00\x00\x00\x1e",
|
||||||
"Offset to BaseGlyphRecordArray from beginning of table (26)",
|
"Offset to BaseGlyphRecordArray from beginning of table (30)",
|
||||||
),
|
),
|
||||||
(b"\x00\x00\x00 ", "Offset to LayerRecordArray from beginning of table (32)"),
|
(b"\x00\x00\x00\x24", "Offset to LayerRecordArray from beginning of table (36)"),
|
||||||
(b"\x00\x03", "LayerRecordCount (3)"),
|
(b"\x00\x03", "LayerRecordCount (3)"),
|
||||||
(b"\x00\x00\x00,", "Offset to BaseGlyphList from beginning of table (44)"),
|
(b"\x00\x00\x00\x30", "Offset to BaseGlyphList from beginning of table (48)"),
|
||||||
(b"\x00\x00\x00\xab", "Offset to LayerList from beginning of table (171)"),
|
(b"\x00\x00\x00\x9b", "Offset to LayerList from beginning of table (155)"),
|
||||||
|
(b"\x00\x00\x00\x00", "Offset to DeltaSetIndexMap (NULL)"),
|
||||||
(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)"),
|
||||||
@ -135,8 +136,8 @@ COLR_V1_SAMPLE = (
|
|||||||
),
|
),
|
||||||
(b"\x00\x0f", "BaseGlyphList.BaseGlyphPaintRecord[2].BaseGlyph (15)"),
|
(b"\x00\x0f", "BaseGlyphList.BaseGlyphPaintRecord[2].BaseGlyph (15)"),
|
||||||
(
|
(
|
||||||
b"\x00\x00\x00\x5e",
|
b"\x00\x00\x00\x4a",
|
||||||
"Offset to Paint table from beginning of BaseGlyphList (94)",
|
"Offset to Paint table from beginning of BaseGlyphList (74)",
|
||||||
),
|
),
|
||||||
# BaseGlyphPaintRecord[0]
|
# BaseGlyphPaintRecord[0]
|
||||||
(b"\x01", "BaseGlyphPaintRecord[0].Paint.Format (1)"),
|
(b"\x01", "BaseGlyphPaintRecord[0].Paint.Format (1)"),
|
||||||
@ -152,12 +153,13 @@ COLR_V1_SAMPLE = (
|
|||||||
(b"\x00\x00\x0a", "Offset to VarAffine2x3 from beginning of PaintVarTransform (10)"),
|
(b"\x00\x00\x0a", "Offset to VarAffine2x3 from beginning of PaintVarTransform (10)"),
|
||||||
(b"\x0b", "BaseGlyphPaintRecord[1].Paint.BackdropPaint.Format (11)"),
|
(b"\x0b", "BaseGlyphPaintRecord[1].Paint.BackdropPaint.Format (11)"),
|
||||||
(b"\x00\x0a", "BaseGlyphPaintRecord[1].Paint.BackdropPaint.Glyph (10)"),
|
(b"\x00\x0a", "BaseGlyphPaintRecord[1].Paint.BackdropPaint.Glyph (10)"),
|
||||||
(b"\x00\x01\x00\x00\xff\xff\xff\xff", "VarAffine2x3.xx (1.0)"),
|
(b"\x00\x01\x00\x00", "VarAffine2x3.xx (1.0)"),
|
||||||
(b"\x00\x00\x00\x00\xff\xff\xff\xff", "VarAffine2x3.xy (0.0)"),
|
(b"\x00\x00\x00\x00", "VarAffine2x3.xy (0.0)"),
|
||||||
(b"\x00\x00\x00\x00\xff\xff\xff\xff", "VarAffine2x3.yx (0.0)"),
|
(b"\x00\x00\x00\x00", "VarAffine2x3.yx (0.0)"),
|
||||||
(b"\x00\x01\x00\x00\xff\xff\xff\xff", "VarAffine2x3.yy (1.0)"),
|
(b"\x00\x01\x00\x00", "VarAffine2x3.yy (1.0)"),
|
||||||
(b"\x01\x2c\x00\x00\xff\xff\xff\xff", "VarAffine2x3.dx (300.0)"),
|
(b"\x01\x2c\x00\x00", "VarAffine2x3.dx (300.0)"),
|
||||||
(b"\x00\x00\x00\x00\xff\xff\xff\xff", "VarAffine2x3.dy (0.0)"),
|
(b"\x00\x00\x00\x00", "VarAffine2x3.dy (0.0)"),
|
||||||
|
(b"\x00\x00\x00\x00", "VarIndexBase (0)"),
|
||||||
(b"\x0a", "BaseGlyphPaintRecord[1].Paint.SourcePaint.Format (10)"),
|
(b"\x0a", "BaseGlyphPaintRecord[1].Paint.SourcePaint.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", "BaseGlyphPaintRecord[1].Paint.SourcePaint.Glyph (11)"),
|
(b"\x00\x0b", "BaseGlyphPaintRecord[1].Paint.SourcePaint.Glyph (11)"),
|
||||||
@ -170,11 +172,11 @@ COLR_V1_SAMPLE = (
|
|||||||
(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 (0.0)"),
|
(b"\x00\x00", "ColorLine.ColorStop[0].StopOffset (0.0)"),
|
||||||
(b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"),
|
(b"\x00\x03", "ColorLine.ColorStop[0].PaletteIndex (3)"),
|
||||||
(b"@\x00", "ColorLine.ColorStop[0].Color.Alpha (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[0].Alpha (1.0)"),
|
||||||
(b"@\x00", "ColorLine.ColorStop[1].StopOffset (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[1].StopOffset (1.0)"),
|
||||||
(b"\x00\x05", "ColorLine.ColorStop[1].Color.PaletteIndex (5)"),
|
(b"\x00\x05", "ColorLine.ColorStop[1].PaletteIndex (5)"),
|
||||||
(b"@\x00", "ColorLine.ColorStop[1].Color.Alpha (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[1].Alpha (1.0)"),
|
||||||
# LayerList
|
# LayerList
|
||||||
(b"\x00\x00\x00\x04", "LayerList.LayerCount (4)"),
|
(b"\x00\x00\x00\x04", "LayerList.LayerCount (4)"),
|
||||||
(
|
(
|
||||||
@ -190,8 +192,8 @@ COLR_V1_SAMPLE = (
|
|||||||
"Third Offset to Paint table from beginning of LayerList (78)",
|
"Third Offset to Paint table from beginning of LayerList (78)",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
b"\x00\x00\x00\xba",
|
b"\x00\x00\x00\x9e",
|
||||||
"Fourth Offset to Paint table from beginning of LayerList (186)",
|
"Fourth Offset to Paint table from beginning of LayerList (158)",
|
||||||
),
|
),
|
||||||
# BaseGlyphPaintRecord[2]
|
# BaseGlyphPaintRecord[2]
|
||||||
(b"\x0a", "BaseGlyphPaintRecord[2].Paint.Format (10)"),
|
(b"\x0a", "BaseGlyphPaintRecord[2].Paint.Format (10)"),
|
||||||
@ -199,9 +201,9 @@ COLR_V1_SAMPLE = (
|
|||||||
(b"\x00\x0b", "BaseGlyphPaintRecord[2].Paint.Glyph (11)"),
|
(b"\x00\x0b", "BaseGlyphPaintRecord[2].Paint.Glyph (11)"),
|
||||||
# PaintVarSolid
|
# PaintVarSolid
|
||||||
(b"\x03", "LayerList.Paint[0].Paint.Format (3)"),
|
(b"\x03", "LayerList.Paint[0].Paint.Format (3)"),
|
||||||
(b"\x00\x02", "Paint.Color.PaletteIndex (2)"),
|
(b"\x00\x02", "Paint.PaletteIndex (2)"),
|
||||||
(b" \x00", "Paint.Color.Alpha.value (0.5)"),
|
(b" \x00", "Paint.Alpha.value (0.5)"),
|
||||||
(b"\xff\xff\xff\xff", "Paint.Color.Alpha.varIdx (0xFFFFFFFF)"),
|
(b"\x00\x00\x00\x06", "VarIndexBase (6)"),
|
||||||
# PaintGlyph glyph00012
|
# PaintGlyph glyph00012
|
||||||
(b"\x0a", "LayerList.Paint[1].Format (10)"),
|
(b"\x0a", "LayerList.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)"),
|
||||||
@ -217,38 +219,41 @@ COLR_V1_SAMPLE = (
|
|||||||
(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 (0.0)"),
|
(b"\x00\x00", "ColorLine.ColorStop[0].StopOffset (0.0)"),
|
||||||
(b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"),
|
(b"\x00\x03", "ColorLine.ColorStop[0].PaletteIndex (3)"),
|
||||||
(b"@\x00", "ColorLine.ColorStop[0].Color.Alpha (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[0].Alpha (1.0)"),
|
||||||
(b" \x00", "ColorLine.ColorStop[1].StopOffset (0.5)"),
|
(b" \x00", "ColorLine.ColorStop[1].StopOffset (0.5)"),
|
||||||
(b"\x00\x04", "ColorLine.ColorStop[1].Color.PaletteIndex (4)"),
|
(b"\x00\x04", "ColorLine.ColorStop[1].PaletteIndex (4)"),
|
||||||
(b"@\x00", "ColorLine.ColorStop[1].Color.Alpha (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[1].Alpha (1.0)"),
|
||||||
(b"@\x00", "ColorLine.ColorStop[2].StopOffset (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[2].StopOffset (1.0)"),
|
||||||
(b"\x00\x05", "ColorLine.ColorStop[2].Color.PaletteIndex (5)"),
|
(b"\x00\x05", "ColorLine.ColorStop[2].PaletteIndex (5)"),
|
||||||
(b"@\x00", "ColorLine.ColorStop[2].Color.Alpha (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[2].Alpha (1.0)"),
|
||||||
# PaintGlyph glyph00013
|
# PaintGlyph glyph00013
|
||||||
(b"\x0a", "LayerList.Paint[2].Format (10)"),
|
(b"\x0a", "LayerList.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\x0d", "LayerList.Paint[2].Glyph (13)"),
|
(b"\x00\x0d", "LayerList.Paint[2].Glyph (13)"),
|
||||||
(b"\x0c", "LayerList.Paint[2].Paint.Format (12)"),
|
(b"\x0c", "LayerList.Paint[2].Paint.Format (12)"),
|
||||||
(b"\x00\x00\x07", "Offset to Paint subtable from beginning of PaintTransform (7)"),
|
(b"\x00\x00\x07", "Offset to Paint subtable from beginning of PaintTransform (7)"),
|
||||||
(b"\x00\x00\x4e", "Offset to Affine2x3 subtable from beginning of PaintTransform (78)"),
|
(b"\x00\x00\x32", "Offset to Affine2x3 subtable from beginning of PaintTransform (50)"),
|
||||||
(b"\x07", "LayerList.Paint[2].Paint.Paint.Format (7)"),
|
(b"\x07", "LayerList.Paint[2].Paint.Paint.Format (7)"),
|
||||||
(b"\x00\x00(", "Offset to ColorLine from beginning of PaintVarRadialGradient (40)"),
|
(b"\x00\x00\x14", "Offset to ColorLine from beginning of PaintVarRadialGradient (20)"),
|
||||||
(b"\x00\x07\xff\xff\xff\xff", "Paint.x0.value (7)"),
|
(b"\x00\x07", "Paint.x0.value (7)"),
|
||||||
(b"\x00\x08\xff\xff\xff\xff", "Paint.y0.value (8)"),
|
(b"\x00\x08", "Paint.y0.value (8)"),
|
||||||
(b"\x00\t\xff\xff\xff\xff", "Paint.r0.value (9)"),
|
(b"\x00\t", "Paint.r0.value (9)"),
|
||||||
(b"\x00\n\xff\xff\xff\xff", "Paint.x1.value (10)"),
|
(b"\x00\n", "Paint.x1.value (10)"),
|
||||||
(b"\x00\x0b\xff\xff\xff\xff", "Paint.y1.value (11)"),
|
(b"\x00\x0b", "Paint.y1.value (11)"),
|
||||||
(b"\x00\x0c\xff\xff\xff\xff", "Paint.r1.value (12)"),
|
(b"\x00\x0c", "Paint.r1.value (12)"),
|
||||||
|
(b"\xff\xff\xff\xff", "VarIndexBase (0xFFFFFFFF)"),
|
||||||
(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\xff\xff\xff\xff", "ColorLine.ColorStop[0].StopOffset.value (0.0)"),
|
(b"\x00\x00", "ColorLine.ColorStop[0].StopOffset.value (0.0)"),
|
||||||
(b"\x00\x06", "ColorLine.ColorStop[0].Color.PaletteIndex (6)"),
|
(b"\x00\x06", "ColorLine.ColorStop[0].PaletteIndex (6)"),
|
||||||
(b"@\x00\xff\xff\xff\xff", "ColorLine.ColorStop[0].Color.Alpha.value (1.0)"),
|
(b"@\x00", "ColorLine.ColorStop[0].Alpha.value (1.0)"),
|
||||||
(b"@\x00\xff\xff\xff\xff", "ColorLine.ColorStop[1].StopOffset.value (1.0)"),
|
(b"\xff\xff\xff\xff", "VarIndexBase (0xFFFFFFFF)"),
|
||||||
(b"\x00\x07", "ColorLine.ColorStop[1].Color.PaletteIndex (7)"),
|
(b"@\x00", "ColorLine.ColorStop[1].StopOffset.value (1.0)"),
|
||||||
(b"\x19\x9a\xff\xff\xff\xff", "ColorLine.ColorStop[1].Color.Alpha.value (0.4)"),
|
(b"\x00\x07", "ColorLine.ColorStop[1].PaletteIndex (7)"),
|
||||||
|
(b"\x19\x9a", "ColorLine.ColorStop[1].Alpha.value (0.4)"),
|
||||||
|
|
||||||
|
(b"\x00\x00\x00\x07", "VarIndexBase (7)"),
|
||||||
(b"\xff\xf3\x00\x00", "Affine2x3.xx (-13)"),
|
(b"\xff\xf3\x00\x00", "Affine2x3.xx (-13)"),
|
||||||
(b"\x00\x0e\x00\x00", "Affine2x3.xy (14)"),
|
(b"\x00\x0e\x00\x00", "Affine2x3.xy (14)"),
|
||||||
(b"\x00\x0f\x00\x00", "Affine2x3.yx (15)"),
|
(b"\x00\x0f\x00\x00", "Affine2x3.yx (15)"),
|
||||||
@ -288,8 +293,8 @@ COLR_V1_SAMPLE = (
|
|||||||
|
|
||||||
# PaintSolid
|
# PaintSolid
|
||||||
(b"\x02", "LayerList.Paint[0].Paint.Paint.Paint.Paint.Format (2)"),
|
(b"\x02", "LayerList.Paint[0].Paint.Paint.Paint.Paint.Format (2)"),
|
||||||
(b"\x00\x02", "Paint.Color.PaletteIndex (2)"),
|
(b"\x00\x02", "Paint.PaletteIndex (2)"),
|
||||||
(b" \x00", "Paint.Color.Alpha (0.5)"),
|
(b" \x00", "Paint.Alpha (0.5)"),
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
@ -346,6 +351,7 @@ COLR_V1_XML = [
|
|||||||
' <yy value="1.0"/>',
|
' <yy value="1.0"/>',
|
||||||
' <dx value="300.0"/>',
|
' <dx value="300.0"/>',
|
||||||
' <dy value="0.0"/>',
|
' <dy value="0.0"/>',
|
||||||
|
' <VarIndexBase value="0"/>',
|
||||||
" </Transform>",
|
" </Transform>",
|
||||||
" </BackdropPaint>",
|
" </BackdropPaint>",
|
||||||
" </Paint>",
|
" </Paint>",
|
||||||
@ -359,17 +365,13 @@ COLR_V1_XML = [
|
|||||||
" <!-- StopCount=2 -->",
|
" <!-- StopCount=2 -->",
|
||||||
' <ColorStop index="0">',
|
' <ColorStop index="0">',
|
||||||
' <StopOffset value="0.0"/>',
|
' <StopOffset value="0.0"/>',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="3"/>',
|
' <PaletteIndex value="3"/>',
|
||||||
' <Alpha value="1.0"/>',
|
' <Alpha value="1.0"/>',
|
||||||
" </Color>",
|
|
||||||
" </ColorStop>",
|
" </ColorStop>",
|
||||||
' <ColorStop index="1">',
|
' <ColorStop index="1">',
|
||||||
' <StopOffset value="1.0"/>',
|
' <StopOffset value="1.0"/>',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="5"/>',
|
' <PaletteIndex value="5"/>',
|
||||||
' <Alpha value="1.0"/>',
|
' <Alpha value="1.0"/>',
|
||||||
" </Color>",
|
|
||||||
" </ColorStop>",
|
" </ColorStop>",
|
||||||
" </ColorLine>",
|
" </ColorLine>",
|
||||||
' <centerX value="259"/>',
|
' <centerX value="259"/>',
|
||||||
@ -385,10 +387,9 @@ COLR_V1_XML = [
|
|||||||
" <!-- LayerCount=4 -->",
|
" <!-- LayerCount=4 -->",
|
||||||
' <Paint index="0" Format="10"><!-- PaintGlyph -->',
|
' <Paint index="0" Format="10"><!-- PaintGlyph -->',
|
||||||
' <Paint Format="3"><!-- PaintVarSolid -->',
|
' <Paint Format="3"><!-- PaintVarSolid -->',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="2"/>',
|
' <PaletteIndex value="2"/>',
|
||||||
' <Alpha value="0.5"/>',
|
' <Alpha value="0.5"/>',
|
||||||
" </Color>",
|
' <VarIndexBase value="6"/>',
|
||||||
" </Paint>",
|
" </Paint>",
|
||||||
' <Glyph value="glyph00011"/>',
|
' <Glyph value="glyph00011"/>',
|
||||||
" </Paint>",
|
" </Paint>",
|
||||||
@ -399,24 +400,18 @@ COLR_V1_XML = [
|
|||||||
" <!-- StopCount=3 -->",
|
" <!-- StopCount=3 -->",
|
||||||
' <ColorStop index="0">',
|
' <ColorStop index="0">',
|
||||||
' <StopOffset value="0.0"/>',
|
' <StopOffset value="0.0"/>',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="3"/>',
|
' <PaletteIndex value="3"/>',
|
||||||
' <Alpha value="1.0"/>',
|
' <Alpha value="1.0"/>',
|
||||||
" </Color>",
|
|
||||||
" </ColorStop>",
|
" </ColorStop>",
|
||||||
' <ColorStop index="1">',
|
' <ColorStop index="1">',
|
||||||
' <StopOffset value="0.5"/>',
|
' <StopOffset value="0.5"/>',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="4"/>',
|
' <PaletteIndex value="4"/>',
|
||||||
' <Alpha value="1.0"/>',
|
' <Alpha value="1.0"/>',
|
||||||
" </Color>",
|
|
||||||
" </ColorStop>",
|
" </ColorStop>",
|
||||||
' <ColorStop index="2">',
|
' <ColorStop index="2">',
|
||||||
' <StopOffset value="1.0"/>',
|
' <StopOffset value="1.0"/>',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="5"/>',
|
' <PaletteIndex value="5"/>',
|
||||||
' <Alpha value="1.0"/>',
|
' <Alpha value="1.0"/>',
|
||||||
" </Color>",
|
|
||||||
" </ColorStop>",
|
" </ColorStop>",
|
||||||
" </ColorLine>",
|
" </ColorLine>",
|
||||||
' <x0 value="1"/>',
|
' <x0 value="1"/>',
|
||||||
@ -436,17 +431,15 @@ COLR_V1_XML = [
|
|||||||
" <!-- StopCount=2 -->",
|
" <!-- StopCount=2 -->",
|
||||||
' <ColorStop index="0">',
|
' <ColorStop index="0">',
|
||||||
' <StopOffset value="0.0"/>',
|
' <StopOffset value="0.0"/>',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="6"/>',
|
' <PaletteIndex value="6"/>',
|
||||||
' <Alpha value="1.0"/>',
|
' <Alpha value="1.0"/>',
|
||||||
" </Color>",
|
" <VarIndexBase/>",
|
||||||
" </ColorStop>",
|
" </ColorStop>",
|
||||||
' <ColorStop index="1">',
|
' <ColorStop index="1">',
|
||||||
' <StopOffset value="1.0"/>',
|
' <StopOffset value="1.0"/>',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="7"/>',
|
' <PaletteIndex value="7"/>',
|
||||||
' <Alpha value="0.4"/>',
|
' <Alpha value="0.4"/>',
|
||||||
" </Color>",
|
' <VarIndexBase value="7"/>',
|
||||||
" </ColorStop>",
|
" </ColorStop>",
|
||||||
" </ColorLine>",
|
" </ColorLine>",
|
||||||
' <x0 value="7"/>',
|
' <x0 value="7"/>',
|
||||||
@ -455,6 +448,7 @@ COLR_V1_XML = [
|
|||||||
' <x1 value="10"/>',
|
' <x1 value="10"/>',
|
||||||
' <y1 value="11"/>',
|
' <y1 value="11"/>',
|
||||||
' <r1 value="12"/>',
|
' <r1 value="12"/>',
|
||||||
|
" <VarIndexBase/>",
|
||||||
" </Paint>",
|
" </Paint>",
|
||||||
" <Transform>",
|
" <Transform>",
|
||||||
' <xx value="-13.0"/>',
|
' <xx value="-13.0"/>',
|
||||||
@ -472,10 +466,8 @@ COLR_V1_XML = [
|
|||||||
' <Paint Format="28"><!-- PaintSkew -->',
|
' <Paint Format="28"><!-- PaintSkew -->',
|
||||||
' <Paint Format="10"><!-- PaintGlyph -->',
|
' <Paint Format="10"><!-- PaintGlyph -->',
|
||||||
' <Paint Format="2"><!-- PaintSolid -->',
|
' <Paint Format="2"><!-- PaintSolid -->',
|
||||||
" <Color>",
|
|
||||||
' <PaletteIndex value="2"/>',
|
' <PaletteIndex value="2"/>',
|
||||||
' <Alpha value="0.5"/>',
|
' <Alpha value="0.5"/>',
|
||||||
" </Color>",
|
|
||||||
" </Paint>",
|
" </Paint>",
|
||||||
' <Glyph value="glyph00011"/>',
|
' <Glyph value="glyph00011"/>',
|
||||||
" </Paint>",
|
" </Paint>",
|
||||||
@ -492,6 +484,52 @@ COLR_V1_XML = [
|
|||||||
"</LayerList>",
|
"</LayerList>",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
COLR_V1_VAR_XML = [
|
||||||
|
'<VarIndexMap Format="0">',
|
||||||
|
' <Map index="0" outer="1" inner="1"/>',
|
||||||
|
' <Map index="1" outer="1" inner="0"/>',
|
||||||
|
' <Map index="2" outer="1" inner="0"/>',
|
||||||
|
' <Map index="3" outer="1" inner="1"/>',
|
||||||
|
' <Map index="4" outer="1" inner="0"/>',
|
||||||
|
' <Map index="5" outer="1" inner="0"/>',
|
||||||
|
' <Map index="6" outer="0" inner="2"/>',
|
||||||
|
' <Map index="7" outer="0" inner="0"/>',
|
||||||
|
' <Map index="8" outer="0" inner="1"/>',
|
||||||
|
"</VarIndexMap>",
|
||||||
|
'<VarStore Format="1">',
|
||||||
|
' <Format value="1"/>',
|
||||||
|
" <VarRegionList>",
|
||||||
|
" <!-- RegionAxisCount=1 -->",
|
||||||
|
" <!-- RegionCount=1 -->",
|
||||||
|
' <Region index="0">',
|
||||||
|
' <VarRegionAxis index="0">',
|
||||||
|
' <StartCoord value="0.0"/>',
|
||||||
|
' <PeakCoord value="1.0"/>',
|
||||||
|
' <EndCoord value="1.0"/>',
|
||||||
|
" </VarRegionAxis>",
|
||||||
|
" </Region>",
|
||||||
|
" </VarRegionList>",
|
||||||
|
" <!-- VarDataCount=2 -->",
|
||||||
|
' <VarData index="0">',
|
||||||
|
" <!-- ItemCount=3 -->",
|
||||||
|
' <NumShorts value="1"/>',
|
||||||
|
" <!-- VarRegionCount=1 -->",
|
||||||
|
' <VarRegionIndex index="0" value="0"/>',
|
||||||
|
' <Item index="0" value="[-3277]"/>',
|
||||||
|
' <Item index="1" value="[6553]"/>',
|
||||||
|
' <Item index="2" value="[8192]"/>',
|
||||||
|
" </VarData>",
|
||||||
|
' <VarData index="1">',
|
||||||
|
" <!-- ItemCount=2 -->",
|
||||||
|
' <NumShorts value="32769"/>',
|
||||||
|
" <!-- VarRegionCount=1 -->",
|
||||||
|
' <VarRegionIndex index="0" value="0"/>',
|
||||||
|
' <Item index="0" value="[0]"/>',
|
||||||
|
' <Item index="1" value="[65536]"/>',
|
||||||
|
" </VarData>",
|
||||||
|
"</VarStore>",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class COLR_V1_Test(object):
|
class COLR_V1_Test(object):
|
||||||
def test_decompile_and_compile(self, font):
|
def test_decompile_and_compile(self, font):
|
||||||
@ -521,3 +559,16 @@ class COLR_V1_Test(object):
|
|||||||
colr = table_C_O_L_R_()
|
colr = table_C_O_L_R_()
|
||||||
colr.decompile(compiled, font)
|
colr.decompile(compiled, font)
|
||||||
assert getXML(colr.toXML, font) == COLR_V1_XML
|
assert getXML(colr.toXML, font) == COLR_V1_XML
|
||||||
|
|
||||||
|
|
||||||
|
class COLR_V1_Variable_Test(object):
|
||||||
|
def test_round_trip_xml(self, font):
|
||||||
|
colr = table_C_O_L_R_()
|
||||||
|
xml = COLR_V1_XML + COLR_V1_VAR_XML
|
||||||
|
for name, attrs, content in parseXML(xml):
|
||||||
|
colr.fromXML(name, attrs, content, font)
|
||||||
|
compiled = colr.compile(font)
|
||||||
|
|
||||||
|
colr = table_C_O_L_R_()
|
||||||
|
colr.decompile(compiled, font)
|
||||||
|
assert getXML(colr.toXML, font) == xml
|
||||||
|
Loading…
x
Reference in New Issue
Block a user