Home | History | Annotate | Download | only in tables
      1 from __future__ import print_function, division, absolute_import
      2 from fontTools.misc.py23 import *
      3 from fontTools.misc import sstruct
      4 from fontTools.misc.textTools import readHex
      5 import struct
      6 
      7 
      8 sbixBitmapHeaderFormat = """
      9 	>
     10 	usReserved1:     H    # 00 00
     11 	usReserved2:     H    #       00 00
     12 	imageFormatTag:  4s   # e.g. "png "
     13 """
     14 
     15 sbixBitmapHeaderFormatSize = sstruct.calcsize(sbixBitmapHeaderFormat)
     16 
     17 
     18 class Bitmap(object):
     19 	def __init__(self, glyphName=None, referenceGlyphName=None, usReserved1=0, usReserved2=0, imageFormatTag=None, imageData=None, rawdata=None, gid=0):
     20 		self.gid = gid
     21 		self.glyphName = glyphName
     22 		self.referenceGlyphName = referenceGlyphName
     23 		self.usReserved1 = usReserved1
     24 		self.usReserved2 = usReserved2
     25 		self.rawdata = rawdata
     26 		self.imageFormatTag = imageFormatTag
     27 		self.imageData = imageData
     28 
     29 	def decompile(self, ttFont):
     30 		self.glyphName = ttFont.getGlyphName(self.gid)
     31 		if self.rawdata is None:
     32 			from fontTools import ttLib
     33 			raise ttLib.TTLibError("No table data to decompile")
     34 		if len(self.rawdata) > 0:
     35 			if len(self.rawdata) < sbixBitmapHeaderFormatSize:
     36 				from fontTools import ttLib
     37 				#print "Bitmap %i header too short: Expected %x, got %x." % (self.gid, sbixBitmapHeaderFormatSize, len(self.rawdata))
     38 				raise ttLib.TTLibError("Bitmap header too short.")
     39 
     40 			sstruct.unpack(sbixBitmapHeaderFormat, self.rawdata[:sbixBitmapHeaderFormatSize], self)
     41 
     42 			if self.imageFormatTag == "dupe":
     43 				# bitmap is a reference to another glyph's bitmap
     44 				gid, = struct.unpack(">H", self.rawdata[sbixBitmapHeaderFormatSize:])
     45 				self.referenceGlyphName = ttFont.getGlyphName(gid)
     46 			else:
     47 				self.imageData = self.rawdata[sbixBitmapHeaderFormatSize:]
     48 				self.referenceGlyphName = None
     49 		# clean up
     50 		del self.rawdata
     51 		del self.gid
     52 
     53 	def compile(self, ttFont):
     54 		if self.glyphName is None:
     55 			from fontTools import ttLib
     56 			raise ttLib.TTLibError("Can't compile bitmap without glyph name")
     57 			# TODO: if ttFont has no maxp, cmap etc., ignore glyph names and compile by index?
     58 			# (needed if you just want to compile the sbix table on its own)
     59 		self.gid = struct.pack(">H", ttFont.getGlyphID(self.glyphName))
     60 		if self.imageFormatTag is None:
     61 			self.rawdata = ""
     62 		else:
     63 			self.rawdata = sstruct.pack(sbixBitmapHeaderFormat, self) + self.imageData
     64 
     65 	def toXML(self, xmlWriter, ttFont):
     66 		if self.imageFormatTag == None:
     67 			# TODO: ignore empty bitmaps?
     68 			# a bitmap entry is required for each glyph,
     69 			# but empty ones can be calculated at compile time
     70 			xmlWriter.simpletag("bitmap", glyphname=self.glyphName)
     71 			xmlWriter.newline()
     72 			return
     73 		xmlWriter.begintag("bitmap", format=self.imageFormatTag, glyphname=self.glyphName)
     74 		xmlWriter.newline()
     75 		#xmlWriter.simpletag("usReserved1", value=self.usReserved1)
     76 		#xmlWriter.newline()
     77 		#xmlWriter.simpletag("usReserved2", value=self.usReserved2)
     78 		#xmlWriter.newline()
     79 		if self.imageFormatTag == "dupe":
     80 			# format == "dupe" is apparently a reference to another glyph id.
     81 			xmlWriter.simpletag("ref", glyphname=self.referenceGlyphName)
     82 		else:
     83 			xmlWriter.begintag("hexdata")
     84 			xmlWriter.newline()
     85 			xmlWriter.dumphex(self.imageData)
     86 			xmlWriter.endtag("hexdata")
     87 		xmlWriter.newline()
     88 		xmlWriter.endtag("bitmap")
     89 		xmlWriter.newline()
     90 
     91 	def fromXML(self, name, attrs, content, ttFont):
     92 		#if name in ["usReserved1", "usReserved2"]:
     93 		#	setattr(self, name, int(attrs["value"]))
     94 		#elif
     95 		if name == "ref":
     96 			# bitmap is a "dupe", i.e. a reference to another bitmap.
     97 			# in this case imageData contains the glyph id of the reference glyph
     98 			# get glyph id from glyphname
     99 			self.imageData = struct.pack(">H", ttFont.getGlyphID(attrs["glyphname"]))
    100 		elif name == "hexdata":
    101 			self.imageData = readHex(content)
    102 		else:
    103 			from fontTools import ttLib
    104 			raise ttLib.TTLibError("can't handle '%s' element" % name)
    105