Subject: [PATCH] Fix XBM files on NS (bug#26133)

From: Alan Third <[email-masked]>
Date: Fri, 6 Dec 2019 17:01:56 +0000

Reinstate some of the functionality removed in commit
67a878f78f879ce534232408c34dd11f42dd802b.

* src/nsimage.m (ns_image_from_XBM): Use new reverseBytes argument.
([EmacsImage initFromXBM:width:height:fg:bg:reverseBytes:]): Add
ability to reverse the contents of each byte for use with XBMs, while
still working with fringe bitmaps.
* src/nsterm.h
([EmacsImage initFromXBM:width:height:fg:bg:reverseBytes:]): Modified
function definition.
* src/nsterm.m (ns_draw_fringe_bitmap): Use new reverseBytes argument.
---
 src/nsimage.m | 17 +++++++++++++----
 src/nsterm.h  |  3 ++-
 src/nsterm.m  |  3 ++-
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/nsimage.m b/src/nsimage.m
index e1408c77f5..25d3b2299c 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -52,7 +52,7 @@ Updated by Christian Limpach ([email-masked])
   NSTRACE ("ns_image_from_XBM");
   return [[EmacsImage alloc] initFromXBM: (unsigned char *) bits
                                    width: width height: height
-                                      fg: fg bg: bg];
+                                      fg: fg bg: bg reverseBytes: YES];
 }
 
 void *
@@ -228,7 +228,8 @@ - (void)dealloc
 /* Create image from monochrome bitmap. If both FG and BG are 0
    (black), set the background to white and make it transparent.  */
 - (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
-           fg: (unsigned long)fg bg: (unsigned long)bg
+                         fg: (unsigned long)fg bg: (unsigned long)bg
+               reverseBytes: (BOOL)reverse
 {
   unsigned char *planes[5];
   unsigned char bg_alpha = 0xff;
@@ -252,6 +253,8 @@ - (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
 
   {
     /* Pull bits out to set the (bytewise) alpha mask.  */
+    unsigned char swt[16] = {0, 8, 4, 12, 2, 10, 6, 14,
+                             1, 9, 5, 13, 3, 11, 7, 15};
     int i, j, k;
     unsigned char *s = bits;
     unsigned char *rr = planes[0];
@@ -266,11 +269,18 @@ - (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
     unsigned char bgb = bg & 0xff;
     unsigned char c;
 
-    int idx = 0;
     for (j = 0; j < h; ++j)
       for (i = 0; i < w; )
         {
           c = *s++;
+
+          /* XBM files have the bits in reverse order within each byte
+             as compared to our fringe bitmaps.  This function deals
+             with both so has to be able to handle the bytes in either
+             order.  */
+          if (reverse)
+            c = swt[c >> 4] | (swt[c & 0xf] << 4);
+
           for (k = 0; i < w && k < 8; ++k, ++i)
             {
               if (c & 0x80)
@@ -287,7 +297,6 @@ - (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
                   *bb++ = bgb;
                   *alpha++ = bg_alpha;
                 }
-              idx++;
               c <<= 1;
             }
         }
diff --git a/src/nsterm.h b/src/nsterm.h
index 9773eb3e66..3803009afa 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -639,7 +639,8 @@ #define NSTRACE_UNSILENCE()
 + (instancetype)allocInitFromFile: (Lisp_Object)file;
 - (void)dealloc;
 - (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
-                  fg: (unsigned long)fg bg: (unsigned long)bg;
+                         fg: (unsigned long)fg bg: (unsigned long)bg
+               reverseBytes: (BOOL)reverse;
 - (instancetype)setXBMColor: (NSColor *)color;
 - (instancetype)initForXPMWithDepth: (int)depth width: (int)width height: (int)height;
 - (void)setPixmapData;
diff --git a/src/nsterm.m b/src/nsterm.m
index 71234ac783..369b1173d8 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3106,7 +3106,8 @@ so some key presses (TAB) are swallowed by the system.  */
                 cbits[i] = bits[i];
               img = [[EmacsImage alloc] initFromXBM: cbits width: 8
                                              height: full_height
-                                                 fg: 0 bg: 0];
+                                                 fg: 0 bg: 0
+                                       reverseBytes: NO];
               bimgs[p->which - 1] = img;
               xfree (cbits);
             }
-- 
2.21.0

-- 
Alan Third