xref: /OK3568_Linux_fs/external/xserver/fb/fbpush.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright © 1998 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Keith Packard not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Keith Packard makes no
11  * representations about the suitability of this software for any purpose.  It
12  * is provided "as is" without express or implied warranty.
13  *
14  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #ifdef HAVE_DIX_CONFIG_H
24 #include <dix-config.h>
25 #endif
26 
27 #include "fb.h"
28 
29 static void
fbPushPattern(DrawablePtr pDrawable,GCPtr pGC,FbStip * src,FbStride srcStride,int srcX,int x,int y,int width,int height)30 fbPushPattern(DrawablePtr pDrawable,
31               GCPtr pGC,
32               FbStip * src,
33               FbStride srcStride, int srcX, int x, int y, int width, int height)
34 {
35     FbStip *s, bitsMask, bitsMask0, bits;
36     int xspan;
37     int w;
38     int lenspan;
39 
40     src += srcX >> FB_STIP_SHIFT;
41     srcX &= FB_STIP_MASK;
42 
43     bitsMask0 = FbStipMask(srcX, 1);
44 
45     while (height--) {
46         bitsMask = bitsMask0;
47         w = width;
48         s = src;
49         src += srcStride;
50         bits = READ(s++);
51         xspan = x;
52         while (w) {
53             if (bits & bitsMask) {
54                 lenspan = 0;
55                 do {
56                     lenspan++;
57                     if (lenspan == w)
58                         break;
59                     bitsMask = FbStipRight(bitsMask, 1);
60                     if (!bitsMask) {
61                         bits = READ(s++);
62                         bitsMask = FbBitsMask(0, 1);
63                     }
64                 } while (bits & bitsMask);
65                 fbFill(pDrawable, pGC, xspan, y, lenspan, 1);
66                 xspan += lenspan;
67                 w -= lenspan;
68             }
69             else {
70                 do {
71                     w--;
72                     xspan++;
73                     if (!w)
74                         break;
75                     bitsMask = FbStipRight(bitsMask, 1);
76                     if (!bitsMask) {
77                         bits = READ(s++);
78                         bitsMask = FbBitsMask(0, 1);
79                     }
80                 } while (!(bits & bitsMask));
81             }
82         }
83         y++;
84     }
85 }
86 
87 static void
fbPushFill(DrawablePtr pDrawable,GCPtr pGC,FbStip * src,FbStride srcStride,int srcX,int x,int y,int width,int height)88 fbPushFill(DrawablePtr pDrawable,
89            GCPtr pGC,
90            FbStip * src,
91            FbStride srcStride, int srcX, int x, int y, int width, int height)
92 {
93     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
94 
95     if (pGC->fillStyle == FillSolid) {
96         FbBits *dst;
97         FbStride dstStride;
98         int dstBpp;
99         int dstXoff, dstYoff;
100         int dstX;
101         int dstWidth;
102 
103         fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
104         dst = dst + (y + dstYoff) * dstStride;
105         dstX = (x + dstXoff) * dstBpp;
106         dstWidth = width * dstBpp;
107         if (dstBpp == 1) {
108             fbBltStip(src,
109                       srcStride,
110                       srcX,
111                       (FbStip *) dst,
112                       FbBitsStrideToStipStride(dstStride),
113                       dstX,
114                       dstWidth,
115                       height,
116                       FbStipple1Rop(pGC->alu, pGC->fgPixel), pPriv->pm, dstBpp);
117         }
118         else {
119             fbBltOne(src,
120                      srcStride,
121                      srcX,
122                      dst,
123                      dstStride,
124                      dstX,
125                      dstBpp,
126                      dstWidth,
127                      height,
128                      pPriv->and, pPriv->xor,
129                      fbAnd(GXnoop, (FbBits) 0, FB_ALLONES),
130                      fbXor(GXnoop, (FbBits) 0, FB_ALLONES));
131         }
132         fbFinishAccess(pDrawable);
133     }
134     else {
135         fbPushPattern(pDrawable, pGC, src, srcStride, srcX,
136                       x, y, width, height);
137     }
138 }
139 
140 void
fbPushImage(DrawablePtr pDrawable,GCPtr pGC,FbStip * src,FbStride srcStride,int srcX,int x,int y,int width,int height)141 fbPushImage(DrawablePtr pDrawable,
142             GCPtr pGC,
143             FbStip * src,
144             FbStride srcStride, int srcX, int x, int y, int width, int height)
145 {
146     RegionPtr pClip = fbGetCompositeClip(pGC);
147     int nbox;
148     BoxPtr pbox;
149     int x1, y1, x2, y2;
150 
151     for (nbox = RegionNumRects(pClip),
152          pbox = RegionRects(pClip); nbox--; pbox++) {
153         x1 = x;
154         y1 = y;
155         x2 = x + width;
156         y2 = y + height;
157         if (x1 < pbox->x1)
158             x1 = pbox->x1;
159         if (y1 < pbox->y1)
160             y1 = pbox->y1;
161         if (x2 > pbox->x2)
162             x2 = pbox->x2;
163         if (y2 > pbox->y2)
164             y2 = pbox->y2;
165         if (x1 >= x2 || y1 >= y2)
166             continue;
167         fbPushFill(pDrawable,
168                    pGC,
169                    src + (y1 - y) * srcStride,
170                    srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1);
171     }
172 }
173 
174 void
fbPushPixels(GCPtr pGC,PixmapPtr pBitmap,DrawablePtr pDrawable,int dx,int dy,int xOrg,int yOrg)175 fbPushPixels(GCPtr pGC,
176              PixmapPtr pBitmap,
177              DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg)
178 {
179     FbStip *stip;
180     FbStride stipStride;
181     int stipBpp;
182     _X_UNUSED int stipXoff, stipYoff;
183 
184     fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff,
185                       stipYoff);
186 
187     fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy);
188 }
189