xref: /OK3568_Linux_fs/external/xserver/fb/fbfill.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 1998 Keith Packard
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun  * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun  * the above copyright notice appear in all copies and that both that
7*4882a593Smuzhiyun  * copyright notice and this permission notice appear in supporting
8*4882a593Smuzhiyun  * documentation, and that the name of Keith Packard not be used in
9*4882a593Smuzhiyun  * advertising or publicity pertaining to distribution of the software without
10*4882a593Smuzhiyun  * specific, written prior permission.  Keith Packard makes no
11*4882a593Smuzhiyun  * representations about the suitability of this software for any purpose.  It
12*4882a593Smuzhiyun  * is provided "as is" without express or implied warranty.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20*4882a593Smuzhiyun  * PERFORMANCE OF THIS SOFTWARE.
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
24*4882a593Smuzhiyun #include <dix-config.h>
25*4882a593Smuzhiyun #endif
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include "fb.h"
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun static void
fbTile(FbBits * dst,FbStride dstStride,int dstX,int width,int height,FbBits * tile,FbStride tileStride,int tileWidth,int tileHeight,int alu,FbBits pm,int bpp,int xRot,int yRot)30*4882a593Smuzhiyun fbTile(FbBits * dst, FbStride dstStride, int dstX, int width, int height,
31*4882a593Smuzhiyun        FbBits * tile, FbStride tileStride, int tileWidth, int tileHeight,
32*4882a593Smuzhiyun        int alu, FbBits pm, int bpp, int xRot, int yRot)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun     int tileX, tileY;
35*4882a593Smuzhiyun     int widthTmp;
36*4882a593Smuzhiyun     int h, w;
37*4882a593Smuzhiyun     int x, y;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun     modulus(-yRot, tileHeight, tileY);
40*4882a593Smuzhiyun     y = 0;
41*4882a593Smuzhiyun     while (height) {
42*4882a593Smuzhiyun         h = tileHeight - tileY;
43*4882a593Smuzhiyun         if (h > height)
44*4882a593Smuzhiyun             h = height;
45*4882a593Smuzhiyun         height -= h;
46*4882a593Smuzhiyun         widthTmp = width;
47*4882a593Smuzhiyun         x = dstX;
48*4882a593Smuzhiyun         modulus(dstX - xRot, tileWidth, tileX);
49*4882a593Smuzhiyun         while (widthTmp) {
50*4882a593Smuzhiyun             w = tileWidth - tileX;
51*4882a593Smuzhiyun             if (w > widthTmp)
52*4882a593Smuzhiyun                 w = widthTmp;
53*4882a593Smuzhiyun             widthTmp -= w;
54*4882a593Smuzhiyun             fbBlt(tile + tileY * tileStride,
55*4882a593Smuzhiyun                   tileStride,
56*4882a593Smuzhiyun                   tileX,
57*4882a593Smuzhiyun                   dst + y * dstStride,
58*4882a593Smuzhiyun                   dstStride, x, w, h, alu, pm, bpp, FALSE, FALSE);
59*4882a593Smuzhiyun             x += w;
60*4882a593Smuzhiyun             tileX = 0;
61*4882a593Smuzhiyun         }
62*4882a593Smuzhiyun         y += h;
63*4882a593Smuzhiyun         tileY = 0;
64*4882a593Smuzhiyun     }
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun static void
fbStipple(FbBits * dst,FbStride dstStride,int dstX,int dstBpp,int width,int height,FbStip * stip,FbStride stipStride,int stipWidth,int stipHeight,FbBits fgand,FbBits fgxor,FbBits bgand,FbBits bgxor,int xRot,int yRot)68*4882a593Smuzhiyun fbStipple(FbBits * dst, FbStride dstStride,
69*4882a593Smuzhiyun           int dstX, int dstBpp,
70*4882a593Smuzhiyun           int width, int height,
71*4882a593Smuzhiyun           FbStip * stip, FbStride stipStride,
72*4882a593Smuzhiyun           int stipWidth, int stipHeight,
73*4882a593Smuzhiyun           FbBits fgand, FbBits fgxor,
74*4882a593Smuzhiyun           FbBits bgand, FbBits bgxor,
75*4882a593Smuzhiyun           int xRot, int yRot)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun     int stipX, stipY, sx;
78*4882a593Smuzhiyun     int widthTmp;
79*4882a593Smuzhiyun     int h, w;
80*4882a593Smuzhiyun     int x, y;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun     modulus(-yRot, stipHeight, stipY);
83*4882a593Smuzhiyun     modulus(dstX / dstBpp - xRot, stipWidth, stipX);
84*4882a593Smuzhiyun     y = 0;
85*4882a593Smuzhiyun     while (height) {
86*4882a593Smuzhiyun         h = stipHeight - stipY;
87*4882a593Smuzhiyun         if (h > height)
88*4882a593Smuzhiyun             h = height;
89*4882a593Smuzhiyun         height -= h;
90*4882a593Smuzhiyun         widthTmp = width;
91*4882a593Smuzhiyun         x = dstX;
92*4882a593Smuzhiyun         sx = stipX;
93*4882a593Smuzhiyun         while (widthTmp) {
94*4882a593Smuzhiyun             w = (stipWidth - sx) * dstBpp;
95*4882a593Smuzhiyun             if (w > widthTmp)
96*4882a593Smuzhiyun                 w = widthTmp;
97*4882a593Smuzhiyun             widthTmp -= w;
98*4882a593Smuzhiyun             fbBltOne(stip + stipY * stipStride,
99*4882a593Smuzhiyun                      stipStride,
100*4882a593Smuzhiyun                      sx,
101*4882a593Smuzhiyun                      dst + y * dstStride,
102*4882a593Smuzhiyun                      dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
103*4882a593Smuzhiyun             x += w;
104*4882a593Smuzhiyun             sx = 0;
105*4882a593Smuzhiyun         }
106*4882a593Smuzhiyun         y += h;
107*4882a593Smuzhiyun         stipY = 0;
108*4882a593Smuzhiyun     }
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun void
fbFill(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int width,int height)112*4882a593Smuzhiyun fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun     FbBits *dst;
115*4882a593Smuzhiyun     FbStride dstStride;
116*4882a593Smuzhiyun     int dstBpp;
117*4882a593Smuzhiyun     int dstXoff, dstYoff;
118*4882a593Smuzhiyun     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun     fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun     switch (pGC->fillStyle) {
123*4882a593Smuzhiyun     case FillSolid:
124*4882a593Smuzhiyun #ifndef FB_ACCESS_WRAPPER
125*4882a593Smuzhiyun         if (pPriv->and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
126*4882a593Smuzhiyun                                        x + dstXoff, y + dstYoff,
127*4882a593Smuzhiyun                                        width, height, pPriv->xor))
128*4882a593Smuzhiyun #endif
129*4882a593Smuzhiyun             fbSolid(dst + (y + dstYoff) * dstStride,
130*4882a593Smuzhiyun                     dstStride,
131*4882a593Smuzhiyun                     (x + dstXoff) * dstBpp,
132*4882a593Smuzhiyun                     dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor);
133*4882a593Smuzhiyun         break;
134*4882a593Smuzhiyun     case FillStippled:
135*4882a593Smuzhiyun     case FillOpaqueStippled:{
136*4882a593Smuzhiyun         PixmapPtr pStip = pGC->stipple;
137*4882a593Smuzhiyun         int stipWidth = pStip->drawable.width;
138*4882a593Smuzhiyun         int stipHeight = pStip->drawable.height;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun         if (dstBpp == 1) {
141*4882a593Smuzhiyun             int alu;
142*4882a593Smuzhiyun             FbBits *stip;
143*4882a593Smuzhiyun             FbStride stipStride;
144*4882a593Smuzhiyun             int stipBpp;
145*4882a593Smuzhiyun             _X_UNUSED int stipXoff, stipYoff;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun             if (pGC->fillStyle == FillStippled)
148*4882a593Smuzhiyun                 alu = FbStipple1Rop(pGC->alu, pGC->fgPixel);
149*4882a593Smuzhiyun             else
150*4882a593Smuzhiyun                 alu = FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel);
151*4882a593Smuzhiyun             fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff,
152*4882a593Smuzhiyun                           stipYoff);
153*4882a593Smuzhiyun             fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff,
154*4882a593Smuzhiyun                    width, height, stip, stipStride, stipWidth, stipHeight, alu,
155*4882a593Smuzhiyun                    pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff),
156*4882a593Smuzhiyun                    pGC->patOrg.y + pDrawable->y - y);
157*4882a593Smuzhiyun             fbFinishAccess(&pStip->drawable);
158*4882a593Smuzhiyun         }
159*4882a593Smuzhiyun         else {
160*4882a593Smuzhiyun             FbStip *stip;
161*4882a593Smuzhiyun             FbStride stipStride;
162*4882a593Smuzhiyun             int stipBpp;
163*4882a593Smuzhiyun             _X_UNUSED int stipXoff, stipYoff;
164*4882a593Smuzhiyun             FbBits fgand, fgxor, bgand, bgxor;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun             fgand = pPriv->and;
167*4882a593Smuzhiyun             fgxor = pPriv->xor;
168*4882a593Smuzhiyun             if (pGC->fillStyle == FillStippled) {
169*4882a593Smuzhiyun                 bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
170*4882a593Smuzhiyun                 bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
171*4882a593Smuzhiyun             }
172*4882a593Smuzhiyun             else {
173*4882a593Smuzhiyun                 bgand = pPriv->bgand;
174*4882a593Smuzhiyun                 bgxor = pPriv->bgxor;
175*4882a593Smuzhiyun             }
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun             fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp,
178*4882a593Smuzhiyun                               stipXoff, stipYoff);
179*4882a593Smuzhiyun             fbStipple(dst + (y + dstYoff) * dstStride, dstStride,
180*4882a593Smuzhiyun                       (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height,
181*4882a593Smuzhiyun                       stip, stipStride, stipWidth, stipHeight,
182*4882a593Smuzhiyun                       fgand, fgxor, bgand, bgxor,
183*4882a593Smuzhiyun                       pGC->patOrg.x + pDrawable->x + dstXoff,
184*4882a593Smuzhiyun                       pGC->patOrg.y + pDrawable->y - y);
185*4882a593Smuzhiyun             fbFinishAccess(&pStip->drawable);
186*4882a593Smuzhiyun         }
187*4882a593Smuzhiyun         break;
188*4882a593Smuzhiyun     }
189*4882a593Smuzhiyun     case FillTiled:{
190*4882a593Smuzhiyun         PixmapPtr pTile = pGC->tile.pixmap;
191*4882a593Smuzhiyun         FbBits *tile;
192*4882a593Smuzhiyun         FbStride tileStride;
193*4882a593Smuzhiyun         int tileBpp;
194*4882a593Smuzhiyun         int tileWidth;
195*4882a593Smuzhiyun         int tileHeight;
196*4882a593Smuzhiyun         _X_UNUSED int tileXoff, tileYoff;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun         fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff,
199*4882a593Smuzhiyun                       tileYoff);
200*4882a593Smuzhiyun         tileWidth = pTile->drawable.width;
201*4882a593Smuzhiyun         tileHeight = pTile->drawable.height;
202*4882a593Smuzhiyun         fbTile(dst + (y + dstYoff) * dstStride,
203*4882a593Smuzhiyun                dstStride,
204*4882a593Smuzhiyun                (x + dstXoff) * dstBpp,
205*4882a593Smuzhiyun                width * dstBpp, height,
206*4882a593Smuzhiyun                tile,
207*4882a593Smuzhiyun                tileStride,
208*4882a593Smuzhiyun                tileWidth * tileBpp,
209*4882a593Smuzhiyun                tileHeight,
210*4882a593Smuzhiyun                pGC->alu,
211*4882a593Smuzhiyun                pPriv->pm,
212*4882a593Smuzhiyun                dstBpp,
213*4882a593Smuzhiyun                (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
214*4882a593Smuzhiyun                pGC->patOrg.y + pDrawable->y - y);
215*4882a593Smuzhiyun         fbFinishAccess(&pTile->drawable);
216*4882a593Smuzhiyun         break;
217*4882a593Smuzhiyun     }
218*4882a593Smuzhiyun     }
219*4882a593Smuzhiyun     fbValidateDrawable(pDrawable);
220*4882a593Smuzhiyun     fbFinishAccess(pDrawable);
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun void
fbSolidBoxClipped(DrawablePtr pDrawable,RegionPtr pClip,int x1,int y1,int x2,int y2,FbBits and,FbBits xor)224*4882a593Smuzhiyun fbSolidBoxClipped(DrawablePtr pDrawable,
225*4882a593Smuzhiyun                   RegionPtr pClip,
226*4882a593Smuzhiyun                   int x1, int y1, int x2, int y2, FbBits and, FbBits xor)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun     FbBits *dst;
229*4882a593Smuzhiyun     FbStride dstStride;
230*4882a593Smuzhiyun     int dstBpp;
231*4882a593Smuzhiyun     int dstXoff, dstYoff;
232*4882a593Smuzhiyun     BoxPtr pbox;
233*4882a593Smuzhiyun     int nbox;
234*4882a593Smuzhiyun     int partX1, partX2, partY1, partY2;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun     fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun     for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip);
239*4882a593Smuzhiyun          nbox--; pbox++) {
240*4882a593Smuzhiyun         partX1 = pbox->x1;
241*4882a593Smuzhiyun         if (partX1 < x1)
242*4882a593Smuzhiyun             partX1 = x1;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun         partX2 = pbox->x2;
245*4882a593Smuzhiyun         if (partX2 > x2)
246*4882a593Smuzhiyun             partX2 = x2;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun         if (partX2 <= partX1)
249*4882a593Smuzhiyun             continue;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun         partY1 = pbox->y1;
252*4882a593Smuzhiyun         if (partY1 < y1)
253*4882a593Smuzhiyun             partY1 = y1;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun         partY2 = pbox->y2;
256*4882a593Smuzhiyun         if (partY2 > y2)
257*4882a593Smuzhiyun             partY2 = y2;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun         if (partY2 <= partY1)
260*4882a593Smuzhiyun             continue;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun #ifndef FB_ACCESS_WRAPPER
263*4882a593Smuzhiyun         if (and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
264*4882a593Smuzhiyun                                 partX1 + dstXoff, partY1 + dstYoff,
265*4882a593Smuzhiyun                                 (partX2 - partX1), (partY2 - partY1), xor))
266*4882a593Smuzhiyun #endif
267*4882a593Smuzhiyun             fbSolid(dst + (partY1 + dstYoff) * dstStride,
268*4882a593Smuzhiyun                     dstStride,
269*4882a593Smuzhiyun                     (partX1 + dstXoff) * dstBpp,
270*4882a593Smuzhiyun                     dstBpp,
271*4882a593Smuzhiyun                     (partX2 - partX1) * dstBpp, (partY2 - partY1), and, xor);
272*4882a593Smuzhiyun     }
273*4882a593Smuzhiyun     fbFinishAccess(pDrawable);
274*4882a593Smuzhiyun }
275