1*e1fe3e4aSElliott Hughesfrom copy import deepcopy 2*e1fe3e4aSElliott Hughesimport string 3*e1fe3e4aSElliott Hughesfrom fontTools.colorLib.builder import LayerListBuilder, buildCOLR, buildClipList 4*e1fe3e4aSElliott Hughesfrom fontTools.misc.testTools import getXML 5*e1fe3e4aSElliott Hughesfrom fontTools.varLib.merger import COLRVariationMerger 6*e1fe3e4aSElliott Hughesfrom fontTools.varLib.models import VariationModel 7*e1fe3e4aSElliott Hughesfrom fontTools.ttLib import TTFont 8*e1fe3e4aSElliott Hughesfrom fontTools.ttLib.tables import otTables as ot 9*e1fe3e4aSElliott Hughesfrom fontTools.ttLib.tables.otBase import OTTableReader, OTTableWriter 10*e1fe3e4aSElliott Hughesfrom io import BytesIO 11*e1fe3e4aSElliott Hughesimport pytest 12*e1fe3e4aSElliott Hughes 13*e1fe3e4aSElliott Hughes 14*e1fe3e4aSElliott HughesNO_VARIATION_INDEX = ot.NO_VARIATION_INDEX 15*e1fe3e4aSElliott Hughes 16*e1fe3e4aSElliott Hughes 17*e1fe3e4aSElliott Hughesdef dump_xml(table, ttFont=None): 18*e1fe3e4aSElliott Hughes xml = getXML(table.toXML, ttFont) 19*e1fe3e4aSElliott Hughes print("[") 20*e1fe3e4aSElliott Hughes for line in xml: 21*e1fe3e4aSElliott Hughes print(f" {line!r},") 22*e1fe3e4aSElliott Hughes print("]") 23*e1fe3e4aSElliott Hughes return xml 24*e1fe3e4aSElliott Hughes 25*e1fe3e4aSElliott Hughes 26*e1fe3e4aSElliott Hughesdef compile_decompile(table, ttFont): 27*e1fe3e4aSElliott Hughes writer = OTTableWriter(tableTag="COLR") 28*e1fe3e4aSElliott Hughes # compile itself may modify a table, safer to copy it first 29*e1fe3e4aSElliott Hughes table = deepcopy(table) 30*e1fe3e4aSElliott Hughes table.compile(writer, ttFont) 31*e1fe3e4aSElliott Hughes data = writer.getAllData() 32*e1fe3e4aSElliott Hughes 33*e1fe3e4aSElliott Hughes reader = OTTableReader(data, tableTag="COLR") 34*e1fe3e4aSElliott Hughes table2 = table.__class__() 35*e1fe3e4aSElliott Hughes table2.decompile(reader, ttFont) 36*e1fe3e4aSElliott Hughes 37*e1fe3e4aSElliott Hughes return table2 38*e1fe3e4aSElliott Hughes 39*e1fe3e4aSElliott Hughes 40*e1fe3e4aSElliott Hughes@pytest.fixture 41*e1fe3e4aSElliott Hughesdef ttFont(): 42*e1fe3e4aSElliott Hughes font = TTFont() 43*e1fe3e4aSElliott Hughes font.setGlyphOrder([".notdef"] + list(string.ascii_letters)) 44*e1fe3e4aSElliott Hughes return font 45*e1fe3e4aSElliott Hughes 46*e1fe3e4aSElliott Hughes 47*e1fe3e4aSElliott Hughesdef build_paint(data): 48*e1fe3e4aSElliott Hughes return LayerListBuilder().buildPaint(data) 49*e1fe3e4aSElliott Hughes 50*e1fe3e4aSElliott Hughes 51*e1fe3e4aSElliott Hughesclass COLRVariationMergerTest: 52*e1fe3e4aSElliott Hughes @pytest.mark.parametrize( 53*e1fe3e4aSElliott Hughes "paints, expected_xml, expected_varIdxes", 54*e1fe3e4aSElliott Hughes [ 55*e1fe3e4aSElliott Hughes pytest.param( 56*e1fe3e4aSElliott Hughes [ 57*e1fe3e4aSElliott Hughes { 58*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 59*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 60*e1fe3e4aSElliott Hughes "Alpha": 1.0, 61*e1fe3e4aSElliott Hughes }, 62*e1fe3e4aSElliott Hughes { 63*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 64*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 65*e1fe3e4aSElliott Hughes "Alpha": 1.0, 66*e1fe3e4aSElliott Hughes }, 67*e1fe3e4aSElliott Hughes ], 68*e1fe3e4aSElliott Hughes [ 69*e1fe3e4aSElliott Hughes '<Paint Format="2"><!-- PaintSolid -->', 70*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 71*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 72*e1fe3e4aSElliott Hughes "</Paint>", 73*e1fe3e4aSElliott Hughes ], 74*e1fe3e4aSElliott Hughes [], 75*e1fe3e4aSElliott Hughes id="solid-same", 76*e1fe3e4aSElliott Hughes ), 77*e1fe3e4aSElliott Hughes pytest.param( 78*e1fe3e4aSElliott Hughes [ 79*e1fe3e4aSElliott Hughes { 80*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 81*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 82*e1fe3e4aSElliott Hughes "Alpha": 1.0, 83*e1fe3e4aSElliott Hughes }, 84*e1fe3e4aSElliott Hughes { 85*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 86*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 87*e1fe3e4aSElliott Hughes "Alpha": 0.5, 88*e1fe3e4aSElliott Hughes }, 89*e1fe3e4aSElliott Hughes ], 90*e1fe3e4aSElliott Hughes [ 91*e1fe3e4aSElliott Hughes '<Paint Format="3"><!-- PaintVarSolid -->', 92*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 93*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 94*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 95*e1fe3e4aSElliott Hughes "</Paint>", 96*e1fe3e4aSElliott Hughes ], 97*e1fe3e4aSElliott Hughes [0], 98*e1fe3e4aSElliott Hughes id="solid-alpha", 99*e1fe3e4aSElliott Hughes ), 100*e1fe3e4aSElliott Hughes pytest.param( 101*e1fe3e4aSElliott Hughes [ 102*e1fe3e4aSElliott Hughes { 103*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintLinearGradient), 104*e1fe3e4aSElliott Hughes "ColorLine": { 105*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 106*e1fe3e4aSElliott Hughes "ColorStop": [ 107*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 1.0}, 108*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 1.0}, 109*e1fe3e4aSElliott Hughes ], 110*e1fe3e4aSElliott Hughes }, 111*e1fe3e4aSElliott Hughes "x0": 0, 112*e1fe3e4aSElliott Hughes "y0": 0, 113*e1fe3e4aSElliott Hughes "x1": 1, 114*e1fe3e4aSElliott Hughes "y1": 1, 115*e1fe3e4aSElliott Hughes "x2": 2, 116*e1fe3e4aSElliott Hughes "y2": 2, 117*e1fe3e4aSElliott Hughes }, 118*e1fe3e4aSElliott Hughes { 119*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintLinearGradient), 120*e1fe3e4aSElliott Hughes "ColorLine": { 121*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 122*e1fe3e4aSElliott Hughes "ColorStop": [ 123*e1fe3e4aSElliott Hughes {"StopOffset": 0.1, "PaletteIndex": 0, "Alpha": 1.0}, 124*e1fe3e4aSElliott Hughes {"StopOffset": 0.9, "PaletteIndex": 1, "Alpha": 1.0}, 125*e1fe3e4aSElliott Hughes ], 126*e1fe3e4aSElliott Hughes }, 127*e1fe3e4aSElliott Hughes "x0": 0, 128*e1fe3e4aSElliott Hughes "y0": 0, 129*e1fe3e4aSElliott Hughes "x1": 1, 130*e1fe3e4aSElliott Hughes "y1": 1, 131*e1fe3e4aSElliott Hughes "x2": 2, 132*e1fe3e4aSElliott Hughes "y2": 2, 133*e1fe3e4aSElliott Hughes }, 134*e1fe3e4aSElliott Hughes ], 135*e1fe3e4aSElliott Hughes [ 136*e1fe3e4aSElliott Hughes '<Paint Format="5"><!-- PaintVarLinearGradient -->', 137*e1fe3e4aSElliott Hughes " <ColorLine>", 138*e1fe3e4aSElliott Hughes ' <Extend value="pad"/>', 139*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 140*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 141*e1fe3e4aSElliott Hughes ' <StopOffset value="0.0"/>', 142*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 143*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 144*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 145*e1fe3e4aSElliott Hughes " </ColorStop>", 146*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 147*e1fe3e4aSElliott Hughes ' <StopOffset value="1.0"/>', 148*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 149*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 150*e1fe3e4aSElliott Hughes ' <VarIndexBase value="2"/>', 151*e1fe3e4aSElliott Hughes " </ColorStop>", 152*e1fe3e4aSElliott Hughes " </ColorLine>", 153*e1fe3e4aSElliott Hughes ' <x0 value="0"/>', 154*e1fe3e4aSElliott Hughes ' <y0 value="0"/>', 155*e1fe3e4aSElliott Hughes ' <x1 value="1"/>', 156*e1fe3e4aSElliott Hughes ' <y1 value="1"/>', 157*e1fe3e4aSElliott Hughes ' <x2 value="2"/>', 158*e1fe3e4aSElliott Hughes ' <y2 value="2"/>', 159*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 160*e1fe3e4aSElliott Hughes "</Paint>", 161*e1fe3e4aSElliott Hughes ], 162*e1fe3e4aSElliott Hughes [0, NO_VARIATION_INDEX, 1, NO_VARIATION_INDEX], 163*e1fe3e4aSElliott Hughes id="linear_grad-stop-offsets", 164*e1fe3e4aSElliott Hughes ), 165*e1fe3e4aSElliott Hughes pytest.param( 166*e1fe3e4aSElliott Hughes [ 167*e1fe3e4aSElliott Hughes { 168*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintLinearGradient), 169*e1fe3e4aSElliott Hughes "ColorLine": { 170*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 171*e1fe3e4aSElliott Hughes "ColorStop": [ 172*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 1.0}, 173*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 1.0}, 174*e1fe3e4aSElliott Hughes ], 175*e1fe3e4aSElliott Hughes }, 176*e1fe3e4aSElliott Hughes "x0": 0, 177*e1fe3e4aSElliott Hughes "y0": 0, 178*e1fe3e4aSElliott Hughes "x1": 1, 179*e1fe3e4aSElliott Hughes "y1": 1, 180*e1fe3e4aSElliott Hughes "x2": 2, 181*e1fe3e4aSElliott Hughes "y2": 2, 182*e1fe3e4aSElliott Hughes }, 183*e1fe3e4aSElliott Hughes { 184*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintLinearGradient), 185*e1fe3e4aSElliott Hughes "ColorLine": { 186*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 187*e1fe3e4aSElliott Hughes "ColorStop": [ 188*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 0.5}, 189*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 1.0}, 190*e1fe3e4aSElliott Hughes ], 191*e1fe3e4aSElliott Hughes }, 192*e1fe3e4aSElliott Hughes "x0": 0, 193*e1fe3e4aSElliott Hughes "y0": 0, 194*e1fe3e4aSElliott Hughes "x1": 1, 195*e1fe3e4aSElliott Hughes "y1": 1, 196*e1fe3e4aSElliott Hughes "x2": 2, 197*e1fe3e4aSElliott Hughes "y2": 2, 198*e1fe3e4aSElliott Hughes }, 199*e1fe3e4aSElliott Hughes ], 200*e1fe3e4aSElliott Hughes [ 201*e1fe3e4aSElliott Hughes '<Paint Format="5"><!-- PaintVarLinearGradient -->', 202*e1fe3e4aSElliott Hughes " <ColorLine>", 203*e1fe3e4aSElliott Hughes ' <Extend value="pad"/>', 204*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 205*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 206*e1fe3e4aSElliott Hughes ' <StopOffset value="0.0"/>', 207*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 208*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 209*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 210*e1fe3e4aSElliott Hughes " </ColorStop>", 211*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 212*e1fe3e4aSElliott Hughes ' <StopOffset value="1.0"/>', 213*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 214*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 215*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 216*e1fe3e4aSElliott Hughes " </ColorStop>", 217*e1fe3e4aSElliott Hughes " </ColorLine>", 218*e1fe3e4aSElliott Hughes ' <x0 value="0"/>', 219*e1fe3e4aSElliott Hughes ' <y0 value="0"/>', 220*e1fe3e4aSElliott Hughes ' <x1 value="1"/>', 221*e1fe3e4aSElliott Hughes ' <y1 value="1"/>', 222*e1fe3e4aSElliott Hughes ' <x2 value="2"/>', 223*e1fe3e4aSElliott Hughes ' <y2 value="2"/>', 224*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 225*e1fe3e4aSElliott Hughes "</Paint>", 226*e1fe3e4aSElliott Hughes ], 227*e1fe3e4aSElliott Hughes [NO_VARIATION_INDEX, 0], 228*e1fe3e4aSElliott Hughes id="linear_grad-stop[0].alpha", 229*e1fe3e4aSElliott Hughes ), 230*e1fe3e4aSElliott Hughes pytest.param( 231*e1fe3e4aSElliott Hughes [ 232*e1fe3e4aSElliott Hughes { 233*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintLinearGradient), 234*e1fe3e4aSElliott Hughes "ColorLine": { 235*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 236*e1fe3e4aSElliott Hughes "ColorStop": [ 237*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 1.0}, 238*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 1.0}, 239*e1fe3e4aSElliott Hughes ], 240*e1fe3e4aSElliott Hughes }, 241*e1fe3e4aSElliott Hughes "x0": 0, 242*e1fe3e4aSElliott Hughes "y0": 0, 243*e1fe3e4aSElliott Hughes "x1": 1, 244*e1fe3e4aSElliott Hughes "y1": 1, 245*e1fe3e4aSElliott Hughes "x2": 2, 246*e1fe3e4aSElliott Hughes "y2": 2, 247*e1fe3e4aSElliott Hughes }, 248*e1fe3e4aSElliott Hughes { 249*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintLinearGradient), 250*e1fe3e4aSElliott Hughes "ColorLine": { 251*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 252*e1fe3e4aSElliott Hughes "ColorStop": [ 253*e1fe3e4aSElliott Hughes {"StopOffset": -0.5, "PaletteIndex": 0, "Alpha": 1.0}, 254*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 1.0}, 255*e1fe3e4aSElliott Hughes ], 256*e1fe3e4aSElliott Hughes }, 257*e1fe3e4aSElliott Hughes "x0": 0, 258*e1fe3e4aSElliott Hughes "y0": 0, 259*e1fe3e4aSElliott Hughes "x1": 1, 260*e1fe3e4aSElliott Hughes "y1": 1, 261*e1fe3e4aSElliott Hughes "x2": 2, 262*e1fe3e4aSElliott Hughes "y2": -200, 263*e1fe3e4aSElliott Hughes }, 264*e1fe3e4aSElliott Hughes ], 265*e1fe3e4aSElliott Hughes [ 266*e1fe3e4aSElliott Hughes '<Paint Format="5"><!-- PaintVarLinearGradient -->', 267*e1fe3e4aSElliott Hughes " <ColorLine>", 268*e1fe3e4aSElliott Hughes ' <Extend value="pad"/>', 269*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 270*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 271*e1fe3e4aSElliott Hughes ' <StopOffset value="0.0"/>', 272*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 273*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 274*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 275*e1fe3e4aSElliott Hughes " </ColorStop>", 276*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 277*e1fe3e4aSElliott Hughes ' <StopOffset value="1.0"/>', 278*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 279*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 280*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 281*e1fe3e4aSElliott Hughes " </ColorStop>", 282*e1fe3e4aSElliott Hughes " </ColorLine>", 283*e1fe3e4aSElliott Hughes ' <x0 value="0"/>', 284*e1fe3e4aSElliott Hughes ' <y0 value="0"/>', 285*e1fe3e4aSElliott Hughes ' <x1 value="1"/>', 286*e1fe3e4aSElliott Hughes ' <y1 value="1"/>', 287*e1fe3e4aSElliott Hughes ' <x2 value="2"/>', 288*e1fe3e4aSElliott Hughes ' <y2 value="2"/>', 289*e1fe3e4aSElliott Hughes ' <VarIndexBase value="1"/>', 290*e1fe3e4aSElliott Hughes "</Paint>", 291*e1fe3e4aSElliott Hughes ], 292*e1fe3e4aSElliott Hughes [ 293*e1fe3e4aSElliott Hughes 0, 294*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 295*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 296*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 297*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 298*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 299*e1fe3e4aSElliott Hughes 1, 300*e1fe3e4aSElliott Hughes ], 301*e1fe3e4aSElliott Hughes id="linear_grad-stop[0].offset-y2", 302*e1fe3e4aSElliott Hughes ), 303*e1fe3e4aSElliott Hughes pytest.param( 304*e1fe3e4aSElliott Hughes [ 305*e1fe3e4aSElliott Hughes { 306*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintRadialGradient), 307*e1fe3e4aSElliott Hughes "ColorLine": { 308*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 309*e1fe3e4aSElliott Hughes "ColorStop": [ 310*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 1.0}, 311*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 1.0}, 312*e1fe3e4aSElliott Hughes ], 313*e1fe3e4aSElliott Hughes }, 314*e1fe3e4aSElliott Hughes "x0": 0, 315*e1fe3e4aSElliott Hughes "y0": 0, 316*e1fe3e4aSElliott Hughes "r0": 0, 317*e1fe3e4aSElliott Hughes "x1": 1, 318*e1fe3e4aSElliott Hughes "y1": 1, 319*e1fe3e4aSElliott Hughes "r1": 1, 320*e1fe3e4aSElliott Hughes }, 321*e1fe3e4aSElliott Hughes { 322*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintRadialGradient), 323*e1fe3e4aSElliott Hughes "ColorLine": { 324*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 325*e1fe3e4aSElliott Hughes "ColorStop": [ 326*e1fe3e4aSElliott Hughes {"StopOffset": 0.1, "PaletteIndex": 0, "Alpha": 0.6}, 327*e1fe3e4aSElliott Hughes {"StopOffset": 0.9, "PaletteIndex": 1, "Alpha": 0.7}, 328*e1fe3e4aSElliott Hughes ], 329*e1fe3e4aSElliott Hughes }, 330*e1fe3e4aSElliott Hughes "x0": -1, 331*e1fe3e4aSElliott Hughes "y0": -2, 332*e1fe3e4aSElliott Hughes "r0": 3, 333*e1fe3e4aSElliott Hughes "x1": -4, 334*e1fe3e4aSElliott Hughes "y1": -5, 335*e1fe3e4aSElliott Hughes "r1": 6, 336*e1fe3e4aSElliott Hughes }, 337*e1fe3e4aSElliott Hughes ], 338*e1fe3e4aSElliott Hughes [ 339*e1fe3e4aSElliott Hughes '<Paint Format="7"><!-- PaintVarRadialGradient -->', 340*e1fe3e4aSElliott Hughes " <ColorLine>", 341*e1fe3e4aSElliott Hughes ' <Extend value="pad"/>', 342*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 343*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 344*e1fe3e4aSElliott Hughes ' <StopOffset value="0.0"/>', 345*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 346*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 347*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 348*e1fe3e4aSElliott Hughes " </ColorStop>", 349*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 350*e1fe3e4aSElliott Hughes ' <StopOffset value="1.0"/>', 351*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 352*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 353*e1fe3e4aSElliott Hughes ' <VarIndexBase value="2"/>', 354*e1fe3e4aSElliott Hughes " </ColorStop>", 355*e1fe3e4aSElliott Hughes " </ColorLine>", 356*e1fe3e4aSElliott Hughes ' <x0 value="0"/>', 357*e1fe3e4aSElliott Hughes ' <y0 value="0"/>', 358*e1fe3e4aSElliott Hughes ' <r0 value="0"/>', 359*e1fe3e4aSElliott Hughes ' <x1 value="1"/>', 360*e1fe3e4aSElliott Hughes ' <y1 value="1"/>', 361*e1fe3e4aSElliott Hughes ' <r1 value="1"/>', 362*e1fe3e4aSElliott Hughes ' <VarIndexBase value="4"/>', 363*e1fe3e4aSElliott Hughes "</Paint>", 364*e1fe3e4aSElliott Hughes ], 365*e1fe3e4aSElliott Hughes [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 366*e1fe3e4aSElliott Hughes id="radial_grad-all-different", 367*e1fe3e4aSElliott Hughes ), 368*e1fe3e4aSElliott Hughes pytest.param( 369*e1fe3e4aSElliott Hughes [ 370*e1fe3e4aSElliott Hughes { 371*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSweepGradient), 372*e1fe3e4aSElliott Hughes "ColorLine": { 373*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.REPEAT), 374*e1fe3e4aSElliott Hughes "ColorStop": [ 375*e1fe3e4aSElliott Hughes {"StopOffset": 0.4, "PaletteIndex": 0, "Alpha": 1.0}, 376*e1fe3e4aSElliott Hughes {"StopOffset": 0.6, "PaletteIndex": 1, "Alpha": 1.0}, 377*e1fe3e4aSElliott Hughes ], 378*e1fe3e4aSElliott Hughes }, 379*e1fe3e4aSElliott Hughes "centerX": 0, 380*e1fe3e4aSElliott Hughes "centerY": 0, 381*e1fe3e4aSElliott Hughes "startAngle": 0, 382*e1fe3e4aSElliott Hughes "endAngle": 180.0, 383*e1fe3e4aSElliott Hughes }, 384*e1fe3e4aSElliott Hughes { 385*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSweepGradient), 386*e1fe3e4aSElliott Hughes "ColorLine": { 387*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.REPEAT), 388*e1fe3e4aSElliott Hughes "ColorStop": [ 389*e1fe3e4aSElliott Hughes {"StopOffset": 0.4, "PaletteIndex": 0, "Alpha": 1.0}, 390*e1fe3e4aSElliott Hughes {"StopOffset": 0.6, "PaletteIndex": 1, "Alpha": 1.0}, 391*e1fe3e4aSElliott Hughes ], 392*e1fe3e4aSElliott Hughes }, 393*e1fe3e4aSElliott Hughes "centerX": 0, 394*e1fe3e4aSElliott Hughes "centerY": 0, 395*e1fe3e4aSElliott Hughes "startAngle": 90.0, 396*e1fe3e4aSElliott Hughes "endAngle": 180.0, 397*e1fe3e4aSElliott Hughes }, 398*e1fe3e4aSElliott Hughes ], 399*e1fe3e4aSElliott Hughes [ 400*e1fe3e4aSElliott Hughes '<Paint Format="9"><!-- PaintVarSweepGradient -->', 401*e1fe3e4aSElliott Hughes " <ColorLine>", 402*e1fe3e4aSElliott Hughes ' <Extend value="repeat"/>', 403*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 404*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 405*e1fe3e4aSElliott Hughes ' <StopOffset value="0.4"/>', 406*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 407*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 408*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 409*e1fe3e4aSElliott Hughes " </ColorStop>", 410*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 411*e1fe3e4aSElliott Hughes ' <StopOffset value="0.6"/>', 412*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 413*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 414*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 415*e1fe3e4aSElliott Hughes " </ColorStop>", 416*e1fe3e4aSElliott Hughes " </ColorLine>", 417*e1fe3e4aSElliott Hughes ' <centerX value="0"/>', 418*e1fe3e4aSElliott Hughes ' <centerY value="0"/>', 419*e1fe3e4aSElliott Hughes ' <startAngle value="0.0"/>', 420*e1fe3e4aSElliott Hughes ' <endAngle value="180.0"/>', 421*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 422*e1fe3e4aSElliott Hughes "</Paint>", 423*e1fe3e4aSElliott Hughes ], 424*e1fe3e4aSElliott Hughes [NO_VARIATION_INDEX, NO_VARIATION_INDEX, 0, NO_VARIATION_INDEX], 425*e1fe3e4aSElliott Hughes id="sweep_grad-startAngle", 426*e1fe3e4aSElliott Hughes ), 427*e1fe3e4aSElliott Hughes pytest.param( 428*e1fe3e4aSElliott Hughes [ 429*e1fe3e4aSElliott Hughes { 430*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSweepGradient), 431*e1fe3e4aSElliott Hughes "ColorLine": { 432*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 433*e1fe3e4aSElliott Hughes "ColorStop": [ 434*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 1.0}, 435*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 1.0}, 436*e1fe3e4aSElliott Hughes ], 437*e1fe3e4aSElliott Hughes }, 438*e1fe3e4aSElliott Hughes "centerX": 0, 439*e1fe3e4aSElliott Hughes "centerY": 0, 440*e1fe3e4aSElliott Hughes "startAngle": 0.0, 441*e1fe3e4aSElliott Hughes "endAngle": 180.0, 442*e1fe3e4aSElliott Hughes }, 443*e1fe3e4aSElliott Hughes { 444*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSweepGradient), 445*e1fe3e4aSElliott Hughes "ColorLine": { 446*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 447*e1fe3e4aSElliott Hughes "ColorStop": [ 448*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0, "Alpha": 0.5}, 449*e1fe3e4aSElliott Hughes {"StopOffset": 1.0, "PaletteIndex": 1, "Alpha": 0.5}, 450*e1fe3e4aSElliott Hughes ], 451*e1fe3e4aSElliott Hughes }, 452*e1fe3e4aSElliott Hughes "centerX": 0, 453*e1fe3e4aSElliott Hughes "centerY": 0, 454*e1fe3e4aSElliott Hughes "startAngle": 0.0, 455*e1fe3e4aSElliott Hughes "endAngle": 180.0, 456*e1fe3e4aSElliott Hughes }, 457*e1fe3e4aSElliott Hughes ], 458*e1fe3e4aSElliott Hughes [ 459*e1fe3e4aSElliott Hughes '<Paint Format="9"><!-- PaintVarSweepGradient -->', 460*e1fe3e4aSElliott Hughes " <ColorLine>", 461*e1fe3e4aSElliott Hughes ' <Extend value="pad"/>', 462*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 463*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 464*e1fe3e4aSElliott Hughes ' <StopOffset value="0.0"/>', 465*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 466*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 467*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 468*e1fe3e4aSElliott Hughes " </ColorStop>", 469*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 470*e1fe3e4aSElliott Hughes ' <StopOffset value="1.0"/>', 471*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 472*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 473*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 474*e1fe3e4aSElliott Hughes " </ColorStop>", 475*e1fe3e4aSElliott Hughes " </ColorLine>", 476*e1fe3e4aSElliott Hughes ' <centerX value="0"/>', 477*e1fe3e4aSElliott Hughes ' <centerY value="0"/>', 478*e1fe3e4aSElliott Hughes ' <startAngle value="0.0"/>', 479*e1fe3e4aSElliott Hughes ' <endAngle value="180.0"/>', 480*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 481*e1fe3e4aSElliott Hughes "</Paint>", 482*e1fe3e4aSElliott Hughes ], 483*e1fe3e4aSElliott Hughes [NO_VARIATION_INDEX, 0], 484*e1fe3e4aSElliott Hughes id="sweep_grad-stops-alpha-reuse-varidxbase", 485*e1fe3e4aSElliott Hughes ), 486*e1fe3e4aSElliott Hughes pytest.param( 487*e1fe3e4aSElliott Hughes [ 488*e1fe3e4aSElliott Hughes { 489*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintTransform), 490*e1fe3e4aSElliott Hughes "Paint": { 491*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintRadialGradient), 492*e1fe3e4aSElliott Hughes "ColorLine": { 493*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 494*e1fe3e4aSElliott Hughes "ColorStop": [ 495*e1fe3e4aSElliott Hughes { 496*e1fe3e4aSElliott Hughes "StopOffset": 0.0, 497*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 498*e1fe3e4aSElliott Hughes "Alpha": 1.0, 499*e1fe3e4aSElliott Hughes }, 500*e1fe3e4aSElliott Hughes { 501*e1fe3e4aSElliott Hughes "StopOffset": 1.0, 502*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 503*e1fe3e4aSElliott Hughes "Alpha": 1.0, 504*e1fe3e4aSElliott Hughes }, 505*e1fe3e4aSElliott Hughes ], 506*e1fe3e4aSElliott Hughes }, 507*e1fe3e4aSElliott Hughes "x0": 0, 508*e1fe3e4aSElliott Hughes "y0": 0, 509*e1fe3e4aSElliott Hughes "r0": 0, 510*e1fe3e4aSElliott Hughes "x1": 1, 511*e1fe3e4aSElliott Hughes "y1": 1, 512*e1fe3e4aSElliott Hughes "r1": 1, 513*e1fe3e4aSElliott Hughes }, 514*e1fe3e4aSElliott Hughes "Transform": { 515*e1fe3e4aSElliott Hughes "xx": 1.0, 516*e1fe3e4aSElliott Hughes "xy": 0.0, 517*e1fe3e4aSElliott Hughes "yx": 0.0, 518*e1fe3e4aSElliott Hughes "yy": 1.0, 519*e1fe3e4aSElliott Hughes "dx": 0.0, 520*e1fe3e4aSElliott Hughes "dy": 0.0, 521*e1fe3e4aSElliott Hughes }, 522*e1fe3e4aSElliott Hughes }, 523*e1fe3e4aSElliott Hughes { 524*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintTransform), 525*e1fe3e4aSElliott Hughes "Paint": { 526*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintRadialGradient), 527*e1fe3e4aSElliott Hughes "ColorLine": { 528*e1fe3e4aSElliott Hughes "Extend": int(ot.ExtendMode.PAD), 529*e1fe3e4aSElliott Hughes "ColorStop": [ 530*e1fe3e4aSElliott Hughes { 531*e1fe3e4aSElliott Hughes "StopOffset": 0.0, 532*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 533*e1fe3e4aSElliott Hughes "Alpha": 1.0, 534*e1fe3e4aSElliott Hughes }, 535*e1fe3e4aSElliott Hughes { 536*e1fe3e4aSElliott Hughes "StopOffset": 1.0, 537*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 538*e1fe3e4aSElliott Hughes "Alpha": 1.0, 539*e1fe3e4aSElliott Hughes }, 540*e1fe3e4aSElliott Hughes ], 541*e1fe3e4aSElliott Hughes }, 542*e1fe3e4aSElliott Hughes "x0": 0, 543*e1fe3e4aSElliott Hughes "y0": 0, 544*e1fe3e4aSElliott Hughes "r0": 0, 545*e1fe3e4aSElliott Hughes "x1": 1, 546*e1fe3e4aSElliott Hughes "y1": 1, 547*e1fe3e4aSElliott Hughes "r1": 1, 548*e1fe3e4aSElliott Hughes }, 549*e1fe3e4aSElliott Hughes "Transform": { 550*e1fe3e4aSElliott Hughes "xx": 1.0, 551*e1fe3e4aSElliott Hughes "xy": 0.0, 552*e1fe3e4aSElliott Hughes "yx": 0.0, 553*e1fe3e4aSElliott Hughes "yy": 0.5, 554*e1fe3e4aSElliott Hughes "dx": 0.0, 555*e1fe3e4aSElliott Hughes "dy": -100.0, 556*e1fe3e4aSElliott Hughes }, 557*e1fe3e4aSElliott Hughes }, 558*e1fe3e4aSElliott Hughes ], 559*e1fe3e4aSElliott Hughes [ 560*e1fe3e4aSElliott Hughes '<Paint Format="13"><!-- PaintVarTransform -->', 561*e1fe3e4aSElliott Hughes ' <Paint Format="6"><!-- PaintRadialGradient -->', 562*e1fe3e4aSElliott Hughes " <ColorLine>", 563*e1fe3e4aSElliott Hughes ' <Extend value="pad"/>', 564*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 565*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 566*e1fe3e4aSElliott Hughes ' <StopOffset value="0.0"/>', 567*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 568*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 569*e1fe3e4aSElliott Hughes " </ColorStop>", 570*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 571*e1fe3e4aSElliott Hughes ' <StopOffset value="1.0"/>', 572*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 573*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 574*e1fe3e4aSElliott Hughes " </ColorStop>", 575*e1fe3e4aSElliott Hughes " </ColorLine>", 576*e1fe3e4aSElliott Hughes ' <x0 value="0"/>', 577*e1fe3e4aSElliott Hughes ' <y0 value="0"/>', 578*e1fe3e4aSElliott Hughes ' <r0 value="0"/>', 579*e1fe3e4aSElliott Hughes ' <x1 value="1"/>', 580*e1fe3e4aSElliott Hughes ' <y1 value="1"/>', 581*e1fe3e4aSElliott Hughes ' <r1 value="1"/>', 582*e1fe3e4aSElliott Hughes " </Paint>", 583*e1fe3e4aSElliott Hughes " <Transform>", 584*e1fe3e4aSElliott Hughes ' <xx value="1.0"/>', 585*e1fe3e4aSElliott Hughes ' <yx value="0.0"/>', 586*e1fe3e4aSElliott Hughes ' <xy value="0.0"/>', 587*e1fe3e4aSElliott Hughes ' <yy value="1.0"/>', 588*e1fe3e4aSElliott Hughes ' <dx value="0.0"/>', 589*e1fe3e4aSElliott Hughes ' <dy value="0.0"/>', 590*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 591*e1fe3e4aSElliott Hughes " </Transform>", 592*e1fe3e4aSElliott Hughes "</Paint>", 593*e1fe3e4aSElliott Hughes ], 594*e1fe3e4aSElliott Hughes [ 595*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 596*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 597*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 598*e1fe3e4aSElliott Hughes 0, 599*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 600*e1fe3e4aSElliott Hughes 1, 601*e1fe3e4aSElliott Hughes ], 602*e1fe3e4aSElliott Hughes id="transform-yy-dy", 603*e1fe3e4aSElliott Hughes ), 604*e1fe3e4aSElliott Hughes pytest.param( 605*e1fe3e4aSElliott Hughes [ 606*e1fe3e4aSElliott Hughes { 607*e1fe3e4aSElliott Hughes "Format": ot.PaintFormat.PaintTransform, 608*e1fe3e4aSElliott Hughes "Paint": { 609*e1fe3e4aSElliott Hughes "Format": ot.PaintFormat.PaintSweepGradient, 610*e1fe3e4aSElliott Hughes "ColorLine": { 611*e1fe3e4aSElliott Hughes "Extend": ot.ExtendMode.PAD, 612*e1fe3e4aSElliott Hughes "ColorStop": [ 613*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0}, 614*e1fe3e4aSElliott Hughes { 615*e1fe3e4aSElliott Hughes "StopOffset": 1.0, 616*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 617*e1fe3e4aSElliott Hughes "Alpha": 1.0, 618*e1fe3e4aSElliott Hughes }, 619*e1fe3e4aSElliott Hughes ], 620*e1fe3e4aSElliott Hughes }, 621*e1fe3e4aSElliott Hughes "centerX": 0, 622*e1fe3e4aSElliott Hughes "centerY": 0, 623*e1fe3e4aSElliott Hughes "startAngle": 0, 624*e1fe3e4aSElliott Hughes "endAngle": 360, 625*e1fe3e4aSElliott Hughes }, 626*e1fe3e4aSElliott Hughes "Transform": (1.0, 0, 0, 1.0, 0, 0), 627*e1fe3e4aSElliott Hughes }, 628*e1fe3e4aSElliott Hughes { 629*e1fe3e4aSElliott Hughes "Format": ot.PaintFormat.PaintTransform, 630*e1fe3e4aSElliott Hughes "Paint": { 631*e1fe3e4aSElliott Hughes "Format": ot.PaintFormat.PaintSweepGradient, 632*e1fe3e4aSElliott Hughes "ColorLine": { 633*e1fe3e4aSElliott Hughes "Extend": ot.ExtendMode.PAD, 634*e1fe3e4aSElliott Hughes "ColorStop": [ 635*e1fe3e4aSElliott Hughes {"StopOffset": 0.0, "PaletteIndex": 0}, 636*e1fe3e4aSElliott Hughes { 637*e1fe3e4aSElliott Hughes "StopOffset": 1.0, 638*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 639*e1fe3e4aSElliott Hughes "Alpha": 1.0, 640*e1fe3e4aSElliott Hughes }, 641*e1fe3e4aSElliott Hughes ], 642*e1fe3e4aSElliott Hughes }, 643*e1fe3e4aSElliott Hughes "centerX": 256, 644*e1fe3e4aSElliott Hughes "centerY": 0, 645*e1fe3e4aSElliott Hughes "startAngle": 0, 646*e1fe3e4aSElliott Hughes "endAngle": 360, 647*e1fe3e4aSElliott Hughes }, 648*e1fe3e4aSElliott Hughes # Transform.xx below produces the same VarStore delta as the 649*e1fe3e4aSElliott Hughes # above PaintSweepGradient's centerX because, when Fixed16.16 650*e1fe3e4aSElliott Hughes # is converted to integer, it becomes: 651*e1fe3e4aSElliott Hughes # floatToFixed(1.00390625, 16) == 256 652*e1fe3e4aSElliott Hughes # Because there is overlap between the varIdxes of the 653*e1fe3e4aSElliott Hughes # PaintVarTransform's Affine2x3 and the PaintSweepGradient's 654*e1fe3e4aSElliott Hughes # the VarIndexBase is reused (0 for both) 655*e1fe3e4aSElliott Hughes "Transform": (1.00390625, 0, 0, 1.0, 10, 0), 656*e1fe3e4aSElliott Hughes }, 657*e1fe3e4aSElliott Hughes ], 658*e1fe3e4aSElliott Hughes [ 659*e1fe3e4aSElliott Hughes '<Paint Format="13"><!-- PaintVarTransform -->', 660*e1fe3e4aSElliott Hughes ' <Paint Format="9"><!-- PaintVarSweepGradient -->', 661*e1fe3e4aSElliott Hughes " <ColorLine>", 662*e1fe3e4aSElliott Hughes ' <Extend value="pad"/>', 663*e1fe3e4aSElliott Hughes " <!-- StopCount=2 -->", 664*e1fe3e4aSElliott Hughes ' <ColorStop index="0">', 665*e1fe3e4aSElliott Hughes ' <StopOffset value="0.0"/>', 666*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 667*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 668*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 669*e1fe3e4aSElliott Hughes " </ColorStop>", 670*e1fe3e4aSElliott Hughes ' <ColorStop index="1">', 671*e1fe3e4aSElliott Hughes ' <StopOffset value="1.0"/>', 672*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 673*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 674*e1fe3e4aSElliott Hughes " <VarIndexBase/>", 675*e1fe3e4aSElliott Hughes " </ColorStop>", 676*e1fe3e4aSElliott Hughes " </ColorLine>", 677*e1fe3e4aSElliott Hughes ' <centerX value="0"/>', 678*e1fe3e4aSElliott Hughes ' <centerY value="0"/>', 679*e1fe3e4aSElliott Hughes ' <startAngle value="0.0"/>', 680*e1fe3e4aSElliott Hughes ' <endAngle value="360.0"/>', 681*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 682*e1fe3e4aSElliott Hughes " </Paint>", 683*e1fe3e4aSElliott Hughes " <Transform>", 684*e1fe3e4aSElliott Hughes ' <xx value="1.0"/>', 685*e1fe3e4aSElliott Hughes ' <yx value="0.0"/>', 686*e1fe3e4aSElliott Hughes ' <xy value="0.0"/>', 687*e1fe3e4aSElliott Hughes ' <yy value="1.0"/>', 688*e1fe3e4aSElliott Hughes ' <dx value="0.0"/>', 689*e1fe3e4aSElliott Hughes ' <dy value="0.0"/>', 690*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 691*e1fe3e4aSElliott Hughes " </Transform>", 692*e1fe3e4aSElliott Hughes "</Paint>", 693*e1fe3e4aSElliott Hughes ], 694*e1fe3e4aSElliott Hughes [ 695*e1fe3e4aSElliott Hughes 0, 696*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 697*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 698*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 699*e1fe3e4aSElliott Hughes 1, 700*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 701*e1fe3e4aSElliott Hughes ], 702*e1fe3e4aSElliott Hughes id="transform-xx-sweep_grad-centerx-same-varidxbase", 703*e1fe3e4aSElliott Hughes ), 704*e1fe3e4aSElliott Hughes ], 705*e1fe3e4aSElliott Hughes ) 706*e1fe3e4aSElliott Hughes def test_merge_Paint(self, paints, ttFont, expected_xml, expected_varIdxes): 707*e1fe3e4aSElliott Hughes paints = [build_paint(p) for p in paints] 708*e1fe3e4aSElliott Hughes out = deepcopy(paints[0]) 709*e1fe3e4aSElliott Hughes 710*e1fe3e4aSElliott Hughes model = VariationModel([{}, {"ZZZZ": 1.0}]) 711*e1fe3e4aSElliott Hughes merger = COLRVariationMerger(model, ["ZZZZ"], ttFont) 712*e1fe3e4aSElliott Hughes 713*e1fe3e4aSElliott Hughes merger.mergeThings(out, paints) 714*e1fe3e4aSElliott Hughes 715*e1fe3e4aSElliott Hughes assert compile_decompile(out, ttFont) == out 716*e1fe3e4aSElliott Hughes assert dump_xml(out, ttFont) == expected_xml 717*e1fe3e4aSElliott Hughes assert merger.varIdxes == expected_varIdxes 718*e1fe3e4aSElliott Hughes 719*e1fe3e4aSElliott Hughes def test_merge_ClipList(self, ttFont): 720*e1fe3e4aSElliott Hughes clipLists = [ 721*e1fe3e4aSElliott Hughes buildClipList(clips) 722*e1fe3e4aSElliott Hughes for clips in [ 723*e1fe3e4aSElliott Hughes { 724*e1fe3e4aSElliott Hughes "A": (0, 0, 1000, 1000), 725*e1fe3e4aSElliott Hughes "B": (0, 0, 1000, 1000), 726*e1fe3e4aSElliott Hughes "C": (0, 0, 1000, 1000), 727*e1fe3e4aSElliott Hughes "D": (0, 0, 1000, 1000), 728*e1fe3e4aSElliott Hughes }, 729*e1fe3e4aSElliott Hughes { 730*e1fe3e4aSElliott Hughes # non-default masters' clip boxes can be 'sparse' 731*e1fe3e4aSElliott Hughes # (i.e. can omit explicit clip box for some glyphs) 732*e1fe3e4aSElliott Hughes # "A": (0, 0, 1000, 1000), 733*e1fe3e4aSElliott Hughes "B": (10, 0, 1000, 1000), 734*e1fe3e4aSElliott Hughes "C": (20, 20, 1020, 1020), 735*e1fe3e4aSElliott Hughes "D": (20, 20, 1020, 1020), 736*e1fe3e4aSElliott Hughes }, 737*e1fe3e4aSElliott Hughes ] 738*e1fe3e4aSElliott Hughes ] 739*e1fe3e4aSElliott Hughes out = deepcopy(clipLists[0]) 740*e1fe3e4aSElliott Hughes 741*e1fe3e4aSElliott Hughes model = VariationModel([{}, {"ZZZZ": 1.0}]) 742*e1fe3e4aSElliott Hughes merger = COLRVariationMerger(model, ["ZZZZ"], ttFont) 743*e1fe3e4aSElliott Hughes 744*e1fe3e4aSElliott Hughes merger.mergeThings(out, clipLists) 745*e1fe3e4aSElliott Hughes 746*e1fe3e4aSElliott Hughes assert compile_decompile(out, ttFont) == out 747*e1fe3e4aSElliott Hughes assert dump_xml(out, ttFont) == [ 748*e1fe3e4aSElliott Hughes '<ClipList Format="1">', 749*e1fe3e4aSElliott Hughes " <Clip>", 750*e1fe3e4aSElliott Hughes ' <Glyph value="A"/>', 751*e1fe3e4aSElliott Hughes ' <ClipBox Format="1">', 752*e1fe3e4aSElliott Hughes ' <xMin value="0"/>', 753*e1fe3e4aSElliott Hughes ' <yMin value="0"/>', 754*e1fe3e4aSElliott Hughes ' <xMax value="1000"/>', 755*e1fe3e4aSElliott Hughes ' <yMax value="1000"/>', 756*e1fe3e4aSElliott Hughes " </ClipBox>", 757*e1fe3e4aSElliott Hughes " </Clip>", 758*e1fe3e4aSElliott Hughes " <Clip>", 759*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 760*e1fe3e4aSElliott Hughes ' <ClipBox Format="2">', 761*e1fe3e4aSElliott Hughes ' <xMin value="0"/>', 762*e1fe3e4aSElliott Hughes ' <yMin value="0"/>', 763*e1fe3e4aSElliott Hughes ' <xMax value="1000"/>', 764*e1fe3e4aSElliott Hughes ' <yMax value="1000"/>', 765*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 766*e1fe3e4aSElliott Hughes " </ClipBox>", 767*e1fe3e4aSElliott Hughes " </Clip>", 768*e1fe3e4aSElliott Hughes " <Clip>", 769*e1fe3e4aSElliott Hughes ' <Glyph value="C"/>', 770*e1fe3e4aSElliott Hughes ' <Glyph value="D"/>', 771*e1fe3e4aSElliott Hughes ' <ClipBox Format="2">', 772*e1fe3e4aSElliott Hughes ' <xMin value="0"/>', 773*e1fe3e4aSElliott Hughes ' <yMin value="0"/>', 774*e1fe3e4aSElliott Hughes ' <xMax value="1000"/>', 775*e1fe3e4aSElliott Hughes ' <yMax value="1000"/>', 776*e1fe3e4aSElliott Hughes ' <VarIndexBase value="4"/>', 777*e1fe3e4aSElliott Hughes " </ClipBox>", 778*e1fe3e4aSElliott Hughes " </Clip>", 779*e1fe3e4aSElliott Hughes "</ClipList>", 780*e1fe3e4aSElliott Hughes ] 781*e1fe3e4aSElliott Hughes assert merger.varIdxes == [ 782*e1fe3e4aSElliott Hughes 0, 783*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 784*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 785*e1fe3e4aSElliott Hughes NO_VARIATION_INDEX, 786*e1fe3e4aSElliott Hughes 1, 787*e1fe3e4aSElliott Hughes 1, 788*e1fe3e4aSElliott Hughes 1, 789*e1fe3e4aSElliott Hughes 1, 790*e1fe3e4aSElliott Hughes ] 791*e1fe3e4aSElliott Hughes 792*e1fe3e4aSElliott Hughes @pytest.mark.parametrize( 793*e1fe3e4aSElliott Hughes "master_layer_reuse", 794*e1fe3e4aSElliott Hughes [ 795*e1fe3e4aSElliott Hughes pytest.param(False, id="no-reuse"), 796*e1fe3e4aSElliott Hughes pytest.param(True, id="with-reuse"), 797*e1fe3e4aSElliott Hughes ], 798*e1fe3e4aSElliott Hughes ) 799*e1fe3e4aSElliott Hughes @pytest.mark.parametrize( 800*e1fe3e4aSElliott Hughes "color_glyphs, output_layer_reuse, expected_xml, expected_varIdxes", 801*e1fe3e4aSElliott Hughes [ 802*e1fe3e4aSElliott Hughes pytest.param( 803*e1fe3e4aSElliott Hughes [ 804*e1fe3e4aSElliott Hughes { 805*e1fe3e4aSElliott Hughes "A": { 806*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 807*e1fe3e4aSElliott Hughes "Layers": [ 808*e1fe3e4aSElliott Hughes { 809*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 810*e1fe3e4aSElliott Hughes "Paint": { 811*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 812*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 813*e1fe3e4aSElliott Hughes "Alpha": 1.0, 814*e1fe3e4aSElliott Hughes }, 815*e1fe3e4aSElliott Hughes "Glyph": "B", 816*e1fe3e4aSElliott Hughes }, 817*e1fe3e4aSElliott Hughes { 818*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 819*e1fe3e4aSElliott Hughes "Paint": { 820*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 821*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 822*e1fe3e4aSElliott Hughes "Alpha": 1.0, 823*e1fe3e4aSElliott Hughes }, 824*e1fe3e4aSElliott Hughes "Glyph": "B", 825*e1fe3e4aSElliott Hughes }, 826*e1fe3e4aSElliott Hughes ], 827*e1fe3e4aSElliott Hughes }, 828*e1fe3e4aSElliott Hughes }, 829*e1fe3e4aSElliott Hughes { 830*e1fe3e4aSElliott Hughes "A": { 831*e1fe3e4aSElliott Hughes "Format": ot.PaintFormat.PaintColrLayers, 832*e1fe3e4aSElliott Hughes "Layers": [ 833*e1fe3e4aSElliott Hughes { 834*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 835*e1fe3e4aSElliott Hughes "Paint": { 836*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 837*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 838*e1fe3e4aSElliott Hughes "Alpha": 1.0, 839*e1fe3e4aSElliott Hughes }, 840*e1fe3e4aSElliott Hughes "Glyph": "B", 841*e1fe3e4aSElliott Hughes }, 842*e1fe3e4aSElliott Hughes { 843*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 844*e1fe3e4aSElliott Hughes "Paint": { 845*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 846*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 847*e1fe3e4aSElliott Hughes "Alpha": 1.0, 848*e1fe3e4aSElliott Hughes }, 849*e1fe3e4aSElliott Hughes "Glyph": "B", 850*e1fe3e4aSElliott Hughes }, 851*e1fe3e4aSElliott Hughes ], 852*e1fe3e4aSElliott Hughes }, 853*e1fe3e4aSElliott Hughes }, 854*e1fe3e4aSElliott Hughes ], 855*e1fe3e4aSElliott Hughes False, 856*e1fe3e4aSElliott Hughes [ 857*e1fe3e4aSElliott Hughes "<COLR>", 858*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 859*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 860*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 861*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 862*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=1 -->", 863*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 864*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 865*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 866*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 867*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="0"/>', 868*e1fe3e4aSElliott Hughes " </Paint>", 869*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 870*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 871*e1fe3e4aSElliott Hughes " <LayerList>", 872*e1fe3e4aSElliott Hughes " <!-- LayerCount=2 -->", 873*e1fe3e4aSElliott Hughes ' <Paint index="0" Format="10"><!-- PaintGlyph -->', 874*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 875*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 876*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 877*e1fe3e4aSElliott Hughes " </Paint>", 878*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 879*e1fe3e4aSElliott Hughes " </Paint>", 880*e1fe3e4aSElliott Hughes ' <Paint index="1" Format="10"><!-- PaintGlyph -->', 881*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 882*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 883*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 884*e1fe3e4aSElliott Hughes " </Paint>", 885*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 886*e1fe3e4aSElliott Hughes " </Paint>", 887*e1fe3e4aSElliott Hughes " </LayerList>", 888*e1fe3e4aSElliott Hughes "</COLR>", 889*e1fe3e4aSElliott Hughes ], 890*e1fe3e4aSElliott Hughes [], 891*e1fe3e4aSElliott Hughes id="no-variation", 892*e1fe3e4aSElliott Hughes ), 893*e1fe3e4aSElliott Hughes pytest.param( 894*e1fe3e4aSElliott Hughes [ 895*e1fe3e4aSElliott Hughes { 896*e1fe3e4aSElliott Hughes "A": { 897*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 898*e1fe3e4aSElliott Hughes "Layers": [ 899*e1fe3e4aSElliott Hughes { 900*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 901*e1fe3e4aSElliott Hughes "Paint": { 902*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 903*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 904*e1fe3e4aSElliott Hughes "Alpha": 1.0, 905*e1fe3e4aSElliott Hughes }, 906*e1fe3e4aSElliott Hughes "Glyph": "B", 907*e1fe3e4aSElliott Hughes }, 908*e1fe3e4aSElliott Hughes { 909*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 910*e1fe3e4aSElliott Hughes "Paint": { 911*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 912*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 913*e1fe3e4aSElliott Hughes "Alpha": 1.0, 914*e1fe3e4aSElliott Hughes }, 915*e1fe3e4aSElliott Hughes "Glyph": "B", 916*e1fe3e4aSElliott Hughes }, 917*e1fe3e4aSElliott Hughes ], 918*e1fe3e4aSElliott Hughes }, 919*e1fe3e4aSElliott Hughes "C": { 920*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 921*e1fe3e4aSElliott Hughes "Layers": [ 922*e1fe3e4aSElliott Hughes { 923*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 924*e1fe3e4aSElliott Hughes "Paint": { 925*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 926*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 927*e1fe3e4aSElliott Hughes "Alpha": 1.0, 928*e1fe3e4aSElliott Hughes }, 929*e1fe3e4aSElliott Hughes "Glyph": "B", 930*e1fe3e4aSElliott Hughes }, 931*e1fe3e4aSElliott Hughes { 932*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 933*e1fe3e4aSElliott Hughes "Paint": { 934*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 935*e1fe3e4aSElliott Hughes "PaletteIndex": 3, 936*e1fe3e4aSElliott Hughes "Alpha": 1.0, 937*e1fe3e4aSElliott Hughes }, 938*e1fe3e4aSElliott Hughes "Glyph": "B", 939*e1fe3e4aSElliott Hughes }, 940*e1fe3e4aSElliott Hughes ], 941*e1fe3e4aSElliott Hughes }, 942*e1fe3e4aSElliott Hughes }, 943*e1fe3e4aSElliott Hughes { 944*e1fe3e4aSElliott Hughes # NOTE: 'A' is missing from non-default master 945*e1fe3e4aSElliott Hughes "C": { 946*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 947*e1fe3e4aSElliott Hughes "Layers": [ 948*e1fe3e4aSElliott Hughes { 949*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 950*e1fe3e4aSElliott Hughes "Paint": { 951*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 952*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 953*e1fe3e4aSElliott Hughes "Alpha": 0.5, 954*e1fe3e4aSElliott Hughes }, 955*e1fe3e4aSElliott Hughes "Glyph": "B", 956*e1fe3e4aSElliott Hughes }, 957*e1fe3e4aSElliott Hughes { 958*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 959*e1fe3e4aSElliott Hughes "Paint": { 960*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 961*e1fe3e4aSElliott Hughes "PaletteIndex": 3, 962*e1fe3e4aSElliott Hughes "Alpha": 0.5, 963*e1fe3e4aSElliott Hughes }, 964*e1fe3e4aSElliott Hughes "Glyph": "B", 965*e1fe3e4aSElliott Hughes }, 966*e1fe3e4aSElliott Hughes ], 967*e1fe3e4aSElliott Hughes }, 968*e1fe3e4aSElliott Hughes }, 969*e1fe3e4aSElliott Hughes ], 970*e1fe3e4aSElliott Hughes False, 971*e1fe3e4aSElliott Hughes [ 972*e1fe3e4aSElliott Hughes "<COLR>", 973*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 974*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 975*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 976*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 977*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=2 -->", 978*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 979*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 980*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 981*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 982*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="0"/>', 983*e1fe3e4aSElliott Hughes " </Paint>", 984*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 985*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="1">', 986*e1fe3e4aSElliott Hughes ' <BaseGlyph value="C"/>', 987*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 988*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 989*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="2"/>', 990*e1fe3e4aSElliott Hughes " </Paint>", 991*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 992*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 993*e1fe3e4aSElliott Hughes " <LayerList>", 994*e1fe3e4aSElliott Hughes " <!-- LayerCount=4 -->", 995*e1fe3e4aSElliott Hughes ' <Paint index="0" Format="10"><!-- PaintGlyph -->', 996*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 997*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 998*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 999*e1fe3e4aSElliott Hughes " </Paint>", 1000*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1001*e1fe3e4aSElliott Hughes " </Paint>", 1002*e1fe3e4aSElliott Hughes ' <Paint index="1" Format="10"><!-- PaintGlyph -->', 1003*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1004*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1005*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1006*e1fe3e4aSElliott Hughes " </Paint>", 1007*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1008*e1fe3e4aSElliott Hughes " </Paint>", 1009*e1fe3e4aSElliott Hughes ' <Paint index="2" Format="10"><!-- PaintGlyph -->', 1010*e1fe3e4aSElliott Hughes ' <Paint Format="3"><!-- PaintVarSolid -->', 1011*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1012*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1013*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 1014*e1fe3e4aSElliott Hughes " </Paint>", 1015*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1016*e1fe3e4aSElliott Hughes " </Paint>", 1017*e1fe3e4aSElliott Hughes ' <Paint index="3" Format="10"><!-- PaintGlyph -->', 1018*e1fe3e4aSElliott Hughes ' <Paint Format="3"><!-- PaintVarSolid -->', 1019*e1fe3e4aSElliott Hughes ' <PaletteIndex value="3"/>', 1020*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1021*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 1022*e1fe3e4aSElliott Hughes " </Paint>", 1023*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1024*e1fe3e4aSElliott Hughes " </Paint>", 1025*e1fe3e4aSElliott Hughes " </LayerList>", 1026*e1fe3e4aSElliott Hughes "</COLR>", 1027*e1fe3e4aSElliott Hughes ], 1028*e1fe3e4aSElliott Hughes [0], 1029*e1fe3e4aSElliott Hughes id="sparse-masters", 1030*e1fe3e4aSElliott Hughes ), 1031*e1fe3e4aSElliott Hughes pytest.param( 1032*e1fe3e4aSElliott Hughes [ 1033*e1fe3e4aSElliott Hughes { 1034*e1fe3e4aSElliott Hughes "A": { 1035*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1036*e1fe3e4aSElliott Hughes "Layers": [ 1037*e1fe3e4aSElliott Hughes { 1038*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1039*e1fe3e4aSElliott Hughes "Paint": { 1040*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1041*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 1042*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1043*e1fe3e4aSElliott Hughes }, 1044*e1fe3e4aSElliott Hughes "Glyph": "B", 1045*e1fe3e4aSElliott Hughes }, 1046*e1fe3e4aSElliott Hughes { 1047*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1048*e1fe3e4aSElliott Hughes "Paint": { 1049*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1050*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1051*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1052*e1fe3e4aSElliott Hughes }, 1053*e1fe3e4aSElliott Hughes "Glyph": "B", 1054*e1fe3e4aSElliott Hughes }, 1055*e1fe3e4aSElliott Hughes { 1056*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1057*e1fe3e4aSElliott Hughes "Paint": { 1058*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1059*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1060*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1061*e1fe3e4aSElliott Hughes }, 1062*e1fe3e4aSElliott Hughes "Glyph": "B", 1063*e1fe3e4aSElliott Hughes }, 1064*e1fe3e4aSElliott Hughes ], 1065*e1fe3e4aSElliott Hughes }, 1066*e1fe3e4aSElliott Hughes "C": { 1067*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1068*e1fe3e4aSElliott Hughes "Layers": [ 1069*e1fe3e4aSElliott Hughes # 'C' reuses layers 1-3 from 'A' 1070*e1fe3e4aSElliott Hughes { 1071*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1072*e1fe3e4aSElliott Hughes "Paint": { 1073*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1074*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1075*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1076*e1fe3e4aSElliott Hughes }, 1077*e1fe3e4aSElliott Hughes "Glyph": "B", 1078*e1fe3e4aSElliott Hughes }, 1079*e1fe3e4aSElliott Hughes { 1080*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1081*e1fe3e4aSElliott Hughes "Paint": { 1082*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1083*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1084*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1085*e1fe3e4aSElliott Hughes }, 1086*e1fe3e4aSElliott Hughes "Glyph": "B", 1087*e1fe3e4aSElliott Hughes }, 1088*e1fe3e4aSElliott Hughes ], 1089*e1fe3e4aSElliott Hughes }, 1090*e1fe3e4aSElliott Hughes "D": { # identical to 'C' 1091*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1092*e1fe3e4aSElliott Hughes "Layers": [ 1093*e1fe3e4aSElliott Hughes { 1094*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1095*e1fe3e4aSElliott Hughes "Paint": { 1096*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1097*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1098*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1099*e1fe3e4aSElliott Hughes }, 1100*e1fe3e4aSElliott Hughes "Glyph": "B", 1101*e1fe3e4aSElliott Hughes }, 1102*e1fe3e4aSElliott Hughes { 1103*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1104*e1fe3e4aSElliott Hughes "Paint": { 1105*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1106*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1107*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1108*e1fe3e4aSElliott Hughes }, 1109*e1fe3e4aSElliott Hughes "Glyph": "B", 1110*e1fe3e4aSElliott Hughes }, 1111*e1fe3e4aSElliott Hughes ], 1112*e1fe3e4aSElliott Hughes }, 1113*e1fe3e4aSElliott Hughes "E": { # superset of 'C' or 'D' 1114*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1115*e1fe3e4aSElliott Hughes "Layers": [ 1116*e1fe3e4aSElliott Hughes { 1117*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1118*e1fe3e4aSElliott Hughes "Paint": { 1119*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1120*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1121*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1122*e1fe3e4aSElliott Hughes }, 1123*e1fe3e4aSElliott Hughes "Glyph": "B", 1124*e1fe3e4aSElliott Hughes }, 1125*e1fe3e4aSElliott Hughes { 1126*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1127*e1fe3e4aSElliott Hughes "Paint": { 1128*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1129*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1130*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1131*e1fe3e4aSElliott Hughes }, 1132*e1fe3e4aSElliott Hughes "Glyph": "B", 1133*e1fe3e4aSElliott Hughes }, 1134*e1fe3e4aSElliott Hughes { 1135*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1136*e1fe3e4aSElliott Hughes "Paint": { 1137*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1138*e1fe3e4aSElliott Hughes "PaletteIndex": 3, 1139*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1140*e1fe3e4aSElliott Hughes }, 1141*e1fe3e4aSElliott Hughes "Glyph": "B", 1142*e1fe3e4aSElliott Hughes }, 1143*e1fe3e4aSElliott Hughes ], 1144*e1fe3e4aSElliott Hughes }, 1145*e1fe3e4aSElliott Hughes }, 1146*e1fe3e4aSElliott Hughes { 1147*e1fe3e4aSElliott Hughes # NOTE: 'A' is missing from non-default master 1148*e1fe3e4aSElliott Hughes "C": { 1149*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1150*e1fe3e4aSElliott Hughes "Layers": [ 1151*e1fe3e4aSElliott Hughes { 1152*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1153*e1fe3e4aSElliott Hughes "Paint": { 1154*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1155*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1156*e1fe3e4aSElliott Hughes "Alpha": 0.5, 1157*e1fe3e4aSElliott Hughes }, 1158*e1fe3e4aSElliott Hughes "Glyph": "B", 1159*e1fe3e4aSElliott Hughes }, 1160*e1fe3e4aSElliott Hughes { 1161*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1162*e1fe3e4aSElliott Hughes "Paint": { 1163*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1164*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1165*e1fe3e4aSElliott Hughes "Alpha": 0.5, 1166*e1fe3e4aSElliott Hughes }, 1167*e1fe3e4aSElliott Hughes "Glyph": "B", 1168*e1fe3e4aSElliott Hughes }, 1169*e1fe3e4aSElliott Hughes ], 1170*e1fe3e4aSElliott Hughes }, 1171*e1fe3e4aSElliott Hughes "D": { # same as 'C' 1172*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1173*e1fe3e4aSElliott Hughes "Layers": [ 1174*e1fe3e4aSElliott Hughes { 1175*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1176*e1fe3e4aSElliott Hughes "Paint": { 1177*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1178*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1179*e1fe3e4aSElliott Hughes "Alpha": 0.5, 1180*e1fe3e4aSElliott Hughes }, 1181*e1fe3e4aSElliott Hughes "Glyph": "B", 1182*e1fe3e4aSElliott Hughes }, 1183*e1fe3e4aSElliott Hughes { 1184*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1185*e1fe3e4aSElliott Hughes "Paint": { 1186*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1187*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1188*e1fe3e4aSElliott Hughes "Alpha": 0.5, 1189*e1fe3e4aSElliott Hughes }, 1190*e1fe3e4aSElliott Hughes "Glyph": "B", 1191*e1fe3e4aSElliott Hughes }, 1192*e1fe3e4aSElliott Hughes ], 1193*e1fe3e4aSElliott Hughes }, 1194*e1fe3e4aSElliott Hughes "E": { # first two layers vary the same way as 'C' or 'D' 1195*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1196*e1fe3e4aSElliott Hughes "Layers": [ 1197*e1fe3e4aSElliott Hughes { 1198*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1199*e1fe3e4aSElliott Hughes "Paint": { 1200*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1201*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1202*e1fe3e4aSElliott Hughes "Alpha": 0.5, 1203*e1fe3e4aSElliott Hughes }, 1204*e1fe3e4aSElliott Hughes "Glyph": "B", 1205*e1fe3e4aSElliott Hughes }, 1206*e1fe3e4aSElliott Hughes { 1207*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1208*e1fe3e4aSElliott Hughes "Paint": { 1209*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1210*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1211*e1fe3e4aSElliott Hughes "Alpha": 0.5, 1212*e1fe3e4aSElliott Hughes }, 1213*e1fe3e4aSElliott Hughes "Glyph": "B", 1214*e1fe3e4aSElliott Hughes }, 1215*e1fe3e4aSElliott Hughes { 1216*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1217*e1fe3e4aSElliott Hughes "Paint": { 1218*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1219*e1fe3e4aSElliott Hughes "PaletteIndex": 3, 1220*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1221*e1fe3e4aSElliott Hughes }, 1222*e1fe3e4aSElliott Hughes "Glyph": "B", 1223*e1fe3e4aSElliott Hughes }, 1224*e1fe3e4aSElliott Hughes ], 1225*e1fe3e4aSElliott Hughes }, 1226*e1fe3e4aSElliott Hughes }, 1227*e1fe3e4aSElliott Hughes ], 1228*e1fe3e4aSElliott Hughes True, # reuse 1229*e1fe3e4aSElliott Hughes [ 1230*e1fe3e4aSElliott Hughes "<COLR>", 1231*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 1232*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 1233*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 1234*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 1235*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=4 -->", 1236*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 1237*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 1238*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1239*e1fe3e4aSElliott Hughes ' <NumLayers value="3"/>', 1240*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="0"/>', 1241*e1fe3e4aSElliott Hughes " </Paint>", 1242*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1243*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="1">', 1244*e1fe3e4aSElliott Hughes ' <BaseGlyph value="C"/>', 1245*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1246*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 1247*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="3"/>', 1248*e1fe3e4aSElliott Hughes " </Paint>", 1249*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1250*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="2">', 1251*e1fe3e4aSElliott Hughes ' <BaseGlyph value="D"/>', 1252*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1253*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 1254*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="3"/>', 1255*e1fe3e4aSElliott Hughes " </Paint>", 1256*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1257*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="3">', 1258*e1fe3e4aSElliott Hughes ' <BaseGlyph value="E"/>', 1259*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1260*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 1261*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="5"/>', 1262*e1fe3e4aSElliott Hughes " </Paint>", 1263*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1264*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 1265*e1fe3e4aSElliott Hughes " <LayerList>", 1266*e1fe3e4aSElliott Hughes " <!-- LayerCount=7 -->", 1267*e1fe3e4aSElliott Hughes ' <Paint index="0" Format="10"><!-- PaintGlyph -->', 1268*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1269*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 1270*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1271*e1fe3e4aSElliott Hughes " </Paint>", 1272*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1273*e1fe3e4aSElliott Hughes " </Paint>", 1274*e1fe3e4aSElliott Hughes ' <Paint index="1" Format="10"><!-- PaintGlyph -->', 1275*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1276*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1277*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1278*e1fe3e4aSElliott Hughes " </Paint>", 1279*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1280*e1fe3e4aSElliott Hughes " </Paint>", 1281*e1fe3e4aSElliott Hughes ' <Paint index="2" Format="10"><!-- PaintGlyph -->', 1282*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1283*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1284*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1285*e1fe3e4aSElliott Hughes " </Paint>", 1286*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1287*e1fe3e4aSElliott Hughes " </Paint>", 1288*e1fe3e4aSElliott Hughes ' <Paint index="3" Format="10"><!-- PaintGlyph -->', 1289*e1fe3e4aSElliott Hughes ' <Paint Format="3"><!-- PaintVarSolid -->', 1290*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1291*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1292*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 1293*e1fe3e4aSElliott Hughes " </Paint>", 1294*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1295*e1fe3e4aSElliott Hughes " </Paint>", 1296*e1fe3e4aSElliott Hughes ' <Paint index="4" Format="10"><!-- PaintGlyph -->', 1297*e1fe3e4aSElliott Hughes ' <Paint Format="3"><!-- PaintVarSolid -->', 1298*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1299*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1300*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 1301*e1fe3e4aSElliott Hughes " </Paint>", 1302*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1303*e1fe3e4aSElliott Hughes " </Paint>", 1304*e1fe3e4aSElliott Hughes ' <Paint index="5" Format="1"><!-- PaintColrLayers -->', 1305*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 1306*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="3"/>', 1307*e1fe3e4aSElliott Hughes " </Paint>", 1308*e1fe3e4aSElliott Hughes ' <Paint index="6" Format="10"><!-- PaintGlyph -->', 1309*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1310*e1fe3e4aSElliott Hughes ' <PaletteIndex value="3"/>', 1311*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1312*e1fe3e4aSElliott Hughes " </Paint>", 1313*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1314*e1fe3e4aSElliott Hughes " </Paint>", 1315*e1fe3e4aSElliott Hughes " </LayerList>", 1316*e1fe3e4aSElliott Hughes "</COLR>", 1317*e1fe3e4aSElliott Hughes ], 1318*e1fe3e4aSElliott Hughes [0], 1319*e1fe3e4aSElliott Hughes id="sparse-masters-with-reuse", 1320*e1fe3e4aSElliott Hughes ), 1321*e1fe3e4aSElliott Hughes pytest.param( 1322*e1fe3e4aSElliott Hughes [ 1323*e1fe3e4aSElliott Hughes { 1324*e1fe3e4aSElliott Hughes "A": { 1325*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1326*e1fe3e4aSElliott Hughes "Layers": [ 1327*e1fe3e4aSElliott Hughes { 1328*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1329*e1fe3e4aSElliott Hughes "Paint": { 1330*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1331*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 1332*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1333*e1fe3e4aSElliott Hughes }, 1334*e1fe3e4aSElliott Hughes "Glyph": "B", 1335*e1fe3e4aSElliott Hughes }, 1336*e1fe3e4aSElliott Hughes { 1337*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1338*e1fe3e4aSElliott Hughes "Paint": { 1339*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1340*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1341*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1342*e1fe3e4aSElliott Hughes }, 1343*e1fe3e4aSElliott Hughes "Glyph": "B", 1344*e1fe3e4aSElliott Hughes }, 1345*e1fe3e4aSElliott Hughes { 1346*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1347*e1fe3e4aSElliott Hughes "Paint": { 1348*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1349*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1350*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1351*e1fe3e4aSElliott Hughes }, 1352*e1fe3e4aSElliott Hughes "Glyph": "B", 1353*e1fe3e4aSElliott Hughes }, 1354*e1fe3e4aSElliott Hughes ], 1355*e1fe3e4aSElliott Hughes }, 1356*e1fe3e4aSElliott Hughes "C": { # 'C' shares layer 1 and 2 with 'A' 1357*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1358*e1fe3e4aSElliott Hughes "Layers": [ 1359*e1fe3e4aSElliott Hughes { 1360*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1361*e1fe3e4aSElliott Hughes "Paint": { 1362*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1363*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1364*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1365*e1fe3e4aSElliott Hughes }, 1366*e1fe3e4aSElliott Hughes "Glyph": "B", 1367*e1fe3e4aSElliott Hughes }, 1368*e1fe3e4aSElliott Hughes { 1369*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1370*e1fe3e4aSElliott Hughes "Paint": { 1371*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1372*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1373*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1374*e1fe3e4aSElliott Hughes }, 1375*e1fe3e4aSElliott Hughes "Glyph": "B", 1376*e1fe3e4aSElliott Hughes }, 1377*e1fe3e4aSElliott Hughes ], 1378*e1fe3e4aSElliott Hughes }, 1379*e1fe3e4aSElliott Hughes }, 1380*e1fe3e4aSElliott Hughes { 1381*e1fe3e4aSElliott Hughes "A": { 1382*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1383*e1fe3e4aSElliott Hughes "Layers": [ 1384*e1fe3e4aSElliott Hughes { 1385*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1386*e1fe3e4aSElliott Hughes "Paint": { 1387*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1388*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 1389*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1390*e1fe3e4aSElliott Hughes }, 1391*e1fe3e4aSElliott Hughes "Glyph": "B", 1392*e1fe3e4aSElliott Hughes }, 1393*e1fe3e4aSElliott Hughes { 1394*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1395*e1fe3e4aSElliott Hughes "Paint": { 1396*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1397*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1398*e1fe3e4aSElliott Hughes "Alpha": 0.9, 1399*e1fe3e4aSElliott Hughes }, 1400*e1fe3e4aSElliott Hughes "Glyph": "B", 1401*e1fe3e4aSElliott Hughes }, 1402*e1fe3e4aSElliott Hughes { 1403*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1404*e1fe3e4aSElliott Hughes "Paint": { 1405*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1406*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1407*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1408*e1fe3e4aSElliott Hughes }, 1409*e1fe3e4aSElliott Hughes "Glyph": "B", 1410*e1fe3e4aSElliott Hughes }, 1411*e1fe3e4aSElliott Hughes ], 1412*e1fe3e4aSElliott Hughes }, 1413*e1fe3e4aSElliott Hughes "C": { 1414*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1415*e1fe3e4aSElliott Hughes "Layers": [ 1416*e1fe3e4aSElliott Hughes { 1417*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1418*e1fe3e4aSElliott Hughes "Paint": { 1419*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1420*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1421*e1fe3e4aSElliott Hughes "Alpha": 0.5, 1422*e1fe3e4aSElliott Hughes }, 1423*e1fe3e4aSElliott Hughes "Glyph": "B", 1424*e1fe3e4aSElliott Hughes }, 1425*e1fe3e4aSElliott Hughes { 1426*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1427*e1fe3e4aSElliott Hughes "Paint": { 1428*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1429*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1430*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1431*e1fe3e4aSElliott Hughes }, 1432*e1fe3e4aSElliott Hughes "Glyph": "B", 1433*e1fe3e4aSElliott Hughes }, 1434*e1fe3e4aSElliott Hughes ], 1435*e1fe3e4aSElliott Hughes }, 1436*e1fe3e4aSElliott Hughes }, 1437*e1fe3e4aSElliott Hughes ], 1438*e1fe3e4aSElliott Hughes True, 1439*e1fe3e4aSElliott Hughes [ 1440*e1fe3e4aSElliott Hughes # a different Alpha variation is applied to a shared layer between 1441*e1fe3e4aSElliott Hughes # 'A' and 'C' and thus they are no longer shared. 1442*e1fe3e4aSElliott Hughes "<COLR>", 1443*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 1444*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 1445*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 1446*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 1447*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=2 -->", 1448*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 1449*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 1450*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1451*e1fe3e4aSElliott Hughes ' <NumLayers value="3"/>', 1452*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="0"/>', 1453*e1fe3e4aSElliott Hughes " </Paint>", 1454*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1455*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="1">', 1456*e1fe3e4aSElliott Hughes ' <BaseGlyph value="C"/>', 1457*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1458*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 1459*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="3"/>', 1460*e1fe3e4aSElliott Hughes " </Paint>", 1461*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1462*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 1463*e1fe3e4aSElliott Hughes " <LayerList>", 1464*e1fe3e4aSElliott Hughes " <!-- LayerCount=5 -->", 1465*e1fe3e4aSElliott Hughes ' <Paint index="0" Format="10"><!-- PaintGlyph -->', 1466*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1467*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 1468*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1469*e1fe3e4aSElliott Hughes " </Paint>", 1470*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1471*e1fe3e4aSElliott Hughes " </Paint>", 1472*e1fe3e4aSElliott Hughes ' <Paint index="1" Format="10"><!-- PaintGlyph -->', 1473*e1fe3e4aSElliott Hughes ' <Paint Format="3"><!-- PaintVarSolid -->', 1474*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1475*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1476*e1fe3e4aSElliott Hughes ' <VarIndexBase value="0"/>', 1477*e1fe3e4aSElliott Hughes " </Paint>", 1478*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1479*e1fe3e4aSElliott Hughes " </Paint>", 1480*e1fe3e4aSElliott Hughes ' <Paint index="2" Format="10"><!-- PaintGlyph -->', 1481*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1482*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1483*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1484*e1fe3e4aSElliott Hughes " </Paint>", 1485*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1486*e1fe3e4aSElliott Hughes " </Paint>", 1487*e1fe3e4aSElliott Hughes ' <Paint index="3" Format="10"><!-- PaintGlyph -->', 1488*e1fe3e4aSElliott Hughes ' <Paint Format="3"><!-- PaintVarSolid -->', 1489*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1490*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1491*e1fe3e4aSElliott Hughes ' <VarIndexBase value="1"/>', 1492*e1fe3e4aSElliott Hughes " </Paint>", 1493*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1494*e1fe3e4aSElliott Hughes " </Paint>", 1495*e1fe3e4aSElliott Hughes ' <Paint index="4" Format="10"><!-- PaintGlyph -->', 1496*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1497*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1498*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1499*e1fe3e4aSElliott Hughes " </Paint>", 1500*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1501*e1fe3e4aSElliott Hughes " </Paint>", 1502*e1fe3e4aSElliott Hughes " </LayerList>", 1503*e1fe3e4aSElliott Hughes "</COLR>", 1504*e1fe3e4aSElliott Hughes ], 1505*e1fe3e4aSElliott Hughes [0, 1], 1506*e1fe3e4aSElliott Hughes id="shared-master-layers-different-variations", 1507*e1fe3e4aSElliott Hughes ), 1508*e1fe3e4aSElliott Hughes ], 1509*e1fe3e4aSElliott Hughes ) 1510*e1fe3e4aSElliott Hughes def test_merge_full_table( 1511*e1fe3e4aSElliott Hughes self, 1512*e1fe3e4aSElliott Hughes color_glyphs, 1513*e1fe3e4aSElliott Hughes ttFont, 1514*e1fe3e4aSElliott Hughes expected_xml, 1515*e1fe3e4aSElliott Hughes expected_varIdxes, 1516*e1fe3e4aSElliott Hughes master_layer_reuse, 1517*e1fe3e4aSElliott Hughes output_layer_reuse, 1518*e1fe3e4aSElliott Hughes ): 1519*e1fe3e4aSElliott Hughes master_ttfs = [deepcopy(ttFont) for _ in range(len(color_glyphs))] 1520*e1fe3e4aSElliott Hughes for ttf, glyphs in zip(master_ttfs, color_glyphs): 1521*e1fe3e4aSElliott Hughes # merge algorithm is expected to work the same even if the master COLRs 1522*e1fe3e4aSElliott Hughes # may differ as to the layer reuse, hence we try both ways 1523*e1fe3e4aSElliott Hughes ttf["COLR"] = buildCOLR(glyphs, allowLayerReuse=master_layer_reuse) 1524*e1fe3e4aSElliott Hughes vf = deepcopy(master_ttfs[0]) 1525*e1fe3e4aSElliott Hughes 1526*e1fe3e4aSElliott Hughes model = VariationModel([{}, {"ZZZZ": 1.0}]) 1527*e1fe3e4aSElliott Hughes merger = COLRVariationMerger( 1528*e1fe3e4aSElliott Hughes model, ["ZZZZ"], vf, allowLayerReuse=output_layer_reuse 1529*e1fe3e4aSElliott Hughes ) 1530*e1fe3e4aSElliott Hughes 1531*e1fe3e4aSElliott Hughes merger.mergeTables(vf, master_ttfs) 1532*e1fe3e4aSElliott Hughes 1533*e1fe3e4aSElliott Hughes out = vf["COLR"].table 1534*e1fe3e4aSElliott Hughes 1535*e1fe3e4aSElliott Hughes assert compile_decompile(out, vf) == out 1536*e1fe3e4aSElliott Hughes assert dump_xml(out, vf) == expected_xml 1537*e1fe3e4aSElliott Hughes assert merger.varIdxes == expected_varIdxes 1538*e1fe3e4aSElliott Hughes 1539*e1fe3e4aSElliott Hughes @pytest.mark.parametrize( 1540*e1fe3e4aSElliott Hughes "color_glyphs, before_xml, expected_xml", 1541*e1fe3e4aSElliott Hughes [ 1542*e1fe3e4aSElliott Hughes pytest.param( 1543*e1fe3e4aSElliott Hughes { 1544*e1fe3e4aSElliott Hughes "A": { 1545*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1546*e1fe3e4aSElliott Hughes "Layers": [ 1547*e1fe3e4aSElliott Hughes { 1548*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1549*e1fe3e4aSElliott Hughes "Paint": { 1550*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1551*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 1552*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1553*e1fe3e4aSElliott Hughes }, 1554*e1fe3e4aSElliott Hughes "Glyph": "B", 1555*e1fe3e4aSElliott Hughes }, 1556*e1fe3e4aSElliott Hughes { 1557*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1558*e1fe3e4aSElliott Hughes "Paint": { 1559*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1560*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1561*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1562*e1fe3e4aSElliott Hughes }, 1563*e1fe3e4aSElliott Hughes "Glyph": "C", 1564*e1fe3e4aSElliott Hughes }, 1565*e1fe3e4aSElliott Hughes { 1566*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1567*e1fe3e4aSElliott Hughes "Paint": { 1568*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1569*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1570*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1571*e1fe3e4aSElliott Hughes }, 1572*e1fe3e4aSElliott Hughes "Glyph": "D", 1573*e1fe3e4aSElliott Hughes }, 1574*e1fe3e4aSElliott Hughes ], 1575*e1fe3e4aSElliott Hughes }, 1576*e1fe3e4aSElliott Hughes "E": { 1577*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrLayers), 1578*e1fe3e4aSElliott Hughes "Layers": [ 1579*e1fe3e4aSElliott Hughes { 1580*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1581*e1fe3e4aSElliott Hughes "Paint": { 1582*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1583*e1fe3e4aSElliott Hughes "PaletteIndex": 1, 1584*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1585*e1fe3e4aSElliott Hughes }, 1586*e1fe3e4aSElliott Hughes "Glyph": "C", 1587*e1fe3e4aSElliott Hughes }, 1588*e1fe3e4aSElliott Hughes { 1589*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1590*e1fe3e4aSElliott Hughes "Paint": { 1591*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1592*e1fe3e4aSElliott Hughes "PaletteIndex": 2, 1593*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1594*e1fe3e4aSElliott Hughes }, 1595*e1fe3e4aSElliott Hughes "Glyph": "D", 1596*e1fe3e4aSElliott Hughes }, 1597*e1fe3e4aSElliott Hughes { 1598*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1599*e1fe3e4aSElliott Hughes "Paint": { 1600*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1601*e1fe3e4aSElliott Hughes "PaletteIndex": 3, 1602*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1603*e1fe3e4aSElliott Hughes }, 1604*e1fe3e4aSElliott Hughes "Glyph": "F", 1605*e1fe3e4aSElliott Hughes }, 1606*e1fe3e4aSElliott Hughes ], 1607*e1fe3e4aSElliott Hughes }, 1608*e1fe3e4aSElliott Hughes "G": { 1609*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintColrGlyph), 1610*e1fe3e4aSElliott Hughes "Glyph": "E", 1611*e1fe3e4aSElliott Hughes }, 1612*e1fe3e4aSElliott Hughes }, 1613*e1fe3e4aSElliott Hughes [ 1614*e1fe3e4aSElliott Hughes "<COLR>", 1615*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 1616*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 1617*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 1618*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 1619*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=3 -->", 1620*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 1621*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 1622*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1623*e1fe3e4aSElliott Hughes ' <NumLayers value="3"/>', 1624*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="0"/>', 1625*e1fe3e4aSElliott Hughes " </Paint>", 1626*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1627*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="1">', 1628*e1fe3e4aSElliott Hughes ' <BaseGlyph value="E"/>', 1629*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1630*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 1631*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="3"/>', 1632*e1fe3e4aSElliott Hughes " </Paint>", 1633*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1634*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="2">', 1635*e1fe3e4aSElliott Hughes ' <BaseGlyph value="G"/>', 1636*e1fe3e4aSElliott Hughes ' <Paint Format="11"><!-- PaintColrGlyph -->', 1637*e1fe3e4aSElliott Hughes ' <Glyph value="E"/>', 1638*e1fe3e4aSElliott Hughes " </Paint>", 1639*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1640*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 1641*e1fe3e4aSElliott Hughes " <LayerList>", 1642*e1fe3e4aSElliott Hughes " <!-- LayerCount=5 -->", 1643*e1fe3e4aSElliott Hughes ' <Paint index="0" Format="10"><!-- PaintGlyph -->', 1644*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1645*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 1646*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1647*e1fe3e4aSElliott Hughes " </Paint>", 1648*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1649*e1fe3e4aSElliott Hughes " </Paint>", 1650*e1fe3e4aSElliott Hughes ' <Paint index="1" Format="10"><!-- PaintGlyph -->', 1651*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1652*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1653*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1654*e1fe3e4aSElliott Hughes " </Paint>", 1655*e1fe3e4aSElliott Hughes ' <Glyph value="C"/>', 1656*e1fe3e4aSElliott Hughes " </Paint>", 1657*e1fe3e4aSElliott Hughes ' <Paint index="2" Format="10"><!-- PaintGlyph -->', 1658*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1659*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1660*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1661*e1fe3e4aSElliott Hughes " </Paint>", 1662*e1fe3e4aSElliott Hughes ' <Glyph value="D"/>', 1663*e1fe3e4aSElliott Hughes " </Paint>", 1664*e1fe3e4aSElliott Hughes ' <Paint index="3" Format="1"><!-- PaintColrLayers -->', 1665*e1fe3e4aSElliott Hughes ' <NumLayers value="2"/>', 1666*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="1"/>', 1667*e1fe3e4aSElliott Hughes " </Paint>", 1668*e1fe3e4aSElliott Hughes ' <Paint index="4" Format="10"><!-- PaintGlyph -->', 1669*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1670*e1fe3e4aSElliott Hughes ' <PaletteIndex value="3"/>', 1671*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1672*e1fe3e4aSElliott Hughes " </Paint>", 1673*e1fe3e4aSElliott Hughes ' <Glyph value="F"/>', 1674*e1fe3e4aSElliott Hughes " </Paint>", 1675*e1fe3e4aSElliott Hughes " </LayerList>", 1676*e1fe3e4aSElliott Hughes "</COLR>", 1677*e1fe3e4aSElliott Hughes ], 1678*e1fe3e4aSElliott Hughes [ 1679*e1fe3e4aSElliott Hughes "<COLR>", 1680*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 1681*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 1682*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 1683*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 1684*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=3 -->", 1685*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 1686*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 1687*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1688*e1fe3e4aSElliott Hughes ' <NumLayers value="3"/>', 1689*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="0"/>', 1690*e1fe3e4aSElliott Hughes " </Paint>", 1691*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1692*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="1">', 1693*e1fe3e4aSElliott Hughes ' <BaseGlyph value="E"/>', 1694*e1fe3e4aSElliott Hughes ' <Paint Format="1"><!-- PaintColrLayers -->', 1695*e1fe3e4aSElliott Hughes ' <NumLayers value="3"/>', 1696*e1fe3e4aSElliott Hughes ' <FirstLayerIndex value="3"/>', 1697*e1fe3e4aSElliott Hughes " </Paint>", 1698*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1699*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="2">', 1700*e1fe3e4aSElliott Hughes ' <BaseGlyph value="G"/>', 1701*e1fe3e4aSElliott Hughes ' <Paint Format="11"><!-- PaintColrGlyph -->', 1702*e1fe3e4aSElliott Hughes ' <Glyph value="E"/>', 1703*e1fe3e4aSElliott Hughes " </Paint>", 1704*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1705*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 1706*e1fe3e4aSElliott Hughes " <LayerList>", 1707*e1fe3e4aSElliott Hughes " <!-- LayerCount=6 -->", 1708*e1fe3e4aSElliott Hughes ' <Paint index="0" Format="10"><!-- PaintGlyph -->', 1709*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1710*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 1711*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1712*e1fe3e4aSElliott Hughes " </Paint>", 1713*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1714*e1fe3e4aSElliott Hughes " </Paint>", 1715*e1fe3e4aSElliott Hughes ' <Paint index="1" Format="10"><!-- PaintGlyph -->', 1716*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1717*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1718*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1719*e1fe3e4aSElliott Hughes " </Paint>", 1720*e1fe3e4aSElliott Hughes ' <Glyph value="C"/>', 1721*e1fe3e4aSElliott Hughes " </Paint>", 1722*e1fe3e4aSElliott Hughes ' <Paint index="2" Format="10"><!-- PaintGlyph -->', 1723*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1724*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1725*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1726*e1fe3e4aSElliott Hughes " </Paint>", 1727*e1fe3e4aSElliott Hughes ' <Glyph value="D"/>', 1728*e1fe3e4aSElliott Hughes " </Paint>", 1729*e1fe3e4aSElliott Hughes ' <Paint index="3" Format="10"><!-- PaintGlyph -->', 1730*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1731*e1fe3e4aSElliott Hughes ' <PaletteIndex value="1"/>', 1732*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1733*e1fe3e4aSElliott Hughes " </Paint>", 1734*e1fe3e4aSElliott Hughes ' <Glyph value="C"/>', 1735*e1fe3e4aSElliott Hughes " </Paint>", 1736*e1fe3e4aSElliott Hughes ' <Paint index="4" Format="10"><!-- PaintGlyph -->', 1737*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1738*e1fe3e4aSElliott Hughes ' <PaletteIndex value="2"/>', 1739*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1740*e1fe3e4aSElliott Hughes " </Paint>", 1741*e1fe3e4aSElliott Hughes ' <Glyph value="D"/>', 1742*e1fe3e4aSElliott Hughes " </Paint>", 1743*e1fe3e4aSElliott Hughes ' <Paint index="5" Format="10"><!-- PaintGlyph -->', 1744*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1745*e1fe3e4aSElliott Hughes ' <PaletteIndex value="3"/>', 1746*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1747*e1fe3e4aSElliott Hughes " </Paint>", 1748*e1fe3e4aSElliott Hughes ' <Glyph value="F"/>', 1749*e1fe3e4aSElliott Hughes " </Paint>", 1750*e1fe3e4aSElliott Hughes " </LayerList>", 1751*e1fe3e4aSElliott Hughes "</COLR>", 1752*e1fe3e4aSElliott Hughes ], 1753*e1fe3e4aSElliott Hughes id="simple-reuse", 1754*e1fe3e4aSElliott Hughes ), 1755*e1fe3e4aSElliott Hughes pytest.param( 1756*e1fe3e4aSElliott Hughes { 1757*e1fe3e4aSElliott Hughes "A": { 1758*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintGlyph), 1759*e1fe3e4aSElliott Hughes "Paint": { 1760*e1fe3e4aSElliott Hughes "Format": int(ot.PaintFormat.PaintSolid), 1761*e1fe3e4aSElliott Hughes "PaletteIndex": 0, 1762*e1fe3e4aSElliott Hughes "Alpha": 1.0, 1763*e1fe3e4aSElliott Hughes }, 1764*e1fe3e4aSElliott Hughes "Glyph": "B", 1765*e1fe3e4aSElliott Hughes }, 1766*e1fe3e4aSElliott Hughes }, 1767*e1fe3e4aSElliott Hughes [ 1768*e1fe3e4aSElliott Hughes "<COLR>", 1769*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 1770*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 1771*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 1772*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 1773*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=1 -->", 1774*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 1775*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 1776*e1fe3e4aSElliott Hughes ' <Paint Format="10"><!-- PaintGlyph -->', 1777*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1778*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 1779*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1780*e1fe3e4aSElliott Hughes " </Paint>", 1781*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1782*e1fe3e4aSElliott Hughes " </Paint>", 1783*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1784*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 1785*e1fe3e4aSElliott Hughes "</COLR>", 1786*e1fe3e4aSElliott Hughes ], 1787*e1fe3e4aSElliott Hughes [ 1788*e1fe3e4aSElliott Hughes "<COLR>", 1789*e1fe3e4aSElliott Hughes ' <Version value="1"/>', 1790*e1fe3e4aSElliott Hughes " <!-- BaseGlyphRecordCount=0 -->", 1791*e1fe3e4aSElliott Hughes " <!-- LayerRecordCount=0 -->", 1792*e1fe3e4aSElliott Hughes " <BaseGlyphList>", 1793*e1fe3e4aSElliott Hughes " <!-- BaseGlyphCount=1 -->", 1794*e1fe3e4aSElliott Hughes ' <BaseGlyphPaintRecord index="0">', 1795*e1fe3e4aSElliott Hughes ' <BaseGlyph value="A"/>', 1796*e1fe3e4aSElliott Hughes ' <Paint Format="10"><!-- PaintGlyph -->', 1797*e1fe3e4aSElliott Hughes ' <Paint Format="2"><!-- PaintSolid -->', 1798*e1fe3e4aSElliott Hughes ' <PaletteIndex value="0"/>', 1799*e1fe3e4aSElliott Hughes ' <Alpha value="1.0"/>', 1800*e1fe3e4aSElliott Hughes " </Paint>", 1801*e1fe3e4aSElliott Hughes ' <Glyph value="B"/>', 1802*e1fe3e4aSElliott Hughes " </Paint>", 1803*e1fe3e4aSElliott Hughes " </BaseGlyphPaintRecord>", 1804*e1fe3e4aSElliott Hughes " </BaseGlyphList>", 1805*e1fe3e4aSElliott Hughes "</COLR>", 1806*e1fe3e4aSElliott Hughes ], 1807*e1fe3e4aSElliott Hughes id="no-layer-list", 1808*e1fe3e4aSElliott Hughes ), 1809*e1fe3e4aSElliott Hughes ], 1810*e1fe3e4aSElliott Hughes ) 1811*e1fe3e4aSElliott Hughes def test_expandPaintColrLayers( 1812*e1fe3e4aSElliott Hughes self, color_glyphs, ttFont, before_xml, expected_xml 1813*e1fe3e4aSElliott Hughes ): 1814*e1fe3e4aSElliott Hughes colr = buildCOLR(color_glyphs, allowLayerReuse=True) 1815*e1fe3e4aSElliott Hughes 1816*e1fe3e4aSElliott Hughes assert dump_xml(colr.table, ttFont) == before_xml 1817*e1fe3e4aSElliott Hughes 1818*e1fe3e4aSElliott Hughes before_layer_count = 0 1819*e1fe3e4aSElliott Hughes reuses_colr_layers = False 1820*e1fe3e4aSElliott Hughes if colr.table.LayerList: 1821*e1fe3e4aSElliott Hughes before_layer_count = len(colr.table.LayerList.Paint) 1822*e1fe3e4aSElliott Hughes reuses_colr_layers = any( 1823*e1fe3e4aSElliott Hughes p.Format == ot.PaintFormat.PaintColrLayers 1824*e1fe3e4aSElliott Hughes for p in colr.table.LayerList.Paint 1825*e1fe3e4aSElliott Hughes ) 1826*e1fe3e4aSElliott Hughes 1827*e1fe3e4aSElliott Hughes COLRVariationMerger.expandPaintColrLayers(colr.table) 1828*e1fe3e4aSElliott Hughes 1829*e1fe3e4aSElliott Hughes assert dump_xml(colr.table, ttFont) == expected_xml 1830*e1fe3e4aSElliott Hughes 1831*e1fe3e4aSElliott Hughes after_layer_count = ( 1832*e1fe3e4aSElliott Hughes 0 if not colr.table.LayerList else len(colr.table.LayerList.Paint) 1833*e1fe3e4aSElliott Hughes ) 1834*e1fe3e4aSElliott Hughes 1835*e1fe3e4aSElliott Hughes if reuses_colr_layers: 1836*e1fe3e4aSElliott Hughes assert not any( 1837*e1fe3e4aSElliott Hughes p.Format == ot.PaintFormat.PaintColrLayers 1838*e1fe3e4aSElliott Hughes for p in colr.table.LayerList.Paint 1839*e1fe3e4aSElliott Hughes ) 1840*e1fe3e4aSElliott Hughes assert after_layer_count > before_layer_count 1841*e1fe3e4aSElliott Hughes else: 1842*e1fe3e4aSElliott Hughes assert after_layer_count == before_layer_count 1843*e1fe3e4aSElliott Hughes 1844*e1fe3e4aSElliott Hughes if colr.table.LayerList: 1845*e1fe3e4aSElliott Hughes assert len({id(p) for p in colr.table.LayerList.Paint}) == after_layer_count 1846*e1fe3e4aSElliott Hughes 1847*e1fe3e4aSElliott Hughes 1848*e1fe3e4aSElliott Hughesclass SparsePositioningMergerTest: 1849*e1fe3e4aSElliott Hughes def test_zero_kern_at_default(self): 1850*e1fe3e4aSElliott Hughes # https://github.com/fonttools/fonttools/issues/3111 1851*e1fe3e4aSElliott Hughes 1852*e1fe3e4aSElliott Hughes pytest.importorskip("ufo2ft") 1853*e1fe3e4aSElliott Hughes pytest.importorskip("ufoLib2") 1854*e1fe3e4aSElliott Hughes 1855*e1fe3e4aSElliott Hughes from fontTools.designspaceLib import DesignSpaceDocument 1856*e1fe3e4aSElliott Hughes from ufo2ft import compileVariableTTF 1857*e1fe3e4aSElliott Hughes from ufoLib2 import Font 1858*e1fe3e4aSElliott Hughes 1859*e1fe3e4aSElliott Hughes ds = DesignSpaceDocument() 1860*e1fe3e4aSElliott Hughes ds.addAxisDescriptor( 1861*e1fe3e4aSElliott Hughes name="wght", tag="wght", minimum=100, maximum=900, default=400 1862*e1fe3e4aSElliott Hughes ) 1863*e1fe3e4aSElliott Hughes ds.addSourceDescriptor(font=Font(), location=dict(wght=100)) 1864*e1fe3e4aSElliott Hughes ds.addSourceDescriptor(font=Font(), location=dict(wght=400)) 1865*e1fe3e4aSElliott Hughes ds.addSourceDescriptor(font=Font(), location=dict(wght=900)) 1866*e1fe3e4aSElliott Hughes 1867*e1fe3e4aSElliott Hughes ds.sources[0].font.newGlyph("a").unicode = ord("a") 1868*e1fe3e4aSElliott Hughes ds.sources[0].font.newGlyph("b").unicode = ord("b") 1869*e1fe3e4aSElliott Hughes ds.sources[0].font.features.text = "feature kern { pos a b b' 100; } kern;" 1870*e1fe3e4aSElliott Hughes 1871*e1fe3e4aSElliott Hughes ds.sources[1].font.newGlyph("a").unicode = ord("a") 1872*e1fe3e4aSElliott Hughes ds.sources[1].font.newGlyph("b").unicode = ord("b") 1873*e1fe3e4aSElliott Hughes ds.sources[1].font.features.text = "feature kern { pos a b b' 0; } kern;" 1874*e1fe3e4aSElliott Hughes 1875*e1fe3e4aSElliott Hughes ds.sources[2].font.newGlyph("a").unicode = ord("a") 1876*e1fe3e4aSElliott Hughes ds.sources[2].font.newGlyph("b").unicode = ord("b") 1877*e1fe3e4aSElliott Hughes ds.sources[2].font.features.text = "feature kern { pos a b b' -100; } kern;" 1878*e1fe3e4aSElliott Hughes 1879*e1fe3e4aSElliott Hughes font = compileVariableTTF(ds, inplace=True) 1880*e1fe3e4aSElliott Hughes b = BytesIO() 1881*e1fe3e4aSElliott Hughes font.save(b) 1882*e1fe3e4aSElliott Hughes 1883*e1fe3e4aSElliott Hughes assert font["GDEF"].table.VarStore.VarData[0].Item[0] == [100, -100] 1884*e1fe3e4aSElliott Hughes 1885*e1fe3e4aSElliott Hughes def test_sparse_cursive(self): 1886*e1fe3e4aSElliott Hughes # https://github.com/fonttools/fonttools/issues/3168 1887*e1fe3e4aSElliott Hughes 1888*e1fe3e4aSElliott Hughes pytest.importorskip("ufo2ft") 1889*e1fe3e4aSElliott Hughes pytest.importorskip("ufoLib2") 1890*e1fe3e4aSElliott Hughes 1891*e1fe3e4aSElliott Hughes from fontTools.designspaceLib import DesignSpaceDocument 1892*e1fe3e4aSElliott Hughes from ufo2ft import compileVariableTTF 1893*e1fe3e4aSElliott Hughes from ufoLib2 import Font 1894*e1fe3e4aSElliott Hughes 1895*e1fe3e4aSElliott Hughes ds = DesignSpaceDocument() 1896*e1fe3e4aSElliott Hughes ds.addAxisDescriptor( 1897*e1fe3e4aSElliott Hughes name="wght", tag="wght", minimum=100, maximum=900, default=400 1898*e1fe3e4aSElliott Hughes ) 1899*e1fe3e4aSElliott Hughes ds.addSourceDescriptor(font=Font(), location=dict(wght=100)) 1900*e1fe3e4aSElliott Hughes ds.addSourceDescriptor(font=Font(), location=dict(wght=400)) 1901*e1fe3e4aSElliott Hughes ds.addSourceDescriptor(font=Font(), location=dict(wght=900)) 1902*e1fe3e4aSElliott Hughes 1903*e1fe3e4aSElliott Hughes ds.sources[0].font.newGlyph("a").unicode = ord("a") 1904*e1fe3e4aSElliott Hughes ds.sources[0].font.newGlyph("b").unicode = ord("b") 1905*e1fe3e4aSElliott Hughes ds.sources[0].font.newGlyph("c").unicode = ord("c") 1906*e1fe3e4aSElliott Hughes ds.sources[ 1907*e1fe3e4aSElliott Hughes 0 1908*e1fe3e4aSElliott Hughes ].font.features.text = """ 1909*e1fe3e4aSElliott Hughes feature curs { 1910*e1fe3e4aSElliott Hughes position cursive a <anchor 400 20> <anchor 0 -20>; 1911*e1fe3e4aSElliott Hughes position cursive c <anchor NULL> <anchor 0 -20>; 1912*e1fe3e4aSElliott Hughes } curs; 1913*e1fe3e4aSElliott Hughes """ 1914*e1fe3e4aSElliott Hughes 1915*e1fe3e4aSElliott Hughes ds.sources[1].font.newGlyph("a").unicode = ord("a") 1916*e1fe3e4aSElliott Hughes ds.sources[1].font.newGlyph("b").unicode = ord("b") 1917*e1fe3e4aSElliott Hughes ds.sources[1].font.newGlyph("c").unicode = ord("c") 1918*e1fe3e4aSElliott Hughes ds.sources[ 1919*e1fe3e4aSElliott Hughes 1 1920*e1fe3e4aSElliott Hughes ].font.features.text = """ 1921*e1fe3e4aSElliott Hughes feature curs { 1922*e1fe3e4aSElliott Hughes position cursive a <anchor 500 20> <anchor 0 -20>; 1923*e1fe3e4aSElliott Hughes position cursive b <anchor 50 22> <anchor 0 -10>; 1924*e1fe3e4aSElliott Hughes position cursive c <anchor NULL> <anchor 0 -20>; 1925*e1fe3e4aSElliott Hughes } curs; 1926*e1fe3e4aSElliott Hughes """ 1927*e1fe3e4aSElliott Hughes 1928*e1fe3e4aSElliott Hughes ds.sources[2].font.newGlyph("a").unicode = ord("a") 1929*e1fe3e4aSElliott Hughes ds.sources[2].font.newGlyph("b").unicode = ord("b") 1930*e1fe3e4aSElliott Hughes ds.sources[2].font.newGlyph("c").unicode = ord("c") 1931*e1fe3e4aSElliott Hughes ds.sources[ 1932*e1fe3e4aSElliott Hughes 2 1933*e1fe3e4aSElliott Hughes ].font.features.text = """ 1934*e1fe3e4aSElliott Hughes feature curs { 1935*e1fe3e4aSElliott Hughes position cursive b <anchor 100 40> <anchor 0 -30>; 1936*e1fe3e4aSElliott Hughes position cursive c <anchor NULL> <anchor 0 -20>; 1937*e1fe3e4aSElliott Hughes } curs; 1938*e1fe3e4aSElliott Hughes """ 1939*e1fe3e4aSElliott Hughes 1940*e1fe3e4aSElliott Hughes font = compileVariableTTF(ds, inplace=True) 1941*e1fe3e4aSElliott Hughes b = BytesIO() 1942*e1fe3e4aSElliott Hughes font.save(b) 1943*e1fe3e4aSElliott Hughes 1944*e1fe3e4aSElliott Hughes assert font["GDEF"].table.VarStore.VarData[0].Item[0] == [-100, 0] 1945