1from fontTools import ttLib 2from fontTools.misc.testTools import getXML, parseXML 3from fontTools.ttLib.tables.C_O_L_R_ import table_C_O_L_R_ 4 5import binascii 6import pytest 7 8 9COLR_V0_SAMPLE = ( 10 (b"\x00\x00", "Version (0)"), 11 (b"\x00\x01", "BaseGlyphRecordCount (1)"), 12 ( 13 b"\x00\x00\x00\x0e", 14 "Offset to BaseGlyphRecordArray from beginning of table (14)", 15 ), 16 (b"\x00\x00\x00\x14", "Offset to LayerRecordArray from beginning of table (20)"), 17 (b"\x00\x03", "LayerRecordCount (3)"), 18 (b"\x00\x06", "BaseGlyphRecord[0].BaseGlyph (6)"), 19 (b"\x00\x00", "BaseGlyphRecord[0].FirstLayerIndex (0)"), 20 (b"\x00\x03", "BaseGlyphRecord[0].NumLayers (3)"), 21 (b"\x00\x07", "LayerRecord[0].LayerGlyph (7)"), 22 (b"\x00\x00", "LayerRecord[0].PaletteIndex (0)"), 23 (b"\x00\x08", "LayerRecord[1].LayerGlyph (8)"), 24 (b"\x00\x01", "LayerRecord[1].PaletteIndex (1)"), 25 (b"\x00\t", "LayerRecord[2].LayerGlyph (9)"), 26 (b"\x00\x02", "LayerRecord[3].PaletteIndex (2)"), 27) 28 29COLR_V0_DATA = b"".join(t[0] for t in COLR_V0_SAMPLE) 30 31 32COLR_V0_XML = [ 33 '<version value="0"/>', 34 '<ColorGlyph name="glyph00006">', 35 ' <layer colorID="0" name="glyph00007"/>', 36 ' <layer colorID="1" name="glyph00008"/>', 37 ' <layer colorID="2" name="glyph00009"/>', 38 "</ColorGlyph>", 39] 40 41 42def dump(table, ttFont=None): 43 print("\n".join(getXML(table.toXML, ttFont))) 44 45 46def diff_binary_fragments(font_bytes, expected_fragments): 47 pos = 0 48 prev_desc = "" 49 errors = 0 50 for expected_bytes, description in expected_fragments: 51 actual_bytes = font_bytes[pos : pos + len(expected_bytes)] 52 if actual_bytes != expected_bytes: 53 print(f'{description} (previous "{prev_desc}", actual_bytes: {"".join("%02x" % v for v in actual_bytes)} bytes: {str(font_bytes[pos:pos+16])}') 54 errors += 1 55 pos += len(expected_bytes) 56 prev_desc = description 57 assert errors == 0 58 assert pos == len( 59 font_bytes 60 ), f"Leftover font bytes, used {pos} of {len(font_bytes)}" 61 62 63@pytest.fixture 64def font(): 65 font = ttLib.TTFont() 66 font.setGlyphOrder(["glyph%05d" % i for i in range(30)]) 67 return font 68 69 70class COLR_V0_Test(object): 71 def test_decompile_and_compile(self, font): 72 colr = table_C_O_L_R_() 73 colr.decompile(COLR_V0_DATA, font) 74 diff_binary_fragments(colr.compile(font), COLR_V0_SAMPLE) 75 76 def test_decompile_and_dump_xml(self, font): 77 colr = table_C_O_L_R_() 78 colr.decompile(COLR_V0_DATA, font) 79 80 dump(colr, font) 81 assert getXML(colr.toXML, font) == COLR_V0_XML 82 83 def test_load_from_xml_and_compile(self, font): 84 colr = table_C_O_L_R_() 85 for name, attrs, content in parseXML(COLR_V0_XML): 86 colr.fromXML(name, attrs, content, font) 87 88 diff_binary_fragments(colr.compile(font), COLR_V0_SAMPLE) 89 90 def test_round_trip_xml(self, font): 91 colr = table_C_O_L_R_() 92 for name, attrs, content in parseXML(COLR_V0_XML): 93 colr.fromXML(name, attrs, content, font) 94 compiled = colr.compile(font) 95 96 colr = table_C_O_L_R_() 97 colr.decompile(compiled, font) 98 assert getXML(colr.toXML, font) == COLR_V0_XML 99 100 101COLR_V1_SAMPLE = ( 102 (b"\x00\x01", "Version (1)"), 103 (b"\x00\x01", "BaseGlyphRecordCount (1)"), 104 ( 105 b"\x00\x00\x00\x1a", 106 "Offset to BaseGlyphRecordArray from beginning of table (26)", 107 ), 108 (b"\x00\x00\x00 ", "Offset to LayerRecordArray from beginning of table (32)"), 109 (b"\x00\x03", "LayerRecordCount (3)"), 110 (b"\x00\x00\x00,", "Offset to BaseGlyphV1List from beginning of table (44)"), 111 (b"\x00\x00\x00\xac", "Offset to LayerV1List from beginning of table (172)"), 112 (b"\x00\x00\x00\x00", "Offset to VarStore (NULL)"), 113 (b"\x00\x06", "BaseGlyphRecord[0].BaseGlyph (6)"), 114 (b"\x00\x00", "BaseGlyphRecord[0].FirstLayerIndex (0)"), 115 (b"\x00\x03", "BaseGlyphRecord[0].NumLayers (3)"), 116 (b"\x00\x07", "LayerRecord[0].LayerGlyph (7)"), 117 (b"\x00\x00", "LayerRecord[0].PaletteIndex (0)"), 118 (b"\x00\x08", "LayerRecord[1].LayerGlyph (8)"), 119 (b"\x00\x01", "LayerRecord[1].PaletteIndex (1)"), 120 (b"\x00\t", "LayerRecord[2].LayerGlyph (9)"), 121 (b"\x00\x02", "LayerRecord[2].PaletteIndex (2)"), 122 # BaseGlyphV1List 123 (b"\x00\x00\x00\x03", "BaseGlyphV1List.BaseGlyphCount (3)"), 124 (b"\x00\n", "BaseGlyphV1List.BaseGlyphV1Record[0].BaseGlyph (10)"), 125 ( 126 b"\x00\x00\x00\x16", 127 "Offset to Paint table from beginning of BaseGlyphV1List (22)", 128 ), 129 (b"\x00\x0e", "BaseGlyphV1List.BaseGlyphV1Record[1].BaseGlyph (14)"), 130 ( 131 b"\x00\x00\x00\x1c", 132 "Offset to Paint table from beginning of BaseGlyphV1List (28)", 133 ), 134 (b"\x00\x0f", "BaseGlyphV1List.BaseGlyphV1Record[2].BaseGlyph (15)"), 135 ( 136 b"\x00\x00\x00\x5b", 137 "Offset to Paint table from beginning of BaseGlyphV1List (91)", 138 ), 139 # BaseGlyphV1Record[0] 140 (b"\x01", "BaseGlyphV1Record[0].Paint.Format (1)"), 141 (b"\x04", "BaseGlyphV1Record[0].Paint.NumLayers (4)"), 142 (b"\x00\x00\x00\x00", "BaseGlyphV1Record[0].Paint.FirstLayerIndex (0)"), 143 # BaseGlyphV1Record[1] 144 (b"\x14", "BaseGlyphV1Record[1].Paint.Format (20)"), 145 (b"\x00\x00<", "Offset to SourcePaint from beginning of PaintComposite (60)"), 146 (b"\x03", "BaseGlyphV1Record[1].Paint.CompositeMode [SRC_OVER] (3)"), 147 (b"\x00\x00\x08", "Offset to BackdropPaint from beginning of PaintComposite (8)"), 148 (b"\x0d", "BaseGlyphV1Record[1].Paint.BackdropPaint.Format (13)"), 149 (b"\x00\x00\x34", "Offset to Paint from beginning of PaintVarTransform (52)"), 150 (b"\x00\x01\x00\x00\x00\x00\x00\x00", "Affine2x3.xx.value (1.0)"), 151 (b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.xy.value (0.0)"), 152 (b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.yx.value (0.0)"), 153 (b"\x00\x01\x00\x00\x00\x00\x00\x00", "Affine2x3.yy.value (1.0)"), 154 (b"\x01\x2c\x00\x00\x00\x00\x00\x00", "Affine2x3.dx.value (300.0)"), 155 (b"\x00\x00\x00\x00\x00\x00\x00\x00", "Affine2x3.dy.value (0.0)"), 156 (b"\x0b", "BaseGlyphV1Record[1].Paint.SourcePaint.Format (11)"), 157 (b"\x00\n", "BaseGlyphV1Record[1].Paint.SourcePaint.Glyph (10)"), 158 # BaseGlyphV1Record[2] 159 (b"\x0a", "BaseGlyphV1Record[2].Paint.Format (10)"), 160 (b"\x00\x00\x06", "Offset to Paint subtable from beginning of PaintGlyph (6)"), 161 (b"\x00\x0b", "BaseGlyphV1Record[2].Paint.Glyph (11)"), 162 (b"\x08", "BaseGlyphV1Record[2].Paint.Paint.Format (8)"), 163 (b"\x00\x00\x10", "Offset to ColorLine from beginning of PaintSweepGradient (16)"), 164 (b"\x01\x03", "centerX (259)"), 165 (b"\x01\x2c", "centerY (300)"), 166 (b"\x00\x2d\x00\x00", "startAngle (45.0)"), 167 (b"\x00\x87\x00\x00", "endAngle (135.0)"), 168 (b"\x00", "ColorLine.Extend (0; pad)"), 169 (b"\x00\x02", "ColorLine.StopCount (2)"), 170 (b"\x00\x00", "ColorLine.ColorStop[0].StopOffset (0.0)"), 171 (b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"), 172 (b"@\x00", "ColorLine.ColorStop[0].Color.Alpha (1.0)"), 173 (b"@\x00", "ColorLine.ColorStop[1].StopOffset (1.0)"), 174 (b"\x00\x05", "ColorLine.ColorStop[1].Color.PaletteIndex (5)"), 175 (b"@\x00", "ColorLine.ColorStop[1].Color.Alpha (1.0)"), 176 # LayerV1List 177 (b"\x00\x00\x00\x04", "LayerV1List.LayerCount (4)"), 178 ( 179 b"\x00\x00\x00\x14", 180 "First Offset to Paint table from beginning of LayerV1List (20)", 181 ), 182 ( 183 b"\x00\x00\x00\x23", 184 "Second Offset to Paint table from beginning of LayerV1List (35)", 185 ), 186 ( 187 b"\x00\x00\x00\x4e", 188 "Third Offset to Paint table from beginning of LayerV1List (78)", 189 ), 190 ( 191 b"\x00\x00\x00\xb7", 192 "Fourth Offset to Paint table from beginning of LayerV1List (183)", 193 ), 194 # PaintGlyph glyph00011 195 (b"\x0a", "LayerV1List.Paint[0].Format (10)"), 196 (b"\x00\x00\x06", "Offset24 to Paint subtable from beginning of PaintGlyph (6)"), 197 (b"\x00\x0b", "LayerV1List.Paint[0].Glyph (glyph00011)"), 198 # PaintVarSolid 199 (b"\x03", "LayerV1List.Paint[0].Paint.Format (3)"), 200 (b"\x00\x02", "Paint.Color.PaletteIndex (2)"), 201 (b" \x00", "Paint.Color.Alpha.value (0.5)"), 202 (b"\x00\x00\x00\x00", "Paint.Color.Alpha.varIdx (0)"), 203 # PaintGlyph glyph00012 204 (b"\x0a", "LayerV1List.Paint[1].Format (10)"), 205 (b"\x00\x00\x06", "Offset to Paint subtable from beginning of PaintGlyph (6)"), 206 (b"\x00\x0c", "LayerV1List.Paint[1].Glyph (glyph00012)"), 207 (b"\x04", "LayerV1List.Paint[1].Paint.Format (4)"), 208 (b"\x00\x00\x10", "Offset to ColorLine from beginning of PaintLinearGradient (16)"), 209 (b"\x00\x01", "Paint.x0 (1)"), 210 (b"\x00\x02", "Paint.y0 (2)"), 211 (b"\xff\xfd", "Paint.x1 (-3)"), 212 (b"\xff\xfc", "Paint.y1 (-4)"), 213 (b"\x00\x05", "Paint.x2 (5)"), 214 (b"\x00\x06", "Paint.y2 (6)"), 215 (b"\x01", "ColorLine.Extend (1; repeat)"), 216 (b"\x00\x03", "ColorLine.StopCount (3)"), 217 (b"\x00\x00", "ColorLine.ColorStop[0].StopOffset (0.0)"), 218 (b"\x00\x03", "ColorLine.ColorStop[0].Color.PaletteIndex (3)"), 219 (b"@\x00", "ColorLine.ColorStop[0].Color.Alpha (1.0)"), 220 (b" \x00", "ColorLine.ColorStop[1].StopOffset (0.5)"), 221 (b"\x00\x04", "ColorLine.ColorStop[1].Color.PaletteIndex (4)"), 222 (b"@\x00", "ColorLine.ColorStop[1].Color.Alpha (1.0)"), 223 (b"@\x00", "ColorLine.ColorStop[2].StopOffset (1.0)"), 224 (b"\x00\x05", "ColorLine.ColorStop[2].Color.PaletteIndex (5)"), 225 (b"@\x00", "ColorLine.ColorStop[2].Color.Alpha (1.0)"), 226 # PaintGlyph glyph00013 227 (b"\x0a", "LayerV1List.Paint[2].Format (10)"), 228 (b"\x00\x00\x06", "Offset to Paint subtable from beginning of PaintGlyph (6)"), 229 (b"\x00\r", "LayerV1List.Paint[2].Glyph (13)"), 230 (b"\x0c", "LayerV1List.Paint[2].Paint.Format (12)"), 231 (b"\x00\x00\x1c", "Offset to Paint subtable from beginning of PaintTransform (28)"), 232 (b"\xff\xf3\x00\x00", "Affine2x3.xx (-13)"), 233 (b"\x00\x0e\x00\x00", "Affine2x3.xy (14)"), 234 (b"\x00\x0f\x00\x00", "Affine2x3.yx (15)"), 235 (b"\xff\xef\x00\x00", "Affine2x3.yy (-17)"), 236 (b"\x00\x12\x00\x00", "Affine2x3.yy (18)"), 237 (b"\x00\x13\x00\x00", "Affine2x3.yy (19)"), 238 (b"\x07", "LayerV1List.Paint[2].Paint.Paint.Format (7)"), 239 (b"\x00\x00(", "Offset to ColorLine from beginning of PaintVarRadialGradient (40)"), 240 (b"\x00\x07\x00\x00\x00\x00", "Paint.x0.value (7)"), 241 (b"\x00\x08\x00\x00\x00\x00", "Paint.y0.value (8)"), 242 (b"\x00\t\x00\x00\x00\x00", "Paint.r0.value (9)"), 243 (b"\x00\n\x00\x00\x00\x00", "Paint.x1.value (10)"), 244 (b"\x00\x0b\x00\x00\x00\x00", "Paint.y1.value (11)"), 245 (b"\x00\x0c\x00\x00\x00\x00", "Paint.r1.value (12)"), 246 (b"\x00", "ColorLine.Extend (0; pad)"), 247 (b"\x00\x02", "ColorLine.StopCount (2)"), 248 (b"\x00\x00\x00\x00\x00\x00", "ColorLine.ColorStop[0].StopOffset.value (0.0)"), 249 (b"\x00\x06", "ColorLine.ColorStop[0].Color.PaletteIndex (6)"), 250 (b"@\x00\x00\x00\x00\x00", "ColorLine.ColorStop[0].Color.Alpha.value (1.0)"), 251 (b"@\x00\x00\x00\x00\x00", "ColorLine.ColorStop[1].StopOffset.value (1.0)"), 252 (b"\x00\x07", "ColorLine.ColorStop[1].Color.PaletteIndex (7)"), 253 (b"\x19\x9a\x00\x00\x00\x00", "ColorLine.ColorStop[1].Color.Alpha.value (0.4)"), 254 # PaintTranslate 255 (b"\x0e", "LayerV1List.Paint[3].Format (14)"), 256 (b"\x00\x00\x0c", "Offset to Paint subtable from beginning of PaintTranslate (12)"), 257 (b"\x01\x01\x00\x00", "dx (257)"), 258 (b"\x01\x02\x00\x00", "dy (258)"), 259 # PaintRotate 260 (b"\x10", "LayerV1List.Paint[3].Paint.Format (16)"), 261 (b"\x00\x00\x10", "Offset to Paint subtable from beginning of PaintRotate (16)"), 262 (b"\x00\x2d\x00\x00", "angle (45)"), 263 (b"\x00\xff\x00\x00", "centerX (255)"), 264 (b"\x01\x00\x00\x00", "centerY (256)"), 265 # PaintSkew 266 (b"\x12", "LayerV1List.Paint[3].Paint.Paint.Format (18)"), 267 (b"\x00\x00\x14", "Offset to Paint subtable from beginning of PaintSkew (20)"), 268 (b"\xff\xf5\x00\x00", "xSkewAngle (-11)"), 269 (b"\x00\x05\x00\x00", "ySkewAngle (5)"), 270 (b"\x00\xfd\x00\x00", "centerX.value (253)"), 271 (b"\x00\xfe\x00\x00", "centerY.value (254)"), 272 # PaintGlyph 273 (b"\x0a", "LayerV1List.Paint[3].Paint.Paint.Paint.Format (10)"), 274 (b"\x00\x00\x06", "Offset to Paint subtable from beginning of PaintGlyph (6)"), 275 (b"\x00\x0b", "LayerV1List.Paint[2].Glyph (11)"), 276 # PaintSolid 277 (b"\x02", "LayerV1List.Paint[0].Paint.Paint.Paint.Paint.Format (2)"), 278 (b"\x00\x02", "Paint.Color.PaletteIndex (2)"), 279 (b" \x00", "Paint.Color.Alpha (0.5)"), 280) 281 282COLR_V1_DATA = b"".join(t[0] for t in COLR_V1_SAMPLE) 283 284COLR_V1_XML = [ 285 '<Version value="1"/>', 286 "<!-- BaseGlyphRecordCount=1 -->", 287 "<BaseGlyphRecordArray>", 288 ' <BaseGlyphRecord index="0">', 289 ' <BaseGlyph value="glyph00006"/>', 290 ' <FirstLayerIndex value="0"/>', 291 ' <NumLayers value="3"/>', 292 " </BaseGlyphRecord>", 293 "</BaseGlyphRecordArray>", 294 "<LayerRecordArray>", 295 ' <LayerRecord index="0">', 296 ' <LayerGlyph value="glyph00007"/>', 297 ' <PaletteIndex value="0"/>', 298 " </LayerRecord>", 299 ' <LayerRecord index="1">', 300 ' <LayerGlyph value="glyph00008"/>', 301 ' <PaletteIndex value="1"/>', 302 " </LayerRecord>", 303 ' <LayerRecord index="2">', 304 ' <LayerGlyph value="glyph00009"/>', 305 ' <PaletteIndex value="2"/>', 306 " </LayerRecord>", 307 "</LayerRecordArray>", 308 "<!-- LayerRecordCount=3 -->", 309 "<BaseGlyphV1List>", 310 " <!-- BaseGlyphCount=3 -->", 311 ' <BaseGlyphV1Record index="0">', 312 ' <BaseGlyph value="glyph00010"/>', 313 ' <Paint Format="1"><!-- PaintColrLayers -->', 314 ' <NumLayers value="4"/>', 315 ' <FirstLayerIndex value="0"/>', 316 " </Paint>", 317 " </BaseGlyphV1Record>", 318 ' <BaseGlyphV1Record index="1">', 319 ' <BaseGlyph value="glyph00014"/>', 320 ' <Paint Format="20"><!-- PaintComposite -->', 321 ' <SourcePaint Format="11"><!-- PaintColrGlyph -->', 322 ' <Glyph value="glyph00010"/>', 323 " </SourcePaint>", 324 ' <CompositeMode value="src_over"/>', 325 ' <BackdropPaint Format="13"><!-- PaintVarTransform -->', 326 ' <Paint Format="11"><!-- PaintColrGlyph -->', 327 ' <Glyph value="glyph00010"/>', 328 " </Paint>", 329 " <Transform>", 330 ' <xx value="1.0"/>', 331 ' <yx value="0.0"/>', 332 ' <xy value="0.0"/>', 333 ' <yy value="1.0"/>', 334 ' <dx value="300.0"/>', 335 ' <dy value="0.0"/>', 336 " </Transform>", 337 " </BackdropPaint>", 338 " </Paint>", 339 " </BaseGlyphV1Record>", 340 ' <BaseGlyphV1Record index="2">', 341 ' <BaseGlyph value="glyph00015"/>', 342 ' <Paint Format="10"><!-- PaintGlyph -->', 343 ' <Paint Format="8"><!-- PaintSweepGradient -->', 344 " <ColorLine>", 345 ' <Extend value="pad"/>', 346 " <!-- StopCount=2 -->", 347 ' <ColorStop index="0">', 348 ' <StopOffset value="0.0"/>', 349 " <Color>", 350 ' <PaletteIndex value="3"/>', 351 ' <Alpha value="1.0"/>', 352 " </Color>", 353 " </ColorStop>", 354 ' <ColorStop index="1">', 355 ' <StopOffset value="1.0"/>', 356 " <Color>", 357 ' <PaletteIndex value="5"/>', 358 ' <Alpha value="1.0"/>', 359 " </Color>", 360 " </ColorStop>", 361 " </ColorLine>", 362 ' <centerX value="259"/>', 363 ' <centerY value="300"/>', 364 ' <startAngle value="45.0"/>', 365 ' <endAngle value="135.0"/>', 366 " </Paint>", 367 ' <Glyph value="glyph00011"/>', 368 " </Paint>", 369 " </BaseGlyphV1Record>", 370 "</BaseGlyphV1List>", 371 "<LayerV1List>", 372 " <!-- LayerCount=4 -->", 373 ' <Paint index="0" Format="10"><!-- PaintGlyph -->', 374 ' <Paint Format="3"><!-- PaintVarSolid -->', 375 " <Color>", 376 ' <PaletteIndex value="2"/>', 377 ' <Alpha value="0.5"/>', 378 " </Color>", 379 " </Paint>", 380 ' <Glyph value="glyph00011"/>', 381 " </Paint>", 382 ' <Paint index="1" Format="10"><!-- PaintGlyph -->', 383 ' <Paint Format="4"><!-- PaintLinearGradient -->', 384 " <ColorLine>", 385 ' <Extend value="repeat"/>', 386 " <!-- StopCount=3 -->", 387 ' <ColorStop index="0">', 388 ' <StopOffset value="0.0"/>', 389 " <Color>", 390 ' <PaletteIndex value="3"/>', 391 ' <Alpha value="1.0"/>', 392 " </Color>", 393 " </ColorStop>", 394 ' <ColorStop index="1">', 395 ' <StopOffset value="0.5"/>', 396 " <Color>", 397 ' <PaletteIndex value="4"/>', 398 ' <Alpha value="1.0"/>', 399 " </Color>", 400 " </ColorStop>", 401 ' <ColorStop index="2">', 402 ' <StopOffset value="1.0"/>', 403 " <Color>", 404 ' <PaletteIndex value="5"/>', 405 ' <Alpha value="1.0"/>', 406 " </Color>", 407 " </ColorStop>", 408 " </ColorLine>", 409 ' <x0 value="1"/>', 410 ' <y0 value="2"/>', 411 ' <x1 value="-3"/>', 412 ' <y1 value="-4"/>', 413 ' <x2 value="5"/>', 414 ' <y2 value="6"/>', 415 " </Paint>", 416 ' <Glyph value="glyph00012"/>', 417 " </Paint>", 418 ' <Paint index="2" Format="10"><!-- PaintGlyph -->', 419 ' <Paint Format="12"><!-- PaintTransform -->', 420 ' <Paint Format="7"><!-- PaintVarRadialGradient -->', 421 " <ColorLine>", 422 ' <Extend value="pad"/>', 423 " <!-- StopCount=2 -->", 424 ' <ColorStop index="0">', 425 ' <StopOffset value="0.0"/>', 426 " <Color>", 427 ' <PaletteIndex value="6"/>', 428 ' <Alpha value="1.0"/>', 429 " </Color>", 430 " </ColorStop>", 431 ' <ColorStop index="1">', 432 ' <StopOffset value="1.0"/>', 433 " <Color>", 434 ' <PaletteIndex value="7"/>', 435 ' <Alpha value="0.4"/>', 436 " </Color>", 437 " </ColorStop>", 438 " </ColorLine>", 439 ' <x0 value="7"/>', 440 ' <y0 value="8"/>', 441 ' <r0 value="9"/>', 442 ' <x1 value="10"/>', 443 ' <y1 value="11"/>', 444 ' <r1 value="12"/>', 445 " </Paint>", 446 " <Transform>", 447 ' <xx value="-13.0"/>', 448 ' <yx value="14.0"/>', 449 ' <xy value="15.0"/>', 450 ' <yy value="-17.0"/>', 451 ' <dx value="18.0"/>', 452 ' <dy value="19.0"/>', 453 " </Transform>", 454 " </Paint>", 455 ' <Glyph value="glyph00013"/>', 456 " </Paint>", 457 ' <Paint index="3" Format="14"><!-- PaintTranslate -->', 458 ' <Paint Format="16"><!-- PaintRotate -->', 459 ' <Paint Format="18"><!-- PaintSkew -->', 460 ' <Paint Format="10"><!-- PaintGlyph -->', 461 ' <Paint Format="2"><!-- PaintSolid -->', 462 " <Color>", 463 ' <PaletteIndex value="2"/>', 464 ' <Alpha value="0.5"/>', 465 " </Color>", 466 " </Paint>", 467 ' <Glyph value="glyph00011"/>', 468 " </Paint>", 469 ' <xSkewAngle value="-11.0"/>', 470 ' <ySkewAngle value="5.0"/>', 471 ' <centerX value="253.0"/>', 472 ' <centerY value="254.0"/>', 473 " </Paint>", 474 ' <angle value="45.0"/>', 475 ' <centerX value="255.0"/>', 476 ' <centerY value="256.0"/>', 477 " </Paint>", 478 ' <dx value="257.0"/>', 479 ' <dy value="258.0"/>', 480 " </Paint>", 481 "</LayerV1List>", 482] 483 484 485class COLR_V1_Test(object): 486 def test_decompile_and_compile(self, font): 487 colr = table_C_O_L_R_() 488 colr.decompile(COLR_V1_DATA, font) 489 diff_binary_fragments(colr.compile(font), COLR_V1_SAMPLE) 490 491 def test_decompile_and_dump_xml(self, font): 492 colr = table_C_O_L_R_() 493 colr.decompile(COLR_V1_DATA, font) 494 495 dump(colr, font) 496 assert getXML(colr.toXML, font) == COLR_V1_XML 497 498 def test_load_from_xml_and_compile(self, font): 499 colr = table_C_O_L_R_() 500 for name, attrs, content in parseXML(COLR_V1_XML): 501 colr.fromXML(name, attrs, content, font) 502 diff_binary_fragments(colr.compile(font), COLR_V1_SAMPLE) 503 504 def test_round_trip_xml(self, font): 505 colr = table_C_O_L_R_() 506 for name, attrs, content in parseXML(COLR_V1_XML): 507 colr.fromXML(name, attrs, content, font) 508 compiled = colr.compile(font) 509 510 colr = table_C_O_L_R_() 511 colr.decompile(compiled, font) 512 assert getXML(colr.toXML, font) == COLR_V1_XML 513