diff options
author | Anders Lindgren <andlind@gmail.com> | 2015-11-04 06:50:19 +0100 |
---|---|---|
committer | Anders Lindgren <andlind@gmail.com> | 2015-11-04 06:50:19 +0100 |
commit | 411b516d65b4e3b88e7b268dac7a32668e8d39c7 (patch) | |
tree | 85f5afd81828e5e6ec753c3a983d6c923e16e4c2 | |
parent | 335cb1ee158db47003bda61a6cb077b62d04ca4f (diff) |
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).
-rw-r--r-- | src/nsimage.m | 15 | ||||
-rw-r--r-- | src/nsterm.m | 45 |
2 files changed, 49 insertions, 11 deletions
diff --git a/src/nsimage.m b/src/nsimage.m index e76a7db8ef..bdaf6a46b8 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 925e9af30a..4f97276d79 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 |