diff --git a/Lib/fontTools/ttLib/tables/_k_e_r_n.py b/Lib/fontTools/ttLib/tables/_k_e_r_n.py
index f9b64c615..cc98fabf1 100644
--- a/Lib/fontTools/ttLib/tables/_k_e_r_n.py
+++ b/Lib/fontTools/ttLib/tables/_k_e_r_n.py
@@ -37,15 +37,14 @@ class table__k_e_r_n(DefaultTable.DefaultTable):
for i in range(nTables):
if self.version == 1.0:
# Apple
- length, coverage = struct.unpack(">LH", data[:6])
+ length, coverage, subtableFormat = struct.unpack(">LBB", data[:6])
else:
# in OpenType spec the "version" field refers to the common
# subtable header; the actual subtable format is stored in
# the last 8 mask bits of "coverage" field.
# Since this "version" is always 0 (and is not present in the
# later AAT extensions), we simply ignore it here
- _, length, coverage = struct.unpack(">HHH", data[:6])
- subtableFormat = coverage & 0xff
+ _, length, subtableFormat, coverage = struct.unpack(">HHBB", data[:6])
if subtableFormat not in kern_classes:
subtable = KernTable_format_unkown(subtableFormat)
else:
@@ -103,7 +102,8 @@ class KernTable_format_0(object):
def decompile(self, data, ttFont):
if not self.apple:
- version, length, coverage = struct.unpack(">HHH", data[:6])
+ version, length, subtableFormat, coverage = struct.unpack(
+ ">HHBB", data[:6])
if version != 0:
from fontTools.ttLib import TTLibError
raise TTLibError(
@@ -112,9 +112,10 @@ class KernTable_format_0(object):
# Should we also assert length == len(data)?
data = data[6:]
else:
- length, coverage, tupleIndex = struct.unpack(">LHH", data[:8])
+ length, coverage, subtableFormat, tupleIndex = struct.unpack(
+ ">LBBH", data[:8])
data = data[8:]
- assert self.format == coverage & 0xFF, "unsupported format"
+ assert self.format == subtableFormat, "unsupported format"
self.coverage = coverage
self.tupleIndex = tupleIndex
@@ -168,13 +169,12 @@ class KernTable_format_0(object):
for left, right, value in kernTable:
data = data + struct.pack(">HHh", left, right, value)
- # ensure mask bits 8-15 (subtable format) are set to 0
- self.coverage &= ~0xFF
if not self.apple:
version = 0
length = len(data) + 6
- header = struct.pack(">HHH", version, length, self.coverage)
+ header = struct.pack(
+ ">HHBB", version, length, self.format, self.coverage)
else:
if self.tupleIndex is None:
# sensible default when compiling a TTX from an old fonttools
@@ -183,7 +183,8 @@ class KernTable_format_0(object):
log.warning("'tupleIndex' is None; default to 0")
self.tupleIndex = 0
length = len(data) + 8
- header = struct.pack(">LHH", length, self.coverage, self.tupleIndex)
+ header = struct.pack(
+ ">LBBH", length, self.coverage, self.format, self.tupleIndex)
return header + data
def toXML(self, writer, ttFont):
diff --git a/Tests/ttLib/tables/_k_e_r_n_test.py b/Tests/ttLib/tables/_k_e_r_n_test.py
index ea843c58f..f45403ddd 100644
--- a/Tests/ttLib/tables/_k_e_r_n_test.py
+++ b/Tests/ttLib/tables/_k_e_r_n_test.py
@@ -13,7 +13,8 @@ KERN_VER_0_FMT_0_DATA = deHexStr(
'0001 ' # 2: nTables=1
'0000 ' # 4: version=0 (bogus field, unused)
'0020 ' # 6: length=32
- '0000 ' # 8: coverage=0
+ '00 ' # 8: format=0
+ '01 ' # 9: coverage=1
'0003 ' # 10: nPairs=3
'000C ' # 12: searchRange=12
'0001 ' # 14: entrySelector=1
@@ -26,7 +27,7 @@ assert len(KERN_VER_0_FMT_0_DATA) == 36
KERN_VER_0_FMT_0_XML = [
'',
- '',
+ '',
' ',
' ',
' ',
@@ -37,7 +38,8 @@ KERN_VER_1_FMT_0_DATA = deHexStr(
'0001 0000 ' # 0: version=1
'0000 0001 ' # 4: nTables=1
'0000 0022 ' # 8: length=34
- '0000 ' # 12: coverage=0
+ '00 ' # 12: coverage=0
+ '00 ' # 13: format=0
'0000 ' # 14: tupleIndex=0
'0003 ' # 16: nPairs=3
'000C ' # 18: searchRange=12
@@ -63,11 +65,13 @@ KERN_VER_0_FMT_UNKNOWN_DATA = deHexStr(
'0002 ' # 2: nTables=2
'0000 ' # 4: version=0
'000A ' # 6: length=10
- '0004 ' # 8: coverage=4 (format 4 doesn't exist)
+ '04 ' # 8: format=4 (format 4 doesn't exist)
+ '01 ' # 9: coverage=1
'1234 5678 ' # 10: garbage...
'0000 ' # 14: version=0
'000A ' # 16: length=10
- '0005 ' # 18: coverage=5 (format 5 doesn't exist)
+ '05 ' # 18: format=5 (format 5 doesn't exist)
+ '01 ' # 18: coverage=1
'9ABC DEF0 ' # 20: garbage...
)
assert len(KERN_VER_0_FMT_UNKNOWN_DATA) == 24
@@ -76,11 +80,13 @@ KERN_VER_1_FMT_UNKNOWN_DATA = deHexStr(
'0001 0000 ' # 0: version=1
'0000 0002 ' # 4: nTables=2
'0000 000C ' # 8: length=12
- '0004 ' # 12: coverage=4 (format 4 doesn't exist)
+ '00 ' # 12: coverage=0
+ '04 ' # 13: format=4 (format 4 doesn't exist)
'0000 ' # 14: tupleIndex=0
'1234 5678' # 16: garbage...
'0000 000C ' # 20: length=12
- '0005 ' # 18: coverage=5 (format 5 doesn't exist)
+ '00 ' # 18: coverage=0
+ '05 ' # 19: format=5 (format 5 doesn't exist)
'0000 ' # 20: tupleIndex=0
'9ABC DEF0 ' # 22: garbage...
)
@@ -113,7 +119,9 @@ class KernTableTest(object):
st = kern.kernTables[0]
assert st.apple is (version == 1.0)
assert st.format == 0
- assert st.coverage == 0
+ # horizontal kerning in OT kern is coverage 0x01, while in
+ # AAT kern it's the default (0)
+ assert st.coverage == (0 if st.apple else 1)
assert st.tupleIndex == (0 if st.apple else None)
assert len(st.kernTable) == 3
assert st.kernTable == {
@@ -136,7 +144,7 @@ class KernTableTest(object):
apple = version == 1.0
st = KernTable_format_0(apple)
kern.kernTables = [st]
- st.coverage = 0
+ st.coverage = (0 if apple else 1)
st.tupleIndex = 0 if apple else None
st.kernTable = {
('E', 'M'): -40,
@@ -165,7 +173,7 @@ class KernTableTest(object):
st = kern.kernTables[0]
assert st.apple is (version == 1.0)
assert st.format == 0
- assert st.coverage == 0
+ assert st.coverage == (0 if st.apple else 1)
assert st.tupleIndex == (0 if st.apple else None)
assert len(st.kernTable) == 3
assert st.kernTable == {
@@ -188,7 +196,7 @@ class KernTableTest(object):
apple = version == 1.0
st = KernTable_format_0(apple)
kern.kernTables = [st]
- st.coverage = 0
+ st.coverage = 0 if apple else 1
st.tupleIndex = 0 if apple else None
st.kernTable = {
('E', 'M'): -40,
@@ -238,13 +246,15 @@ class KernTableTest(object):
kern.kernTables = []
for unknown_fmt, kern_data in zip((4, 5), ("1234 5678", "9ABC DEF0")):
- coverage = unknown_fmt
if version > 0:
+ coverage = 0
header_fmt = deHexStr(
- "%08X %04X %04X" % (st_length, coverage, 0))
+ "%08X %02X %02X %04X" % (
+ st_length, coverage, unknown_fmt, 0))
else:
+ coverage = 1
header_fmt = deHexStr(
- "%04X %04X %04X" % (0, st_length, coverage))
+ "%04X %04X %02X %02X" % (0, st_length, unknown_fmt, coverage))
st = KernTable_format_unkown(unknown_fmt)
st.data = header_fmt + deHexStr(kern_data)
kern.kernTables.append(st)