📄 tkcanvimg.c
字号:
/* * tkCanvImg.c -- * * This file implements image items for canvas widgets. * * Copyright (c) 1994 The Regents of the University of California. * Copyright (c) 1994-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkCanvImg.c 1.18 96/05/03 10:49:09 */#include <stdio.h>#include "tkInt.h"#include "tkPort.h"#include "tkCanvas.h"/* * The structure below defines the record for each image item. */typedef struct ImageItem { Tk_Item header; /* Generic stuff that's the same for all * types. MUST BE FIRST IN STRUCTURE. */ Tk_Canvas canvas; /* Canvas containing the image. */ double x, y; /* Coordinates of positioning point for * image. */ Tk_Anchor anchor; /* Where to anchor image relative to * (x,y). */ char *imageString; /* String describing -image option (malloc-ed). * NULL means no image right now. */ Tk_Image image; /* 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, Tk_CanvasTagsPrintProc, (ClientData) NULL};static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL, "center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL, (char *) NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK}, {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, (char *) NULL, 0, 0}};/* * Prototypes for procedures defined in this file: */static void ImageChangedProc _ANSI_ARGS_((ClientData clientData, int x, int y, int width, int height, int imgWidth, int imgHeight));static int ImageCoords _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, char **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 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));static int CreateImage _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, int argc, char **argv));static void DeleteImage _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, Display *display));static void DisplayImage _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, Display *display, Drawable dst, int x, int y, int width, int height));static void ScaleImage _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double originX, double originY, double scaleX, double scaleY));static void TranslateImage _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, double deltaX, double deltaY));/* * The structures below defines the image item type in terms of * procedures that can be invoked by generic item code. */Tk_ItemType tkImageType = { "image", /* name */ sizeof(ImageItem), /* itemSize */ CreateImage, /* createProc */ configSpecs, /* configSpecs */ ConfigureImage, /* configureProc */ ImageCoords, /* coordProc */ DeleteImage, /* deleteProc */ DisplayImage, /* displayProc */ 0, /* alwaysRedraw */ ImageToPoint, /* pointProc */ ImageToArea, /* areaProc */ (Tk_ItemPostscriptProc *) NULL, /* postscriptProc */ ScaleImage, /* scaleProc */ TranslateImage, /* translateProc */ (Tk_ItemIndexProc *) NULL, /* indexProc */ (Tk_ItemCursorProc *) NULL, /* icursorProc */ (Tk_ItemSelectionProc *) NULL, /* selectionProc */ (Tk_ItemInsertProc *) NULL, /* insertProc */ (Tk_ItemDCharsProc *) NULL, /* dTextProc */ (Tk_ItemType *) NULL /* nextPtr */};/* *-------------------------------------------------------------- * * CreateImage -- * * This procedure is invoked to create a new image * item in a canvas. * * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in * interp->result; in this case itemPtr is left uninitialized, * so it can be safely freed by the caller. * * Side effects: * A new image item is created. * *-------------------------------------------------------------- */static intCreateImage(interp, canvas, itemPtr, argc, argv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Canvas canvas; /* Canvas to hold new item. */ 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. */{ ImageItem *imgPtr = (ImageItem *) itemPtr; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tk_PathName(Tk_CanvasTkwin(canvas)), " create ", itemPtr->typePtr->name, " x y ?options?\"", (char *) NULL); return TCL_ERROR; } /* * Initialize item's record. */ imgPtr->canvas = canvas; imgPtr->anchor = TK_ANCHOR_CENTER; imgPtr->imageString = NULL; imgPtr->image = 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 (ConfigureImage(interp, canvas, itemPtr, argc-2, argv+2, 0) != TCL_OK) { DeleteImage(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas))); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * ImageCoords -- * * This procedure is invoked to process the "coords" widget * command on image items. See the user documentation for * details on what it does. * * Results: * Returns TCL_OK or TCL_ERROR, and sets interp->result. * * Side effects: * The coordinates for the given item may be changed. * *-------------------------------------------------------------- */static intImageCoords(interp, canvas, itemPtr, argc, argv) Tcl_Interp *interp; /* Used for error reporting. */ Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item whose coordinates are to be * read or modified. */ int argc; /* Number of coordinates supplied in * argv. */ char **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)) { return TCL_ERROR; } ComputeImageBbox(canvas, imgPtr); } else { sprintf(interp->result, "wrong # coordinates: expected 0 or 2, got %d", argc); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * ConfigureImage -- * * This procedure is invoked to configure various aspects * of an image item, such as its anchor position. * * Results: * A standard Tcl result code. If an error occurs, then * an error message is left in interp->result. * * Side effects: * Configuration information may be set for itemPtr. * *-------------------------------------------------------------- */static intConfigureImage(interp, canvas, itemPtr, argc, argv, flags) Tcl_Interp *interp; /* Used for error reporting. */ 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. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */{ ImageItem *imgPtr = (ImageItem *) itemPtr; Tk_Window tkwin; Tk_Image image; tkwin = Tk_CanvasTkwin(canvas); if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv, (char *) imgPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * Create the image. Save the old image around and don't free it * until after the new one is allocated. This keeps the reference * count from going to zero so the image doesn't have to be recreated * if it hasn't changed. */ if (imgPtr->imageString != NULL) { image = Tk_GetImage(interp, tkwin, imgPtr->imageString, ImageChangedProc, (ClientData) imgPtr); if (image == NULL) { return TCL_ERROR; } } else { image = NULL; } if (imgPtr->image != NULL) { Tk_FreeImage(imgPtr->image); } imgPtr->image = image; ComputeImageBbox(canvas, imgPtr); return TCL_OK;}/* *-------------------------------------------------------------- * * DeleteImage -- * * This procedure is called to clean up the data structure * associated with a image item. * * Results: * None. * * Side effects: * Resources associated with itemPtr are released. * *-------------------------------------------------------------- */static voidDeleteImage(canvas, itemPtr, display) Tk_Canvas canvas; /* Info about overall canvas widget. */ Tk_Item *itemPtr; /* Item that is being deleted. */ Display *display; /* Display containing window for * canvas. */{ ImageItem *imgPtr = (ImageItem *) itemPtr; if (imgPtr->imageString != NULL) { ckfree(imgPtr->imageString); } if (imgPtr->image != NULL) { Tk_FreeImage(imgPtr->image); }}/* *-------------------------------------------------------------- * * ComputeImageBbox -- * * This procedure is invoked to compute the bounding box of * all the pixels that may be drawn as part of a image item. * This procedure is where the child image's placement is * computed. * * Results:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -