diff options
author | culler <culler> | 2018-11-08 20:19:29 (GMT) |
---|---|---|
committer | culler <culler> | 2018-11-08 20:19:29 (GMT) |
commit | 23edb997712e41c74e3a457f54beb42ce5ed14a4 (patch) | |
tree | 6698701c317553d28a271aa8664ca5baa12f99d6 /macosx/tkMacOSXImage.c | |
parent | 3391cf4be8163d08bf29e7ef2adc64bdbb030b22 (diff) | |
download | tk-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.c | 78 |
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"); |