diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2003-03-06 15:05:20 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2003-03-06 15:05:20 (GMT) |
commit | b180774f6bce433082da35c309b89e6bfa766152 (patch) | |
tree | cf2cecb4facabb94108e75d9490c5b0fb25dd347 /generic/tkImgPhoto.c | |
parent | 717fec397c31305a08d57a4ca6aa8bc9e038c5a6 (diff) | |
download | tk-b180774f6bce433082da35c309b89e6bfa766152.zip tk-b180774f6bce433082da35c309b89e6bfa766152.tar.gz tk-b180774f6bce433082da35c309b89e6bfa766152.tar.bz2 |
TIP#116 implementation. Docs still to come, tests will never be done because
they could never be done portably as they'd inevitably depend on the total
amount of memory available to the process... :^(
Diffstat (limited to 'generic/tkImgPhoto.c')
-rw-r--r-- | generic/tkImgPhoto.c | 172 |
1 files changed, 140 insertions, 32 deletions
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 8379f1d..3849556 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -16,7 +16,7 @@ * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPhoto.c,v 1.36 2002/10/18 00:48:22 hobbs Exp $ + * RCS: @(#) $Id: tkImgPhoto.c,v 1.37 2003/03/06 15:05:36 dkf Exp $ */ #include "tkInt.h" @@ -877,11 +877,13 @@ ImgPhotoCmd(clientData, interp, objc, objv) + options.fromY * block.pitch; block.width = options.fromX2 - options.fromX; block.height = options.fromY2 - options.fromY; - Tk_PhotoPutZoomedBlock((Tk_PhotoHandle) masterPtr, &block, + if (Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr, &block, options.toX, options.toY, options.toX2 - options.toX, options.toY2 - options.toY, options.zoomX, options.zoomY, options.subsampleX, options.subsampleY, - options.compositingRule); + options.compositingRule) != TCL_OK) { + return TCL_ERROR; + } break; @@ -1125,9 +1127,13 @@ ImgPhotoCmd(clientData, interp, objc, objv) block.offset[1] = 1; block.offset[2] = 2; block.offset[3] = 0; - Tk_PhotoPutBlock((ClientData)masterPtr, &block, + if (Tk_PhotoPutBlock(interp, (ClientData)masterPtr, &block, options.toX, options.toY, options.toX2 - options.toX, - options.toY2 - options.toY, TK_PHOTO_COMPOSITE_SET); + options.toY2 - options.toY, + TK_PHOTO_COMPOSITE_SET) != TCL_OK) { + ckfree((char *) block.pixelPtr); + return TCL_ERROR; + } ckfree((char *) block.pixelPtr); break; @@ -3962,16 +3968,21 @@ Tk_FindPhoto(interp, imageName) * This procedure is called to put image data into a photo image. * * Results: - * None. + * A standard Tcl result code. * * Side effects: * The image data is stored. The image may be expanded. * The Tk image code is informed that the image has changed. + * If the result code is TCL_ERROR, an error message will be placed + * in the interpreter (if non-NULL). * - *---------------------------------------------------------------------- */ + *---------------------------------------------------------------------- + */ -void -Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule) +int +Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) + Tcl_Interp *interp; /* Interpreter for passing back error + * messages, or NULL. */ Tk_PhotoHandle handle; /* Opaque handle for the photo image * to be updated. */ register Tk_PhotoImageBlock *blockPtr; @@ -4004,7 +4015,7 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule) height = masterPtr->userHeight - y; } if ((width <= 0) || (height <= 0)) { - return; + return TCL_OK; } xEnd = x + width; @@ -4012,7 +4023,12 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule) if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), MAX(yEnd, masterPtr->height)) == TCL_ERROR) { - panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + if (interp != NULL) { + Tcl_ResetResult(interp); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL); + } + return TCL_ERROR; } } @@ -4233,8 +4249,9 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule) * Tell the core image code that this image has changed. */ - Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, - masterPtr->height); + Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, + masterPtr->width, masterPtr->height); + return TCL_OK; } /* @@ -4255,9 +4272,11 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule) *---------------------------------------------------------------------- */ -void -Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, - subsampleX, subsampleY, compRule) +int +Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, + zoomX, zoomY, subsampleX, subsampleY, compRule) + Tcl_Interp *interp; /* Interpreter for passing back error + * messages, or NULL. */ Tk_PhotoHandle handle; /* Opaque handle for the photo image * to be updated. */ register Tk_PhotoImageBlock *blockPtr; @@ -4286,14 +4305,14 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, XRectangle rect; if (zoomX==1 && zoomY==1 && subsampleX==1 && subsampleY==1) { - Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule); - return; + return Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, + compRule); } masterPtr = (PhotoMaster *) handle; if (zoomX <= 0 || zoomY <= 0) { - return; + return TCL_OK; } if ((masterPtr->userWidth != 0) && ((x + width) > masterPtr->userWidth)) { width = masterPtr->userWidth - x; @@ -4303,7 +4322,7 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, height = masterPtr->userHeight - y; } if (width <= 0 || height <= 0) { - return; + return TCL_OK; } xEnd = x + width; @@ -4312,7 +4331,12 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), MAX(yEnd, masterPtr->height)) == TCL_ERROR) { - panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + if (interp != NULL) { + Tcl_ResetResult(interp); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL); + } + return TCL_ERROR; } if (sameSrc) { blockPtr->pixelPtr = masterPtr->pix32; @@ -4518,6 +4542,7 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, masterPtr->height); + return TCL_OK; } /* @@ -5024,8 +5049,10 @@ Tk_PhotoBlank(handle) *---------------------------------------------------------------------- */ -void -Tk_PhotoExpand(handle, width, height) +int +Tk_PhotoExpand(interp, handle, width, height) + Tcl_Interp *interp; /* Interpreter for passing back error + * messages, or NULL. */ Tk_PhotoHandle handle; /* Handle for the image to be expanded. */ int width, height; /* Desired minimum dimensions of the image. */ { @@ -5042,11 +5069,17 @@ Tk_PhotoExpand(handle, width, height) if ((width != masterPtr->width) || (height != masterPtr->height)) { if (ImgPhotoSetSize(masterPtr, MAX(width, masterPtr->width), MAX(height, masterPtr->height)) == TCL_ERROR) { - panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + if (interp != NULL) { + Tcl_ResetResult(interp); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL); + } + return TCL_ERROR; } Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, masterPtr->width, masterPtr->height); } + return TCL_OK; } /* @@ -5100,8 +5133,10 @@ Tk_PhotoGetSize(handle, widthPtr, heightPtr) *---------------------------------------------------------------------- */ -void -Tk_PhotoSetSize(handle, width, height) +int +Tk_PhotoSetSize(interp, handle, width, height) + Tcl_Interp *interp; /* Interpreter for passing back error + * messages, or NULL. */ Tk_PhotoHandle handle; /* Handle for the image whose size is to * be set. */ int width, height; /* New dimensions for the image. */ @@ -5114,10 +5149,16 @@ Tk_PhotoSetSize(handle, width, height) masterPtr->userHeight = height; if (ImgPhotoSetSize(masterPtr, ((width > 0) ? width: masterPtr->width), ((height > 0) ? height: masterPtr->height)) == TCL_ERROR) { - panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + if (interp != NULL) { + Tcl_ResetResult(interp); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL); + } + return TCL_ERROR; } Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, masterPtr->width, masterPtr->height); + return TCL_OK; } /* @@ -5613,7 +5654,9 @@ ImgPhotoPostscript(clientData, interp, tkwin, psInfo, * * These backward-compatability functions just exist to fill slots in * stubs table. For the behaviour of *_NoComposite, refer to the - * corresponding function without the extra suffix. + * corresponding function without the extra suffix, except that the + * compositing rule is always "overlay" and the function always panics + * on memory-allocation failure. * *---------------------------------------------------------------------- */ @@ -5623,8 +5666,10 @@ Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x, y, width, height) Tk_PhotoImageBlock *blockPtr; int x, y, width, height; { - Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, - TK_PHOTO_COMPOSITE_OVERLAY); + if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height, + TK_PHOTO_COMPOSITE_OVERLAY) != TCL_OK) { + panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + } } void @@ -5634,6 +5679,69 @@ Tk_PhotoPutZoomedBlock_NoComposite(handle, blockPtr, x, y, width, height, Tk_PhotoImageBlock *blockPtr; int x, y, width, height, zoomX, zoomY, subsampleX, subsampleY; { - Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, - zoomX, zoomY, subsampleX, subsampleY, TK_PHOTO_COMPOSITE_OVERLAY); + if (Tk_PhotoPutZoomedBlock(NULL, handle, blockPtr, x, y, width, height, + zoomX, zoomY, subsampleX, subsampleY, + TK_PHOTO_COMPOSITE_OVERLAY) != TCL_OK) { + panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic, + * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic + * + * Backward compatability functions for preserving the old behaviour + * (i.e. panic on memory allocation failure) so that extensions do not + * need to be significantly updated to take account of TIP #116. These + * call the new interface (i.e. the interface without the extra suffix), + * but panic if an error condition is returned. + * + *---------------------------------------------------------------------- + */ + +void +Tk_PhotoExpand_Panic(handle, width, height) + Tk_PhotoHandle handle; + int width, height; +{ + if (Tk_PhotoExpand(NULL, handle, width, height) != TCL_OK) { + panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + } +} + +void +Tk_PhotoPutBlock_Panic(handle, blockPtr, x, y, width, height, compRule) + Tk_PhotoHandle handle; + Tk_PhotoImageBlock *blockPtr; + int x, y, width, height, compRule; +{ + if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height, + compRule) != TCL_OK) { + panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + } +} + +void +Tk_PhotoPutZoomedBlock_Panic(handle, blockPtr, x, y, width, height, + zoomX, zoomY, subsampleX, subsampleY, compRule) + Tk_PhotoHandle handle; + register Tk_PhotoImageBlock *blockPtr; + int x, y, width, height, zoomX, zoomY, subsampleX, subsampleY, compRule; +{ + if (Tk_PhotoPutZoomedBlock(NULL, handle, blockPtr, x, y, width, height, + zoomX, zoomY, subsampleX, subsampleY, compRule) != TCL_OK) { + panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + } +} + +void +Tk_PhotoSetSize_Panic(handle, width, height) + Tk_PhotoHandle handle; + int width, height; +{ + if (Tk_PhotoSetSize(NULL, handle, width, height) != TCL_OK) { + panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); + } } |