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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69 - (show annotations) (download)
Sat Nov 5 10:54:17 2016 UTC (8 years, 1 month ago) by dashley
File MIME type: text/plain
File size: 26989 byte(s)
License and property (keyword) changes.
1 /* $Header$ */
2
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 /* End of tkcanvimg.c */

Properties

Name Value
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25