emacs-diffs
[Top][All Lists]
Advanced

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

master 28fcdb5 3/3: Fix crash in GNUstep font coverage check


From: Alan Third
Subject: master 28fcdb5 3/3: Fix crash in GNUstep font coverage check
Date: Sun, 4 Jul 2021 06:40:00 -0400 (EDT)

branch: master
commit 28fcdb521922db56a30f75f7d3e656fcb8ef6bd7
Author: Alan Third <alan@idiocy.org>
Commit: Alan Third <alan@idiocy.org>

    Fix crash in GNUstep font coverage check
    
    * src/nsfont.m (ns_charset_covers): Check coverage more accurately and
    don't automatically assume the buffer is 8192 bytes long.
---
 src/nsfont.m | 44 +++++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/src/nsfont.m b/src/nsfont.m
index 06e10d5..5a9cdfe 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -277,30 +277,36 @@ ns_ascii_average_width (NSFont *sfont)
 
 
 /* Return whether set1 covers set2 to a reasonable extent given by pct.
-   We check, out of each 16 Unicode char range containing chars in set2,
-   whether at least one character is present in set1.
-   This must be true for pct of the pairs to consider it covering.  */
+
+   The GNUstep bitmap representation doesn't match Apple's
+   description.  It appears to be a single block of bytes, not broken
+   up into planes, where the last byte contains the highest character
+   the character set supports.  */
 static BOOL
 ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct)
 {
-    const unsigned short *bytes1 = [[set1 bitmapRepresentation] bytes];
-    const unsigned short *bytes2 = [[set2 bitmapRepresentation] bytes];
-    int i, off = 0, tot = 0;
+  NSData *font = [set1 bitmapRepresentation];
+  NSData *script = [set2 bitmapRepresentation];
 
-    /* Work around what appears to be a GNUstep bug.
-       See <https://bugs.gnu.org/11853>.  */
-    if (! (bytes1 && bytes2))
-      return NO;
+  uint8_t *fontPlane = (uint8_t *)[font bytes];
+  uint8_t *scriptPlane = (uint8_t *)[script bytes];
 
-    for (i=0; i<4096; i++, bytes1++, bytes2++)
-       if (*bytes2)
-         {
-           tot++;
-           if (*bytes1 == 0)  // *bytes1 & *bytes2 != *bytes2
-               off++;
-         }
-    // fprintf(stderr, "off = %d\ttot = %d\n", off,tot);
-    return (float)off / tot < 1.0F - pct;
+  int covered = 0, total = 0;
+
+  for (ptrdiff_t b = 0 ; b < [script length] ; b++)
+    for (int i = 0 ; i < 8 ; i++)
+      {
+        if (*(scriptPlane + b) & (1 << i))
+          {
+            total++;
+
+            if (b < [font length]
+                && *(fontPlane + b) & (1 << i))
+              covered++;
+          }
+      }
+
+  return (float)covered / total >= 1.0F - pct;
 }
 
 



reply via email to

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