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