mipushpxl.c 9.33 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/***********************************************************

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

Peter Hutterer's avatar
Peter Hutterer committed
29 30
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
31
provided that the above copyright notice appear in all copies and that
Peter Hutterer's avatar
Peter Hutterer committed
32
both that copyright notice and this permission notice appear in
33 34
supporting documentation, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
Peter Hutterer's avatar
Peter Hutterer committed
35
software without specific, written prior permission.
36 37 38 39 40 41 42 43 44 45

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.

******************************************************************/
46 47 48 49
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif

50
#include <X11/X.h>
51 52 53
#include "gcstruct.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
54
#include "regionstr.h"
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
55
#include "mi.h"
Adam Jackson's avatar
Adam Jackson committed
56
#include "servermd.h"
57 58 59

#define NPT 128

Adam Jackson's avatar
Adam Jackson committed
60 61 62 63 64 65 66 67
/* 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
68
#define PPW	(PGSZB<<3)      /* assuming 8 bits per byte */
Adam Jackson's avatar
Adam Jackson committed
69 70 71 72 73
#define PGSZ	PPW
#define PLST	(PPW-1)
#define PIM	PLST
#define PWSH	5

74 75 76 77 78 79 80 81 82 83 84 85 86 87
/* 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).)

 */
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
88 89 90 91 92

/*
 * in order to have both (MSB_FIRST and LSB_FIRST) versions of this
 * in the server, we need to rename one of them
 */
93
void
Peter Hutterer's avatar
Peter Hutterer committed
94 95
miPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
             int dx, int dy, int xOrg, int yOrg)
96
{
97 98 99 100 101 102 103 104 105 106
    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];

107
#if 1
108 109
    MiBits startmask;

Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
110
    if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
111 112 113 114 115 116
        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);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
117
    else
118
        startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) >> 1);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
119
#endif
120

121
    pwLineStart = malloc(BitmapBytePad(dx));
122
    if (!pwLineStart)
123
        return;
124
    ipt = 0;
125 126 127
    dxDivPPW = dx / PPW;

    for (h = 0, ptThisLine.x = 0, ptThisLine.y = 0; h < dy; h++, ptThisLine.y++) {
128

129 130 131
        (*pBitMap->drawable.pScreen->GetSpans) ((DrawablePtr) pBitMap, dx,
                                                &ptThisLine, &dx, 1,
                                                (char *) pwLineStart);
132

133 134
        pw = pwLineStart;
        /* Process all words which are fully in the pixmap */
135

136 137 138 139
        fInBox = FALSE;
        pwEnd = pwLineStart + dxDivPPW;
        while (pw < pwEnd) {
            w = *pw;
140
#if 1
141
            msk = startmask;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
142
#else
143
            msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
144
#endif
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
            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;
                    }
                }
167
#if 1
168 169 170 171 172 173 174 175 176 177 178 179
                /* 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);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
180
#else
181
                msk = SCRRIGHT(msk, 1);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
182
#endif
183 184 185 186 187 188 189
            }
            pw++;
        }
        ibEnd = dx & PIM;
        if (ibEnd) {
            /* Process final partial word on line */
            w = *pw;
190
#if 1
191
            msk = startmask;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
192
#else
193
            msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
194
#endif
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
            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;
                    }
                }
217
#if 1
218 219 220 221 222 223 224 225 226 227 228 229
                /* 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);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
230
#else
231
                msk = SCRRIGHT(msk, 1);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
232
#endif
233 234 235 236 237 238 239 240 241 242
            }
        }
        /* 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;
            }
        }
243
    }
244
    free(pwLineStart);
245
    /* Flush any remaining spans */
246 247
    if (ipt) {
        (*pGC->ops->FillSpans) (pDrawable, pGC, ipt, pt, width, TRUE);
248 249
    }
}