diff options
author | culler <culler> | 2018-11-08 23:01:16 (GMT) |
---|---|---|
committer | culler <culler> | 2018-11-08 23:01:16 (GMT) |
commit | 664660a0047e8d1388365ea1447f244dde484625 (patch) | |
tree | 6bd9353fe840577c4e0f0428ade40ba0fd69b6fe /generic | |
parent | 827f7aabce730f6caf209e345ebc96777d5ca363 (diff) | |
parent | 653b68156bf6eb7fa6514493fa5e02bb6e5734c6 (diff) | |
download | tk-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.c | 64 | ||||
-rw-r--r-- | generic/tkTest.c | 24 |
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, |