Skip to content

Commit

Permalink
Merge pull request #3126 from fonttools/varStore-quantize
Browse files Browse the repository at this point in the history
Var store quantize
  • Loading branch information
behdad committed May 25, 2023
2 parents 62bca25 + a08f5eb commit 5255c01
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 4 deletions.
18 changes: 14 additions & 4 deletions Lib/fontTools/varLib/varStore.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ def _row_characteristics(row):
return chars


def VarStore_optimize(self, use_NO_VARIATION_INDEX=True):
def VarStore_optimize(self, use_NO_VARIATION_INDEX=True, quantization=1):
"""Optimize storage. Returns mapping from old VarIdxes to new ones."""

# Overview:
Expand Down Expand Up @@ -551,8 +551,16 @@ def VarStore_optimize(self, use_NO_VARIATION_INDEX=True):

for minor, item in enumerate(data.Item):
row = list(zeroes)
for regionIdx, v in zip(regionIndices, item):
row[regionIdx] += v

if quantization == 1:
for regionIdx, v in zip(regionIndices, item):
row[regionIdx] += v
else:
for regionIdx, v in zip(regionIndices, item):
row[regionIdx] += (
round(v / quantization) * quantization
) # TODO https://github.com/fonttools/fonttools/pull/3126#discussion_r1205439785

row = tuple(row)

if use_NO_VARIATION_INDEX and not any(row):
Expand Down Expand Up @@ -684,13 +692,15 @@ def main(args=None):
from fontTools.ttLib.tables.otBase import OTTableWriter

parser = ArgumentParser(prog="varLib.varStore", description=main.__doc__)
parser.add_argument("--quantization", type=int, default=1)
parser.add_argument("fontfile")
parser.add_argument("outfile", nargs="?")
options = parser.parse_args(args)

# TODO: allow user to configure logging via command-line options
configLogger(level="INFO")

quantization = options.quantization
fontfile = options.fontfile
outfile = options.outfile

Expand All @@ -703,7 +713,7 @@ def main(args=None):
size = len(writer.getAllData())
print("Before: %7d bytes" % size)

varidx_map = store.optimize()
varidx_map = store.optimize(quantization=quantization)

writer = OTTableWriter()
store.compile(writer, font)
Expand Down
54 changes: 54 additions & 0 deletions Tests/varLib/varStore_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,57 @@ def test_optimize(numRegions, varData, expectedNumVarData, expectedBytes):
data = writer.getAllData()

assert len(data) == expectedBytes, xml


@pytest.mark.parametrize(
"quantization, expectedBytes",
[
(1, 200),
(2, 180),
(3, 170),
(4, 175),
(8, 170),
(32, 152),
(64, 146),
],
)
def test_quantize(quantization, expectedBytes):
varData = [
[0, 11, 12, 0, 20],
[0, 13, 12, 0, 20],
[0, 14, 12, 0, 20],
[0, 15, 12, 0, 20],
[0, 16, 12, 0, 20],
[10, 300, 0, 0, 20],
[10, 301, 0, 0, 20],
[10, 302, 0, 0, 20],
[10, 303, 0, 0, 20],
[10, 304, 0, 0, 20],
]

numRegions = 5
locations = [{i: i / 16384.0} for i in range(numRegions)]
axisTags = sorted({k for loc in locations for k in loc})

model = VariationModel(locations)

builder = OnlineVarStoreBuilder(axisTags)
builder.setModel(model)

for data in varData:
builder.storeMasters(data)

varStore = builder.finish()
varStore.optimize(quantization=quantization)

dummyFont = TTFont()

writer = XMLWriter(StringIO())
varStore.toXML(writer, dummyFont)
xml = writer.file.getvalue()

writer = OTTableWriter()
varStore.compile(writer, dummyFont)
data = writer.getAllData()

assert len(data) == expectedBytes, xml

0 comments on commit 5255c01

Please sign in to comment.