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