support proposed PaintSweepGradient's angles with +1.0 (180°) bias

In the upcoming draft of COLR spec, PaintSweepGradient's startAngle/endAngle are encoded with a +1.0 bias to allow for representation of a full +360° positive angle. Normal F2Dot14-fraction-of-half-circle angles can only represent angles between -360 <= angle < +360

This is a breaking change and will need to be coordinated with rendering implementations (at least FreeType/Skia).
This commit is contained in:
Cosimo Lupo 2022-06-28 17:36:40 +01:00
parent 87e86cb5fb
commit 1dffbae240
4 changed files with 21 additions and 14 deletions

View File

@ -452,13 +452,14 @@ class F2Dot14(BaseFixedValue):
class Angle(F2Dot14):
# angles are specified in degrees, and encoded as F2Dot14 fractions of half
# circle: e.g. 1.0 => 180, -0.5 => -90, -2.0 => -360, etc.
bias = 0.0
factor = 1.0/(1<<14) * 180 # 0.010986328125
@classmethod
def fromInt(cls, value):
return super().fromInt(value) * 180
return (super().fromInt(value) + cls.bias) * 180
@classmethod
def toInt(cls, value):
return super().toInt(value / 180)
return super().toInt((value / 180) - cls.bias)
@classmethod
def fromString(cls, value):
# quantize to nearest multiples of minimum fixed-precision angle
@ -467,6 +468,11 @@ class Angle(F2Dot14):
def toString(cls, value):
return nearestMultipleShortestRepr(value, cls.factor)
class BiasedAngle(Angle):
# A bias of 1.0 is used in the representation of start and end angles
# of COLRv1 PaintSweepGradients to allow for encoding +360deg
bias = 1.0
class Version(SimpleValue):
staticSize = 4
def read(self, reader, font, tableDict):
@ -1773,6 +1779,7 @@ converterMapping = {
"Fixed": Fixed,
"F2Dot14": F2Dot14,
"Angle": Angle,
"BiasedAngle": BiasedAngle,
"struct": Struct,
"Offset": Table,
"LOffset": LTable,

View File

@ -1755,8 +1755,8 @@ otData = [
('Offset24', 'ColorLine', None, None, 'Offset (from beginning of PaintSweepGradient table) to ColorLine subtable.'),
('int16', 'centerX', None, None, 'Center x coordinate.'),
('int16', 'centerY', None, None, 'Center y coordinate.'),
('Angle', 'startAngle', None, None, 'Start of the angular range of the gradient.'),
('Angle', 'endAngle', None, None, 'End of the angular range of the gradient.'),
('BiasedAngle', 'startAngle', None, None, 'Start of the angular range of the gradient.'),
('BiasedAngle', 'endAngle', None, None, 'End of the angular range of the gradient.'),
]),
# PaintVarSweepGradient
('PaintFormat9', [
@ -1764,8 +1764,8 @@ otData = [
('LOffset24To(VarColorLine)', 'ColorLine', None, None, 'Offset (from beginning of PaintVarSweepGradient table) to VarColorLine subtable.'),
('int16', 'centerX', None, None, 'Center x coordinate. VarIndexBase + 0.'),
('int16', 'centerY', None, None, 'Center y coordinate. VarIndexBase + 1.'),
('Angle', 'startAngle', None, None, 'Start of the angular range of the gradient. VarIndexBase + 2.'),
('Angle', 'endAngle', None, None, 'End of the angular range of the gradient. VarIndexBase + 3.'),
('BiasedAngle', 'startAngle', None, None, 'Start of the angular range of the gradient. VarIndexBase + 2.'),
('BiasedAngle', 'endAngle', None, None, 'End of the angular range of the gradient. VarIndexBase + 3.'),
('VarIndex', 'VarIndexBase', None, None, 'Base index into DeltaSetIndexMap.'),
]),

View File

@ -400,8 +400,8 @@ COLR_V1_XML = [
" </ColorLine>",
' <centerX value="259"/>',
' <centerY value="300"/>',
' <startAngle value="45.0"/>',
' <endAngle value="135.0"/>',
' <startAngle value="225.0"/>',
' <endAngle value="315.0"/>',
" </Paint>",
' <Glyph value="glyph00011"/>',
" </Paint>",

View File

@ -619,8 +619,8 @@ class COLRVariationMergerTest:
},
"centerX": 0,
"centerY": 0,
"startAngle": -360,
"endAngle": 0,
"startAngle": 0,
"endAngle": 360,
},
"Transform": (1.0, 0, 0, 1.0, 0, 0),
},
@ -641,8 +641,8 @@ class COLRVariationMergerTest:
},
"centerX": 256,
"centerY": 0,
"startAngle": -360,
"endAngle": 0,
"startAngle": 0,
"endAngle": 360,
},
# Transform.xx below produces the same VarStore delta as the
# above PaintSweepGradient's centerX because, when Fixed16.16
@ -675,8 +675,8 @@ class COLRVariationMergerTest:
" </ColorLine>",
' <centerX value="0"/>',
' <centerY value="0"/>',
' <startAngle value="-360.0"/>',
' <endAngle value="0.0"/>',
' <startAngle value="0.0"/>',
' <endAngle value="360.0"/>',
' <VarIndexBase value="0"/>',
" </Paint>",
" <Transform>",