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