mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-07 06:50:23 -08:00
Support colored stipples on Cocoa NS (Bug#73384)
On Cocoa builds of NS Emacs, stipples are now rendered using masked CGImages instead of patterned NSColors so that stipples now render with color. * src/nsimage.m ([EmacsImage stippleMask:]): Use a CGImageMask to store the stipple mask when building for Cocoa. * src/nsterm.m (ns_maybe_dumpglyphs_background): Perform a masked fill to draw stipples when building for Cocoa. (ns_draw_stretch_glyph_string): Perform a masked fill to draw stipples when building for Cocoa.
This commit is contained in:
parent
fe7a8c92be
commit
9cbbdcee13
3 changed files with 106 additions and 1 deletions
|
|
@ -35,6 +35,9 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "coding.h"
|
#include "coding.h"
|
||||||
|
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
#include <CoreGraphics/CoreGraphics.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MAX_ALLOWED < 1070
|
#if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MAX_ALLOWED < 1070
|
||||||
# define COLORSPACE_NAME NSCalibratedRGBColorSpace
|
# define COLORSPACE_NAME NSCalibratedRGBColorSpace
|
||||||
|
|
@ -289,7 +292,11 @@ ns_image_size_in_bytes (void *img)
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
CGImageRelease(stippleMask);
|
||||||
|
#else
|
||||||
[stippleMask release];
|
[stippleMask release];
|
||||||
|
#endif
|
||||||
[bmRep release];
|
[bmRep release];
|
||||||
[transform release];
|
[transform release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
|
|
@ -300,7 +307,11 @@ ns_image_size_in_bytes (void *img)
|
||||||
{
|
{
|
||||||
EmacsImage *copy = [super copyWithZone:zone];
|
EmacsImage *copy = [super copyWithZone:zone];
|
||||||
|
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
copy->stippleMask = CGImageCreateCopy(stippleMask);
|
||||||
|
#else
|
||||||
copy->stippleMask = [stippleMask copyWithZone:zone];
|
copy->stippleMask = [stippleMask copyWithZone:zone];
|
||||||
|
#endif /* NS_IMPL_COCOA */
|
||||||
copy->bmRep = [bmRep copyWithZone:zone];
|
copy->bmRep = [bmRep copyWithZone:zone];
|
||||||
copy->transform = [transform copyWithZone:zone];
|
copy->transform = [transform copyWithZone:zone];
|
||||||
|
|
||||||
|
|
@ -509,6 +520,25 @@ ns_image_size_in_bytes (void *img)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
/* Returns a cached CGImageMask of the stipple pattern */
|
||||||
|
- (CGImageRef)stippleMask
|
||||||
|
{
|
||||||
|
if (stippleMask == nil)
|
||||||
|
{
|
||||||
|
CGDataProviderRef provider = CGDataProviderCreateWithData (NULL, [bmRep bitmapData],
|
||||||
|
[self sizeInBytes], NULL);
|
||||||
|
CGImageRef mask = CGImageMaskCreate([self size].width,
|
||||||
|
[self size].height,
|
||||||
|
8, 8, [self size].width,
|
||||||
|
provider, NULL, 0);
|
||||||
|
|
||||||
|
CGDataProviderRelease(provider);
|
||||||
|
stippleMask = CGImageRetain(mask);
|
||||||
|
}
|
||||||
|
return stippleMask;
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* Returns a pattern color, which is cached here. */
|
/* Returns a pattern color, which is cached here. */
|
||||||
- (NSColor *)stippleMask
|
- (NSColor *)stippleMask
|
||||||
{
|
{
|
||||||
|
|
@ -516,6 +546,7 @@ ns_image_size_in_bytes (void *img)
|
||||||
stippleMask = [[NSColor colorWithPatternImage: self] retain];
|
stippleMask = [[NSColor colorWithPatternImage: self] retain];
|
||||||
return stippleMask;
|
return stippleMask;
|
||||||
}
|
}
|
||||||
|
#endif /* NS_IMPL_COCOA */
|
||||||
|
|
||||||
/* Find the first NSBitmapImageRep which has multiple frames. */
|
/* Find the first NSBitmapImageRep which has multiple frames. */
|
||||||
- (NSBitmapImageRep *)getAnimatedBitmapImageRep
|
- (NSBitmapImageRep *)getAnimatedBitmapImageRep
|
||||||
|
|
|
||||||
|
|
@ -671,7 +671,11 @@ enum ns_return_frame_mode
|
||||||
{
|
{
|
||||||
NSBitmapImageRep *bmRep; /* used for accessing pixel data */
|
NSBitmapImageRep *bmRep; /* used for accessing pixel data */
|
||||||
unsigned char *pixmapData[5]; /* shortcut to access pixel data */
|
unsigned char *pixmapData[5]; /* shortcut to access pixel data */
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
CGImageRef stippleMask;
|
||||||
|
#else
|
||||||
NSColor *stippleMask;
|
NSColor *stippleMask;
|
||||||
|
#endif /* NS_IMPL_COCOA */
|
||||||
@public
|
@public
|
||||||
NSAffineTransform *transform;
|
NSAffineTransform *transform;
|
||||||
BOOL smoothing;
|
BOOL smoothing;
|
||||||
|
|
@ -688,7 +692,11 @@ enum ns_return_frame_mode
|
||||||
green: (unsigned char)g blue: (unsigned char)b
|
green: (unsigned char)g blue: (unsigned char)b
|
||||||
alpha:(unsigned char)a;
|
alpha:(unsigned char)a;
|
||||||
- (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a;
|
- (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a;
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
- (CGImageRef)stippleMask;
|
||||||
|
#else
|
||||||
- (NSColor *)stippleMask;
|
- (NSColor *)stippleMask;
|
||||||
|
#endif /* NS_IMPL_COCOA */
|
||||||
- (Lisp_Object)getMetadata;
|
- (Lisp_Object)getMetadata;
|
||||||
- (BOOL)setFrame: (unsigned int) index;
|
- (BOOL)setFrame: (unsigned int) index;
|
||||||
- (void)setTransform: (double[3][3]) m;
|
- (void)setTransform: (double[3][3]) m;
|
||||||
|
|
|
||||||
68
src/nsterm.m
68
src/nsterm.m
|
|
@ -3817,8 +3817,41 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
|
||||||
if (s->stippled_p)
|
if (s->stippled_p)
|
||||||
{
|
{
|
||||||
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
|
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
/* On cocoa emacs the stipple is stored as a mask CGImage.
|
||||||
|
First we want to clear the background with the bg colour */
|
||||||
|
[[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;
|
||||||
|
CGImageRef mask =
|
||||||
|
[dpyinfo->bitmaps[face->stipple - 1].img stippleMask];
|
||||||
|
|
||||||
|
/* This part could possibly be improved, the author is
|
||||||
|
unfamiliar with NS/CoreGraphics and isn't sure if it's
|
||||||
|
possible to do this with NSImage */
|
||||||
|
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
||||||
|
[ctx saveGraphicsState];
|
||||||
|
/* Checkpoint the graphics state and then focus in on the area
|
||||||
|
we're going to fill */
|
||||||
|
CGContextRef context = [ctx CGContext];
|
||||||
|
CGContextClipToRect (context, r);
|
||||||
|
CGContextScaleCTM (context, 1, -1);
|
||||||
|
|
||||||
|
/* Stamp the foreground colour using the stipple mask */
|
||||||
|
[[NSColor colorWithUnsignedLong:face->foreground] set];
|
||||||
|
CGRect imageSize = CGRectMake (0, 0, CGImageGetWidth (mask),
|
||||||
|
CGImageGetHeight (mask));
|
||||||
|
CGContextDrawTiledImage (context, imageSize, mask);
|
||||||
|
|
||||||
|
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||||
|
#else
|
||||||
[[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
|
[[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
|
||||||
goto fill;
|
goto fill;
|
||||||
|
#endif /* NS_IMPL_COCOA */
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||||
/* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
|
/* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
|
||||||
|
|
@ -3841,7 +3874,9 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
|
||||||
else
|
else
|
||||||
[FRAME_CURSOR_COLOR (s->f) set];
|
[FRAME_CURSOR_COLOR (s->f) set];
|
||||||
|
|
||||||
|
#ifndef NS_IMPL_COCOA
|
||||||
fill:
|
fill:
|
||||||
|
#endif /* !NS_IMPL_COCOA */
|
||||||
r = NSMakeRect (s->x, s->y + box_line_width,
|
r = NSMakeRect (s->x, s->y + box_line_width,
|
||||||
s->background_width,
|
s->background_width,
|
||||||
s->height - 2 * box_line_width);
|
s->height - 2 * box_line_width);
|
||||||
|
|
@ -4166,7 +4201,38 @@ ns_draw_stretch_glyph_string (struct glyph_string *s)
|
||||||
if (s->hl == DRAW_CURSOR)
|
if (s->hl == DRAW_CURSOR)
|
||||||
[FRAME_CURSOR_COLOR (s->f) set];
|
[FRAME_CURSOR_COLOR (s->f) set];
|
||||||
else if (s->stippled_p)
|
else if (s->stippled_p)
|
||||||
[[dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask] set];
|
{
|
||||||
|
#ifdef NS_IMPL_COCOA
|
||||||
|
/* On cocoa emacs the stipple is stored as a mask CGImage.
|
||||||
|
First we want to clear the background with the bg
|
||||||
|
colour */
|
||||||
|
[[NSColor colorWithUnsignedLong:s->face->background] set];
|
||||||
|
NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
|
||||||
|
|
||||||
|
/* This part could possibly be improved, the author is
|
||||||
|
unfamiliar with NS/CoreGraphics and isn't sure if it's
|
||||||
|
possible to do this with NSImage */
|
||||||
|
CGImageRef mask = [dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask];
|
||||||
|
CGRect bounds = CGRectMake (s->x, s->y, s->background_width, s->height);
|
||||||
|
|
||||||
|
/* Checkpoint the graphics state and then focus in on the
|
||||||
|
area we're going to fill */
|
||||||
|
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
||||||
|
[ctx saveGraphicsState];
|
||||||
|
CGContextRef context = [ctx CGContext];
|
||||||
|
CGContextClipToRect(context, bounds);
|
||||||
|
CGContextScaleCTM (context, 1, -1);
|
||||||
|
|
||||||
|
/* Stamp the foreground colour using the stipple mask */
|
||||||
|
[[NSColor colorWithUnsignedLong:s->face->foreground] set];
|
||||||
|
CGRect imageSize = CGRectMake (0, 0, CGImageGetWidth (mask),
|
||||||
|
CGImageGetHeight (mask));
|
||||||
|
CGContextDrawTiledImage (context, imageSize, mask);
|
||||||
|
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||||
|
#else
|
||||||
|
[[dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask] set];
|
||||||
|
#endif /* NS_IMPL_COCOA */
|
||||||
|
}
|
||||||
else
|
else
|
||||||
[[NSColor colorWithUnsignedLong: s->face->background] set];
|
[[NSColor colorWithUnsignedLong: s->face->background] set];
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue