def compile(self, ttFont): nPairs = len(self.kernTable) entrySelector = sfnt.maxPowerOfTwo(nPairs) searchRange = (2 ** entrySelector) * 6 rangeShift = (nPairs - (2 ** entrySelector)) * 6 data = struct.pack(">HHHH", nPairs, searchRange, entrySelector, rangeShift) # yeehee! (I mean, turn names into indices) getGlyphID = ttFont.getGlyphID kernTable = sorted((getGlyphID(left), getGlyphID(right), value) for ((left,right),value) in self.kernTable.items()) for left, right, value in kernTable: data = data + struct.pack(">HHh", left, right, value) return struct.pack(">HHH", self.version, len(data) + 6, self.coverage) + data
def compile(self, ttFont): nPairs = len(self.kernTable) entrySelector = sfnt.maxPowerOfTwo(nPairs) searchRange = (2 ** entrySelector) * 6 rangeShift = (nPairs - (2 ** entrySelector)) * 6 data = struct.pack(">HHHH", nPairs, searchRange, entrySelector, rangeShift) # yeehee! (I mean, turn names into indices) kernTable = map(lambda ((left, right), value), getGlyphID=ttFont.getGlyphID: (getGlyphID(left), getGlyphID(right), value), self.kernTable.items()) kernTable.sort() for left, right, value in kernTable: data = data + struct.pack(">HHh", left, right, value) return struct.pack(">HHH", self.version, len(data) + 6, self.coverage) + data
def compile(self, ttFont): if self.data: return struct.pack(">HHH", self.format, self.length, self.language) + self.data from fontTools.ttLib.sfnt import maxPowerOfTwo charCodes = self.cmap.keys() lenCharCodes = len(charCodes) if lenCharCodes == 0: startCode = [0xffff] endCode = [0xffff] else: charCodes.sort() names = map(operator.getitem, [self.cmap]*lenCharCodes, charCodes) nameMap = ttFont.getReverseGlyphMap() try: gids = map(operator.getitem, [nameMap]*lenCharCodes, names) except KeyError: nameMap = ttFont.getReverseGlyphMap(rebuild=1) try: gids = map(operator.getitem, [nameMap]*lenCharCodes, names) except KeyError: # allow virtual GIDs in format 4 tables gids = [] for name in names: try: gid = nameMap[name] except KeyError: try: if (name[:3] == 'gid'): gid = eval(name[3:]) else: gid = ttFont.getGlyphID(name) except: raise KeyError(name) gids.append(gid) cmap = {} # code:glyphID mapping map(operator.setitem, [cmap]*len(charCodes), charCodes, gids) # Build startCode and endCode lists. # Split the char codes in ranges of consecutive char codes, then split # each range in more ranges of consecutive/not consecutive glyph IDs. # See splitRange(). lastCode = charCodes[0] endCode = [] startCode = [lastCode] for charCode in charCodes[1:]: # skip the first code, it's the first start code if charCode == lastCode + 1: lastCode = charCode continue start, end = splitRange(startCode[-1], lastCode, cmap) startCode.extend(start) endCode.extend(end) startCode.append(charCode) lastCode = charCode endCode.append(lastCode) startCode.append(0xffff) endCode.append(0xffff) # build up rest of cruft idDelta = [] idRangeOffset = [] glyphIndexArray = [] for i in range(len(endCode)-1): # skip the closing codes (0xffff) indices = [] for charCode in range(startCode[i], endCode[i] + 1): indices.append(cmap[charCode]) if (indices == range(indices[0], indices[0] + len(indices))): idDeltaTemp = self.setIDDelta(indices[0] - startCode[i]) idDelta.append( idDeltaTemp) idRangeOffset.append(0) else: # someone *definitely* needs to get killed. idDelta.append(0) idRangeOffset.append(2 * (len(endCode) + len(glyphIndexArray) - i)) glyphIndexArray.extend(indices) idDelta.append(1) # 0xffff + 1 == (tadaa!) 0. So this end code maps to .notdef idRangeOffset.append(0) # Insane. segCount = len(endCode) segCountX2 = segCount * 2 maxExponent = maxPowerOfTwo(segCount) searchRange = 2 * (2 ** maxExponent) entrySelector = maxExponent rangeShift = 2 * segCount - searchRange charCodeArray = numpy.array( endCode + [0] + startCode, numpy.uint16) idDeltaeArray = numpy.array(idDelta, numpy.int16) restArray = numpy.array(idRangeOffset + glyphIndexArray, numpy.uint16) if sys.byteorder <> "big": charCodeArray = charCodeArray.byteswap() idDeltaeArray = idDeltaeArray.byteswap() restArray = restArray.byteswap() data = charCodeArray.tostring() + idDeltaeArray.tostring() + restArray.tostring() length = struct.calcsize(cmap_format_4_format) + len(data) header = struct.pack(cmap_format_4_format, self.format, length, self.language, segCountX2, searchRange, entrySelector, rangeShift) return header + data
def compile(self, ttFont): if self.data: return struct.pack(">HHH", self.format, self.length, self.language) + self.data from fontTools.ttLib.sfnt import maxPowerOfTwo charCodes = list(self.cmap.keys()) lenCharCodes = len(charCodes) if lenCharCodes == 0: startCode = [0xffff] endCode = [0xffff] else: charCodes.sort() names = list(map(operator.getitem, [self.cmap]*lenCharCodes, charCodes)) nameMap = ttFont.getReverseGlyphMap() try: gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) except KeyError: nameMap = ttFont.getReverseGlyphMap(rebuild=1) try: gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) except KeyError: # allow virtual GIDs in format 4 tables gids = [] for name in names: try: gid = nameMap[name] except KeyError: try: if (name[:3] == 'gid'): gid = eval(name[3:]) else: gid = ttFont.getGlyphID(name) except: raise KeyError(name) gids.append(gid) cmap = {} # code:glyphID mapping list(map(operator.setitem, [cmap]*len(charCodes), charCodes, gids)) # Build startCode and endCode lists. # Split the char codes in ranges of consecutive char codes, then split # each range in more ranges of consecutive/not consecutive glyph IDs. # See splitRange(). lastCode = charCodes[0] endCode = [] startCode = [lastCode] for charCode in charCodes[1:]: # skip the first code, it's the first start code if charCode == lastCode + 1: lastCode = charCode continue start, end = splitRange(startCode[-1], lastCode, cmap) startCode.extend(start) endCode.extend(end) startCode.append(charCode) lastCode = charCode endCode.append(lastCode) startCode.append(0xffff) endCode.append(0xffff) # build up rest of cruft idDelta = [] idRangeOffset = [] glyphIndexArray = [] for i in range(len(endCode)-1): # skip the closing codes (0xffff) indices = [] for charCode in range(startCode[i], endCode[i] + 1): indices.append(cmap[charCode]) if (indices == list(range(indices[0], indices[0] + len(indices)))): idDeltaTemp = self.setIDDelta(indices[0] - startCode[i]) idDelta.append( idDeltaTemp) idRangeOffset.append(0) else: # someone *definitely* needs to get killed. idDelta.append(0) idRangeOffset.append(2 * (len(endCode) + len(glyphIndexArray) - i)) glyphIndexArray.extend(indices) idDelta.append(1) # 0xffff + 1 == (tadaa!) 0. So this end code maps to .notdef idRangeOffset.append(0) # Insane. segCount = len(endCode) segCountX2 = segCount * 2 maxExponent = maxPowerOfTwo(segCount) searchRange = 2 * (2 ** maxExponent) entrySelector = maxExponent rangeShift = 2 * segCount - searchRange charCodeArray = numpy.array( endCode + [0] + startCode, numpy.uint16) idDeltaeArray = numpy.array(idDelta, numpy.int16) restArray = numpy.array(idRangeOffset + glyphIndexArray, numpy.uint16) if sys.byteorder != "big": charCodeArray = charCodeArray.byteswap() idDeltaeArray = idDeltaeArray.byteswap() restArray = restArray.byteswap() data = charCodeArray.tostring() + idDeltaeArray.tostring() + restArray.tostring() length = struct.calcsize(cmap_format_4_format) + len(data) header = struct.pack(cmap_format_4_format, self.format, length, self.language, segCountX2, searchRange, entrySelector, rangeShift) return header + data