From 67a878f78f879ce534232408c34dd11f42dd802b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Fri, 15 May 2015 11:31:38 +0200 Subject: [PATCH] Honor :fore/background for XBM on NS (Bug#14969). * nsterm.h (EmacsImage): Add xbm_fg, remove initFromSkipXBM, initFromXBM takes bg, fg args, remove flip arg. (ns_image_from_XBM): Add bg, fg args. * image.c (x_create_bitmap_from_data) (Create_Pixmap_From_Bitmap_Data): ns_image_from_XBM takes bg, fg args. * nsimage.m (ns_image_from_XBM): Add fg, bg args, pass to initFromXBM. Remove flip arg. (initFromSkipXBM): Move code to initFromXBM. (initFromXBM): Actually set fg and bg, instead of playing alpha games. Use fg, bg from args (Bug#14969). Remove if (length) section, was always false. Remove bit flipping (bitPat, swt), generated incorrect images when width/height wasn't a multiple of 8. (setXBMColor:): Modify planes by comparing to saved xbm_fg. * nsterm.m (ns_draw_fringe_bitmap): initFromXBM takes fg, bg args, remove flip arg. --- src/image.c | 4 +-- src/nsimage.m | 95 +++++++++++++++++++++++++-------------------------- src/nsterm.h | 8 ++--- src/nsterm.m | 2 +- 4 files changed, 53 insertions(+), 56 deletions(-) diff --git a/src/image.c b/src/image.c index 5e4843834c1..d7f48bd81dd 100644 --- a/src/image.c +++ b/src/image.c @@ -233,7 +233,7 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi #endif /* HAVE_NTGUI */ #ifdef HAVE_NS - void *bitmap = ns_image_from_XBM (bits, width, height); + void *bitmap = ns_image_from_XBM (bits, width, height, 0, 0); if (!bitmap) return -1; #endif @@ -2648,7 +2648,7 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data, convert_mono_to_color_image (f, img, fg, bg); #elif defined (HAVE_NS) - img->pixmap = ns_image_from_XBM (data, img->width, img->height); + img->pixmap = ns_image_from_XBM (data, img->width, img->height, fg, bg); #else img->pixmap = diff --git a/src/nsimage.m b/src/nsimage.m index f37ad38ad1e..3e90226cbf6 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -53,12 +53,13 @@ int image_trace_num = 0; ========================================================================== */ void * -ns_image_from_XBM (unsigned char *bits, int width, int height) +ns_image_from_XBM (unsigned char *bits, int width, int height, + unsigned long fg, unsigned long bg) { NSTRACE (ns_image_from_XBM); return [[EmacsImage alloc] initFromXBM: bits width: width height: height - flip: YES]; + fg: fg bg: bg]; } void * @@ -204,14 +205,7 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) - initFromXBM: (unsigned char *)bits width: (int)w height: (int)h - flip: (BOOL)flip -{ - return [self initFromSkipXBM: bits width: w height: h flip: flip length: 0]; -} - - -- initFromSkipXBM: (unsigned char *)bits width: (int)w height: (int)h - flip: (BOOL)flip length: (int)length; + fg: (unsigned long)fg bg: (unsigned long)bg { int bpr = (w + 7) / 8; unsigned char *planes[5]; @@ -226,57 +220,58 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) bytesPerRow: w bitsPerPixel: 0]; [bmRep getBitmapDataPlanes: planes]; + + if (fg == 0 && bg == 0) + bg = 0xffffff; + { /* pull bits out to set the (bytewise) alpha mask */ int i, j, k; unsigned char *s = bits; + unsigned char *rr = planes[0]; + unsigned char *gg = planes[1]; + unsigned char *bb = planes[2]; unsigned char *alpha = planes[3]; - unsigned char swt[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, - 3, 11, 7, 15}; - unsigned char c, bitPat; - - for (j = 0; j < h; j++) - for (i = 0; i < bpr; i++) + unsigned char fgr = (fg >> 16) & 0xff; + unsigned char fgg = (fg >> 8) & 0xff; + unsigned char fgb = fg & 0xff; + unsigned char bgr = (bg >> 16) & 0xff; + unsigned char bgg = (bg >> 8) & 0xff; + unsigned char bgb = bg & 0xff; + unsigned char c; + + int idx = 0; + for (j = 0; j < h; ++j) + for (i = 0; i < w; ) { - if (length) + c = *s++; + for (k = 0; i < w && k < 8; ++k, ++i) { - unsigned char s1, s2; - while (*s++ != 'x' && s < bits + length); - if (s >= bits + length) + *alpha++ = 0xff; + if (c & 1) { - [bmRep release]; - bmRep = nil; - return nil; + *rr++ = fgr; + *gg++ = fgg; + *bb++ = fgb; } -#define hexchar(x) ('0' <= (x) && (x) <= '9' ? (x) - '0' : (x) - 'a' + 10) - s1 = *s++; - s2 = *s++; - c = hexchar (s1) * 0x10 + hexchar (s2); - } - else - c = *s++; - - bitPat = flip ? swt[c >> 4] | (swt[c & 0xf] << 4) : c ^ 255; - for (k =0; k<8; k++) - { - *alpha++ = (bitPat & 0x80) ? 0xff : 0; - bitPat <<= 1; + else + { + *rr++ = bgr; + *gg++ = bgg; + *bb++ = bgb; + } + idx++; + c >>= 1; } } } + xbm_fg = fg; [self addRepresentation: bmRep]; - - memset (planes[0], 0, w*h); - memset (planes[1], 0, w*h); - memset (planes[2], 0, w*h); - [self setXBMColor: [NSColor blackColor]]; return self; } - -/* Set color for a bitmap image (see initFromSkipXBM). Note that the alpha - is used as a mask, so we just memset the entire array. */ +/* Set color for a bitmap image. */ - setXBMColor: (NSColor *)color { NSSize s = [self size]; @@ -296,19 +291,21 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) [bmRep getBitmapDataPlanes: planes]; - /* we used to just do this, but Cocoa seems to have a bug when rendering - an alpha-masked image onto a dark background where it bloats the mask */ - /* memset (planes[0..2], r, g, b*0xff, len); */ { int i, len = s.width*s.height; int rr = r * 0xff, gg = g * 0xff, bb = b * 0xff; - for (i =0; i> 16) & 0xff; + unsigned char fgg = (xbm_fg >> 8) & 0xff; + unsigned char fgb = xbm_fg & 0xff; + + for (i = 0; i < len; ++i) + if (planes[0][i] == fgr && planes[1][i] == fgg && planes[2][i] == fgb) { planes[0][i] = rr; planes[1][i] = gg; planes[2][i] = bb; } + xbm_fg = ((rr << 16) & 0xff) + ((gg << 8) & 0xff) + (bb & 0xff); } return self; diff --git a/src/nsterm.h b/src/nsterm.h index 9035ee1a328..d8ffd93a71b 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -341,13 +341,12 @@ typedef float EmacsCGFloat; NSBitmapImageRep *bmRep; /* used for accessing pixel data */ unsigned char *pixmapData[5]; /* shortcut to access pixel data */ NSColor *stippleMask; + unsigned long xbm_fg; } + allocInitFromFile: (Lisp_Object)file; - (void)dealloc; - initFromXBM: (unsigned char *)bits width: (int)w height: (int)h - flip: (BOOL)flip; -- initFromSkipXBM: (unsigned char *)bits width: (int)w height: (int)h - flip: (BOOL)flip length: (int)length; + fg: (unsigned long)fg bg: (unsigned long)bg; - setXBMColor: (NSColor *)color; - initForXPMWithDepth: (int)depth width: (int)width height: (int)height; - (void)setPixmapData; @@ -864,7 +863,8 @@ extern void syms_of_nsselect (void); /* From nsimage.m, needed in image.c */ struct image; -extern void *ns_image_from_XBM (unsigned char *bits, int width, int height); +extern void *ns_image_from_XBM (unsigned char *bits, int width, int height, + unsigned long fg, unsigned long bg); extern void *ns_image_for_XPM (int width, int height, int depth); extern void *ns_image_from_file (Lisp_Object file); extern bool ns_load_image (struct frame *f, struct image *img, diff --git a/src/nsterm.m b/src/nsterm.m index 187086cf826..6a4d0a6ad23 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2317,7 +2317,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, for (i = 0; i < len; i++) cbits[i] = ~(bits[i] & 0xff); img = [[EmacsImage alloc] initFromXBM: cbits width: 8 height: p->h - flip: NO]; + fg: 0 bg: 0]; bimgs[p->which - 1] = img; xfree (cbits); } -- 2.39.2