From fb62846b68bd12f90dc16f1b0dd326546d41ec49 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Tue, 8 Jun 2021 20:08:34 +0100 Subject: Fix image filename encoding issues (bug#48902) * src/image.c (image_find_image_fd): Don't return an encoded filename string. * src/nsfns.m: ([NSString stringWithLispString:]): Clarify usage comment. * src/nsimage.m ([EmacsImage allocInitFromFile:]): No need to encode the filename when converting to NSString. --- src/nsimage.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/nsimage.m') diff --git a/src/nsimage.m b/src/nsimage.m index fa81a41a519..3c16cd371e6 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -254,15 +254,15 @@ ns_image_size_in_bytes (void *img) NSImageRep *imgRep; Lisp_Object found; EmacsImage *image; + NSString *filename; /* Search bitmap-file-path for the file, if appropriate. */ found = image_find_image_file (file); if (!STRINGP (found)) return nil; - found = ENCODE_FILE (found); + filename = [NSString stringWithLispString:found]; - image = [[EmacsImage alloc] initByReferencingFile: - [NSString stringWithLispString: found]]; + image = [[EmacsImage alloc] initByReferencingFile:filename]; image->bmRep = nil; #ifdef NS_IMPL_COCOA @@ -277,8 +277,7 @@ ns_image_size_in_bytes (void *img) } [image setSize: NSMakeSize([imgRep pixelsWide], [imgRep pixelsHigh])]; - - [image setName: [NSString stringWithLispString: file]]; + [image setName:filename]; return image; } -- cgit v1.2.3 From 246803f26fdec5f425418210167da0f93d4b3401 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 24 Jul 2021 12:44:19 +0100 Subject: Fix image crash on macOS (bug#49688) * src/nsimage.m ([EmacsImage allocInitFromFile:]): Use isValid to check whether the image is valid instead of generating a tiff. --- src/nsimage.m | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/nsimage.m') diff --git a/src/nsimage.m b/src/nsimage.m index 3c16cd371e6..3668a7ab107 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -265,16 +265,12 @@ ns_image_size_in_bytes (void *img) image = [[EmacsImage alloc] initByReferencingFile:filename]; image->bmRep = nil; -#ifdef NS_IMPL_COCOA - imgRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]]; -#else - imgRep = [image bestRepresentationForDevice: nil]; -#endif - if (imgRep == nil) + if (![image isValid]) { [image release]; return nil; } + imgRep = [[image representations] firstObject]; [image setSize: NSMakeSize([imgRep pixelsWide], [imgRep pixelsHigh])]; [image setName:filename]; -- cgit v1.2.3 From d2d3fc39295953b4db5bdd7a21d513a87d3d00f0 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 24 Jul 2021 16:08:09 +0100 Subject: 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. --- src/nsimage.m | 41 ------------------- src/nsterm.h | 2 - src/nsterm.m | 128 ++++++++++++++++++++++++++-------------------------------- 3 files changed, 58 insertions(+), 113 deletions(-) (limited to 'src/nsimage.m') diff --git a/src/nsimage.m b/src/nsimage.m index 3668a7ab107..dd2bb3b0d7b 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -377,51 +377,10 @@ ns_image_size_in_bytes (void *img) } } - 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 { diff --git a/src/nsterm.h b/src/nsterm.h index b29e76cc63f..57c1e4cbae0 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -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; diff --git a/src/nsterm.m b/src/nsterm.m index 9eff01c7246..853c0fa2fa9 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3067,6 +3067,39 @@ ns_compute_glyph_string_overhangs (struct glyph_string *s) ========================================================================== */ +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 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, 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 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, 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 struct redisplay_interface ns_redisplay_interface = 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 @@ ns_term_init (Lisp_Object display_name) terminal->name = xlispstrdup (display_name); + gui_init_fringe (terminal->rif); + unblock_input (); if (!inhibit_x_resources) -- cgit v1.2.3