1 # Copyright 2013 Google, Inc. All Rights Reserved. 2 # 3 # Google Author(s): Behdad Esfahbod 4 5 from __future__ import print_function, division, absolute_import 6 from fontTools.misc.py23 import * 7 from fontTools.misc.textTools import safeEval 8 from . import DefaultTable 9 import struct 10 11 12 class table_C_P_A_L_(DefaultTable.DefaultTable): 13 14 def decompile(self, data, ttFont): 15 self.version, self.numPaletteEntries, numPalettes, numColorRecords, goffsetFirstColorRecord = struct.unpack(">HHHHL", data[:12]) 16 assert (self.version == 0), "Version of COLR table is higher than I know how to handle" 17 self.palettes = [] 18 pos = 12 19 for i in range(numPalettes): 20 startIndex = struct.unpack(">H", data[pos:pos+2])[0] 21 assert (startIndex + self.numPaletteEntries <= numColorRecords) 22 pos += 2 23 palette = [] 24 ppos = goffsetFirstColorRecord + startIndex * 4 25 for j in range(self.numPaletteEntries): 26 palette.append( Color(*struct.unpack(">BBBB", data[ppos:ppos+4])) ) 27 ppos += 4 28 self.palettes.append(palette) 29 30 def compile(self, ttFont): 31 dataList = [struct.pack(">HHHHL", self.version, self.numPaletteEntries, len(self.palettes), self.numPaletteEntries * len(self.palettes), 12+2*len(self.palettes))] 32 for i in range(len(self.palettes)): 33 dataList.append(struct.pack(">H", i*self.numPaletteEntries)) 34 for palette in self.palettes: 35 assert(len(palette) == self.numPaletteEntries) 36 for color in palette: 37 dataList.append(struct.pack(">BBBB", color.blue,color.green,color.red,color.alpha)) 38 data = bytesjoin(dataList) 39 return data 40 41 def toXML(self, writer, ttFont): 42 writer.simpletag("version", value=self.version) 43 writer.newline() 44 writer.simpletag("numPaletteEntries", value=self.numPaletteEntries) 45 writer.newline() 46 for index, palette in enumerate(self.palettes): 47 writer.begintag("palette", index=index) 48 writer.newline() 49 assert(len(palette) == self.numPaletteEntries) 50 for cindex, color in enumerate(palette): 51 color.toXML(writer, ttFont, cindex) 52 writer.endtag("palette") 53 writer.newline() 54 55 def fromXML(self, name, attrs, content, ttFont): 56 if not hasattr(self, "palettes"): 57 self.palettes = [] 58 if name == "palette": 59 palette = [] 60 for element in content: 61 if isinstance(element, basestring): 62 continue 63 palette = [] 64 for element in content: 65 if isinstance(element, basestring): 66 continue 67 color = Color() 68 color.fromXML(element[0], element[1], element[2], ttFont) 69 palette.append (color) 70 self.palettes.append(palette) 71 elif "value" in attrs: 72 value = safeEval(attrs["value"]) 73 setattr(self, name, value) 74 75 class Color(object): 76 77 def __init__(self, blue=None, green=None, red=None, alpha=None): 78 self.blue = blue 79 self.green = green 80 self.red = red 81 self.alpha = alpha 82 83 def hex(self): 84 return "#%02X%02X%02X%02X" % (self.red, self.green, self.blue, self.alpha) 85 86 def __repr__(self): 87 return self.hex() 88 89 def toXML(self, writer, ttFont, index=None): 90 writer.simpletag("color", value=self.hex(), index=index) 91 writer.newline() 92 93 def fromXML(self, eltname, attrs, content, ttFont): 94 value = attrs["value"] 95 if value[0] == '#': 96 value = value[1:] 97 self.red = int(value[0:2], 16) 98 self.green = int(value[2:4], 16) 99 self.blue = int(value[4:6], 16) 100 self.alpha = int(value[6:8], 16) if len (value) >= 8 else 0xFF 101