def compile(self, ttFont):
     keys = sorted(self.data.keys())
     headerSize = sstruct.calcsize(META_HEADER_FORMAT)
     dataOffset = headerSize + len(keys) * sstruct.calcsize(DATA_MAP_FORMAT)
     header = sstruct.pack(META_HEADER_FORMAT, {
             "version": 1,
             "flags": 0,
             "dataOffset": dataOffset,
             "numDataMaps": len(keys)
     })
     dataMaps = []
     dataBlocks = []
     for tag in keys:
         if tag in ["dlng", "slng"]:
             data = self.data[tag].encode("utf-8")
         else:
             data = self.data[tag]
         dataMaps.append(sstruct.pack(DATA_MAP_FORMAT, {
             "tag": tag,
             "dataOffset": dataOffset,
             "dataLength": len(data)
         }))
         dataBlocks.append(data)
         dataOffset += len(data)
     return bytesjoin([header] + dataMaps + dataBlocks)
Ejemplo n.º 2
0
	def compile(self, ttFont):
		self.updateFirstAndLastCharIndex(ttFont)
		panose = self.panose
		head = ttFont["head"]
		if (self.fsSelection & 1) and not (head.macStyle & 1<<1):
			log.warning("fsSelection bit 0 (italic) and "
				"head table macStyle bit 1 (italic) should match")
		if (self.fsSelection & 1<<5) and not (head.macStyle & 1):
			log.warning("fsSelection bit 5 (bold) and "
				"head table macStyle bit 0 (bold) should match")
		if (self.fsSelection & 1<<6) and (self.fsSelection & 1 + (1<<5)):
			log.warning("fsSelection bit 6 (regular) is set, "
				"bits 0 (italic) and 5 (bold) must be clear")
		if self.version < 4 and self.fsSelection & 0b1110000000:
			log.warning("fsSelection bits 7, 8 and 9 are only defined in "
				"OS/2 table version 4 and up: version %s", self.version)
		self.panose = sstruct.pack(panoseFormat, self.panose)
		if self.version == 0:
			data = sstruct.pack(OS2_format_0, self)
		elif self.version == 1:
			data = sstruct.pack(OS2_format_1, self)
		elif self.version in (2, 3, 4):
			data = sstruct.pack(OS2_format_2, self)
		elif self.version == 5:
			d = self.__dict__.copy()
			d['usLowerOpticalPointSize'] = round(self.usLowerOpticalPointSize * 20)
			d['usUpperOpticalPointSize'] = round(self.usUpperOpticalPointSize * 20)
			data = sstruct.pack(OS2_format_5, d)
		else:
			from fontemon_blender_addon.fontTools import ttLib
			raise ttLib.TTLibError("unknown format for OS/2 table: version %s" % self.version)
		self.panose = panose
		return data
Ejemplo n.º 3
0
	def compile(self, ttFont):
		self.glyphDataOffsets = b""
		self.bitmapData = b""

		glyphOrder = ttFont.getGlyphOrder()

		# first glyph starts right after the header
		currentGlyphDataOffset = sbixStrikeHeaderFormatSize + sbixGlyphDataOffsetFormatSize * (len(glyphOrder) + 1)
		for glyphName in glyphOrder:
			if glyphName in self.glyphs:
				# we have glyph data for this glyph
				current_glyph = self.glyphs[glyphName]
			else:
				# must add empty glyph data record for this glyph
				current_glyph = Glyph(glyphName=glyphName)
			current_glyph.compile(ttFont)
			current_glyph.glyphDataOffset = currentGlyphDataOffset
			self.bitmapData += current_glyph.rawdata
			currentGlyphDataOffset += len(current_glyph.rawdata)
			self.glyphDataOffsets += sstruct.pack(sbixGlyphDataOffsetFormat, current_glyph)

		# add last "offset", really the end address of the last glyph data record
		dummy = Glyph()
		dummy.glyphDataOffset = currentGlyphDataOffset
		self.glyphDataOffsets += sstruct.pack(sbixGlyphDataOffsetFormat, dummy)

		# pack header
		self.data = sstruct.pack(sbixStrikeHeaderFormat, self)
		# add offsets and image data after header
		self.data += self.glyphDataOffsets + self.bitmapData
 def compile(self, ttFont):
     dataList = []
     dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
     dataList.append(struct.pack(">H", len(self.componentArray)))
     for curComponent in self.componentArray:
         curComponent.glyphCode = ttFont.getGlyphID(curComponent.name)
         dataList.append(sstruct.pack(ebdtComponentFormat, curComponent))
     return bytesjoin(dataList)
Ejemplo n.º 5
0
 def compileAttributes3(self, attrs):
     if self.hasOctaboxes:
         o = attrs.octabox
         data = sstruct.pack(Glat_format_3_octabox_metrics, o)
         numsub = bin(o.subboxBitmap).count("1")
         for b in range(numsub):
             data += sstruct.pack(Glat_format_3_subbox_entry, o.subboxes[b])
     else:
         data = ""
     return data + self.compileAttributes12(attrs, Glat_format_23_entry)
 def compile(self, ttFont):
     if 'glyf' in ttFont:
         if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
             self.recalc(ttFont)
     else:
         pass  # CFF
     self.numGlyphs = len(ttFont.getGlyphOrder())
     if self.tableVersion != 0x00005000:
         self.tableVersion = 0x00010000
     data = sstruct.pack(maxpFormat_0_5, self)
     if self.tableVersion == 0x00010000:
         data = data + sstruct.pack(maxpFormat_1_0_add, self)
     return data
 def compile(self, ttFont):
     if ttFont.recalcBBoxes:
         # For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc().
         if 'CFF ' in ttFont:
             topDict = ttFont['CFF '].cff.topDictIndex[0]
             self.xMin, self.yMin, self.xMax, self.yMax = intRect(
                 topDict.FontBBox)
         elif 'CFF2' in ttFont:
             topDict = ttFont['CFF2'].cff.topDictIndex[0]
             charStrings = topDict.CharStrings
             fontBBox = None
             for charString in charStrings.values():
                 bounds = charString.calcBounds(charStrings)
                 if bounds is not None:
                     if fontBBox is not None:
                         fontBBox = unionRect(fontBBox, bounds)
                     else:
                         fontBBox = bounds
             if fontBBox is not None:
                 self.xMin, self.yMin, self.xMax, self.yMax = intRect(
                     fontBBox)
     if ttFont.recalcTimestamp:
         self.modified = timestampNow()
     data = sstruct.pack(headFormat, self)
     return data
Ejemplo n.º 8
0
	def _calcMasterChecksum(self, directory):
		# calculate checkSumAdjustment
		tags = list(self.tables.keys())
		checksums = []
		for i in range(len(tags)):
			checksums.append(self.tables[tags[i]].checkSum)

		if self.DirectoryEntry != SFNTDirectoryEntry:
			# Create a SFNT directory for checksum calculation purposes
			from fontemon_blender_addon.fontTools.ttLib import getSearchRange
			self.searchRange, self.entrySelector, self.rangeShift = getSearchRange(self.numTables, 16)
			directory = sstruct.pack(sfntDirectoryFormat, self)
			tables = sorted(self.tables.items())
			for tag, entry in tables:
				sfntEntry = SFNTDirectoryEntry()
				sfntEntry.tag = entry.tag
				sfntEntry.checkSum = entry.checkSum
				sfntEntry.offset = entry.origOffset
				sfntEntry.length = entry.origLength
				directory = directory + sfntEntry.toString()

		directory_end = sfntDirectorySize + len(self.tables) * sfntDirectoryEntrySize
		assert directory_end == len(directory)

		checksums.append(calcChecksum(directory))
		checksum = sum(checksums) & 0xffffffff
		# BiboAfba!
		checksumadjustment = (0xB1B0AFBA - checksum) & 0xffffffff
		return checksumadjustment
Ejemplo n.º 9
0
    def compile(self, ttFont):
        axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
        sharedTuples = tv.compileSharedTuples(
            axisTags, itertools.chain(*self.variations.values()))
        sharedTupleIndices = {coord: i for i, coord in enumerate(sharedTuples)}
        sharedTupleSize = sum([len(c) for c in sharedTuples])
        compiledGlyphs = self.compileGlyphs_(ttFont, axisTags,
                                             sharedTupleIndices)
        offset = 0
        offsets = []
        for glyph in compiledGlyphs:
            offsets.append(offset)
            offset += len(glyph)
        offsets.append(offset)
        compiledOffsets, tableFormat = self.compileOffsets_(offsets)

        header = {}
        header["version"] = self.version
        header["reserved"] = self.reserved
        header["axisCount"] = len(axisTags)
        header["sharedTupleCount"] = len(sharedTuples)
        header["offsetToSharedTuples"] = GVAR_HEADER_SIZE + len(
            compiledOffsets)
        header["glyphCount"] = len(compiledGlyphs)
        header["flags"] = tableFormat
        header["offsetToGlyphVariationData"] = header[
            "offsetToSharedTuples"] + sharedTupleSize
        compiledHeader = sstruct.pack(GVAR_HEADER_FORMAT, header)

        result = [compiledHeader, compiledOffsets]
        result.extend(sharedTuples)
        result.extend(compiledGlyphs)
        return bytesjoin(result)
Ejemplo n.º 10
0
 def compile(self, ttFont):
     fdat = b""
     vdat = b""
     offset = 0
     for f, v in sorted(self.features.items(), key=lambda x: x[1].index):
         fnum = grUtils.tag2num(f)
         if self.version >= 2.0:
             fdat += struct.pack(">LHHLHH", grUtils.tag2num(f),
                                 len(v.settings), 0,
                                 offset * 4 + 12 + 16 * len(self.features),
                                 v.flags, v.label)
         elif fnum > 65535:  # self healing for alphabetic ids
             self.version = 2.0
             return self.compile(ttFont)
         else:
             fdat += struct.pack(">HHLHH", grUtils.tag2num(f),
                                 len(v.settings),
                                 offset * 4 + 12 + 12 * len(self.features),
                                 v.flags, v.label)
         for s, l in sorted(v.settings.items(),
                            key=lambda x: (-1, x[1])
                            if x[0] == v.default else x):
             vdat += struct.pack(">HH", s, l)
         offset += len(v.settings)
     hdr = sstruct.pack(Feat_hdr_format, self)
     return hdr + struct.pack('>HHL', len(self.features), 0,
                              0) + fdat + vdat
Ejemplo n.º 11
0
    def compile(self, ttFont):
        self.numGMAPs = len(self.GMAPs)
        self.numGlyplets = len(self.glyphlets)
        GMAPoffsets = [0] * (self.numGMAPs + 1)
        glyphletOffsets = [0] * (self.numGlyplets + 1)

        dataList = [sstruct.pack(GPKGFormat, self)]

        pos = len(
            dataList[0]) + (self.numGMAPs + 1) * 4 + (self.numGlyplets + 1) * 4
        GMAPoffsets[0] = pos
        for i in range(1, self.numGMAPs + 1):
            pos += len(self.GMAPs[i - 1])
            GMAPoffsets[i] = pos
        gmapArray = array.array("I", GMAPoffsets)
        if sys.byteorder != "big": gmapArray.byteswap()
        dataList.append(gmapArray.tobytes())

        glyphletOffsets[0] = pos
        for i in range(1, self.numGlyplets + 1):
            pos += len(self.glyphlets[i - 1])
            glyphletOffsets[i] = pos
        glyphletArray = array.array("I", glyphletOffsets)
        if sys.byteorder != "big": glyphletArray.byteswap()
        dataList.append(glyphletArray.tobytes())
        dataList += self.GMAPs
        dataList += self.glyphlets
        data = bytesjoin(dataList)
        return data
Ejemplo n.º 12
0
    def compile(self, ttFont, version=2.0):
        self.numPasses = len(self.passes)
        self.numJLevels = len(self.jLevels)
        self.numCritFeatures = len(self.critFeatures)
        numPseudo = len(self.pMap)
        data = b""
        if version >= 3.0:
            hdroffset = sstruct.calcsize(Silf_part1_format_v3)
        else:
            hdroffset = 0
        data += sstruct.pack(Silf_part1_format, self)
        for j in self.jLevels:
            data += sstruct.pack(Silf_justify_format, j)
        data += sstruct.pack(Silf_part2_format, self)
        if self.numCritFeatures:
            data += struct.pack((">%dH" % self.numCritFeaturs),
                                *self.critFeatures)
        data += struct.pack("BB", 0, len(self.scriptTags))
        if len(self.scriptTags):
            tdata = [
                struct.pack("4s", x.encode("ascii")) for x in self.scriptTags
            ]
            data += b"".join(tdata)
        data += struct.pack(">H", self.lbGID)
        self.passOffset = len(data)

        data1 = grUtils.bininfo(numPseudo, 6)
        currpos = hdroffset + len(data) + 4 * (self.numPasses + 1)
        self.pseudosOffset = currpos + len(data1)
        for u, p in sorted(self.pMap.items()):
            data1 += struct.pack((">LH" if version >= 3.0 else ">HH"), u,
                                 ttFont.getGlyphID(p))
        data1 += self.classes.compile(ttFont, version)
        currpos += len(data1)
        data2 = b""
        datao = b""
        for i, p in enumerate(self.passes):
            base = currpos + len(data2)
            datao += struct.pack(">L", base)
            data2 += p.compile(ttFont, base, version)
        datao += struct.pack(">L", currpos + len(data2))

        if version >= 3.0:
            data3 = sstruct.pack(Silf_part1_format_v3, self)
        else:
            data3 = b""
        return data3 + data + datao + data1 + data2
Ejemplo n.º 13
0
	def compile(self, ttFont):
		if 	self.UV is None:
			self.UV = 0
		nameLen = len(self.name)
		if nameLen < 32:
			self.name = self.name + "\0"*(32 - nameLen)
		data = sstruct.pack(GMAPRecordFormat1, self)
		return data
Ejemplo n.º 14
0
 def compile(self, axisTags, includePostScriptName):
     result = [sstruct.pack(FVAR_INSTANCE_FORMAT, self)]
     for axis in axisTags:
         fixedCoord = fl2fi(self.coordinates[axis], 16)
         result.append(struct.pack(">l", fixedCoord))
     if includePostScriptName:
         result.append(struct.pack(">H", self.postscriptNameID))
     return bytesjoin(result)
Ejemplo n.º 15
0
 def compile(self, ttFont):
     self.numSilf = len(self.silfs)
     if self.version < 3.0:
         hdr = sstruct.pack(Silf_hdr_format, self)
         hdr += struct.pack(">HH", self.numSilf, 0)
     else:
         hdr = sstruct.pack(Silf_hdr_format_3, self)
     offset = len(hdr) + 4 * self.numSilf
     data = b""
     for s in self.silfs:
         hdr += struct.pack(">L", offset)
         subdata = s.compile(ttFont, self.version)
         offset += len(subdata)
         data += subdata
     if self.version >= 5.0:
         return grUtils.compress(self.scheme, hdr + data)
     return hdr + data
Ejemplo n.º 16
0
 def compile(self, ttFont):
     if ttFont.recalcBBoxes and (ttFont.isLoaded('glyf')
                                 or ttFont.isLoaded('CFF ')
                                 or ttFont.isLoaded('CFF2')):
         # LFDS modified
         pass
         # self.recalc(ttFont)
     self.tableVersion = fi2ve(self.tableVersion)
     return sstruct.pack(hheaFormat, self)
Ejemplo n.º 17
0
	def compile(self, ttFont):
		sbixData = b""
		self.numStrikes = len(self.strikes)
		sbixHeader = sstruct.pack(sbixHeaderFormat, self)

		# calculate offset to start of first strike
		setOffset = sbixHeaderFormatSize + sbixStrikeOffsetFormatSize * self.numStrikes

		for si in sorted(self.strikes.keys()):
			current_strike = self.strikes[si]
			current_strike.compile(ttFont)
			# append offset to this strike to table header
			current_strike.strikeOffset = setOffset
			sbixHeader += sstruct.pack(sbixStrikeOffsetFormat, current_strike)
			setOffset += len(current_strike.data)
			sbixData += current_strike.data

		return sbixHeader + sbixData
Ejemplo n.º 18
0
	def compile(self, ttFont):
		self.recordsCount = len(self.gmapRecords)
		self.fontNameLength = len(self.psFontName)
		self.recordsOffset = 4 * (((self.fontNameLength + 12) + 3) // 4)
		data = sstruct.pack(GMAPFormat, self)
		data = data + tobytes(self.psFontName)
		data = data + b"\0" * (self.recordsOffset - len(data))
		for record in self.gmapRecords:
			data = data + record.compile(ttFont)
		return data
Ejemplo n.º 19
0
def writeTTCHeader(file, numFonts):
	self = SimpleNamespace()
	self.TTCTag = 'ttcf'
	self.Version = 0x00010000
	self.numFonts = numFonts
	file.seek(0)
	file.write(sstruct.pack(ttcHeaderFormat, self))
	offset = file.tell()
	file.write(struct.pack(">%dL" % self.numFonts, *([0] * self.numFonts)))
	return offset
Ejemplo n.º 20
0
 def compile(self, ttFont):
     self.imageDataOffset = min(next(iter(zip(*self.locations))))
     dataList = [EblcIndexSubTable.compile(self, ttFont)]
     dataList.append(struct.pack(">L", self.imageSize))
     dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
     glyphIds = list(map(ttFont.getGlyphID, self.names))
     dataList.append(struct.pack(">L", len(glyphIds)))
     dataList += [struct.pack(">H", curId) for curId in glyphIds]
     if len(glyphIds) % 2 == 1:
         dataList.append(struct.pack(">H", 0))
     return bytesjoin(dataList)
Ejemplo n.º 21
0
    def compile(self, ttFont):
        glyphIds = list(map(ttFont.getGlyphID, self.names))
        # Make sure all the ids are consecutive. This is required by Format 2.
        assert glyphIds == list(
            range(self.firstGlyphIndex, self.lastGlyphIndex +
                  1)), "Format 2 ids must be consecutive."
        self.imageDataOffset = min(next(iter(zip(*self.locations))))

        dataList = [EblcIndexSubTable.compile(self, ttFont)]
        dataList.append(struct.pack(">L", self.imageSize))
        dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
        return bytesjoin(dataList)
Ejemplo n.º 22
0
 def compile(self, ttFont):
     if not (self.version == 0 or self.version == 1):
         from fontemon_blender_addon.fontTools import ttLib
         raise ttLib.TTLibError(
             "unknown format for VDMX table: version %s" % self.version)
     data = sstruct.pack(VDMX_HeaderFmt, self)
     for ratio in self.ratRanges:
         data += sstruct.pack(VDMX_RatRangeFmt, ratio)
     # recalculate offsets to VDMX groups
     for offset in self._getOffsets():
         data += struct.pack('>H', offset)
     for group in self.groups:
         recs = len(group)
         startsz = min(group.keys())
         endsz = max(group.keys())
         gHeader = {'recs': recs, 'startsz': startsz, 'endsz': endsz}
         data += sstruct.pack(VDMX_GroupFmt, gHeader)
         for yPelHeight, (yMax, yMin) in sorted(group.items()):
             vTable = {'yPelHeight': yPelHeight, 'yMax': yMax, 'yMin': yMin}
             data += sstruct.pack(VDMX_vTableFmt, vTable)
     return data
Ejemplo n.º 23
0
 def compile(self, ttFont):
     if self.glyphName is None:
         from fontemon_blender_addon.fontTools import ttLib
         raise ttLib.TTLibError("Can't compile Glyph without glyph name")
         # TODO: if ttFont has no maxp, cmap etc., ignore glyph names and compile by index?
         # (needed if you just want to compile the sbix table on its own)
     self.gid = struct.pack(">H", ttFont.getGlyphID(self.glyphName))
     if self.graphicType is None:
         self.rawdata = b""
     else:
         self.rawdata = sstruct.pack(sbixGlyphHeaderFormat,
                                     self) + self.imageData
Ejemplo n.º 24
0
 def compile(self, ttFont):
     d = self.__dict__.copy()
     d["nameLength"] = bytechr(len(self.baseGlyphName))
     d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28)
     METAMD5List = eval(self.METAMD5)
     d["METAMD5"] = b""
     for val in METAMD5List:
         d["METAMD5"] += bytechr(val)
     assert (len(d["METAMD5"]) == 16
             ), "Failed to pack 16 byte MD5 hash in SING table"
     data = sstruct.pack(SINGFormat, d)
     data = data + tobytes(self.baseGlyphName)
     return data
Ejemplo n.º 25
0
 def compile(self, ttFont):
     packed = sstruct.pack(DSIG_HeaderFormat, self)
     headers = [packed]
     offset = len(
         packed) + self.usNumSigs * sstruct.calcsize(DSIG_SignatureFormat)
     data = []
     for sigrec in self.signatureRecords:
         # first pack signature block
         sigrec.cbSignature = len(sigrec.pkcs7)
         packed = sstruct.pack(DSIG_SignatureBlockFormat,
                               sigrec) + sigrec.pkcs7
         data.append(packed)
         # update redundant length field
         sigrec.ulLength = len(packed)
         # update running table offset
         sigrec.ulOffset = offset
         headers.append(sstruct.pack(DSIG_SignatureFormat, sigrec))
         offset += sigrec.ulLength
     if offset % 2:
         # Pad to even bytes
         data.append(b'\0')
     return bytesjoin(headers + data)
Ejemplo n.º 26
0
 def compile(self, ttFont):
     ldat = b""
     fdat = b""
     offset = len(self.langs)
     for c, inf in sorted(self.langs.items()):
         ldat += struct.pack(">4sHH", c.encode('utf8'), len(inf),
                             8 * offset + 20)
         for fid, val in inf:
             fdat += struct.pack(">LHH", fid, val, 0)
         offset += len(inf)
     ldat += struct.pack(">LHH", 0x80808080, 0, 8 * offset + 20)
     return sstruct.pack(Sill_hdr, self) + grUtils.bininfo(len(self.langs)) + \
             ldat + fdat
Ejemplo n.º 27
0
 def compile(self, ttFont, base, version=2.0):
     # build it all up backwards
     oActions = reduce(lambda a, x: (a[0] + len(x), a[1] + [a[0]]),
                       self.actions + [b""], (0, []))[1]
     oConstraints = reduce(lambda a, x: (a[0] + len(x), a[1] + [a[0]]),
                           self.ruleConstraints + [b""], (1, []))[1]
     constraintCode = b"\000" + b"".join(self.ruleConstraints)
     transes = []
     for t in self.stateTrans:
         if sys.byteorder != "big": t.byteswap()
         transes.append(t.tobytes())
         if sys.byteorder != "big": t.byteswap()
     if not len(transes):
         self.startStates = [0]
     oRuleMap = reduce(lambda a, x: (a[0] + len(x), a[1] + [a[0]]),
                       self.rules + [[]], (0, []))[1]
     passRanges = []
     gidcolmap = dict([(ttFont.getGlyphID(x[0]), x[1])
                       for x in self.colMap.items()])
     for e in grUtils.entries(gidcolmap, sameval=True):
         if e[1]:
             passRanges.append((e[0], e[0] + e[1] - 1, e[2][0]))
     self.numRules = len(self.actions)
     self.fsmOffset = (sstruct.calcsize(Silf_pass_format) + 8 +
                       len(passRanges) * 6 + len(oRuleMap) * 2 +
                       2 * oRuleMap[-1] + 2 + 2 * len(self.startStates) +
                       3 * self.numRules + 3 + 4 * self.numRules + 4)
     self.pcCode = self.fsmOffset + 2 * self.numTransitional * self.numColumns + 1 + base
     self.rcCode = self.pcCode + len(self.passConstraints)
     self.aCode = self.rcCode + len(constraintCode)
     self.oDebug = 0
     # now generate output
     data = sstruct.pack(Silf_pass_format, self)
     data += grUtils.bininfo(len(passRanges), 6)
     data += b"".join(struct.pack(">3H", *p) for p in passRanges)
     data += struct.pack((">%dH" % len(oRuleMap)), *oRuleMap)
     flatrules = reduce(lambda a, x: a + x, self.rules, [])
     data += struct.pack((">%dH" % oRuleMap[-1]), *flatrules)
     data += struct.pack("BB", self.minRulePreContext,
                         self.maxRulePreContext)
     data += struct.pack((">%dH" % len(self.startStates)),
                         *self.startStates)
     data += struct.pack((">%dH" % self.numRules), *self.ruleSortKeys)
     data += struct.pack(("%dB" % self.numRules), *self.rulePreContexts)
     data += struct.pack(">BH", self.collisionThreshold,
                         len(self.passConstraints))
     data += struct.pack((">%dH" % (self.numRules + 1)), *oConstraints)
     data += struct.pack((">%dH" % (self.numRules + 1)), *oActions)
     return data + b"".join(transes) + struct.pack("B", 0) + \
             self.passConstraints + constraintCode + b"".join(self.actions)
Ejemplo n.º 28
0
    def compile(self, ttFont):

        dataList = []
        dataList.append(sstruct.pack(ebdtTableVersionFormat, self))
        dataSize = len(dataList[0])

        # Keep a dict of glyphs that have been seen so they aren't remade.
        # This dict maps the id of the BitmapGlyph to the interval
        # in the data.
        glyphDict = {}

        # Go through the bitmap glyph data. Just in case the data for a glyph
        # changed the size metrics should be recalculated. There are a variety
        # of formats and they get stored in the EBLC table. That is why
        # recalculation is defered to the EblcIndexSubTable class and just
        # pass what is known about bitmap glyphs from this particular table.
        locator = ttFont[self.__class__.locatorName]
        for curStrike, curGlyphDict in zip(locator.strikes, self.strikeData):
            for curIndexSubTable in curStrike.indexSubTables:
                dataLocations = []
                for curName in curIndexSubTable.names:
                    # Handle the data placement based on seeing the glyph or not.
                    # Just save a reference to the location if the glyph has already
                    # been saved in compile. This code assumes that glyphs will only
                    # be referenced multiple times from indexFormat5. By luck the
                    # code may still work when referencing poorly ordered fonts with
                    # duplicate references. If there is a font that is unlucky the
                    # respective compile methods for the indexSubTables will fail
                    # their assertions. All fonts seem to follow this assumption.
                    # More complicated packing may be needed if a counter-font exists.
                    glyph = curGlyphDict[curName]
                    objectId = id(glyph)
                    if objectId not in glyphDict:
                        data = glyph.compile(ttFont)
                        data = curIndexSubTable.padBitmapData(data)
                        startByte = dataSize
                        dataSize += len(data)
                        endByte = dataSize
                        dataList.append(data)
                        dataLoc = (startByte, endByte)
                        glyphDict[objectId] = dataLoc
                    else:
                        dataLoc = glyphDict[objectId]
                    dataLocations.append(dataLoc)
                # Just use the new data locations in the indexSubTable.
                # The respective compile implementations will take care
                # of any of the problems in the convertion that may arise.
                curIndexSubTable.locations = dataLocations

        return bytesjoin(dataList)
Ejemplo n.º 29
0
    def compile(self, ttFont):
        data = sstruct.pack(Glat_format_0, self)
        if self.version <= 1.9:
            encoder = partial(self.compileAttributes12,
                              fmt=Glat_format_1_entry)
        elif self.version <= 2.9:
            encoder = partial(self.compileAttributes12,
                              fmt=Glat_format_1_entry)
        elif self.version >= 3.0:
            self.compression = (self.scheme << 27) + (1 if self.hasOctaboxes
                                                      else 0)
            data = sstruct.pack(Glat_format_3, self)
            encoder = self.compileAttributes3

        glocs = []
        for n in range(len(self.attributes)):
            glocs.append(len(data))
            data += encoder(self.attributes[ttFont.getGlyphName(n)])
        glocs.append(len(data))
        ttFont['Gloc'].set(glocs)

        if self.version >= 3.0:
            data = grUtils.compress(self.scheme, data)
        return data
Ejemplo n.º 30
0
 def compile(self, ttFont, useSharedPoints=False):
     tupleVariationCount, tuples, data = compileTupleVariationStore(
         variations=[v for v in self.variations if v.hasImpact()],
         pointCount=len(ttFont["cvt "].values),
         axisTags=[axis.axisTag for axis in ttFont["fvar"].axes],
         sharedTupleIndices={},
         useSharedPoints=useSharedPoints)
     header = {
         "majorVersion": self.majorVersion,
         "minorVersion": self.minorVersion,
         "tupleVariationCount": tupleVariationCount,
         "offsetToData": CVAR_HEADER_SIZE + len(tuples),
     }
     return bytesjoin(
         [sstruct.pack(CVAR_HEADER_FORMAT, header), tuples, data])