2006-11-26 11:13:41 -07:00
|
|
|
/***********************************************************
|
|
|
|
|
|
|
|
Copyright 1987, 1998 The Open Group
|
|
|
|
|
|
|
|
Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
the above copyright notice appear in all copies and that both that
|
|
|
|
copyright notice and this permission notice appear in supporting
|
|
|
|
documentation.
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
|
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
Except as contained in this notice, the name of The Open Group shall not be
|
|
|
|
used in advertising or otherwise to promote the sale, use or other dealings
|
|
|
|
in this Software without prior written authorization from The Open Group.
|
|
|
|
|
|
|
|
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
|
|
|
|
|
|
|
All Rights Reserved
|
|
|
|
|
|
|
|
Permission to use, copy, modify, and distribute this software and its
|
|
|
|
documentation for any purpose and without fee is hereby granted,
|
|
|
|
provided that the above copyright notice appear in all copies and that
|
|
|
|
both that copyright notice and this permission notice appear in
|
|
|
|
supporting documentation, and that the name of Digital not be
|
|
|
|
used in advertising or publicity pertaining to distribution of the
|
|
|
|
software without specific, written prior permission.
|
|
|
|
|
|
|
|
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
|
|
|
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|
|
|
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|
|
|
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
|
|
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
|
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
|
|
SOFTWARE.
|
|
|
|
|
|
|
|
******************************************************************/
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
|
|
#include <dix-config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <X11/X.h>
|
|
|
|
#include "gcstruct.h"
|
|
|
|
#include "scrnintstr.h"
|
|
|
|
#include "pixmapstr.h"
|
|
|
|
#include "regionstr.h"
|
|
|
|
#include "mi.h"
|
2008-11-02 08:26:08 -07:00
|
|
|
#include "servermd.h"
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
#define NPT 128
|
|
|
|
|
2008-11-02 08:26:08 -07:00
|
|
|
/* These were stolen from mfb. They don't really belong here. */
|
|
|
|
#define LONG2CHARSSAMEORDER(x) ((MiBits)(x))
|
|
|
|
#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \
|
|
|
|
| ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \
|
|
|
|
| ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \
|
|
|
|
| ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) )
|
|
|
|
|
|
|
|
#define PGSZB 4
|
2012-06-10 07:21:05 -06:00
|
|
|
#define PPW (PGSZB<<3) /* assuming 8 bits per byte */
|
2008-11-02 08:26:08 -07:00
|
|
|
#define PGSZ PPW
|
|
|
|
#define PLST (PPW-1)
|
|
|
|
#define PIM PLST
|
|
|
|
#define PWSH 5
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
/* miPushPixels -- squeegees the fill style of pGC through pBitMap
|
|
|
|
* into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
|
|
|
|
* be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
|
|
|
|
* is set in the bitmap, the fill style is put onto the drawable using
|
|
|
|
* the GC's logical function. The drawable is not changed where the bitmap
|
|
|
|
* has a zero bit or outside the area covered by the stencil.
|
|
|
|
|
|
|
|
WARNING:
|
|
|
|
this code works if the 1-bit deep pixmap format returned by GetSpans
|
|
|
|
is the same as the format defined by the mfb code (i.e. 32-bit padding
|
|
|
|
per scanline, scanline unit = 32 bits; later, this might mean
|
|
|
|
bitsizeof(int) padding and sacnline unit == bitsizeof(int).)
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* in order to have both (MSB_FIRST and LSB_FIRST) versions of this
|
|
|
|
* in the server, we need to rename one of them
|
|
|
|
*/
|
2009-09-06 13:44:18 -06:00
|
|
|
void
|
|
|
|
miPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
|
|
|
|
int dx, int dy, int xOrg, int yOrg)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
int h, dxDivPPW, ibEnd;
|
|
|
|
MiBits *pwLineStart;
|
|
|
|
MiBits *pw, *pwEnd;
|
|
|
|
MiBits msk;
|
|
|
|
int ib, w;
|
|
|
|
int ipt; /* index into above arrays */
|
|
|
|
Bool fInBox;
|
|
|
|
DDXPointRec pt[NPT], ptThisLine;
|
|
|
|
int width[NPT];
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
#if 1
|
2012-06-10 07:21:05 -06:00
|
|
|
MiBits startmask;
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
|
2012-06-10 07:21:05 -06:00
|
|
|
if (screenInfo.bitmapBitOrder == LSBFirst)
|
|
|
|
startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) << 1);
|
|
|
|
else
|
|
|
|
startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) >> 1);
|
|
|
|
else if (screenInfo.bitmapBitOrder == LSBFirst)
|
|
|
|
startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) << 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
else
|
2012-06-10 07:21:05 -06:00
|
|
|
startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) >> 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
#endif
|
|
|
|
|
2010-12-05 08:36:02 -07:00
|
|
|
pwLineStart = malloc(BitmapBytePad(dx));
|
2006-11-26 11:13:41 -07:00
|
|
|
if (!pwLineStart)
|
2012-06-10 07:21:05 -06:00
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
ipt = 0;
|
2012-06-10 07:21:05 -06:00
|
|
|
dxDivPPW = dx / PPW;
|
|
|
|
|
|
|
|
for (h = 0, ptThisLine.x = 0, ptThisLine.y = 0; h < dy; h++, ptThisLine.y++) {
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
(*pBitMap->drawable.pScreen->GetSpans) ((DrawablePtr) pBitMap, dx,
|
|
|
|
&ptThisLine, &dx, 1,
|
|
|
|
(char *) pwLineStart);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
pw = pwLineStart;
|
|
|
|
/* Process all words which are fully in the pixmap */
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
fInBox = FALSE;
|
|
|
|
pwEnd = pwLineStart + dxDivPPW;
|
|
|
|
while (pw < pwEnd) {
|
|
|
|
w = *pw;
|
2006-11-26 11:13:41 -07:00
|
|
|
#if 1
|
2012-06-10 07:21:05 -06:00
|
|
|
msk = startmask;
|
2006-11-26 11:13:41 -07:00
|
|
|
#else
|
2012-06-10 07:21:05 -06:00
|
|
|
msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
#endif
|
2012-06-10 07:21:05 -06:00
|
|
|
for (ib = 0; ib < PPW; ib++) {
|
|
|
|
if (w & msk) {
|
|
|
|
if (!fInBox) {
|
|
|
|
pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
|
|
|
|
pt[ipt].y = h + yOrg;
|
|
|
|
/* start new box */
|
|
|
|
fInBox = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (fInBox) {
|
|
|
|
width[ipt] = ((pw - pwLineStart) << PWSH) +
|
|
|
|
ib + xOrg - pt[ipt].x;
|
|
|
|
if (++ipt >= NPT) {
|
|
|
|
(*pGC->ops->FillSpans) (pDrawable, pGC,
|
|
|
|
NPT, pt, width, TRUE);
|
|
|
|
ipt = 0;
|
|
|
|
}
|
|
|
|
/* end box */
|
|
|
|
fInBox = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2006-11-26 11:13:41 -07:00
|
|
|
#if 1
|
2012-06-10 07:21:05 -06:00
|
|
|
/* This is not quite right, but it'll do for now */
|
|
|
|
if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
|
|
|
|
if (screenInfo.bitmapBitOrder == LSBFirst)
|
|
|
|
msk =
|
|
|
|
LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
|
|
|
|
else
|
|
|
|
msk =
|
|
|
|
LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
|
|
|
|
else if (screenInfo.bitmapBitOrder == LSBFirst)
|
|
|
|
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
|
|
|
|
else
|
|
|
|
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
#else
|
2012-06-10 07:21:05 -06:00
|
|
|
msk = SCRRIGHT(msk, 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
#endif
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
pw++;
|
|
|
|
}
|
|
|
|
ibEnd = dx & PIM;
|
|
|
|
if (ibEnd) {
|
|
|
|
/* Process final partial word on line */
|
|
|
|
w = *pw;
|
2006-11-26 11:13:41 -07:00
|
|
|
#if 1
|
2012-06-10 07:21:05 -06:00
|
|
|
msk = startmask;
|
2006-11-26 11:13:41 -07:00
|
|
|
#else
|
2012-06-10 07:21:05 -06:00
|
|
|
msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
#endif
|
2012-06-10 07:21:05 -06:00
|
|
|
for (ib = 0; ib < ibEnd; ib++) {
|
|
|
|
if (w & msk) {
|
|
|
|
if (!fInBox) {
|
|
|
|
/* start new box */
|
|
|
|
pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
|
|
|
|
pt[ipt].y = h + yOrg;
|
|
|
|
fInBox = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (fInBox) {
|
|
|
|
/* end box */
|
|
|
|
width[ipt] = ((pw - pwLineStart) << PWSH) +
|
|
|
|
ib + xOrg - pt[ipt].x;
|
|
|
|
if (++ipt >= NPT) {
|
|
|
|
(*pGC->ops->FillSpans) (pDrawable,
|
|
|
|
pGC, NPT, pt, width, TRUE);
|
|
|
|
ipt = 0;
|
|
|
|
}
|
|
|
|
fInBox = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2006-11-26 11:13:41 -07:00
|
|
|
#if 1
|
2012-06-10 07:21:05 -06:00
|
|
|
/* This is not quite right, but it'll do for now */
|
|
|
|
if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
|
|
|
|
if (screenInfo.bitmapBitOrder == LSBFirst)
|
|
|
|
msk =
|
|
|
|
LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
|
|
|
|
else
|
|
|
|
msk =
|
|
|
|
LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
|
|
|
|
else if (screenInfo.bitmapBitOrder == LSBFirst)
|
|
|
|
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
|
|
|
|
else
|
|
|
|
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
#else
|
2012-06-10 07:21:05 -06:00
|
|
|
msk = SCRRIGHT(msk, 1);
|
2006-11-26 11:13:41 -07:00
|
|
|
#endif
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* If scanline ended with last bit set, end the box */
|
|
|
|
if (fInBox) {
|
|
|
|
width[ipt] = dx + xOrg - pt[ipt].x;
|
|
|
|
if (++ipt >= NPT) {
|
|
|
|
(*pGC->ops->FillSpans) (pDrawable, pGC, NPT, pt, width, TRUE);
|
|
|
|
ipt = 0;
|
|
|
|
}
|
|
|
|
}
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
2010-12-05 08:36:02 -07:00
|
|
|
free(pwLineStart);
|
2006-11-26 11:13:41 -07:00
|
|
|
/* Flush any remaining spans */
|
2012-06-10 07:21:05 -06:00
|
|
|
if (ipt) {
|
|
|
|
(*pGC->ops->FillSpans) (pDrawable, pGC, ipt, pt, width, TRUE);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|