Hello, I've been advised to submit my patch adding support for drawing coloured stipples on NS Emacs here: From 87c143b1b77ae02a08b9e1bbe27da57859e28a8d Mon Sep 17 00:00:00 2001 From: Ben Simms Date: Fri, 20 Sep 2024 09:50:47 +0200 Subject: [PATCH] Support drawing coloured stipples This makes use of CoreGraphics, while this works fine on macos systems, I'm unsure how to test this on a GNUStep or other supported NS implementation. --- src/nsimage.m | 17 +++++++++++++--- src/nsterm.h | 4 ++-- src/nsterm.m | 56 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/nsimage.m b/src/nsimage.m index ee72d6e0ea..100af5c3e9 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -28,6 +28,7 @@ Updated by Christian Limpach (chris@nice.ch) /* This should be the first include, as it may set up #defines affecting interpretation of even the system includes. */ #include +#include #include "lisp.h" #include "dispextern.h" @@ -510,10 +511,20 @@ - (void) setAlphaAtX: (int) x Y: (int) y to: (unsigned char) a } /* Returns a pattern color, which is cached here. */ -- (NSColor *)stippleMask +- (CGImageRef)stippleMask { - if (stippleMask == nil) - stippleMask = [[NSColor colorWithPatternImage: self] retain]; + if (stippleMask == nil) { + CGDataProviderRef provider = CGDataProviderCreateWithData (NULL, [bmRep bitmapData], + [self sizeInBytes], NULL); + id mask = (id)CGImageMaskCreate( + [self size].width, + [self size].height, + 8, 8, [self size].width, + provider, NULL, 0); + + CGDataProviderRelease(provider); + stippleMask = (CGImageRef)[mask retain]; + } return stippleMask; } diff --git a/src/nsterm.h b/src/nsterm.h index 3a713f8e8c..7ec851966f 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -670,7 +670,7 @@ #define NSTRACE_UNSILENCE() { NSBitmapImageRep *bmRep; /* used for accessing pixel data */ unsigned char *pixmapData[5]; /* shortcut to access pixel data */ - NSColor *stippleMask; + CGImageRef stippleMask; @public NSAffineTransform *transform; BOOL smoothing; @@ -687,7 +687,7 @@ #define NSTRACE_UNSILENCE() green: (unsigned char)g blue: (unsigned char)b alpha:(unsigned char)a; - (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a; -- (NSColor *)stippleMask; +- (CGImageRef)stippleMask; - (Lisp_Object)getMetadata; - (BOOL)setFrame: (unsigned int) index; - (void)setTransform: (double[3][3]) m; diff --git a/src/nsterm.m b/src/nsterm.m index 794630de1c..84084f12a4 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3826,9 +3826,28 @@ Function modeled after x_draw_glyph_string_box (). if (s->stippled_p) { + [[NSColor colorWithUnsignedLong:face->background] set]; + r = NSMakeRect (s->x, s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); + NSRectFill (r); + s->background_filled_p = 1; struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f); - [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set]; - goto fill; + CGImageRef mask = + [dpyinfo->bitmaps[face->stipple - 1].img stippleMask]; + CGRect bounds = CGRectMake (s->x, s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); + NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; + [ctx saveGraphicsState]; + CGContextRef context = [ctx CGContext]; + CGContextClipToRect (context, bounds); + CGContextScaleCTM (context, 1, -1); + [[NSColor colorWithUnsignedLong:face->foreground] set]; + CGRect imageSize = CGRectMake (0, 0, CGImageGetWidth (mask), + CGImageGetHeight (mask)); + CGContextDrawTiledImage (context, imageSize, mask); + [[NSGraphicsContext currentContext] restoreGraphicsState]; } else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font @@ -3851,7 +3870,6 @@ Function modeled after x_draw_glyph_string_box (). else [FRAME_CURSOR_COLOR (s->f) set]; - fill: r = NSMakeRect (s->x, s->y + box_line_width, s->background_width, s->height - 2 * box_line_width); @@ -4175,10 +4193,36 @@ Function modeled after x_draw_glyph_string_box (). dpyinfo = FRAME_DISPLAY_INFO (s->f); if (s->hl == DRAW_CURSOR) [FRAME_CURSOR_COLOR (s->f) set]; - else if (s->stippled_p) - [[dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask] set]; - else + else if (s->stippled_p) { + [[NSColor colorWithUnsignedLong:s->face->background] + set]; + NSRectFill ( + NSMakeRect (x, s->y, background_width, s->height)); + CGImageRef mask = + [dpyinfo->bitmaps[s->face->stipple - 1] + .img stippleMask]; + CGRect bounds + = CGRectMake (s->x, s->y, s->background_width, + s->height); + NSGraphicsContext *ctx = + [NSGraphicsContext currentContext]; + [ctx saveGraphicsState]; + CGContextRef context = [ctx CGContext]; + CGContextClipToRect(context, bounds); + CGContextScaleCTM (context, 1, -1); + [[NSColor colorWithUnsignedLong:s->face->foreground] + set]; + CGRect imageSize + = CGRectMake (0, 0, CGImageGetWidth (mask), + CGImageGetHeight (mask)); + CGContextDrawTiledImage (context, imageSize, mask); + [[NSGraphicsContext currentContext] + restoreGraphicsState]; + } + else { [[NSColor colorWithUnsignedLong: s->face->background] set]; + NSRectFill (NSMakeRect (x, s->y, background_width, s->height)); + } NSRectFill (NSMakeRect (x, s->y, background_width, s->height)); } -- 2.45.2