Exemplo n.º 1
0
	def decompile(self, data, ttFont):
		# read table header
		sstruct.unpack(sbixHeaderFormat, data[ : sbixHeaderFormatSize], self)
		# collect offsets to individual strikes in self.strikeOffsets
		for i in range(self.numStrikes):
			current_offset = sbixHeaderFormatSize + i * sbixStrikeOffsetFormatSize
			offset_entry = sbixStrikeOffset()
			sstruct.unpack(sbixStrikeOffsetFormat, \
				data[current_offset:current_offset+sbixStrikeOffsetFormatSize], \
				offset_entry)
			self.strikeOffsets.append(offset_entry.strikeOffset)

		# decompile Strikes
		for i in range(self.numStrikes-1, -1, -1):
			current_strike = Strike(rawdata=data[self.strikeOffsets[i]:])
			data = data[:self.strikeOffsets[i]]
			current_strike.decompile(ttFont)
			#print "  Strike length: %xh" % len(bitmapSetData)
			#print "Number of Glyph entries:", len(current_strike.glyphs)
			if current_strike.ppem in self.strikes:
				from fontemon_blender_addon.fontTools import ttLib
				raise ttLib.TTLibError("Pixel 'ppem' must be unique for each Strike")
			self.strikes[current_strike.ppem] = current_strike

		# after the glyph data records have been extracted, we don't need the offsets anymore
		del self.strikeOffsets
		del self.numStrikes
Exemplo n.º 2
0
	def decompile(self, ttFont):
		if self.data is None:
			from fontemon_blender_addon.fontTools import ttLib
			raise ttLib.TTLibError
		if len(self.data) < sbixStrikeHeaderFormatSize:
			from fontemon_blender_addon.fontTools import ttLib
			raise(ttLib.TTLibError, "Strike header too short: Expected %x, got %x.") \
				% (sbixStrikeHeaderFormatSize, len(self.data))

		# read Strike header from raw data
		sstruct.unpack(sbixStrikeHeaderFormat, self.data[:sbixStrikeHeaderFormatSize], self)

		# calculate number of glyphs
		firstGlyphDataOffset, = struct.unpack(">L", \
			self.data[sbixStrikeHeaderFormatSize:sbixStrikeHeaderFormatSize + sbixGlyphDataOffsetFormatSize])
		self.numGlyphs = (firstGlyphDataOffset - sbixStrikeHeaderFormatSize) // sbixGlyphDataOffsetFormatSize - 1
		# ^ -1 because there's one more offset than glyphs

		# build offset list for single glyph data offsets
		self.glyphDataOffsets = []
		for i in range(self.numGlyphs + 1): # + 1 because there's one more offset than glyphs
			start = i * sbixGlyphDataOffsetFormatSize + sbixStrikeHeaderFormatSize
			current_offset, = struct.unpack(">L", self.data[start:start + sbixGlyphDataOffsetFormatSize])
			self.glyphDataOffsets.append(current_offset)

		# iterate through offset list and slice raw data into glyph data records
		for i in range(self.numGlyphs):
			current_glyph = Glyph(rawdata=self.data[self.glyphDataOffsets[i]:self.glyphDataOffsets[i+1]], gid=i)
			current_glyph.decompile(ttFont)
			self.glyphs[current_glyph.glyphName] = current_glyph
		del self.glyphDataOffsets
		del self.numGlyphs
		del self.data
Exemplo n.º 3
0
 def decompile(self, data, ttFont):
     axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
     glyphs = ttFont.getGlyphOrder()
     sstruct.unpack(GVAR_HEADER_FORMAT, data[0:GVAR_HEADER_SIZE], self)
     assert len(glyphs) == self.glyphCount
     assert len(axisTags) == self.axisCount
     offsets = self.decompileOffsets_(data[GVAR_HEADER_SIZE:],
                                      tableFormat=(self.flags & 1),
                                      glyphCount=self.glyphCount)
     sharedCoords = tv.decompileSharedTuples(axisTags,
                                             self.sharedTupleCount, data,
                                             self.offsetToSharedTuples)
     self.variations = {}
     offsetToData = self.offsetToGlyphVariationData
     for i in range(self.glyphCount):
         glyphName = glyphs[i]
         glyph = ttFont["glyf"][glyphName]
         numPointsInGlyph = self.getNumPoints_(glyph)
         gvarData = data[offsetToData + offsets[i]:offsetToData +
                         offsets[i + 1]]
         try:
             self.variations[glyphName] = decompileGlyph_(
                 numPointsInGlyph, sharedCoords, axisTags, gvarData)
         except Exception:
             log.error(
                 "Failed to decompile deltas for glyph '%s' (%d points)",
                 glyphName,
                 numPointsInGlyph,
             )
             raise
Exemplo n.º 4
0
    def decompile(self, ttFont):
        self.glyphName = ttFont.getGlyphName(self.gid)
        if self.rawdata is None:
            from fontemon_blender_addon.fontTools import ttLib
            raise ttLib.TTLibError("No table data to decompile")
        if len(self.rawdata) > 0:
            if len(self.rawdata) < sbixGlyphHeaderFormatSize:
                from fontemon_blender_addon.fontTools import ttLib
                #print "Glyph %i header too short: Expected %x, got %x." % (self.gid, sbixGlyphHeaderFormatSize, len(self.rawdata))
                raise ttLib.TTLibError("Glyph header too short.")

            sstruct.unpack(sbixGlyphHeaderFormat,
                           self.rawdata[:sbixGlyphHeaderFormatSize], self)

            if self.graphicType == "dupe":
                # this glyph is a reference to another glyph's image data
                gid, = struct.unpack(">H",
                                     self.rawdata[sbixGlyphHeaderFormatSize:])
                self.referenceGlyphName = ttFont.getGlyphName(gid)
            else:
                self.imageData = self.rawdata[sbixGlyphHeaderFormatSize:]
                self.referenceGlyphName = None
        # clean up
        del self.rawdata
        del self.gid
Exemplo n.º 5
0
 def decompile(self, data, ttFont):
     sstruct.unpack(TRAK_HEADER_FORMAT, data[:TRAK_HEADER_FORMAT_SIZE],
                    self)
     for direction in ('horiz', 'vert'):
         trackData = TrackData()
         offset = getattr(self, direction + 'Offset')
         if offset != 0:
             trackData.decompile(data, offset)
         setattr(self, direction + 'Data', trackData)
Exemplo n.º 6
0
 def _readHeaderAndMap(self):
     self.file.seek(0)
     headerData = self._read(ResourceForkHeaderSize)
     sstruct.unpack(ResourceForkHeader, headerData, self)
     # seek to resource map, skip reserved
     mapOffset = self.mapOffset + 22
     resourceMapData = self._read(ResourceMapHeaderSize, mapOffset)
     sstruct.unpack(ResourceMapHeader, resourceMapData, self)
     self.absTypeListOffset = self.mapOffset + self.typeListOffset
     self.absNameListOffset = self.mapOffset + self.nameListOffset
Exemplo n.º 7
0
    def decompile(self, data, ttFont):

        # Save the original data because offsets are from the start of the table.
        origData = data
        i = 0

        dummy = sstruct.unpack(eblcHeaderFormat, data[:8], self)
        i += 8

        self.strikes = []
        for curStrikeIndex in range(self.numSizes):
            curStrike = Strike()
            self.strikes.append(curStrike)
            curTable = curStrike.bitmapSizeTable
            dummy = sstruct.unpack2(bitmapSizeTableFormatPart1, data[i:i + 16],
                                    curTable)
            i += 16
            for metric in ('hori', 'vert'):
                metricObj = SbitLineMetrics()
                vars(curTable)[metric] = metricObj
                dummy = sstruct.unpack2(sbitLineMetricsFormat, data[i:i + 12],
                                        metricObj)
                i += 12
            dummy = sstruct.unpack(bitmapSizeTableFormatPart2, data[i:i + 8],
                                   curTable)
            i += 8

        for curStrike in self.strikes:
            curTable = curStrike.bitmapSizeTable
            for subtableIndex in range(curTable.numberOfIndexSubTables):
                i = curTable.indexSubTableArrayOffset + subtableIndex * indexSubTableArraySize

                tup = struct.unpack(indexSubTableArrayFormat,
                                    data[i:i + indexSubTableArraySize])
                (firstGlyphIndex, lastGlyphIndex,
                 additionalOffsetToIndexSubtable) = tup
                i = curTable.indexSubTableArrayOffset + additionalOffsetToIndexSubtable

                tup = struct.unpack(indexSubHeaderFormat,
                                    data[i:i + indexSubHeaderSize])
                (indexFormat, imageFormat, imageDataOffset) = tup

                indexFormatClass = self.getIndexFormatClass(indexFormat)
                indexSubTable = indexFormatClass(data[i + indexSubHeaderSize:],
                                                 ttFont)
                indexSubTable.firstGlyphIndex = firstGlyphIndex
                indexSubTable.lastGlyphIndex = lastGlyphIndex
                indexSubTable.additionalOffsetToIndexSubtable = additionalOffsetToIndexSubtable
                indexSubTable.indexFormat = indexFormat
                indexSubTable.imageFormat = imageFormat
                indexSubTable.imageDataOffset = imageDataOffset
                indexSubTable.decompile(
                )  # https://github.com/fontemon_blender_addon.fontTools/fontemon_blender_addon.fontTools/issues/317
                curStrike.indexSubTables.append(indexSubTable)
 def decompile(self, data, ttFont, version=2.0):
     if version >= 3.0:
         _, data = sstruct.unpack2(Silf_part1_format_v3, data, self)
         self.ruleVersion = float(
             floatToFixedToStr(self.ruleVersion, precisionBits=16))
     _, data = sstruct.unpack2(Silf_part1_format, data, self)
     for jlevel in range(self.numJLevels):
         j, data = sstruct.unpack2(Silf_justify_format, data, _Object())
         self.jLevels.append(j)
     _, data = sstruct.unpack2(Silf_part2_format, data, self)
     if self.numCritFeatures:
         self.critFeatures = struct.unpack_from(
             ('>%dH' % self.numCritFeatures), data)
     data = data[self.numCritFeatures * 2 + 1:]
     (numScriptTag, ) = struct.unpack_from('B', data)
     if numScriptTag:
         self.scriptTags = [
             struct.unpack("4s", data[x:x + 4])[0].decode("ascii")
             for x in range(1, 1 + 4 * numScriptTag, 4)
         ]
     data = data[1 + 4 * numScriptTag:]
     (self.lbGID, ) = struct.unpack('>H', data[:2])
     if self.numPasses:
         self.oPasses = struct.unpack(('>%dL' % (self.numPasses + 1)),
                                      data[2:6 + 4 * self.numPasses])
     data = data[6 + 4 * self.numPasses:]
     (numPseudo, ) = struct.unpack(">H", data[:2])
     for i in range(numPseudo):
         if version >= 3.0:
             pseudo = sstruct.unpack(Silf_pseudomap_format,
                                     data[8 + 6 * i:14 + 6 * i], _Object())
         else:
             pseudo = sstruct.unpack(Silf_pseudomap_format_h,
                                     data[8 + 4 * i:12 + 4 * i], _Object())
         self.pMap[pseudo.unicode] = ttFont.getGlyphName(pseudo.nPseudo)
     data = data[8 + 6 * numPseudo:]
     currpos = (sstruct.calcsize(Silf_part1_format) +
                sstruct.calcsize(Silf_justify_format) * self.numJLevels +
                sstruct.calcsize(Silf_part2_format) +
                2 * self.numCritFeatures + 1 + 1 + 4 * numScriptTag + 6 +
                4 * self.numPasses + 8 + 6 * numPseudo)
     if version >= 3.0:
         currpos += sstruct.calcsize(Silf_part1_format_v3)
     self.classes = Classes()
     self.classes.decompile(data, ttFont, version)
     for i in range(self.numPasses):
         p = Pass()
         self.passes.append(p)
         p.decompile(
             data[self.oPasses[i] - currpos:self.oPasses[i + 1] - currpos],
             ttFont, version)
Exemplo n.º 9
0
def readTTCHeader(file):
	file.seek(0)
	data = file.read(ttcHeaderSize)
	if len(data) != ttcHeaderSize:
		raise TTLibError("Not a Font Collection (not enough data)")
	self = SimpleNamespace()
	sstruct.unpack(ttcHeaderFormat, data, self)
	if self.TTCTag != "ttcf":
		raise TTLibError("Not a Font Collection")
	assert self.Version == 0x00010000 or self.Version == 0x00020000, "unrecognized TTC version 0x%08x" % self.Version
	self.offsetTable = struct.unpack(">%dL" % self.numFonts, file.read(self.numFonts * 4))
	if self.Version == 0x00020000:
		pass # ignoring version 2.0 signatures
	return self
Exemplo n.º 10
0
 def decompile(self, refData, reader):
     sstruct.unpack(ResourceRefItem, refData, self)
     # interpret 3-byte dataOffset as (padded) ULONG to unpack it with struct
     self.dataOffset, = struct.unpack('>L',
                                      bytesjoin([b"\0", self.dataOffset]))
     absDataOffset = reader.dataOffset + self.dataOffset
     dataLength, = struct.unpack(">L", reader._read(4, absDataOffset))
     self.data = reader._read(dataLength)
     if self.nameOffset == -1:
         return
     absNameOffset = reader.absNameListOffset + self.nameOffset
     nameLength, = struct.unpack('B', reader._read(1, absNameOffset))
     name, = struct.unpack('>%ss' % nameLength, reader._read(nameLength))
     self.name = tostr(name, encoding='mac-roman')
Exemplo n.º 11
0
 def decompile(self, data, ttFont):
     sstruct.unpack(postFormat, data[:postFormatSize], self)
     data = data[postFormatSize:]
     if self.formatType == 1.0:
         self.decode_format_1_0(data, ttFont)
     elif self.formatType == 2.0:
         self.decode_format_2_0(data, ttFont)
     elif self.formatType == 3.0:
         self.decode_format_3_0(data, ttFont)
     elif self.formatType == 4.0:
         self.decode_format_4_0(data, ttFont)
     else:
         # supported format
         raise ttLib.TTLibError("'post' table format %f not supported" %
                                self.formatType)
Exemplo n.º 12
0
 def decompile(self, data, ttFont):
     axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
     header = {}
     sstruct.unpack(CVAR_HEADER_FORMAT, data[0:CVAR_HEADER_SIZE], header)
     self.majorVersion = header["majorVersion"]
     self.minorVersion = header["minorVersion"]
     assert self.majorVersion == 1, self.majorVersion
     self.variations = decompileTupleVariationStore(
         tableTag=self.tableTag,
         axisTags=axisTags,
         tupleVariationCount=header["tupleVariationCount"],
         pointCount=len(ttFont["cvt "].values),
         sharedTuples=None,
         data=data,
         pos=CVAR_HEADER_SIZE,
         dataPos=header["offsetToData"])
Exemplo n.º 13
0
 def decompile(self, data, ttFont):
     headerSize = sstruct.calcsize(META_HEADER_FORMAT)
     header = sstruct.unpack(META_HEADER_FORMAT, data[0 : headerSize])
     if header["version"] != 1:
         raise TTLibError("unsupported 'meta' version %d" %
                          header["version"])
     dataMapSize = sstruct.calcsize(DATA_MAP_FORMAT)
     for i in range(header["numDataMaps"]):
         dataMapOffset = headerSize + i * dataMapSize
         dataMap = sstruct.unpack(
             DATA_MAP_FORMAT,
             data[dataMapOffset : dataMapOffset + dataMapSize])
         tag = dataMap["tag"]
         offset = dataMap["dataOffset"]
         self.data[tag] = data[offset : offset + dataMap["dataLength"]]
         if tag in ["dlng", "slng"]:
             self.data[tag] = self.data[tag].decode("utf-8")
Exemplo n.º 14
0
    def decompile(self, data, offset):
        # initial offset is from the start of trak table to the current TrackData
        trackDataHeader = data[offset:offset + TRACK_DATA_FORMAT_SIZE]
        if len(trackDataHeader) != TRACK_DATA_FORMAT_SIZE:
            raise TTLibError('not enough data to decompile TrackData header')
        sstruct.unpack(TRACK_DATA_FORMAT, trackDataHeader, self)
        offset += TRACK_DATA_FORMAT_SIZE

        nSizes = self.nSizes
        sizeTableOffset = self.sizeTableOffset
        sizeTable = []
        for i in range(nSizes):
            sizeValueData = data[sizeTableOffset:sizeTableOffset +
                                 SIZE_VALUE_FORMAT_SIZE]
            if len(sizeValueData) < SIZE_VALUE_FORMAT_SIZE:
                raise TTLibError(
                    'not enough data to decompile TrackData size subtable')
            sizeValue, = struct.unpack(SIZE_VALUE_FORMAT, sizeValueData)
            sizeTable.append(fi2fl(sizeValue, 16))
            sizeTableOffset += SIZE_VALUE_FORMAT_SIZE

        for i in range(self.nTracks):
            entry = TrackTableEntry()
            entryData = data[offset:offset + TRACK_TABLE_ENTRY_FORMAT_SIZE]
            if len(entryData) < TRACK_TABLE_ENTRY_FORMAT_SIZE:
                raise TTLibError(
                    'not enough data to decompile TrackTableEntry record')
            sstruct.unpack(TRACK_TABLE_ENTRY_FORMAT, entryData, entry)
            perSizeOffset = entry.offset
            for j in range(nSizes):
                size = sizeTable[j]
                perSizeValueData = data[perSizeOffset:perSizeOffset +
                                        PER_SIZE_VALUE_FORMAT_SIZE]
                if len(perSizeValueData) < PER_SIZE_VALUE_FORMAT_SIZE:
                    raise TTLibError(
                        'not enough data to decompile per-size track values')
                perSizeValue, = struct.unpack(PER_SIZE_VALUE_FORMAT,
                                              perSizeValueData)
                entry[size] = perSizeValue
                perSizeOffset += PER_SIZE_VALUE_FORMAT_SIZE
            self[entry.track] = entry
            offset += TRACK_TABLE_ENTRY_FORMAT_SIZE
Exemplo n.º 15
0
 def _readTypeList(self):
     absTypeListOffset = self.absTypeListOffset
     numTypesData = self._read(2, absTypeListOffset)
     self.numTypes, = struct.unpack('>H', numTypesData)
     absTypeListOffset2 = absTypeListOffset + 2
     for i in range(self.numTypes + 1):
         resTypeItemOffset = absTypeListOffset2 + ResourceTypeItemSize * i
         resTypeItemData = self._read(ResourceTypeItemSize,
                                      resTypeItemOffset)
         item = sstruct.unpack(ResourceTypeItem, resTypeItemData)
         resType = tostr(item['type'], encoding='mac-roman')
         refListOffset = absTypeListOffset + item['refListOffset']
         numRes = item['numRes'] + 1
         resources = self._readReferenceList(resType, refListOffset, numRes)
         self._resources[resType] = resources
Exemplo n.º 16
0
 def decompile(self, data, ttFont):
     axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
     header = {}
     headerSize = sstruct.calcsize(AVAR_HEADER_FORMAT)
     header = sstruct.unpack(AVAR_HEADER_FORMAT, data[0:headerSize])
     majorVersion = header["majorVersion"]
     if majorVersion != 1:
         raise TTLibError("unsupported 'avar' version %d" % majorVersion)
     pos = headerSize
     for axis in axisTags:
         segments = self.segments[axis] = {}
         numPairs = struct.unpack(">H", data[pos:pos+2])[0]
         pos = pos + 2
         for _ in range(numPairs):
             fromValue, toValue = struct.unpack(">hh", data[pos:pos+4])
             segments[fi2fl(fromValue, 14)] = fi2fl(toValue, 14)
             pos = pos + 4
Exemplo n.º 17
0
	def decompile(self, data, ttFont):
		dummy, data = sstruct.unpack2(OS2_format_0, data, self)

		if self.version == 1:
			dummy, data = sstruct.unpack2(OS2_format_1_addition, data, self)
		elif self.version in (2, 3, 4):
			dummy, data = sstruct.unpack2(OS2_format_2_addition, data, self)
		elif self.version == 5:
			dummy, data = sstruct.unpack2(OS2_format_5_addition, data, self)
			self.usLowerOpticalPointSize /= 20
			self.usUpperOpticalPointSize /= 20
		elif self.version != 0:
			from fontemon_blender_addon.fontTools import ttLib
			raise ttLib.TTLibError("unknown format for OS/2 table: version %s" % self.version)
		if len(data):
			log.warning("too much 'OS/2' table data")

		self.panose = sstruct.unpack(panoseFormat, self.panose, Panose())
Exemplo n.º 18
0
 def decompile(self, data, ttFont):
     header = {}
     headerSize = sstruct.calcsize(FVAR_HEADER_FORMAT)
     header = sstruct.unpack(FVAR_HEADER_FORMAT, data[0:headerSize])
     if header["version"] != 0x00010000:
         raise TTLibError("unsupported 'fvar' version %04x" %
                          header["version"])
     pos = header["offsetToData"]
     axisSize = header["axisSize"]
     for _ in range(header["axisCount"]):
         axis = Axis()
         axis.decompile(data[pos:pos + axisSize])
         self.axes.append(axis)
         pos += axisSize
     instanceSize = header["instanceSize"]
     axisTags = [axis.axisTag for axis in self.axes]
     for _ in range(header["instanceCount"]):
         instance = NamedInstance()
         instance.decompile(data[pos:pos + instanceSize], axisTags)
         self.instances.append(instance)
         pos += instanceSize
Exemplo n.º 19
0
	def __init__(self, file, checkChecksums=0, fontNumber=-1):
		self.file = file
		self.checkChecksums = checkChecksums

		self.flavor = None
		self.flavorData = None
		self.DirectoryEntry = SFNTDirectoryEntry
		self.file.seek(0)
		self.sfntVersion = self.file.read(4)
		self.file.seek(0)
		if self.sfntVersion == b"ttcf":
			header = readTTCHeader(self.file)
			numFonts = header.numFonts
			if not 0 <= fontNumber < numFonts:
				raise TTLibError("specify a font number between 0 and %d (inclusive)" % (numFonts - 1))
			self.numFonts = numFonts
			self.file.seek(header.offsetTable[fontNumber])
			data = self.file.read(sfntDirectorySize)
			if len(data) != sfntDirectorySize:
				raise TTLibError("Not a Font Collection (not enough data)")
			sstruct.unpack(sfntDirectoryFormat, data, self)
		elif self.sfntVersion == b"wOFF":
			self.flavor = "woff"
			self.DirectoryEntry = WOFFDirectoryEntry
			data = self.file.read(woffDirectorySize)
			if len(data) != woffDirectorySize:
				raise TTLibError("Not a WOFF font (not enough data)")
			sstruct.unpack(woffDirectoryFormat, data, self)
		else:
			data = self.file.read(sfntDirectorySize)
			if len(data) != sfntDirectorySize:
				raise TTLibError("Not a TrueType or OpenType font (not enough data)")
			sstruct.unpack(sfntDirectoryFormat, data, self)
		self.sfntVersion = Tag(self.sfntVersion)

		if self.sfntVersion not in ("\x00\x01\x00\x00", "OTTO", "true"):
			raise TTLibError("Not a TrueType or OpenType font (bad sfntVersion)")
		tables = {}
		for i in range(self.numTables):
			entry = self.DirectoryEntry()
			entry.fromFile(self.file)
			tag = Tag(entry.tag)
			tables[tag] = entry
		self.tables = OrderedDict(sorted(tables.items(), key=lambda i: i[1].offset))

		# Load flavor data if any
		if self.flavor == "woff":
			self.flavorData = WOFFFlavorData(self)
Exemplo n.º 20
0
 def decompile(self, data, ttFont):
     sstruct.unpack(hheaFormat, data, self)
Exemplo n.º 21
0
	def fromFile(self, file):
		sstruct.unpack(self.format, file.read(self.formatSize), self)
Exemplo n.º 22
0
	def fromString(self, str):
		sstruct.unpack(self.format, str, self)