[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.
This commit is contained in:
Sascha Brawer 2017-08-16 19:43:25 +02:00
parent 77876e8df4
commit ff7cf27777
2 changed files with 14 additions and 14 deletions

View File

@ -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]

View File

@ -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]=<END>
"FFFF FFFF 0000 " # segments[2]=<END>
))
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]=<END>
"FFFF 0000 " # entries[4]=<END>
))
def test_writeFormat8(self):