summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--macosx/tkMacOSXDraw.c202
-rw-r--r--macosx/tkMacOSXSubwindows.c20
3 files changed, 150 insertions, 83 deletions
diff --git a/ChangeLog b/ChangeLog
index efc1ce8..aaaec5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-06-14 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/tkMacOSXSubwindows.c (TkMacOSXInvalidateWindow): ensure invalid
+ clip regions are recreated via TkMacOSXUpdateClipRgn() before they are
+ used; correct call order of TkMacOSXInvalidateWindow() and
+ TkMacOSXInvalClipRgns() throughout. [Bug 1501922]
+
+ * macosx/tkMacOSXDraw.c (TkPutImage): implement drawing of very wide
+ images in slices of less than 4096 pixels to workaround CopyBits
+ limitation. [Bug 950121]
+
2006-06-09 Don Porter <dgp@users.sourceforge.net>
* generic/tkMain.c: Added Tcl_Preserve() call on the master
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 5d254f1..dc017d1 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.15 2006/05/12 18:17:48 das Exp $
+ * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.16 2006/06/14 21:18:47 das Exp $
*/
#include "tkMacOSXInt.h"
@@ -396,16 +396,17 @@ TkPutImage(
const BitMap * destBits;
MacDrawable *dstDraw = (MacDrawable *) d;
int i, j;
- BitMap bitmap;
char *newData = NULL;
Rect destRect, srcRect, *destPtr, *srcPtr;
-
- destPort = TkMacOSXGetDrawablePort(d);
+ char *dataPtr, *newPtr, *oldPtr;
+ int rowBytes = image->bytes_per_line;
+ int slices, sliceRowBytes, lastSliceRowBytes, sliceWidth, lastSliceWidth;
display->request++;
GetGWorld(&saveWorld, &saveDevice);
+ destPort = TkMacOSXGetDrawablePort(d);
SetGWorld(destPort, NULL);
-
+ destBits = GetPortBitMapForCopyBits(destPort);
TkMacOSXSetUpClippingRgn(d);
srcPtr = &srcRect;
@@ -429,81 +430,136 @@ TkPutImage(
}
if (image->obdata) {
- /* Image from XGetImage, copy from containing GWorld directly */
- GWorldPtr srcPort = TkMacOSXGetDrawablePort((Drawable)image->obdata);
- CopyBits(GetPortBitMapForCopyBits(srcPort),
- GetPortBitMapForCopyBits(destPort),
- srcPtr, destPtr, srcCopy, NULL);
+ /* Image from XGetImage, copy from containing GWorld directly */
+ GWorldPtr srcPort = TkMacOSXGetDrawablePort((Drawable)image->obdata);
+ CopyBits(GetPortBitMapForCopyBits(srcPort),
+ destBits, srcPtr, destPtr, srcCopy, NULL);
} else if (image->depth == 1) {
- /*
- * This code assumes a pixel depth of 1
- */
-
- bitmap.bounds.top = bitmap.bounds.left = 0;
- bitmap.bounds.right = (short) image->width;
- bitmap.bounds.bottom = (short) image->height;
- if ((image->bytes_per_line % 2) == 1) {
- char *newPtr, *oldPtr;
- newData = (char *) ckalloc(image->height *
- (image->bytes_per_line + 1));
- newPtr = newData;
- oldPtr = image->data;
- for (i = 0; i < image->height; i++) {
- for (j = 0; j < image->bytes_per_line; j++) {
- *newPtr = InvertByte((unsigned char) *oldPtr);
- newPtr++, oldPtr++;
- }
- *newPtr = 0;
- newPtr++;
- }
- bitmap.baseAddr = newData;
- bitmap.rowBytes = image->bytes_per_line + 1;
- } else {
- size_t size = image->height * image->bytes_per_line;
- newData = (char *) ckalloc((int) size);
- for (i = 0; i < size; i++) {
- newData[i] = InvertByte((unsigned char) image->data[i]);
- }
- bitmap.baseAddr = newData;
- bitmap.rowBytes = image->bytes_per_line;
- }
- destBits = GetPortBitMapForCopyBits(destPort);
- CopyBits(&bitmap, destBits, srcPtr, destPtr, srcCopy, NULL);
+ /*
+ * BW image
+ */
+ const int maxRowBytes = 0x3ffe;
+ BitMap bitmap;
+ int odd;
+
+ if (rowBytes > maxRowBytes) {
+ slices = rowBytes / maxRowBytes;
+ sliceRowBytes = maxRowBytes;
+ lastSliceRowBytes = rowBytes - (slices * maxRowBytes);
+ if (!lastSliceRowBytes) {
+ slices--;
+ lastSliceRowBytes = maxRowBytes;
+ }
+ sliceWidth = (long) image->width * maxRowBytes / rowBytes;
+ lastSliceWidth = image->width - (sliceWidth * slices);
+ } else {
+ slices = 0;
+ sliceRowBytes = lastSliceRowBytes = rowBytes;
+ sliceWidth = lastSliceWidth = image->width;
+ }
+ bitmap.bounds.top = bitmap.bounds.left = 0;
+ bitmap.bounds.bottom = (short) image->height;
+ dataPtr = image->data;
+ do {
+ if (slices) {
+ bitmap.bounds.right = bitmap.bounds.left + sliceWidth;
+ } else {
+ sliceRowBytes = lastSliceRowBytes;
+ bitmap.bounds.right = bitmap.bounds.left + lastSliceWidth;
+ }
+ oldPtr = dataPtr;
+ odd = sliceRowBytes % 2;
+ if (!newData) {
+ newData = (char *) ckalloc(image->height * (sliceRowBytes + odd));
+ }
+ newPtr = newData;
+ for (i = 0; i < image->height; i++) {
+ for (j = 0; j < sliceRowBytes; j++) {
+ *newPtr = InvertByte((unsigned char) *oldPtr);
+ newPtr++; oldPtr++;
+ }
+ if (odd) {
+ *newPtr++ = 0;
+ }
+ oldPtr += rowBytes - sliceRowBytes;
+ }
+ bitmap.baseAddr = newData;
+ bitmap.rowBytes = sliceRowBytes + odd;
+ CopyBits(&bitmap, destBits, srcPtr, destPtr, srcCopy, NULL);
+ if (slices) {
+ bitmap.bounds.left = bitmap.bounds.right;
+ dataPtr += sliceRowBytes;
+ }
+ } while (slices--);
} else {
- /*
- * Color image
- */
- PixMap pixmap;
-
- pixmap.bounds.left = 0;
- pixmap.bounds.top = 0;
- pixmap.bounds.right = (short) image->width;
- pixmap.bounds.bottom = (short) image->height;
- pixmap.pixelType = RGBDirect;
- pixmap.pmVersion = baseAddr32; /* 32bit clean */
- pixmap.packType = 0;
- pixmap.packSize = 0;
- pixmap.hRes = 0x00480000;
- pixmap.vRes = 0x00480000;
- pixmap.pixelSize = 32;
- pixmap.cmpCount = 3;
- pixmap.cmpSize = 8;
+ /*
+ * Color image
+ */
+ const int maxRowBytes = 0x3ffc;
+ PixMap pixmap;
+
+ pixmap.bounds.left = 0;
+ pixmap.bounds.top = 0;
+ pixmap.bounds.bottom = (short) image->height;
+ pixmap.pixelType = RGBDirect;
+ pixmap.pmVersion = baseAddr32; /* 32bit clean */
+ pixmap.packType = 0;
+ pixmap.packSize = 0;
+ pixmap.hRes = 0x00480000;
+ pixmap.vRes = 0x00480000;
+ pixmap.pixelSize = 32;
+ pixmap.cmpCount = 3;
+ pixmap.cmpSize = 8;
#ifdef WORDS_BIGENDIAN
- pixmap.pixelFormat = k32ARGBPixelFormat;
+ pixmap.pixelFormat = k32ARGBPixelFormat;
#else
- pixmap.pixelFormat = k32BGRAPixelFormat;
+ pixmap.pixelFormat = k32BGRAPixelFormat;
#endif
- pixmap.pmTable = NULL;
- pixmap.pmExt = 0;
- pixmap.baseAddr = image->data;
- pixmap.rowBytes = image->bytes_per_line | 0x8000;
-
- CopyBits((BitMap *) &pixmap, GetPortBitMapForCopyBits(destPort),
- srcPtr, destPtr, srcCopy, NULL);
+ pixmap.pmTable = NULL;
+ pixmap.pmExt = 0;
+ if (rowBytes > maxRowBytes) {
+ slices = rowBytes / maxRowBytes;
+ sliceRowBytes = maxRowBytes;
+ lastSliceRowBytes = rowBytes - (slices * maxRowBytes);
+ if (!lastSliceRowBytes) {
+ slices--;
+ lastSliceRowBytes = maxRowBytes;
+ }
+ sliceWidth = (long) image->width * maxRowBytes / rowBytes;
+ lastSliceWidth = image->width - (sliceWidth * slices);
+ dataPtr = image->data;
+ newData = (char *) ckalloc(image->height * sliceRowBytes);
+ do {
+ if (slices) {
+ pixmap.bounds.right = pixmap.bounds.left + sliceWidth;
+ } else {
+ sliceRowBytes = lastSliceRowBytes;
+ pixmap.bounds.right = pixmap.bounds.left + lastSliceWidth;
+ }
+ oldPtr = dataPtr;
+ newPtr = newData;
+ for (i = 0; i < image->height; i++) {
+ memcpy(newPtr, oldPtr, sliceRowBytes);
+ oldPtr += rowBytes;
+ newPtr += sliceRowBytes;
+ }
+ pixmap.baseAddr = newData;
+ pixmap.rowBytes = sliceRowBytes | 0x8000;
+ CopyBits((BitMap *) &pixmap, destBits, srcPtr, destPtr, srcCopy, NULL);
+ if (slices) {
+ pixmap.bounds.left = pixmap.bounds.right;
+ dataPtr += sliceRowBytes;
+ }
+ } while (slices--);
+ } else {
+ pixmap.bounds.right = (short) image->width;
+ pixmap.baseAddr = image->data;
+ pixmap.rowBytes = rowBytes | 0x8000;
+ CopyBits((BitMap *) &pixmap, destBits, srcPtr, destPtr, srcCopy, NULL);
+ }
}
-
if (newData != NULL) {
- ckfree(newData);
+ ckfree(newData);
}
SetGWorld(saveWorld, saveDevice);
}
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 1ac6579..92295fb 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.13 2006/05/12 18:17:48 das Exp $
+ * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.14 2006/06/14 21:18:47 das Exp $
*/
#include "tkMacOSXInt.h"
@@ -231,8 +231,8 @@ XMapWindow(
* Generate damage for that area of the window
*/
SetGWorld(destPort, NULL);
- TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
}
}
@@ -368,8 +368,8 @@ XResizeWindow(
if (havePort) {
SetPort(destPort);
- TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+ TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
}
deltaX = macParent->xOff +
macWin->winPtr->changes.x - macWin->xOff;
@@ -402,8 +402,8 @@ XResizeWindow(
if (havePort) {
SetPort(destPort);
- TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+ TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
}
deltaX = - macWin->xOff;
deltaY = - macWin->yOff;
@@ -497,14 +497,12 @@ XMoveResizeWindow(
* region. It is currently assumed that Tk will need
* to completely redraw anway.
*/
-
if (havePort) {
SetPort( destPort);
SizeWindow(GetWindowFromPort(destPort),
(short) width, (short) height, false);
MoveWindowStructure(GetWindowFromPort(destPort), x, y);
- /* TODO: is the following right? */
TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr);
}
@@ -541,8 +539,8 @@ XMoveResizeWindow(
if (havePort) {
SetPort( destPort);
- TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+ TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
}
deltaX = - macWin->xOff;
@@ -615,7 +613,6 @@ XMoveWindow(
SetPort(destPort);
MoveWindowStructure( GetWindowFromPort(destPort), x, y);
- /* TODO: is the following right? */
TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr);
}
@@ -651,8 +648,8 @@ XMoveWindow(
if (havePort) {
SetPort(destPort);
- TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+ TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
}
deltaX = - macWin->xOff;
@@ -1046,8 +1043,11 @@ TkMacOSXInvalidateWindow(
grafPtr = TkMacOSXGetDrawablePort((Drawable)macWin);
windowRef = GetWindowFromPort(grafPtr);
+ if (macWin->flags & TK_CLIP_INVALID) {
+ TkMacOSXUpdateClipRgn(macWin->winPtr);
+ }
if (flag == TK_WINDOW_ONLY) {
- InvalWindowRgn(windowRef,macWin->clipRgn);
+ InvalWindowRgn(windowRef, macWin->clipRgn);
} else {
if (!EmptyRgn(macWin->aboveClipRgn)) {
InvalWindowRgn(windowRef, macWin->aboveClipRgn);