mipushpxl.c revision 6747b715
105b261ecSmrg/***********************************************************
205b261ecSmrg
305b261ecSmrgCopyright 1987, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included in
1205b261ecSmrgall copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2005b261ecSmrg
2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be
2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings
2305b261ecSmrgin this Software without prior written authorization from The Open Group.
2405b261ecSmrg
2505b261ecSmrg
2605b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
2705b261ecSmrg
2805b261ecSmrg                        All Rights Reserved
2905b261ecSmrg
3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its
3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted,
3205b261ecSmrgprovided that the above copyright notice appear in all copies and that
3305b261ecSmrgboth that copyright notice and this permission notice appear in
3405b261ecSmrgsupporting documentation, and that the name of Digital not be
3505b261ecSmrgused in advertising or publicity pertaining to distribution of the
3605b261ecSmrgsoftware without specific, written prior permission.
3705b261ecSmrg
3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4405b261ecSmrgSOFTWARE.
4505b261ecSmrg
4605b261ecSmrg******************************************************************/
4705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
4805b261ecSmrg#include <dix-config.h>
4905b261ecSmrg#endif
5005b261ecSmrg
5105b261ecSmrg#include <X11/X.h>
5205b261ecSmrg#include "gcstruct.h"
5305b261ecSmrg#include "scrnintstr.h"
5405b261ecSmrg#include "pixmapstr.h"
5505b261ecSmrg#include "regionstr.h"
5605b261ecSmrg#include "mi.h"
574642e01fSmrg#include "servermd.h"
5805b261ecSmrg
5905b261ecSmrg#define NPT 128
6005b261ecSmrg
614642e01fSmrg/* These were stolen from mfb.  They don't really belong here. */
624642e01fSmrg#define LONG2CHARSSAMEORDER(x) ((MiBits)(x))
634642e01fSmrg#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \
644642e01fSmrg                        | ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \
654642e01fSmrg                        | ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \
664642e01fSmrg                        | ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) )
674642e01fSmrg
684642e01fSmrg
694642e01fSmrg#define PGSZB	4
704642e01fSmrg#define PPW	(PGSZB<<3) /* assuming 8 bits per byte */
714642e01fSmrg#define PGSZ	PPW
724642e01fSmrg#define PLST	(PPW-1)
734642e01fSmrg#define PIM	PLST
744642e01fSmrg#define PWSH	5
754642e01fSmrg
7605b261ecSmrg/* miPushPixels -- squeegees the fill style of pGC through pBitMap
7705b261ecSmrg * into pDrawable.  pBitMap is a stencil (dx by dy of it is used, it may
7805b261ecSmrg * be bigger) which is placed on the drawable at xOrg, yOrg.  Where a 1 bit
7905b261ecSmrg * is set in the bitmap, the fill style is put onto the drawable using
8005b261ecSmrg * the GC's logical function. The drawable is not changed where the bitmap
8105b261ecSmrg * has a zero bit or outside the area covered by the stencil.
8205b261ecSmrg
8305b261ecSmrgWARNING:
8405b261ecSmrg    this code works if the 1-bit deep pixmap format returned by GetSpans
8505b261ecSmrgis the same as the format defined by the mfb code (i.e. 32-bit padding
8605b261ecSmrgper scanline, scanline unit = 32 bits; later, this might mean
8705b261ecSmrgbitsizeof(int) padding and sacnline unit == bitsizeof(int).)
8805b261ecSmrg
8905b261ecSmrg */
9005b261ecSmrg
9105b261ecSmrg/*
9205b261ecSmrg * in order to have both (MSB_FIRST and LSB_FIRST) versions of this
9305b261ecSmrg * in the server, we need to rename one of them
9405b261ecSmrg */
954642e01fSmrgvoid
964642e01fSmrgmiPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
974642e01fSmrg             int dx, int dy, int xOrg, int yOrg)
9805b261ecSmrg{
9905b261ecSmrg    int		h, dxDivPPW, ibEnd;
10005b261ecSmrg    MiBits 	*pwLineStart;
10105b261ecSmrg    MiBits	*pw, *pwEnd;
10205b261ecSmrg    MiBits 	msk;
10305b261ecSmrg    int 	ib, w;
10405b261ecSmrg    int 	ipt;		/* index into above arrays */
10505b261ecSmrg    Bool 	fInBox;
10605b261ecSmrg    DDXPointRec	pt[NPT], ptThisLine;
10705b261ecSmrg    int		width[NPT];
10805b261ecSmrg#if 1
1094642e01fSmrg    MiBits	startmask;
11005b261ecSmrg    if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
11105b261ecSmrg      if (screenInfo.bitmapBitOrder == LSBFirst)
11205b261ecSmrg        startmask = (MiBits)(-1) ^
11305b261ecSmrg            LONG2CHARSSAMEORDER((MiBits)(-1) << 1);
11405b261ecSmrg      else
11505b261ecSmrg        startmask = (MiBits)(-1) ^
11605b261ecSmrg            LONG2CHARSSAMEORDER((MiBits)(-1) >> 1);
11705b261ecSmrg    else
11805b261ecSmrg      if (screenInfo.bitmapBitOrder == LSBFirst)
11905b261ecSmrg        startmask = (MiBits)(-1) ^
12005b261ecSmrg            LONG2CHARSDIFFORDER((MiBits)(-1) << 1);
12105b261ecSmrg      else
12205b261ecSmrg        startmask = (MiBits)(-1) ^
12305b261ecSmrg            LONG2CHARSDIFFORDER((MiBits)(-1) >> 1);
12405b261ecSmrg#endif
12505b261ecSmrg
1266747b715Smrg    pwLineStart = malloc(BitmapBytePad(dx));
12705b261ecSmrg    if (!pwLineStart)
12805b261ecSmrg	return;
12905b261ecSmrg    ipt = 0;
13005b261ecSmrg    dxDivPPW = dx/PPW;
13105b261ecSmrg
13205b261ecSmrg    for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0;
13305b261ecSmrg	h < dy;
13405b261ecSmrg	h++, ptThisLine.y++)
13505b261ecSmrg    {
13605b261ecSmrg
13705b261ecSmrg	(*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx,
13805b261ecSmrg			&ptThisLine, &dx, 1, (char *)pwLineStart);
13905b261ecSmrg
14005b261ecSmrg	pw = pwLineStart;
14105b261ecSmrg	/* Process all words which are fully in the pixmap */
14205b261ecSmrg
14305b261ecSmrg	fInBox = FALSE;
14405b261ecSmrg	pwEnd = pwLineStart + dxDivPPW;
14505b261ecSmrg	while(pw  < pwEnd)
14605b261ecSmrg	{
14705b261ecSmrg	    w = *pw;
14805b261ecSmrg#if 1
14905b261ecSmrg	    msk = startmask;
15005b261ecSmrg#else
15105b261ecSmrg	    msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
15205b261ecSmrg#endif
15305b261ecSmrg	    for(ib = 0; ib < PPW; ib++)
15405b261ecSmrg	    {
15505b261ecSmrg		if(w & msk)
15605b261ecSmrg		{
15705b261ecSmrg		    if(!fInBox)
15805b261ecSmrg		    {
15905b261ecSmrg			pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
16005b261ecSmrg			pt[ipt].y = h + yOrg;
16105b261ecSmrg			/* start new box */
16205b261ecSmrg			fInBox = TRUE;
16305b261ecSmrg		    }
16405b261ecSmrg		}
16505b261ecSmrg		else
16605b261ecSmrg		{
16705b261ecSmrg		    if(fInBox)
16805b261ecSmrg		    {
16905b261ecSmrg			width[ipt] = ((pw - pwLineStart) << PWSH) +
17005b261ecSmrg				     ib + xOrg - pt[ipt].x;
17105b261ecSmrg			if (++ipt >= NPT)
17205b261ecSmrg			{
17305b261ecSmrg			    (*pGC->ops->FillSpans)(pDrawable, pGC,
17405b261ecSmrg					      NPT, pt, width, TRUE);
17505b261ecSmrg			    ipt = 0;
17605b261ecSmrg			}
17705b261ecSmrg			/* end box */
17805b261ecSmrg			fInBox = FALSE;
17905b261ecSmrg		    }
18005b261ecSmrg		}
18105b261ecSmrg#if 1
18205b261ecSmrg    		/* This is not quite right, but it'll do for now */
18305b261ecSmrg		if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
18405b261ecSmrg		  if (screenInfo.bitmapBitOrder == LSBFirst)
18505b261ecSmrg		    msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
18605b261ecSmrg		  else
18705b261ecSmrg		    msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
18805b261ecSmrg		else
18905b261ecSmrg		  if (screenInfo.bitmapBitOrder == LSBFirst)
19005b261ecSmrg		    msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
19105b261ecSmrg		  else
19205b261ecSmrg		    msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
19305b261ecSmrg#else
19405b261ecSmrg		msk = SCRRIGHT(msk, 1);
19505b261ecSmrg#endif
19605b261ecSmrg	    }
19705b261ecSmrg	    pw++;
19805b261ecSmrg	}
19905b261ecSmrg	ibEnd = dx & PIM;
20005b261ecSmrg	if(ibEnd)
20105b261ecSmrg	{
20205b261ecSmrg	    /* Process final partial word on line */
20305b261ecSmrg	    w = *pw;
20405b261ecSmrg#if 1
20505b261ecSmrg	    msk = startmask;
20605b261ecSmrg#else
20705b261ecSmrg	    msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
20805b261ecSmrg#endif
20905b261ecSmrg	    for(ib = 0; ib < ibEnd; ib++)
21005b261ecSmrg	    {
21105b261ecSmrg		if(w & msk)
21205b261ecSmrg		{
21305b261ecSmrg		    if(!fInBox)
21405b261ecSmrg		    {
21505b261ecSmrg			/* start new box */
21605b261ecSmrg			pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
21705b261ecSmrg			pt[ipt].y = h + yOrg;
21805b261ecSmrg			fInBox = TRUE;
21905b261ecSmrg		    }
22005b261ecSmrg		}
22105b261ecSmrg		else
22205b261ecSmrg		{
22305b261ecSmrg		    if(fInBox)
22405b261ecSmrg		    {
22505b261ecSmrg			/* end box */
22605b261ecSmrg			width[ipt] = ((pw - pwLineStart) << PWSH) +
22705b261ecSmrg				     ib + xOrg - pt[ipt].x;
22805b261ecSmrg			if (++ipt >= NPT)
22905b261ecSmrg			{
23005b261ecSmrg			    (*pGC->ops->FillSpans)(pDrawable,
23105b261ecSmrg					      pGC, NPT, pt, width, TRUE);
23205b261ecSmrg			    ipt = 0;
23305b261ecSmrg			}
23405b261ecSmrg			fInBox = FALSE;
23505b261ecSmrg		    }
23605b261ecSmrg		}
23705b261ecSmrg#if 1
23805b261ecSmrg    		/* This is not quite right, but it'll do for now */
23905b261ecSmrg		if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
24005b261ecSmrg		  if (screenInfo.bitmapBitOrder == LSBFirst)
24105b261ecSmrg		    msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
24205b261ecSmrg		  else
24305b261ecSmrg		    msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
24405b261ecSmrg		else
24505b261ecSmrg		  if (screenInfo.bitmapBitOrder == LSBFirst)
24605b261ecSmrg		    msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
24705b261ecSmrg		  else
24805b261ecSmrg		    msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
24905b261ecSmrg#else
25005b261ecSmrg		msk = SCRRIGHT(msk, 1);
25105b261ecSmrg#endif
25205b261ecSmrg	    }
25305b261ecSmrg	}
25405b261ecSmrg	/* If scanline ended with last bit set, end the box */
25505b261ecSmrg	if(fInBox)
25605b261ecSmrg	{
25705b261ecSmrg	    width[ipt] = dx + xOrg - pt[ipt].x;
25805b261ecSmrg	    if (++ipt >= NPT)
25905b261ecSmrg	    {
26005b261ecSmrg		(*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
26105b261ecSmrg		ipt = 0;
26205b261ecSmrg	    }
26305b261ecSmrg	}
26405b261ecSmrg    }
2656747b715Smrg    free(pwLineStart);
26605b261ecSmrg    /* Flush any remaining spans */
26705b261ecSmrg    if (ipt)
26805b261ecSmrg    {
26905b261ecSmrg	(*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
27005b261ecSmrg    }
27105b261ecSmrg}
272