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

« back to all changes in this revision

Viewing changes to cfb/cfbfillrct.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
/*
 
2
 * Fill rectangles.
 
3
 */
 
4
/* $XFree86: xc/programs/Xserver/cfb/cfbfillrct.c,v 3.7 2001/01/17 22:36:35 dawes Exp $ */
 
5
 
 
6
/*
 
7
 
 
8
Copyright 1989, 1998  The Open Group
 
9
 
 
10
Permission to use, copy, modify, distribute, and sell this software and its
 
11
documentation for any purpose is hereby granted without fee, provided that
 
12
the above copyright notice appear in all copies and that both that
 
13
copyright notice and this permission notice appear in supporting
 
14
documentation.
 
15
 
 
16
The above copyright notice and this permission notice shall be included in
 
17
all copies or substantial portions of the Software.
 
18
 
 
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
22
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
23
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
24
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 
 
26
Except as contained in this notice, the name of The Open Group shall not be
 
27
used in advertising or otherwise to promote the sale, use or other dealings
 
28
in this Software without prior written authorization from The Open Group.
 
29
*/
 
30
 
 
31
/* $Xorg: cfbfillrct.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */
 
32
 
 
33
#ifdef HAVE_DIX_CONFIG_H
 
34
#include <dix-config.h>
 
35
#endif
 
36
 
 
37
#include <X11/X.h>
 
38
#include <X11/Xmd.h>
 
39
#include "servermd.h"
 
40
#include "gcstruct.h"
 
41
#include "window.h"
 
42
#include "pixmapstr.h"
 
43
#include "scrnintstr.h"
 
44
#include "windowstr.h"
 
45
#include "mi.h"
 
46
#include "cfb.h"
 
47
#include "cfbmskbits.h"
 
48
#include "mergerop.h"
 
49
 
 
50
 
 
51
void
 
52
cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
 
53
    DrawablePtr pDrawable;
 
54
    int         n;
 
55
    BoxPtr      rects;
 
56
    PixmapPtr   tile;
 
57
    int         xrot, yrot;
 
58
{
 
59
#if PSZ == 24
 
60
    if (tile->drawable.width & 3)
 
61
#else
 
62
    if (tile->drawable.width & PIM)
 
63
#endif
 
64
        cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
 
65
    else
 
66
        cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
 
67
}
 
68
 
 
69
void
 
70
cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
 
71
    DrawablePtr pDrawable;
 
72
    GCPtr       pGC;
 
73
    int         nBox;
 
74
    BoxPtr      pBox;
 
75
{
 
76
    int xrot, yrot;
 
77
    void    (*fill)(DrawablePtr, int, BoxPtr, PixmapPtr, int, int, int, unsigned long);
 
78
 
 
79
    xrot = pDrawable->x + pGC->patOrg.x;
 
80
    yrot = pDrawable->y + pGC->patOrg.y;
 
81
#if PSZ == 24
 
82
    if (pGC->tile.pixmap->drawable.width & 3)
 
83
#else
 
84
    if (pGC->tile.pixmap->drawable.width & PIM)
 
85
#endif
 
86
    {
 
87
        fill = cfbFillBoxTileOddGeneral;
 
88
        if ((pGC->planemask & PMSK) == PMSK)
 
89
        {
 
90
            if (pGC->alu == GXcopy)
 
91
                fill = cfbFillBoxTileOddCopy;
 
92
        }
 
93
    }
 
94
    else
 
95
    {
 
96
        fill = cfbFillBoxTile32sGeneral;
 
97
        if ((pGC->planemask & PMSK) == PMSK)
 
98
        {
 
99
            if (pGC->alu == GXcopy)
 
100
                fill = cfbFillBoxTile32sCopy;
 
101
        }
 
102
    }
 
103
    (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
 
104
}
 
105
 
 
106
#define NUM_STACK_RECTS 1024
 
107
 
 
108
void
 
109
cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
 
110
    DrawablePtr pDrawable;
 
111
    register GCPtr pGC;
 
112
    int         nrectFill;      /* number of rectangles to fill */
 
113
    xRectangle  *prectInit;     /* Pointer to first rectangle to fill */
 
114
{
 
115
    xRectangle      *prect;
 
116
    RegionPtr       prgnClip;
 
117
    register BoxPtr pbox;
 
118
    register BoxPtr pboxClipped;
 
119
    BoxPtr          pboxClippedBase;
 
120
    BoxPtr          pextent;
 
121
    BoxRec          stackRects[NUM_STACK_RECTS];
 
122
    cfbPrivGC       *priv;
 
123
    int             numRects;
 
124
    void            (*BoxFill)(DrawablePtr, GCPtr, int, BoxPtr);
 
125
    int             n;
 
126
    int             xorg, yorg;
 
127
 
 
128
#if PSZ != 8
 
129
    if ((pGC->fillStyle == FillStippled) ||
 
130
        (pGC->fillStyle == FillOpaqueStippled)) {
 
131
       miPolyFillRect(pDrawable, pGC, nrectFill, prectInit);
 
132
       return;
 
133
    }
 
134
#endif
 
135
 
 
136
    priv = cfbGetGCPrivate(pGC);
 
137
    prgnClip = pGC->pCompositeClip;
 
138
 
 
139
    BoxFill = 0;
 
140
    switch (pGC->fillStyle)
 
141
    {
 
142
    case FillSolid:
 
143
        switch (priv->rop) {
 
144
        case GXcopy:
 
145
            BoxFill = cfbFillRectSolidCopy;
 
146
            break;
 
147
        case GXxor:
 
148
            BoxFill = cfbFillRectSolidXor;
 
149
            break;
 
150
        default:
 
151
            BoxFill = cfbFillRectSolidGeneral;
 
152
            break;
 
153
        }
 
154
        break;
 
155
    case FillTiled:
 
156
        if (!pGC->pRotatedPixmap)
 
157
            BoxFill = cfbFillRectTileOdd;
 
158
        else
 
159
        {
 
160
            if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
 
161
                BoxFill = cfbFillRectTile32Copy;
 
162
            else
 
163
                BoxFill = cfbFillRectTile32General;
 
164
        }
 
165
        break;
 
166
#if PSZ == 8
 
167
    case FillStippled:
 
168
        if (!pGC->pRotatedPixmap)
 
169
            BoxFill = cfb8FillRectStippledUnnatural;
 
170
        else
 
171
            BoxFill = cfb8FillRectTransparentStippled32;
 
172
        break;
 
173
    case FillOpaqueStippled:
 
174
        if (!pGC->pRotatedPixmap)
 
175
            BoxFill = cfb8FillRectStippledUnnatural;
 
176
        else
 
177
            BoxFill = cfb8FillRectOpaqueStippled32;
 
178
        break;
 
179
#endif
 
180
    }
 
181
    prect = prectInit;
 
182
    xorg = pDrawable->x;
 
183
    yorg = pDrawable->y;
 
184
    if (xorg || yorg)
 
185
    {
 
186
        prect = prectInit;
 
187
        n = nrectFill;
 
188
        while(n--)
 
189
        {
 
190
            prect->x += xorg;
 
191
            prect->y += yorg;
 
192
            prect++;
 
193
        }
 
194
    }
 
195
 
 
196
    prect = prectInit;
 
197
 
 
198
    numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
 
199
    if (numRects > NUM_STACK_RECTS)
 
200
    {
 
201
        pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
 
202
        if (!pboxClippedBase)
 
203
            return;
 
204
    }
 
205
    else
 
206
        pboxClippedBase = stackRects;
 
207
 
 
208
    pboxClipped = pboxClippedBase;
 
209
        
 
210
    if (REGION_NUM_RECTS(prgnClip) == 1)
 
211
    {
 
212
        int x1, y1, x2, y2, bx2, by2;
 
213
 
 
214
        pextent = REGION_RECTS(prgnClip);
 
215
        x1 = pextent->x1;
 
216
        y1 = pextent->y1;
 
217
        x2 = pextent->x2;
 
218
        y2 = pextent->y2;
 
219
        while (nrectFill--)
 
220
        {
 
221
            if ((pboxClipped->x1 = prect->x) < x1)
 
222
                pboxClipped->x1 = x1;
 
223
    
 
224
            if ((pboxClipped->y1 = prect->y) < y1)
 
225
                pboxClipped->y1 = y1;
 
226
    
 
227
            bx2 = (int) prect->x + (int) prect->width;
 
228
            if (bx2 > x2)
 
229
                bx2 = x2;
 
230
            pboxClipped->x2 = bx2;
 
231
    
 
232
            by2 = (int) prect->y + (int) prect->height;
 
233
            if (by2 > y2)
 
234
                by2 = y2;
 
235
            pboxClipped->y2 = by2;
 
236
 
 
237
            prect++;
 
238
            if ((pboxClipped->x1 < pboxClipped->x2) &&
 
239
                (pboxClipped->y1 < pboxClipped->y2))
 
240
            {
 
241
                pboxClipped++;
 
242
            }
 
243
        }
 
244
    }
 
245
    else
 
246
    {
 
247
        int x1, y1, x2, y2, bx2, by2;
 
248
 
 
249
        pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
 
250
        x1 = pextent->x1;
 
251
        y1 = pextent->y1;
 
252
        x2 = pextent->x2;
 
253
        y2 = pextent->y2;
 
254
        while (nrectFill--)
 
255
        {
 
256
            BoxRec box;
 
257
    
 
258
            if ((box.x1 = prect->x) < x1)
 
259
                box.x1 = x1;
 
260
    
 
261
            if ((box.y1 = prect->y) < y1)
 
262
                box.y1 = y1;
 
263
    
 
264
            bx2 = (int) prect->x + (int) prect->width;
 
265
            if (bx2 > x2)
 
266
                bx2 = x2;
 
267
            box.x2 = bx2;
 
268
    
 
269
            by2 = (int) prect->y + (int) prect->height;
 
270
            if (by2 > y2)
 
271
                by2 = y2;
 
272
            box.y2 = by2;
 
273
    
 
274
            prect++;
 
275
    
 
276
            if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
 
277
                continue;
 
278
    
 
279
            n = REGION_NUM_RECTS (prgnClip);
 
280
            pbox = REGION_RECTS(prgnClip);
 
281
    
 
282
            /* clip the rectangle to each box in the clip region
 
283
               this is logically equivalent to calling Intersect()
 
284
            */
 
285
            while(n--)
 
286
            {
 
287
                pboxClipped->x1 = max(box.x1, pbox->x1);
 
288
                pboxClipped->y1 = max(box.y1, pbox->y1);
 
289
                pboxClipped->x2 = min(box.x2, pbox->x2);
 
290
                pboxClipped->y2 = min(box.y2, pbox->y2);
 
291
                pbox++;
 
292
 
 
293
                /* see if clipping left anything */
 
294
                if(pboxClipped->x1 < pboxClipped->x2 && 
 
295
                   pboxClipped->y1 < pboxClipped->y2)
 
296
                {
 
297
                    pboxClipped++;
 
298
                }
 
299
            }
 
300
        }
 
301
    }
 
302
    if (pboxClipped != pboxClippedBase)
 
303
        (*BoxFill) (pDrawable, pGC,
 
304
                    pboxClipped-pboxClippedBase, pboxClippedBase);
 
305
    if (pboxClippedBase != stackRects)
 
306
        DEALLOCATE_LOCAL(pboxClippedBase);
 
307
}