Пример #1
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
Пример #2
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
Пример #3
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)
Пример #4
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
Пример #5
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)
Пример #6
0
    def decompile(self, ttFont):
        if self.data is None:
            from fontTools import ttLib

            raise (ttLib.TTLibError, "No table data to decompile.")
        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
Пример #7
0
	def decompile(self, ttFont):
		if self.data is None:
			from fontTools import ttLib
			raise(ttLib.TTLibError, "No table data to decompile.")
		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
Пример #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
Пример #9
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
Пример #10
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'))
Пример #11
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'))
Пример #12
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
Пример #13
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)
Пример #14
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
Пример #15
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):
			WOFF2Reader(BytesIO(data + self.file.read()))
Пример #16
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):
         WOFF2Reader(BytesIO(data + self.file.read()))
Пример #17
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()))
Пример #18
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
Пример #19
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()))
Пример #20
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
Пример #21
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 == "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 == "wOFF":
            self.flavor = "woff"
            self.DirectoryEntry = WOFFDirectoryEntry
            sstruct.unpack(woffDirectoryFormat,
                           self.file.read(woffDirectorySize), self)
        else:
            sstruct.unpack(sfntDirectoryFormat,
                           self.file.read(sfntDirectorySize), self)

        if self.sfntVersion not in ("\000\001\000\000", "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[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)
Пример #22
0
	def decompile(self, data, ttFont):
		dummy, data = sstruct.unpack2(OS2_format_0, data, self)
		if self.version == 1 and not data:
			# workaround for buggy Apple fonts
			self.version = 0
		if self.version == 1:
			sstruct.unpack2(OS2_format_1_addition, data, self)
		elif self.version in (2, 3, 4):
			sstruct.unpack2(OS2_format_2_addition, data, self)
		elif self.version != 0:
			from fontTools import ttLib
			raise ttLib.TTLibError("unknown format for OS/2 table: version %s" % self.version)
		self.panose = sstruct.unpack(panoseFormat, self.panose, Panose())
Пример #23
0
 def decompile(self, data, ttFont):
     dummy, data = sstruct.unpack2(OS2_format_0, data, self)
     if self.version == 1 and not data:
         # workaround for buggy Apple fonts
         self.version = 0
     if self.version == 1:
         sstruct.unpack2(OS2_format_1_addition, data, self)
     elif self.version in (2, 3, 4):
         sstruct.unpack2(OS2_format_2_addition, data, self)
     elif self.version <> 0:
         from fontTools import ttLib
         raise ttLib.TTLibError, "unknown format for OS/2 table: version %s" % self.version
     self.panose = sstruct.unpack(panoseFormat, self.panose, Panose())
Пример #24
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 == "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 == "wOFF":
			self.flavor = "woff"
			self.DirectoryEntry = WOFFDirectoryEntry
			sstruct.unpack(woffDirectoryFormat, self.file.read(woffDirectorySize), self)
		else:
			sstruct.unpack(sfntDirectoryFormat, self.file.read(sfntDirectorySize), self)

		if self.sfntVersion not in ("\000\001\000\000", "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[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)
Пример #25
0
	def decompile(self, data, ttFont):
		dummy, data = sstruct.unpack2(OS2_format_0, data, self)
		# workarounds for buggy fonts (Apple, mona)
		if not data:
			self.version = 0
		elif len(data) == sstruct.calcsize(OS2_format_1_addition):
			self.version = 1
		elif len(data) == sstruct.calcsize(OS2_format_2_addition):
			if self.version not in (2, 3, 4):
				self.version = 1
		else:
			from fontTools import ttLib
			raise ttLib.TTLibError, "unknown format for OS/2 table (incorrect length): version %s" % (self.version, len(data))
		if self.version == 1:
			sstruct.unpack2(OS2_format_1_addition, data, self)
		elif self.version in (2, 3, 4):
			sstruct.unpack2(OS2_format_2_addition, data, self)
		elif self.version <> 0:
			from fontTools import ttLib
			raise ttLib.TTLibError, "unknown format for OS/2 table: version %s" % self.version
		self.panose = sstruct.unpack(panoseFormat, self.panose, Panose())
Пример #26
0
 def decompile(self, data, ttFont):
     dummy, data = sstruct.unpack2(OS2_format_0, data, self)
     # workarounds for buggy fonts (Apple, mona)
     if not data:
         self.version = 0
     elif len(data) == sstruct.calcsize(OS2_format_1_addition):
         self.version = 1
     elif len(data) == sstruct.calcsize(OS2_format_2_addition):
         if self.version not in (2, 3, 4):
             self.version = 1
     else:
         from fontTools import ttLib
         raise ttLib.TTLibError, "unknown format for OS/2 table (incorrect length): version %s" % (
             self.version, len(data))
     if self.version == 1:
         sstruct.unpack2(OS2_format_1_addition, data, self)
     elif self.version in (2, 3, 4):
         sstruct.unpack2(OS2_format_2_addition, data, self)
     elif self.version <> 0:
         from fontTools import ttLib
         raise ttLib.TTLibError, "unknown format for OS/2 table: version %s" % self.version
     self.panose = sstruct.unpack(panoseFormat, self.panose, Panose())
Пример #27
0
 def __init__(self, file, checkChecksums=1, fontNumber=-1):
     self.file = file
     self.checkChecksums = checkChecksums
     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)
     if self.sfntVersion == b"ttcf":
         assert ttcHeaderSize == sfntDirectorySize
         sstruct.unpack(ttcHeaderFormat, data, self)
         assert self.Version == b'\0\1\0\0' or self.Version == b'\0\2\0\0', "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 == b'\0\2\0\0':
             pass  # ignoring version 2.0 signatures
         self.file.seek(offsetTable[fontNumber])
         data = self.file.read(sfntDirectorySize)
         sstruct.unpack(sfntDirectoryFormat, data, self)
     if self.sfntVersion not in (b'\0\1\0\0', b"OTTO", b"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 = SFNTDirectoryEntry()
         entry.fromFile(self.file)
         if entry.length > 0:
             self.tables[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
Пример #28
0
	def __init__(self, file, checkChecksums=1, fontNumber=-1):
		self.file = file
		self.checkChecksums = checkChecksums
		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)
		if self.sfntVersion == b"ttcf":
			assert ttcHeaderSize == sfntDirectorySize
			sstruct.unpack(ttcHeaderFormat, data, self)
			assert self.Version == b'\0\1\0\0' or self.Version == b'\0\2\0\0', "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 == b'\0\2\0\0':
				pass # ignoring version 2.0 signatures
			self.file.seek(offsetTable[fontNumber])
			data = self.file.read(sfntDirectorySize)
			sstruct.unpack(sfntDirectoryFormat, data, self)
		if self.sfntVersion not in (b'\0\1\0\0', b"OTTO", b"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 = SFNTDirectoryEntry()
			entry.fromFile(self.file)
			if entry.length > 0:
                                self.tables[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
Пример #29
0
 def fromString(self, str):
     sstruct.unpack(sfntDirectoryEntryFormat, str, self)
Пример #30
0
def checkSFNTConformance(file):
    """
    This function checks a SFNT file to see if it meets
    the conformance recomendations in the WOFF specification.
    This includes:
    - searchRange must be correct.
    - entrySelector must be correct.
    - rangeShift must be correct.
    - offset to each table must be after the table directory
      and before the end of the file.
    - offset + length of each table must not extend past
      the end of the file.
    - the table directory must be in ascending order.
    - tables must be padded to 4 byte boundaries.
    - the final table must be padded to a 4 byte boundary.
    - the gaps between table data blocks must not be more
      than necessary to pad the table to a 4 byte boundary.
    - the gap between the end of the final table and
      the end of the file must not be more than necessary
      to pad the table to a four byte boundary.
    - the checksums for each table in the table directory
      must be correct.
    - the head checkSumAdjustment must be correct.
    - the padding bytes must be null.

    The returned value of this function will be a list.
    If any errors were found, they will be represented
    as strings in the list.
    """
    # load the data
    closeFile = False
    if not hasattr(file, "read"):
        file = open(file, "rb")
        closeFile = True
    data = file.read()
    if closeFile:
        file.close()
    # storage
    errors = []
    # unpack the header
    headerData = data[:sfntDirectorySize]
    header = sstruct.unpack(sfntDirectoryFormat, headerData)
    # unpack the table directory
    numTables = header["numTables"]
    directoryData = data[sfntDirectorySize:sfntDirectorySize +
                         (sfntDirectoryEntrySize * numTables)]
    tableDirectory = []
    for index in range(numTables):
        entry = sstruct.unpack(sfntDirectoryEntryFormat,
                               directoryData[:sfntDirectoryEntrySize])
        tableDirectory.append(entry)
        directoryData = directoryData[sfntDirectoryEntrySize:]
    # sanity testing
    errors += _testOffsetBoundaryValidity(len(data), tableDirectory)
    errors += _testLengthBoundaryValidity(len(data), tableDirectory)
    # if one or more errors have already been found, something
    # is very wrong and this should come to a screeching halt.
    if errors:
        return errors
    # junk at the beginning of the file
    errors += _testJunkAtTheBeginningOfTheFile(header)
    # test directory order
    errors += _testDirectoryOrder(tableDirectory)
    # load the table data
    for entry in tableDirectory:
        offset = entry["offset"]
        length = entry["length"]
        entry["data"] = data[offset:offset + length]
    # test for overlaps
    errors += _testOverlaps(tableDirectory)
    # test for padding
    errors += _testOffsets(tableDirectory)
    # test the final table padding
    errors += _testFinalTablePadding(len(data), numTables,
                                     tableDirectory[-1]["tag"])
    # test for gaps
    errors += _testGaps(tableDirectory)
    # test for a gap at the end of the file
    errors += _testGapAfterFinalTable(len(data), tableDirectory)
    # test padding value
    errors += _testPaddingValue(tableDirectory, data)
    # validate checksums
    errors += _testCheckSums(tableDirectory)
    errors += _testHeadCheckSum(header, tableDirectory)
    # done.
    return errors
Пример #31
0
	def fromFile(self, file):
		sstruct.unpack(self.format, file.read(self.formatSize), self)
Пример #32
0
 def fromString(self, str):
     sstruct.unpack(sfntDirectoryEntryFormat, str, self)
Пример #33
0
 def fromFile(self, file):
     sstruct.unpack(sfntDirectoryEntryFormat, file.read(sfntDirectoryEntrySize), self)
Пример #34
0
	def decompile(self, data, ttFont):
		sstruct.unpack(vheaFormat, data, self)
Пример #35
0
 def test_num_tables(self):
     tags = [t for t in self.font.keys() if t not in ('GlyphOrder', 'DSIG')]
     data = self.file.read(woff2DirectorySize)
     header = sstruct.unpack(woff2DirectoryFormat, data)
     self.assertEqual(header['numTables'], len(tags))
Пример #36
0
def checkSFNTConformance(file):
    """
    This function checks a SFNT file to see if it meets
    the conformance recomendations in the WOFF specification.
    This includes:
    - searchRange must be correct.
    - entrySelector must be correct.
    - rangeShift must be correct.
    - offset to each table must be after the table directory
      and before the end of the file.
    - offset + length of each table must not extend past
      the end of the file.
    - the table directory must be in ascending order.
    - tables must be padded to 4 byte boundaries.
    - the final table must be padded to a 4 byte boundary.
    - the gaps between table data blocks must not be more
      than necessary to pad the table to a 4 byte boundary.
    - the gap between the end of the final table and
      the end of the file must not be more than necessary
      to pad the table to a four byte boundary.
    - the checksums for each table in the table directory
      must be correct.
    - the head checkSumAdjustment must be correct.
    - the padding bytes must be null.

    The returned value of this function will be a list.
    If any errors were found, they will be represented
    as strings in the list.
    """
    # load the data
    closeFile = False
    if not hasattr(file, "read"):
        file = open(file, "rb")
        closeFile = True
    data = file.read()
    if closeFile:
        file.close()
    # storage
    errors = []
    # unpack the header
    headerData = data[:sfntDirectorySize]
    header = sstruct.unpack(sfntDirectoryFormat, headerData)
    # unpack the table directory
    numTables = header["numTables"]
    directoryData = data[sfntDirectorySize : sfntDirectorySize + (sfntDirectoryEntrySize * numTables)]
    tableDirectory = []
    for index in range(numTables):
        entry = sstruct.unpack(sfntDirectoryEntryFormat, directoryData[:sfntDirectoryEntrySize])
        tableDirectory.append(entry)
        directoryData = directoryData[sfntDirectoryEntrySize:]
    # sanity testing
    errors += _testOffsetBoundaryValidity(len(data), tableDirectory)
    errors += _testLengthBoundaryValidity(len(data), tableDirectory)
    # if one or more errors have already been found, something
    # is very wrong and this should come to a screeching halt.
    if errors:
        return errors
    # junk at the beginning of the file
    errors += _testJunkAtTheBeginningOfTheFile(header)
    # test directory order
    errors += _testDirectoryOrder(tableDirectory)
    # load the table data
    for entry in tableDirectory:
        offset = entry["offset"]
        length = entry["length"]
        entry["data"] = data[offset:offset+length]
    # test for overlaps
    errors += _testOverlaps(tableDirectory)
    # test for padding
    errors += _testOffsets(tableDirectory)
    # test the final table padding
    errors += _testFinalTablePadding(len(data), numTables, tableDirectory[-1]["tag"])
    # test for gaps
    errors += _testGaps(tableDirectory)
    # test for a gap at the end of the file
    errors += _testGapAfterFinalTable(len(data), tableDirectory)
    # test padding value
    errors += _testPaddingValue(tableDirectory, data)
    # validate checksums
    errors += _testCheckSums(tableDirectory)
    errors += _testHeadCheckSum(header, tableDirectory)
    # done.
    return errors
Пример #37
0
	def fromString(self, str):
		sstruct.unpack(self.format, str, self)
Пример #38
0
	def test_num_tables(self):
		tags = [t for t in self.font.keys() if t not in ('GlyphOrder', 'DSIG')]
		data = self.file.read(woff2DirectorySize)
		header = sstruct.unpack(woff2DirectoryFormat, data)
		self.assertEqual(header['numTables'], len(tags))
Пример #39
0
 def decompile(self, data, ttFont):
     sstruct.unpack(vheaFormat, data, self)
Пример #40
0
 def fromFile(self, file):
     sstruct.unpack(sfntDirectoryEntryFormat,
                    file.read(sfntDirectoryEntrySize), self)
Пример #41
0
 def fromFile(self, file):
     sstruct.unpack(self.format, file.read(self.formatSize), self)
Пример #42
0
 def fromString(self, str):
     sstruct.unpack(self.format, str, self)