2 * Fill 32 bit stippled rectangles for 8 bit frame buffers
6 Copyright (c) 1989 X Consortium
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of the X Consortium shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings
27 in this Software without prior written authorization from the X Consortium.
29 Author: Keith Packard, MIT X Consortium
33 /* $XConsortium: cfbrctstp8.c,v 1.17 94/04/17 20:28:59 dpw Exp $ */
34 /* $XFree86: xc/programs/Xserver/cfb/cfbrctstp8.c,v 3.0 1996/12/09 11:50:55 dawes Exp $ */
43 #include "pixmapstr.h"
44 #include "scrnintstr.h"
45 #include "windowstr.h"
48 #include "cfbmskbits.h"
51 #define MFB_CONSTS_ONLY
55 cfb8FillRectOpaqueStippled32 (pDrawable, pGC, nBox, pBox)
56 DrawablePtr pDrawable;
58 int nBox; /* number of boxes to fill */
59 register BoxPtr pBox; /* pointer to list of boxes to fill */
64 int nlwDst; /* width in longwords of the dest pixmap */
65 int w; /* width of current box */
66 register int h; /* height of current box */
67 unsigned long startmask;
68 unsigned long endmask; /* masks for reggedy bits at either end of line */
69 int nlwMiddle; /* number of longwords between sides of boxes */
70 register int nlw; /* loop version of nlwMiddle */
71 unsigned long *dstLine;
72 register unsigned long *dst; /* pointer to bits we're writing */
73 unsigned long *dstTmp;
74 int y; /* current scan line */
76 unsigned long *pbits;/* pointer to start of pixmap */
77 register unsigned long bits; /* bits from stipple */
79 register unsigned long xor, and;
84 devPriv = cfbGetGCPrivate(pGC);
85 stipple = devPriv->pRotatedPixmap;
87 cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
89 stippleHeight = stipple->drawable.height;
90 src = (unsigned long *)stipple->devPrivate.ptr;
92 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
96 w = pBox->x2 - pBox->x1;
97 h = pBox->y2 - pBox->y1;
99 dstLine = pbits + (pBox->y1 * nlwDst) + ((pBox->x1 & ~PIM) >> PWSH);
100 if (((pBox->x1 & PIM) + w) <= PPW)
102 maskpartialbits(pBox->x1, w, startmask);
108 maskbits (pBox->x1, w, startmask, endmask, nlwMiddle);
110 rot = (pBox->x1 & ((PGSZ-1) & ~PIM));
112 y = y % stippleHeight;
114 if (cfb8StippleRRop == GXcopy)
122 if (y == stippleHeight)
125 RotBitsLeft(bits,rot);
130 *dst = *dst & ~startmask |
131 GetPixelGroup (bits) & startmask;
133 RotBitsLeft (bits, PGSZB);
138 *dst++ = GetPixelGroup(bits);
139 RotBitsLeft (bits, PGSZB);
143 *dst = *dst & ~endmask |
144 GetPixelGroup (bits) & endmask;
150 wEnd = 7 - (nlwMiddle & 7);
151 nlwMiddle = (nlwMiddle >> 3) + 1;
156 if (y == stippleHeight)
159 RotBitsLeft (bits, rot);
164 *dstTmp = *dstTmp & ~startmask |
165 GetPixelGroup (bits) & startmask;
167 RotBitsLeft (bits, PGSZB);
175 xor = GetPixelGroup (bits);
187 dst = dstTmp + (nlwMiddle << 3);
188 *dst = (*dst & ~endmask) |
189 GetPixelGroup (bits) & endmask;
196 xor = GetPixelGroup (bits);
209 #endif /* PPW == 4 */
215 if (y == stippleHeight)
218 RotBitsLeft(bits,rot);
223 xor = GetBitGroup(bits);
224 *dst = MaskRRopPixels(*dst, xor, startmask);
226 RotBitsLeft (bits, PGSZB);
231 RRopBitGroup(dst, GetBitGroup(bits));
233 RotBitsLeft (bits, PGSZB);
237 xor = GetBitGroup(bits);
238 *dst = MaskRRopPixels(*dst, xor, endmask);
246 cfb8FillRectTransparentStippled32 (pDrawable, pGC, nBox, pBox)
247 DrawablePtr pDrawable;
249 int nBox; /* number of boxes to fill */
250 BoxPtr pBox; /* pointer to list of boxes to fill */
253 int nlwMiddle, nlwDst, nlwTmp;
254 unsigned long startmask, endmask;
255 register unsigned long *dst;
256 unsigned long *dstLine, *pbits, *dstTmp;
258 register unsigned long xor;
259 register unsigned long bits, mask;
262 cfbPrivGCPtr devPriv;
267 devPriv = cfbGetGCPrivate(pGC);
268 stipple = devPriv->pRotatedPixmap;
269 src = (unsigned long *)stipple->devPrivate.ptr;
270 stippleHeight = stipple->drawable.height;
272 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
274 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
280 if (((x & PIM) + w) <= PPW)
282 maskpartialbits(x, w, startmask);
288 maskbits (x, w, startmask, endmask, nlwMiddle);
290 rot = (x & ((PGSZ-1) & ~PIM));
292 dstLine = pbits + (y * nlwDst) + (x >> PWSH);
297 if (cfb8StippleRRop == GXcopy)
306 if (y == stippleHeight)
309 RotBitsLeft (bits, rot);
314 mask = cfb8PixelMasks[GetBitGroup(bits)];
315 *dst = (*dst & ~(mask & startmask)) |
316 (xor & (mask & startmask));
318 RotBitsLeft (bits, PGSZB);
323 WriteBitGroup (dst,xor,GetBitGroup(bits))
325 RotBitsLeft (bits, PGSZB);
329 mask = cfb8PixelMasks[GetBitGroup(bits)];
330 *dst = (*dst & ~(mask & endmask)) |
331 (xor & (mask & endmask));
337 wEnd = 7 - (nlwMiddle & 7);
338 nlwMiddle = (nlwMiddle >> 3) + 1;
343 if (y == stippleHeight)
346 RotBitsLeft (bits, rot);
351 mask = cfb8PixelMasks[GetBitGroup(bits)];
352 *dstTmp = (*dstTmp & ~(mask & startmask)) |
353 (xor & (mask & startmask));
355 RotBitsLeft (bits, PGSZB);
363 #if defined(__GNUC__) && defined(mc68020)
364 mask = cfb8PixelMasks[GetBitGroup(bits)];
369 *dst = (*dst & mask) | xor;
374 #define SwitchBitsLoop(body) \
380 SwitchBitGroup(dst, xor, GetBitGroup(bits));
381 #undef SwitchBitsLoop
389 mask = cfb8PixelMasks[GetBitGroup(bits)];
390 dst = dstTmp + (nlwMiddle << 3);
391 *dst = (*dst & ~(mask & endmask)) |
392 (xor & (mask & endmask));
399 #if defined(__GNUC__) && defined(mc68020)
400 mask = cfb8PixelMasks[GetBitGroup(bits)];
405 *dst = (*dst & mask) | xor;
410 #define SwitchBitsLoop(body) \
416 SwitchBitGroup(dst, xor, GetBitGroup(bits));
417 #undef SwitchBitsLoop
426 #endif /* PPW == 4 */
432 if (y == stippleHeight)
435 RotBitsLeft (bits, rot);
440 xor = GetBitGroup(bits);
441 *dst = MaskRRopPixels(*dst, xor, startmask);
443 RotBitsLeft (bits, PGSZB);
448 RRopBitGroup(dst, GetBitGroup(bits));
450 RotBitsLeft (bits, PGSZB);
454 xor = GetBitGroup(bits);
455 *dst = MaskRRopPixels(*dst, xor, endmask);
464 cfb8FillRectStippledUnnatural (pDrawable, pGC, nBox, pBox)
465 DrawablePtr pDrawable;
468 register BoxPtr pBox;
470 unsigned long *pdstBase; /* pointer to start of bitmap */
471 unsigned long *pdstLine; /* current destination line */
472 int nlwDst; /* width in longwords of bitmap */
473 PixmapPtr pStipple; /* pointer to stipple we want to fill with */
476 int x, y, w, h, xrem, xSrc, ySrc;
477 int stwidth, stippleWidth;
479 register unsigned long bits, inputBits;
480 register int partBitsLeft;
482 int bitsLeft, bitsWhole;
483 register unsigned long *pdst; /* pointer to current word in bitmap */
484 unsigned long *srcTemp, *srcStart;
485 unsigned long *psrcBase;
486 unsigned long startmask, endmask;
488 if (pGC->fillStyle == FillStippled)
489 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
491 cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
493 if (cfb8StippleRRop == GXnoop)
497 * OK, so what's going on here? We have two Drawables:
501 * Width = stippleWidth
502 * Words per scanline = stwidth
503 * Pointer to pixels = pStipple->devPrivate.ptr
506 pStipple = pGC->stipple;
508 stwidth = pStipple->devKind >> PWSH;
509 stippleWidth = pStipple->drawable.width;
510 stippleHeight = pStipple->drawable.height;
511 psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
516 * Width = determined from *pwidth
517 * Words per scanline = nlwDst
518 * Pointer to pixels = addrlBase
524 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
526 /* this replaces rotating the stipple. Instead we just adjust the offset
527 * at which we start grabbing bits from the stipple.
528 * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
529 * so that iline and xrem always stay within the stipple bounds.
532 xSrc += (pGC->patOrg.x % stippleWidth) - stippleWidth;
533 ySrc += (pGC->patOrg.y % stippleHeight) - stippleHeight;
535 bitsWhole = stippleWidth;
544 pdstLine = pdstBase + y * nlwDst + (x >> PWSH);
545 y = (y - ySrc) % stippleHeight;
546 srcStart = psrcBase + y * stwidth;
547 xrem = ((x & ~PIM) - xSrc) % stippleWidth;
548 if (((x & PIM) + w) < PPW)
550 maskpartialbits (x, w, startmask);
556 maskbits (x, w, startmask, endmask, nlwMiddle);
560 srcTemp = srcStart + (xrem >> MFB_PWSH);
561 bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
562 NextUnnaturalStippleWord
563 NextSomeBits (inputBits, (xrem & MFB_PIM));
564 partBitsLeft -= (xrem & MFB_PIM);
565 NextUnnaturalStippleBits
570 *pdst = MaskRRopPixels(*pdst,bits,startmask);
572 NextUnnaturalStippleBits
576 *pdst = RRopPixels(*pdst,bits);
578 NextUnnaturalStippleBits
581 *pdst = MaskRRopPixels(*pdst,bits,endmask);
585 if (y == stippleHeight)
594 #endif /* PSZ == 8 */