1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-13 09:32:47 +00:00

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.
This commit is contained in:
Alan Third 2021-07-24 16:08:09 +01:00
parent 9ce3fdc461
commit d2d3fc3929
3 changed files with 58 additions and 113 deletions

View File

@ -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
{

View File

@ -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;

View File

@ -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 need to clear. */
clearRect = NSMakeRect (p->x, p->y, p->wd, p->h);
/* 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. 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];
NSAffineTransform *transform = [NSAffineTransform transform];
NSColor *bm_color;
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);
/* 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];
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);
}
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;
[bm_color set];
[bmp fill];
{
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);
NSTRACE_RECT ("fromRect", fromRect);
[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)