From dd2a728b2874239f39fa0a833ea27e33beb07340 Mon Sep 17 00:00:00 2001 From: hobbs Date: Thu, 10 Oct 2002 21:01:13 +0000 Subject: * generic/tkCanvPs.c (TkImageGetColor): corrected bogus use of TkColormapData on Windows (Windows now requires RGB pixel data from image). * win/tkWinImage.c (XGetImage, XGetImageZPixmap): added support for generating ps for embedded widgets on canvases on Windows, tested for 8, 16, 24 and 32-bit depths (XGetImageZPixmap not used). --- ChangeLog | 7 ++-- generic/tkCanvPs.c | 40 ++++++++++++------ win/tkWinImage.c | 121 ++++++++++++++++++++++++++++------------------------- 3 files changed, 97 insertions(+), 71 deletions(-) diff --git a/ChangeLog b/ChangeLog index a311622..5c9a4e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,11 @@ * generic/tkCanvWind.c (CanvasPsWindow): removed dead code loop. * generic/tkCanvas.h: moved TkColormapData struct to tkCanvPs.c * generic/tkCanvPs.c (TkImageGetColor): corrected bogus use of - TkColormapData on Windows. Non-separated data may need correction - as well. + TkColormapData on Windows (Windows now requires RGB pixel data + from image). * win/tkWinImage.c (XGetImage, XGetImageZPixmap): added support - for generating ps for embedded windows on canvases. + for generating ps for embedded widgets on canvases on Windows, + tested for 8, 16, 24 and 32-bit depths (XGetImageZPixmap not used). * library/tk.tcl: simplified the adding of extra and events to <>. diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c index b72ded9..d32434f 100644 --- a/generic/tkCanvPs.c +++ b/generic/tkCanvPs.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvPs.c,v 1.11 2002/10/10 07:25:24 hobbs Exp $ + * RCS: @(#) $Id: tkCanvPs.c,v 1.12 2002/10/10 21:01:17 hobbs Exp $ */ #include "tkInt.h" @@ -1113,6 +1113,12 @@ GetPostscriptPoints(interp, string, doublePtr) * data passed as an argument, and should work for all Visual * types. * + * This implementation is bogus on Windows because the colormap + * data is never filled in. Instead all postscript generated + * data coming through here is expected to be RGB color data. + * To handle lower bit-depth images properly, XQueryColors + * must be implemented for Windows. + * * Results: * Returns red, green, and blue color values in the range * 0 to 1. There are no error returns. @@ -1122,7 +1128,27 @@ GetPostscriptPoints(interp, string, doublePtr) * *-------------------------------------------------------------- */ +#ifdef WIN32 +#include +/* + * We could just define these instead of pulling in windows.h. + #define GetRValue(rgb) ((BYTE)(rgb)) + #define GetGValue(rgb) ((BYTE)(((WORD)(rgb)) >> 8)) + #define GetBValue(rgb) ((BYTE)((rgb)>>16)) +*/ + +static void +TkImageGetColor(cdata, pixel, red, green, blue) + TkColormapData *cdata; /* Colormap data */ + unsigned long pixel; /* Pixel value to look up */ + double *red, *green, *blue; /* Color data to return */ +{ + *red = (double) GetRValue(pixel) / 255.0; + *green = (double) GetGValue(pixel) / 255.0; + *blue = (double) GetBValue(pixel) / 255.0; +} +#else static void TkImageGetColor(cdata, pixel, red, green, blue) TkColormapData *cdata; /* Colormap data */ @@ -1133,26 +1159,16 @@ TkImageGetColor(cdata, pixel, red, green, blue) int r = (pixel & cdata->red_mask) >> cdata->red_shift; int g = (pixel & cdata->green_mask) >> cdata->green_shift; int b = (pixel & cdata->blue_mask) >> cdata->blue_shift; -#ifdef WIN32 - /* - * Because XQueryColors is an empty stub on Windows, we need - * to just make this simple calculation. The TkColormapData - * XColor data is otherwise bogus on Windows. -- hobbs - */ - *red = (double)r / 255.0; - *green = (double)g / 255.0; - *blue = (double)b / 255.0; -#else *red = cdata->colors[r].red / 65535.0; *green = cdata->colors[g].green / 65535.0; *blue = cdata->colors[b].blue / 65535.0; -#endif } else { *red = cdata->colors[pixel].red / 65535.0; *green = cdata->colors[pixel].green / 65535.0; *blue = cdata->colors[pixel].blue / 65535.0; } } +#endif /* *-------------------------------------------------------------- diff --git a/win/tkWinImage.c b/win/tkWinImage.c index 32b2ecb..7ba9329 100644 --- a/win/tkWinImage.c +++ b/win/tkWinImage.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinImage.c,v 1.5 2002/10/10 07:25:24 hobbs Exp $ + * RCS: @(#) $Id: tkWinImage.c,v 1.6 2002/10/10 21:01:18 hobbs Exp $ */ #include "tkWinInt.h" @@ -292,17 +292,14 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format) { TkWinDrawable *twdPtr = (TkWinDrawable *)d; XImage *ret_image; - unsigned char *smallBitData, *smallBitBase, *bigBitData; HDC hdc, hdcMem; HBITMAP hbmp, hbmpPrev; BITMAPINFO *bmInfo = NULL; HPALETTE hPal, hPalPrev1, hPalPrev2; - unsigned int byte_width; - unsigned int h, w, n; - unsigned char plmr, plmg, plmb; - unsigned char *data; int size; + unsigned int n; unsigned int depth; + unsigned char *data; TkWinDCState state; BOOL ret; @@ -443,43 +440,54 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format) goto cleanup; } - byte_width = ((width * 3 + 3) & ~3); - smallBitBase = ckalloc(byte_width * height); - if (!smallBitBase) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); - ret_image = NULL; - goto cleanup; - } - smallBitData = smallBitBase; - - /* Get the BITMAP info into the Image. */ - if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo, - DIB_RGB_COLORS) == 0) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); - ret_image = NULL; - goto cleanup; - } - - plmr = (unsigned char) (plane_mask & 0xff0000) >> 16; - plmg = (unsigned char) (plane_mask & 0x00ff00) >> 8; - plmb = (unsigned char) (plane_mask & 0x0000ff); - - /* Copy the 24 Bit Pixmap to a 32-Bit one. */ - for (h = 0; h < height; h++) { - bigBitData = ret_image->data + h * ret_image->bytes_per_line; - smallBitData = smallBitBase + h * byte_width; + if (depth <= 24) { + unsigned char *smallBitData, *smallBitBase, *bigBitData; + unsigned int byte_width, h, w; + + byte_width = ((width * 3 + 3) & ~3); + smallBitBase = ckalloc(byte_width * height); + if (!smallBitBase) { + ckfree((char *) ret_image->data); + ckfree((char *) ret_image); + ret_image = NULL; + goto cleanup; + } + smallBitData = smallBitBase; + + /* Get the BITMAP info into the Image. */ + if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo, + DIB_RGB_COLORS) == 0) { + ckfree((char *) ret_image->data); + ckfree((char *) ret_image); + ckfree((char *) smallBitBase); + ret_image = NULL; + goto cleanup; + } - for (w = 0; w < width; w++) { - *bigBitData++ = ((*smallBitData++)) /* & plmr */; - *bigBitData++ = ((*smallBitData++)) /* & plmg */; - *bigBitData++ = ((*smallBitData++)) /* & plmb */; - *bigBitData++ = 0; + /* Copy the 24 Bit Pixmap to a 32-Bit one. */ + for (h = 0; h < height; h++) { + bigBitData = ret_image->data + h * ret_image->bytes_per_line; + smallBitData = smallBitBase + h * byte_width; + + for (w = 0; w < width; w++) { + *bigBitData++ = ((*smallBitData++)); + *bigBitData++ = ((*smallBitData++)); + *bigBitData++ = ((*smallBitData++)); + *bigBitData++ = 0; + } + } + /* Free the Device contexts, and the Bitmap */ + ckfree((char *) smallBitBase); + } else { + /* Get the BITMAP info directly into the Image. */ + if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo, + DIB_RGB_COLORS) == 0) { + ckfree((char *) ret_image->data); + ckfree((char *) ret_image); + ret_image = NULL; + goto cleanup; } } - /* Free the Device contexts, and the Bitmap */ - ckfree((char *) smallBitBase); } cleanup: @@ -537,30 +545,22 @@ XGetImage(display, d, x, y, width, height, plane_mask, format) return NULL; } - if (format == ZPixmap) { + if (twdPtr->type != TWD_BITMAP) { /* - * This actually handles most TWD_WINDOW requests, but it varies - * from the one below in that it really does a screen capture of - * an area, but that is consistent with the Unix behavior -- hobbs + * This handles TWD_WINDOW or TWD_WINDC, always creating a 32bit + * image. If the window being copied isn't visible (unmapped or + * obscured), we quietly stop copying (no user error). + * The user will see black where the widget should be. + * This branch is likely followed in favor of XGetImageZPixmap as + * postscript printed widgets require RGB data. */ - imagePtr = XGetImageZPixmap(display, d, x, y, - width, height, plane_mask, format); - } else if (twdPtr->type != TWD_BITMAP) { - /* - * This handles TWD_WINDOW or TWD_WINDC. - * If the window being copied isn't visible (unmapped or obscured), - * we quietly stop copying (no user error). The user will see black - * where the widget should be. - * This branch is likely not followed in favor of XGetImageZPixmap. - */ - Tk_Window tkwin = (Tk_Window) TkWinGetWinPtr(d); TkWinDCState state; unsigned int xx, yy, size; COLORREF pixel; dc = TkWinGetDrawableDC(display, d, &state); - imagePtr = XCreateImage(display, NULL, Tk_Depth(tkwin), + imagePtr = XCreateImage(display, NULL, 32, format, 0, NULL, width, height, 32, 0); size = imagePtr->bytes_per_line * imagePtr->height; imagePtr->data = ckalloc(size); @@ -577,6 +577,15 @@ XGetImage(display, d, x, y, width, height, plane_mask, format) } TkWinReleaseDrawableDC(d, dc, &state); + } else if (format == ZPixmap) { + /* + * This actually handles most TWD_WINDOW requests, but it varies + * from the above in that it really does a screen capture of + * an area, which is consistent with the Unix behavior, but does + * not appear to handle all bit depths correctly. -- hobbs + */ + imagePtr = XGetImageZPixmap(display, d, x, y, + width, height, plane_mask, format); } else { char *errMsg = NULL; char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)]; -- cgit v0.12