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 safeEval
      5 from . import DefaultTable
      6 
      7 maxpFormat_0_5 = """
      8 		>	# big endian
      9 		tableVersion:           i
     10 		numGlyphs:              H
     11 """
     12 
     13 maxpFormat_1_0_add = """
     14 		>	# big endian
     15 		maxPoints:              H
     16 		maxContours:            H
     17 		maxCompositePoints:     H
     18 		maxCompositeContours:   H
     19 		maxZones:               H
     20 		maxTwilightPoints:      H
     21 		maxStorage:             H
     22 		maxFunctionDefs:        H
     23 		maxInstructionDefs:     H
     24 		maxStackElements:       H
     25 		maxSizeOfInstructions:  H
     26 		maxComponentElements:   H
     27 		maxComponentDepth:      H
     28 """
     29 
     30 
     31 class table__m_a_x_p(DefaultTable.DefaultTable):
     32 	
     33 	dependencies = ['glyf']
     34 	
     35 	def decompile(self, data, ttFont):
     36 		dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self)
     37 		self.numGlyphs = int(self.numGlyphs)
     38 		if self.tableVersion != 0x00005000:
     39 			dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self)
     40 		assert len(data) == 0
     41 	
     42 	def compile(self, ttFont):
     43 		if 'glyf' in ttFont:
     44 			if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
     45 				self.recalc(ttFont)
     46 		else:
     47 			pass  # CFF
     48 		self.numGlyphs = len(ttFont.getGlyphOrder())
     49 		if self.tableVersion != 0x00005000:
     50 			self.tableVersion = 0x00010000
     51 		data = sstruct.pack(maxpFormat_0_5, self)
     52 		if self.tableVersion == 0x00010000:
     53 			data = data + sstruct.pack(maxpFormat_1_0_add, self)
     54 		return data
     55 	
     56 	def recalc(self, ttFont):
     57 		"""Recalculate the font bounding box, and most other maxp values except
     58 		for the TT instructions values. Also recalculate the value of bit 1
     59 		of the flags field and the font bounding box of the 'head' table.
     60 		"""
     61 		glyfTable = ttFont['glyf']
     62 		hmtxTable = ttFont['hmtx']
     63 		headTable = ttFont['head']
     64 		self.numGlyphs = len(glyfTable)
     65 		INFINITY = 100000
     66 		xMin = +INFINITY
     67 		yMin = +INFINITY
     68 		xMax = -INFINITY
     69 		yMax = -INFINITY
     70 		maxPoints = 0
     71 		maxContours = 0
     72 		maxCompositePoints = 0
     73 		maxCompositeContours = 0
     74 		maxComponentElements = 0
     75 		maxComponentDepth = 0
     76 		allXMaxIsLsb = 1
     77 		for glyphName in ttFont.getGlyphOrder():
     78 			g = glyfTable[glyphName]
     79 			if g.numberOfContours:
     80 				if hmtxTable[glyphName][1] != g.xMin:
     81 					allXMaxIsLsb = 0
     82 				xMin = min(xMin, g.xMin)
     83 				yMin = min(yMin, g.yMin)
     84 				xMax = max(xMax, g.xMax)
     85 				yMax = max(yMax, g.yMax)
     86 				if g.numberOfContours > 0:
     87 					nPoints, nContours = g.getMaxpValues()
     88 					maxPoints = max(maxPoints, nPoints)
     89 					maxContours = max(maxContours, nContours)
     90 				else:
     91 					nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable)
     92 					maxCompositePoints = max(maxCompositePoints, nPoints)
     93 					maxCompositeContours = max(maxCompositeContours, nContours)
     94 					maxComponentElements = max(maxComponentElements, len(g.components))
     95 					maxComponentDepth = max(maxComponentDepth, componentDepth)
     96 		if xMin == +INFINITY:
     97 			headTable.xMin = 0
     98 			headTable.yMin = 0
     99 			headTable.xMax = 0
    100 			headTable.yMax = 0
    101 		else:
    102 		    headTable.xMin = xMin
    103 		    headTable.yMin = yMin
    104 		    headTable.xMax = xMax
    105 		    headTable.yMax = yMax
    106 		self.maxPoints = maxPoints
    107 		self.maxContours = maxContours
    108 		self.maxCompositePoints = maxCompositePoints
    109 		self.maxCompositeContours = maxCompositeContours
    110 		self.maxComponentDepth = maxComponentDepth
    111 		if allXMaxIsLsb:
    112 			headTable.flags = headTable.flags | 0x2
    113 		else:
    114 			headTable.flags = headTable.flags & ~0x2
    115 	
    116 	def testrepr(self):
    117 		items = sorted(self.__dict__.items())
    118 		print(". . . . . . . . .")
    119 		for combo in items:
    120 			print("  %s: %s" % combo)
    121 		print(". . . . . . . . .")
    122 	
    123 	def toXML(self, writer, ttFont):
    124 		if self.tableVersion != 0x00005000:
    125 			writer.comment("Most of this table will be recalculated by the compiler")
    126 			writer.newline()
    127 		formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
    128 		if self.tableVersion != 0x00005000:
    129 			formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
    130 			names = names + names_1_0
    131 		for name in names:
    132 			value = getattr(self, name)
    133 			if name == "tableVersion":
    134 				value = hex(value)
    135 			writer.simpletag(name, value=value)
    136 			writer.newline()
    137 	
    138 	def fromXML(self, name, attrs, content, ttFont):
    139 		setattr(self, name, safeEval(attrs["value"]))
    140 		
    141 
    142