Skip to content

Commit

Permalink
Merge pull request #2679 from fonttools/avar2
Browse files Browse the repository at this point in the history
Avar2
  • Loading branch information
behdad committed Mar 15, 2023
2 parents a55a545 + 2edbbc1 commit 05872d6
Show file tree
Hide file tree
Showing 23 changed files with 237 additions and 53 deletions.
99 changes: 57 additions & 42 deletions Lib/fontTools/ttLib/tables/_a_v_a_r.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,20 @@
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
Expand All @@ -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)
Expand All @@ -105,9 +103,24 @@ def toXML(self, writer, ttFont):
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:
Expand All @@ -121,3 +134,5 @@ def fromXML(self, name, attrs, content, ttFont):
"duplicate entry for %s in axis '%s'", fromValue, axis
)
segment[fromValue] = toValue
else:
super().fromXML(name, attrs, content, ttFont)
2 changes: 0 additions & 2 deletions Lib/fontTools/ttLib/tables/otConverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,10 @@ class Version(SimpleValue):

def read(self, reader, font, tableDict):
value = reader.readLong()
assert (value >> 16) == 1, "Unsupported version 0x%08x" % value
return value

def write(self, writer, font, tableDict, value, repeatIndex=None):
value = fi2ve(value)
assert (value >> 16) == 1, "Unsupported version 0x%08x" % value
writer.writeLong(value)

@staticmethod
Expand Down
76 changes: 76 additions & 0 deletions Lib/fontTools/ttLib/tables/otData.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -6157,4 +6157,80 @@
),
],
),
#
# avar
#
(
"AxisValueMap",
[
(
"F2Dot14",
"FromCoordinate",
None,
None,
"A normalized coordinate value obtained using default normalization",
),
(
"F2Dot14",
"ToCoordinate",
None,
None,
"The modified, normalized coordinate value",
),
],
),
(
"AxisSegmentMap",
[
(
"uint16",
"PositionMapCount",
None,
None,
"The number of correspondence pairs for this axis",
),
(
"AxisValueMap",
"AxisValueMap",
"PositionMapCount",
0,
"The array of axis value map records for this axis",
),
],
),
(
"avar",
[
(
"Version",
"Version",
None,
None,
"Version of the avar table- 0x00010000 or 0x00020000",
),
("uint16", "Reserved", None, None, "Permanently reserved; set to zero"),
(
"uint16",
"AxisCount",
None,
None,
'The number of variation axes for this font. This must be the same number as axisCount in the "fvar" table',
),
(
"AxisSegmentMap",
"AxisSegmentMap",
"AxisCount",
0,
'The segment maps array — one segment map for each axis, in the order of axes specified in the "fvar" table',
),
(
"LOffsetTo(DeltaSetIndexMap)",
"VarIdxMap",
None,
"Version >= 0x00020000",
"",
),
("LOffset", "VarStore", None, "Version >= 0x00020000", ""),
],
),
]
1 change: 1 addition & 0 deletions Tests/cffLib/data/TestCFF2Widths.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@
</STAT>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/cffLib/data/TestSparseCFF2VF.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -1809,6 +1809,7 @@
</VORG>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/subset/data/TestGVAR.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@
</GSUB>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/subset/data/TestHVVAR.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@
</VVAR>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/subset/data/expect_HVVAR.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
</VVAR>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/subset/data/expect_HVVAR_retain_gids.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
</VVAR>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/subset/data/expect_keep_gvar.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</GlyphOrder>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/subset/data/expect_keep_gvar_notdef_outline.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</GlyphOrder>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/ttLib/data/I-512upem.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -2668,6 +2668,7 @@
</STAT>

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="0.0" to="0.0"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/ttLib/data/TestTTF_normalizeLocation.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.36">

<avar>
<version major="1" minor="0"/>
<segment axis="wght">
<mapping from="-1.0" to="-1.0"/>
<mapping from="-0.5" to="-0.75"/>
Expand Down
1 change: 1 addition & 0 deletions Tests/ttLib/data/varc-ac00-ac01-500upem.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@
</post>

<avar>
<version major="1" minor="0"/>
<segment axis="0000">
</segment>
<segment axis="0001">
Expand Down

0 comments on commit 05872d6

Please sign in to comment.