19d7dc222990efdab0681ce7c519ef3a73d3fd718Behdad Esfahbod# Copyright 2013 Google, Inc. All Rights Reserved. 29d7dc222990efdab0681ce7c519ef3a73d3fd718Behdad Esfahbod# 39d7dc222990efdab0681ce7c519ef3a73d3fd718Behdad Esfahbod# Google Author(s): Behdad Esfahbod 49d7dc222990efdab0681ce7c519ef3a73d3fd718Behdad Esfahbod 51ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import 630e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import * 730e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.textTools import safeEval 82b06aaa2a6bcd363c25fb0c43f6bb906906594bdBehdad Esfahbodfrom . import DefaultTable 950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbodimport struct 1050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 1150d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 1250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbodclass table_C_P_A_L_(DefaultTable.DefaultTable): 1350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 1450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod def decompile(self, data, ttFont): 1550d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.version, self.numPaletteEntries, numPalettes, numColorRecords, goffsetFirstColorRecord = struct.unpack(">HHHHL", data[:12]) 1650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod assert (self.version == 0), "Version of COLR table is higher than I know how to handle" 1750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.palettes = [] 1850d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod pos = 12 1950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for i in range(numPalettes): 2050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod startIndex = struct.unpack(">H", data[pos:pos+2])[0] 2150d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod assert (startIndex + self.numPaletteEntries <= numColorRecords) 2250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod pos += 2 2350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod palette = [] 2450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod ppos = goffsetFirstColorRecord + startIndex * 4 2550d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for j in range(self.numPaletteEntries): 2650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod palette.append( Color(*struct.unpack(">BBBB", data[ppos:ppos+4])) ) 2750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod ppos += 4 2850d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.palettes.append(palette) 2950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 3050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod def compile(self, ttFont): 3150d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod dataList = [struct.pack(">HHHHL", self.version, self.numPaletteEntries, len(self.palettes), self.numPaletteEntries * len(self.palettes), 12+2*len(self.palettes))] 3250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for i in range(len(self.palettes)): 3350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod dataList.append(struct.pack(">H", i*self.numPaletteEntries)) 3450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for palette in self.palettes: 3550d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod assert(len(palette) == self.numPaletteEntries) 3650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for color in palette: 3750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod dataList.append(struct.pack(">BBBB", color.blue,color.green,color.red,color.alpha)) 3818316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod data = bytesjoin(dataList) 3950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod return data 4050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 4150d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod def toXML(self, writer, ttFont): 4250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.simpletag("version", value=self.version) 4350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.newline() 4450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.simpletag("numPaletteEntries", value=self.numPaletteEntries) 4550d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.newline() 4650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for index, palette in enumerate(self.palettes): 4750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.begintag("palette", index=index) 4850d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.newline() 4950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod assert(len(palette) == self.numPaletteEntries) 5050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for cindex, color in enumerate(palette): 5150d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod color.toXML(writer, ttFont, cindex) 5250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.endtag("palette") 5350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.newline() 5450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 553a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content, ttFont): 5650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod if not hasattr(self, "palettes"): 5750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.palettes = [] 5850d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod if name == "palette": 5950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod palette = [] 6050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for element in content: 61faaca764a1cd62d376f783df20cd1edce21ca816Behdad Esfahbod if isinstance(element, basestring): 6250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod continue 6350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod palette = [] 6450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod for element in content: 65faaca764a1cd62d376f783df20cd1edce21ca816Behdad Esfahbod if isinstance(element, basestring): 6650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod continue 6750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod color = Color() 683a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod color.fromXML(element[0], element[1], element[2], ttFont) 6950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod palette.append (color) 7050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.palettes.append(palette) 71bc5e1cb195c0bfa1c8e7507326d5a9ad05aecb4bBehdad Esfahbod elif "value" in attrs: 7250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod value = safeEval(attrs["value"]) 7350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod setattr(self, name, value) 7450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 75e388db566b9ba42669c7e353db4293cf27bc2a5bBehdad Esfahbodclass Color(object): 7650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 7750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod def __init__(self, blue=None, green=None, red=None, alpha=None): 7850d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.blue = blue 7950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.green = green 8050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.red = red 8150d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.alpha = alpha 8250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 8350d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod def hex(self): 8450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod return "#%02X%02X%02X%02X" % (self.red, self.green, self.blue, self.alpha) 8550d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 8650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod def __repr__(self): 8750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod return self.hex() 8850d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 8950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod def toXML(self, writer, ttFont, index=None): 9050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.simpletag("color", value=self.hex(), index=index) 9150d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod writer.newline() 9250d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod 933a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, eltname, attrs, content, ttFont): 9450d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod value = attrs["value"] 9550d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod if value[0] == '#': 9650d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod value = value[1:] 9750d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.red = int(value[0:2], 16) 9850d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.green = int(value[2:4], 16) 9950d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.blue = int(value[4:6], 16) 10050d9a44e5887e303480af571cca8b69cd82c3173Behdad Esfahbod self.alpha = int(value[6:8], 16) if len (value) >= 8 else 0xFF 101