Home | History | Annotate | Download | only in misc
      1 from __future__ import print_function, division, absolute_import
      2 from fontTools.misc.py23 import *
      3 from fontTools import ttLib
      4 from fontTools.misc.textTools import safeEval
      5 from fontTools.ttLib.tables.DefaultTable import DefaultTable
      6 import os
      7 
      8 
      9 class TTXParseError(Exception): pass
     10 
     11 BUFSIZE = 0x4000
     12 
     13 
     14 class XMLReader(object):
     15 	
     16 	def __init__(self, fileName, ttFont, progress=None, quiet=False):
     17 		self.ttFont = ttFont
     18 		self.fileName = fileName
     19 		self.progress = progress
     20 		self.quiet = quiet
     21 		self.root = None
     22 		self.contentStack = []
     23 		self.stackSize = 0
     24 	
     25 	def read(self):
     26 		if self.progress:
     27 			import stat
     28 			self.progress.set(0, os.stat(self.fileName)[stat.ST_SIZE] // 100 or 1)
     29 		file = open(self.fileName)
     30 		self._parseFile(file)
     31 		file.close()
     32 	
     33 	def _parseFile(self, file):
     34 		from xml.parsers.expat import ParserCreate
     35 		parser = ParserCreate()
     36 		parser.StartElementHandler = self._startElementHandler
     37 		parser.EndElementHandler = self._endElementHandler
     38 		parser.CharacterDataHandler = self._characterDataHandler
     39 		
     40 		pos = 0
     41 		while True:
     42 			chunk = file.read(BUFSIZE)
     43 			if not chunk:
     44 				parser.Parse(chunk, 1)
     45 				break
     46 			pos = pos + len(chunk)
     47 			if self.progress:
     48 				self.progress.set(pos // 100)
     49 			parser.Parse(chunk, 0)
     50 	
     51 	def _startElementHandler(self, name, attrs):
     52 		stackSize = self.stackSize
     53 		self.stackSize = stackSize + 1
     54 		if not stackSize:
     55 			if name != "ttFont":
     56 				raise TTXParseError("illegal root tag: %s" % name)
     57 			sfntVersion = attrs.get("sfntVersion")
     58 			if sfntVersion is not None:
     59 				if len(sfntVersion) != 4:
     60 					sfntVersion = safeEval('"' + sfntVersion + '"')
     61 				self.ttFont.sfntVersion = sfntVersion
     62 			self.contentStack.append([])
     63 		elif stackSize == 1:
     64 			subFile = attrs.get("src")
     65 			if subFile is not None:
     66 				subFile = os.path.join(os.path.dirname(self.fileName), subFile)
     67 				subReader = XMLReader(subFile, self.ttFont, self.progress, self.quiet)
     68 				subReader.read()
     69 				self.contentStack.append([])
     70 				return
     71 			tag = ttLib.xmlToTag(name)
     72 			msg = "Parsing '%s' table..." % tag
     73 			if self.progress:
     74 				self.progress.setlabel(msg)
     75 			elif self.ttFont.verbose:
     76 				ttLib.debugmsg(msg)
     77 			else:
     78 				if not self.quiet:
     79 					print(msg)
     80 			if tag == "GlyphOrder":
     81 				tableClass = ttLib.GlyphOrder
     82 			elif "ERROR" in attrs or ('raw' in attrs and safeEval(attrs['raw'])):
     83 				tableClass = DefaultTable
     84 			else:
     85 				tableClass = ttLib.getTableClass(tag)
     86 				if tableClass is None:
     87 					tableClass = DefaultTable
     88 			if tag == 'loca' and tag in self.ttFont:
     89 				# Special-case the 'loca' table as we need the
     90 				#    original if the 'glyf' table isn't recompiled.
     91 				self.currentTable = self.ttFont[tag]
     92 			else:
     93 				self.currentTable = tableClass(tag)
     94 				self.ttFont[tag] = self.currentTable
     95 			self.contentStack.append([])
     96 		elif stackSize == 2:
     97 			self.contentStack.append([])
     98 			self.root = (name, attrs, self.contentStack[-1])
     99 		else:
    100 			l = []
    101 			self.contentStack[-1].append((name, attrs, l))
    102 			self.contentStack.append(l)
    103 	
    104 	def _characterDataHandler(self, data):
    105 		if self.stackSize > 1:
    106 			self.contentStack[-1].append(data)
    107 	
    108 	def _endElementHandler(self, name):
    109 		self.stackSize = self.stackSize - 1
    110 		del self.contentStack[-1]
    111 		if self.stackSize == 1:
    112 			self.root = None
    113 		elif self.stackSize == 2:
    114 			name, attrs, content = self.root
    115 			self.currentTable.fromXML(name, attrs, content, self.ttFont)
    116 			self.root = None
    117 
    118 
    119 class ProgressPrinter(object):
    120 	
    121 	def __init__(self, title, maxval=100):
    122 		print(title)
    123 	
    124 	def set(self, val, maxval=None):
    125 		pass
    126 	
    127 	def increment(self, val=1):
    128 		pass
    129 	
    130 	def setLabel(self, text):
    131 		print(text)
    132 
    133