From: Anders Lindgren Date: Wed, 4 Nov 2015 05:50:19 +0000 (+0100) Subject: Render fringe bitmaps correctly on NextStep (bug#21301). X-Git-Tag: emacs-25.0.90~925 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=411b516d65b4e3b88e7b268dac7a32668e8d39c7;p=emacs.git Render fringe bitmaps correctly on NextStep (bug#21301). The fringe bitmaps were inverted, the background was not transparent, the image data was horizontally mirrored, and periodic fringe bitmaps were not supported. * nsimage.m ([EmacsImage initFromXBM:width:height:fg:bg:]): When both background and foreground colors are 0, set the background alpha channel to 0 (making the background transparent). When copying the image data, do this from the most significant bit (leftmost) to the least (rightmost), to avoid mirroring. * nsterm.m (ns_draw_fringe_bitmap): Don't invert the image bits. Add support for periodic images (e.g. the empty line indicator). --- diff --git a/src/nsimage.m b/src/nsimage.m index e76a7db8ef3..bdaf6a46b83 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -202,10 +202,13 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) } +/* Create image from monochrome bitmap. If both FG and BG are 0 + (black), set the background to white and make it transparent. */ - initFromXBM: (unsigned char *)bits width: (int)w height: (int)h fg: (unsigned long)fg bg: (unsigned long)bg { unsigned char *planes[5]; + unsigned char bg_alpha = 0xff; [self initWithSize: NSMakeSize (w, h)]; @@ -219,7 +222,10 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) [bmRep getBitmapDataPlanes: planes]; if (fg == 0 && bg == 0) - bg = 0xffffff; + { + bg = 0xffffff; + bg_alpha = 0; + } { /* pull bits out to set the (bytewise) alpha mask */ @@ -244,21 +250,22 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) c = *s++; for (k = 0; i < w && k < 8; ++k, ++i) { - *alpha++ = 0xff; - if (c & 1) + if (c & 0x80) { *rr++ = fgr; *gg++ = fgg; *bb++ = fgb; + *alpha++ = 0xff; } else { *rr++ = bgr; *gg++ = bgg; *bb++ = bgb; + *alpha++ = bg_alpha; } idx++; - c >>= 1; + c <<= 1; } } } diff --git a/src/nsterm.m b/src/nsterm.m index 925e9af30a7..4f97276d794 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2456,11 +2456,31 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, External (RIF); fringe-related -------------------------------------------------------------------------- */ { + /* Fringe bitmaps comes in two variants, normal and periodic. A + periodic bitmap is used to create a continuous pattern. Since a + bitmap is rendered one text line at a time, the start offset (dh) + of the bitmap varies. Concretely, this is used for the empty + line indicator. + + For a bitmap, "h + dh" is the full height and is always + invariant. For a normal bitmap "dh" is zero. + + For example, when the period is three and the full height is 72 + the following combinations exists: + + h=72 dh=0 + h=71 dh=1 + h=70 dh=2 */ + struct frame *f = XFRAME (WINDOW_FRAME (w)); struct face *face = p->face; static EmacsImage **bimgs = NULL; static int nBimgs = 0; + NSTRACE ("ns_draw_fringe_bitmap"); + NSTRACE_MSG ("which:%d cursor:%d overlay:%d width:%d height:%d period:%d", + p->which, p->cursor_p, p->overlay_p, p->wd, p->h, p->dh); + /* grow bimgs if needed */ if (nBimgs < max_used_fringe_bitmap) { @@ -2493,19 +2513,24 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, if (!img) { - unsigned short *bits = p->bits + p->dh; - int len = p->h; + // Note: For "periodic" images, allocate one EmacsImage for + // the base image, and use it for all dh:s. + unsigned short *bits = p->bits; + int full_height = p->h + p->dh; int i; - unsigned char *cbits = xmalloc (len); + unsigned char *cbits = xmalloc (full_height); - for (i = 0; i < len; i++) - cbits[i] = ~(bits[i] & 0xff); - img = [[EmacsImage alloc] initFromXBM: cbits width: 8 height: p->h + for (i = 0; i < full_height; i++) + cbits[i] = bits[i]; + img = [[EmacsImage alloc] initFromXBM: cbits width: 8 + height: full_height fg: 0 bg: 0]; bimgs[p->which - 1] = img; xfree (cbits); } + NSTRACE_RECT ("r", r); + NSRectClip (r); /* Since we composite the bitmap instead of just blitting it, we need to erase the whole background. */ @@ -2523,9 +2548,15 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, [img setXBMColor: bm_color]; } + // Note: For periodic images, the full image height is "h + hd". + // By using the height h, a suitable part of the image is used. + NSRect fromRect = NSMakeRect(0, 0, p->wd, p->h); + + NSTRACE_RECT ("fromRect", fromRect); + #ifdef NS_IMPL_COCOA [img drawInRect: r - fromRect: NSZeroRect + fromRect: fromRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES