summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Lindgren <andlind@gmail.com>2015-11-04 06:50:19 +0100
committerAnders Lindgren <andlind@gmail.com>2015-11-04 06:50:19 +0100
commit411b516d65b4e3b88e7b268dac7a32668e8d39c7 (patch)
tree85f5afd81828e5e6ec753c3a983d6c923e16e4c2
parent335cb1ee158db47003bda61a6cb077b62d04ca4f (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.m15
-rw-r--r--src/nsterm.m45
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