Example #1
0
    def decompile(self, ttFont):
        self.glyphName = ttFont.getGlyphName(self.gid)
        if self.rawdata is None:
            from fontTools import ttLib
            raise ttLib.TTLibError("No table data to decompile")
        if len(self.rawdata) > 0:
            if len(self.rawdata) < sbixGlyphHeaderFormatSize:
                from 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
Example #2
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 = _lazy_dict()
     offsetToData = self.offsetToGlyphVariationData
     glyf = ttFont['glyf']
     for i in range(self.glyphCount):
         glyphName = glyphs[i]
         glyph = glyf[glyphName]
         numPointsInGlyph = self.getNumPoints_(glyph)
         gvarData = data[offsetToData + offsets[i]:offsetToData +
                         offsets[i + 1]]
         self.variations[glyphName] = partial(decompileGlyph_,
                                              numPointsInGlyph,
                                              sharedCoords, axisTags,
                                              gvarData)
Example #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
Example #4
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 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
Example #5
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
Example #6
0
    def decompile(self, data, ttFont):
        # read table header
        sstruct.unpack(sbixHeaderFormat, data[:sbixHeaderFormatSize], self)
        # collect offsets to individual bitmap sets in self.bitmapSetOffsets
        for i in range(self.numSets):
            myOffset = sbixHeaderFormatSize + i * sbixBitmapSetOffsetFormatSize
            offsetEntry = sbixBitmapSetOffset()
            sstruct.unpack(sbixBitmapSetOffsetFormat, \
             data[myOffset : myOffset+sbixBitmapSetOffsetFormatSize], \
             offsetEntry)
            self.bitmapSetOffsets.append(offsetEntry.offset)

        # decompile BitmapSets
        for i in range(self.numSets - 1, -1, -1):
            myBitmapSet = BitmapSet(rawdata=data[self.bitmapSetOffsets[i]:])
            data = data[:self.bitmapSetOffsets[i]]
            myBitmapSet.decompile(ttFont)
            #print "  BitmapSet length: %xh" % len(bitmapSetData)
            #print "Number of Bitmaps:", myBitmapSet.numBitmaps
            if myBitmapSet.size in self.bitmapSets:
                from fontTools import ttLib
                raise ttLib.TTLibError(
                    "Pixel 'size' must be unique for each BitmapSet")
            self.bitmapSets[myBitmapSet.size] = myBitmapSet

        # after the bitmaps have been extracted, we don't need the offsets anymore
        del self.bitmapSetOffsets
Example #7
0
	def decompile(self, data):
		# header; FontRec
		sstruct.unpack(nfntHeaderFormat, data[:headerSize], self)
		
		#assert self.fRectHeight == (self.ascent + self.descent)
		
		# rest
		tableSize = 2 * (self.lastChar - self.firstChar + 3)
		bitmapSize = 2 * self.rowWords * self.fRectHeight
		
		self.bits = data[headerSize:headerSize + bitmapSize]
		
		# XXX deal with self.nDescent being a positive number
		assert (headerSize + bitmapSize + tableSize - 16) / 2 == self.owTLoc  # ugh...
		
		locTable = data[headerSize + bitmapSize:headerSize + bitmapSize + tableSize]
		if len(locTable) <> tableSize:
			raise ValueError, 'invalid NFNT format'
		
		owTable = data[headerSize + bitmapSize + tableSize:headerSize + bitmapSize + 2 * tableSize]
		if len(owTable) <> tableSize:
			raise ValueError, 'invalid NFNT format'
		
		# fill tables
		self.offsetTable = []
		self.widthTable = []
		self.locTable = []
		for i in range(0, tableSize, 2):
			self.offsetTable.append(ord(owTable[i]))
			self.widthTable.append(ord(owTable[i+1]))
			loc, = struct.unpack("h", locTable[i:i+2])
			self.locTable.append(loc)
Example #8
0
	def decompile(self, data, ttFont):
		# read table header
		sstruct.unpack(sbixHeaderFormat, data[ : sbixHeaderFormatSize], self)
		# collect offsets to individual bitmap sets in self.bitmapSetOffsets
		for i in range(self.numSets):
			myOffset = sbixHeaderFormatSize + i * sbixBitmapSetOffsetFormatSize
			offsetEntry = sbixBitmapSetOffset()
			sstruct.unpack(sbixBitmapSetOffsetFormat, \
				data[myOffset : myOffset+sbixBitmapSetOffsetFormatSize], \
				offsetEntry)
			self.bitmapSetOffsets.append(offsetEntry.offset)

		# decompile BitmapSets
		for i in range(self.numSets-1, -1, -1):
			myBitmapSet = BitmapSet(rawdata=data[self.bitmapSetOffsets[i]:])
			data = data[:self.bitmapSetOffsets[i]]
			myBitmapSet.decompile(ttFont)
			#print "  BitmapSet length: %xh" % len(bitmapSetData)
			#print "Number of Bitmaps:", myBitmapSet.numBitmaps
			if myBitmapSet.size in self.bitmapSets:
				from fontTools import ttLib
				raise ttLib.TTLibError("Pixel 'size' must be unique for each BitmapSet")
			self.bitmapSets[myBitmapSet.size] = myBitmapSet

		# after the bitmaps have been extracted, we don't need the offsets anymore
		del self.bitmapSetOffsets
Example #9
0
	def decompile(self, ttFont):
		if self.data is None:
			from fontTools import ttLib
			raise ttLib.TTLibError
		if len(self.data) < sbixBitmapSetHeaderFormatSize:
			from fontTools import ttLib
			raise(ttLib.TTLibError, "BitmapSet header too short: Expected %x, got %x.") \
				% (sbixBitmapSetHeaderFormatSize, len(self.data))

		# read BitmapSet header from raw data
		sstruct.unpack(sbixBitmapSetHeaderFormat, self.data[:sbixBitmapSetHeaderFormatSize], self)

		# calculate number of bitmaps
		firstBitmapOffset, = struct.unpack(">L", \
			self.data[sbixBitmapSetHeaderFormatSize : sbixBitmapSetHeaderFormatSize + sbixBitmapOffsetEntryFormatSize])
		self.numBitmaps = (firstBitmapOffset - sbixBitmapSetHeaderFormatSize) // sbixBitmapOffsetEntryFormatSize - 1
		# ^ -1 because there's one more offset than bitmaps

		# build offset list for single bitmap offsets
		self.bitmapOffsets = []
		for i in range(self.numBitmaps + 1): # + 1 because there's one more offset than bitmaps
			start = i * sbixBitmapOffsetEntryFormatSize + sbixBitmapSetHeaderFormatSize
			myOffset, = struct.unpack(">L", self.data[start : start + sbixBitmapOffsetEntryFormatSize])
			self.bitmapOffsets.append(myOffset)

		# iterate through offset list and slice raw data into bitmaps
		for i in range(self.numBitmaps):
			myBitmap = Bitmap(rawdata=self.data[self.bitmapOffsets[i] : self.bitmapOffsets[i+1]], gid=i)
			myBitmap.decompile(ttFont)
			self.bitmaps[myBitmap.glyphName] = myBitmap
		del self.bitmapOffsets
		del self.data
Example #10
0
	def decompile(self, ttFont):
		if self.data is None:
			from fontTools import ttLib
			raise ttLib.TTLibError
		if len(self.data) < sbixStrikeHeaderFormatSize:
			from 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
Example #11
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 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
	def decompile(self, ttFont):
		if self.data is None:
			from fontTools import ttLib
			raise ttLib.TTLibError
		if len(self.data) < sbixStrikeHeaderFormatSize:
			from 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
Example #13
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)
Example #14
0
	def __init__(self, refNum):
		self.__fileName = array.array("c", "\0" * 64)
		sstruct.unpack(_FCBPBFormat, 
				"\0" * sstruct.calcsize(_FCBPBFormat), self)
		self.ioNamePtr = self.__fileName.buffer_info()[0]
		self.ioRefNum = refNum
		self.ioVRefNum = GetVRefNum(refNum)
		self.__haveInfo = 0
Example #15
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)
Example #16
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)
 def __init__(self, refNum):
     self.__fileName = array.array("c", "\0" * 64)
     sstruct.unpack(_FCBPBFormat, "\0" * sstruct.calcsize(_FCBPBFormat),
                    self)
     self.ioNamePtr = self.__fileName.buffer_info()[0]
     self.ioRefNum = refNum
     self.ioVRefNum = GetVRefNum(refNum)
     self.__haveInfo = 0
Example #18
0
	def _getheader(self):
		data = self.FOND.data
		sstruct.unpack(headerformat, data[:28], self)
		self.ffProperty = struct.unpack(">9h", data[28:46])
		self.ffIntl = struct.unpack(">hh", data[46:50])
		self.ffVersion, = struct.unpack(">h", data[50:FONDheadersize])
		
		if DEBUG:
			self._rawheader = data[:FONDheadersize]
			self.parsedthings.append((0, FONDheadersize, 'header'))
Example #19
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
Example #20
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
Example #21
0
	def getInfo(self):
		if self.__haveInfo:
			return
		data = sstruct.pack(_FCBPBFormat, self)
		buf = array.array("c", data)
		ptr = buf.buffer_info()[0]
		err = _getInfo(ptr)
		if err:
			raise Res.Error("can't get file info", err)
		sstruct.unpack(_FCBPBFormat, buf.tostring(), self)
		self.__haveInfo = 1
 def getInfo(self):
     if self.__haveInfo:
         return
     data = sstruct.pack(_FCBPBFormat, self)
     buf = array.array("c", data)
     ptr = buf.buffer_info()[0]
     err = _getInfo(ptr)
     if err:
         raise Res.Error("can't get file info", err)
     sstruct.unpack(_FCBPBFormat, buf.tostring(), self)
     self.__haveInfo = 1
Example #23
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/fonttools/fonttools/issues/317
                curStrike.indexSubTables.append(indexSubTable)
Example #24
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"])
Example #25
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)
		else:
			# supported format
			raise ttLib.TTLibError("'post' table format %f not supported" % self.formatType)
Example #26
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')
Example #27
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)
     else:
         # supported format
         raise ttLib.TTLibError("'post' table format %f not supported" %
                                self.formatType)
Example #28
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')
Example #29
0
 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)
Example #30
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
Example #31
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
Example #32
0
    def __init__(self, file, checkChecksums=1, fontNumber=-1):
        if not haveBrotli:
            print(
                'The WOFF2 decoder requires the Brotli Python extension, available at:\n'
                'https://github.com/google/brotli',
                file=sys.stderr)
            raise ImportError("No module named brotli")

        self.file = file

        signature = Tag(self.file.read(4))
        if signature != b"wOF2":
            raise TTLibError("Not a WOFF2 font (bad signature)")

        self.file.seek(0)
        self.DirectoryEntry = WOFF2DirectoryEntry
        data = self.file.read(woff2DirectorySize)
        if len(data) != woff2DirectorySize:
            raise TTLibError('Not a WOFF2 font (not enough data)')
        sstruct.unpack(woff2DirectoryFormat, data, self)

        self.tables = OrderedDict()
        offset = 0
        for i in range(self.numTables):
            entry = self.DirectoryEntry()
            entry.fromFile(self.file)
            tag = Tag(entry.tag)
            self.tables[tag] = entry
            entry.offset = offset
            offset += entry.length

        totalUncompressedSize = offset
        compressedData = self.file.read(self.totalCompressedSize)
        decompressedData = brotli.decompress(compressedData)
        if len(decompressedData) != totalUncompressedSize:
            raise TTLibError(
                'unexpected size for decompressed font data: expected %d, found %d'
                % (totalUncompressedSize, len(decompressedData)))
        self.transformBuffer = BytesIO(decompressedData)

        self.file.seek(0, 2)
        if self.length != self.file.tell():
            raise TTLibError(
                "reported 'length' doesn't match the actual file size")

        self.flavorData = WOFF2FlavorData(self)

        # make empty TTFont to store data while reconstructing tables
        self.ttFont = TTFont(recalcBBoxes=False, recalcTimestamp=False)
Example #33
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"]]
Example #34
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"]]
Example #35
0
	def decompile(self, data, ttFont):
		axisTags = [axis.AxisTag for axis in ttFont["fvar"].table.VariationAxis]
		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 = self.decompileSharedCoords_(axisTags, data)
		self.variations = {}
		for i in range(self.glyphCount):
			glyphName = glyphs[i]
			glyph = ttFont["glyf"][glyphName]
			numPoints = self.getNumPoints_(glyph)
			gvarData = data[self.offsetToData + offsets[i] : self.offsetToData + offsets[i + 1]]
			self.variations[glyphName] = self.decompileGlyph_(numPoints, sharedCoords, axisTags, gvarData)
Example #36
0
	def __init__(self, file, checkChecksums=1, fontNumber=-1):
		self.file = file
		self.checkChecksums = checkChecksums

		self.flavor = None
		self.flavorData = None
		self.DirectoryEntry = SFNTDirectoryEntry
		self.sfntVersion = self.file.read(4)
		self.file.seek(0)
		if self.sfntVersion == b"ttcf":
			data = self.file.read(ttcHeaderSize)
			if len(data) != ttcHeaderSize:
				from fontTools import ttLib
				raise ttLib.TTLibError("Not a Font Collection (not enough data)")
			sstruct.unpack(ttcHeaderFormat, data, self)
			assert self.Version == 0x00010000 or self.Version == 0x00020000, "unrecognized TTC version 0x%08x" % self.Version
			if not 0 <= fontNumber < self.numFonts:
				from fontTools import ttLib
				raise ttLib.TTLibError("specify a font number between 0 and %d (inclusive)" % (self.numFonts - 1))
			offsetTable = struct.unpack(">%dL" % self.numFonts, self.file.read(self.numFonts * 4))
			if self.Version == 0x00020000:
				pass # ignoring version 2.0 signatures
			self.file.seek(offsetTable[fontNumber])
			data = self.file.read(sfntDirectorySize)
			if len(data) != sfntDirectorySize:
				from fontTools import ttLib
				raise ttLib.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:
				from fontTools import ttLib
				raise ttLib.TTLibError("Not a WOFF font (not enough data)")
			sstruct.unpack(woffDirectoryFormat, data, self)
		else:
			data = self.file.read(sfntDirectorySize)
			if len(data) != sfntDirectorySize:
				from fontTools import ttLib
				raise ttLib.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"):
			from fontTools import ttLib
			raise ttLib.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)
Example #37
0
	def test_incorrect_compressed_size(self):
		data = self.file.read(woff2DirectorySize)
		header = sstruct.unpack(woff2DirectoryFormat, data)
		header['totalCompressedSize'] = 0
		data = sstruct.pack(woff2DirectoryFormat, header)
		with self.assertRaises((brotli.error, ttLib.TTLibError)):
			WOFF2Reader(BytesIO(data + self.file.read()))
Example #38
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 = self.decompileSharedCoords_(axisTags, data)
		self.variations = {}
		for i in range(self.glyphCount):
			glyphName = glyphs[i]
			glyph = ttFont["glyf"][glyphName]
			numPointsInGlyph = self.getNumPoints_(glyph)
			gvarData = data[self.offsetToData + offsets[i] : self.offsetToData + offsets[i + 1]]
			self.variations[glyphName] = \
			    self.decompileGlyph_(numPointsInGlyph, sharedCoords, axisTags, gvarData)
Example #39
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"])
Example #40
0
 def test_incorrect_file_size(self):
     data = self.file.read(woff2DirectorySize)
     header = sstruct.unpack(woff2DirectoryFormat, data)
     header["length"] -= 1
     data = sstruct.pack(woff2DirectoryFormat, header)
     with self.assertRaisesRegex(ttLib.TTLibError, "doesn't match the actual file size"):
         WOFF2Reader(BytesIO(data + self.file.read()))
Example #41
0
	def test_incorrect_compressed_size(self):
		data = self.file.read(woff2DirectorySize)
		header = sstruct.unpack(woff2DirectoryFormat, data)
		header['totalCompressedSize'] = 0
		data = sstruct.pack(woff2DirectoryFormat, header)
		with self.assertRaises((brotli.error, ttLib.TTLibError)):
			WOFF2Reader(BytesIO(data + self.file.read()))
Example #42
0
	def __init__(self, file, checkChecksums=1, fontNumber=-1):
		if not haveBrotli:
			log.error(
				'The WOFF2 decoder requires the Brotli Python extension, available at: '
				'https://github.com/google/brotli')
			raise ImportError("No module named brotli")

		self.file = file

		signature = Tag(self.file.read(4))
		if signature != b"wOF2":
			raise TTLibError("Not a WOFF2 font (bad signature)")

		self.file.seek(0)
		self.DirectoryEntry = WOFF2DirectoryEntry
		data = self.file.read(woff2DirectorySize)
		if len(data) != woff2DirectorySize:
			raise TTLibError('Not a WOFF2 font (not enough data)')
		sstruct.unpack(woff2DirectoryFormat, data, self)

		self.tables = OrderedDict()
		offset = 0
		for i in range(self.numTables):
			entry = self.DirectoryEntry()
			entry.fromFile(self.file)
			tag = Tag(entry.tag)
			self.tables[tag] = entry
			entry.offset = offset
			offset += entry.length

		totalUncompressedSize = offset
		compressedData = self.file.read(self.totalCompressedSize)
		decompressedData = brotli.decompress(compressedData)
		if len(decompressedData) != totalUncompressedSize:
			raise TTLibError(
				'unexpected size for decompressed font data: expected %d, found %d'
				% (totalUncompressedSize, len(decompressedData)))
		self.transformBuffer = BytesIO(decompressedData)

		self.file.seek(0, 2)
		if self.length != self.file.tell():
			raise TTLibError("reported 'length' doesn't match the actual file size")

		self.flavorData = WOFF2FlavorData(self)

		# make empty TTFont to store data while reconstructing tables
		self.ttFont = TTFont(recalcBBoxes=False, recalcTimestamp=False)
Example #43
0
 def __init__(self, file, checkChecksums=1):
     self.file = file
     self.checkChecksums = checkChecksums
     # unpack the header
     self.file.seek(0)
     bytes = self.file.read(woffHeaderSize)
     if len(bytes) != woffHeaderSize:
         raise WOFFLibError("Not a properly formatted WOFF file.")
     sstruct.unpack(woffHeaderFormat, bytes, self)
     if self.signature != "wOFF":
         raise WOFFLibError("Not a properly formatted WOFF file.")
     # unpack the directory
     self.tables = {}
     for i in range(self.numTables):
         entry = WOFFDirectoryEntry()
         entry.fromFile(self.file)
         self.tables[entry.tag] = entry
Example #44
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/behdad/fonttools/issues/317
				curStrike.indexSubTables.append(indexSubTable)
Example #45
0
	def test_incorrect_file_size(self):
		data = self.file.read(woff2DirectorySize)
		header = sstruct.unpack(woff2DirectoryFormat, data)
		header['length'] -= 1
		data = sstruct.pack(woff2DirectoryFormat, header)
		with self.assertRaisesRegex(
				ttLib.TTLibError, "doesn't match the actual file size"):
			WOFF2Reader(BytesIO(data + self.file.read()))
Example #46
0
 def __init__(self, file, checkChecksums=1):
     self.file = file
     self.checkChecksums = checkChecksums
     # unpack the header
     self.file.seek(0)
     bytes = self.file.read(woffHeaderSize)
     if len(bytes) != woffHeaderSize:
         raise WOFFLibError("Not a properly formatted WOFF file.")
     sstruct.unpack(woffHeaderFormat, bytes, self)
     if self.signature != "wOFF":
         raise WOFFLibError("Not a properly formatted WOFF file.")
     # unpack the directory
     self.tables = {}
     for i in range(self.numTables):
         entry = WOFFDirectoryEntry()
         entry.fromFile(self.file)
         self.tables[entry.tag] = entry
Example #47
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
Example #48
0
 def decompile(self, data, ttFont, version=2.0):
     if version >= 3.0 :
         _, data = sstruct.unpack2(Silf_part1_format_v3, data, self)
     _, 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] 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)
Example #49
0
    def __init__(self, file, checkChecksums=1, fontNumber=-1):
        self.file = file
        self.checkChecksums = checkChecksums

        self.flavor = None
        self.flavorData = None
        self.DirectoryEntry = SFNTDirectoryEntry
        self.sfntVersion = self.file.read(4)
        self.file.seek(0)
        if self.sfntVersion == b"ttcf":
            sstruct.unpack(ttcHeaderFormat, self.file.read(ttcHeaderSize),
                           self)
            assert self.Version == 0x00010000 or self.Version == 0x00020000, "unrecognized TTC version 0x%08x" % self.Version
            if not 0 <= fontNumber < self.numFonts:
                from fontTools import ttLib

                raise ttLib.TTLibError(
                    "specify a font number between 0 and %d (inclusive)" %
                    (self.numFonts - 1))
            offsetTable = struct.unpack(">%dL" % self.numFonts,
                                        self.file.read(self.numFonts * 4))
            if self.Version == 0x00020000:
                pass  # ignoring version 2.0 signatures
            self.file.seek(offsetTable[fontNumber])
            sstruct.unpack(sfntDirectoryFormat,
                           self.file.read(sfntDirectorySize), self)
        elif self.sfntVersion == b"wOFF":
            self.flavor = "woff"
            self.DirectoryEntry = WOFFDirectoryEntry
            sstruct.unpack(woffDirectoryFormat,
                           self.file.read(woffDirectorySize), self)
        else:
            sstruct.unpack(sfntDirectoryFormat,
                           self.file.read(sfntDirectorySize), self)
        self.sfntVersion = Tag(self.sfntVersion)

        if self.sfntVersion not in ("\x00\x01\x00\x00", "OTTO", "true"):
            from fontTools import ttLib

            raise ttLib.TTLibError(
                "Not a TrueType or OpenType font (bad sfntVersion)")
        self.tables = {}
        for i in range(self.numTables):
            entry = self.DirectoryEntry()
            entry.fromFile(self.file)
            self.tables[Tag(entry.tag)] = entry

        # Load flavor data if any
        if self.flavor == "woff":
            self.flavorData = WOFFFlavorData(self)
    def decompile(self, ttFont):
        if self.data is None:
            from fontTools import ttLib
            raise ttLib.TTLibError
        if len(self.data) < sbixBitmapSetHeaderFormatSize:
            from fontTools import ttLib
            raise(ttLib.TTLibError, "BitmapSet header too short: Expected %x, got %x.") \
             % (sbixBitmapSetHeaderFormatSize, len(self.data))

        # read BitmapSet header from raw data
        sstruct.unpack(sbixBitmapSetHeaderFormat,
                       self.data[:sbixBitmapSetHeaderFormatSize], self)

        # calculate number of bitmaps
        firstBitmapOffset, = struct.unpack(">L", \
         self.data[sbixBitmapSetHeaderFormatSize : sbixBitmapSetHeaderFormatSize + sbixBitmapOffsetEntryFormatSize])
        self.numBitmaps = (firstBitmapOffset - sbixBitmapSetHeaderFormatSize
                           ) // sbixBitmapOffsetEntryFormatSize - 1
        # ^ -1 because there's one more offset than bitmaps

        # build offset list for single bitmap offsets
        self.bitmapOffsets = []
        for i in range(self.numBitmaps +
                       1):  # + 1 because there's one more offset than bitmaps
            start = i * sbixBitmapOffsetEntryFormatSize + sbixBitmapSetHeaderFormatSize
            myOffset, = struct.unpack(
                ">L", self.data[start:start + sbixBitmapOffsetEntryFormatSize])
            self.bitmapOffsets.append(myOffset)

        # iterate through offset list and slice raw data into bitmaps
        for i in range(self.numBitmaps):
            myBitmap = Bitmap(
                rawdata=self.data[self.bitmapOffsets[i]:self.bitmapOffsets[i +
                                                                           1]],
                gid=i)
            myBitmap.decompile(ttFont)
            self.bitmaps[myBitmap.glyphName] = myBitmap
        del self.bitmapOffsets
        del self.data
Example #51
0
    def decompile(self, data, ttFont):
        self.docList = []
        # Version 0 is the standardized version of the table; and current.
        # https://www.microsoft.com/typography/otspec/svg.htm
        sstruct.unpack(SVG_format_0, data[:SVG_format_0Size], self)
        if self.version != 0:
            log.warning(
                "Unknown SVG table version '%s'. Decompiling as version 0.",
                self.version)
        # read in SVG Documents Index
        # data starts with the first entry of the entry list.
        pos = subTableStart = self.offsetToSVGDocIndex
        self.numEntries = struct.unpack(">H", data[pos:pos + 2])[0]
        pos += 2
        if self.numEntries > 0:
            data2 = data[pos:]
            entries = []
            for i in range(self.numEntries):
                docIndexEntry, data2 = sstruct.unpack2(
                    doc_index_entry_format_0, data2, DocumentIndexEntry())
                entries.append(docIndexEntry)

            for entry in entries:
                start = entry.svgDocOffset + subTableStart
                end = start + entry.svgDocLength
                doc = data[start:end]
                compressed = False
                if doc.startswith(b"\x1f\x8b"):
                    import gzip
                    bytesIO = BytesIO(doc)
                    with gzip.GzipFile(None, "r",
                                       fileobj=bytesIO) as gunzipper:
                        doc = gunzipper.read()
                    del bytesIO
                    compressed = True
                doc = tostr(doc, "utf_8")
                self.docList.append(
                    SVGDocument(doc, entry.startGlyphID, entry.endGlyphID,
                                compressed))
Example #52
0
	def decompile(self, ttFont):
		self.glyphName = ttFont.getGlyphName(self.gid)
		if self.rawdata is None:
			from fontTools import ttLib
			raise ttLib.TTLibError("No table data to decompile")
		if len(self.rawdata) > 0:
			if len(self.rawdata) < sbixBitmapHeaderFormatSize:
				from fontTools import ttLib
				#print "Bitmap %i header too short: Expected %x, got %x." % (self.gid, sbixBitmapHeaderFormatSize, len(self.rawdata))
				raise ttLib.TTLibError("Bitmap header too short.")

			sstruct.unpack(sbixBitmapHeaderFormat, self.rawdata[:sbixBitmapHeaderFormatSize], self)

			if self.imageFormatTag == "dupe":
				# bitmap is a reference to another glyph's bitmap
				gid, = struct.unpack(">H", self.rawdata[sbixBitmapHeaderFormatSize:])
				self.referenceGlyphName = ttFont.getGlyphName(gid)
			else:
				self.imageData = self.rawdata[sbixBitmapHeaderFormatSize:]
				self.referenceGlyphName = None
		# clean up
		del self.rawdata
		del self.gid
Example #53
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
Example #54
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
Example #55
0
	def __init__(self, file, checkChecksums=1, fontNumber=-1):
		self.file = file
		self.checkChecksums = checkChecksums

		self.flavor = None
		self.flavorData = None
		self.DirectoryEntry = SFNTDirectoryEntry
		self.sfntVersion = self.file.read(4)
		self.file.seek(0)
		if self.sfntVersion == b"ttcf":
			sstruct.unpack(ttcHeaderFormat, self.file.read(ttcHeaderSize), self)
			assert self.Version == 0x00010000 or self.Version == 0x00020000, "unrecognized TTC version 0x%08x" % self.Version
			if not 0 <= fontNumber < self.numFonts:
				from fontTools import ttLib
				raise ttLib.TTLibError("specify a font number between 0 and %d (inclusive)" % (self.numFonts - 1))
			offsetTable = struct.unpack(">%dL" % self.numFonts, self.file.read(self.numFonts * 4))
			if self.Version == 0x00020000:
				pass # ignoring version 2.0 signatures
			self.file.seek(offsetTable[fontNumber])
			sstruct.unpack(sfntDirectoryFormat, self.file.read(sfntDirectorySize), self)
		elif self.sfntVersion == b"wOFF":
			self.flavor = "woff"
			self.DirectoryEntry = WOFFDirectoryEntry
			sstruct.unpack(woffDirectoryFormat, self.file.read(woffDirectorySize), self)
		else:
			sstruct.unpack(sfntDirectoryFormat, self.file.read(sfntDirectorySize), self)
		self.sfntVersion = Tag(self.sfntVersion)

		if self.sfntVersion not in ("\x00\x01\x00\x00", "OTTO", "true"):
			from fontTools import ttLib
			raise ttLib.TTLibError("Not a TrueType or OpenType font (bad sfntVersion)")
		self.tables = {}
		for i in range(self.numTables):
			entry = self.DirectoryEntry()
			entry.fromFile(self.file)
			if entry.length > 0:
				self.tables[Tag(entry.tag)] = entry
			else:
				# Ignore zero-length tables. This doesn't seem to be documented,
				# yet it's apparently how the Windows TT rasterizer behaves.
				# Besides, at least one font has been sighted which actually
				# *has* a zero-length table.
				pass

		# Load flavor data if any
		if self.flavor == "woff":
			self.flavorData = WOFFFlavorData(self)
Example #56
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
Example #57
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
Example #58
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])
     if header["version"] != 0x00010000:
         raise TTLibError("unsupported 'avar' version %04x" % header["version"])
     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[fixedToFloat(fromValue, 14)] = fixedToFloat(toValue, 14)
             pos = pos + 4
     self.fixupSegments_(warn=warnings.warn)
Example #59
0
    def __init__(self, file, checkChecksums=1, 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)
Example #60
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 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())