diff options
Diffstat (limited to 'Lib/fontTools/ttLib/tables/_a_v_a_r.py')
-rw-r--r-- | Lib/fontTools/ttLib/tables/_a_v_a_r.py | 104 |
1 files changed, 60 insertions, 44 deletions
diff --git a/Lib/fontTools/ttLib/tables/_a_v_a_r.py b/Lib/fontTools/ttLib/tables/_a_v_a_r.py index 16f2a219..39039cf7 100644 --- a/Lib/fontTools/ttLib/tables/_a_v_a_r.py +++ b/Lib/fontTools/ttLib/tables/_a_v_a_r.py @@ -5,29 +5,20 @@ from fontTools.misc.fixedTools import ( floatToFixedToStr as fl2str, strToFixedToFloat as str2fl, ) -from fontTools.misc.textTools import bytesjoin +from fontTools.misc.textTools import bytesjoin, safeEval from fontTools.ttLib import TTLibError from . import DefaultTable +from . import otTables import struct import logging log = logging.getLogger(__name__) -# Apple's documentation of 'avar': -# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6avar.html +from .otBase import BaseTTXConverter -AVAR_HEADER_FORMAT = """ - > # big endian - majorVersion: H - minorVersion: H - reserved: H - axisCount: H -""" -assert sstruct.calcsize(AVAR_HEADER_FORMAT) == 8, sstruct.calcsize(AVAR_HEADER_FORMAT) - -class table__a_v_a_r(DefaultTable.DefaultTable): +class table__a_v_a_r(BaseTTXConverter): """Axis Variations Table This class represents the ``avar`` table of a variable font. The object has one @@ -54,46 +45,53 @@ class table__a_v_a_r(DefaultTable.DefaultTable): dependencies = ["fvar"] def __init__(self, tag=None): - DefaultTable.DefaultTable.__init__(self, tag) + super().__init__(tag) self.segments = {} def compile(self, ttFont): axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] - header = { - "majorVersion": 1, - "minorVersion": 0, - "reserved": 0, - "axisCount": len(axisTags) - } - result = [sstruct.pack(AVAR_HEADER_FORMAT, header)] + if not hasattr(self, "table"): + self.table = otTables.avar() + if not hasattr(self.table, "Reserved"): + self.table.Reserved = 0 + self.table.Version = (getattr(self, "majorVersion", 1) << 16) | getattr( + self, "minorVersion", 0 + ) + self.table.AxisCount = len(axisTags) + self.table.AxisSegmentMap = [] for axis in axisTags: - mappings = sorted(self.segments[axis].items()) - result.append(struct.pack(">H", len(mappings))) - for key, value in mappings: - fixedKey = fl2fi(key, 14) - fixedValue = fl2fi(value, 14) - result.append(struct.pack(">hh", fixedKey, fixedValue)) - return bytesjoin(result) + mappings = self.segments[axis] + segmentMap = otTables.AxisSegmentMap() + segmentMap.PositionMapCount = len(mappings) + segmentMap.AxisValueMap = [] + for key, value in sorted(mappings.items()): + valueMap = otTables.AxisValueMap() + valueMap.FromCoordinate = key + valueMap.ToCoordinate = value + segmentMap.AxisValueMap.append(valueMap) + self.table.AxisSegmentMap.append(segmentMap) + return super().compile(ttFont) def decompile(self, data, ttFont): + super().decompile(data, ttFont) + assert self.table.Version >= 0x00010000 + self.majorVersion = self.table.Version >> 16 + self.minorVersion = self.table.Version & 0xFFFF axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] - header = {} - headerSize = sstruct.calcsize(AVAR_HEADER_FORMAT) - header = sstruct.unpack(AVAR_HEADER_FORMAT, data[0:headerSize]) - majorVersion = header["majorVersion"] - if majorVersion != 1: - raise TTLibError("unsupported 'avar' version %d" % majorVersion) - pos = headerSize for axis in axisTags: + self.segments[axis] = {} + for axis, segmentMap in zip(axisTags, self.table.AxisSegmentMap): segments = self.segments[axis] = {} - numPairs = struct.unpack(">H", data[pos:pos+2])[0] - pos = pos + 2 - for _ in range(numPairs): - fromValue, toValue = struct.unpack(">hh", data[pos:pos+4]) - segments[fi2fl(fromValue, 14)] = fi2fl(toValue, 14) - pos = pos + 4 + for segment in segmentMap.AxisValueMap: + segments[segment.FromCoordinate] = segment.ToCoordinate def toXML(self, writer, ttFont): + writer.simpletag( + "version", + major=getattr(self, "majorVersion", 1), + minor=getattr(self, "minorVersion", 0), + ) + writer.newline() axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] for axis in axisTags: writer.begintag("segment", axis=axis) @@ -105,9 +103,24 @@ class table__a_v_a_r(DefaultTable.DefaultTable): writer.newline() writer.endtag("segment") writer.newline() + if getattr(self, "majorVersion", 1) >= 2: + if self.table.VarIdxMap: + self.table.VarIdxMap.toXML(writer, ttFont, name="VarIdxMap") + if self.table.VarStore: + self.table.VarStore.toXML(writer, ttFont) def fromXML(self, name, attrs, content, ttFont): - if name == "segment": + if not hasattr(self, "table"): + self.table = otTables.avar() + if not hasattr(self.table, "Reserved"): + self.table.Reserved = 0 + if name == "version": + self.majorVersion = safeEval(attrs["major"]) + self.minorVersion = safeEval(attrs["minor"]) + self.table.Version = (getattr(self, "majorVersion", 1) << 16) | getattr( + self, "minorVersion", 0 + ) + elif name == "segment": axis = attrs["axis"] segment = self.segments[axis] = {} for element in content: @@ -117,6 +130,9 @@ class table__a_v_a_r(DefaultTable.DefaultTable): fromValue = str2fl(elementAttrs["from"], 14) toValue = str2fl(elementAttrs["to"], 14) if fromValue in segment: - log.warning("duplicate entry for %s in axis '%s'", - fromValue, axis) + log.warning( + "duplicate entry for %s in axis '%s'", fromValue, axis + ) segment[fromValue] = toValue + else: + super().fromXML(name, attrs, content, ttFont) |