summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorculler <culler>2018-11-08 23:01:16 (GMT)
committerculler <culler>2018-11-08 23:01:16 (GMT)
commit664660a0047e8d1388365ea1447f244dde484625 (patch)
tree6bd9353fe840577c4e0f0428ade40ba0fd69b6fe /generic
parent827f7aabce730f6caf209e345ebc96777d5ca363 (diff)
parent653b68156bf6eb7fa6514493fa5e02bb6e5734c6 (diff)
downloadtk-664660a0047e8d1388365ea1447f244dde484625.zip
tk-664660a0047e8d1388365ea1447f244dde484625.tar.gz
tk-664660a0047e8d1388365ea1447f244dde484625.tar.bz2
Another big round of updates for macOS, fixing bugs old and new including
crashes and graphics artifacts.
Diffstat (limited to 'generic')
-rw-r--r--generic/tkImgPhInstance.c64
-rw-r--r--generic/tkTest.c24
2 files changed, 50 insertions, 38 deletions
diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c
index 13e6bbf..cf07dcf 100644
--- a/generic/tkImgPhInstance.c
+++ b/generic/tkImgPhInstance.c
@@ -30,8 +30,10 @@ extern int _XInitImageFuncPtrs(XImage *image);
* Forward declarations
*/
+#ifndef MAC_OSX_TK
static void BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
int xOffset, int yOffset, int width, int height);
+#endif
static int IsValidPalette(PhotoInstance *instancePtr,
const char *palette);
static int CountBits(pixel mask);
@@ -409,7 +411,7 @@ TkImgPhotoGet(
*
*----------------------------------------------------------------------
*/
-
+#ifndef MAC_OSX_TK
#ifndef _WIN32
#define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift))
@@ -418,13 +420,6 @@ TkImgPhotoGet(
(UCHAR(r) << red_shift) | \
(UCHAR(g) << green_shift) | \
(UCHAR(b) << blue_shift) ))
-#ifdef MAC_OSX_TK
-#define RGBA(r, g, b, a) ((unsigned)( \
- (UCHAR(r) << red_shift) | \
- (UCHAR(g) << green_shift) | \
- (UCHAR(b) << blue_shift) | \
- (UCHAR(a) << alpha_shift) ))
-#endif
#define RGB15(r, g, b) ((unsigned)( \
(((r) * red_mask / 255) & red_mask) | \
(((g) * green_mask / 255) & green_mask) | \
@@ -443,16 +438,7 @@ BlendComplexAlpha(
unsigned long pixel;
unsigned char r, g, b, alpha, unalpha, *masterPtr;
unsigned char *alphaAr = iPtr->masterPtr->pix32;
-#if defined(MAC_OSX_TK)
- /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels. Each
- * block gets blended with the color of one image pixel. Since we iterate
- * over the background subpixels, we reset the width and height to the
- * subpixel dimensions of the background image we are using.
- */
- int pp = bgImg->pixelpower;
- width = width << pp;
- height = height << pp;
-#endif
+
/*
* This blending is an integer version of the Source-Over compositing rule
* (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
@@ -492,13 +478,6 @@ BlendComplexAlpha(
while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
blue_shift++;
}
-#ifdef MAC_OSX_TK
- unsigned long alpha_mask = visual->alpha_mask;
- unsigned long alpha_shift = 0;
- while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) {
- alpha_shift++;
- }
-#endif
#endif /* !_WIN32 */
/*
@@ -558,16 +537,9 @@ BlendComplexAlpha(
#endif /* !_WIN32 && !MAC_OSX_TK */
for (y = 0; y < height; y++) {
-# if !defined(MAC_OSX_TK)
line = (y + yOffset) * iPtr->masterPtr->width;
for (x = 0; x < width; x++) {
masterPtr = alphaAr + ((line + x + xOffset) * 4);
-#else
- /* Repeat each image row and column 2^pp times. */
- line = ((y>>pp) + yOffset) * iPtr->masterPtr->width;
- for (x = 0; x < width; x++) {
- masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4);
-#endif
alpha = masterPtr[3];
/*
@@ -599,16 +571,13 @@ BlendComplexAlpha(
g = ALPHA_BLEND(ga, g, alpha, unalpha);
b = ALPHA_BLEND(ba, b, alpha, unalpha);
}
-#ifndef MAC_OSX_TK
XPutPixel(bgImg, x, y, RGB(r, g, b));
-#else
- XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha));
-#endif
}
}
}
#undef ALPHA_BLEND
}
+#endif /* MAC_OSX_TK */
/*
*----------------------------------------------------------------------
@@ -640,7 +609,6 @@ TkImgPhotoDisplay(
* to imageX and imageY. */
{
PhotoInstance *instancePtr = clientData;
- XVisualInfo visInfo = instancePtr->visualInfo;
/*
* If there's no pixmap, it means that an error occurred while creating
@@ -651,6 +619,27 @@ TkImgPhotoDisplay(
return;
}
+#ifdef MAC_OSX_TK
+ /*
+ * The Mac version of TkPutImage handles RGBA images directly. There is
+ * no need to call XGetImage or to do the Porter-Duff compositing by hand.
+ * We just let the CG graphics library do it, using the graphics hardware.
+ */
+ unsigned char *rgbaPixels = instancePtr->masterPtr->pix32;
+
+ XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
+ (unsigned int)instancePtr->width,
+ (unsigned int)instancePtr->height,
+ 0, (unsigned int)(4 * instancePtr->width));
+
+ TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
+ photo, imageX, imageY, drawableX, drawableY,
+ (unsigned int) width, (unsigned int) height);
+ photo->data = NULL;
+ XDestroyImage(photo);
+#else
+ XVisualInfo visInfo = instancePtr->visualInfo;
+
if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
&& visInfo.depth >= 15
&& (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
@@ -709,6 +698,7 @@ TkImgPhotoDisplay(
XSetClipOrigin(display, instancePtr->gc, 0, 0);
}
XFlush(display);
+#endif
}
/*
diff --git a/generic/tkTest.c b/generic/tkTest.c
index 0cf1f49..fff997c 100644
--- a/generic/tkTest.c
+++ b/generic/tkTest.c
@@ -31,6 +31,9 @@
#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
+#define SIMULATE_DRAWING TkTestSimulateDrawing(true);
+#else
+#define SIMULATE_DRAWING
#endif
#ifdef __UNIX__
@@ -1560,16 +1563,35 @@ ImageDisplay(
TImageInstance *instPtr = (TImageInstance *) clientData;
char buffer[200 + TCL_INTEGER_SPACE * 6];
+ /*
+ * The purpose of the test image type is to track the calls to an image
+ * display proc and record the parameters passed in each call. On macOS
+ * these tests will fail because of the asynchronous drawing. The low
+ * level graphics calls below which are supposed to draw a rectangle will
+ * not draw anything to the screen because the idle task will not be
+ * processed inside of the drawRect method and hence will not be able to
+ * obtain a valid graphics context. Instead, the window will be marked as
+ * needing display, and will be redrawn during a future asynchronous call
+ * to drawRect. This will generate an other call to this display proc,
+ * and the recorded data will show extra calls, causing the test to fail.
+ * To avoid this, we can set the [NSApp simulateDrawing] flag, which will
+ * cause all low level drawing routines to return immediately and not
+ * schedule the window for drawing later. This flag is cleared by the
+ * next call to XSync, which is called by the update command.
+ */
+
sprintf(buffer, "%s display %d %d %d %d",
instPtr->masterPtr->imageName, imageX, imageY, width, height);
Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
- buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
if (width > (instPtr->masterPtr->width - imageX)) {
width = instPtr->masterPtr->width - imageX;
}
if (height > (instPtr->masterPtr->height - imageY)) {
height = instPtr->masterPtr->height - imageY;
}
+
+ SIMULATE_DRAWING
XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
(unsigned) (width-1), (unsigned) (height-1));
XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,