summaryrefslogtreecommitdiffstats
path: root/generic/tkCanvImg.c
diff options
context:
space:
mode:
authorhobbs <hobbs>1999-12-14 06:52:24 (GMT)
committerhobbs <hobbs>1999-12-14 06:52:24 (GMT)
commitb6b6ff8f0eee42e270a45b019789faa444ed4dad (patch)
tree5b5ddecf0f3677601c5511eaded466191ef3ba8a /generic/tkCanvImg.c
parent9b37fa05b11850066aed28ed447109e55708bce0 (diff)
downloadtk-b6b6ff8f0eee42e270a45b019789faa444ed4dad.zip
tk-b6b6ff8f0eee42e270a45b019789faa444ed4dad.tar.gz
tk-b6b6ff8f0eee42e270a45b019789faa444ed4dad.tar.bz2
* generic/tkStubInit.c:
* generic/tkDecls.h: * generic/tkIntXlibDecls.h: * generic/tkInt.decls: added XSetDashes and XWarpPointer * generic/tk.decls: added Tk_CreateSmoothMethod, and reserved two spots * generic/tk.h: added Tk_SmoothMethod struct, state item to canvas record, #defines for item state, support for using old char*-based canvas item C creation procedures with -DUSE_OLD_CANVAS, Tk_Dash, Tk_TSOffset (-offsets) & Tk_Outline structs and #defs, decls for dash, outline and postscript routines * generic/tkBind.c: added support for Quadruple clicks, and added the -warp option to 'event' with pointer warping routines * xlib/xgc.c: * generic/tkRectOval.c: * generic/tkCanvArc.c: * generic/tkCanvBmap.c: * generic/tkCanvImg.c: * generic/tkCanvLine.c: * generic/tkCanvPoly.c: * generic/tkCanvPs.c: * generic/tkCanvText.c: * generic/tkCanvUtil.c: * generic/tkCanvWind.c: * generic/tkCanvas.c: * generic/tkCanvas.h: Canvas and items received overhaul to with the addition of the dash patch (Nijtmans, et al) This includes objectification of the 'canvas' command, as well as support for (where appropriate) dashes in items, extended stipple support, state for all items, and postscript generation of images and windows. See the new canvas man page for related docs. * generic/tkEntry.c: added entry widget validation, see entry.n * generic/tkEvent.c: on simulated events, ButtonPress should be matched with ButtonRelease to be correct * generic/tkFont.c: corrected possible null reference * generic/tkFrame.c: made frame a Tcl_Obj based command * generic/tkGet.c: added TkGetDoublePixels * generic/tkImage.c: bug fixes from Img patch and new Tk_PostscriptImage and Tk_SetTSOrigin functions * generic/tkImgBmap.c: new ImgBmapPostscript function * generic/tkImgPhoto.c: new Tk_CreatePhotoOption, Tk_DitherPhoto * generic/tkInt.h: declarations for some new functions * generic/tkMessage.c: reworked relief drawing * generic/tkOldConfig.c: added TK_CONFIG_OBJS so old style ConfigureWidget calls can pass in Tcl_Obj arrays * generic/tkScrollbar.c: * generic/tkScrollbar.h: made -orient use an option table * generic/tkText.c: * generic/tkText.h: made -wrap and -state use option tables * generic/tkTextBTree.c: * generic/tkTextDisp.c: * generic/tkTextImage.c: * generic/tkTextMark.c: * generic/tkTextTag.c: * generic/tkTextWind.c: added support for -elide and -state hidden * generic/tkTrig.c: changed TkMakeBezierCurve to support returning the upper limit of points needed for spline * generic/tkUtil.c: new option table parsing routines * generic/tkWindow.c: init'ing of warp stuff, mouseButtonState
Diffstat (limited to 'generic/tkCanvImg.c')
-rw-r--r--generic/tkCanvImg.c290
1 files changed, 255 insertions, 35 deletions
diff --git a/generic/tkCanvImg.c b/generic/tkCanvImg.c
index cf1106d..144b755 100644
--- a/generic/tkCanvImg.c
+++ b/generic/tkCanvImg.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkCanvImg.c,v 1.3 1999/04/16 01:51:11 stanton Exp $
+ * RCS: @(#) $Id: tkCanvImg.c,v 1.4 1999/12/14 06:52:25 hobbs Exp $
*/
#include <stdio.h>
@@ -31,23 +31,45 @@ typedef struct ImageItem {
* (x,y). */
char *imageString; /* String describing -image option (malloc-ed).
* NULL means no image right now. */
+ char *activeImageString; /* String describing -activeimage option.
+ * NULL means no image right now. */
+ char *disabledImageString; /* String describing -disabledimage option.
+ * NULL means no image right now. */
Tk_Image image; /* Image to display in window, or NULL if
* no image at present. */
+ Tk_Image activeImage; /* Image to display in window, or NULL if
+ * no image at present. */
+ Tk_Image disabledImage; /* Image to display in window, or NULL if
+ * no image at present. */
} ImageItem;
/*
* Information used for parsing configuration specs:
*/
-static Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,
+static Tk_CustomOption stateOption = {
+ (Tk_OptionParseProc *) TkStateParseProc,
+ TkStatePrintProc, (ClientData) 2
+};
+static Tk_CustomOption tagsOption = {
+ (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
Tk_CanvasTagsPrintProc, (ClientData) NULL
};
static Tk_ConfigSpec configSpecs[] = {
+ {TK_CONFIG_STRING, "-activeimage", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(ImageItem, activeImageString),
+ TK_CONFIG_NULL_OK},
{TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
"center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_STRING, "-disabledimage", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(ImageItem, disabledImageString),
+ TK_CONFIG_NULL_OK},
{TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL,
(char *) NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
+ &stateOption},
{TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
(char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
@@ -63,19 +85,21 @@ static void ImageChangedProc _ANSI_ARGS_((ClientData clientData,
int imgHeight));
static int ImageCoords _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- char **argv));
+ Tcl_Obj *CONST argv[]));
static int ImageToArea _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, double *rectPtr));
static double ImageToPoint _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, double *coordPtr));
+static int ImageToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
static void ComputeImageBbox _ANSI_ARGS_((Tk_Canvas canvas,
ImageItem *imgPtr));
static int ConfigureImage _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- char **argv, int flags));
+ Tcl_Obj *CONST argv[], int flags));
static int CreateImage _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int argc, char **argv));
+ int argc, Tcl_Obj *CONST argv[]));
static void DeleteImage _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display));
static void DisplayImage _ANSI_ARGS_((Tk_Canvas canvas,
@@ -101,10 +125,10 @@ Tk_ItemType tkImageType = {
ImageCoords, /* coordProc */
DeleteImage, /* deleteProc */
DisplayImage, /* displayProc */
- 0, /* alwaysRedraw */
+ TK_CONFIG_OBJS, /* flags */
ImageToPoint, /* pointProc */
ImageToArea, /* areaProc */
- (Tk_ItemPostscriptProc *) NULL, /* postscriptProc */
+ ImageToPostscript, /* postscriptProc */
ScaleImage, /* scaleProc */
TranslateImage, /* translateProc */
(Tk_ItemIndexProc *) NULL, /* indexProc */
@@ -112,7 +136,7 @@ Tk_ItemType tkImageType = {
(Tk_ItemSelectionProc *) NULL, /* selectionProc */
(Tk_ItemInsertProc *) NULL, /* insertProc */
(Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL /* nextPtr */
+ (Tk_ItemType *) NULL, /* nextPtr */
};
/*
@@ -142,11 +166,24 @@ CreateImage(interp, canvas, itemPtr, argc, argv)
Tk_Item *itemPtr; /* Record to hold new item; header
* has been initialized by caller. */
int argc; /* Number of arguments in argv. */
- char **argv; /* Arguments describing rectangle. */
+ Tcl_Obj *CONST argv[]; /* Arguments describing rectangle. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
+ int i;
- if (argc < 2) {
+ if (argc==1) {
+ i = 1;
+ } else {
+ char *arg = Tcl_GetStringFromObj((Tcl_Obj *) argv[1], NULL);
+ if (((argc>1) && (arg[0] == '-')
+ && (arg[1] >= 'a') && (arg[1] <= 'z'))) {
+ i = 1;
+ } else {
+ i = 2;
+ }
+ }
+
+ if (argc < i) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",
itemPtr->typePtr->name, " x y ?options?\"",
@@ -161,23 +198,26 @@ CreateImage(interp, canvas, itemPtr, argc, argv)
imgPtr->canvas = canvas;
imgPtr->anchor = TK_ANCHOR_CENTER;
imgPtr->imageString = NULL;
+ imgPtr->activeImageString = NULL;
+ imgPtr->disabledImageString = NULL;
imgPtr->image = NULL;
+ imgPtr->activeImage = NULL;
+ imgPtr->disabledImage = NULL;
/*
* Process the arguments to fill in the item record.
*/
- if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &imgPtr->x) != TCL_OK)
- || (Tk_CanvasGetCoord(interp, canvas, argv[1], &imgPtr->y)
- != TCL_OK)) {
- return TCL_ERROR;
+ if ((ImageCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) {
+ goto error;
}
-
- if (ConfigureImage(interp, canvas, itemPtr, argc-2, argv+2, 0) != TCL_OK) {
- DeleteImage(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
- return TCL_ERROR;
+ if (ConfigureImage(interp, canvas, itemPtr, argc-i, argv+i, 0) == TCL_OK) {
+ return TCL_OK;
}
- return TCL_OK;
+
+ error:
+ DeleteImage(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
+ return TCL_ERROR;
}
/*
@@ -206,20 +246,34 @@ ImageCoords(interp, canvas, itemPtr, argc, argv)
* read or modified. */
int argc; /* Number of coordinates supplied in
* argv. */
- char **argv; /* Array of coordinates: x1, y1,
+ Tcl_Obj *CONST argv[]; /* Array of coordinates: x1, y1,
* x2, y2, ... */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
- char x[TCL_DOUBLE_SPACE], y[TCL_DOUBLE_SPACE];
if (argc == 0) {
- Tcl_PrintDouble(interp, imgPtr->x, x);
- Tcl_PrintDouble(interp, imgPtr->y, y);
- Tcl_AppendResult(interp, x, " ", y, (char *) NULL);
- } else if (argc == 2) {
- if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &imgPtr->x) != TCL_OK)
- || (Tk_CanvasGetCoord(interp, canvas, argv[1],
- &imgPtr->y) != TCL_OK)) {
+ Tcl_Obj *obj = Tcl_NewObj();
+ Tcl_Obj *subobj = Tcl_NewDoubleObj(imgPtr->x);
+ Tcl_ListObjAppendElement(interp, obj, subobj);
+ subobj = Tcl_NewDoubleObj(imgPtr->y);
+ Tcl_ListObjAppendElement(interp, obj, subobj);
+ Tcl_SetObjResult(interp, obj);
+ } else if (argc < 3) {
+ if (argc==1) {
+ if (Tcl_ListObjGetElements(interp, argv[0], &argc,
+ (Tcl_Obj ***) &argv) != TCL_OK) {
+ return TCL_ERROR;
+ } else if (argc != 2) {
+ char buf[64];
+
+ sprintf(buf, "wrong # coordinates: expected 2, got %d", argc);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_ERROR;
+ }
+ }
+ if ((Tk_CanvasGetCoordFromObj(interp, canvas, argv[0], &imgPtr->x) != TCL_OK)
+ || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[1],
+ &imgPtr->y) != TCL_OK)) {
return TCL_ERROR;
}
ComputeImageBbox(canvas, imgPtr);
@@ -257,7 +311,7 @@ ConfigureImage(interp, canvas, itemPtr, argc, argv, flags)
Tk_Canvas canvas; /* Canvas containing itemPtr. */
Tk_Item *itemPtr; /* Image item to reconfigure. */
int argc; /* Number of elements in argv. */
- char **argv; /* Arguments describing things to configure. */
+ Tcl_Obj *CONST argv[]; /* Arguments describing things to configure. */
int flags; /* Flags to pass to Tk_ConfigureWidget. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
@@ -265,8 +319,8 @@ ConfigureImage(interp, canvas, itemPtr, argc, argv, flags)
Tk_Image image;
tkwin = Tk_CanvasTkwin(canvas);
- if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc,
- argv, (char *) imgPtr, flags) != TCL_OK) {
+ if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv,
+ (char *) imgPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
return TCL_ERROR;
}
@@ -277,6 +331,11 @@ ConfigureImage(interp, canvas, itemPtr, argc, argv, flags)
* if it hasn't changed.
*/
+ if (imgPtr->activeImageString != NULL) {
+ itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
+ } else {
+ itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
+ }
if (imgPtr->imageString != NULL) {
image = Tk_GetImage(interp, tkwin, imgPtr->imageString,
ImageChangedProc, (ClientData) imgPtr);
@@ -290,6 +349,32 @@ ConfigureImage(interp, canvas, itemPtr, argc, argv, flags)
Tk_FreeImage(imgPtr->image);
}
imgPtr->image = image;
+ if (imgPtr->activeImageString != NULL) {
+ image = Tk_GetImage(interp, tkwin, imgPtr->activeImageString,
+ ImageChangedProc, (ClientData) imgPtr);
+ if (image == NULL) {
+ return TCL_ERROR;
+ }
+ } else {
+ image = NULL;
+ }
+ if (imgPtr->activeImage != NULL) {
+ Tk_FreeImage(imgPtr->activeImage);
+ }
+ imgPtr->activeImage = image;
+ if (imgPtr->disabledImageString != NULL) {
+ image = Tk_GetImage(interp, tkwin, imgPtr->disabledImageString,
+ ImageChangedProc, (ClientData) imgPtr);
+ if (image == NULL) {
+ return TCL_ERROR;
+ }
+ } else {
+ image = NULL;
+ }
+ if (imgPtr->disabledImage != NULL) {
+ Tk_FreeImage(imgPtr->disabledImage);
+ }
+ imgPtr->disabledImage = image;
ComputeImageBbox(canvas, imgPtr);
return TCL_OK;
}
@@ -323,9 +408,21 @@ DeleteImage(canvas, itemPtr, display)
if (imgPtr->imageString != NULL) {
ckfree(imgPtr->imageString);
}
+ if (imgPtr->activeImageString != NULL) {
+ ckfree(imgPtr->activeImageString);
+ }
+ if (imgPtr->disabledImageString != NULL) {
+ ckfree(imgPtr->disabledImageString);
+ }
if (imgPtr->image != NULL) {
Tk_FreeImage(imgPtr->image);
}
+ if (imgPtr->activeImage != NULL) {
+ Tk_FreeImage(imgPtr->activeImage);
+ }
+ if (imgPtr->disabledImage != NULL) {
+ Tk_FreeImage(imgPtr->disabledImage);
+ }
}
/*
@@ -357,11 +454,27 @@ ComputeImageBbox(canvas, imgPtr)
{
int width, height;
int x, y;
+ Tk_Image image;
+ Tk_State state = imgPtr->header.state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+ image = imgPtr->image;
+ if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)imgPtr) {
+ if (imgPtr->activeImage != NULL) {
+ image = imgPtr->activeImage;
+ }
+ } else if (state == TK_STATE_DISABLED) {
+ if (imgPtr->disabledImage != NULL) {
+ image = imgPtr->disabledImage;
+ }
+ }
x = (int) (imgPtr->x + ((imgPtr->x >= 0) ? 0.5 : - 0.5));
y = (int) (imgPtr->y + ((imgPtr->y >= 0) ? 0.5 : - 0.5));
- if (imgPtr->image == None) {
+ if ((state == TK_STATE_HIDDEN) || (image == None)) {
imgPtr->header.x1 = imgPtr->header.x2 = x;
imgPtr->header.y1 = imgPtr->header.y2 = y;
return;
@@ -371,7 +484,7 @@ ComputeImageBbox(canvas, imgPtr)
* Compute location and size of image, using anchor information.
*/
- Tk_SizeOfImage(imgPtr->image, &width, &height);
+ Tk_SizeOfImage(image, &width, &height);
switch (imgPtr->anchor) {
case TK_ANCHOR_N:
x -= width/2;
@@ -445,8 +558,25 @@ DisplayImage(canvas, itemPtr, display, drawable, x, y, width, height)
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
short drawableX, drawableY;
+ Tk_Image image;
+ Tk_State state = itemPtr->state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
- if (imgPtr->image == NULL) {
+ image = imgPtr->image;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (imgPtr->activeImage != NULL) {
+ image = imgPtr->activeImage;
+ }
+ } else if (state == TK_STATE_DISABLED) {
+ if (imgPtr->disabledImage != NULL) {
+ image = imgPtr->disabledImage;
+ }
+ }
+
+ if (image == NULL) {
return;
}
@@ -456,7 +586,7 @@ DisplayImage(canvas, itemPtr, display, drawable, x, y, width, height)
Tk_CanvasDrawableCoords(canvas, (double) x, (double) y,
&drawableX, &drawableY);
- Tk_RedrawImage(imgPtr->image, x - imgPtr->header.x1, y - imgPtr->header.y1,
+ Tk_RedrawImage(image, x - imgPtr->header.x1, y - imgPtr->header.y1,
width, height, drawable, drawableX, drawableY);
}
@@ -565,6 +695,96 @@ ImageToArea(canvas, itemPtr, rectPtr)
/*
*--------------------------------------------------------------
*
+ * ImageToPostscript --
+ *
+ * This procedure is called to generate Postscript for
+ * image items.
+ *
+ * Results:
+ * The return value is a standard Tcl result. If an error
+ * occurs in generating Postscript then an error message is
+ * left in interp->result, replacing whatever used to be there.
+ * If no error occurs, then Postscript for the item is appended
+ * to the result.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+ImageToPostscript(interp, canvas, itemPtr, prepass)
+ Tcl_Interp *interp; /* Leave Postscript or error message
+ * here. */
+ Tk_Canvas canvas; /* Information about overall canvas. */
+ Tk_Item *itemPtr; /* Item for which Postscript is
+ * wanted. */
+ int prepass; /* 1 means this is a prepass to
+ * collect font information; 0 means
+ * final Postscript is being created.*/
+{
+ ImageItem *imgPtr = (ImageItem *)itemPtr;
+ Tk_Window canvasWin = Tk_CanvasTkwin(canvas);
+
+ char buffer[256];
+ double x, y;
+ int width, height;
+ Tk_Image image;
+ Tk_State state = itemPtr->state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ image = imgPtr->image;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (imgPtr->activeImage != NULL) {
+ image = imgPtr->activeImage;
+ }
+ } else if (state == TK_STATE_DISABLED) {
+ if (imgPtr->disabledImage != NULL) {
+ image = imgPtr->disabledImage;
+ }
+ }
+ Tk_SizeOfImage(image, &width, &height);
+
+ /*
+ * Compute the coordinates of the lower-left corner of the image,
+ * taking into account the anchor position for the image.
+ */
+
+ x = imgPtr->x;
+ y = Tk_CanvasPsY(canvas, imgPtr->y);
+
+ switch (imgPtr->anchor) {
+ case TK_ANCHOR_NW: y -= height; break;
+ case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
+ case TK_ANCHOR_NE: x -= width; y -= height; break;
+ case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
+ case TK_ANCHOR_SE: x -= width; break;
+ case TK_ANCHOR_S: x -= width/2.0; break;
+ case TK_ANCHOR_SW: break;
+ case TK_ANCHOR_W: y -= height/2.0; break;
+ case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
+ }
+
+ if (image == NULL) {
+ return TCL_OK;
+ }
+
+ if (!prepass) {
+ sprintf(buffer, "%.15g %.15g", x, y);
+ Tcl_AppendResult(interp, buffer, " translate\n", (char *) NULL);
+ }
+
+ return Tk_PostscriptImage(image, interp, canvasWin,
+ ((TkCanvas *) canvas)->psInfo, 0, 0, width, height, prepass);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* ScaleImage --
*
* This procedure is invoked to rescale an item.