[varLib.builder] Implement building 32bit VarStore
The full optimizer in varLib.varStore still needs to be updated. But this pretty much enables building 32bit VarStores, even if they won't be fully optimal. Part of https://github.com/fonttools/fonttools/issues/2279
This commit is contained in:
parent
802e3636bc
commit
e454e96238
@ -26,39 +26,40 @@ def buildVarRegionList(supports, axisTags):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def _reorderItem(lst, narrows, zeroes):
|
def _reorderItem(lst, mapping):
|
||||||
out = []
|
return [lst[i] for i in mapping]
|
||||||
count = len(lst)
|
|
||||||
for i in range(count):
|
|
||||||
if i not in narrows:
|
|
||||||
out.append(lst[i])
|
|
||||||
for i in range(count):
|
|
||||||
if i in narrows and i not in zeroes:
|
|
||||||
out.append(lst[i])
|
|
||||||
return out
|
|
||||||
|
|
||||||
def VarData_calculateNumShorts(self, optimize=False):
|
def VarData_calculateNumShorts(self, optimize=False):
|
||||||
count = self.VarRegionCount
|
count = self.VarRegionCount
|
||||||
items = self.Item
|
items = self.Item
|
||||||
narrows = set(range(count))
|
bit_lengths = [0] * count
|
||||||
zeroes = set(range(count))
|
|
||||||
for item in items:
|
for item in items:
|
||||||
wides = [i for i in narrows if not (-128 <= item[i] <= 127)]
|
bl = [(i + (i < -1)).bit_length() for i in item]
|
||||||
narrows.difference_update(wides)
|
bit_lengths = [max(*pair) for pair in zip(bl, bit_lengths)]
|
||||||
nonzeroes = [i for i in zeroes if item[i]]
|
byte_lengths = [((b + 8) // 8) if b else 0 for b in bit_lengths]
|
||||||
zeroes.difference_update(nonzeroes)
|
|
||||||
if not narrows and not zeroes:
|
# https://github.com/fonttools/fonttools/issues/2279
|
||||||
break
|
longWords = any(b > 2 for b in byte_lengths)
|
||||||
|
|
||||||
if optimize:
|
if optimize:
|
||||||
# Reorder columns such that all SHORT columns come before UINT8
|
# Reorder columns such that wider columns come before narrower columns
|
||||||
self.VarRegionIndex = _reorderItem(self.VarRegionIndex, narrows, zeroes)
|
mapping = []
|
||||||
|
mapping.extend(i for i,b in enumerate(byte_lengths) if b > 2)
|
||||||
|
mapping.extend(i for i,b in enumerate(byte_lengths) if b == 2)
|
||||||
|
mapping.extend(i for i,b in enumerate(byte_lengths) if b == 1)
|
||||||
|
|
||||||
|
byte_lengths = _reorderItem(byte_lengths, mapping)
|
||||||
|
self.VarRegionIndex = _reorderItem(self.VarRegionIndex, mapping)
|
||||||
self.VarRegionCount = len(self.VarRegionIndex)
|
self.VarRegionCount = len(self.VarRegionIndex)
|
||||||
for i in range(len(items)):
|
for i in range(len(items)):
|
||||||
items[i] = _reorderItem(items[i], narrows, zeroes)
|
items[i] = _reorderItem(items[i], mapping)
|
||||||
self.NumShorts = count - len(narrows)
|
|
||||||
|
if longWords:
|
||||||
|
self.NumShorts = max((i for i,b in enumerate(byte_lengths) if b > 2), default=-1) + 1
|
||||||
|
self.NumShorts |= 0x8000
|
||||||
else:
|
else:
|
||||||
wides = set(range(count)) - narrows
|
self.NumShorts = max((i for i,b in enumerate(byte_lengths) if b > 1), default=-1) + 1
|
||||||
self.NumShorts = 1+max(wides) if wides else 0
|
|
||||||
self.VarRegionCount = len(self.VarRegionIndex)
|
self.VarRegionCount = len(self.VarRegionIndex)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user