105b261ecSmrg/*
205b261ecSmrg * Copyright © 1998 Keith Packard
305b261ecSmrg *
405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
605b261ecSmrg * the above copyright notice appear in all copies and that both that
705b261ecSmrg * copyright notice and this permission notice appear in supporting
805b261ecSmrg * documentation, and that the name of Keith Packard not be used in
905b261ecSmrg * advertising or publicity pertaining to distribution of the software without
1005b261ecSmrg * specific, written prior permission.  Keith Packard makes no
1105b261ecSmrg * representations about the suitability of this software for any purpose.  It
1205b261ecSmrg * is provided "as is" without express or implied warranty.
1305b261ecSmrg *
1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
2105b261ecSmrg */
2205b261ecSmrg
2305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
2405b261ecSmrg#include <dix-config.h>
2505b261ecSmrg#endif
2605b261ecSmrg
2705b261ecSmrg#include "fb.h"
2805b261ecSmrg
2935c4bbdfSmrgstatic void
3035c4bbdfSmrgfbPushPattern(DrawablePtr pDrawable,
3135c4bbdfSmrg              GCPtr pGC,
3235c4bbdfSmrg              FbStip * src,
3335c4bbdfSmrg              FbStride srcStride, int srcX, int x, int y, int width, int height)
3405b261ecSmrg{
3535c4bbdfSmrg    FbStip *s, bitsMask, bitsMask0, bits;
3635c4bbdfSmrg    int xspan;
3735c4bbdfSmrg    int w;
3835c4bbdfSmrg    int lenspan;
3935c4bbdfSmrg
4005b261ecSmrg    src += srcX >> FB_STIP_SHIFT;
4105b261ecSmrg    srcX &= FB_STIP_MASK;
4235c4bbdfSmrg
4335c4bbdfSmrg    bitsMask0 = FbStipMask(srcX, 1);
4435c4bbdfSmrg
4535c4bbdfSmrg    while (height--) {
4635c4bbdfSmrg        bitsMask = bitsMask0;
4735c4bbdfSmrg        w = width;
4835c4bbdfSmrg        s = src;
4935c4bbdfSmrg        src += srcStride;
5035c4bbdfSmrg        bits = READ(s++);
5135c4bbdfSmrg        xspan = x;
5235c4bbdfSmrg        while (w) {
5335c4bbdfSmrg            if (bits & bitsMask) {
5435c4bbdfSmrg                lenspan = 0;
5535c4bbdfSmrg                do {
5635c4bbdfSmrg                    lenspan++;
5735c4bbdfSmrg                    if (lenspan == w)
5835c4bbdfSmrg                        break;
5935c4bbdfSmrg                    bitsMask = FbStipRight(bitsMask, 1);
6035c4bbdfSmrg                    if (!bitsMask) {
6135c4bbdfSmrg                        bits = READ(s++);
6235c4bbdfSmrg                        bitsMask = FbBitsMask(0, 1);
6335c4bbdfSmrg                    }
6435c4bbdfSmrg                } while (bits & bitsMask);
6535c4bbdfSmrg                fbFill(pDrawable, pGC, xspan, y, lenspan, 1);
6635c4bbdfSmrg                xspan += lenspan;
6735c4bbdfSmrg                w -= lenspan;
6835c4bbdfSmrg            }
6935c4bbdfSmrg            else {
7035c4bbdfSmrg                do {
7135c4bbdfSmrg                    w--;
7235c4bbdfSmrg                    xspan++;
7335c4bbdfSmrg                    if (!w)
7435c4bbdfSmrg                        break;
7535c4bbdfSmrg                    bitsMask = FbStipRight(bitsMask, 1);
7635c4bbdfSmrg                    if (!bitsMask) {
7735c4bbdfSmrg                        bits = READ(s++);
7835c4bbdfSmrg                        bitsMask = FbBitsMask(0, 1);
7935c4bbdfSmrg                    }
8035c4bbdfSmrg                } while (!(bits & bitsMask));
8135c4bbdfSmrg            }
8235c4bbdfSmrg        }
8335c4bbdfSmrg        y++;
8405b261ecSmrg    }
8505b261ecSmrg}
8605b261ecSmrg
8735c4bbdfSmrgstatic void
8835c4bbdfSmrgfbPushFill(DrawablePtr pDrawable,
8935c4bbdfSmrg           GCPtr pGC,
9035c4bbdfSmrg           FbStip * src,
9135c4bbdfSmrg           FbStride srcStride, int srcX, int x, int y, int width, int height)
9205b261ecSmrg{
9335c4bbdfSmrg    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
9435c4bbdfSmrg
9535c4bbdfSmrg    if (pGC->fillStyle == FillSolid) {
9635c4bbdfSmrg        FbBits *dst;
9735c4bbdfSmrg        FbStride dstStride;
9835c4bbdfSmrg        int dstBpp;
9935c4bbdfSmrg        int dstXoff, dstYoff;
10035c4bbdfSmrg        int dstX;
10135c4bbdfSmrg        int dstWidth;
10205b261ecSmrg
10335c4bbdfSmrg        fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
10435c4bbdfSmrg        dst = dst + (y + dstYoff) * dstStride;
10535c4bbdfSmrg        dstX = (x + dstXoff) * dstBpp;
10635c4bbdfSmrg        dstWidth = width * dstBpp;
10735c4bbdfSmrg        if (dstBpp == 1) {
10835c4bbdfSmrg            fbBltStip(src,
10935c4bbdfSmrg                      srcStride,
11035c4bbdfSmrg                      srcX,
11135c4bbdfSmrg                      (FbStip *) dst,
11235c4bbdfSmrg                      FbBitsStrideToStipStride(dstStride),
11335c4bbdfSmrg                      dstX,
11435c4bbdfSmrg                      dstWidth,
11535c4bbdfSmrg                      height,
11635c4bbdfSmrg                      FbStipple1Rop(pGC->alu, pGC->fgPixel), pPriv->pm, dstBpp);
11735c4bbdfSmrg        }
11835c4bbdfSmrg        else {
11935c4bbdfSmrg            fbBltOne(src,
12035c4bbdfSmrg                     srcStride,
12135c4bbdfSmrg                     srcX,
12235c4bbdfSmrg                     dst,
12335c4bbdfSmrg                     dstStride,
12435c4bbdfSmrg                     dstX,
12535c4bbdfSmrg                     dstBpp,
12635c4bbdfSmrg                     dstWidth,
12735c4bbdfSmrg                     height,
12835c4bbdfSmrg                     pPriv->and, pPriv->xor,
12935c4bbdfSmrg                     fbAnd(GXnoop, (FbBits) 0, FB_ALLONES),
13035c4bbdfSmrg                     fbXor(GXnoop, (FbBits) 0, FB_ALLONES));
13135c4bbdfSmrg        }
13235c4bbdfSmrg        fbFinishAccess(pDrawable);
13305b261ecSmrg    }
13435c4bbdfSmrg    else {
13535c4bbdfSmrg        fbPushPattern(pDrawable, pGC, src, srcStride, srcX,
13635c4bbdfSmrg                      x, y, width, height);
13705b261ecSmrg    }
13805b261ecSmrg}
13905b261ecSmrg
14035c4bbdfSmrgvoid
14135c4bbdfSmrgfbPushImage(DrawablePtr pDrawable,
14235c4bbdfSmrg            GCPtr pGC,
14335c4bbdfSmrg            FbStip * src,
14435c4bbdfSmrg            FbStride srcStride, int srcX, int x, int y, int width, int height)
14505b261ecSmrg{
14635c4bbdfSmrg    RegionPtr pClip = fbGetCompositeClip(pGC);
14735c4bbdfSmrg    int nbox;
14835c4bbdfSmrg    BoxPtr pbox;
14935c4bbdfSmrg    int x1, y1, x2, y2;
15005b261ecSmrg
15135c4bbdfSmrg    for (nbox = RegionNumRects(pClip),
15235c4bbdfSmrg         pbox = RegionRects(pClip); nbox--; pbox++) {
15335c4bbdfSmrg        x1 = x;
15435c4bbdfSmrg        y1 = y;
15535c4bbdfSmrg        x2 = x + width;
15635c4bbdfSmrg        y2 = y + height;
15735c4bbdfSmrg        if (x1 < pbox->x1)
15835c4bbdfSmrg            x1 = pbox->x1;
15935c4bbdfSmrg        if (y1 < pbox->y1)
16035c4bbdfSmrg            y1 = pbox->y1;
16135c4bbdfSmrg        if (x2 > pbox->x2)
16235c4bbdfSmrg            x2 = pbox->x2;
16335c4bbdfSmrg        if (y2 > pbox->y2)
16435c4bbdfSmrg            y2 = pbox->y2;
16535c4bbdfSmrg        if (x1 >= x2 || y1 >= y2)
16635c4bbdfSmrg            continue;
16735c4bbdfSmrg        fbPushFill(pDrawable,
16835c4bbdfSmrg                   pGC,
16935c4bbdfSmrg                   src + (y1 - y) * srcStride,
17035c4bbdfSmrg                   srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1);
17105b261ecSmrg    }
17205b261ecSmrg}
17335c4bbdfSmrg
17405b261ecSmrgvoid
17535c4bbdfSmrgfbPushPixels(GCPtr pGC,
17635c4bbdfSmrg             PixmapPtr pBitmap,
17735c4bbdfSmrg             DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg)
17805b261ecSmrg{
17935c4bbdfSmrg    FbStip *stip;
18035c4bbdfSmrg    FbStride stipStride;
18135c4bbdfSmrg    int stipBpp;
18235c4bbdfSmrg    _X_UNUSED int stipXoff, stipYoff;
18305b261ecSmrg
18435c4bbdfSmrg    fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff,
18535c4bbdfSmrg                      stipYoff);
18605b261ecSmrg
18735c4bbdfSmrg    fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy);
18805b261ecSmrg}
189