From 32bd6bcc31c4152ee4e0edff34f9258f2611424b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 11 Aug 2016 01:02:52 -0700 Subject: [PATCH] [varLib] Add optimizeVarData() Though not really effective right now since we don't split into multiple VarData sets. --- Lib/fontTools/ttLib/tables/otTables.py | 5 +++- Lib/fontTools/varLib/__init__.py | 5 ++++ Lib/fontTools/varLib/builder.py | 36 +++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index b286b2d7e..a41ed6c37 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -193,11 +193,14 @@ class VarData(BaseTable): rawTable = self.__dict__.copy() numShorts = 0 + count = self.VarRegionCount for item in self.Item: - for i in range(len(item) - 1, numShorts - 1, -1): + for i in range(count - 1, numShorts - 1, -1): if not (-128 <= item[i] <= 127): numShorts = i + 1 break + if numShorts == count: + break rawTable['NumShorts'] = numShorts return rawTable diff --git a/Lib/fontTools/varLib/__init__.py b/Lib/fontTools/varLib/__init__.py index d9525bd75..f3f7fe3a3 100644 --- a/Lib/fontTools/varLib/__init__.py +++ b/Lib/fontTools/varLib/__init__.py @@ -488,6 +488,11 @@ def _add_HVAR(font, model, master_ttfs, axes): items.append(hAdvanceDeltas.get(glyphName, zeroes)) while items and items[-1] is zeroes: del items[-1] + + # TODO Add indirect mapping to save on duplicates + #uniq = set(items) + #if (len(items) - len(uniq)) * len(varTupleIndexs)) > len(items) * 2: + varData = builder.buildVarData(varTupleIndexes, items) varStore = builder.buildVarStore(varTupleList, [varData]) diff --git a/Lib/fontTools/varLib/builder.py b/Lib/fontTools/varLib/builder.py index 33e9339e5..5bd89c065 100644 --- a/Lib/fontTools/varLib/builder.py +++ b/Lib/fontTools/varLib/builder.py @@ -26,7 +26,38 @@ def buildVarRegionList(supports, axisTags): self.VarRegionCount = len(self.VarRegion) return self -def buildVarData(varRegionIndices, items): + +def _reorderItem(lst, narrows): + 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: + out.append(lst[i]) + return out + +def optimizeVarData(self): + # Reorder columns such that all SHORT columns come before UINT8 + count = self.VarRegionCount + items = self.Item + narrows = set(range(count)) + for item in items: + for i in narrows: + if not (-128 <= item[i] <= 127): + narrows.remove(i) + break + if not narrows: + break + + self.VarRegionIndex = _reorderItem(self.VarRegionIndex, narrows) + for i in range(self.ItemCount): + items[i] = _reorderItem(items[i], narrows) + + return self + +def buildVarData(varRegionIndices, items, optimize=True): self = ot.VarData() self.VarRegionIndex = list(varRegionIndices) regionCount = self.VarRegionCount = len(self.VarRegionIndex) @@ -35,8 +66,11 @@ def buildVarData(varRegionIndices, items): assert len(item) == regionCount records.append(list(item)) self.ItemCount = len(self.Item) + if optimize: + optimizeVarData(self) return self + def buildVarStore(varTupleList, varDataList): self = ot.VarStore() self.Format = 1