Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tottfgpos: Fix occasional fail to create lookups
[why] Sometimes, especially when generating fonts with a lot ligatures, fontforge can not create the font file correctly. A typical error message looks like this: Attempt to output 68142 into a 16-bit field. It will be truncated and the file may not be useful. This will already happen when the font is opened and generated without any change. But the generated font must contain the lookups of course. [how] When the lookup tables are written we need to check if the indices can be represented by 16 bit values. Big tables will often be longer. In the file first is comes the lookups table that points to all lookups. Then follow the lookups themselves. When a lookup would violate the 16 bit boundary we need a different and longer (!) entry in the lookups table, so all lookups will be shifted. For this reason the function tottfgpos.c:g___FigureExtensionSubTables() does this calculation recursively. Increasing the size of the lookups table step by step for each lookup, and then checking the previous lookups again (because they shifted). Unfortunately the check if the 16 bit boundary would be violated does not take the grown lookups table into account. Under some circumstances this means that a lookup, that fittet just-so before is now shifted because of the bigger lookups table and will then be too far away (i.e. index > 16 bit). In the calculation the `len` (size increase) of the lookups table needs to be included. [note] In the `fontforge/tottfgsub.c`: g___FigureExtensionSubTables() 3179: if ( sub->subtable_offset+offset>65535 ) 3218: sub->subtable_offset += len; and later: dumpg___info() 3410: efile=g___FigureExtensionSubTables(all,offset,is_gpos); 3423: putshort(g___,offset+sub->subtable_offset); On line 3179 is decided if a figure-extension has to be used, from the original offsets sum. One offset is then changed on line 3218. On line 3423 we push out the changed offset sum as 16 bits, but did not check if the changed (3218) offset values would fit. There is this comment nearby in the code /* Offset to lookup data which is in the temp file */ /* we keep adjusting offset so it reflects the distance between */ /* here and the place where the temp file will start, and then */ /* we need to skip l->offset bytes in the temp file */ /* If it's a big GPOS/SUB table we may also need some extension */ /* pointers, but FigureExtension will adjust for that */ [note] This fix has been triggered by ryanoasis/nerd-fonts#694 Reported-by: Gulajava Ministudio <GulajavaMinistudio> Reported-by: Rui Ming (Max) Xiong <xsrvmy> Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
- Loading branch information