~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to ilbm/ilbmgc.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/ilbm/ilbmgc.c,v 3.0 1996/08/18 01:53:52 dawes Exp $ */
 
2
/***********************************************************
 
3
 
 
4
Copyright (c) 1987  X Consortium
 
5
 
 
6
Permission is hereby granted, free of charge, to any person obtaining a copy
 
7
of this software and associated documentation files (the "Software"), to deal
 
8
in the Software without restriction, including without limitation the rights
 
9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
10
copies of the Software, and to permit persons to whom the Software is
 
11
furnished to do so, subject to the following conditions:
 
12
 
 
13
The above copyright notice and this permission notice shall be included in
 
14
all copies or substantial portions of the Software.
 
15
 
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
19
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
20
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
 
 
23
Except as contained in this notice, the name of the X Consortium shall not be
 
24
used in advertising or otherwise to promote the sale, use or other dealings
 
25
in this Software without prior written authorization from the X Consortium.
 
26
 
 
27
 
 
28
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 
29
 
 
30
                        All Rights Reserved
 
31
 
 
32
Permission to use, copy, modify, and distribute this software and its
 
33
documentation for any purpose and without fee is hereby granted,
 
34
provided that the above copyright notice appear in all copies and that
 
35
both that copyright notice and this permission notice appear in
 
36
supporting documentation, and that the name of Digital not be
 
37
used in advertising or publicity pertaining to distribution of the
 
38
software without specific, written prior permission.
 
39
 
 
40
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
41
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
42
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
43
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
44
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
45
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
46
SOFTWARE.
 
47
 
 
48
******************************************************************/
 
49
/* $XConsortium: ilbmgc.c,v 5.35 94/04/17 20:28:23 dpw Exp $ */
 
50
 
 
51
/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
 
52
   to use interleaved bitplanes instead of normal bitplanes */
 
53
 
 
54
#ifdef HAVE_DIX_CONFIG_H
 
55
#include <dix-config.h>
 
56
#endif
 
57
 
 
58
#include <X11/X.h>
 
59
#include <X11/Xmd.h>
 
60
#include <X11/Xproto.h>
 
61
#include "ilbm.h"
 
62
#include "dixfontstr.h"
 
63
#include <X11/fonts/fontstruct.h>
 
64
#include "gcstruct.h"
 
65
#include "windowstr.h"
 
66
#include "pixmapstr.h"
 
67
#include "scrnintstr.h"
 
68
#include "region.h"
 
69
 
 
70
#include "mistruct.h"
 
71
#include "migc.h"
 
72
 
 
73
#include "maskbits.h"
 
74
 
 
75
static GCFuncs ilbmFuncs = {
 
76
                ilbmValidateGC,
 
77
                miChangeGC,
 
78
                miCopyGC,
 
79
                ilbmDestroyGC,
 
80
                miChangeClip,
 
81
                miDestroyClip,
 
82
                miCopyClip
 
83
};
 
84
 
 
85
static GCOps ilbmGCOps = {
 
86
                ilbmSolidFS,
 
87
                ilbmSetSpans,
 
88
                ilbmPutImage,
 
89
                ilbmCopyArea,
 
90
                miCopyPlane,
 
91
                ilbmPolyPoint,
 
92
                ilbmLineSS,
 
93
                ilbmSegmentSS,
 
94
                miPolyRectangle,
 
95
                ilbmZeroPolyArcSS,
 
96
                ilbmFillPolygonSolid,
 
97
                ilbmPolyFillRect,
 
98
                ilbmPolyFillArcSolid,
 
99
                miPolyText8,
 
100
                miPolyText16,
 
101
                miImageText8,
 
102
                miImageText16,
 
103
                ilbmTEGlyphBlt,
 
104
                ilbmPolyGlyphBlt,
 
105
                ilbmPushPixels
 
106
#ifdef NEED_LINEHELPER
 
107
                ,NULL
 
108
#endif
 
109
};
 
110
 
 
111
 
 
112
Bool
 
113
ilbmCreateGC(pGC)
 
114
        register GCPtr pGC;
 
115
{
 
116
        ilbmPrivGC              *pPriv;
 
117
 
 
118
        pGC->clientClip = NULL;
 
119
        pGC->clientClipType = CT_NONE;
 
120
 
 
121
        /* some of the output primitives aren't really necessary, since
 
122
           they will be filled in ValidateGC because of dix/CreateGC()
 
123
           setting all the change bits.  Others are necessary because although
 
124
           they depend on being a monochrome frame buffer, they don't change
 
125
        */
 
126
 
 
127
        pGC->ops = &ilbmGCOps;
 
128
        pGC->funcs = &ilbmFuncs;
 
129
 
 
130
        /* ilbm wants to translate before scan convesion */
 
131
        pGC->miTranslate = 1;
 
132
 
 
133
        pPriv = (ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr);
 
134
        ilbmReduceRop(pGC->alu, pGC->fgPixel, pGC->planemask, pGC->depth,
 
135
                                          pPriv->rrops);
 
136
        ilbmReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask,
 
137
                                                                        pGC->depth, pPriv->rropOS);
 
138
 
 
139
        pGC->fExpose = TRUE;
 
140
        pGC->pRotatedPixmap = NullPixmap;
 
141
        pGC->freeCompClip = FALSE;
 
142
        return TRUE;
 
143
}
 
144
 
 
145
/* Clipping conventions
 
146
                if the drawable is a window
 
147
                        CT_REGION ==> pCompositeClip really is the composite
 
148
                        CT_other ==> pCompositeClip is the window clip region
 
149
                if the drawable is a pixmap
 
150
                        CT_REGION ==> pCompositeClip is the translated client region
 
151
                                clipped to the pixmap boundary
 
152
                        CT_other ==> pCompositeClip is the pixmap bounding box
 
153
*/
 
154
 
 
155
/*ARGSUSED*/
 
156
void
 
157
ilbmValidateGC(pGC, changes, pDrawable)
 
158
        register GCPtr          pGC;
 
159
        unsigned long           changes;
 
160
        DrawablePtr             pDrawable;
 
161
{
 
162
        register ilbmPrivGCPtr devPriv;
 
163
        int mask;                                               /* stateChanges */
 
164
        int index;                                              /* used for stepping through bitfields */
 
165
        int xrot, yrot;                         /* rotations for tile and stipple pattern */
 
166
        int rrop;                                               /* reduced rasterop */
 
167
                                                                                /* flags for changing the proc vector
 
168
                                                                                   and updating things in devPriv
 
169
                                                                                */
 
170
        int new_rotate, new_rrop,  new_line, new_text, new_fill;
 
171
        DDXPointRec             oldOrg;                         /* origin of thing GC was last used with */
 
172
 
 
173
        oldOrg = pGC->lastWinOrg;
 
174
 
 
175
        pGC->lastWinOrg.x = pDrawable->x;
 
176
        pGC->lastWinOrg.y = pDrawable->y;
 
177
 
 
178
        /* we need to re-rotate the tile if the previous window/pixmap
 
179
           origin (oldOrg) differs from the new window/pixmap origin
 
180
           (pGC->lastWinOrg)
 
181
        */
 
182
        new_rotate = (oldOrg.x != pGC->lastWinOrg.x) ||
 
183
                                         (oldOrg.y != pGC->lastWinOrg.y);
 
184
 
 
185
 
 
186
        devPriv = ((ilbmPrivGCPtr)(pGC->devPrivates[ilbmGCPrivateIndex].ptr));
 
187
 
 
188
 
 
189
        /*
 
190
                if the client clip is different or moved OR
 
191
                the subwindowMode has changed OR
 
192
                the window's clip has changed since the last validation
 
193
                we need to recompute the composite clip
 
194
        */
 
195
        if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
 
196
                 (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
 
197
                ilbmComputeCompositeClip(pGC, pDrawable);
 
198
 
 
199
        new_rrop = FALSE;
 
200
        new_line = FALSE;
 
201
        new_text = FALSE;
 
202
        new_fill = FALSE;
 
203
 
 
204
        mask = changes;
 
205
        while (mask) {
 
206
                index = lowbit(mask);
 
207
                mask &= ~index;
 
208
 
 
209
                /* this switch acculmulates a list of which procedures
 
210
                   might have to change due to changes in the GC.  in
 
211
                   some cases (e.g. changing one 16 bit tile for another)
 
212
                   we might not really need a change, but the code is
 
213
                   being paranoid.
 
214
                   this sort of batching wins if, for example, the alu
 
215
                   and the font have been changed, or any other pair
 
216
                   of items that both change the same thing.
 
217
                */
 
218
                switch (index) {
 
219
                        case GCPlaneMask:
 
220
                        case GCFunction:
 
221
                        case GCForeground:
 
222
                                new_rrop = TRUE;
 
223
                                break;
 
224
                        case GCBackground:
 
225
                                new_rrop = TRUE;                /* for opaque stipples */
 
226
                                break;
 
227
                        case GCLineStyle:
 
228
                        case GCLineWidth:
 
229
                        case GCJoinStyle:
 
230
                                        new_line = TRUE;
 
231
                                        break;
 
232
                        case GCCapStyle:
 
233
                                break;
 
234
                        case GCFillStyle:
 
235
                                new_fill = TRUE;
 
236
                                break;
 
237
                        case GCFillRule:
 
238
                                break;
 
239
                        case GCTile:
 
240
                                if (pGC->tileIsPixel)
 
241
                                        break;
 
242
                                new_rotate = TRUE;
 
243
                                new_fill = TRUE;
 
244
                                break;
 
245
 
 
246
                        case GCStipple:
 
247
                                if (pGC->stipple == (PixmapPtr)NULL)
 
248
                                        break;
 
249
                                new_rotate = TRUE;
 
250
                                new_fill = TRUE;
 
251
                                break;
 
252
 
 
253
                        case GCTileStipXOrigin:
 
254
                                new_rotate = TRUE;
 
255
                                break;
 
256
 
 
257
                        case GCTileStipYOrigin:
 
258
                                new_rotate = TRUE;
 
259
                                break;
 
260
 
 
261
                        case GCFont:
 
262
                                new_text = TRUE;
 
263
                                break;
 
264
                        case GCSubwindowMode:
 
265
                                break;
 
266
                        case GCGraphicsExposures:
 
267
                                break;
 
268
                        case GCClipXOrigin:
 
269
                                break;
 
270
                        case GCClipYOrigin:
 
271
                                break;
 
272
                        case GCClipMask:
 
273
                                break;
 
274
                        case GCDashOffset:
 
275
                                break;
 
276
                        case GCDashList:
 
277
                                break;
 
278
                        case GCArcMode:
 
279
                                break;
 
280
                        default:
 
281
                                        break;
 
282
                }
 
283
        }
 
284
 
 
285
        /* deal with the changes we've collected .
 
286
           new_rrop must be done first because subsequent things
 
287
           depend on it.
 
288
        */
 
289
 
 
290
        if (new_rotate || new_fill) {
 
291
                Bool new_pix = FALSE;
 
292
 
 
293
                /* figure out how much to rotate */
 
294
                xrot = pGC->patOrg.x;
 
295
                yrot = pGC->patOrg.y;
 
296
                xrot += pDrawable->x;
 
297
                yrot += pDrawable->y;
 
298
 
 
299
                switch (pGC->fillStyle) {
 
300
                        case FillTiled:
 
301
                                /* copy current tile and stipple */
 
302
                                if (!pGC->tileIsPixel &&
 
303
                                         (pGC->tile.pixmap->drawable.width <= PPW) &&
 
304
                                         !(pGC->tile.pixmap->drawable.width &
 
305
                                                (pGC->tile.pixmap->drawable.width - 1))) {
 
306
                                        ilbmCopyRotatePixmap(pGC->tile.pixmap, &pGC->pRotatedPixmap,
 
307
                                                                                                xrot, yrot);
 
308
                                        new_pix = TRUE;
 
309
                                }
 
310
                                break;
 
311
                        case FillStippled:
 
312
                        case FillOpaqueStippled:
 
313
                                if (pGC->stipple && (pGC->stipple->drawable.width <= PPW) &&
 
314
                                         !(pGC->stipple->drawable.width &
 
315
                                                (pGC->stipple->drawable.width - 1))) {
 
316
                                        ilbmCopyRotatePixmap(pGC->stipple, &pGC->pRotatedPixmap,
 
317
                                                                                                xrot, yrot);
 
318
                                        new_pix = TRUE;
 
319
                                }
 
320
                }
 
321
                /* destroy any previously rotated tile or stipple */
 
322
                if (!new_pix && pGC->pRotatedPixmap) {
 
323
                        (*pDrawable->pScreen->DestroyPixmap)(pGC->pRotatedPixmap);
 
324
                        pGC->pRotatedPixmap = (PixmapPtr)NULL;
 
325
                }
 
326
        }
 
327
 
 
328
        /*
 
329
         * duck out here when the GC is unchanged
 
330
         */
 
331
 
 
332
        if (!changes)
 
333
                return;
 
334
 
 
335
        if (new_rrop || new_fill) {
 
336
                ilbmReduceRop(pGC->alu, pGC->fgPixel, pGC->planemask, pDrawable->depth,
 
337
                                                  devPriv->rrops);
 
338
                ilbmReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask,
 
339
                                                                                pGC->depth, devPriv->rropOS);
 
340
                new_fill = TRUE;
 
341
        }
 
342
 
 
343
        if (new_line || new_fill || new_text) {
 
344
                if (!pGC->ops->devPrivate.val) {
 
345
                        pGC->ops = miCreateGCOps(pGC->ops);
 
346
                        pGC->ops->devPrivate.val = 1;
 
347
                }
 
348
        }
 
349
 
 
350
        if (new_line || new_fill) {
 
351
                if (pGC->lineWidth == 0) {
 
352
                        if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid)
 
353
                                pGC->ops->PolyArc = ilbmZeroPolyArcSS;
 
354
                        else
 
355
                                pGC->ops->PolyArc = miZeroPolyArc;
 
356
                } else
 
357
                        pGC->ops->PolyArc = miPolyArc;
 
358
                if (pGC->lineStyle == LineSolid) {
 
359
                        if (pGC->lineWidth == 0) {
 
360
                                if (pGC->fillStyle == FillSolid) {
 
361
                                        pGC->ops->PolySegment = ilbmSegmentSS;
 
362
                                        pGC->ops->Polylines = ilbmLineSS;
 
363
                                } else {
 
364
                                        pGC->ops->PolySegment = miPolySegment;
 
365
                                        pGC->ops->Polylines = miZeroLine;
 
366
                                }
 
367
                        } else {
 
368
                                pGC->ops->PolySegment = miPolySegment;
 
369
                                pGC->ops->Polylines = miWideLine;
 
370
                        }
 
371
                } else {
 
372
                        if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid) {
 
373
                                pGC->ops->PolySegment = ilbmSegmentSD;
 
374
                                pGC->ops->Polylines = ilbmLineSD;
 
375
                        } else {
 
376
                                pGC->ops->PolySegment = miPolySegment;
 
377
                                pGC->ops->Polylines = miWideDash;
 
378
                        }
 
379
                }
 
380
        }
 
381
 
 
382
        if (new_text || new_fill) {
 
383
                if ((pGC->font) &&
 
384
                        (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
 
385
                         FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
 
386
                         FONTMINBOUNDS(pGC->font,characterWidth) < 0)) {
 
387
                        pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
 
388
                        pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
 
389
                } else {
 
390
                        /* special case ImageGlyphBlt for terminal emulator fonts */
 
391
                        if ((pGC->font) &&
 
392
                                TERMINALFONT(pGC->font)) {
 
393
                                pGC->ops->ImageGlyphBlt = ilbmTEGlyphBlt;
 
394
                        } else {
 
395
                                pGC->ops->ImageGlyphBlt = ilbmImageGlyphBlt;
 
396
                        }
 
397
 
 
398
                        /* now do PolyGlyphBlt */
 
399
                        if (pGC->fillStyle == FillSolid) {
 
400
                                pGC->ops->PolyGlyphBlt = ilbmPolyGlyphBlt;
 
401
                        } else {
 
402
                                pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
 
403
                        }
 
404
                }
 
405
        }
 
406
 
 
407
        if (new_fill) {
 
408
                /* install a suitable fillspans and pushpixels */
 
409
                pGC->ops->PushPixels = ilbmPushPixels;
 
410
                pGC->ops->FillPolygon = miFillPolygon;
 
411
                pGC->ops->PolyFillArc = miPolyFillArc;
 
412
 
 
413
                switch (pGC->fillStyle) {
 
414
                        case FillSolid:
 
415
                                pGC->ops->FillSpans = ilbmSolidFS;
 
416
                                pGC->ops->FillPolygon = ilbmFillPolygonSolid;
 
417
                                pGC->ops->PolyFillArc = ilbmPolyFillArcSolid;
 
418
                                break;
 
419
                        case FillTiled:
 
420
                                if (pGC->pRotatedPixmap)
 
421
                                        pGC->ops->FillSpans = ilbmTileFS;
 
422
                                else
 
423
                                        pGC->ops->FillSpans = ilbmUnnaturalTileFS;
 
424
                                break;
 
425
                        case FillOpaqueStippled:
 
426
                                if (pGC->pRotatedPixmap)
 
427
                                        pGC->ops->FillSpans = ilbmOpaqueStippleFS;
 
428
                                else
 
429
                                        pGC->ops->FillSpans = ilbmUnnaturalOpaqueStippleFS;
 
430
                                break;
 
431
 
 
432
                        case FillStippled:
 
433
                                if (pGC->pRotatedPixmap)
 
434
                                        pGC->ops->FillSpans = ilbmStippleFS;
 
435
                                else
 
436
                                        pGC->ops->FillSpans = ilbmUnnaturalStippleFS;
 
437
                                break;
 
438
                }
 
439
        } /* end of new_fill */
 
440
}
 
441
 
 
442
void
 
443
ilbmDestroyGC(pGC)
 
444
        GCPtr pGC;
 
445
{
 
446
        if (pGC->pRotatedPixmap)
 
447
                (*pGC->pScreen->DestroyPixmap)(pGC->pRotatedPixmap);
 
448
        if (pGC->freeCompClip)
 
449
                REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
 
450
        miDestroyGCOps(pGC->ops);
 
451
}
 
452
 
 
453
/* table to map alu(src, dst) to alu(~src, dst) */
 
454
int ilbmInverseAlu[16] = {
 
455
                GXclear,
 
456
                GXandInverted,
 
457
                GXnor,
 
458
                GXcopyInverted,
 
459
                GXand,
 
460
                GXnoop,
 
461
                GXequiv,
 
462
                GXorInverted,
 
463
                GXandReverse,
 
464
                GXxor,
 
465
                GXinvert,
 
466
                GXnand,
 
467
                GXcopy,
 
468
                GXor,
 
469
                GXorReverse,
 
470
                GXset
 
471
};
 
472
 
 
473
void
 
474
ilbmReduceOpaqueStipple(fg, bg, planemask, depth, rop)
 
475
register PixelType fg;
 
476
register PixelType bg;
 
477
register unsigned long planemask;
 
478
int depth;
 
479
register unsigned char *rop;
 
480
{
 
481
        register int d;
 
482
        register Pixel mask = 1;
 
483
 
 
484
        bg ^= fg;
 
485
 
 
486
        for (d = 0; d < depth; d++, mask <<= 1) {
 
487
                if (!(planemask & mask))
 
488
                        rop[d] = RROP_NOP;
 
489
                else if (!(bg & mask)) {
 
490
                        /* Both fg and bg have a 0 or 1 in this plane */
 
491
                        if (fg & mask)
 
492
                                rop[d] = RROP_WHITE;
 
493
                        else
 
494
                                rop[d] = RROP_BLACK;
 
495
                } else {
 
496
                        /* Both fg and bg have different bits on this plane */
 
497
                        if (fg & mask)
 
498
                                rop[d] = RROP_COPY;
 
499
                        else
 
500
                                rop[d] = RROP_INVERT;
 
501
                }
 
502
        }
 
503
}
 
504
 
 
505
void
 
506
ilbmReduceRop(alu, src, planemask, depth, rop)
 
507
        register int alu;
 
508
        register Pixel src;
 
509
        register unsigned long planemask;
 
510
        int depth;
 
511
        register unsigned char *rop;
 
512
{
 
513
        register int d;
 
514
        register Pixel mask = 1;
 
515
 
 
516
        for (d = 0; d < depth; d++, mask <<= 1) {
 
517
                if (!(planemask & mask))
 
518
                        rop[d] = RROP_NOP;
 
519
                else if ((src & mask) == 0)             /* src is black */
 
520
                        switch (alu) {
 
521
                                case GXclear:
 
522
                                        rop[d] = RROP_BLACK;
 
523
                                        break;
 
524
                                case GXand:
 
525
                                        rop[d] = RROP_BLACK;
 
526
                                        break;
 
527
                                case GXandReverse:
 
528
                                        rop[d] = RROP_BLACK;
 
529
                                        break;
 
530
                                case GXcopy:
 
531
                                        rop[d] = RROP_BLACK;
 
532
                                        break;
 
533
                                case GXandInverted:
 
534
                                        rop[d] = RROP_NOP;
 
535
                                        break;
 
536
                                case GXnoop:
 
537
                                        rop[d] = RROP_NOP;
 
538
                                        break;
 
539
                                case GXxor:
 
540
                                        rop[d] = RROP_NOP;
 
541
                                        break;
 
542
                                case GXor:
 
543
                                        rop[d] = RROP_NOP;
 
544
                                        break;
 
545
                                case GXnor:
 
546
                                        rop[d] = RROP_INVERT;
 
547
                                        break;
 
548
                                case GXequiv:
 
549
                                        rop[d] = RROP_INVERT;
 
550
                                        break;
 
551
                                case GXinvert:
 
552
                                        rop[d] = RROP_INVERT;
 
553
                                        break;
 
554
                                case GXorReverse:
 
555
                                        rop[d] = RROP_INVERT;
 
556
                                        break;
 
557
                                case GXcopyInverted:
 
558
                                        rop[d] = RROP_WHITE;
 
559
                                        break;
 
560
                                case GXorInverted:
 
561
                                        rop[d] = RROP_WHITE;
 
562
                                        break;
 
563
                                case GXnand:
 
564
                                        rop[d] = RROP_WHITE;
 
565
                                        break;
 
566
                                case GXset:
 
567
                                        rop[d] = RROP_WHITE;
 
568
                                        break;
 
569
                        }
 
570
                else /* src is white */
 
571
                        switch (alu) {
 
572
                                case GXclear:
 
573
                                        rop[d] = RROP_BLACK;
 
574
                                        break;
 
575
                                case GXand:
 
576
                                        rop[d] = RROP_NOP;
 
577
                                        break;
 
578
                                case GXandReverse:
 
579
                                        rop[d] = RROP_INVERT;
 
580
                                        break;
 
581
                                case GXcopy:
 
582
                                        rop[d] = RROP_WHITE;
 
583
                                        break;
 
584
                                case GXandInverted:
 
585
                                        rop[d] = RROP_BLACK;
 
586
                                        break;
 
587
                                case GXnoop:
 
588
                                        rop[d] = RROP_NOP;
 
589
                                        break;
 
590
                                case GXxor:
 
591
                                        rop[d] = RROP_INVERT;
 
592
                                        break;
 
593
                                case GXor:
 
594
                                        rop[d] = RROP_WHITE;
 
595
                                        break;
 
596
                                case GXnor:
 
597
                                        rop[d] = RROP_BLACK;
 
598
                                        break;
 
599
                                case GXequiv:
 
600
                                        rop[d] = RROP_NOP;
 
601
                                        break;
 
602
                                case GXinvert:
 
603
                                        rop[d] = RROP_INVERT;
 
604
                                        break;
 
605
                                case GXorReverse:
 
606
                                        rop[d] = RROP_WHITE;
 
607
                                        break;
 
608
                                case GXcopyInverted:
 
609
                                        rop[d] = RROP_BLACK;
 
610
                                        break;
 
611
                                case GXorInverted:
 
612
                                        rop[d] = RROP_NOP;
 
613
                                        break;
 
614
                                case GXnand:
 
615
                                        rop[d] = RROP_INVERT;
 
616
                                        break;
 
617
                                case GXset:
 
618
                                        rop[d] = RROP_WHITE;
 
619
                                        break;
 
620
                        }
 
621
        }
 
622
}
 
623
 
 
624
void
 
625
ilbmComputeCompositeClip(pGC, pDrawable)
 
626
        GCPtr pGC;
 
627
        DrawablePtr pDrawable;
 
628
{
 
629
        ScreenPtr pScreen = pGC->pScreen;
 
630
 
 
631
        if (pDrawable->type == DRAWABLE_WINDOW) {
 
632
                WindowPtr pWin = (WindowPtr) pDrawable;
 
633
                RegionPtr pregWin;
 
634
                Bool freeTmpClip, freeCompClip;
 
635
 
 
636
        if (pGC->subWindowMode == IncludeInferiors) {
 
637
                pregWin = NotClippedByChildren(pWin);
 
638
                freeTmpClip = TRUE;
 
639
        } else {
 
640
                pregWin = &pWin->clipList;
 
641
                freeTmpClip = FALSE;
 
642
        }
 
643
        freeCompClip = pGC->freeCompClip;
 
644
 
 
645
        /*
 
646
         * if there is no client clip, we can get by with just keeping the
 
647
         * pointer we got, and remembering whether or not should destroy (or
 
648
         * maybe re-use) it later.  this way, we avoid unnecessary copying of
 
649
         * regions.  (this wins especially if many clients clip by children
 
650
         * and have no client clip.)
 
651
         */
 
652
        if (pGC->clientClipType == CT_NONE) {
 
653
                if (freeCompClip)
 
654
                        REGION_DESTROY(pScreen, pGC->pCompositeClip);
 
655
                        pGC->pCompositeClip = pregWin;
 
656
                        pGC->freeCompClip = freeTmpClip;
 
657
                } else {
 
658
                        /*
 
659
                         * we need one 'real' region to put into the composite clip. if
 
660
                         * pregWin the current composite clip are real, we can get rid of
 
661
                         * one. if pregWin is real and the current composite clip isn't,
 
662
                         * use pregWin for the composite clip. if the current composite
 
663
                         * clip is real and pregWin isn't, use the current composite
 
664
                         * clip. if neither is real, create a new region.
 
665
                         */
 
666
 
 
667
                        REGION_TRANSLATE(pScreen, pGC->clientClip,
 
668
                        pDrawable->x + pGC->clipOrg.x,
 
669
                        pDrawable->y + pGC->clipOrg.y);
 
670
 
 
671
                        if (freeCompClip) {
 
672
                                REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip, pregWin,
 
673
                                                                          pGC->clientClip);
 
674
                                if (freeTmpClip)
 
675
                                        REGION_DESTROY(pScreen, pregWin);
 
676
                        } else if (freeTmpClip) {
 
677
                                REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip);
 
678
                                pGC->pCompositeClip = pregWin;
 
679
                        } else {
 
680
                                pGC->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
 
681
                                REGION_INTERSECT(pScreen, pGC->pCompositeClip,
 
682
                                pregWin, pGC->clientClip);
 
683
                        }
 
684
                        pGC->freeCompClip = TRUE;
 
685
                        REGION_TRANSLATE(pScreen, pGC->clientClip,
 
686
                        -(pDrawable->x + pGC->clipOrg.x),
 
687
                        -(pDrawable->y + pGC->clipOrg.y));
 
688
                }
 
689
        }       /* end of composite clip for a window */
 
690
        else {
 
691
                BoxRec pixbounds;
 
692
 
 
693
                /* XXX should we translate by drawable.x/y here ? */
 
694
                pixbounds.x1 = 0;
 
695
                pixbounds.y1 = 0;
 
696
                pixbounds.x2 = pDrawable->width;
 
697
                pixbounds.y2 = pDrawable->height;
 
698
 
 
699
                if (pGC->freeCompClip) {
 
700
                        REGION_RESET(pScreen, pGC->pCompositeClip, &pixbounds);
 
701
                } else {
 
702
                        pGC->freeCompClip = TRUE;
 
703
                        pGC->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
 
704
                }
 
705
 
 
706
                if (pGC->clientClipType == CT_REGION) {
 
707
                        REGION_TRANSLATE(pScreen, pGC->pCompositeClip, -pGC->clipOrg.x,
 
708
                                                                  -pGC->clipOrg.y);
 
709
                        REGION_INTERSECT(pScreen, pGC->pCompositeClip,
 
710
                                                                  pGC->pCompositeClip, pGC->clientClip);
 
711
                        REGION_TRANSLATE(pScreen, pGC->pCompositeClip, pGC->clipOrg.x,
 
712
                                                                  pGC->clipOrg.y);
 
713
                }
 
714
        }       /* end of composite clip for pixmap */
 
715
} /* end ilbmComputeCompositeClip */