[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
|
||||
|
||||
|
||||
def _reorderItem(lst, narrows, zeroes):
|
||||
out = []
|
||||
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 _reorderItem(lst, mapping):
|
||||
return [lst[i] for i in mapping]
|
||||
|
||||
def VarData_calculateNumShorts(self, optimize=False):
|
||||
count = self.VarRegionCount
|
||||
items = self.Item
|
||||
narrows = set(range(count))
|
||||
zeroes = set(range(count))
|
||||
bit_lengths = [0] * count
|
||||
for item in items:
|
||||
wides = [i for i in narrows if not (-128 <= item[i] <= 127)]
|
||||
narrows.difference_update(wides)
|
||||
nonzeroes = [i for i in zeroes if item[i]]
|
||||
zeroes.difference_update(nonzeroes)
|
||||
if not narrows and not zeroes:
|
||||
break
|
||||
bl = [(i + (i < -1)).bit_length() for i in item]
|
||||
bit_lengths = [max(*pair) for pair in zip(bl, bit_lengths)]
|
||||
byte_lengths = [((b + 8) // 8) if b else 0 for b in bit_lengths]
|
||||
|
||||
# https://github.com/fonttools/fonttools/issues/2279
|
||||
longWords = any(b > 2 for b in byte_lengths)
|
||||
|
||||
if optimize:
|
||||
# Reorder columns such that all SHORT columns come before UINT8
|
||||
self.VarRegionIndex = _reorderItem(self.VarRegionIndex, narrows, zeroes)
|
||||
# Reorder columns such that wider columns come before narrower columns
|
||||
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)
|
||||
for i in range(len(items)):
|
||||
items[i] = _reorderItem(items[i], narrows, zeroes)
|
||||
self.NumShorts = count - len(narrows)
|
||||
items[i] = _reorderItem(items[i], mapping)
|
||||
|
||||
if longWords:
|
||||
self.NumShorts = max((i for i,b in enumerate(byte_lengths) if b > 2), default=-1) + 1
|
||||
self.NumShorts |= 0x8000
|
||||
else:
|
||||
wides = set(range(count)) - narrows
|
||||
self.NumShorts = 1+max(wides) if wides else 0
|
||||
self.NumShorts = max((i for i,b in enumerate(byte_lengths) if b > 1), default=-1) + 1
|
||||
|
||||
self.VarRegionCount = len(self.VarRegionIndex)
|
||||
return self
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user