4
/* $XFree86: xc/programs/Xserver/cfb/cfbfillrct.c,v 3.7 2001/01/17 22:36:35 dawes Exp $ */
8
Copyright 1989, 1998 The Open Group
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
16
The above copyright notice and this permission notice shall be included in
17
all copies or substantial portions of the Software.
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.
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.
31
/* $Xorg: cfbfillrct.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */
33
#ifdef HAVE_DIX_CONFIG_H
34
#include <dix-config.h>
42
#include "pixmapstr.h"
43
#include "scrnintstr.h"
44
#include "windowstr.h"
47
#include "cfbmskbits.h"
52
cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
53
DrawablePtr pDrawable;
60
if (tile->drawable.width & 3)
62
if (tile->drawable.width & PIM)
64
cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
66
cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
70
cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
71
DrawablePtr pDrawable;
77
void (*fill)(DrawablePtr, int, BoxPtr, PixmapPtr, int, int, int, unsigned long);
79
xrot = pDrawable->x + pGC->patOrg.x;
80
yrot = pDrawable->y + pGC->patOrg.y;
82
if (pGC->tile.pixmap->drawable.width & 3)
84
if (pGC->tile.pixmap->drawable.width & PIM)
87
fill = cfbFillBoxTileOddGeneral;
88
if ((pGC->planemask & PMSK) == PMSK)
90
if (pGC->alu == GXcopy)
91
fill = cfbFillBoxTileOddCopy;
96
fill = cfbFillBoxTile32sGeneral;
97
if ((pGC->planemask & PMSK) == PMSK)
99
if (pGC->alu == GXcopy)
100
fill = cfbFillBoxTile32sCopy;
103
(*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
106
#define NUM_STACK_RECTS 1024
109
cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
110
DrawablePtr pDrawable;
112
int nrectFill; /* number of rectangles to fill */
113
xRectangle *prectInit; /* Pointer to first rectangle to fill */
117
register BoxPtr pbox;
118
register BoxPtr pboxClipped;
119
BoxPtr pboxClippedBase;
121
BoxRec stackRects[NUM_STACK_RECTS];
124
void (*BoxFill)(DrawablePtr, GCPtr, int, BoxPtr);
129
if ((pGC->fillStyle == FillStippled) ||
130
(pGC->fillStyle == FillOpaqueStippled)) {
131
miPolyFillRect(pDrawable, pGC, nrectFill, prectInit);
136
priv = cfbGetGCPrivate(pGC);
137
prgnClip = pGC->pCompositeClip;
140
switch (pGC->fillStyle)
145
BoxFill = cfbFillRectSolidCopy;
148
BoxFill = cfbFillRectSolidXor;
151
BoxFill = cfbFillRectSolidGeneral;
156
if (!pGC->pRotatedPixmap)
157
BoxFill = cfbFillRectTileOdd;
160
if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
161
BoxFill = cfbFillRectTile32Copy;
163
BoxFill = cfbFillRectTile32General;
168
if (!pGC->pRotatedPixmap)
169
BoxFill = cfb8FillRectStippledUnnatural;
171
BoxFill = cfb8FillRectTransparentStippled32;
173
case FillOpaqueStippled:
174
if (!pGC->pRotatedPixmap)
175
BoxFill = cfb8FillRectStippledUnnatural;
177
BoxFill = cfb8FillRectOpaqueStippled32;
198
numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
199
if (numRects > NUM_STACK_RECTS)
201
pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
202
if (!pboxClippedBase)
206
pboxClippedBase = stackRects;
208
pboxClipped = pboxClippedBase;
210
if (REGION_NUM_RECTS(prgnClip) == 1)
212
int x1, y1, x2, y2, bx2, by2;
214
pextent = REGION_RECTS(prgnClip);
221
if ((pboxClipped->x1 = prect->x) < x1)
222
pboxClipped->x1 = x1;
224
if ((pboxClipped->y1 = prect->y) < y1)
225
pboxClipped->y1 = y1;
227
bx2 = (int) prect->x + (int) prect->width;
230
pboxClipped->x2 = bx2;
232
by2 = (int) prect->y + (int) prect->height;
235
pboxClipped->y2 = by2;
238
if ((pboxClipped->x1 < pboxClipped->x2) &&
239
(pboxClipped->y1 < pboxClipped->y2))
247
int x1, y1, x2, y2, bx2, by2;
249
pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
258
if ((box.x1 = prect->x) < x1)
261
if ((box.y1 = prect->y) < y1)
264
bx2 = (int) prect->x + (int) prect->width;
269
by2 = (int) prect->y + (int) prect->height;
276
if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
279
n = REGION_NUM_RECTS (prgnClip);
280
pbox = REGION_RECTS(prgnClip);
282
/* clip the rectangle to each box in the clip region
283
this is logically equivalent to calling Intersect()
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);
293
/* see if clipping left anything */
294
if(pboxClipped->x1 < pboxClipped->x2 &&
295
pboxClipped->y1 < pboxClipped->y2)
302
if (pboxClipped != pboxClippedBase)
303
(*BoxFill) (pDrawable, pGC,
304
pboxClipped-pboxClippedBase, pboxClippedBase);
305
if (pboxClippedBase != stackRects)
306
DEALLOCATE_LOCAL(pboxClippedBase);