From 87c143b1b77ae02a08b9e1bbe27da57859e28a8d Mon Sep 17 00:00:00 2001
From: Ben Simms <ben@bensimms.moe>
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 <config.h>
+#include <CoreGraphics/CoreGraphics.h>
#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