Commit d2d3fc39 authored by Alan Third's avatar Alan Third
Browse files

Convert fringe bitmaps to vectors on NS port

Unfortunately *step doesn't support masks for bitmap images so
changing the colors of fringe bitmaps is awkward.  We can work around
this by converting the bitmap into an NSBezierPath and drawing it in
the required color.

* src/nsterm.m (ns_define_fringe_bitmap):
(ns_destroy_fringe_bitmap): New functions
(ns_draw_fringe_bitmap): Display the NSBezierPath.
* src/nsimage.m
([EmacsImage initFromXBM:width:height:fg:bg:reverseBytes:]): Remove
variable that's there to allow us to easily modify the XBM colors.
([EmacsImage setXBMColor:]): Remove method.
parent 9ce3fdc4
Pipeline #11610 failed with stages
in 12 seconds
......@@ -377,51 +377,10 @@ - (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
}
}
xbm_fg = fg;
[self addRepresentation: bmRep];
return self;
}
/* Set color for a bitmap image. */
- (instancetype)setXBMColor: (NSColor *)color
{
NSSize s = [self size];
unsigned char *planes[5];
EmacsCGFloat r, g, b, a;
NSColor *rgbColor;
if (bmRep == nil || color == nil)
return self;
if ([color colorSpace] != [NSColorSpace genericRGBColorSpace])
rgbColor = [color colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]];
else
rgbColor = color;
[rgbColor getRed: &r green: &g blue: &b alpha: &a];
[bmRep getBitmapDataPlanes: planes];
{
int i, len = s.width*s.height;
int rr = r * 0xff, gg = g * 0xff, bb = b * 0xff;
unsigned char fgr = (xbm_fg >> 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) & 0xff0000) + ((gg << 8) & 0xff00) + (bb & 0xff);
}
return self;
}
- (instancetype)initForXPMWithDepth: (int)depth width: (int)width height: (int)height
{
......
......@@ -647,7 +647,6 @@ typedef id instancetype;
NSBitmapImageRep *bmRep; /* used for accessing pixel data */
unsigned char *pixmapData[5]; /* shortcut to access pixel data */
NSColor *stippleMask;
unsigned long xbm_fg;
@public
NSAffineTransform *transform;
BOOL smoothing;
......@@ -657,7 +656,6 @@ typedef id instancetype;
- (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
fg: (unsigned long)fg bg: (unsigned long)bg
reverseBytes: (BOOL)reverse;
- (instancetype)setXBMColor: (NSColor *)color;
- (instancetype)initForXPMWithDepth: (int)depth width: (int)width height: (int)height;
- (void)setPixmapData;
- (unsigned long)getPixelAtX: (int)x Y: (int)y;
......
......@@ -3067,6 +3067,39 @@ so some key presses (TAB) are swallowed by the system. */
========================================================================== */
static NSMutableDictionary *fringe_bmp;
static void
ns_define_fringe_bitmap (int which, unsigned short *bits, int h, int w)
{
NSBezierPath *p = [NSBezierPath bezierPath];
if (!fringe_bmp)
fringe_bmp = [[NSMutableDictionary alloc] initWithCapacity:25];
[p moveToPoint:NSMakePoint (0, 0)];
for (int y = 0 ; y < h ; y++)
for (int x = 0 ; x < w ; x++)
{
/* XBM rows are always round numbers of bytes, with any unused
bits ignored. */
int byte = y * (w/8 + (w%8 ? 1 : 0)) + x/8;
bool bit = bits[byte] & (0x80 >> x%8);
if (bit)
[p appendBezierPathWithRect:NSMakeRect (x, y, 1, 1)];
}
[fringe_bmp setObject:p forKey:[NSNumber numberWithInt:which]];
}
static void
ns_destroy_fringe_bitmap (int which)
{
[fringe_bmp removeObjectForKey:[NSNumber numberWithInt:which]];
}
extern int max_used_fringe_bitmap;
static void
......@@ -3094,41 +3127,18 @@ so some key presses (TAB) are swallowed by the system. */
struct frame *f = XFRAME (WINDOW_FRAME (w));
struct face *face = p->face;
static EmacsImage **bimgs = NULL;
static int nBimgs = 0;
NSRect clearRect = NSZeroRect;
NSRect imageRect = NSZeroRect;
NSRect rowRect = ns_row_rect (w, row, ANY_AREA);
NSTRACE_WHEN (NSTRACE_GROUP_FRINGE, "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)
{
bimgs = xrealloc (bimgs, max_used_fringe_bitmap * sizeof *bimgs);
memset (bimgs + nBimgs, 0,
(max_used_fringe_bitmap - nBimgs) * sizeof *bimgs);
nBimgs = max_used_fringe_bitmap;
}
/* Work out the rectangle we will composite into. */
if (p->which)
imageRect = NSMakeRect (p->x, p->y, p->wd, p->h);
/* Work out the rectangle we will need to clear. */
clearRect = NSMakeRect (p->x, p->y, p->wd, p->h);
/* Work out the rectangle we will need to clear. Because we're
compositing rather than blitting, we need to clear the area under
the image regardless of anything else. */
if (p->bx >= 0 && !p->overlay_p)
{
clearRect = NSMakeRect (p->bx, p->by, p->nx, p->ny);
clearRect = NSUnionRect (clearRect, imageRect);
}
else
{
clearRect = imageRect;
}
clearRect = NSUnionRect (clearRect, NSMakeRect (p->bx, p->by, p->nx, p->ny));
/* Handle partially visible rows. */
clearRect = NSIntersectionRect (clearRect, rowRect);
......@@ -3144,53 +3154,29 @@ so some key presses (TAB) are swallowed by the system. */
NSRectFill (clearRect);
}
if (p->which)
NSBezierPath *bmp = [fringe_bmp objectForKey:[NSNumber numberWithInt:p->which]];
if (bmp)
{
EmacsImage *img = bimgs[p->which - 1];
if (!img)
{
// 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 (full_height);
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
reverseBytes: NO];
bimgs[p->which - 1] = img;
xfree (cbits);
}
NSAffineTransform *transform = [NSAffineTransform transform];
NSColor *bm_color;
/* Because the image is defined at (0, 0) we need to take a copy
and then transform that copy to the new origin. */
bmp = [bmp copy];
[transform translateXBy:p->x yBy:p->y - p->dh];
[bmp transformUsingAffineTransform:transform];
{
NSColor *bm_color;
if (!p->cursor_p)
bm_color = ns_lookup_indexed_color(face->foreground, f);
else if (p->overlay_p)
bm_color = ns_lookup_indexed_color(face->background, f);
else
bm_color = f->output_data.ns->cursor_color;
[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);
if (!p->cursor_p)
bm_color = ns_lookup_indexed_color(face->foreground, f);
else if (p->overlay_p)
bm_color = ns_lookup_indexed_color(face->background, f);
else
bm_color = f->output_data.ns->cursor_color;
NSTRACE_RECT ("fromRect", fromRect);
[bm_color set];
[bmp fill];
[img drawInRect: imageRect
fromRect: fromRect
operation: NSCompositingOperationSourceOver
fraction: 1.0
respectFlipped: YES
hints: nil];
[bmp release];
}
ns_unfocus (f);
}
......@@ -5162,8 +5148,8 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
gui_get_glyph_overhangs,
gui_fix_overlapping_area,
ns_draw_fringe_bitmap,
0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */
0, /* destroy_fringe_bitmap */
ns_define_fringe_bitmap,
ns_destroy_fringe_bitmap,
ns_compute_glyph_string_overhangs,
ns_draw_glyph_string,
ns_define_frame_cursor,
......@@ -5349,6 +5335,8 @@ Needs to be here because ns_initialize_display_info () uses AppKit classes.
terminal->name = xlispstrdup (display_name);
gui_init_fringe (terminal->rif);
unblock_input ();
if (!inhibit_x_resources)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment