]> git.eshelyaron.com Git - emacs.git/commitdiff
Properly parse format 4 cmap tables
authorPo Lu <luangruo@yahoo.com>
Thu, 24 Aug 2023 08:32:42 +0000 (16:32 +0800)
committerPo Lu <luangruo@yahoo.com>
Thu, 24 Aug 2023 08:36:13 +0000 (16:36 +0800)
* src/sfnt.c (sfnt_read_cmap_format_4): Read range_shift field
propery.  Prior to this, it would be inadvertently treated as an
entry within the segment end code array, which only functioned
by happenstance.
(sfnt_lookup_glyph_4): Remove workaround grounded upon an
erroneous interpretation of the bug fixed by the aformentioned
change.

* src/sfnt.h (struct sfnt_cmap_format_4): Introduce previously
absent `range_shift' field.

src/sfnt.c
src/sfnt.h

index c987ec424413e0ce9317bcd6f2d25b6fc282a017..87a11019b1312e89e12d38ff33c98774c1a08ff7 100644 (file)
@@ -432,7 +432,7 @@ sfnt_read_cmap_format_4 (int fd,
   int seg_count, i;
 
   min_bytes = SFNT_ENDOF (struct sfnt_cmap_format_4,
-                         entry_selector, uint16_t);
+                         range_shift, uint16_t);
 
   /* Check that the length is at least min_bytes.  */
   if (header->length < min_bytes)
@@ -460,6 +460,7 @@ sfnt_read_cmap_format_4 (int fd,
   sfnt_swap16 (&format4->seg_count_x2);
   sfnt_swap16 (&format4->search_range);
   sfnt_swap16 (&format4->entry_selector);
+  sfnt_swap16 (&format4->range_shift);
 
   /* Get the number of segments to read.  */
   seg_count = format4->seg_count_x2 / 2;
@@ -467,7 +468,7 @@ sfnt_read_cmap_format_4 (int fd,
   /* Now calculate whether or not the size is sufficiently large.  */
   bytes_minus_format4
     = format4->length - SFNT_ENDOF (struct sfnt_cmap_format_4,
-                                   entry_selector, uint16_t);
+                                   range_shift, uint16_t);
   variable_size = (seg_count * sizeof *format4->end_code
                   + sizeof *format4->reserved_pad
                   + seg_count * sizeof *format4->start_code
@@ -1222,27 +1223,6 @@ sfnt_lookup_glyph_4 (sfnt_char character,
   if (glyph)
     return glyph;
 
-  /* Droid Sans Mono has overlapping segments in its format 4 cmap
-     subtable where the first segment's end code is 32, while the
-     second segment's start code is also 32.  The TrueType Reference
-     Manual says that mapping should begin by searching for the first
-     segment whose end code is greater than or equal to the character
-     being indexed, but that results in the first subtable being
-     found, which doesn't work, while the second table does.  Try to
-     detect this situation and use the second table if possible.  */
-
-  if (!glyph
-      /* The character being looked up is the current segment's end
-        code.  */
-      && code == format4->end_code[segment]
-      /* There is an additional segment.  */
-      && segment + 1 < format4->seg_count_x2 / 2
-      /* That segment's start code is the same as this segment's end
-        code.  */
-      && format4->start_code[segment + 1] == format4->end_code[segment])
-    /* Try the second segment.  */
-    return sfnt_lookup_glyph_4_1 (character, segment + 1, format4);
-
   /* Fail.  */
   return 0;
 }
index 0fb67e918a66b4be07282a9028cc768839a28093..1a6b2209abc9f506259fb6cc3261dd41ec49e81f 100644 (file)
@@ -364,6 +364,9 @@ struct sfnt_cmap_format_4
   /* log2(searchRange/2) */
   uint16_t entry_selector;
 
+  /* (2 * segCount) - searchRange */
+  uint16_t range_shift;
+
   /* Variable-length data.  */
   uint16_t *end_code;
   uint16_t *reserved_pad;