[varLib.builder] Document bit-tweedling

https://github.com/fonttools/fonttools/pull/2285#discussion_r628401241
This commit is contained in:
Behdad Esfahbod 2021-05-07 15:41:11 -06:00
parent b8963256fd
commit 98e2bf5526
2 changed files with 19 additions and 5 deletions

View File

@ -1630,10 +1630,10 @@ class VarDataValue(BaseConverter):
longWords = bool(wordCount & 0x8000)
wordCount = wordCount & 0x7FFF
(readBigArray, readSmallArray) = {
False: (reader.readShortArray, reader.readInt8Array),
True: (reader.readLongArray, reader.readShortArray),
}[longWords]
if longWords:
readBigArray, readSmallArray = reader.readLongArray, reader.readShortArray
else:
readBigArray, readSmallArray = reader.readShortArray, reader.readInt8Array
n1, n2 = min(regionCount, wordCount), max(regionCount, wordCount)
values.extend(readBigArray(n1))

View File

@ -34,9 +34,23 @@ def VarData_calculateNumShorts(self, optimize=False):
items = self.Item
bit_lengths = [0] * count
for item in items:
# The "+ (i < -1)" magic is to handle two's-compliment.
# That is, we want to get back 7 for -128, whereas
# bit_length() returns 8. Similarly for -65536.
# The reason "i < -1" is used instead of "i < 0" is that
# the latter would make it return 0 for "-1" instead of 1.
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]
# The addition of 8, instead of seven, is to account for the sign bit.
# This "((b + 8) >> 3) if b else 0" when combined with the above
# "(i + (i < -1)).bit_length()" is a faster way to compute byte-lengths
# conforming to:
#
# byte_length = (0 if i == 0 else
# 1 if -128 <= i < 128 else
# 2 if -65536 <= i < 65536 else
# ...)
byte_lengths = [((b + 8) >> 3) 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)