• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from __future__ import print_function, division, absolute_import
2from fontTools import ttLib
3from fontTools.ttLib.tables import otTables as ot
4
5# VariationStore
6
7def buildVarRegionAxis(axisSupport):
8	self = ot.VarRegionAxis()
9	self.StartCoord, self.PeakCoord, self.EndCoord = [float(v) for v in axisSupport]
10	return self
11
12def 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
21def 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
31def _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
42def 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
67ot.VarData.calculateNumShorts = VarData_calculateNumShorts
68
69def 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
75def VarData_optimize(self):
76	return VarData_calculateNumShorts(self, optimize=True)
77
78ot.VarData.optimize = VarData_optimize
79
80
81def 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
95def 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
106def buildVarIdxMap(varIdxes, glyphOrder):
107	self = ot.VarIdxMap()
108	self.mapping = {g:v for g,v in zip(glyphOrder, varIdxes)}
109	return self
110
111def buildVarDevTable(varIdx):
112	self = ot.Device()
113	self.DeltaFormat = 0x8000
114	self.StartSize = varIdx >> 16
115	self.EndSize = varIdx & 0xFFFF
116	return self
117