summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXImage.c
diff options
context:
space:
mode:
authorculler <culler>2018-11-08 20:19:29 (GMT)
committerculler <culler>2018-11-08 20:19:29 (GMT)
commit23edb997712e41c74e3a457f54beb42ce5ed14a4 (patch)
tree6698701c317553d28a271aa8664ca5baa12f99d6 /macosx/tkMacOSXImage.c
parent3391cf4be8163d08bf29e7ef2adc64bdbb030b22 (diff)
downloadtk-23edb997712e41c74e3a457f54beb42ce5ed14a4.zip
tk-23edb997712e41c74e3a457f54beb42ce5ed14a4.tar.gz
tk-23edb997712e41c74e3a457f54beb42ce5ed14a4.tar.bz2
Fixed transparency issues and crashes related to PhotoImages and greatly simplified
the PhotoImage display procedure.
Diffstat (limited to 'macosx/tkMacOSXImage.c')
-rw-r--r--macosx/tkMacOSXImage.c78
1 files changed, 37 insertions, 41 deletions
diff --git a/macosx/tkMacOSXImage.c b/macosx/tkMacOSXImage.c
index 861b7ab..2b747f1 100644
--- a/macosx/tkMacOSXImage.c
+++ b/macosx/tkMacOSXImage.c
@@ -6,7 +6,7 @@
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
- * Copyright 2017 Marc Culler.
+ * Copyright 2017-2018 Marc Culler.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -29,7 +29,8 @@ _XInitImageFuncPtrs(
*
* TkMacOSXCreateCGImageWithXImage --
*
- * Create CGImage from XImage, copying the image data.
+ * Create CGImage from XImage, copying the image data. Called
+ * in Tk_PutImage and (currently) nowhere else.
*
* Results:
* CGImage, release after use.
@@ -46,8 +47,7 @@ static void ReleaseData(void *info, const void *data, size_t size) {
CGImageRef
TkMacOSXCreateCGImageWithXImage(
- XImage *image,
- int use_ximage_alpha)
+ XImage *image)
{
CGImageRef img = NULL;
size_t bitsPerComponent, bitsPerPixel;
@@ -88,21 +88,17 @@ TkMacOSXCreateCGImageWithXImage(
bitsPerPixel, image->bytes_per_line, provider, decode, 0);
}
} else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
+
/*
* Color image
*/
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
-
bitsPerComponent = 8;
bitsPerPixel = 32;
bitmapInfo = (image->byte_order == MSBFirst ?
- kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little);
- if (use_ximage_alpha) {
- bitmapInfo |= kCGImageAlphaPremultipliedFirst;
- } else {
- bitmapInfo |= kCGImageAlphaNoneSkipFirst;
- }
+ kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);
+ bitmapInfo |= kCGImageAlphaLast;
data = memcpy(ckalloc(len), image->data + image->xoffset, len);
if (data) {
provider = CGDataProviderCreateWithData(data, data, len, releaseData);
@@ -128,7 +124,12 @@ TkMacOSXCreateCGImageWithXImage(
*
* XGetImage --
*
- * This function copies data from a pixmap or window into an XImage.
+ * This function copies data from a pixmap or window into an XImage. It
+ * is essentially never used. At one time it was called by
+ * pTkImgPhotoDisplay, but that is no longer the case. Currently it is
+ * called two places, one of which is requesting an XY image which we do
+ * not support. It probably does not work correctly -- see the comments
+ * for TkMacOSXBitmapRepFromDrawableRect.
*
* Results:
* Returns a newly allocated XImage containing the data from the given
@@ -165,7 +166,6 @@ XGetImage(
unsigned int bytes_per_row, size, row, n, m;
unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
NSWindow *win = TkMacOSXDrawableWindow(drawable);
- MacDrawable *macDraw = ((MacDrawable*)drawable);
static enum {unknown, no, yes} has_retina = unknown;
if (win && has_retina == unknown) {
@@ -178,9 +178,11 @@ XGetImage(
}
if (has_retina == yes) {
+
/*
* We only allow scale factors 1 or 2, as Apple currently does.
*/
+
#ifdef __clang__
scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
#endif
@@ -192,8 +194,9 @@ XGetImage(
if (width == 0 || height == 0) {
return NULL;
}
+
bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
- x, y, width, height);
+ x, y, width, height);
if (!bitmap_rep) {
TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
return NULL;
@@ -212,29 +215,14 @@ XGetImage(
CFRelease(bitmap_rep);
return NULL;
}
-
- if (macDraw->flags & TK_USE_XIMAGE_ALPHA) {
- /*
- * When called by TkImgPhotoDisplay we are being asked to return a
- * background image to be blended with the photoimage using its
- * alpha channel, if it has one. Returning a black pixmap here
- * makes TkImgPhotoDisplay create an XImage with a premultiplied
- * alpha channel, as favored by Apple. When TkImgPhotoDisplay
- * passes this XImage to TkPutImage, targeting a pixmap, it creates
- * an image with correct transparency. This is used, for example,
- * when creating an iconphoto or a menu image from a PNG
- * photoimage.
- */
- bzero(bitmap, size);
- } else {
- memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
- }
+ memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
CFRelease(bitmap_rep);
/*
* When Apple extracts a bitmap from an NSView, it may be in
* either BGRA or ABGR format. For an XImage we need RGBA.
*/
+
struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;
for (row = 0, n = 0; row < scaled_height; row++, n += bytes_per_row) {
@@ -514,8 +502,9 @@ XCreateImage(
*
* TkPutImage --
*
- * Copies a subimage from an in-memory image to a rectangle of
- * of the specified drawable.
+ * Copies a rectangular subimage of an XImage into a drawable.
+ * Currently this is only called by TkImgPhotoDisplay, using
+ * a Window as the drawable.
*
* Results:
* None.
@@ -542,23 +531,30 @@ TkPutImage(
unsigned int height) /* distination and source. */
{
TkMacOSXDrawingContext dc;
- MacDrawable *macDraw = ((MacDrawable*)drawable);
display->request++;
if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
return BadDrawable;
}
if (dc.context) {
- CGImageRef img = TkMacOSXCreateCGImageWithXImage(image,
- macDraw->flags & TK_USE_XIMAGE_ALPHA);
+ CGRect bounds, srcRect, dstRect;
+ CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);
+ CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
if (img) {
- /* If the XImage has big pixels, rescale the source dimensions.*/
+
+ /* If the XImage has big pixels, the source is rescaled to reflect
+ * the actual pixel dimensions. This is not currently used, but
+ * could arise if the image were copied from a retina monitor and
+ * redrawn on an ordinary monitor.
+ */
+
int pp = image->pixelpower;
+ bounds = CGRectMake(0, 0, image->width, image->height);
+ srcRect = CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp);
+ dstRect = CGRectMake(dest_x, dest_y, width, height);
TkMacOSXDrawCGImage(drawable, gc, dc.context,
- img, gc->foreground, gc->background,
- 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));
+ img, gc->foreground, gc->background,
+ bounds, srcRect, dstRect);
CFRelease(img);
} else {
TkMacOSXDbgMsg("Invalid source drawable");