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