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