fbpush.c revision 05b261ec
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
2905b261ecSmrgvoid
3005b261ecSmrgfbPushPattern (DrawablePtr  pDrawable,
3105b261ecSmrg	       GCPtr	    pGC,
3205b261ecSmrg
3305b261ecSmrg	       FbStip	    *src,
3405b261ecSmrg	       FbStride	    srcStride,
3505b261ecSmrg	       int	    srcX,
3605b261ecSmrg
3705b261ecSmrg	       int	    x,
3805b261ecSmrg	       int	    y,
3905b261ecSmrg
4005b261ecSmrg	       int	    width,
4105b261ecSmrg	       int	    height)
4205b261ecSmrg{
4305b261ecSmrg    FbStip	    *s, bitsMask, bitsMask0, bits;
4405b261ecSmrg    int		    xspan;
4505b261ecSmrg    int		    w;
4605b261ecSmrg    int		    lenspan;
4705b261ecSmrg
4805b261ecSmrg    src += srcX >> FB_STIP_SHIFT;
4905b261ecSmrg    srcX &= FB_STIP_MASK;
5005b261ecSmrg
5105b261ecSmrg    bitsMask0 = FbStipMask (srcX, 1);
5205b261ecSmrg
5305b261ecSmrg    while (height--)
5405b261ecSmrg    {
5505b261ecSmrg	bitsMask = bitsMask0;
5605b261ecSmrg	w = width;
5705b261ecSmrg	s = src;
5805b261ecSmrg	src += srcStride;
5905b261ecSmrg	bits = READ(s++);
6005b261ecSmrg	xspan = x;
6105b261ecSmrg	while (w)
6205b261ecSmrg	{
6305b261ecSmrg	    if (bits & bitsMask)
6405b261ecSmrg	    {
6505b261ecSmrg		lenspan = 0;
6605b261ecSmrg		do
6705b261ecSmrg		{
6805b261ecSmrg		    lenspan++;
6905b261ecSmrg		    if (lenspan == w)
7005b261ecSmrg			break;
7105b261ecSmrg		    bitsMask = FbStipRight (bitsMask, 1);
7205b261ecSmrg		    if (!bitsMask)
7305b261ecSmrg		    {
7405b261ecSmrg			bits = READ(s++);
7505b261ecSmrg			bitsMask = FbBitsMask(0,1);
7605b261ecSmrg		    }
7705b261ecSmrg		} while (bits & bitsMask);
7805b261ecSmrg		fbFill (pDrawable, pGC, xspan, y, lenspan, 1);
7905b261ecSmrg		xspan += lenspan;
8005b261ecSmrg		w -= lenspan;
8105b261ecSmrg	    }
8205b261ecSmrg	    else
8305b261ecSmrg	    {
8405b261ecSmrg		do
8505b261ecSmrg		{
8605b261ecSmrg		    w--;
8705b261ecSmrg		    xspan++;
8805b261ecSmrg		    if (!w)
8905b261ecSmrg			break;
9005b261ecSmrg		    bitsMask = FbStipRight (bitsMask, 1);
9105b261ecSmrg		    if (!bitsMask)
9205b261ecSmrg		    {
9305b261ecSmrg			bits = READ(s++);
9405b261ecSmrg			bitsMask = FbBitsMask(0,1);
9505b261ecSmrg		    }
9605b261ecSmrg		} while (!(bits & bitsMask));
9705b261ecSmrg	    }
9805b261ecSmrg	}
9905b261ecSmrg	y++;
10005b261ecSmrg    }
10105b261ecSmrg}
10205b261ecSmrg
10305b261ecSmrgvoid
10405b261ecSmrgfbPushFill (DrawablePtr	pDrawable,
10505b261ecSmrg	    GCPtr	pGC,
10605b261ecSmrg
10705b261ecSmrg	    FbStip	*src,
10805b261ecSmrg	    FbStride	srcStride,
10905b261ecSmrg	    int		srcX,
11005b261ecSmrg
11105b261ecSmrg	    int		x,
11205b261ecSmrg	    int		y,
11305b261ecSmrg	    int		width,
11405b261ecSmrg	    int		height)
11505b261ecSmrg{
11605b261ecSmrg    FbGCPrivPtr	pPriv = fbGetGCPrivate(pGC);
11705b261ecSmrg
11805b261ecSmrg    if (pGC->fillStyle == FillSolid)
11905b261ecSmrg    {
12005b261ecSmrg	FbBits	    *dst;
12105b261ecSmrg	FbStride    dstStride;
12205b261ecSmrg	int	    dstBpp;
12305b261ecSmrg	int	    dstXoff, dstYoff;
12405b261ecSmrg	int	    dstX;
12505b261ecSmrg	int	    dstWidth;
12605b261ecSmrg
12705b261ecSmrg	fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
12805b261ecSmrg	dst = dst + (y + dstYoff) * dstStride;
12905b261ecSmrg	dstX = (x + dstXoff) * dstBpp;
13005b261ecSmrg	dstWidth = width * dstBpp;
13105b261ecSmrg	if (dstBpp == 1)
13205b261ecSmrg	{
13305b261ecSmrg	    fbBltStip (src,
13405b261ecSmrg		       srcStride,
13505b261ecSmrg		       srcX,
13605b261ecSmrg
13705b261ecSmrg		       (FbStip *) dst,
13805b261ecSmrg		       FbBitsStrideToStipStride (dstStride),
13905b261ecSmrg		       dstX,
14005b261ecSmrg
14105b261ecSmrg		       dstWidth,
14205b261ecSmrg		       height,
14305b261ecSmrg
14405b261ecSmrg		       FbStipple1Rop(pGC->alu,pGC->fgPixel),
14505b261ecSmrg		       pPriv->pm,
14605b261ecSmrg		       dstBpp);
14705b261ecSmrg	}
14805b261ecSmrg	else
14905b261ecSmrg	{
15005b261ecSmrg	    fbBltOne (src,
15105b261ecSmrg		      srcStride,
15205b261ecSmrg		      srcX,
15305b261ecSmrg
15405b261ecSmrg		      dst,
15505b261ecSmrg		      dstStride,
15605b261ecSmrg		      dstX,
15705b261ecSmrg		      dstBpp,
15805b261ecSmrg
15905b261ecSmrg		      dstWidth,
16005b261ecSmrg		      height,
16105b261ecSmrg
16205b261ecSmrg		      pPriv->and, pPriv->xor,
16305b261ecSmrg		      fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
16405b261ecSmrg		      fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
16505b261ecSmrg	}
16605b261ecSmrg	fbFinishAccess (pDrawable);
16705b261ecSmrg    }
16805b261ecSmrg    else
16905b261ecSmrg    {
17005b261ecSmrg	fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
17105b261ecSmrg		       x, y, width, height);
17205b261ecSmrg    }
17305b261ecSmrg}
17405b261ecSmrg
17505b261ecSmrgvoid
17605b261ecSmrgfbPushImage (DrawablePtr    pDrawable,
17705b261ecSmrg	     GCPtr	    pGC,
17805b261ecSmrg
17905b261ecSmrg	     FbStip	    *src,
18005b261ecSmrg	     FbStride	    srcStride,
18105b261ecSmrg	     int	    srcX,
18205b261ecSmrg
18305b261ecSmrg	     int	    x,
18405b261ecSmrg	     int	    y,
18505b261ecSmrg	     int	    width,
18605b261ecSmrg	     int	    height)
18705b261ecSmrg{
18805b261ecSmrg    RegionPtr	pClip = fbGetCompositeClip (pGC);
18905b261ecSmrg    int		nbox;
19005b261ecSmrg    BoxPtr	pbox;
19105b261ecSmrg    int		x1, y1, x2, y2;
19205b261ecSmrg
19305b261ecSmrg    for (nbox = REGION_NUM_RECTS (pClip),
19405b261ecSmrg	 pbox = REGION_RECTS(pClip);
19505b261ecSmrg	 nbox--;
19605b261ecSmrg	 pbox++)
19705b261ecSmrg    {
19805b261ecSmrg	x1 = x;
19905b261ecSmrg	y1 = y;
20005b261ecSmrg	x2 = x + width;
20105b261ecSmrg	y2 = y + height;
20205b261ecSmrg	if (x1 < pbox->x1)
20305b261ecSmrg	    x1 = pbox->x1;
20405b261ecSmrg	if (y1 < pbox->y1)
20505b261ecSmrg	    y1 = pbox->y1;
20605b261ecSmrg	if (x2 > pbox->x2)
20705b261ecSmrg	    x2 = pbox->x2;
20805b261ecSmrg	if (y2 > pbox->y2)
20905b261ecSmrg	    y2 = pbox->y2;
21005b261ecSmrg	if (x1 >= x2 || y1 >= y2)
21105b261ecSmrg	    continue;
21205b261ecSmrg	fbPushFill (pDrawable,
21305b261ecSmrg		    pGC,
21405b261ecSmrg
21505b261ecSmrg		    src + (y1 - y) * srcStride,
21605b261ecSmrg		    srcStride,
21705b261ecSmrg		    srcX + (x1 - x),
21805b261ecSmrg
21905b261ecSmrg		    x1,
22005b261ecSmrg		    y1,
22105b261ecSmrg		    x2 - x1,
22205b261ecSmrg		    y2 - y1);
22305b261ecSmrg    }
22405b261ecSmrg}
22505b261ecSmrg
22605b261ecSmrgvoid
22705b261ecSmrgfbPushPixels (GCPtr	    pGC,
22805b261ecSmrg	      PixmapPtr	    pBitmap,
22905b261ecSmrg	      DrawablePtr   pDrawable,
23005b261ecSmrg	      int	    dx,
23105b261ecSmrg	      int	    dy,
23205b261ecSmrg	      int	    xOrg,
23305b261ecSmrg	      int	    yOrg)
23405b261ecSmrg{
23505b261ecSmrg    FbStip	*stip;
23605b261ecSmrg    FbStride	stipStride;
23705b261ecSmrg    int		stipBpp;
23805b261ecSmrg    int		stipXoff, stipYoff; /* Assumed to be zero */
23905b261ecSmrg
24005b261ecSmrg    fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
24105b261ecSmrg
24205b261ecSmrg    fbPushImage (pDrawable, pGC,
24305b261ecSmrg		 stip, stipStride, 0,
24405b261ecSmrg		 xOrg, yOrg, dx, dy);
24505b261ecSmrg}
246