diff options
Diffstat (limited to 'macosx')
-rw-r--r-- | macosx/tkMacOSXButton.c | 3 | ||||
-rw-r--r-- | macosx/tkMacOSXDraw.c | 55 | ||||
-rw-r--r-- | macosx/tkMacOSXSubwindows.c | 20 | ||||
-rw-r--r-- | macosx/tkMacOSXXStubs.c | 37 |
4 files changed, 75 insertions, 40 deletions
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c index ebbcf09..f4fbc48 100644 --- a/macosx/tkMacOSXButton.c +++ b/macosx/tkMacOSXButton.c @@ -318,7 +318,8 @@ TkpComputeButtonGeometry( Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength, butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); - txtWidth = butPtr->textWidth + DEF_INSET_LEFT + DEF_INSET_RIGHT; + /*Remove extraneous padding around label widgets.*/ + txtWidth = butPtr->textWidth; txtHeight = butPtr->textHeight + DEF_INSET_BOTTOM + DEF_INSET_TOP; charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); Tk_GetFontMetrics(butPtr->tkfont, &fm); diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index 6a0b409..f48538d 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -314,29 +314,35 @@ XCopyPlane( TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; unsigned long imageBackground = gc->background; if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){ - CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap); - CGRect rect = CGRectMake(dest_x, dest_y, width, height); - rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff); - CGContextSaveGState(context); - /* Move the origin of the destination to top left. */ - CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect)); - CGContextScaleCTM(context, 1, -1); - /* Fill with the background color, clipping to the mask. */ - CGContextClipToMask(context, rect, mask); - TkMacOSXSetColorInContext(gc, gc->background, dc.context); - CGContextFillRect(dc.context, rect); - /* Fill with the foreground color, clipping to the intersection of img and mask. */ - CGContextClipToMask(context, rect, img); - TkMacOSXSetColorInContext(gc, gc->foreground, context); - CGContextFillRect(context, rect); - CGContextRestoreGState(context); - CGImageRelease(mask); - CGImageRelease(img); + CGRect srcRect = CGRectMake(src_x, src_y, width, height); + CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap); + CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect); + CGRect rect = CGRectMake(dest_x, dest_y, width, height); + rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff); + CGContextSaveGState(context); + /* Move the origin of the destination to top left. */ + CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect)); + CGContextScaleCTM(context, 1, -1); + /* Fill with the background color, clipping to the mask. */ + CGContextClipToMask(context, rect, submask); + TkMacOSXSetColorInContext(gc, gc->background, dc.context); + CGContextFillRect(context, rect); + /* Fill with the foreground color, clipping to the + intersection of img and mask. */ + CGImageRef subimage = CGImageCreateWithImageInRect(img, srcRect); + CGContextClipToMask(context, rect, subimage); + TkMacOSXSetColorInContext(gc, gc->foreground, context); + CGContextFillRect(context, rect); + CGContextRestoreGState(context); + CGImageRelease(img); + CGImageRelease(mask); + CGImageRelease(submask); + CGImageRelease(subimage); } else { DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground, CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), - CGRectMake(src_x, src_y, width, height), - CGRectMake(dest_x, dest_y, width, height)); + CGRectMake(src_x, src_y, width, height), + CGRectMake(dest_x, dest_y, width, height)); CGImageRelease(img); } } else { /* no image */ @@ -393,9 +399,11 @@ TkPutImage( CGImageRef img = CreateCGImageWithXImage(image); if (img) { + /* If the XImage has big pixels, rescale the source dimensions.*/ + int pp = image->pixelpower; DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background, - CGRectMake(0, 0, image->width, image->height), - CGRectMake(src_x, src_y, width, height), + CGRectMake(0, 0, image->width<<pp, image->height<<pp), + CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp), CGRectMake(dest_x, dest_y, width, height)); CFRelease(img); } else { @@ -786,9 +794,6 @@ DrawCGImage( CGContextDrawImage(context, dstBounds, image); CGContextRestoreGState(context); #endif /* TK_MAC_DEBUG_IMAGE_DRAWING */ - /*if (CGImageIsMask(image)) { - CGContextRestoreGState(context); - }*/ if (subImage) { CFRelease(subImage); } diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index f026318..9851474 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -153,8 +153,6 @@ XMapWindow( if ( [win canBecomeKeyWindow] ) { [win makeKeyAndOrderFront:NSApp]; } - /* Why do we need this? (It is used by Carbon)*/ - [win windowRef]; TkMacOSXApplyWindowAttributes(macWin->winPtr, win); } TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); @@ -316,7 +314,6 @@ XResizeWindow( display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { NSWindow *w = macWin->winPtr->wmInfoPtr->window; - if (w) { NSRect r = [w contentRectForFrameRect:[w frame]]; r.origin.y += r.size.height - height; @@ -360,10 +357,19 @@ XMoveResizeWindow( if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { NSWindow *w = macWin->winPtr->wmInfoPtr->window; if (w) { - NSRect r = NSMakeRect(x + macWin->winPtr->wmInfoPtr->xInParent, - tkMacOSXZeroScreenHeight - (y + - macWin->winPtr->wmInfoPtr->yInParent + height), - width, height); + /* We explicitly convert everything to doubles so we don't get + * surprised (again) by what happens when you do arithmetic with + * unsigned ints. + */ + CGFloat X = (CGFloat)x; + CGFloat Y = (CGFloat)y; + CGFloat Width = (CGFloat)width; + CGFloat Height = (CGFloat)height; + CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent; + CGFloat YOff = (CGFloat)macWin->winPtr->wmInfoPtr->yInParent; + NSRect r = NSMakeRect(X + XOff, + tkMacOSXZeroScreenHeight - Y - YOff - Height, + Width, Height); [w setFrame:[w frameRectForContentRect:r] display:YES]; } } else { diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index 5d6ffb9..a2d175b 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -805,6 +805,10 @@ XCreateImage( ximage->format = format; ximage->data = data; ximage->obdata = NULL; + /* The default pixelpower is 0. This must be explicitly set to 1 in the + * case of an XImage extracted from a Retina display. + */ + ximage->pixelpower = 0; if (format == ZPixmap) { ximage->bits_per_pixel = 32; @@ -856,7 +860,8 @@ XCreateImage( * Results: * Returns a newly allocated XImage containing the data from the given * rectangle of the given drawable, or NULL if the XImage could not be - * constructed. + * constructed. NOTE: If we are copying from a window on a Retina + * display, the dimensions of the XImage will be 2*width x 2*height. * * Side effects: * None. @@ -885,7 +890,19 @@ XGetImage( int bitmap_pad = 0; int bytes_per_row = 4*width; int size; - TkMacOSXDbgMsg("XGetImage"); + MacDrawable *macDraw = (MacDrawable *) d; + NSWindow *win = TkMacOSXDrawableWindow(d); + /* This code assumes that backing scale factors are integers. Currently + * Retina displays use a scale factor of 2.0 and normal displays use 1.0. + * We do not support any other values here. + */ + int scalefactor = 1; + if (win && [win respondsToSelector:@selector(backingScaleFactor)]) { + scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1; + } + int scaled_height = height * scalefactor; + int scaled_width = width * scalefactor; + if (format == ZPixmap) { if (width == 0 || height == 0) { /* This happens all the time. @@ -894,7 +911,7 @@ XGetImage( return NULL; } - bitmap_rep = BitmapRepFromDrawableRect(d, x, y,width, height); + bitmap_rep = BitmapRepFromDrawableRect(d, x, y, width, height); bitmap_fmt = [bitmap_rep bitmapFormat]; if ( bitmap_rep == Nil || @@ -913,7 +930,9 @@ XGetImage( if ( [bitmap_rep isPlanar ] == 0 && [bitmap_rep samplesPerPixel] == 4 ) { bytes_per_row = [bitmap_rep bytesPerRow]; - size = bytes_per_row*height; + assert(bytes_per_row == 4 * scaled_width); + assert([bitmap_rep bytesPerPlane] == bytes_per_row * scaled_height); + size = bytes_per_row*scaled_height; image_data = (char*)[bitmap_rep bitmapData]; if ( image_data ) { int row, n, m; @@ -924,7 +943,7 @@ XGetImage( */ if (bitmap_fmt == 0) { /* BGRA */ - for (row=0, n=0; row<height; row++, n+=bytes_per_row) { + for (row=0, n=0; row<scaled_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); @@ -934,7 +953,7 @@ XGetImage( } } else { /* ABGR */ - for (row=0, n=0; row<height; row++, n+=bytes_per_row) { + for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) { for (m=n; m<n+bytes_per_row; m+=4) { *(bitmap+m) = *(image_data+m+3); *(bitmap+m+1) = *(image_data+m+2); @@ -947,7 +966,11 @@ XGetImage( } if (bitmap) { imagePtr = XCreateImage(display, NULL, depth, format, offset, - (char*)bitmap, width, height, bitmap_pad, bytes_per_row); + (char*)bitmap, scaled_width, scaled_height, + bitmap_pad, bytes_per_row); + if (scalefactor == 2) { + imagePtr->pixelpower = 1; + } [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/ [ns_image release]; } |