From 7bf8ec3b18d2d7c04bccc522b4140f7a72f37202 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 23 Jun 2014 02:18:46 +0000 Subject: Reverse previous commit for alpha channel data in image because of newly discovered crashes in Tk --- macosx/tkMacOSXDraw.c | 153 +++++++++++++++++++------------------------- macosx/tkMacOSXPrivate.h | 2 - macosx/tkMacOSXSubwindows.c | 4 +- macosx/tkMacOSXXStubs.c | 90 +++++++++++++------------- 4 files changed, 113 insertions(+), 136 deletions(-) diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index 1589e43..0727b26 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -114,70 +114,6 @@ TkMacOSXInitCGDrawing( /* *---------------------------------------------------------------------- * - * BitmapRepFromDrawableRect - * - * Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep. - * - * Results: - * Returns an NSBitmapRep representing the image of the given rectangle of - * the given drawable. - * - * NOTE: The x,y coordinates should be relative to a coordinate system with - * origin at the top left, as used by XImage and CGImage, not bottom - * left as used by NSView. - * - * Side effects: - * Allocates an NSBitmapImageRep, which must be released. - * - *---------------------------------------------------------------------- - */ -NSBitmapImageRep* -BitmapRepFromDrawableRect( - MacDrawable *drawable, - int x, - int y, - unsigned int width, - unsigned int height) -{ - CGImageRef cg_image=NULL, sub_cg_image=NULL; - NSBitmapImageRep *bitmap_rep=NULL; - NSView *view=NULL; - - if ( drawable->flags & TK_IS_PIXMAP && drawable->context) { - /* This means that the MacDrawable is functioning as a Tk Pixmap, so its view - field is NULL and its context field points to a CGBitmapContext. - */ - CGRect image_rect = CGRectMake(x, y, width, height); - cg_image = CGBitmapContextCreateImage( (CGContextRef) drawable->context); - sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect); - if ( sub_cg_image ) { - bitmap_rep = [NSBitmapImageRep alloc]; - [bitmap_rep initWithCGImage:sub_cg_image]; - CGImageRelease(sub_cg_image); - } - if ( cg_image ) { - CGImageRelease(cg_image); - } - } else if ( (view = TkMacOSXDrawableView(drawable)) ) { - /* convert top-left coordinates to NSView coordinates */ - int view_height = [view bounds].size.height; - NSRect view_rect = NSMakeRect(x + drawable->xOff, - view_height - height - y - drawable->yOff, - width,height); - bitmap_rep = [NSBitmapImageRep alloc]; - [view lockFocus]; - [bitmap_rep initWithFocusedViewRect:view_rect]; - [view unlockFocus]; - } else { - TkMacOSXDbgMsg("Invalid source drawable"); - } - - return bitmap_rep; -} - -/* - *---------------------------------------------------------------------- - * * XCopyArea -- * * Copies data from one drawable to another using block transfer @@ -198,45 +134,86 @@ XCopyArea( Display *display, /* Display. */ Drawable src, /* Source drawable. */ Drawable dst, /* Destination drawable. */ - GC gc, /* GC to use. */ + GC gc, /* GC to use. */ int src_x, /* X & Y, width & height */ int src_y, /* define the source rectangle */ - unsigned int width, /* that will be copied. */ + unsigned int width, /* that will be copied. */ unsigned int height, int dest_x, /* Dest X & Y on dest rect. */ int dest_y) { TkMacOSXDrawingContext dc; MacDrawable *srcDraw = (MacDrawable *) src; - NSBitmapImageRep *bitmap_rep = NULL; display->request++; if (!width || !height) { - /* TkMacOSXDbgMsg("Drawing of empty area requested"); */ + /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */ return; } - if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) { - TkMacOSXDbgMsg("Invalid destination drawable"); - } - if (dc.context) { - bitmap_rep = BitmapRepFromDrawableRect(srcDraw, src_x, src_y, width, height); - if ( bitmap_rep ) { - CGImageRef img = [bitmap_rep CGImage]; - CGRect image_rect = CGRectMake(0, 0, - srcDraw->size.width, srcDraw->size.height); - if (img) { - DrawCGImage(dst, gc, dc.context, img, gc->foreground, - gc->background, image_rect, - CGRectMake(src_x, src_y, width, height), - CGRectMake(dest_x, dest_y, width, height)); - CFRelease(img); - } - [bitmap_rep release]; + if (srcDraw->flags & TK_IS_PIXMAP) { + if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) { + return; + } + if (dc.context) { + CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src); + + if (img) { + DrawCGImage(dst, gc, dc.context, img, gc->foreground, + gc->background, CGRectMake(0, 0, + srcDraw->size.width, srcDraw->size.height), + CGRectMake(src_x, src_y, width, height), + CGRectMake(dest_x, dest_y, width, height)); + CFRelease(img); } else { - TkMacOSXDbgMsg("Invalid source drawable"); + TkMacOSXDbgMsg("Invalid source drawable"); + } + } else { + TkMacOSXDbgMsg("Invalid destination drawable"); } + TkMacOSXRestoreDrawingContext(&dc); + } else if (TkMacOSXDrawableWindow(src)) { + NSView *view = TkMacOSXDrawableView(srcDraw); + NSWindow *w = [view window]; + NSInteger gs = [w windowNumber] > 0 ? [w gState] : 0; + /* // alternative using per-view gState: + NSInteger gs = [view gState]; + if (!gs) { + [view allocateGState]; + if ([view lockFocusIfCanDraw]) { + [view unlockFocus]; + } + gs = [view gState]; + } + */ + if (!gs || !TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) { + return; + } + if (dc.context) { + NSGraphicsContext *gc = nil; + CGFloat boundsH = [view bounds].size.height; + NSRect srcRect = NSMakeRect(srcDraw->xOff + src_x, boundsH - + height - (srcDraw->yOff + src_y), width, height); + + if (((MacDrawable *) dst)->flags & TK_IS_PIXMAP) { + gc = [NSGraphicsContext graphicsContextWithGraphicsPort: + dc.context flipped:NO]; + if (gc) { + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:gc]; + } + } + NSCopyBits(gs, srcRect, NSMakePoint(dest_x, + dc.portBounds.size.height - dest_y)); + if (gc) { + [NSGraphicsContext restoreGraphicsState]; + } + } else { + TkMacOSXDbgMsg("Invalid destination drawable"); + } + TkMacOSXRestoreDrawingContext(&dc); + } else { + TkMacOSXDbgMsg("Invalid source drawable"); } - TkMacOSXRestoreDrawingContext(&dc); } /* @@ -277,7 +254,7 @@ XCopyPlane( display->request++; if (!width || !height) { - /* TkMacOSXDbgMsg("Drawing of empty area requested"); */ + /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */ return; } if (plane != 1) { diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index 9220397..034c450 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -230,8 +230,6 @@ MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr); MODULE_SCOPE int TkMacOSXIsWindowZoomed(TkWindow *winPtr); MODULE_SCOPE int TkGenerateButtonEventForXPointer(Window window); MODULE_SCOPE EventModifiers TkMacOSXModifierState(void); -MODULE_SCOPE NSBitmapImageRep* BitmapRepFromDrawableRect(MacDrawable *drawable, - int x, int y, unsigned int width, unsigned int height); MODULE_SCOPE int TkMacOSXSetupDrawingContext(Drawable d, GC gc, int useCG, TkMacOSXDrawingContext *dcPtr); MODULE_SCOPE void TkMacOSXRestoreDrawingContext( diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index 29bc4a3..18276fb 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -1277,7 +1277,7 @@ UpdateOffsets( * Returns a handle to a new pixmap. * * Side effects: - * Allocates a new CGBitmapContext. + * Allocates a new Macintosh GWorld. * *---------------------------------------------------------------------- */ @@ -1323,7 +1323,7 @@ Tk_GetPixmap( * None. * * Side effects: - * Deletes the CGBitmapContext created by Tk_GetPixmap. + * Deletes the Macintosh GWorld created by Tk_GetPixmap. * *---------------------------------------------------------------------- */ diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index f009b52..848b49c 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -842,7 +842,7 @@ XCreateImage( * This function copies data from a pixmap or window into an XImage. * * Results: - * Returns a newly allocated XImage containing the data from the given + * Returns a newly allocated image containing the data from the given * rectangle of the given drawable. * * Side effects: @@ -863,57 +863,59 @@ XGetImage( int format) { MacDrawable *macDraw = (MacDrawable *) d; - NSBitmapImageRep *bitmap_rep; - XImage * imagePtr = NULL; - char * bitmap = NULL; - char * image_data=NULL; - int depth = 32; - int offset = 0; - int bitmap_pad = 0; - int bytes_per_row = 4*width; - int size; + XImage * imagePtr = NULL; + Pixmap pixmap = (Pixmap) NULL; + Tk_Window win = (Tk_Window) macDraw->winPtr; + GC gc; + char * data = NULL; + int depth = 32; + int offset = 0; + int bitmap_pad = 0; + int bytes_per_line = 0; + if (format == ZPixmap) { - if (width == 0 || height == 0) { - return NULL; + if (width > 0 && height > 0) { + /* + * Tk_GetPixmap fails for zero width or height. + */ + + pixmap = Tk_GetPixmap(display, d, width, height, depth); } + if (win) { + XGCValues values; - bitmap_rep = BitmapRepFromDrawableRect(macDraw, x, y,width, height); - NSSize image_size = NSMakeSize(width, height); - NSImage* ns_image = [[NSImage alloc]initWithSize:image_size]; - [ns_image addRepresentation:bitmap_rep]; - - /* Assume premultiplied nonplanar data with 4 bytes per pixel and alpha last.*/ - if ( [bitmap_rep bitmapFormat] == 0 && - [bitmap_rep isPlanar ] == 0 && - [bitmap_rep samplesPerPixel] == 4 ) { - bytes_per_row = [bitmap_rep bytesPerRow]; - size = bytes_per_row*height; - image_data = (char*)[bitmap_rep bitmapData]; - if ( image_data ) { - int row, n, m; - bitmap = ckalloc(size); - /* - Oddly enough, the bitmap has the top row at the beginning, - and the pixels are in BGRA format. - */ - for (row=0, n=0; rowcontext; + if (context) { + data = CGBitmapContextGetData(context); + bytes_per_line = CGBitmapContextGetBytesPerRow(context); } } - if (bitmap) { + if (data) { imagePtr = XCreateImage(display, NULL, depth, format, offset, - (char*)bitmap, width, height, bitmap_pad, bytes_per_row); - [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/ - [ns_image release]; + data, width, height, bitmap_pad, bytes_per_line); + + /* + * Track Pixmap underlying the XImage in the unused obdata field + * so that we can treat XImages coming from XGetImage specially. + */ + + imagePtr->obdata = (XPointer) pixmap; + } else if (pixmap) { + Tk_FreePixmap(display, pixmap); + } + if (!win) { + XFreeGC(display, gc); } } else { - TkMacOSXDbgMsg("Could not extract image from drawable."); + TkMacOSXDbgMsg("Invalid image format"); } return imagePtr; } -- cgit v0.12