fbpush.c revision 35c4bbdf
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
29static void
30fbPushPattern(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
87static void
88fbPushFill(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
140void
141fbPushImage(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
174void
175fbPushPixels(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