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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25