summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXDraw.c
diff options
context:
space:
mode:
authordas <das@noemail.net>2006-06-14 21:18:47 (GMT)
committerdas <das@noemail.net>2006-06-14 21:18:47 (GMT)
commit8c4c871a26e887b1db00597063daa16e050566c5 (patch)
treef2eb65f8b9e8b4145a71a6566999c452a83786aa /macosx/tkMacOSXDraw.c
parent819bc32f93071fe168712dbf4f15d9b575844c0f (diff)
downloadtk-8c4c871a26e887b1db00597063daa16e050566c5.zip
tk-8c4c871a26e887b1db00597063daa16e050566c5.tar.gz
tk-8c4c871a26e887b1db00597063daa16e050566c5.tar.bz2
* 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] FossilOrigin-Name: b09412a6f58bddd1385134fa8130bb2169751a91
Diffstat (limited to 'macosx/tkMacOSXDraw.c')
-rw-r--r--macosx/tkMacOSXDraw.c202
1 files changed, 129 insertions, 73 deletions
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);
}