From e3ba7a7e0b46719e031e5a9bbe6339035eeb2575 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Jan 2024 13:35:09 -0700 Subject: [PATCH] [lazyTools] Simplify based on review feedback --- Lib/fontTools/misc/lazyTools.py | 4 +- Lib/fontTools/ttLib/tables/_g_v_a_r.py | 58 ++++++++--------- Lib/fontTools/ttLib/tables/otConverters.py | 72 +++++++++++----------- 3 files changed, 66 insertions(+), 68 deletions(-) diff --git a/Lib/fontTools/misc/lazyTools.py b/Lib/fontTools/misc/lazyTools.py index a3cc52e53..91cb80c99 100644 --- a/Lib/fontTools/misc/lazyTools.py +++ b/Lib/fontTools/misc/lazyTools.py @@ -11,7 +11,7 @@ class LazyDict(UserDict): def __getitem__(self, k): v = self.data[k] if callable(v): - v = v(self, k) + v = v(k) self.data[k] = v return v @@ -23,7 +23,7 @@ class LazyList(UserList): return [self[i] for i in indices] v = self.data[k] if callable(v): - v = v(self, k) + v = v(k) self.data[k] = v return v diff --git a/Lib/fontTools/ttLib/tables/_g_v_a_r.py b/Lib/fontTools/ttLib/tables/_g_v_a_r.py index a44f72b66..044f65f71 100644 --- a/Lib/fontTools/ttLib/tables/_g_v_a_r.py +++ b/Lib/fontTools/ttLib/tables/_g_v_a_r.py @@ -40,26 +40,6 @@ GVAR_HEADER_FORMAT = """ GVAR_HEADER_SIZE = sstruct.calcsize(GVAR_HEADER_FORMAT) -def _decompileVarGlyph(self, glyphName): - gid = self.reverseGlyphMap[glyphName] - offsetSize = 2 if self.tableFormat == 0 else 4 - startOffset = GVAR_HEADER_SIZE + offsetSize * gid - endOffset = startOffset + offsetSize * 2 - offsets = table__g_v_a_r.decompileOffsets_( - self.gvarData[startOffset:endOffset], - tableFormat=self.tableFormat, - glyphCount=1, - ) - gvarData = self.gvarData[ - self.offsetToData + offsets[0] : self.offsetToData + offsets[1] - ] - if not gvarData: - return [] - glyph = self._glyf[glyphName] - numPointsInGlyph = self._gvar.getNumPoints_(glyph) - return decompileGlyph_(numPointsInGlyph, self.sharedCoords, self.axisTags, gvarData) - - class table__g_v_a_r(DefaultTable.DefaultTable): dependencies = ["fvar", "glyf"] @@ -131,17 +111,33 @@ class table__g_v_a_r(DefaultTable.DefaultTable): offsetToData = self.offsetToGlyphVariationData glyf = ttFont["glyf"] - l = LazyDict( - {glyphs[gid]: _decompileVarGlyph for gid in range(self.glyphCount)} - ) - l.reverseGlyphMap = ttFont.getReverseGlyphMap() - l._glyf = glyf - l._gvar = self - l.gvarData = data - l.offsetToData = offsetToData - l.sharedCoords = sharedCoords - l.axisTags = axisTags - l.tableFormat = self.flags & 1 + def get_read_item(): + reverseGlyphMap = ttFont.getReverseGlyphMap() + tableFormat = self.flags & 1 + + def read_item(glyphName): + gid = reverseGlyphMap[glyphName] + offsetSize = 2 if tableFormat == 0 else 4 + startOffset = GVAR_HEADER_SIZE + offsetSize * gid + endOffset = startOffset + offsetSize * 2 + offsets = table__g_v_a_r.decompileOffsets_( + data[startOffset:endOffset], + tableFormat=tableFormat, + glyphCount=1, + ) + gvarData = data[offsetToData + offsets[0] : offsetToData + offsets[1]] + if not gvarData: + return [] + glyph = glyf[glyphName] + numPointsInGlyph = self.getNumPoints_(glyph) + return decompileGlyph_( + numPointsInGlyph, sharedCoords, axisTags, gvarData + ) + + return read_item + + read_item = get_read_item() + l = LazyDict({glyphs[gid]: read_item for gid in range(self.glyphCount)}) self.variations = l diff --git a/Lib/fontTools/ttLib/tables/otConverters.py b/Lib/fontTools/ttLib/tables/otConverters.py index aee2de547..a66c9e858 100644 --- a/Lib/fontTools/ttLib/tables/otConverters.py +++ b/Lib/fontTools/ttLib/tables/otConverters.py @@ -109,11 +109,6 @@ def buildConverters(tableSpec, tableNamespace): return converters, convertersByName -def _base_converter_read_item(self, i): - self.reader.seek(self.pos + i * self.recordSize) - return self.conv.read(self.reader, self.font, {}) - - class BaseConverter(object): """Base class for converter objects. Apart from the constructor, this is an abstract class.""" @@ -162,13 +157,19 @@ class BaseConverter(object): l.append(self.read(reader, font, tableDict)) return l else: - l = LazyList(_base_converter_read_item for i in range(count)) - l.reader = reader.copy() - l.pos = l.reader.pos - l.font = font - l.conv = self - l.recordSize = recordSize + def get_read_item(): + reader_copy = reader.copy() + pos = reader.pos + + def read_item(i): + reader_copy.seek(pos + i * recordSize) + return self.read(reader_copy, font, {}) + + return read_item + + read_item = get_read_item() + l = LazyList(read_item for i in range(count)) reader.advance(count * recordSize) return l @@ -1819,21 +1820,6 @@ class TupleValues: xmlWriter.newline() -def cff2_index_read_item(self, i): - self.reader.seek(self.offset_pos + i * self.offSize) - offsets = self.readArray(2) - self.reader.seek(self.data_pos + offsets[0]) - item = self.reader.readData(offsets[1] - offsets[0]) - - if self._itemClass is not None: - obj = self._itemClass() - obj.decompile(item, self.font, self.reader.localState) - item = obj - elif self._converter is not None: - item = self._converter.read(item, self.font) - return item - - class CFF2Index(BaseConverter): def __init__( self, @@ -1892,15 +1878,31 @@ class CFF2Index(BaseConverter): lastOffset = offset return items else: - l = LazyList([cff2_index_read_item] * count) - l.reader = reader.copy() - l.offset_pos = l.reader.pos - l.data_pos = l.offset_pos + (count + 1) * offSize - l.font = font - l._itemClass = self._itemClass - l.offSize = offSize - l.readArray = getReadArray(l.reader, offSize) - l._converter = self._converter + + def get_read_item(): + reader_copy = reader.copy() + offset_pos = reader.pos + data_pos = offset_pos + (count + 1) * offSize + readArray = getReadArray(reader_copy, offSize) + + def read_item(i): + reader_copy.seek(offset_pos + i * offSize) + offsets = readArray(2) + reader_copy.seek(data_pos + offsets[0]) + item = reader_copy.readData(offsets[1] - offsets[0]) + + if self._itemClass is not None: + obj = self._itemClass() + obj.decompile(item, self.font, reader_copy.localState) + item = obj + elif self._converter is not None: + item = self._converter.read(item, font) + return item + + return read_item + + read_item = get_read_item() + l = LazyList([read_item] * count) # TODO: Advance reader