From ff7cf2777763b7159447e99408482eb3d3bb5788 Mon Sep 17 00:00:00 2001 From: Sascha Brawer Date: Wed, 16 Aug 2017 19:43:25 +0200 Subject: [PATCH] [AAT] Fix binary search headers of AATLookup formats 2 and 6 In format 2 and 6, AAT lookups contain a binary search header with the number of elements in the lookup table. Before this change, the element count would also include the special trailing end-of-table value that is required by the font format specification. However, the binary search header should only count the actual elements without the trailer. Also, in the examples from the AAT specification, the special end-of-table entries use 0xFFFF for glyph ID keys, and zeroes for the filler values. Before this change, we had filled the values with 0xFF bytes. --- Lib/fontTools/ttLib/tables/otConverters.py | 12 ++++++------ Tests/ttLib/tables/otConverters_test.py | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Lib/fontTools/ttLib/tables/otConverters.py b/Lib/fontTools/ttLib/tables/otConverters.py index 9b5859a5d..b924fcdb0 100644 --- a/Lib/fontTools/ttLib/tables/otConverters.py +++ b/Lib/fontTools/ttLib/tables/otConverters.py @@ -649,7 +649,7 @@ class AATLookup(BaseConverter): def writeFormat2(self, writer, font, segments): writer.writeUShort(2) valueSize = self.converter.staticSize - numUnits, unitSize = len(segments) + 1, valueSize + 4 + numUnits, unitSize = len(segments), valueSize + 4 self.writeBinSearchHeader(writer, numUnits, unitSize) for firstGlyph, lastGlyph, value in segments: writer.writeUShort(lastGlyph) @@ -659,18 +659,18 @@ class AATLookup(BaseConverter): value=value, repeatIndex=None) writer.writeUShort(0xFFFF) writer.writeUShort(0xFFFF) - writer.writeData(b'\xFF' * valueSize) + writer.writeData(b'\x00' * valueSize) def buildFormat6(self, writer, font, values): valueSize = self.converter.staticSize - numUnits, unitSize = len(values) + 1, valueSize + 2 - return (2 + self.BIN_SEARCH_HEADER_SIZE + numUnits * unitSize, 6, + numUnits, unitSize = len(values), valueSize + 2 + return (2 + self.BIN_SEARCH_HEADER_SIZE + (numUnits + 1) * unitSize, 6, lambda: self.writeFormat6(writer, font, values)) def writeFormat6(self, writer, font, values): writer.writeUShort(6) valueSize = self.converter.staticSize - numUnits, unitSize = len(values) + 1, valueSize + 2 + numUnits, unitSize = len(values), valueSize + 2 self.writeBinSearchHeader(writer, numUnits, unitSize) for glyphID, value in values: writer.writeUShort(glyphID) @@ -678,7 +678,7 @@ class AATLookup(BaseConverter): writer, font, tableDict=None, value=value, repeatIndex=None) writer.writeUShort(0xFFFF) - writer.writeData(b'\xFF' * valueSize) + writer.writeData(b'\x00' * valueSize) def buildFormat8(self, writer, font, values): minGlyphID, maxGlyphID = values[0][0], values[-1][0] diff --git a/Tests/ttLib/tables/otConverters_test.py b/Tests/ttLib/tables/otConverters_test.py index 72d8038b1..10919b194 100644 --- a/Tests/ttLib/tables/otConverters_test.py +++ b/Tests/ttLib/tables/otConverters_test.py @@ -199,7 +199,7 @@ class AATLookupTest(unittest.TestCase): def test_readFormat2(self): reader = OTTableReader(deHexStr( - "0002 0006 0003 000C 0001 0006 " + "0002 0006 0002 000C 0001 0006 " "0002 0001 0003 " # glyph A..B: map to C "0007 0005 0008 " # glyph E..G: map to H "FFFF FFFF FFFF")) # end of search table @@ -227,7 +227,7 @@ class AATLookupTest(unittest.TestCase): def test_readFormat6(self): reader = OTTableReader(deHexStr( - "0006 0004 0003 0008 0001 0004 " + "0006 0004 0002 0008 0001 0004 " "0003 0001 " # C --> A "0005 0002 " # E --> B "FFFF FFFF")) # end of search table @@ -279,13 +279,13 @@ class AATLookupTest(unittest.TestCase): self.assertEqual(writer.getData(), deHexStr( "0002 " # format=2 "0006 " # binSrchHeader.unitSize=6 - "0003 " # binSrchHeader.nUnits=3 + "0002 " # binSrchHeader.nUnits=2 "000C " # binSrchHeader.searchRange=12 "0001 " # binSrchHeader.entrySelector=1 - "0006 " # binSrchHeader.rangeShift=6 + "0000 " # binSrchHeader.rangeShift=0 "0005 0002 0003 " # segments[0].lastGlyph=E, firstGlyph=B, value=C "0008 0007 0001 " # segments[1].lastGlyph=H, firstGlyph=G, value=A - "FFFF FFFF FFFF " # segments[2]= + "FFFF FFFF 0000 " # segments[2]= )) def test_writeFormat6(self): @@ -300,15 +300,15 @@ class AATLookupTest(unittest.TestCase): self.assertEqual(writer.getData(), deHexStr( "0006 " # format=6 "0004 " # binSrchHeader.unitSize=4 - "0005 " # binSrchHeader.nUnits=5 + "0004 " # binSrchHeader.nUnits=4 "0010 " # binSrchHeader.searchRange=16 "0002 " # binSrchHeader.entrySelector=2 - "0004 " # binSrchHeader.rangeShift=4 + "0000 " # binSrchHeader.rangeShift=0 "0001 0003 " # entries[0].glyph=A, .value=C "0003 0002 " # entries[1].glyph=C, .value=B "0004 0004 " # entries[2].glyph=D, .value=D "0005 0005 " # entries[3].glyph=E, .value=E - "FFFF FFFF " # entries[4]= + "FFFF 0000 " # entries[4]= )) def test_writeFormat8(self):