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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkMacDraw.c --
3
 *
4
 *      This file contains functions that preform drawing to
5
 *      Xlib windows.  Most of the functions simple emulate
6
 *      Xlib functions.
7
 *
8
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
9
 *
10
 * See the file "license.terms" for information on usage and redistribution
11
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
 *
13
 * RCS: @(#) $Id: tkMacDraw.c,v 1.1.1.1 2002-01-16 10:25:55 markom Exp $
14
 */
15
 
16
#include "tkInt.h"
17
#include "X.h"
18
#include "Xlib.h"
19
#include <stdio.h>
20
#include <tcl.h>
21
 
22
#include <Windows.h>
23
#include <Fonts.h>
24
#include <QDOffscreen.h>
25
#include "tkMacInt.h"
26
 
27
#ifndef PI
28
#    define PI 3.14159265358979323846
29
#endif
30
 
31
/*
32
 * Temporary regions that can be reused.
33
 */
34
static RgnHandle tmpRgn = NULL;
35
static RgnHandle tmpRgn2 = NULL;
36
 
37
static PixPatHandle gPenPat = NULL;
38
 
39
/*
40
 * Prototypes for functions used only in this file.
41
 */
42
static unsigned char    InvertByte _ANSI_ARGS_((unsigned char data));
43
 
44
/*
45
 *----------------------------------------------------------------------
46
 *
47
 * XCopyArea --
48
 *
49
 *      Copies data from one drawable to another using block transfer
50
 *      routines.
51
 *
52
 * Results:
53
 *      None.
54
 *
55
 * Side effects:
56
 *      Data is moved from a window or bitmap to a second window or
57
 *      bitmap.
58
 *
59
 *----------------------------------------------------------------------
60
 */
61
 
62
void
63
XCopyArea(
64
    Display* display,           /* Display. */
65
    Drawable src,               /* Source drawable. */
66
    Drawable dest,              /* Destination drawable. */
67
    GC gc,                      /* GC to use. */
68
    int src_x,                  /* X & Y, width & height */
69
    int src_y,                  /* define the source rectangle */
70
    unsigned int width,         /* the will be copied. */
71
    unsigned int height,
72
    int dest_x,                 /* Dest X & Y on dest rect. */
73
    int dest_y)
74
{
75
    Rect srcRect, destRect;
76
    BitMapPtr srcBit, destBit;
77
    MacDrawable *srcDraw = (MacDrawable *) src;
78
    MacDrawable *destDraw = (MacDrawable *) dest;
79
    GWorldPtr srcPort, destPort;
80
    CGrafPtr saveWorld;
81
    GDHandle saveDevice;
82
    short tmode;
83
    RGBColor origForeColor, origBackColor, whiteColor, blackColor;
84
 
85
    destPort = TkMacGetDrawablePort(dest);
86
    srcPort = TkMacGetDrawablePort(src);
87
 
88
    display->request++;
89
    GetGWorld(&saveWorld, &saveDevice);
90
    SetGWorld(destPort, NULL);
91
    GetForeColor(&origForeColor);
92
    GetBackColor(&origBackColor);
93
    whiteColor.red = 0;
94
    whiteColor.blue = 0;
95
    whiteColor.green = 0;
96
    RGBForeColor(&whiteColor);
97
    blackColor.red = 0xFFFF;
98
    blackColor.blue = 0xFFFF;
99
    blackColor.green = 0xFFFF;
100
    RGBBackColor(&blackColor);
101
 
102
 
103
    TkMacSetUpClippingRgn(dest);
104
 
105
    /*
106
     *  We will change the clip rgn in this routine, so we need to
107
     *  be able to restore it when we exit.
108
     */
109
 
110
    if (tmpRgn2 == NULL) {
111
        tmpRgn2 = NewRgn();
112
    }
113
    GetClip(tmpRgn2);
114
 
115
    if (((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) {
116
        RgnHandle clipRgn = (RgnHandle)
117
                ((TkpClipMask*)gc->clip_mask)->value.region;
118
 
119
        int xOffset, yOffset;
120
 
121
        if (tmpRgn == NULL) {
122
            tmpRgn = NewRgn();
123
        }
124
 
125
        xOffset = destDraw->xOff + gc->clip_x_origin;
126
        yOffset = destDraw->yOff + gc->clip_y_origin;
127
 
128
        OffsetRgn(clipRgn, xOffset, yOffset);
129
 
130
        GetClip(tmpRgn);
131
        SectRgn(tmpRgn, clipRgn, tmpRgn);
132
 
133
        SetClip(tmpRgn);
134
 
135
        OffsetRgn(clipRgn, -xOffset, -yOffset);
136
    }
137
 
138
    srcBit = &((GrafPtr) srcPort)->portBits;
139
    destBit = &((GrafPtr) destPort)->portBits;
140
    SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
141
            (short) (srcDraw->yOff + src_y),
142
            (short) (srcDraw->xOff + src_x + width),
143
            (short) (srcDraw->yOff + src_y + height));
144
    SetRect(&destRect, (short) (destDraw->xOff + dest_x),
145
            (short) (destDraw->yOff + dest_y),
146
            (short) (destDraw->xOff + dest_x + width),
147
            (short) (destDraw->yOff + dest_y + height));
148
    tmode = srcCopy;
149
 
150
    CopyBits(srcBit, destBit, &srcRect, &destRect, tmode, NULL);
151
    RGBForeColor(&origForeColor);
152
    RGBBackColor(&origBackColor);
153
    SetClip(tmpRgn2);
154
    SetGWorld(saveWorld, saveDevice);
155
}
156
 
157
/*
158
 *----------------------------------------------------------------------
159
 *
160
 * XCopyPlane --
161
 *
162
 *      Copies a bitmap from a source drawable to a destination
163
 *      drawable.  The plane argument specifies which bit plane of
164
 *      the source contains the bitmap.  Note that this implementation
165
 *      ignores the gc->function.
166
 *
167
 * Results:
168
 *      None.
169
 *
170
 * Side effects:
171
 *      Changes the destination drawable.
172
 *
173
 *----------------------------------------------------------------------
174
 */
175
 
176
void
177
XCopyPlane(
178
    Display* display,           /* Display. */
179
    Drawable src,               /* Source drawable. */
180
    Drawable dest,              /* Destination drawable. */
181
    GC gc,                      /* The GC to use. */
182
    int src_x,                  /* X, Y, width & height */
183
    int src_y,                  /* define the source rect. */
184
    unsigned int width,
185
    unsigned int height,
186
    int dest_x,                 /* X & Y on dest where we will copy. */
187
    int dest_y,
188
    unsigned long plane)        /* Which plane to copy. */
189
{
190
    Rect srcRect, destRect;
191
    BitMapPtr srcBit, destBit, maskBit;
192
    MacDrawable *srcDraw = (MacDrawable *) src;
193
    MacDrawable *destDraw = (MacDrawable *) dest;
194
    GWorldPtr srcPort, destPort, maskPort;
195
    CGrafPtr saveWorld;
196
    GDHandle saveDevice;
197
    RGBColor macColor;
198
    TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask;
199
    short tmode;
200
 
201
    destPort = TkMacGetDrawablePort(dest);
202
    srcPort = TkMacGetDrawablePort(src);
203
 
204
    display->request++;
205
    GetGWorld(&saveWorld, &saveDevice);
206
    SetGWorld(destPort, NULL);
207
 
208
    TkMacSetUpClippingRgn(dest);
209
 
210
    srcBit = &((GrafPtr) srcPort)->portBits;
211
    destBit = &((GrafPtr) destPort)->portBits;
212
    SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
213
            (short) (srcDraw->yOff + src_y),
214
            (short) (srcDraw->xOff + src_x + width),
215
            (short) (srcDraw->yOff + src_y + height));
216
    SetRect(&destRect, (short) (destDraw->xOff + dest_x),
217
            (short) (destDraw->yOff + dest_y),
218
            (short) (destDraw->xOff + dest_x + width),
219
            (short) (destDraw->yOff + dest_y + height));
220
    tmode = srcOr;
221
    tmode = srcCopy + transparent;
222
 
223
    if (TkSetMacColor(gc->foreground, &macColor) == true) {
224
        RGBForeColor(&macColor);
225
    }
226
 
227
    if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) {
228
 
229
        /*
230
         * Case 1: opaque bitmaps.
231
         */
232
 
233
        TkSetMacColor(gc->background, &macColor);
234
        RGBBackColor(&macColor);
235
        tmode = srcCopy;
236
        CopyBits(srcBit, destBit, &srcRect, &destRect, tmode, NULL);
237
    } else if (clipPtr->type == TKP_CLIP_PIXMAP) {
238
        if (clipPtr->value.pixmap == src) {
239
            /*
240
             * Case 2: transparent bitmaps.  If it's color we ignore
241
             * the forecolor.
242
             */
243
            if ((**(srcPort->portPixMap)).pixelSize == 1) {
244
                tmode = srcOr;
245
            } else {
246
                tmode = transparent;
247
            }
248
            CopyBits(srcBit, destBit, &srcRect, &destRect, tmode, NULL);
249
        } else {
250
            /*
251
             * Case 3: two arbitrary bitmaps.
252
             */
253
            tmode = srcCopy;
254
            maskPort = TkMacGetDrawablePort(clipPtr->value.pixmap);
255
            maskBit = &((GrafPtr) maskPort)->portBits;
256
            CopyDeepMask(srcBit, maskBit, destBit, &srcRect, &srcRect, &destRect, tmode, NULL);
257
        }
258
    }
259
 
260
    SetGWorld(saveWorld, saveDevice);
261
}
262
 
263
/*
264
 *----------------------------------------------------------------------
265
 *
266
 * TkPutImage --
267
 *
268
 *      Copies a subimage from an in-memory image to a rectangle of
269
 *      of the specified drawable.
270
 *
271
 * Results:
272
 *      None.
273
 *
274
 * Side effects:
275
 *      Draws the image on the specified drawable.
276
 *
277
 *----------------------------------------------------------------------
278
 */
279
 
280
void
281
TkPutImage(
282
    unsigned long *colors,      /* Unused on Macintosh. */
283
    int ncolors,                /* Unused on Macintosh. */
284
    Display* display,           /* Display. */
285
    Drawable d,                 /* Drawable to place image on. */
286
    GC gc,                      /* GC to use. */
287
    XImage* image,              /* Image to place. */
288
    int src_x,                  /* Source X & Y. */
289
    int src_y,
290
    int dest_x,                 /* Destination X & Y. */
291
    int dest_y,
292
    unsigned int width,         /* Same width & height for both */
293
    unsigned int height)        /* distination and source. */
294
{
295
    MacDrawable *destDraw = (MacDrawable *) d;
296
    CGrafPtr saveWorld;
297
    GDHandle saveDevice;
298
    GWorldPtr destPort;
299
    int i, j;
300
    BitMap bitmap;
301
    char *newData = NULL;
302
    Rect destRect, srcRect;
303
 
304
    destPort = TkMacGetDrawablePort(d);
305
    SetRect(&destRect, dest_x, dest_y, dest_x + width, dest_y + height);
306
    SetRect(&srcRect, src_x, src_y, src_x + width, src_y + height);
307
 
308
    display->request++;
309
    GetGWorld(&saveWorld, &saveDevice);
310
    SetGWorld(destPort, NULL);
311
 
312
    TkMacSetUpClippingRgn(d);
313
 
314
    if (image->depth == 1) {
315
 
316
        /*
317
         * This code assumes a pixel depth of 1
318
         */
319
 
320
        bitmap.bounds.top = bitmap.bounds.left = 0;
321
        bitmap.bounds.right = (short) image->width;
322
        bitmap.bounds.bottom = (short) image->height;
323
        if ((image->bytes_per_line % 2) == 1) {
324
            char *newPtr, *oldPtr;
325
            newData = (char *) ckalloc(image->height *
326
                    (image->bytes_per_line + 1));
327
            newPtr = newData;
328
            oldPtr = image->data;
329
            for (i = 0; i < image->height; i++) {
330
                for (j = 0; j < image->bytes_per_line; j++) {
331
                    *newPtr = InvertByte((unsigned char) *oldPtr);
332
                    newPtr++, oldPtr++;
333
                }
334
            *newPtr = 0;
335
            newPtr++;
336
            }
337
            bitmap.baseAddr = newData;
338
            bitmap.rowBytes = image->bytes_per_line + 1;
339
        } else {
340
            newData = (char *) ckalloc(image->height * image->bytes_per_line);
341
            for (i = 0; i < image->height * image->bytes_per_line; i++) {
342
                newData[i] = InvertByte((unsigned char) image->data[i]);
343
            }
344
            bitmap.baseAddr = newData;
345
            bitmap.rowBytes = image->bytes_per_line;
346
        }
347
 
348
        CopyBits(&bitmap, &((GrafPtr) destPort)->portBits,
349
                &srcRect, &destRect, srcCopy, NULL);
350
 
351
    } else {
352
        /* Color image */
353
        PixMap pixmap;
354
 
355
        pixmap.bounds.left = 0;
356
        pixmap.bounds.top = 0;
357
        pixmap.bounds.right = (short) image->width;
358
        pixmap.bounds.bottom = (short) image->height;
359
        pixmap.pixelType = RGBDirect;
360
        pixmap.pmVersion = 4;   /* 32bit clean */
361
        pixmap.packType = 0;
362
        pixmap.packSize = 0;
363
        pixmap.hRes = 0x00480000;
364
        pixmap.vRes = 0x00480000;
365
        pixmap.pixelSize = 32;
366
        pixmap.cmpCount = 3;
367
        pixmap.cmpSize = 8;
368
        pixmap.planeBytes = 0;
369
        pixmap.pmTable = NULL;
370
        pixmap.pmReserved = 0;
371
        pixmap.baseAddr = image->data;
372
        pixmap.rowBytes = image->bytes_per_line | 0x8000;
373
 
374
        CopyBits((BitMap *) &pixmap, &((GrafPtr) destPort)->portBits,
375
            &srcRect, &destRect, srcCopy, NULL);
376
    }
377
 
378
    if (newData != NULL) {
379
        ckfree(newData);
380
    }
381
    SetGWorld(saveWorld, saveDevice);
382
}
383
 
384
/*
385
 *----------------------------------------------------------------------
386
 *
387
 * XFillRectangles --
388
 *
389
 *      Fill multiple rectangular areas in the given drawable.
390
 *
391
 * Results:
392
 *      None.
393
 *
394
 * Side effects:
395
 *      Draws onto the specified drawable.
396
 *
397
 *----------------------------------------------------------------------
398
 */
399
 
400
void
401
XFillRectangles(
402
    Display* display,           /* Display. */
403
    Drawable d,                 /* Draw on this. */
404
    GC gc,                      /* Use this GC. */
405
    XRectangle *rectangles,     /* Rectangle array. */
406
    int n_rectangels)           /* Number of rectangles. */
407
{
408
    MacDrawable *macWin = (MacDrawable *) d;
409
    CGrafPtr saveWorld;
410
    GDHandle saveDevice;
411
    GWorldPtr destPort;
412
    Rect theRect;
413
    int i;
414
 
415
    destPort = TkMacGetDrawablePort(d);
416
 
417
    display->request++;
418
    GetGWorld(&saveWorld, &saveDevice);
419
    SetGWorld(destPort, NULL);
420
 
421
    TkMacSetUpClippingRgn(d);
422
 
423
    TkMacSetUpGraphicsPort(gc);
424
 
425
    for (i=0; i<n_rectangels; i++) {
426
        theRect.left = (short) (macWin->xOff + rectangles[i].x);
427
        theRect.top = (short) (macWin->yOff + rectangles[i].y);
428
        theRect.right = (short) (theRect.left + rectangles[i].width);
429
        theRect.bottom = (short) (theRect.top + rectangles[i].height);
430
        FillCRect(&theRect, gPenPat);
431
    }
432
 
433
    SetGWorld(saveWorld, saveDevice);
434
}
435
 
436
/*
437
 *----------------------------------------------------------------------
438
 *
439
 * XDrawLines --
440
 *
441
 *      Draw connected lines.
442
 *
443
 * Results:
444
 *      None.
445
 *
446
 * Side effects:
447
 *      Renders a series of connected lines.
448
 *
449
 *----------------------------------------------------------------------
450
 */
451
 
452
void
453
XDrawLines(
454
    Display* display,           /* Display. */
455
    Drawable d,                 /* Draw on this. */
456
    GC gc,                      /* Use this GC. */
457
    XPoint* points,             /* Array of points. */
458
    int npoints,                /* Number of points. */
459
    int mode)                   /* Line drawing mode. */
460
{
461
    MacDrawable *macWin = (MacDrawable *) d;
462
    CGrafPtr saveWorld;
463
    GWorldPtr destPort;
464
    GDHandle saveDevice;
465
    int i;
466
 
467
    destPort = TkMacGetDrawablePort(d);
468
 
469
    display->request++;
470
    if (npoints < 2) {
471
        return;  /* TODO: generate BadValue error. */
472
    }
473
    GetGWorld(&saveWorld, &saveDevice);
474
    SetGWorld(destPort, NULL);
475
 
476
    TkMacSetUpClippingRgn(d);
477
 
478
    TkMacSetUpGraphicsPort(gc);
479
 
480
    ShowPen();
481
 
482
    PenPixPat(gPenPat);
483
    MoveTo((short) (macWin->xOff + points[0].x),
484
            (short) (macWin->yOff + points[0].y));
485
    for (i = 1; i < npoints; i++) {
486
        if (mode == CoordModeOrigin) {
487
            LineTo((short) (macWin->xOff + points[i].x),
488
                    (short) (macWin->yOff + points[i].y));
489
        } else {
490
            Line((short) (macWin->xOff + points[i].x),
491
                    (short) (macWin->yOff + points[i].y));
492
        }
493
    }
494
 
495
    SetGWorld(saveWorld, saveDevice);
496
}
497
 
498
/*
499
 *----------------------------------------------------------------------
500
 *
501
 * XDrawSegments --
502
 *
503
 *      Draw unconnected lines.
504
 *
505
 * Results:
506
 *      None.
507
 *
508
 * Side effects:
509
 *      Renders a series of connected lines.
510
 *
511
 *----------------------------------------------------------------------
512
 */
513
 
514
void XDrawSegments(
515
    Display *display,
516
    Drawable  d,
517
    GC gc,
518
    XSegment *segments,
519
    int  nsegments)
520
{
521
    MacDrawable *macWin = (MacDrawable *) d;
522
    CGrafPtr saveWorld;
523
    GWorldPtr destPort;
524
    GDHandle saveDevice;
525
    int i;
526
 
527
    destPort = TkMacGetDrawablePort(d);
528
 
529
    display->request++;
530
 
531
    GetGWorld(&saveWorld, &saveDevice);
532
    SetGWorld(destPort, NULL);
533
 
534
    TkMacSetUpClippingRgn(d);
535
 
536
    TkMacSetUpGraphicsPort(gc);
537
 
538
    ShowPen();
539
 
540
    PenPixPat(gPenPat);
541
    for (i = 0; i < nsegments; i++) {
542
        MoveTo((short) (macWin->xOff + segments[i].x1),
543
                (short) (macWin->yOff + segments[i].y1));
544
        LineTo((short) (macWin->xOff + segments[i].x2),
545
                (short) (macWin->yOff + segments[i].y2));
546
    }
547
 
548
    SetGWorld(saveWorld, saveDevice);
549
}
550
 
551
/*
552
 *----------------------------------------------------------------------
553
 *
554
 * XFillPolygon --
555
 *
556
 *      Draws a filled polygon.
557
 *
558
 * Results:
559
 *      None.
560
 *
561
 * Side effects:
562
 *      Draws a filled polygon on the specified drawable.
563
 *
564
 *----------------------------------------------------------------------
565
 */
566
 
567
void
568
XFillPolygon(
569
    Display* display,           /* Display. */
570
    Drawable d,                 /* Draw on this. */
571
    GC gc,                      /* Use this GC. */
572
    XPoint* points,             /* Array of points. */
573
    int npoints,                /* Number of points. */
574
    int shape,                  /* Shape to draw. */
575
    int mode)                   /* Drawing mode. */
576
{
577
    MacDrawable *macWin = (MacDrawable *) d;
578
    PolyHandle polygon;
579
    CGrafPtr saveWorld;
580
    GDHandle saveDevice;
581
    GWorldPtr destPort;
582
    int i;
583
 
584
    destPort = TkMacGetDrawablePort(d);
585
 
586
    display->request++;
587
    GetGWorld(&saveWorld, &saveDevice);
588
    SetGWorld(destPort, NULL);
589
 
590
    TkMacSetUpClippingRgn(d);
591
 
592
    TkMacSetUpGraphicsPort(gc);
593
 
594
    PenNormal();
595
    polygon = OpenPoly();
596
 
597
    MoveTo((short) (macWin->xOff + points[0].x),
598
            (short) (macWin->yOff + points[0].y));
599
    for (i = 1; i < npoints; i++) {
600
        if (mode == CoordModePrevious) {
601
            Line((short) (macWin->xOff + points[i].x),
602
                    (short) (macWin->yOff + points[i].y));
603
        } else {
604
            LineTo((short) (macWin->xOff + points[i].x),
605
                    (short) (macWin->yOff + points[i].y));
606
        }
607
    }
608
 
609
    ClosePoly();
610
 
611
    FillCPoly(polygon, gPenPat);
612
 
613
    KillPoly(polygon);
614
    SetGWorld(saveWorld, saveDevice);
615
}
616
 
617
/*
618
 *----------------------------------------------------------------------
619
 *
620
 * XDrawRectangle --
621
 *
622
 *      Draws a rectangle.
623
 *
624
 * Results:
625
 *      None.
626
 *
627
 * Side effects:
628
 *      Draws a rectangle on the specified drawable.
629
 *
630
 *----------------------------------------------------------------------
631
 */
632
 
633
void
634
XDrawRectangle(
635
    Display* display,           /* Display. */
636
    Drawable d,                 /* Draw on this. */
637
    GC gc,                      /* Use this GC. */
638
    int x,                      /* Upper left corner. */
639
    int y,
640
    unsigned int width,         /* Width & height of rect. */
641
    unsigned int height)
642
{
643
    MacDrawable *macWin = (MacDrawable *) d;
644
    Rect theRect;
645
    CGrafPtr saveWorld;
646
    GDHandle saveDevice;
647
    GWorldPtr destPort;
648
 
649
    destPort = TkMacGetDrawablePort(d);
650
 
651
    display->request++;
652
    GetGWorld(&saveWorld, &saveDevice);
653
    SetGWorld(destPort, NULL);
654
 
655
    TkMacSetUpClippingRgn(d);
656
 
657
    TkMacSetUpGraphicsPort(gc);
658
 
659
    theRect.left = (short) (macWin->xOff + x);
660
    theRect.top = (short) (macWin->yOff + y);
661
    theRect.right = (short) (theRect.left + width);
662
    theRect.bottom = (short) (theRect.top + height);
663
 
664
    ShowPen();
665
    PenPixPat(gPenPat);
666
    FrameRect(&theRect);
667
 
668
    SetGWorld(saveWorld, saveDevice);
669
}
670
 
671
/*
672
 *----------------------------------------------------------------------
673
 *
674
 * XDrawArc --
675
 *
676
 *      Draw an arc.
677
 *
678
 * Results:
679
 *      None.
680
 *
681
 * Side effects:
682
 *      Draws an arc on the specified drawable.
683
 *
684
 *----------------------------------------------------------------------
685
 */
686
 
687
void
688
XDrawArc(
689
    Display* display,           /* Display. */
690
    Drawable d,                 /* Draw on this. */
691
    GC gc,                      /* Use this GC. */
692
    int x,                      /* Upper left of */
693
    int y,                      /* bounding rect. */
694
    unsigned int width,         /* Width & height. */
695
    unsigned int height,
696
    int angle1,                 /* Staring angle of arc. */
697
    int angle2)                 /* Ending angle of arc. */
698
{
699
    MacDrawable *macWin = (MacDrawable *) d;
700
    Rect theRect;
701
    short start, extent;
702
    CGrafPtr saveWorld;
703
    GDHandle saveDevice;
704
    GWorldPtr destPort;
705
 
706
    destPort = TkMacGetDrawablePort(d);
707
 
708
    display->request++;
709
    GetGWorld(&saveWorld, &saveDevice);
710
    SetGWorld(destPort, NULL);
711
 
712
    TkMacSetUpClippingRgn(d);
713
 
714
    TkMacSetUpGraphicsPort(gc);
715
 
716
    theRect.left = (short) (macWin->xOff + x);
717
    theRect.top = (short) (macWin->yOff + y);
718
    theRect.right = (short) (theRect.left + width);
719
    theRect.bottom = (short) (theRect.top + height);
720
    start = (short) (90 - (angle1 / 64));
721
    extent = (short) (-(angle2 / 64));
722
 
723
    ShowPen();
724
    PenPixPat(gPenPat);
725
    FrameArc(&theRect, start, extent);
726
 
727
    SetGWorld(saveWorld, saveDevice);
728
}
729
 
730
/*
731
 *----------------------------------------------------------------------
732
 *
733
 * XFillArc --
734
 *
735
 *      Draw a filled arc.
736
 *
737
 * Results:
738
 *      None.
739
 *
740
 * Side effects:
741
 *      Draws a filled arc on the specified drawable.
742
 *
743
 *----------------------------------------------------------------------
744
 */
745
 
746
void
747
XFillArc(
748
    Display* display,           /* Display. */
749
    Drawable d,                 /* Draw on this. */
750
    GC gc,                      /* Use this GC. */
751
    int x,                      /* Upper left of */
752
    int y,                      /* bounding rect. */
753
    unsigned int width,         /* Width & height. */
754
    unsigned int height,
755
    int angle1,                 /* Staring angle of arc. */
756
    int angle2)                 /* Ending angle of arc. */
757
{
758
    MacDrawable *macWin = (MacDrawable *) d;
759
    Rect theRect;
760
    short start, extent;
761
    PolyHandle polygon;
762
    double sin1, cos1, sin2, cos2, angle;
763
    double boxWidth, boxHeight;
764
    double vertex[2], center1[2], center2[2];
765
    CGrafPtr saveWorld;
766
    GDHandle saveDevice;
767
    GWorldPtr destPort;
768
 
769
    destPort = TkMacGetDrawablePort(d);
770
 
771
    display->request++;
772
    GetGWorld(&saveWorld, &saveDevice);
773
    SetGWorld(destPort, NULL);
774
 
775
    TkMacSetUpClippingRgn(d);
776
 
777
    TkMacSetUpGraphicsPort(gc);
778
 
779
    theRect.left = (short) (macWin->xOff + x);
780
    theRect.top = (short) (macWin->yOff + y);
781
    theRect.right = (short) (theRect.left + width);
782
    theRect.bottom = (short) (theRect.top + height);
783
    start = (short) (90 - (angle1 / 64));
784
    extent = (short) (- (angle2 / 64));
785
 
786
    if (gc->arc_mode == ArcChord) {
787
        boxWidth = theRect.right - theRect.left;
788
        boxHeight = theRect.bottom - theRect.top;
789
        angle = -(angle1/64.0)*PI/180.0;
790
        sin1 = sin(angle);
791
        cos1 = cos(angle);
792
        angle -= (angle2/64.0)*PI/180.0;
793
        sin2 = sin(angle);
794
        cos2 = cos(angle);
795
        vertex[0] = (theRect.left + theRect.right)/2.0;
796
        vertex[1] = (theRect.top + theRect.bottom)/2.0;
797
        center1[0] = vertex[0] + cos1*boxWidth/2.0;
798
        center1[1] = vertex[1] + sin1*boxHeight/2.0;
799
        center2[0] = vertex[0] + cos2*boxWidth/2.0;
800
        center2[1] = vertex[1] + sin2*boxHeight/2.0;
801
 
802
        polygon = OpenPoly();
803
        MoveTo((short) ((theRect.left + theRect.right)/2),
804
                (short) ((theRect.top + theRect.bottom)/2));
805
 
806
        LineTo((short) (center1[0] + 0.5), (short) (center1[1] + 0.5));
807
        LineTo((short) (center2[0] + 0.5), (short) (center2[1] + 0.5));
808
        ClosePoly();
809
 
810
        ShowPen();
811
        FillCArc(&theRect, start, extent, gPenPat);
812
        FillCPoly(polygon, gPenPat);
813
 
814
        KillPoly(polygon);
815
    } else {
816
        ShowPen();
817
        FillCArc(&theRect, start, extent, gPenPat);
818
    }
819
 
820
    SetGWorld(saveWorld, saveDevice);
821
}
822
 
823
/*
824
 *----------------------------------------------------------------------
825
 *
826
 * TkScrollWindow --
827
 *
828
 *      Scroll a rectangle of the specified window and accumulate
829
 *      a damage region.
830
 *
831
 * Results:
832
 *      Returns 0 if the scroll genereated no additional damage.
833
 *      Otherwise, sets the region that needs to be repainted after
834
 *      scrolling and returns 1.
835
 *
836
 * Side effects:
837
 *      Scrolls the bits in the window.
838
 *
839
 *----------------------------------------------------------------------
840
 */
841
 
842
int
843
TkScrollWindow(
844
    Tk_Window tkwin,            /* The window to be scrolled. */
845
    GC gc,                      /* GC for window to be scrolled. */
846
    int x,                      /* Position rectangle to be scrolled. */
847
    int y,
848
    int width,
849
    int height,
850
    int dx,                     /* Distance rectangle should be moved. */
851
    int dy,
852
    TkRegion damageRgn)         /* Region to accumulate damage in. */
853
{
854
    MacDrawable *destDraw = (MacDrawable *) Tk_WindowId(tkwin);
855
    RgnHandle rgn = (RgnHandle) damageRgn;
856
    CGrafPtr saveWorld;
857
    GDHandle saveDevice;
858
    GWorldPtr destPort;
859
    Rect srcRect, scrollRect;
860
 
861
    destPort = TkMacGetDrawablePort(Tk_WindowId(tkwin));
862
 
863
    GetGWorld(&saveWorld, &saveDevice);
864
    SetGWorld(destPort, NULL);
865
 
866
    TkMacSetUpClippingRgn(Tk_WindowId(tkwin));
867
 
868
    /*
869
     * Due to the implementation below the behavior may be differnt
870
     * than X in certain cases that should never occur in Tk.  The
871
     * scrollRect is the source rect extended by the offset (the union
872
     * of the source rect and the offset rect).  Everything
873
     * in the extended scrollRect is scrolled.  On X, it's possible
874
     * to "skip" over an area if the offset makes the source and
875
     * destination rects disjoint and non-aligned.
876
     */
877
 
878
    SetRect(&srcRect, (short) (destDraw->xOff + x),
879
            (short) (destDraw->yOff + y),
880
            (short) (destDraw->xOff + x + width),
881
            (short) (destDraw->yOff + y + height));
882
    scrollRect = srcRect;
883
    if (dx < 0) {
884
        scrollRect.left += dx;
885
    } else {
886
        scrollRect.right += dx;
887
    }
888
    if (dy < 0) {
889
        scrollRect.top += dy;
890
    } else {
891
        scrollRect.bottom += dy;
892
    }
893
 
894
    /*
895
     * Adjust clip region so that we don't copy any windows
896
     * that may overlap us.
897
     */
898
    RectRgn(rgn, &srcRect);
899
    DiffRgn(rgn, destPort->visRgn, rgn);
900
    OffsetRgn(rgn, dx, dy);
901
    DiffRgn(destPort->clipRgn, rgn, destPort->clipRgn);
902
    SetEmptyRgn(rgn);
903
 
904
    /*
905
     * When a menu is up, the Mac does not expect drawing to occur and
906
     * does not clip out the menu. We have to do it ourselves. This
907
     * is pretty gross.
908
     */
909
 
910
    if (tkUseMenuCascadeRgn == 1) {
911
        Point scratch = {0, 0};
912
        MacDrawable *macDraw = (MacDrawable *) Tk_WindowId(tkwin);
913
 
914
        LocalToGlobal(&scratch);
915
        CopyRgn(tkMenuCascadeRgn, rgn);
916
        OffsetRgn(rgn, -scratch.h, -scratch.v);
917
        DiffRgn(destPort->clipRgn, rgn, destPort->clipRgn);
918
        SetEmptyRgn(rgn);
919
        macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU;
920
    }
921
 
922
    ScrollRect(&scrollRect, dx, dy, rgn);
923
 
924
    SetGWorld(saveWorld, saveDevice);
925
 
926
    /*
927
     * Fortunantly, the region returned by ScrollRect is symanticlly
928
     * the same as what we need to return in this function.  If the
929
     * region is empty we return zero to denote that no damage was
930
     * created.
931
     */
932
    if (EmptyRgn(rgn)) {
933
        return 0;
934
    } else {
935
        return 1;
936
    }
937
}
938
 
939
/*
940
 *----------------------------------------------------------------------
941
 *
942
 * TkMacSetUpGraphicsPort --
943
 *
944
 *      Set up the graphics port from the given GC.
945
 *
946
 * Results:
947
 *      None.
948
 *
949
 * Side effects:
950
 *      The current port is adjusted.
951
 *
952
 *----------------------------------------------------------------------
953
 */
954
 
955
void
956
TkMacSetUpGraphicsPort(
957
    GC gc)              /* GC to apply to current port. */
958
{
959
    RGBColor macColor;
960
 
961
    if (gPenPat == NULL) {
962
        gPenPat = NewPixPat();
963
    }
964
 
965
    if (TkSetMacColor(gc->foreground, &macColor) == true) {
966
        /* TODO: cache RGBPats for preformace - measure gains...  */
967
        MakeRGBPat(gPenPat, &macColor);
968
    }
969
 
970
    PenNormal();
971
    if(gc->function == GXxor) {
972
        PenMode(patXor);
973
    }
974
    if (gc->line_width > 1) {
975
        PenSize(gc->line_width, gc->line_width);
976
    }
977
}
978
 
979
/*
980
 *----------------------------------------------------------------------
981
 *
982
 * TkMacSetUpClippingRgn --
983
 *
984
 *      Set up the clipping region so that drawing only occurs on the
985
 *      specified X subwindow.
986
 *
987
 * Results:
988
 *      None.
989
 *
990
 * Side effects:
991
 *      The clipping region in the current port is changed.
992
 *
993
 *----------------------------------------------------------------------
994
 */
995
 
996
void
997
TkMacSetUpClippingRgn(
998
    Drawable drawable)          /* Drawable to update. */
999
{
1000
    MacDrawable *macDraw = (MacDrawable *) drawable;
1001
 
1002
    if (macDraw->winPtr != NULL) {
1003
        if (macDraw->flags & TK_CLIP_INVALID) {
1004
            TkMacUpdateClipRgn(macDraw->winPtr);
1005
        }
1006
 
1007
        /*
1008
         * When a menu is up, the Mac does not expect drawing to occur and
1009
         * does not clip out the menu. We have to do it ourselves. This
1010
         * is pretty gross.
1011
         */
1012
 
1013
        if (macDraw->clipRgn != NULL) {
1014
            if (tkUseMenuCascadeRgn == 1) {
1015
                Point scratch = {0, 0};
1016
                GDHandle saveDevice;
1017
                GWorldPtr saveWorld;
1018
 
1019
                GetGWorld(&saveWorld, &saveDevice);
1020
                SetGWorld(TkMacGetDrawablePort(drawable), NULL);
1021
                LocalToGlobal(&scratch);
1022
                SetGWorld(saveWorld, saveDevice);
1023
                if (tmpRgn == NULL) {
1024
                    tmpRgn = NewRgn();
1025
                }
1026
                CopyRgn(tkMenuCascadeRgn, tmpRgn);
1027
                OffsetRgn(tmpRgn, -scratch.h, -scratch.v);
1028
                DiffRgn(macDraw->clipRgn, tmpRgn, tmpRgn);
1029
                SetClip(tmpRgn);
1030
                macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU;
1031
            } else {
1032
                SetClip(macDraw->clipRgn);
1033
            }
1034
        }
1035
    }
1036
}
1037
 
1038
/*
1039
 *----------------------------------------------------------------------
1040
 *
1041
 * TkMacMakeStippleMap --
1042
 *
1043
 *      Given a drawable and a stipple pattern this function draws the
1044
 *      pattern repeatedly over the drawable.  The drawable can then
1045
 *      be used as a mask for bit-bliting a stipple pattern over an
1046
 *      object.
1047
 *
1048
 * Results:
1049
 *      A BitMap data structure.
1050
 *
1051
 * Side effects:
1052
 *      None.
1053
 *
1054
 *----------------------------------------------------------------------
1055
 */
1056
 
1057
BitMapPtr
1058
TkMacMakeStippleMap(
1059
    Drawable drawable,          /* Window to apply stipple. */
1060
    Drawable stipple)           /* The stipple pattern. */
1061
{
1062
    MacDrawable *destDraw = (MacDrawable *) drawable;
1063
    GWorldPtr destPort;
1064
    BitMapPtr bitmapPtr;
1065
    int width, height, stippleHeight, stippleWidth;
1066
    int i, j;
1067
    char * data;
1068
    Rect bounds;
1069
 
1070
    destPort = TkMacGetDrawablePort(drawable);
1071
    width = destPort->portRect.right - destPort->portRect.left;
1072
    height = destPort->portRect.bottom - destPort->portRect.top;
1073
 
1074
    bitmapPtr = (BitMap *) ckalloc(sizeof(BitMap));
1075
    data = (char *) ckalloc(height * ((width / 8) + 1));
1076
    bitmapPtr->bounds.top = bitmapPtr->bounds.left = 0;
1077
    bitmapPtr->bounds.right = (short) width;
1078
    bitmapPtr->bounds.bottom = (short) height;
1079
    bitmapPtr->baseAddr = data;
1080
    bitmapPtr->rowBytes = (width / 8) + 1;
1081
 
1082
    destPort = TkMacGetDrawablePort(stipple);
1083
    stippleWidth = destPort->portRect.right - destPort->portRect.left;
1084
    stippleHeight = destPort->portRect.bottom - destPort->portRect.top;
1085
 
1086
    for (i = 0; i < height; i += stippleHeight) {
1087
        for (j = 0; j < width; j += stippleWidth) {
1088
            bounds.left = j;
1089
            bounds.top = i;
1090
            bounds.right = j + stippleWidth;
1091
            bounds.bottom = i + stippleHeight;
1092
 
1093
            CopyBits(&((GrafPtr) destPort)->portBits, bitmapPtr,
1094
                &((GrafPtr) destPort)->portRect, &bounds, srcCopy, NULL);
1095
        }
1096
    }
1097
    return bitmapPtr;
1098
}
1099
 
1100
/*
1101
 *----------------------------------------------------------------------
1102
 *
1103
 * InvertByte --
1104
 *
1105
 *      This function reverses the bits in the passed in Byte of data.
1106
 *
1107
 * Results:
1108
 *      The incoming byte in reverse bit order.
1109
 *
1110
 * Side effects:
1111
 *      None.
1112
 *
1113
 *----------------------------------------------------------------------
1114
 */
1115
 
1116
static unsigned char
1117
InvertByte(
1118
    unsigned char data)         /* Byte of data. */
1119
{
1120
    unsigned char i;
1121
    unsigned char mask = 1, result = 0;
1122
 
1123
    for (i = (1 << 7); i != 0; i /= 2) {
1124
        if (data & mask) {
1125
            result |= i;
1126
        }
1127
        mask = mask << 1;
1128
    }
1129
    return result;
1130
}

powered by: WebSVN 2.1.0

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