Imported Upstream version 1.15.1
[deb_xorg-server.git] / mi / mipushpxl.c
CommitLineData
a09e091a
JB
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}