diff options
Diffstat (limited to 'generic/tkImgPhoto.c')
-rw-r--r-- | generic/tkImgPhoto.c | 187 |
1 files changed, 172 insertions, 15 deletions
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 7e3b804..75694c0 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -15,7 +15,7 @@ * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPhoto.c,v 1.10 1999/10/29 03:57:56 hobbs Exp $ + * RCS: @(#) $Id: tkImgPhoto.c,v 1.11 1999/12/14 06:52:28 hobbs Exp $ */ #include "tkInt.h" @@ -301,6 +301,7 @@ Tk_ImageType tkPhotoImageType = { ImgPhotoDisplay, /* displayProc */ ImgPhotoFree, /* freeProc */ ImgPhotoDelete, /* deleteProc */ + (Tk_ImagePostscriptProc *) NULL, /* postscriptProc */ (Tk_ImageType *) NULL /* nextPtr */ }; @@ -394,8 +395,8 @@ static int MatchStringFormat _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *data, Tcl_Obj *formatString, Tk_PhotoImageFormat **imageFormatPtr, int *widthPtr, int *heightPtr, int *oldformat)); -static void Dither _ANSI_ARGS_((PhotoMaster *masterPtr, - int x, int y, int width, int height)); +static Tcl_ObjCmdProc * PhotoOptionFind _ANSI_ARGS_((Tcl_Interp * interp, + Tcl_Obj *obj)); static void DitherInstance _ANSI_ARGS_((PhotoInstance *instancePtr, int x, int y, int width, int height)); @@ -588,7 +589,12 @@ ImgPhotoCmd(clientData, interp, objc, objv) if (Tcl_GetIndexFromObj(interp, objv[1], photoOptions, "option", 0, &index) != TCL_OK) { - return TCL_ERROR; + Tcl_ObjCmdProc *proc; + proc = PhotoOptionFind(interp, objv[1]); + if (proc == (Tcl_ObjCmdProc *) NULL) { + return TCL_ERROR; + } + return proc(clientData, interp, objc, objv); } switch ((enum options) index) { case PHOTO_BLANK: { @@ -610,7 +616,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) Tcl_WrongNumArgs(interp, 2, objv, "option"); return TCL_ERROR; } - arg = Tcl_GetStringFromObj(objv[2],&length); + arg = Tcl_GetStringFromObj(objv[2], (int *) &length); if (strncmp(arg,"-data", length) == 0) { if (masterPtr->dataString) { Tcl_SetObjResult(interp, masterPtr->dataString); @@ -659,7 +665,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) return TCL_OK; } if (objc == 3) { - char *arg = Tcl_GetStringFromObj(objv[2], &length); + char *arg = Tcl_GetStringFromObj(objv[2], (int *) &length); if (!strncmp(arg, "-data", length)) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "-data {} {} {}", (char *) NULL); @@ -1172,11 +1178,11 @@ ImgPhotoCmd(clientData, interp, objc, objv) x = masterPtr->ditherX; y = masterPtr->ditherY; if (masterPtr->ditherX != 0) { - Dither(masterPtr, x, y, masterPtr->width - x, 1); + Tk_DitherPhoto((Tk_PhotoHandle) masterPtr, x, y, masterPtr->width - x, 1); } if (masterPtr->ditherY < masterPtr->height) { x = 0; - Dither(masterPtr, 0, masterPtr->ditherY, masterPtr->width, + Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, 0, masterPtr->ditherY, masterPtr->width, masterPtr->height - masterPtr->ditherY); } @@ -1454,10 +1460,14 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) return TCL_ERROR; } } else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) { + char *val; maxValues = ((bit == OPT_FROM) || (bit == OPT_TO))? 4: 2; argIndex = index + 1; for (numValues = 0; numValues < maxValues; ++numValues) { - char *val = Tcl_GetString(objv[argIndex]); + if (argIndex >= objc) { + break; + } + val = Tcl_GetString(objv[argIndex]); if ((argIndex < objc) && (isdigit(UCHAR(val[0])) || ((val[0] == '-') && isdigit(UCHAR(val[1]))))) { if (Tcl_GetInt(interp, val, &values[numValues]) @@ -3835,7 +3845,7 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height) * Update each instance. */ - Dither(masterPtr, x, y, width, height); + Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, x, y, width, height); /* * Tell the core image code that this image has changed. @@ -4072,7 +4082,7 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, * Update each instance. */ - Dither(masterPtr, x, y, width, height); + Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, x, y, width, height); /* * Tell the core image code that this image has changed. @@ -4085,7 +4095,7 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, /* *---------------------------------------------------------------------- * - * Dither -- + * Tk_DitherPhoto -- * * This procedure is called to update an area of each instance's * pixmap by dithering the corresponding area of the image master. @@ -4101,14 +4111,15 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, *---------------------------------------------------------------------- */ -static void -Dither(masterPtr, x, y, width, height) - PhotoMaster *masterPtr; /* Image master whose instances are +void +Tk_DitherPhoto(photo, x, y, width, height) + Tk_PhotoHandle photo; /* Image master whose instances are * to be updated. */ int x, y; /* Coordinates of the top-left pixel * in the area to be dithered. */ int width, height; /* Dimensions of the area to be dithered. */ { + PhotoMaster *masterPtr = (PhotoMaster *) photo; PhotoInstance *instancePtr; if ((width <= 0) || (height <= 0)) { @@ -4944,3 +4955,149 @@ Tk_PhotoGetImage(handle, blockPtr) blockPtr->offset[3] = 3; return 1; } + +/* + *---------------------------------------------------------------------- + * + * PhotoOptionFind -- + * + * Finds a specific Photo option. + * + * Results: + * None. + * + * Side effects: + * After commands are removed. + * + *---------------------------------------------------------------------- + */ + +typedef struct OptionAssocData { + struct OptionAssocData *nextPtr; /* pointer to next OptionAssocData */ + Tcl_ObjCmdProc *command; /* command associated with this + * option */ + char name[1]; /* name of option (remaining chars) */ +} OptionAssocData; + +static Tcl_ObjCmdProc * +PhotoOptionFind(interp, obj) + Tcl_Interp *interp; /* Interpreter that is being deleted. */ + Tcl_Obj *obj; /* Name of option to be found. */ +{ + size_t length; + char *name = Tcl_GetStringFromObj(obj, (int *) &length); + OptionAssocData *list; + char *prevname = NULL; + Tcl_ObjCmdProc *proc = (Tcl_ObjCmdProc *) NULL; + list = (OptionAssocData *) Tcl_GetAssocData(interp, "photoOption", + (Tcl_InterpDeleteProc **) NULL); + while (list != (OptionAssocData *) NULL) { + if (strncmp(name, list->name, length) == 0) { + if (proc != (Tcl_ObjCmdProc *) NULL) { + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "ambiguous option \"", name, + "\": must be ", prevname, (char *) NULL); + while (list->nextPtr != (OptionAssocData *) NULL) { + Tcl_AppendResult(interp, prevname, ", ",(char *) NULL); + list = list->nextPtr; + prevname = list->name; + } + Tcl_AppendResult(interp, ", or", prevname, (char *) NULL); + return (Tcl_ObjCmdProc *) NULL; + } + proc = list->command; + prevname = list->name; + } + list = list->nextPtr; + } + if (proc != (Tcl_ObjCmdProc *) NULL) { + Tcl_ResetResult(interp); + } + return proc; +} + +/* + *---------------------------------------------------------------------- + * + * PhotoOptionCleanupProc -- + * + * This procedure is invoked whenever an interpreter is deleted + * to cleanup the AssocData for "photoVisitor". + * + * Results: + * None. + * + * Side effects: + * Photo Visitor options are removed. + * + *---------------------------------------------------------------------- + */ + +static void +PhotoOptionCleanupProc(clientData, interp) + ClientData clientData; /* Points to "photoVisitor" AssocData + * for the interpreter. */ + Tcl_Interp *interp; /* Interpreter that is being deleted. */ +{ + OptionAssocData *list = (OptionAssocData *) clientData; + OptionAssocData *ptr; + + while (list != NULL) { + list = (ptr = list)->nextPtr; + ckfree((char *) ptr); + } +} + +/* + *-------------------------------------------------------------- + * + * Tk_CreatePhotoOption -- + * + * This procedure may be invoked to add a new kind of photo + * option to the core photo command supported by Tk. + * + * Results: + * None. + * + * Side effects: + * From now on, the new option will be useable by the + * photo command. + * + *-------------------------------------------------------------- + */ + +void +Tk_CreatePhotoOption(interp, name, proc) + Tcl_Interp *interp; /* interpreter */ + CONST char *name; /* option name */ + Tcl_ObjCmdProc *proc; /* proc to execute command */ +{ + OptionAssocData *typePtr2, *prevPtr, *ptr; + OptionAssocData *list; + + list = (OptionAssocData *) Tcl_GetAssocData(interp, "photoOption", + (Tcl_InterpDeleteProc **) NULL); + + /* + * If there's already a photo option with the given name, remove it. + */ + + for (typePtr2 = list, prevPtr = NULL; typePtr2 != NULL; + prevPtr = typePtr2, typePtr2 = typePtr2->nextPtr) { + if (strcmp(typePtr2->name, name) == 0) { + if (prevPtr == NULL) { + list = typePtr2->nextPtr; + } else { + prevPtr->nextPtr = typePtr2->nextPtr; + } + ckfree((char *) typePtr2); + break; + } + } + ptr = (OptionAssocData *) ckalloc(sizeof(OptionAssocData) + strlen(name)); + strcpy(&(ptr->name[0]), name); + ptr->command = proc; + ptr->nextPtr = list; + Tcl_SetAssocData(interp, "photoOption", PhotoOptionCleanupProc, + (ClientData) ptr); +} |