Home | History | Annotate | Download | only in varLib
      1 from __future__ import print_function, division, absolute_import
      2 from fontTools import ttLib
      3 from fontTools.ttLib.tables import otTables as ot
      4 
      5 # VariationStore
      6 
      7 def buildVarRegionAxis(axisSupport):
      8 	self = ot.VarRegionAxis()
      9 	self.StartCoord, self.PeakCoord, self.EndCoord = [float(v) for v in axisSupport]
     10 	return self
     11 
     12 def buildVarRegion(support, axisTags):
     13 	assert all(tag in axisTags for tag in support.keys()), ("Unknown axis tag found.", support, axisTags)
     14 	self = ot.VarRegion()
     15 	self.VarRegionAxis = []
     16 	for tag in axisTags:
     17 		self.VarRegionAxis.append(buildVarRegionAxis(support.get(tag, (0,0,0))))
     18 	self.VarRegionAxisCount = len(self.VarRegionAxis)
     19 	return self
     20 
     21 def buildVarRegionList(supports, axisTags):
     22 	self = ot.VarRegionList()
     23 	self.RegionAxisCount = len(axisTags)
     24 	self.Region = []
     25 	for support in supports:
     26 		self.Region.append(buildVarRegion(support, axisTags))
     27 	self.RegionCount = len(self.Region)
     28 	return self
     29 
     30 
     31 def _reorderItem(lst, narrows, zeroes):
     32 	out = []
     33 	count = len(lst)
     34 	for i in range(count):
     35 		if i not in narrows:
     36 			out.append(lst[i])
     37 	for i in range(count):
     38 		if i in narrows  and i not in zeroes:
     39 			out.append(lst[i])
     40 	return out
     41 
     42 def VarData_calculateNumShorts(self, optimize=False):
     43 	count = self.VarRegionCount
     44 	items = self.Item
     45 	narrows = set(range(count))
     46 	zeroes = set(range(count))
     47 	for item in items:
     48 		wides = [i for i in narrows if not (-128 <= item[i] <= 127)]
     49 		narrows.difference_update(wides)
     50 		nonzeroes = [i for i in zeroes if item[i]]
     51 		zeroes.difference_update(nonzeroes)
     52 		if not narrows and not zeroes:
     53 			break
     54 	if optimize:
     55 		# Reorder columns such that all SHORT columns come before UINT8
     56 		self.VarRegionIndex = _reorderItem(self.VarRegionIndex, narrows, zeroes)
     57 		self.VarRegionCount = len(self.VarRegionIndex)
     58 		for i in range(len(items)):
     59 			items[i] = _reorderItem(items[i], narrows, zeroes)
     60 		self.NumShorts = count - len(narrows)
     61 	else:
     62 		wides = set(range(count)) - narrows
     63 		self.NumShorts = 1+max(wides) if wides else 0
     64 	self.VarRegionCount = len(self.VarRegionIndex)
     65 	return self
     66 
     67 ot.VarData.calculateNumShorts = VarData_calculateNumShorts
     68 
     69 def VarData_CalculateNumShorts(self, optimize=True):
     70 	"""Deprecated name for VarData_calculateNumShorts() which
     71 	defaults to optimize=True.  Use varData.calculateNumShorts()
     72 	or varData.optimize()."""
     73 	return VarData_calculateNumShorts(self, optimize=optimize)
     74 
     75 def VarData_optimize(self):
     76 	return VarData_calculateNumShorts(self, optimize=True)
     77 
     78 ot.VarData.optimize = VarData_optimize
     79 
     80 
     81 def buildVarData(varRegionIndices, items, optimize=True):
     82 	self = ot.VarData()
     83 	self.VarRegionIndex = list(varRegionIndices)
     84 	regionCount = self.VarRegionCount = len(self.VarRegionIndex)
     85 	records = self.Item = []
     86 	if items:
     87 		for item in items:
     88 			assert len(item) == regionCount
     89 			records.append(list(item))
     90 	self.ItemCount = len(self.Item)
     91 	self.calculateNumShorts(optimize=optimize)
     92 	return self
     93 
     94 
     95 def buildVarStore(varRegionList, varDataList):
     96 	self = ot.VarStore()
     97 	self.Format = 1
     98 	self.VarRegionList = varRegionList
     99 	self.VarData = list(varDataList)
    100 	self.VarDataCount = len(self.VarData)
    101 	return self
    102 
    103 
    104 # Variation helpers
    105 
    106 def buildVarIdxMap(varIdxes, glyphOrder):
    107 	self = ot.VarIdxMap()
    108 	self.mapping = {g:v for g,v in zip(glyphOrder, varIdxes)}
    109 	return self
    110 
    111 def buildVarDevTable(varIdx):
    112 	self = ot.Device()
    113 	self.DeltaFormat = 0x8000
    114 	self.StartSize = varIdx >> 16
    115 	self.EndSize = varIdx & 0xFFFF
    116 	return self
    117