Correct Android failure to open an old CJK font

* src/sfnt.c (sfnt_read_cmap_format_2): Properly compute
subtable count, and append the empty table at position 0.
(sfnt_lookup_glyph_2): Update commentary.
This commit is contained in:
Po Lu 2024-08-20 21:56:41 +08:00
parent 45ae4de0e7
commit 3419e7ea52

View file

@ -383,15 +383,18 @@ sfnt_read_cmap_format_2 (int fd,
for (i = 0; i < 256; ++i) for (i = 0; i < 256; ++i)
{ {
/* Values in sub_header_keys are actually offsets from the end of
that array. Since the language of the spec is such as to imply
that they must be divisible by eight, divide them by the
same. */
sfnt_swap16 (&format2->sub_header_keys[i]); sfnt_swap16 (&format2->sub_header_keys[i]);
if (format2->sub_header_keys[i] > nsub) if (format2->sub_header_keys[i] > nsub)
nsub = format2->sub_header_keys[i]; nsub = format2->sub_header_keys[i] / 8;
} }
if (!nsub) /* There always exists a subheader at index zero. */
/* If there are no subheaders, then things are finished. */ nsub ++;
return format2;
/* Otherwise, read the rest of the variable length data to the end /* Otherwise, read the rest of the variable length data to the end
of format2. */ of format2. */
@ -1108,9 +1111,11 @@ sfnt_lookup_glyph_2 (sfnt_char character,
&& j <= ((int) subheader->first_code && j <= ((int) subheader->first_code
+ (int) subheader->entry_count)) + (int) subheader->entry_count))
{ {
/* id_range_offset is actually the number of bytes past /* id_range_offset is actually the number of bytes past itself
itself containing the uint16_t ``slice''. It is possibly containing the uint16_t ``slice''. Whether this may be
unaligned. */ unaligned is not stated in the specification, but I doubt
it, for that would render values meaningless if the array
were byte swapped when read. */
slice = (unsigned char *) &subheader->id_range_offset; slice = (unsigned char *) &subheader->id_range_offset;
slice += subheader->id_range_offset; slice += subheader->id_range_offset;
slice += (j - subheader->first_code) * sizeof (uint16_t); slice += (j - subheader->first_code) * sizeof (uint16_t);