summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macosx/tkMacOSXDraw.c153
-rw-r--r--macosx/tkMacOSXPrivate.h2
-rw-r--r--macosx/tkMacOSXSubwindows.c4
-rw-r--r--macosx/tkMacOSXXStubs.c90
4 files changed, 113 insertions, 136 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 3ce38fd..5be04a4 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -113,70 +113,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
@@ -197,45 +133,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);
}
/*
@@ -276,7 +253,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 1c174fe..3ad0689 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -228,8 +228,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 915dea1..c235cbf 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 29233d9..9594cd3 100644
--- a/macosx/tkMacOSXXStubs.c
+++ b/macosx/tkMacOSXXStubs.c
@@ -869,7 +869,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:
@@ -890,57 +890,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; row<height; row++, n+=bytes_per_row) {
- for (m=n; m<n+bytes_per_row; m+=4) {
- *(bitmap+m) = *(image_data+m+2);
- *(bitmap+m+1) = *(image_data+m+1);
- *(bitmap+m+2) = *(image_data+m);
- *(bitmap+m+3) = *(image_data+m+3);
- }
- }
+ gc = Tk_GetGC(win, 0, &values);
+ } else {
+ gc = XCreateGC(display, pixmap, 0, NULL);
+ }
+ if (pixmap) {
+ CGContextRef context;
+
+ XCopyArea(display, d, pixmap, gc, x, y, width, height, 0, 0);
+ context = ((MacDrawable *) pixmap)->context;
+ 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;
}