mipushpxl.c revision 35c4bbdf
1/*********************************************************** 2 3Copyright 1987, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 26 27 All Rights Reserved 28 29Permission to use, copy, modify, and distribute this software and its 30documentation for any purpose and without fee is hereby granted, 31provided that the above copyright notice appear in all copies and that 32both that copyright notice and this permission notice appear in 33supporting documentation, and that the name of Digital not be 34used in advertising or publicity pertaining to distribution of the 35software without specific, written prior permission. 36 37DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43SOFTWARE. 44 45******************************************************************/ 46#ifdef HAVE_DIX_CONFIG_H 47#include <dix-config.h> 48#endif 49 50#include <X11/X.h> 51#include "gcstruct.h" 52#include "scrnintstr.h" 53#include "pixmapstr.h" 54#include "regionstr.h" 55#include "mi.h" 56#include "servermd.h" 57 58#define NPT 128 59 60/* These were stolen from mfb. They don't really belong here. */ 61#define LONG2CHARSSAMEORDER(x) ((MiBits)(x)) 62#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \ 63 | ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \ 64 | ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \ 65 | ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) ) 66 67#define PGSZB 4 68#define PPW (PGSZB<<3) /* assuming 8 bits per byte */ 69#define PGSZ PPW 70#define PLST (PPW-1) 71#define PIM PLST 72#define PWSH 5 73 74/* miPushPixels -- squeegees the fill style of pGC through pBitMap 75 * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may 76 * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit 77 * is set in the bitmap, the fill style is put onto the drawable using 78 * the GC's logical function. The drawable is not changed where the bitmap 79 * has a zero bit or outside the area covered by the stencil. 80 81WARNING: 82 this code works if the 1-bit deep pixmap format returned by GetSpans 83is the same as the format defined by the mfb code (i.e. 32-bit padding 84per scanline, scanline unit = 32 bits; later, this might mean 85bitsizeof(int) padding and sacnline unit == bitsizeof(int).) 86 87 */ 88 89/* 90 * in order to have both (MSB_FIRST and LSB_FIRST) versions of this 91 * in the server, we need to rename one of them 92 */ 93void 94miPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, 95 int dx, int dy, int xOrg, int yOrg) 96{ 97 int h, dxDivPPW, ibEnd; 98 MiBits *pwLineStart; 99 MiBits *pw, *pwEnd; 100 MiBits msk; 101 int ib, w; 102 int ipt; /* index into above arrays */ 103 Bool fInBox; 104 DDXPointRec pt[NPT], ptThisLine; 105 int width[NPT]; 106 107#if 1 108 MiBits startmask; 109 110 if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) 111 if (screenInfo.bitmapBitOrder == LSBFirst) 112 startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) << 1); 113 else 114 startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) >> 1); 115 else if (screenInfo.bitmapBitOrder == LSBFirst) 116 startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) << 1); 117 else 118 startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) >> 1); 119#endif 120 121 pwLineStart = malloc(BitmapBytePad(dx)); 122 if (!pwLineStart) 123 return; 124 ipt = 0; 125 dxDivPPW = dx / PPW; 126 127 for (h = 0, ptThisLine.x = 0, ptThisLine.y = 0; h < dy; h++, ptThisLine.y++) { 128 129 (*pBitMap->drawable.pScreen->GetSpans) ((DrawablePtr) pBitMap, dx, 130 &ptThisLine, &dx, 1, 131 (char *) pwLineStart); 132 133 pw = pwLineStart; 134 /* Process all words which are fully in the pixmap */ 135 136 fInBox = FALSE; 137 pwEnd = pwLineStart + dxDivPPW; 138 while (pw < pwEnd) { 139 w = *pw; 140#if 1 141 msk = startmask; 142#else 143 msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1); 144#endif 145 for (ib = 0; ib < PPW; ib++) { 146 if (w & msk) { 147 if (!fInBox) { 148 pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; 149 pt[ipt].y = h + yOrg; 150 /* start new box */ 151 fInBox = TRUE; 152 } 153 } 154 else { 155 if (fInBox) { 156 width[ipt] = ((pw - pwLineStart) << PWSH) + 157 ib + xOrg - pt[ipt].x; 158 if (++ipt >= NPT) { 159 (*pGC->ops->FillSpans) (pDrawable, pGC, 160 NPT, pt, width, TRUE); 161 ipt = 0; 162 } 163 /* end box */ 164 fInBox = FALSE; 165 } 166 } 167#if 1 168 /* This is not quite right, but it'll do for now */ 169 if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) 170 if (screenInfo.bitmapBitOrder == LSBFirst) 171 msk = 172 LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1); 173 else 174 msk = 175 LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1); 176 else if (screenInfo.bitmapBitOrder == LSBFirst) 177 msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1); 178 else 179 msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); 180#else 181 msk = SCRRIGHT(msk, 1); 182#endif 183 } 184 pw++; 185 } 186 ibEnd = dx & PIM; 187 if (ibEnd) { 188 /* Process final partial word on line */ 189 w = *pw; 190#if 1 191 msk = startmask; 192#else 193 msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1); 194#endif 195 for (ib = 0; ib < ibEnd; ib++) { 196 if (w & msk) { 197 if (!fInBox) { 198 /* start new box */ 199 pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; 200 pt[ipt].y = h + yOrg; 201 fInBox = TRUE; 202 } 203 } 204 else { 205 if (fInBox) { 206 /* end box */ 207 width[ipt] = ((pw - pwLineStart) << PWSH) + 208 ib + xOrg - pt[ipt].x; 209 if (++ipt >= NPT) { 210 (*pGC->ops->FillSpans) (pDrawable, 211 pGC, NPT, pt, width, TRUE); 212 ipt = 0; 213 } 214 fInBox = FALSE; 215 } 216 } 217#if 1 218 /* This is not quite right, but it'll do for now */ 219 if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) 220 if (screenInfo.bitmapBitOrder == LSBFirst) 221 msk = 222 LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1); 223 else 224 msk = 225 LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1); 226 else if (screenInfo.bitmapBitOrder == LSBFirst) 227 msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1); 228 else 229 msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); 230#else 231 msk = SCRRIGHT(msk, 1); 232#endif 233 } 234 } 235 /* If scanline ended with last bit set, end the box */ 236 if (fInBox) { 237 width[ipt] = dx + xOrg - pt[ipt].x; 238 if (++ipt >= NPT) { 239 (*pGC->ops->FillSpans) (pDrawable, pGC, NPT, pt, width, TRUE); 240 ipt = 0; 241 } 242 } 243 } 244 free(pwLineStart); 245 /* Flush any remaining spans */ 246 if (ipt) { 247 (*pGC->ops->FillSpans) (pDrawable, pGC, ipt, pt, width, TRUE); 248 } 249} 250