mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-21 04:17:35 +00:00
Use CGImage instead of NSBitmapImageRep (bug#32932)
* src/nsterm.m (ns_update_end): (ns_clear_frame): Remove forced draws. (ns_draw_fringe_bitmap): (ns_dumpglyphs_image): No longer need to invert images as the context is already flipped. ([EmacsView updateFrameSize:]): ([EmacsView initFrameFromEmacs:]): Use new function. ([EmacsView createDrawingBuffer]): Replaces createDrawingBufferWithRect:. ([EmacsView focusOnDrawingBuffer]): Set CGImage context. ([EmacsView windowDidChangeBackingProperties:]): Use new function. ([EmacsView copyRect:to:]): Copy using CGImages. ([EmacsView wantsUpdateLayer]): ([EmacsView updateLayer]): New Functions. ([EmacsView drawRect:]): We no longer do anything special here for Cocoa. ([EmacsView windowDidChangeBackingProperties:]): Fix indentation and add NSTRACE.
This commit is contained in:
parent
a13d1f9539
commit
44298ea6aa
2 changed files with 93 additions and 69 deletions
|
|
@ -418,7 +418,7 @@ typedef id instancetype;
|
|||
NSWindow *nonfs_window;
|
||||
BOOL fs_is_native;
|
||||
#ifdef NS_IMPL_COCOA
|
||||
NSBitmapImageRep *drawingBuffer;
|
||||
CGContextRef drawingBuffer;
|
||||
#endif
|
||||
@public
|
||||
struct frame *emacsframe;
|
||||
|
|
@ -464,7 +464,7 @@ typedef id instancetype;
|
|||
- (void)focusOnDrawingBuffer;
|
||||
#endif
|
||||
- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect;
|
||||
- (void)createDrawingBufferWithRect:(NSRect)rect;
|
||||
- (void)createDrawingBuffer;
|
||||
|
||||
/* Non-notification versions of NSView methods. Used for direct calls. */
|
||||
- (void)windowWillEnterFullScreen;
|
||||
|
|
|
|||
158
src/nsterm.m
158
src/nsterm.m
|
|
@ -1141,7 +1141,6 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
|||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
[NSGraphicsContext setCurrentContext:nil];
|
||||
[view display];
|
||||
#else
|
||||
block_input ();
|
||||
|
||||
|
|
@ -2853,7 +2852,9 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
ns_unfocus (f);
|
||||
|
||||
/* as of 2006/11 or so this is now needed */
|
||||
ns_redraw_scroll_bars (f);
|
||||
/* FIXME: I don't see any reason for this and removing it makes no
|
||||
difference here. Do we need it for GNUstep? */
|
||||
//ns_redraw_scroll_bars (f);
|
||||
unblock_input ();
|
||||
}
|
||||
|
||||
|
|
@ -3169,18 +3170,6 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
|
||||
NSTRACE_RECT ("fromRect", fromRect);
|
||||
|
||||
/* Because we're drawing into an offscreen buffer which isn't
|
||||
flipped, the images come out upside down. To work around it
|
||||
we need to do some fancy transforms. */
|
||||
{
|
||||
NSAffineTransform *transform = [NSAffineTransform transform];
|
||||
[transform translateXBy:0 yBy:NSMaxY(imageRect)];
|
||||
[transform scaleXBy:1 yBy:-1];
|
||||
[transform concat];
|
||||
|
||||
imageRect.origin.y = 0;
|
||||
}
|
||||
|
||||
[img drawInRect: imageRect
|
||||
fromRect: fromRect
|
||||
operation: NSCompositingOperationSourceOver
|
||||
|
|
@ -3938,11 +3927,6 @@ Function modeled after x_draw_glyph_string_box ().
|
|||
|
||||
NSAffineTransform *doTransform = [NSAffineTransform transform];
|
||||
|
||||
/* We have to flip the image around the X axis as the offscreen
|
||||
bitmap we're drawing to is flipped. */
|
||||
[doTransform scaleXBy:1 yBy:-1];
|
||||
[doTransform translateXBy:0 yBy:-[img size].height];
|
||||
|
||||
/* ImageMagick images don't have transforms. */
|
||||
if (img->transform)
|
||||
[doTransform appendTransform:img->transform];
|
||||
|
|
@ -7104,7 +7088,7 @@ - (void) updateFrameSize: (BOOL) delay
|
|||
from non-native fullscreen, in other circumstances it appears
|
||||
to be a noop. (bug#28872) */
|
||||
wr = NSMakeRect (0, 0, neww, newh);
|
||||
[self createDrawingBufferWithRect:wr];
|
||||
[self createDrawingBuffer];
|
||||
[view setFrame: wr];
|
||||
|
||||
// To do: consider using [NSNotificationCenter postNotificationName:].
|
||||
|
|
@ -7444,7 +7428,7 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
|
|||
maximizing_resize = NO;
|
||||
#endif
|
||||
|
||||
[self createDrawingBufferWithRect:r];
|
||||
[self createDrawingBuffer];
|
||||
|
||||
win = [[EmacsWindow alloc]
|
||||
initWithContentRect: r
|
||||
|
|
@ -8229,52 +8213,65 @@ - (instancetype)toggleToolbar: (id)sender
|
|||
}
|
||||
|
||||
|
||||
- (void)createDrawingBufferWithRect:(NSRect)rect
|
||||
/* Create and store a new NSBitmapImageRep for Emacs to draw
|
||||
into.
|
||||
|
||||
Drawing to an offscreen bitmap doesn't work in GNUstep as there's
|
||||
a bug in graphicsContextWithBitmapImageRep
|
||||
(https://savannah.gnu.org/bugs/?38405). So under GNUstep we
|
||||
retain the old method of drawing direct to the EmacsView. */
|
||||
{
|
||||
#ifdef NS_IMPL_COCOA
|
||||
if (drawingBuffer != nil)
|
||||
[drawingBuffer release];
|
||||
- (void)createDrawingBuffer
|
||||
/* Create and store a new CGGraphicsContext for Emacs to draw into.
|
||||
|
||||
drawingBuffer = [[self bitmapImageRepForCachingDisplayInRect:rect] retain];
|
||||
#endif
|
||||
We can't do this in GNUstep as there's no equivalent, so under
|
||||
GNUstep we retain the old method of drawing direct to the
|
||||
EmacsView. */
|
||||
{
|
||||
NSTRACE ("EmacsView createDrawingBuffer]");
|
||||
|
||||
NSGraphicsContext *screen;
|
||||
CGColorSpaceRef colorSpace = [[[self window] colorSpace] CGColorSpace];
|
||||
CGFloat scale = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
|
||||
if (drawingBuffer != nil)
|
||||
CGContextRelease (drawingBuffer);
|
||||
|
||||
drawingBuffer = CGBitmapContextCreate (nil, NSWidth (frame) * scale, NSHeight (frame) * scale,
|
||||
8, 0, colorSpace,
|
||||
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
|
||||
|
||||
/* This fixes the scale to match the backing scale factor, and flips the image. */
|
||||
CGContextTranslateCTM(drawingBuffer, 0, NSHeight (frame) * scale);
|
||||
CGContextScaleCTM(drawingBuffer, scale, -scale);
|
||||
}
|
||||
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
- (void)focusOnDrawingBuffer
|
||||
{
|
||||
/* Creating the graphics context each time is very slow, but it
|
||||
doesn't seem possible to cache and reuse it. */
|
||||
[NSGraphicsContext
|
||||
setCurrentContext:
|
||||
[NSGraphicsContext graphicsContextWithBitmapImageRep:drawingBuffer]];
|
||||
NSTRACE ("EmacsView focusOnDrawingBuffer]");
|
||||
|
||||
NSGraphicsContext *buf =
|
||||
[NSGraphicsContext
|
||||
graphicsContextWithCGContext:drawingBuffer flipped:YES];
|
||||
|
||||
[NSGraphicsContext setCurrentContext:buf];
|
||||
}
|
||||
|
||||
|
||||
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
|
||||
/* Update the drawing buffer when the backing scale factor changes. */
|
||||
{
|
||||
CGFloat old = [[[notification userInfo]
|
||||
objectForKey:@"NSBackingPropertyOldScaleFactorKey"]
|
||||
doubleValue];
|
||||
CGFloat new = [[self window] backingScaleFactor];
|
||||
NSTRACE ("EmacsView windowDidChangeBackingProperties:]");
|
||||
|
||||
if (old != new)
|
||||
{
|
||||
NSRect frame = [self frame];
|
||||
[self createDrawingBufferWithRect:frame];
|
||||
ns_clear_frame (emacsframe);
|
||||
expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
|
||||
}
|
||||
CGFloat old = [[[notification userInfo]
|
||||
objectForKey:@"NSBackingPropertyOldScaleFactorKey"]
|
||||
doubleValue];
|
||||
CGFloat new = [[self window] backingScaleFactor];
|
||||
|
||||
if (old != new)
|
||||
{
|
||||
NSRect frame = [self frame];
|
||||
[self createDrawingBuffer];
|
||||
ns_clear_frame (emacsframe);
|
||||
expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* NS_IMPL_COCOA */
|
||||
|
||||
|
||||
- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect
|
||||
|
|
@ -8284,13 +8281,31 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect
|
|||
NSTRACE_RECT ("Destination", dstRect);
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
[drawingBuffer drawInRect:dstRect
|
||||
fromRect:srcRect
|
||||
operation:NSCompositingOperationCopy
|
||||
fraction:1.0
|
||||
respectFlipped:NO
|
||||
hints:nil];
|
||||
CGImageRef copy;
|
||||
NSRect frame = [self frame];
|
||||
NSAffineTransform *setOrigin = [NSAffineTransform transform];
|
||||
|
||||
[[NSGraphicsContext currentContext] saveGraphicsState];
|
||||
|
||||
/* Set the clipping before messing with the buffer's
|
||||
orientation. */
|
||||
NSRectClip (dstRect);
|
||||
|
||||
/* Unflip the buffer as the copied image will be unflipped, and
|
||||
offset the top left so when we draw back into the buffer the
|
||||
correct part of the image is drawn. */
|
||||
CGContextScaleCTM(drawingBuffer, 1, -1);
|
||||
CGContextTranslateCTM(drawingBuffer, 0, -NSHeight (frame)
|
||||
- (NSMinY (dstRect) - NSMinY (srcRect)));
|
||||
|
||||
/* Take a copy of the buffer and then draw it back to the buffer,
|
||||
limited by the clipping rectangle. */
|
||||
copy = CGBitmapContextCreateImage (drawingBuffer);
|
||||
CGContextDrawImage (drawingBuffer, frame, copy);
|
||||
|
||||
CGImageRelease (copy);
|
||||
|
||||
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||
[self setNeedsDisplayInRect:dstRect];
|
||||
#else
|
||||
hide_bell(); // Ensure the bell image isn't scrolled.
|
||||
|
|
@ -8304,6 +8319,24 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect
|
|||
}
|
||||
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
- (BOOL)wantsUpdateLayer
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)updateLayer
|
||||
{
|
||||
NSTRACE ("EmacsView updateLayer]");
|
||||
|
||||
CGImageRef contentsImage = CGBitmapContextCreateImage(drawingBuffer);
|
||||
[[self layer] setContents:(id)contentsImage];
|
||||
CGImageRelease(contentsImage);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
- (void)drawRect: (NSRect)rect
|
||||
{
|
||||
NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]",
|
||||
|
|
@ -8312,14 +8345,6 @@ - (void)drawRect: (NSRect)rect
|
|||
if (!emacsframe || !emacsframe->output_data.ns)
|
||||
return;
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
[drawingBuffer drawInRect:rect
|
||||
fromRect:rect
|
||||
operation:NSCompositingOperationSourceOver
|
||||
fraction:1
|
||||
respectFlipped:NO
|
||||
hints:nil];
|
||||
#else
|
||||
int x = NSMinX (rect), y = NSMinY (rect);
|
||||
int width = NSWidth (rect), height = NSHeight (rect);
|
||||
|
||||
|
|
@ -8327,7 +8352,6 @@ - (void)drawRect: (NSRect)rect
|
|||
block_input ();
|
||||
expose_frame (emacsframe, x, y, width, height);
|
||||
unblock_input ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue