1from fontTools.misc.testTools import getXML, parseXML 2from fontTools.misc.textTools import deHexStr 3from fontTools.ttLib import getTableModule, newTable 4import unittest 5 6 7CPAL_DATA_V0 = deHexStr( 8 "0000 0002 " # version=0, numPaletteEntries=2 9 "0002 0004 " # numPalettes=2, numColorRecords=4 10 "00000010 " # offsetToFirstColorRecord=16 11 "0000 0002 " # colorRecordIndex=[0, 2] 12 "000000FF FFCC66FF " # colorRecord #0, #1 (blue/green/red/alpha) 13 "000000FF 000080FF" 14) # colorRecord #2, #3 15 16 17CPAL_DATA_V0_SHARING_COLORS = deHexStr( 18 "0000 0003 " # version=0, numPaletteEntries=3 19 "0004 0006 " # numPalettes=4, numColorRecords=6 20 "00000014 " # offsetToFirstColorRecord=20 21 "0000 0000 0003 0000 " # colorRecordIndex=[0, 0, 3, 0] 22 "443322FF 77889911 55555555 " # colorRecord #0, #1, #2 (BGRA) 23 "443322FF 77889911 FFFFFFFF" 24) # colorRecord #3, #4, #5 25 26 27CPAL_DATA_V1_NOLABELS_NOTYPES = deHexStr( 28 "0001 0003 " # version=1, numPaletteEntries=3 29 "0002 0006 " # numPalettes=2, numColorRecords=6 30 "0000001C " # offsetToFirstColorRecord=28 31 "0000 0003 " # colorRecordIndex=[0, 3] 32 "00000000 " # offsetToPaletteTypeArray=0 33 "00000000 " # offsetToPaletteLabelArray=0 34 "00000000 " # offsetToPaletteEntryLabelArray=0 35 "CAFECAFE 00112233 44556677 " # colorRecord #0, #1, #2 (BGRA) 36 "31415927 42424242 00331337" 37) # colorRecord #3, #4, #5 38 39 40CPAL_DATA_V1 = deHexStr( 41 "0001 0003 " # version=1, numPaletteEntries=3 42 "0002 0006 " # numPalettes=2, numColorRecords=6 43 "0000001C " # offsetToFirstColorRecord=28 44 "0000 0003 " # colorRecordIndex=[0, 3] 45 "00000034 " # offsetToPaletteTypeArray=52 46 "0000003C " # offsetToPaletteLabelArray=60 47 "00000040 " # offsetToPaletteEntryLabelArray=64 48 "CAFECAFE 00112233 44556677 " # colorRecord #0, #1, #2 (BGRA) 49 "31415927 42424242 00331337 " # colorRecord #3, #4, #5 50 "00000001 00000002 " # paletteType=[1, 2] 51 "0102 0103 " # paletteLabel=[258, 259] 52 "0201 0202 0203" 53) # paletteEntryLabel=[513, 514, 515] 54 55 56class FakeNameTable(object): 57 def __init__(self, names): 58 self.names = names 59 60 def getDebugName(self, nameID): 61 return self.names.get(nameID) 62 63 64class CPALTest(unittest.TestCase): 65 def test_decompile_v0(self): 66 cpal = newTable("CPAL") 67 cpal.decompile(CPAL_DATA_V0, ttFont=None) 68 self.assertEqual(cpal.version, 0) 69 self.assertEqual(cpal.numPaletteEntries, 2) 70 self.assertEqual( 71 repr(cpal.palettes), "[[#000000FF, #66CCFFFF], [#000000FF, #800000FF]]" 72 ) 73 74 def test_decompile_v0_sharingColors(self): 75 cpal = newTable("CPAL") 76 cpal.decompile(CPAL_DATA_V0_SHARING_COLORS, ttFont=None) 77 self.assertEqual(cpal.version, 0) 78 self.assertEqual(cpal.numPaletteEntries, 3) 79 self.assertEqual( 80 [repr(p) for p in cpal.palettes], 81 [ 82 "[#223344FF, #99887711, #55555555]", 83 "[#223344FF, #99887711, #55555555]", 84 "[#223344FF, #99887711, #FFFFFFFF]", 85 "[#223344FF, #99887711, #55555555]", 86 ], 87 ) 88 89 def test_decompile_v1_noLabelsNoTypes(self): 90 cpal = newTable("CPAL") 91 cpal.decompile(CPAL_DATA_V1_NOLABELS_NOTYPES, ttFont=None) 92 self.assertEqual(cpal.version, 1) 93 self.assertEqual(cpal.numPaletteEntries, 3) 94 self.assertEqual( 95 [repr(p) for p in cpal.palettes], 96 [ 97 "[#CAFECAFE, #22110033, #66554477]", # RGBA 98 "[#59413127, #42424242, #13330037]", 99 ], 100 ) 101 self.assertEqual(cpal.paletteLabels, [cpal.NO_NAME_ID] * len(cpal.palettes)) 102 self.assertEqual(cpal.paletteTypes, [0, 0]) 103 self.assertEqual( 104 cpal.paletteEntryLabels, [cpal.NO_NAME_ID] * cpal.numPaletteEntries 105 ) 106 107 def test_decompile_v1(self): 108 cpal = newTable("CPAL") 109 cpal.decompile(CPAL_DATA_V1, ttFont=None) 110 self.assertEqual(cpal.version, 1) 111 self.assertEqual(cpal.numPaletteEntries, 3) 112 self.assertEqual( 113 [repr(p) for p in cpal.palettes], 114 [ 115 "[#CAFECAFE, #22110033, #66554477]", # RGBA 116 "[#59413127, #42424242, #13330037]", 117 ], 118 ) 119 self.assertEqual(cpal.paletteTypes, [1, 2]) 120 self.assertEqual(cpal.paletteLabels, [258, 259]) 121 self.assertEqual(cpal.paletteEntryLabels, [513, 514, 515]) 122 123 def test_compile_v0(self): 124 cpal = newTable("CPAL") 125 cpal.decompile(CPAL_DATA_V0, ttFont=None) 126 self.assertEqual(cpal.compile(ttFont=None), CPAL_DATA_V0) 127 128 def test_compile_v0_sharingColors(self): 129 cpal = newTable("CPAL") 130 cpal.version = 0 131 Color = getTableModule("CPAL").Color 132 palette1 = [ 133 Color(red=0x22, green=0x33, blue=0x44, alpha=0xFF), 134 Color(red=0x99, green=0x88, blue=0x77, alpha=0x11), 135 Color(red=0x55, green=0x55, blue=0x55, alpha=0x55), 136 ] 137 palette2 = [ 138 Color(red=0x22, green=0x33, blue=0x44, alpha=0xFF), 139 Color(red=0x99, green=0x88, blue=0x77, alpha=0x11), 140 Color(red=0xFF, green=0xFF, blue=0xFF, alpha=0xFF), 141 ] 142 cpal.numPaletteEntries = len(palette1) 143 cpal.palettes = [palette1, palette1, palette2, palette1] 144 self.assertEqual(cpal.compile(ttFont=None), CPAL_DATA_V0_SHARING_COLORS) 145 146 def test_compile_v1(self): 147 cpal = newTable("CPAL") 148 cpal.decompile(CPAL_DATA_V1, ttFont=None) 149 self.assertEqual(cpal.compile(ttFont=None), CPAL_DATA_V1) 150 151 def test_compile_v1_noLabelsNoTypes(self): 152 cpal = newTable("CPAL") 153 cpal.decompile(CPAL_DATA_V1_NOLABELS_NOTYPES, ttFont=None) 154 self.assertEqual(cpal.compile(ttFont=None), CPAL_DATA_V1_NOLABELS_NOTYPES) 155 156 def test_toXML_v0(self): 157 cpal = newTable("CPAL") 158 cpal.decompile(CPAL_DATA_V0, ttFont=None) 159 self.assertEqual( 160 getXML(cpal.toXML), 161 [ 162 '<version value="0"/>', 163 '<numPaletteEntries value="2"/>', 164 '<palette index="0">', 165 ' <color index="0" value="#000000FF"/>', 166 ' <color index="1" value="#66CCFFFF"/>', 167 "</palette>", 168 '<palette index="1">', 169 ' <color index="0" value="#000000FF"/>', 170 ' <color index="1" value="#800000FF"/>', 171 "</palette>", 172 ], 173 ) 174 175 def test_toXML_v1(self): 176 name = FakeNameTable( 177 {258: "Spring theme", 259: "Winter theme", 513: "darks", 515: "lights"} 178 ) 179 cpal = newTable("CPAL") 180 ttFont = {"name": name, "CPAL": cpal} 181 cpal.decompile(CPAL_DATA_V1, ttFont) 182 self.assertEqual( 183 getXML(cpal.toXML, ttFont), 184 [ 185 '<version value="1"/>', 186 '<numPaletteEntries value="3"/>', 187 '<palette index="0" label="258" type="1">', 188 " <!-- Spring theme -->", 189 ' <color index="0" value="#CAFECAFE"/>', 190 ' <color index="1" value="#22110033"/>', 191 ' <color index="2" value="#66554477"/>', 192 "</palette>", 193 '<palette index="1" label="259" type="2">', 194 " <!-- Winter theme -->", 195 ' <color index="0" value="#59413127"/>', 196 ' <color index="1" value="#42424242"/>', 197 ' <color index="2" value="#13330037"/>', 198 "</palette>", 199 "<paletteEntryLabels>", 200 ' <label index="0" value="513"/><!-- darks -->', 201 ' <label index="1" value="514"/>', 202 ' <label index="2" value="515"/><!-- lights -->', 203 "</paletteEntryLabels>", 204 ], 205 ) 206 207 def test_fromXML_v0(self): 208 cpal = newTable("CPAL") 209 for name, attrs, content in parseXML( 210 '<version value="0"/>' 211 '<numPaletteEntries value="2"/>' 212 '<palette index="0">' 213 ' <color index="0" value="#12345678"/>' 214 ' <color index="1" value="#FEDCBA98"/>' 215 "</palette>" 216 ): 217 cpal.fromXML(name, attrs, content, ttFont=None) 218 self.assertEqual(cpal.version, 0) 219 self.assertEqual(cpal.numPaletteEntries, 2) 220 self.assertEqual(repr(cpal.palettes), "[[#12345678, #FEDCBA98]]") 221 222 def test_fromXML_v1(self): 223 cpal = newTable("CPAL") 224 for name, attrs, content in parseXML( 225 '<version value="1"/>' 226 '<numPaletteEntries value="3"/>' 227 '<palette index="0" label="259" type="2">' 228 ' <color index="0" value="#12345678"/>' 229 ' <color index="1" value="#FEDCBA98"/>' 230 ' <color index="2" value="#CAFECAFE"/>' 231 "</palette>" 232 "<paletteEntryLabels>" 233 ' <label index="1" value="262"/>' 234 "</paletteEntryLabels>" 235 ): 236 cpal.fromXML(name, attrs, content, ttFont=None) 237 self.assertEqual(cpal.version, 1) 238 self.assertEqual(cpal.numPaletteEntries, 3) 239 self.assertEqual(repr(cpal.palettes), "[[#12345678, #FEDCBA98, #CAFECAFE]]") 240 self.assertEqual(cpal.paletteLabels, [259]) 241 self.assertEqual(cpal.paletteTypes, [2]) 242 self.assertEqual( 243 cpal.paletteEntryLabels, [cpal.NO_NAME_ID, 262, cpal.NO_NAME_ID] 244 ) 245 246 247if __name__ == "__main__": 248 import sys 249 250 sys.exit(unittest.main()) 251