OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [generic/] [tkCanvBmap.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.