#ifdef NS_IMPL_COCOA
[NSGraphicsContext setCurrentContext:nil];
- [view display];
#else
block_input ();
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 ();
}
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
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];
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:].
maximizing_resize = NO;
#endif
- [self createDrawingBufferWithRect:r];
+ [self createDrawingBuffer];
win = [[EmacsWindow alloc]
initWithContentRect: r
}
-- (void)createDrawingBufferWithRect:(NSRect)rect
- /* Create and store a new NSBitmapImageRep for Emacs to draw
- into.
+#ifdef NS_IMPL_COCOA
+- (void)createDrawingBuffer
+ /* Create and store a new CGGraphicsContext 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. */
+ 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. */
{
-#ifdef NS_IMPL_COCOA
+ NSTRACE ("EmacsView createDrawingBuffer]");
+
+ NSGraphicsContext *screen;
+ CGColorSpaceRef colorSpace = [[[self window] colorSpace] CGColorSpace];
+ CGFloat scale = [[self window] backingScaleFactor];
+ NSRect frame = [self frame];
+
if (drawingBuffer != nil)
- [drawingBuffer release];
+ CGContextRelease (drawingBuffer);
- drawingBuffer = [[self bitmapImageRepForCachingDisplayInRect:rect] retain];
-#endif
+ 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]
+ NSTRACE ("EmacsView windowDidChangeBackingProperties:]");
+
+ CGFloat old = [[[notification userInfo]
objectForKey:@"NSBackingPropertyOldScaleFactorKey"]
- doubleValue];
- CGFloat new = [[self window] backingScaleFactor];
+ doubleValue];
+ CGFloat new = [[self window] backingScaleFactor];
- if (old != new)
- {
- NSRect frame = [self frame];
- [self createDrawingBufferWithRect:frame];
- ns_clear_frame (emacsframe);
- expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
- }
+ 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
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.
}
+#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 "]",
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);
block_input ();
expose_frame (emacsframe, x, y, width, height);
unblock_input ();
-#endif
}