diff options
| author | Anders Lindgren | 2015-11-04 06:50:19 +0100 |
|---|---|---|
| committer | Anders Lindgren | 2015-11-04 06:50:19 +0100 |
| commit | 411b516d65b4e3b88e7b268dac7a32668e8d39c7 (patch) | |
| tree | 85f5afd81828e5e6ec753c3a983d6c923e16e4c2 /src | |
| parent | 335cb1ee158db47003bda61a6cb077b62d04ca4f (diff) | |
| download | emacs-411b516d65b4e3b88e7b268dac7a32668e8d39c7.tar.gz emacs-411b516d65b4e3b88e7b268dac7a32668e8d39c7.zip | |
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).
Diffstat (limited to 'src')
| -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 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) | |||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | 204 | ||
| 205 | /* Create image from monochrome bitmap. If both FG and BG are 0 | ||
| 206 | (black), set the background to white and make it transparent. */ | ||
| 205 | - initFromXBM: (unsigned char *)bits width: (int)w height: (int)h | 207 | - initFromXBM: (unsigned char *)bits width: (int)w height: (int)h |
| 206 | fg: (unsigned long)fg bg: (unsigned long)bg | 208 | fg: (unsigned long)fg bg: (unsigned long)bg |
| 207 | { | 209 | { |
| 208 | unsigned char *planes[5]; | 210 | unsigned char *planes[5]; |
| 211 | unsigned char bg_alpha = 0xff; | ||
| 209 | 212 | ||
| 210 | [self initWithSize: NSMakeSize (w, h)]; | 213 | [self initWithSize: NSMakeSize (w, h)]; |
| 211 | 214 | ||
| @@ -219,7 +222,10 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) | |||
| 219 | [bmRep getBitmapDataPlanes: planes]; | 222 | [bmRep getBitmapDataPlanes: planes]; |
| 220 | 223 | ||
| 221 | if (fg == 0 && bg == 0) | 224 | if (fg == 0 && bg == 0) |
| 222 | bg = 0xffffff; | 225 | { |
| 226 | bg = 0xffffff; | ||
| 227 | bg_alpha = 0; | ||
| 228 | } | ||
| 223 | 229 | ||
| 224 | { | 230 | { |
| 225 | /* pull bits out to set the (bytewise) alpha mask */ | 231 | /* 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) | |||
| 244 | c = *s++; | 250 | c = *s++; |
| 245 | for (k = 0; i < w && k < 8; ++k, ++i) | 251 | for (k = 0; i < w && k < 8; ++k, ++i) |
| 246 | { | 252 | { |
| 247 | *alpha++ = 0xff; | 253 | if (c & 0x80) |
| 248 | if (c & 1) | ||
| 249 | { | 254 | { |
| 250 | *rr++ = fgr; | 255 | *rr++ = fgr; |
| 251 | *gg++ = fgg; | 256 | *gg++ = fgg; |
| 252 | *bb++ = fgb; | 257 | *bb++ = fgb; |
| 258 | *alpha++ = 0xff; | ||
| 253 | } | 259 | } |
| 254 | else | 260 | else |
| 255 | { | 261 | { |
| 256 | *rr++ = bgr; | 262 | *rr++ = bgr; |
| 257 | *gg++ = bgg; | 263 | *gg++ = bgg; |
| 258 | *bb++ = bgb; | 264 | *bb++ = bgb; |
| 265 | *alpha++ = bg_alpha; | ||
| 259 | } | 266 | } |
| 260 | idx++; | 267 | idx++; |
| 261 | c >>= 1; | 268 | c <<= 1; |
| 262 | } | 269 | } |
| 263 | } | 270 | } |
| 264 | } | 271 | } |
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, | |||
| 2456 | External (RIF); fringe-related | 2456 | External (RIF); fringe-related |
| 2457 | -------------------------------------------------------------------------- */ | 2457 | -------------------------------------------------------------------------- */ |
| 2458 | { | 2458 | { |
| 2459 | /* Fringe bitmaps comes in two variants, normal and periodic. A | ||
| 2460 | periodic bitmap is used to create a continuous pattern. Since a | ||
| 2461 | bitmap is rendered one text line at a time, the start offset (dh) | ||
| 2462 | of the bitmap varies. Concretely, this is used for the empty | ||
| 2463 | line indicator. | ||
| 2464 | |||
| 2465 | For a bitmap, "h + dh" is the full height and is always | ||
| 2466 | invariant. For a normal bitmap "dh" is zero. | ||
| 2467 | |||
| 2468 | For example, when the period is three and the full height is 72 | ||
| 2469 | the following combinations exists: | ||
| 2470 | |||
| 2471 | h=72 dh=0 | ||
| 2472 | h=71 dh=1 | ||
| 2473 | h=70 dh=2 */ | ||
| 2474 | |||
| 2459 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 2475 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 2460 | struct face *face = p->face; | 2476 | struct face *face = p->face; |
| 2461 | static EmacsImage **bimgs = NULL; | 2477 | static EmacsImage **bimgs = NULL; |
| 2462 | static int nBimgs = 0; | 2478 | static int nBimgs = 0; |
| 2463 | 2479 | ||
| 2480 | NSTRACE ("ns_draw_fringe_bitmap"); | ||
| 2481 | NSTRACE_MSG ("which:%d cursor:%d overlay:%d width:%d height:%d period:%d", | ||
| 2482 | p->which, p->cursor_p, p->overlay_p, p->wd, p->h, p->dh); | ||
| 2483 | |||
| 2464 | /* grow bimgs if needed */ | 2484 | /* grow bimgs if needed */ |
| 2465 | if (nBimgs < max_used_fringe_bitmap) | 2485 | if (nBimgs < max_used_fringe_bitmap) |
| 2466 | { | 2486 | { |
| @@ -2493,19 +2513,24 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, | |||
| 2493 | 2513 | ||
| 2494 | if (!img) | 2514 | if (!img) |
| 2495 | { | 2515 | { |
| 2496 | unsigned short *bits = p->bits + p->dh; | 2516 | // Note: For "periodic" images, allocate one EmacsImage for |
| 2497 | int len = p->h; | 2517 | // the base image, and use it for all dh:s. |
| 2518 | unsigned short *bits = p->bits; | ||
| 2519 | int full_height = p->h + p->dh; | ||
| 2498 | int i; | 2520 | int i; |
| 2499 | unsigned char *cbits = xmalloc (len); | 2521 | unsigned char *cbits = xmalloc (full_height); |
| 2500 | 2522 | ||
| 2501 | for (i = 0; i < len; i++) | 2523 | for (i = 0; i < full_height; i++) |
| 2502 | cbits[i] = ~(bits[i] & 0xff); | 2524 | cbits[i] = bits[i]; |
| 2503 | img = [[EmacsImage alloc] initFromXBM: cbits width: 8 height: p->h | 2525 | img = [[EmacsImage alloc] initFromXBM: cbits width: 8 |
| 2526 | height: full_height | ||
| 2504 | fg: 0 bg: 0]; | 2527 | fg: 0 bg: 0]; |
| 2505 | bimgs[p->which - 1] = img; | 2528 | bimgs[p->which - 1] = img; |
| 2506 | xfree (cbits); | 2529 | xfree (cbits); |
| 2507 | } | 2530 | } |
| 2508 | 2531 | ||
| 2532 | NSTRACE_RECT ("r", r); | ||
| 2533 | |||
| 2509 | NSRectClip (r); | 2534 | NSRectClip (r); |
| 2510 | /* Since we composite the bitmap instead of just blitting it, we need | 2535 | /* Since we composite the bitmap instead of just blitting it, we need |
| 2511 | to erase the whole background. */ | 2536 | to erase the whole background. */ |
| @@ -2523,9 +2548,15 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, | |||
| 2523 | [img setXBMColor: bm_color]; | 2548 | [img setXBMColor: bm_color]; |
| 2524 | } | 2549 | } |
| 2525 | 2550 | ||
| 2551 | // Note: For periodic images, the full image height is "h + hd". | ||
| 2552 | // By using the height h, a suitable part of the image is used. | ||
| 2553 | NSRect fromRect = NSMakeRect(0, 0, p->wd, p->h); | ||
| 2554 | |||
| 2555 | NSTRACE_RECT ("fromRect", fromRect); | ||
| 2556 | |||
| 2526 | #ifdef NS_IMPL_COCOA | 2557 | #ifdef NS_IMPL_COCOA |
| 2527 | [img drawInRect: r | 2558 | [img drawInRect: r |
| 2528 | fromRect: NSZeroRect | 2559 | fromRect: fromRect |
| 2529 | operation: NSCompositeSourceOver | 2560 | operation: NSCompositeSourceOver |
| 2530 | fraction: 1.0 | 2561 | fraction: 1.0 |
| 2531 | respectFlipped: YES | 2562 | respectFlipped: YES |