emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master ad5e17d0638: Properly parse format 4 cmap tables


From: Po Lu
Subject: master ad5e17d0638: Properly parse format 4 cmap tables
Date: Thu, 24 Aug 2023 04:36:23 -0400 (EDT)

branch: master
commit ad5e17d0638be46f982d1448e8fef1d28d224735
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Properly parse format 4 cmap tables
    
    * 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 | 26 +++-----------------------
 src/sfnt.h |  3 +++
 2 files changed, 6 insertions(+), 23 deletions(-)

diff --git a/src/sfnt.c b/src/sfnt.c
index c987ec42441..87a11019b13 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -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;
 }
diff --git a/src/sfnt.h b/src/sfnt.h
index 0fb67e918a6..1a6b2209abc 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]