/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkcanvimg.c
ViewVC logotype

Annotation of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkcanvimg.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69 - (hide annotations) (download)
Sat Nov 5 10:54:17 2016 UTC (6 years, 4 months ago) by dashley
File MIME type: text/plain
File size: 26989 byte(s)
License and property (keyword) changes.
1 dashley 69 /* $Header$ */
2 dashley 25
3     /*
4     * tkCanvImg.c --
5     *
6     * This file implements image items for canvas widgets.
7     *
8     * Copyright (c) 1994 The Regents of the University of California.
9     * Copyright (c) 1994-1997 Sun Microsystems, Inc.
10     *
11     * See the file "license.terms" for information on usage and redistribution
12     * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13     *
14     * RCS: @(#) $Id: tkcanvimg.c,v 1.1.1.1 2001/06/13 04:56:24 dtashley Exp $
15     */
16    
17     #include <stdio.h>
18     #include "tkInt.h"
19     #include "tkPort.h"
20     #include "tkCanvas.h"
21    
22     /*
23     * The structure below defines the record for each image item.
24     */
25    
26     typedef struct ImageItem {
27     Tk_Item header; /* Generic stuff that's the same for all
28     * types. MUST BE FIRST IN STRUCTURE. */
29     Tk_Canvas canvas; /* Canvas containing the image. */
30     double x, y; /* Coordinates of positioning point for
31     * image. */
32     Tk_Anchor anchor; /* Where to anchor image relative to
33     * (x,y). */
34     char *imageString; /* String describing -image option (malloc-ed).
35     * NULL means no image right now. */
36     char *activeImageString; /* String describing -activeimage option.
37     * NULL means no image right now. */
38     char *disabledImageString; /* String describing -disabledimage option.
39     * NULL means no image right now. */
40     Tk_Image image; /* Image to display in window, or NULL if
41     * no image at present. */
42     Tk_Image activeImage; /* Image to display in window, or NULL if
43     * no image at present. */
44     Tk_Image disabledImage; /* Image to display in window, or NULL if
45     * no image at present. */
46     } ImageItem;
47    
48     /*
49     * Information used for parsing configuration specs:
50     */
51    
52     static Tk_CustomOption stateOption = {
53     (Tk_OptionParseProc *) TkStateParseProc,
54     TkStatePrintProc, (ClientData) 2
55     };
56     static Tk_CustomOption tagsOption = {
57     (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
58     Tk_CanvasTagsPrintProc, (ClientData) NULL
59     };
60    
61     static Tk_ConfigSpec configSpecs[] = {
62     {TK_CONFIG_STRING, "-activeimage", (char *) NULL, (char *) NULL,
63     (char *) NULL, Tk_Offset(ImageItem, activeImageString),
64     TK_CONFIG_NULL_OK},
65     {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
66     "center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
67     {TK_CONFIG_STRING, "-disabledimage", (char *) NULL, (char *) NULL,
68     (char *) NULL, Tk_Offset(ImageItem, disabledImageString),
69     TK_CONFIG_NULL_OK},
70     {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL,
71     (char *) NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK},
72     {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
73     (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
74     &stateOption},
75     {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
76     (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
77     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
78     (char *) NULL, 0, 0}
79     };
80    
81     /*
82     * Prototypes for procedures defined in this file:
83     */
84    
85     static void ImageChangedProc _ANSI_ARGS_((ClientData clientData,
86     int x, int y, int width, int height, int imgWidth,
87     int imgHeight));
88     static int ImageCoords _ANSI_ARGS_((Tcl_Interp *interp,
89     Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
90     Tcl_Obj *CONST argv[]));
91     static int ImageToArea _ANSI_ARGS_((Tk_Canvas canvas,
92     Tk_Item *itemPtr, double *rectPtr));
93     static double ImageToPoint _ANSI_ARGS_((Tk_Canvas canvas,
94     Tk_Item *itemPtr, double *coordPtr));
95     static int ImageToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
96     Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
97     static void ComputeImageBbox _ANSI_ARGS_((Tk_Canvas canvas,
98     ImageItem *imgPtr));
99     static int ConfigureImage _ANSI_ARGS_((Tcl_Interp *interp,
100     Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
101     Tcl_Obj *CONST argv[], int flags));
102     static int CreateImage _ANSI_ARGS_((Tcl_Interp *interp,
103     Tk_Canvas canvas, struct Tk_Item *itemPtr,
104     int argc, Tcl_Obj *CONST argv[]));
105     static void DeleteImage _ANSI_ARGS_((Tk_Canvas canvas,
106     Tk_Item *itemPtr, Display *display));
107     static void DisplayImage _ANSI_ARGS_((Tk_Canvas canvas,
108     Tk_Item *itemPtr, Display *display, Drawable dst,
109     int x, int y, int width, int height));
110     static void ScaleImage _ANSI_ARGS_((Tk_Canvas canvas,
111     Tk_Item *itemPtr, double originX, double originY,
112     double scaleX, double scaleY));
113     static void TranslateImage _ANSI_ARGS_((Tk_Canvas canvas,
114     Tk_Item *itemPtr, double deltaX, double deltaY));
115    
116     /*
117     * The structures below defines the image item type in terms of
118     * procedures that can be invoked by generic item code.
119     */
120    
121     Tk_ItemType tkImageType = {
122     "image", /* name */
123     sizeof(ImageItem), /* itemSize */
124     CreateImage, /* createProc */
125     configSpecs, /* configSpecs */
126     ConfigureImage, /* configureProc */
127     ImageCoords, /* coordProc */
128     DeleteImage, /* deleteProc */
129     DisplayImage, /* displayProc */
130     TK_CONFIG_OBJS, /* flags */
131     ImageToPoint, /* pointProc */
132     ImageToArea, /* areaProc */
133     ImageToPostscript, /* postscriptProc */
134     ScaleImage, /* scaleProc */
135     TranslateImage, /* translateProc */
136     (Tk_ItemIndexProc *) NULL, /* indexProc */
137     (Tk_ItemCursorProc *) NULL, /* icursorProc */
138     (Tk_ItemSelectionProc *) NULL, /* selectionProc */
139     (Tk_ItemInsertProc *) NULL, /* insertProc */
140     (Tk_ItemDCharsProc *) NULL, /* dTextProc */
141     (Tk_ItemType *) NULL, /* nextPtr */
142     };
143    
144     /*
145     *--------------------------------------------------------------
146     *
147     * CreateImage --
148     *
149     * This procedure is invoked to create a new image
150     * item in a canvas.
151     *
152     * Results:
153     * A standard Tcl return value. If an error occurred in
154     * creating the item, then an error message is left in
155     * the interp's result; in this case itemPtr is left uninitialized,
156     * so it can be safely freed by the caller.
157     *
158     * Side effects:
159     * A new image item is created.
160     *
161     *--------------------------------------------------------------
162     */
163    
164     static int
165     CreateImage(interp, canvas, itemPtr, argc, argv)
166     Tcl_Interp *interp; /* Interpreter for error reporting. */
167     Tk_Canvas canvas; /* Canvas to hold new item. */
168     Tk_Item *itemPtr; /* Record to hold new item; header
169     * has been initialized by caller. */
170     int argc; /* Number of arguments in argv. */
171     Tcl_Obj *CONST argv[]; /* Arguments describing rectangle. */
172     {
173     ImageItem *imgPtr = (ImageItem *) itemPtr;
174     int i;
175    
176     if (argc==1) {
177     i = 1;
178     } else {
179     char *arg = Tcl_GetStringFromObj((Tcl_Obj *) argv[1], NULL);
180     if (((argc>1) && (arg[0] == '-')
181     && (arg[1] >= 'a') && (arg[1] <= 'z'))) {
182     i = 1;
183     } else {
184     i = 2;
185     }
186     }
187    
188     if (argc < i) {
189     Tcl_AppendResult(interp, "wrong # args: should be \"",
190     Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",
191     itemPtr->typePtr->name, " x y ?options?\"",
192     (char *) NULL);
193     return TCL_ERROR;
194     }
195    
196     /*
197     * Initialize item's record.
198     */
199    
200     imgPtr->canvas = canvas;
201     imgPtr->anchor = TK_ANCHOR_CENTER;
202     imgPtr->imageString = NULL;
203     imgPtr->activeImageString = NULL;
204     imgPtr->disabledImageString = NULL;
205     imgPtr->image = NULL;
206     imgPtr->activeImage = NULL;
207     imgPtr->disabledImage = NULL;
208    
209     /*
210     * Process the arguments to fill in the item record.
211     */
212    
213     if ((ImageCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) {
214     goto error;
215     }
216     if (ConfigureImage(interp, canvas, itemPtr, argc-i, argv+i, 0) == TCL_OK) {
217     return TCL_OK;
218     }
219    
220     error:
221     DeleteImage(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
222     return TCL_ERROR;
223     }
224    
225     /*
226     *--------------------------------------------------------------
227     *
228     * ImageCoords --
229     *
230     * This procedure is invoked to process the "coords" widget
231     * command on image items. See the user documentation for
232     * details on what it does.
233     *
234     * Results:
235     * Returns TCL_OK or TCL_ERROR, and sets the interp's result.
236     *
237     * Side effects:
238     * The coordinates for the given item may be changed.
239     *
240     *--------------------------------------------------------------
241     */
242    
243     static int
244     ImageCoords(interp, canvas, itemPtr, argc, argv)
245     Tcl_Interp *interp; /* Used for error reporting. */
246     Tk_Canvas canvas; /* Canvas containing item. */
247     Tk_Item *itemPtr; /* Item whose coordinates are to be
248     * read or modified. */
249     int argc; /* Number of coordinates supplied in
250     * argv. */
251     Tcl_Obj *CONST argv[]; /* Array of coordinates: x1, y1,
252     * x2, y2, ... */
253     {
254     ImageItem *imgPtr = (ImageItem *) itemPtr;
255    
256     if (argc == 0) {
257     Tcl_Obj *obj = Tcl_NewObj();
258     Tcl_Obj *subobj = Tcl_NewDoubleObj(imgPtr->x);
259     Tcl_ListObjAppendElement(interp, obj, subobj);
260     subobj = Tcl_NewDoubleObj(imgPtr->y);
261     Tcl_ListObjAppendElement(interp, obj, subobj);
262     Tcl_SetObjResult(interp, obj);
263     } else if (argc < 3) {
264     if (argc==1) {
265     if (Tcl_ListObjGetElements(interp, argv[0], &argc,
266     (Tcl_Obj ***) &argv) != TCL_OK) {
267     return TCL_ERROR;
268     } else if (argc != 2) {
269     char buf[64];
270    
271     sprintf(buf, "wrong # coordinates: expected 2, got %d", argc);
272     Tcl_SetResult(interp, buf, TCL_VOLATILE);
273     return TCL_ERROR;
274     }
275     }
276     if ((Tk_CanvasGetCoordFromObj(interp, canvas, argv[0], &imgPtr->x) != TCL_OK)
277     || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[1],
278     &imgPtr->y) != TCL_OK)) {
279     return TCL_ERROR;
280     }
281     ComputeImageBbox(canvas, imgPtr);
282     } else {
283     char buf[64];
284    
285     sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", argc);
286     Tcl_SetResult(interp, buf, TCL_VOLATILE);
287     return TCL_ERROR;
288     }
289     return TCL_OK;
290     }
291    
292     /*
293     *--------------------------------------------------------------
294     *
295     * ConfigureImage --
296     *
297     * This procedure is invoked to configure various aspects
298     * of an image item, such as its anchor position.
299     *
300     * Results:
301     * A standard Tcl result code. If an error occurs, then
302     * an error message is left in the interp's result.
303     *
304     * Side effects:
305     * Configuration information may be set for itemPtr.
306     *
307     *--------------------------------------------------------------
308     */
309    
310     static int
311     ConfigureImage(interp, canvas, itemPtr, argc, argv, flags)
312     Tcl_Interp *interp; /* Used for error reporting. */
313     Tk_Canvas canvas; /* Canvas containing itemPtr. */
314     Tk_Item *itemPtr; /* Image item to reconfigure. */
315     int argc; /* Number of elements in argv. */
316     Tcl_Obj *CONST argv[]; /* Arguments describing things to configure. */
317     int flags; /* Flags to pass to Tk_ConfigureWidget. */
318     {
319     ImageItem *imgPtr = (ImageItem *) itemPtr;
320     Tk_Window tkwin;
321     Tk_Image image;
322    
323     tkwin = Tk_CanvasTkwin(canvas);
324     if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv,
325     (char *) imgPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
326     return TCL_ERROR;
327     }
328    
329     /*
330     * Create the image. Save the old image around and don't free it
331     * until after the new one is allocated. This keeps the reference
332     * count from going to zero so the image doesn't have to be recreated
333     * if it hasn't changed.
334     */
335    
336     if (imgPtr->activeImageString != NULL) {
337     itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
338     } else {
339     itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
340     }
341     if (imgPtr->imageString != NULL) {
342     image = Tk_GetImage(interp, tkwin, imgPtr->imageString,
343     ImageChangedProc, (ClientData) imgPtr);
344     if (image == NULL) {
345     return TCL_ERROR;
346     }
347     } else {
348     image = NULL;
349     }
350     if (imgPtr->image != NULL) {
351     Tk_FreeImage(imgPtr->image);
352     }
353     imgPtr->image = image;
354     if (imgPtr->activeImageString != NULL) {
355     image = Tk_GetImage(interp, tkwin, imgPtr->activeImageString,
356     ImageChangedProc, (ClientData) imgPtr);
357     if (image == NULL) {
358     return TCL_ERROR;
359     }
360     } else {
361     image = NULL;
362     }
363     if (imgPtr->activeImage != NULL) {
364     Tk_FreeImage(imgPtr->activeImage);
365     }
366     imgPtr->activeImage = image;
367     if (imgPtr->disabledImageString != NULL) {
368     image = Tk_GetImage(interp, tkwin, imgPtr->disabledImageString,
369     ImageChangedProc, (ClientData) imgPtr);
370     if (image == NULL) {
371     return TCL_ERROR;
372     }
373     } else {
374     image = NULL;
375     }
376     if (imgPtr->disabledImage != NULL) {
377     Tk_FreeImage(imgPtr->disabledImage);
378     }
379     imgPtr->disabledImage = image;
380     ComputeImageBbox(canvas, imgPtr);
381     return TCL_OK;
382     }
383    
384     /*
385     *--------------------------------------------------------------
386     *
387     * DeleteImage --
388     *
389     * This procedure is called to clean up the data structure
390     * associated with a image item.
391     *
392     * Results:
393     * None.
394     *
395     * Side effects:
396     * Resources associated with itemPtr are released.
397     *
398     *--------------------------------------------------------------
399     */
400    
401     static void
402     DeleteImage(canvas, itemPtr, display)
403     Tk_Canvas canvas; /* Info about overall canvas widget. */
404     Tk_Item *itemPtr; /* Item that is being deleted. */
405     Display *display; /* Display containing window for
406     * canvas. */
407     {
408     ImageItem *imgPtr = (ImageItem *) itemPtr;
409    
410     if (imgPtr->imageString != NULL) {
411     ckfree(imgPtr->imageString);
412     }
413     if (imgPtr->activeImageString != NULL) {
414     ckfree(imgPtr->activeImageString);
415     }
416     if (imgPtr->disabledImageString != NULL) {
417     ckfree(imgPtr->disabledImageString);
418     }
419     if (imgPtr->image != NULL) {
420     Tk_FreeImage(imgPtr->image);
421     }
422     if (imgPtr->activeImage != NULL) {
423     Tk_FreeImage(imgPtr->activeImage);
424     }
425     if (imgPtr->disabledImage != NULL) {
426     Tk_FreeImage(imgPtr->disabledImage);
427     }
428     }
429    
430     /*
431     *--------------------------------------------------------------
432     *
433     * ComputeImageBbox --
434     *
435     * This procedure is invoked to compute the bounding box of
436     * all the pixels that may be drawn as part of a image item.
437     * This procedure is where the child image's placement is
438     * computed.
439     *
440     * Results:
441     * None.
442     *
443     * Side effects:
444     * The fields x1, y1, x2, and y2 are updated in the header
445     * for itemPtr.
446     *
447     *--------------------------------------------------------------
448     */
449    
450     /* ARGSUSED */
451     static void
452     ComputeImageBbox(canvas, imgPtr)
453     Tk_Canvas canvas; /* Canvas that contains item. */
454     ImageItem *imgPtr; /* Item whose bbox is to be
455     * recomputed. */
456     {
457     int width, height;
458     int x, y;
459     Tk_Image image;
460     Tk_State state = imgPtr->header.state;
461    
462     if(state == TK_STATE_NULL) {
463     state = ((TkCanvas *)canvas)->canvas_state;
464     }
465     image = imgPtr->image;
466     if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)imgPtr) {
467     if (imgPtr->activeImage != NULL) {
468     image = imgPtr->activeImage;
469     }
470     } else if (state == TK_STATE_DISABLED) {
471     if (imgPtr->disabledImage != NULL) {
472     image = imgPtr->disabledImage;
473     }
474     }
475    
476     x = (int) (imgPtr->x + ((imgPtr->x >= 0) ? 0.5 : - 0.5));
477     y = (int) (imgPtr->y + ((imgPtr->y >= 0) ? 0.5 : - 0.5));
478    
479     if ((state == TK_STATE_HIDDEN) || (image == None)) {
480     imgPtr->header.x1 = imgPtr->header.x2 = x;
481     imgPtr->header.y1 = imgPtr->header.y2 = y;
482     return;
483     }
484    
485     /*
486     * Compute location and size of image, using anchor information.
487     */
488    
489     Tk_SizeOfImage(image, &width, &height);
490     switch (imgPtr->anchor) {
491     case TK_ANCHOR_N:
492     x -= width/2;
493     break;
494     case TK_ANCHOR_NE:
495     x -= width;
496     break;
497     case TK_ANCHOR_E:
498     x -= width;
499     y -= height/2;
500     break;
501     case TK_ANCHOR_SE:
502     x -= width;
503     y -= height;
504     break;
505     case TK_ANCHOR_S:
506     x -= width/2;
507     y -= height;
508     break;
509     case TK_ANCHOR_SW:
510     y -= height;
511     break;
512     case TK_ANCHOR_W:
513     y -= height/2;
514     break;
515     case TK_ANCHOR_NW:
516     break;
517     case TK_ANCHOR_CENTER:
518     x -= width/2;
519     y -= height/2;
520     break;
521     }
522    
523     /*
524     * Store the information in the item header.
525     */
526    
527     imgPtr->header.x1 = x;
528     imgPtr->header.y1 = y;
529     imgPtr->header.x2 = x + width;
530     imgPtr->header.y2 = y + height;
531     }
532    
533     /*
534     *--------------------------------------------------------------
535     *
536     * DisplayImage --
537     *
538     * This procedure is invoked to draw a image item in a given
539     * drawable.
540     *
541     * Results:
542     * None.
543     *
544     * Side effects:
545     * ItemPtr is drawn in drawable using the transformation
546     * information in canvas.
547     *
548     *--------------------------------------------------------------
549     */
550    
551     static void
552     DisplayImage(canvas, itemPtr, display, drawable, x, y, width, height)
553     Tk_Canvas canvas; /* Canvas that contains item. */
554     Tk_Item *itemPtr; /* Item to be displayed. */
555     Display *display; /* Display on which to draw item. */
556     Drawable drawable; /* Pixmap or window in which to draw
557     * item. */
558     int x, y, width, height; /* Describes region of canvas that
559     * must be redisplayed (not used). */
560     {
561     ImageItem *imgPtr = (ImageItem *) itemPtr;
562     short drawableX, drawableY;
563     Tk_Image image;
564     Tk_State state = itemPtr->state;
565    
566     if(state == TK_STATE_NULL) {
567     state = ((TkCanvas *)canvas)->canvas_state;
568     }
569    
570     image = imgPtr->image;
571     if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
572     if (imgPtr->activeImage != NULL) {
573     image = imgPtr->activeImage;
574     }
575     } else if (state == TK_STATE_DISABLED) {
576     if (imgPtr->disabledImage != NULL) {
577     image = imgPtr->disabledImage;
578     }
579     }
580    
581     if (image == NULL) {
582     return;
583     }
584    
585     /*
586     * Translate the coordinates to those of the image, then redisplay it.
587     */
588    
589     Tk_CanvasDrawableCoords(canvas, (double) x, (double) y,
590     &drawableX, &drawableY);
591     Tk_RedrawImage(image, x - imgPtr->header.x1, y - imgPtr->header.y1,
592     width, height, drawable, drawableX, drawableY);
593     }
594    
595     /*
596     *--------------------------------------------------------------
597     *
598     * ImageToPoint --
599     *
600     * Computes the distance from a given point to a given
601     * rectangle, in canvas units.
602     *
603     * Results:
604     * The return value is 0 if the point whose x and y coordinates
605     * are coordPtr[0] and coordPtr[1] is inside the image. If the
606     * point isn't inside the image then the return value is the
607     * distance from the point to the image.
608     *
609     * Side effects:
610     * None.
611     *
612     *--------------------------------------------------------------
613     */
614    
615     static double
616     ImageToPoint(canvas, itemPtr, coordPtr)
617     Tk_Canvas canvas; /* Canvas containing item. */
618     Tk_Item *itemPtr; /* Item to check against point. */
619     double *coordPtr; /* Pointer to x and y coordinates. */
620     {
621     ImageItem *imgPtr = (ImageItem *) itemPtr;
622     double x1, x2, y1, y2, xDiff, yDiff;
623    
624     x1 = imgPtr->header.x1;
625     y1 = imgPtr->header.y1;
626     x2 = imgPtr->header.x2;
627     y2 = imgPtr->header.y2;
628    
629     /*
630     * Point is outside rectangle.
631     */
632    
633     if (coordPtr[0] < x1) {
634     xDiff = x1 - coordPtr[0];
635     } else if (coordPtr[0] > x2) {
636     xDiff = coordPtr[0] - x2;
637     } else {
638     xDiff = 0;
639     }
640    
641     if (coordPtr[1] < y1) {
642     yDiff = y1 - coordPtr[1];
643     } else if (coordPtr[1] > y2) {
644     yDiff = coordPtr[1] - y2;
645     } else {
646     yDiff = 0;
647     }
648    
649     return hypot(xDiff, yDiff);
650     }
651    
652     /*
653     *--------------------------------------------------------------
654     *
655     * ImageToArea --
656     *
657     * This procedure is called to determine whether an item
658     * lies entirely inside, entirely outside, or overlapping
659     * a given rectangle.
660     *
661     * Results:
662     * -1 is returned if the item is entirely outside the area
663     * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
664     * inside the given area.
665     *
666     * Side effects:
667     * None.
668     *
669     *--------------------------------------------------------------
670     */
671    
672     static int
673     ImageToArea(canvas, itemPtr, rectPtr)
674     Tk_Canvas canvas; /* Canvas containing item. */
675     Tk_Item *itemPtr; /* Item to check against rectangle. */
676     double *rectPtr; /* Pointer to array of four coordinates
677     * (x1, y1, x2, y2) describing rectangular
678     * area. */
679     {
680     ImageItem *imgPtr = (ImageItem *) itemPtr;
681    
682     if ((rectPtr[2] <= imgPtr->header.x1)
683     || (rectPtr[0] >= imgPtr->header.x2)
684     || (rectPtr[3] <= imgPtr->header.y1)
685     || (rectPtr[1] >= imgPtr->header.y2)) {
686     return -1;
687     }
688     if ((rectPtr[0] <= imgPtr->header.x1)
689     && (rectPtr[1] <= imgPtr->header.y1)
690     && (rectPtr[2] >= imgPtr->header.x2)
691     && (rectPtr[3] >= imgPtr->header.y2)) {
692     return 1;
693     }
694     return 0;
695     }
696    
697     /*
698     *--------------------------------------------------------------
699     *
700     * ImageToPostscript --
701     *
702     * This procedure is called to generate Postscript for
703     * image items.
704     *
705     * Results:
706     * The return value is a standard Tcl result. If an error
707     * occurs in generating Postscript then an error message is
708     * left in interp->result, replacing whatever used to be there.
709     * If no error occurs, then Postscript for the item is appended
710     * to the result.
711     *
712     * Side effects:
713     * None.
714     *
715     *--------------------------------------------------------------
716     */
717    
718     static int
719     ImageToPostscript(interp, canvas, itemPtr, prepass)
720     Tcl_Interp *interp; /* Leave Postscript or error message
721     * here. */
722     Tk_Canvas canvas; /* Information about overall canvas. */
723     Tk_Item *itemPtr; /* Item for which Postscript is
724     * wanted. */
725     int prepass; /* 1 means this is a prepass to
726     * collect font information; 0 means
727     * final Postscript is being created.*/
728     {
729     ImageItem *imgPtr = (ImageItem *)itemPtr;
730     Tk_Window canvasWin = Tk_CanvasTkwin(canvas);
731    
732     char buffer[256];
733     double x, y;
734     int width, height;
735     Tk_Image image;
736     Tk_State state = itemPtr->state;
737    
738     if(state == TK_STATE_NULL) {
739     state = ((TkCanvas *)canvas)->canvas_state;
740     }
741    
742     image = imgPtr->image;
743     if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
744     if (imgPtr->activeImage != NULL) {
745     image = imgPtr->activeImage;
746     }
747     } else if (state == TK_STATE_DISABLED) {
748     if (imgPtr->disabledImage != NULL) {
749     image = imgPtr->disabledImage;
750     }
751     }
752     Tk_SizeOfImage(image, &width, &height);
753    
754     /*
755     * Compute the coordinates of the lower-left corner of the image,
756     * taking into account the anchor position for the image.
757     */
758    
759     x = imgPtr->x;
760     y = Tk_CanvasPsY(canvas, imgPtr->y);
761    
762     switch (imgPtr->anchor) {
763     case TK_ANCHOR_NW: y -= height; break;
764     case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
765     case TK_ANCHOR_NE: x -= width; y -= height; break;
766     case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
767     case TK_ANCHOR_SE: x -= width; break;
768     case TK_ANCHOR_S: x -= width/2.0; break;
769     case TK_ANCHOR_SW: break;
770     case TK_ANCHOR_W: y -= height/2.0; break;
771     case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
772     }
773    
774     if (image == NULL) {
775     return TCL_OK;
776     }
777    
778     if (!prepass) {
779     sprintf(buffer, "%.15g %.15g", x, y);
780     Tcl_AppendResult(interp, buffer, " translate\n", (char *) NULL);
781     }
782    
783     return Tk_PostscriptImage(image, interp, canvasWin,
784     ((TkCanvas *) canvas)->psInfo, 0, 0, width, height, prepass);
785     }
786    
787     /*
788     *--------------------------------------------------------------
789     *
790     * ScaleImage --
791     *
792     * This procedure is invoked to rescale an item.
793     *
794     * Results:
795     * None.
796     *
797     * Side effects:
798     * The item referred to by itemPtr is rescaled so that the
799     * following transformation is applied to all point coordinates:
800     * x' = originX + scaleX*(x-originX)
801     * y' = originY + scaleY*(y-originY)
802     *
803     *--------------------------------------------------------------
804     */
805    
806     static void
807     ScaleImage(canvas, itemPtr, originX, originY, scaleX, scaleY)
808     Tk_Canvas canvas; /* Canvas containing rectangle. */
809     Tk_Item *itemPtr; /* Rectangle to be scaled. */
810     double originX, originY; /* Origin about which to scale rect. */
811     double scaleX; /* Amount to scale in X direction. */
812     double scaleY; /* Amount to scale in Y direction. */
813     {
814     ImageItem *imgPtr = (ImageItem *) itemPtr;
815    
816     imgPtr->x = originX + scaleX*(imgPtr->x - originX);
817     imgPtr->y = originY + scaleY*(imgPtr->y - originY);
818     ComputeImageBbox(canvas, imgPtr);
819     }
820    
821     /*
822     *--------------------------------------------------------------
823     *
824     * TranslateImage --
825     *
826     * This procedure is called to move an item by a given amount.
827     *
828     * Results:
829     * None.
830     *
831     * Side effects:
832     * The position of the item is offset by (xDelta, yDelta), and
833     * the bounding box is updated in the generic part of the item
834     * structure.
835     *
836     *--------------------------------------------------------------
837     */
838    
839     static void
840     TranslateImage(canvas, itemPtr, deltaX, deltaY)
841     Tk_Canvas canvas; /* Canvas containing item. */
842     Tk_Item *itemPtr; /* Item that is being moved. */
843     double deltaX, deltaY; /* Amount by which item is to be
844     * moved. */
845     {
846     ImageItem *imgPtr = (ImageItem *) itemPtr;
847    
848     imgPtr->x += deltaX;
849     imgPtr->y += deltaY;
850     ComputeImageBbox(canvas, imgPtr);
851     }
852    
853     /*
854     *----------------------------------------------------------------------
855     *
856     * ImageChangedProc --
857     *
858     * This procedure is invoked by the image code whenever the manager
859     * for an image does something that affects the image's size or
860     * how it is displayed.
861     *
862     * Results:
863     * None.
864     *
865     * Side effects:
866     * Arranges for the canvas to get redisplayed.
867     *
868     *----------------------------------------------------------------------
869     */
870    
871     static void
872     ImageChangedProc(clientData, x, y, width, height, imgWidth, imgHeight)
873     ClientData clientData; /* Pointer to canvas item for image. */
874     int x, y; /* Upper left pixel (within image)
875     * that must be redisplayed. */
876     int width, height; /* Dimensions of area to redisplay
877     * (may be <= 0). */
878     int imgWidth, imgHeight; /* New dimensions of image. */
879     {
880     ImageItem *imgPtr = (ImageItem *) clientData;
881    
882     /*
883     * If the image's size changed and it's not anchored at its
884     * northwest corner then just redisplay the entire area of the
885     * image. This is a bit over-conservative, but we need to do
886     * something because a size change also means a position change.
887     */
888    
889     if (((imgPtr->header.x2 - imgPtr->header.x1) != imgWidth)
890     || ((imgPtr->header.y2 - imgPtr->header.y1) != imgHeight)) {
891     x = y = 0;
892     width = imgWidth;
893     height = imgHeight;
894     Tk_CanvasEventuallyRedraw(imgPtr->canvas, imgPtr->header.x1,
895     imgPtr->header.y1, imgPtr->header.x2, imgPtr->header.y2);
896     }
897     ComputeImageBbox(imgPtr->canvas, imgPtr);
898     Tk_CanvasEventuallyRedraw(imgPtr->canvas, imgPtr->header.x1 + x,
899     imgPtr->header.y1 + y, (int) (imgPtr->header.x1 + x + width),
900     (int) (imgPtr->header.y1 + y + height));
901     }
902    
903 dashley 69 /* End of tkcanvimg.c */

Properties

Name Value
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25