]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbfillrct.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbfillrct.c
1 /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
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: mfbfillrct.c,v 5.10 94/04/17 20:28:21 dpw Exp $ */
50 #include "X.h"
51 #include "Xprotostr.h"
52 #include "pixmapstr.h"
53 #include "gcstruct.h"
54 #include "windowstr.h"
55 #include "miscstruct.h"
56 #include "regionstr.h"
57 #include "scrnintstr.h"
58
59 #include "mfb.h"
60 #include "maskbits.h"
61
62 #define MODEQ(a, b) ((a) %= (b))
63 void mfbPaintOddSize();
64
65 /* 
66     filled rectangles.
67     translate the rectangles, clip them, and call the
68 helper function in the GC.
69 */
70
71 #define NUM_STACK_RECTS 1024
72
73 void
74 mfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
75     DrawablePtr pDrawable;
76     GCPtr       pGC;
77     int         nrectFill;      /* number of rectangles to fill */
78     xRectangle  *prectInit;     /* Pointer to first rectangle to fill */
79 {
80     xRectangle      *prect;
81     RegionPtr       prgnClip;
82     register BoxPtr pbox;
83     register BoxPtr pboxClipped;
84     BoxPtr          pboxClippedBase;
85     BoxPtr          pextent;
86     BoxRec          stackRects[NUM_STACK_RECTS];
87     int             numRects;
88     int             n;
89     int             xorg, yorg;
90     mfbPrivGC   *priv;
91     int alu;
92     void (* pfn) ();
93     PixmapPtr ppix;
94
95     if (!(pGC->planemask & 1))
96         return;
97
98     priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
99     alu = priv->ropFillArea;
100     pfn = priv->FillArea;
101     ppix = priv->pRotatedPixmap;
102     prgnClip = priv->pCompositeClip;
103
104     prect = prectInit;
105     xorg = pDrawable->x;
106     yorg = pDrawable->y;
107     if (xorg || yorg)
108     {
109         prect = prectInit;
110         n = nrectFill;
111         Duff (n, prect->x += xorg; prect->y += yorg; prect++);
112     }
113
114
115     prect = prectInit;
116
117     numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
118     if (numRects > NUM_STACK_RECTS)
119     {
120         pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
121         if (!pboxClippedBase)
122             return;
123     }
124     else
125         pboxClippedBase = stackRects;
126
127     pboxClipped = pboxClippedBase;
128         
129     if (REGION_NUM_RECTS(prgnClip) == 1)
130     {
131         int x1, y1, x2, y2, bx2, by2;
132
133         pextent = REGION_RECTS(prgnClip);
134         x1 = pextent->x1;
135         y1 = pextent->y1;
136         x2 = pextent->x2;
137         y2 = pextent->y2;
138         while (nrectFill--)
139         {
140             if ((pboxClipped->x1 = prect->x) < x1)
141                 pboxClipped->x1 = x1;
142     
143             if ((pboxClipped->y1 = prect->y) < y1)
144                 pboxClipped->y1 = y1;
145     
146             bx2 = (int) prect->x + (int) prect->width;
147             if (bx2 > x2)
148                 bx2 = x2;
149             pboxClipped->x2 = bx2;
150     
151             by2 = (int) prect->y + (int) prect->height;
152             if (by2 > y2)
153                 by2 = y2;
154             pboxClipped->y2 = by2;
155
156             prect++;
157             if ((pboxClipped->x1 < pboxClipped->x2) &&
158                 (pboxClipped->y1 < pboxClipped->y2))
159             {
160                 pboxClipped++;
161             }
162         }
163     }
164     else
165     {
166         int x1, y1, x2, y2, bx2, by2;
167
168         pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
169         x1 = pextent->x1;
170         y1 = pextent->y1;
171         x2 = pextent->x2;
172         y2 = pextent->y2;
173         while (nrectFill--)
174         {
175             BoxRec box;
176     
177             if ((box.x1 = prect->x) < x1)
178                 box.x1 = x1;
179     
180             if ((box.y1 = prect->y) < y1)
181                 box.y1 = y1;
182     
183             bx2 = (int) prect->x + (int) prect->width;
184             if (bx2 > x2)
185                 bx2 = x2;
186             box.x2 = bx2;
187     
188             by2 = (int) prect->y + (int) prect->height;
189             if (by2 > y2)
190                 by2 = y2;
191             box.y2 = by2;
192     
193             prect++;
194     
195             if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
196                 continue;
197     
198             n = REGION_NUM_RECTS (prgnClip);
199             pbox = REGION_RECTS(prgnClip);
200     
201             /* clip the rectangle to each box in the clip region
202                this is logically equivalent to calling Intersect()
203             */
204             while(n--)
205             {
206                 pboxClipped->x1 = max(box.x1, pbox->x1);
207                 pboxClipped->y1 = max(box.y1, pbox->y1);
208                 pboxClipped->x2 = min(box.x2, pbox->x2);
209                 pboxClipped->y2 = min(box.y2, pbox->y2);
210                 pbox++;
211
212                 /* see if clipping left anything */
213                 if(pboxClipped->x1 < pboxClipped->x2 && 
214                    pboxClipped->y1 < pboxClipped->y2)
215                 {
216                     pboxClipped++;
217                 }
218             }
219         }
220     }
221     if (pboxClipped != pboxClippedBase)
222         (*pfn) (pDrawable,pboxClipped-pboxClippedBase, pboxClippedBase, alu, ppix);
223     if (pboxClippedBase != stackRects)
224         DEALLOCATE_LOCAL(pboxClippedBase);
225 }