First import
[xorg_rtime.git] / xorg-server-1.4 / cfb / cfbrctstp8.c
blob485d40998d86c4dc482239be99eef7f8e84b7cef
1 /*
2 * Fill 32 bit stippled rectangles for 8 bit frame buffers
3 */
4 /*
6 Copyright 1989, 1998 The Open Group
8 Permission to use, copy, modify, distribute, and sell this software and its
9 documentation for any purpose is hereby granted without fee, provided that
10 the above copyright notice appear in all copies and that both that
11 copyright notice and this permission notice appear in supporting
12 documentation.
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of The Open Group shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from The Open Group.
28 Author: Keith Packard, MIT X Consortium
33 #ifdef HAVE_DIX_CONFIG_H
34 #include <dix-config.h>
35 #endif
37 #if PSZ == 8
39 #include <X11/X.h>
40 #include <X11/Xmd.h>
41 #include "servermd.h"
42 #include "gcstruct.h"
43 #include "window.h"
44 #include "pixmapstr.h"
45 #include "scrnintstr.h"
46 #include "windowstr.h"
48 #include "cfb.h"
49 #include "cfbmskbits.h"
50 #include "cfb8bit.h"
52 #define MFB_CONSTS_ONLY
53 #include "maskbits.h"
55 void
56 cfb8FillRectOpaqueStippled32 (pDrawable, pGC, nBox, pBox)
57 DrawablePtr pDrawable;
58 GCPtr pGC;
59 int nBox; /* number of boxes to fill */
60 register BoxPtr pBox; /* pointer to list of boxes to fill */
62 CfbBits *src;
63 int stippleHeight;
65 int nlwDst; /* width in longwords of the dest pixmap */
66 int w; /* width of current box */
67 register int h; /* height of current box */
68 CfbBits startmask;
69 CfbBits endmask; /* masks for reggedy bits at either end of line */
70 int nlwMiddle; /* number of longwords between sides of boxes */
71 register int nlw; /* loop version of nlwMiddle */
72 CfbBits *dstLine;
73 register CfbBits *dst; /* pointer to bits we're writing */
74 CfbBits *dstTmp;
75 int y; /* current scan line */
77 CfbBits *pbits;/* pointer to start of pixmap */
78 register CfbBits bits; /* bits from stipple */
79 int rot;
80 register CfbBits xor;
81 PixmapPtr stipple;
82 int wEnd;
84 stipple = pGC->pRotatedPixmap;
86 cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
88 stippleHeight = stipple->drawable.height;
89 src = (CfbBits *)stipple->devPrivate.ptr;
91 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
93 while (nBox--)
95 w = pBox->x2 - pBox->x1;
96 h = pBox->y2 - pBox->y1;
97 y = pBox->y1;
98 dstLine = pbits + (pBox->y1 * nlwDst) + ((pBox->x1 & ~PIM) >> PWSH);
99 if (((pBox->x1 & PIM) + w) <= PPW)
101 maskpartialbits(pBox->x1, w, startmask);
102 nlwMiddle = 0;
103 endmask = 0;
105 else
107 maskbits (pBox->x1, w, startmask, endmask, nlwMiddle);
109 rot = (pBox->x1 & ((PGSZ-1) & ~PIM));
110 pBox++;
111 y = y % stippleHeight;
112 #if PPW == 4
113 if (cfb8StippleRRop == GXcopy)
115 if (w < PGSZ*2)
117 while (h--)
119 bits = src[y];
120 y++;
121 if (y == stippleHeight)
122 y = 0;
123 if (rot)
124 RotBitsLeft(bits,rot);
125 dst = dstLine;
126 dstLine += nlwDst;
127 if (startmask)
129 *dst = (*dst & ~startmask) |
130 (GetPixelGroup (bits) & startmask);
131 dst++;
132 RotBitsLeft (bits, PGSZB);
134 nlw = nlwMiddle;
135 while (nlw--)
137 *dst++ = GetPixelGroup(bits);
138 RotBitsLeft (bits, PGSZB);
140 if (endmask)
142 *dst = (*dst & ~endmask) |
143 (GetPixelGroup (bits) & endmask);
147 else
149 wEnd = 7 - (nlwMiddle & 7);
150 nlwMiddle = (nlwMiddle >> 3) + 1;
151 while (h--)
153 bits = src[y];
154 y++;
155 if (y == stippleHeight)
156 y = 0;
157 if (rot != 0)
158 RotBitsLeft (bits, rot);
159 dstTmp = dstLine;
160 dstLine += nlwDst;
161 if (startmask)
163 *dstTmp = (*dstTmp & ~startmask) |
164 (GetPixelGroup (bits) & startmask);
165 dstTmp++;
166 RotBitsLeft (bits, PGSZB);
168 w = 7 - wEnd;
169 while (w--)
171 nlw = nlwMiddle;
172 dst = dstTmp;
173 dstTmp++;
174 xor = GetPixelGroup (bits);
175 while (nlw--)
177 *dst = xor;
178 dst += 8;
180 NextBitGroup (bits);
182 nlwMiddle--;
183 w = wEnd + 1;
184 if (endmask)
186 dst = dstTmp + (nlwMiddle << 3);
187 *dst = (*dst & ~endmask) |
188 (GetPixelGroup(bits) & endmask);
190 while (w--)
192 nlw = nlwMiddle;
193 dst = dstTmp;
194 dstTmp++;
195 xor = GetPixelGroup (bits);
196 while (nlw--)
198 *dst = xor;
199 dst += 8;
201 NextBitGroup (bits);
203 nlwMiddle++;
207 else
208 #endif /* PPW == 4 */
210 while (h--)
212 bits = src[y];
213 y++;
214 if (y == stippleHeight)
215 y = 0;
216 if (rot)
217 RotBitsLeft(bits,rot);
218 dst = dstLine;
219 dstLine += nlwDst;
220 if (startmask)
222 xor = GetBitGroup(bits);
223 *dst = MaskRRopPixels(*dst, xor, startmask);
224 dst++;
225 RotBitsLeft (bits, PGSZB);
227 nlw = nlwMiddle;
228 while (nlw--)
230 RRopBitGroup(dst, GetBitGroup(bits));
231 dst++;
232 RotBitsLeft (bits, PGSZB);
234 if (endmask)
236 xor = GetBitGroup(bits);
237 *dst = MaskRRopPixels(*dst, xor, endmask);
244 void
245 cfb8FillRectTransparentStippled32 (pDrawable, pGC, nBox, pBox)
246 DrawablePtr pDrawable;
247 GCPtr pGC;
248 int nBox; /* number of boxes to fill */
249 BoxPtr pBox; /* pointer to list of boxes to fill */
251 int x, y, w, h;
252 int nlwMiddle, nlwDst;
253 CfbBits startmask, endmask;
254 register CfbBits *dst;
255 CfbBits *dstLine, *pbits, *dstTmp;
256 CfbBits *src;
257 register CfbBits xor;
258 register CfbBits bits, mask;
259 int rot;
260 int wEnd;
261 cfbPrivGCPtr devPriv;
262 PixmapPtr stipple;
263 int stippleHeight;
264 register int nlw;
266 devPriv = cfbGetGCPrivate(pGC);
267 stipple = pGC->pRotatedPixmap;
268 src = (CfbBits *)stipple->devPrivate.ptr;
269 stippleHeight = stipple->drawable.height;
271 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
273 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
275 while (nBox--)
277 x = pBox->x1;
278 w = pBox->x2 - x;
279 if (((x & PIM) + w) <= PPW)
281 maskpartialbits(x, w, startmask);
282 endmask = 0;
283 nlwMiddle = 0;
285 else
287 maskbits (x, w, startmask, endmask, nlwMiddle);
289 rot = (x & ((PGSZ-1) & ~PIM));
290 y = pBox->y1;
291 dstLine = pbits + (y * nlwDst) + (x >> PWSH);
292 h = pBox->y2 - y;
293 pBox++;
294 y %= stippleHeight;
295 #if PPW == 4
296 if (cfb8StippleRRop == GXcopy)
298 xor = devPriv->xor;
299 if (w < PGSZ*2)
301 while (h--)
303 bits = src[y];
304 y++;
305 if (y == stippleHeight)
306 y = 0;
307 if (rot != 0)
308 RotBitsLeft (bits, rot);
309 dst = dstLine;
310 dstLine += nlwDst;
311 if (startmask)
313 mask = cfb8PixelMasks[GetBitGroup(bits)];
314 *dst = (*dst & ~(mask & startmask)) |
315 (xor & (mask & startmask));
316 dst++;
317 RotBitsLeft (bits, PGSZB);
319 nlw = nlwMiddle;
320 while (nlw--)
322 WriteBitGroup (dst,xor,GetBitGroup(bits))
323 dst++;
324 RotBitsLeft (bits, PGSZB);
326 if (endmask)
328 mask = cfb8PixelMasks[GetBitGroup(bits)];
329 *dst = (*dst & ~(mask & endmask)) |
330 (xor & (mask & endmask));
334 else
336 wEnd = 7 - (nlwMiddle & 7);
337 nlwMiddle = (nlwMiddle >> 3) + 1;
338 while (h--)
340 bits = src[y];
341 y++;
342 if (y == stippleHeight)
343 y = 0;
344 if (rot != 0)
345 RotBitsLeft (bits, rot);
346 dstTmp = dstLine;
347 dstLine += nlwDst;
348 if (startmask)
350 mask = cfb8PixelMasks[GetBitGroup(bits)];
351 *dstTmp = (*dstTmp & ~(mask & startmask)) |
352 (xor & (mask & startmask));
353 dstTmp++;
354 RotBitsLeft (bits, PGSZB);
356 w = 7 - wEnd;
357 while (w--)
359 nlw = nlwMiddle;
360 dst = dstTmp;
361 dstTmp++;
362 #if defined(__GNUC__) && defined(mc68020)
363 mask = cfb8PixelMasks[GetBitGroup(bits)];
364 xor = xor & mask;
365 mask = ~mask;
366 while (nlw--)
368 *dst = (*dst & mask) | xor;
369 dst += 8;
371 xor = devPriv->xor;
372 #else
373 #define SwitchBitsLoop(body) \
374 while (nlw--) \
376 body \
377 dst += 8; \
379 SwitchBitGroup(dst, xor, GetBitGroup(bits));
380 #undef SwitchBitsLoop
381 #endif
382 NextBitGroup (bits);
384 nlwMiddle--;
385 w = wEnd + 1;
386 if (endmask)
388 mask = cfb8PixelMasks[GetBitGroup(bits)];
389 dst = dstTmp + (nlwMiddle << 3);
390 *dst = (*dst & ~(mask & endmask)) |
391 (xor & (mask & endmask));
393 while (w--)
395 nlw = nlwMiddle;
396 dst = dstTmp;
397 dstTmp++;
398 #if defined(__GNUC__) && defined(mc68020)
399 mask = cfb8PixelMasks[GetBitGroup(bits)];
400 xor = xor & mask;
401 mask = ~mask;
402 while (nlw--)
404 *dst = (*dst & mask) | xor;
405 dst += 8;
407 xor = devPriv->xor;
408 #else
409 #define SwitchBitsLoop(body) \
410 while (nlw--) \
412 body \
413 dst += 8; \
415 SwitchBitGroup(dst, xor, GetBitGroup(bits));
416 #undef SwitchBitsLoop
417 #endif
418 NextBitGroup (bits);
420 nlwMiddle++;
424 else
425 #endif /* PPW == 4 */
427 while (h--)
429 bits = src[y];
430 y++;
431 if (y == stippleHeight)
432 y = 0;
433 if (rot != 0)
434 RotBitsLeft (bits, rot);
435 dst = dstLine;
436 dstLine += nlwDst;
437 if (startmask)
439 xor = GetBitGroup(bits);
440 *dst = MaskRRopPixels(*dst, xor, startmask);
441 dst++;
442 RotBitsLeft (bits, PGSZB);
444 nlw = nlwMiddle;
445 while (nlw--)
447 RRopBitGroup(dst, GetBitGroup(bits));
448 dst++;
449 RotBitsLeft (bits, PGSZB);
451 if (endmask)
453 xor = GetBitGroup(bits);
454 *dst = MaskRRopPixels(*dst, xor, endmask);
462 void
463 cfb8FillRectStippledUnnatural (pDrawable, pGC, nBox, pBox)
464 DrawablePtr pDrawable;
465 GCPtr pGC;
466 int nBox;
467 register BoxPtr pBox;
469 CfbBits *pdstBase; /* pointer to start of bitmap */
470 CfbBits *pdstLine; /* current destination line */
471 int nlwDst; /* width in longwords of bitmap */
472 PixmapPtr pStipple; /* pointer to stipple we want to fill with */
473 int nlwMiddle;
474 register int nlw;
475 int x, y, w, h, xrem, xSrc, ySrc;
476 int stwidth, stippleWidth;
477 int stippleHeight;
478 register CfbBits bits, inputBits;
479 register int partBitsLeft;
480 int nextPartBits;
481 int bitsLeft, bitsWhole;
482 register CfbBits *pdst; /* pointer to current word in bitmap */
483 CfbBits *srcTemp, *srcStart;
484 CfbBits *psrcBase;
485 CfbBits startmask, endmask;
487 if (pGC->fillStyle == FillStippled)
488 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
489 else
490 cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
492 if (cfb8StippleRRop == GXnoop)
493 return;
496 * OK, so what's going on here? We have two Drawables:
498 * The Stipple:
499 * Depth = 1
500 * Width = stippleWidth
501 * Words per scanline = stwidth
502 * Pointer to pixels = pStipple->devPrivate.ptr
505 pStipple = pGC->stipple;
507 stwidth = pStipple->devKind >> PWSH;
508 stippleWidth = pStipple->drawable.width;
509 stippleHeight = pStipple->drawable.height;
510 psrcBase = (CfbBits *) pStipple->devPrivate.ptr;
513 * The Target:
514 * Depth = PSZ
515 * Width = determined from *pwidth
516 * Words per scanline = nlwDst
517 * Pointer to pixels = addrlBase
520 xSrc = pDrawable->x;
521 ySrc = pDrawable->y;
523 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
525 /* this replaces rotating the stipple. Instead we just adjust the offset
526 * at which we start grabbing bits from the stipple.
527 * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
528 * so that iline and xrem always stay within the stipple bounds.
531 xSrc += (pGC->patOrg.x % stippleWidth) - stippleWidth;
532 ySrc += (pGC->patOrg.y % stippleHeight) - stippleHeight;
534 bitsWhole = stippleWidth;
536 while (nBox--)
538 x = pBox->x1;
539 y = pBox->y1;
540 w = pBox->x2 - x;
541 h = pBox->y2 - y;
542 pBox++;
543 pdstLine = pdstBase + y * nlwDst + (x >> PWSH);
544 y = (y - ySrc) % stippleHeight;
545 srcStart = psrcBase + y * stwidth;
546 xrem = ((x & ~PIM) - xSrc) % stippleWidth;
547 if (((x & PIM) + w) < PPW)
549 maskpartialbits (x, w, startmask);
550 nlwMiddle = 0;
551 endmask = 0;
553 else
555 maskbits (x, w, startmask, endmask, nlwMiddle);
557 while (h--)
559 srcTemp = srcStart + (xrem >> MFB_PWSH);
560 bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
561 NextUnnaturalStippleWord
562 NextSomeBits (inputBits, (xrem & MFB_PIM));
563 partBitsLeft -= (xrem & MFB_PIM);
564 NextUnnaturalStippleBits
565 nlw = nlwMiddle;
566 pdst = pdstLine;
567 if (startmask)
569 *pdst = MaskRRopPixels(*pdst,bits,startmask);
570 pdst++;
571 NextUnnaturalStippleBits
573 while (nlw--)
575 *pdst = RRopPixels(*pdst,bits);
576 pdst++;
577 NextUnnaturalStippleBits
579 if (endmask)
580 *pdst = MaskRRopPixels(*pdst,bits,endmask);
581 pdstLine += nlwDst;
582 y++;
583 srcStart += stwidth;
584 if (y == stippleHeight)
586 y = 0;
587 srcStart = psrcBase;
593 #endif /* PSZ == 8 */