2 * Fill 32 bit stippled rectangles for 8 bit frame buffers
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
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>
44 #include "pixmapstr.h"
45 #include "scrnintstr.h"
46 #include "windowstr.h"
49 #include "cfbmskbits.h"
52 #define MFB_CONSTS_ONLY
56 cfb8FillRectOpaqueStippled32 (pDrawable
, pGC
, nBox
, pBox
)
57 DrawablePtr pDrawable
;
59 int nBox
; /* number of boxes to fill */
60 register BoxPtr pBox
; /* pointer to list of boxes to fill */
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 */
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 */
73 register CfbBits
*dst
; /* pointer to bits we're writing */
75 int y
; /* current scan line */
77 CfbBits
*pbits
;/* pointer to start of pixmap */
78 register CfbBits bits
; /* bits from stipple */
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
)
95 w
= pBox
->x2
- pBox
->x1
;
96 h
= pBox
->y2
- 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
);
107 maskbits (pBox
->x1
, w
, startmask
, endmask
, nlwMiddle
);
109 rot
= (pBox
->x1
& ((PGSZ
-1) & ~PIM
));
111 y
= y
% stippleHeight
;
113 if (cfb8StippleRRop
== GXcopy
)
121 if (y
== stippleHeight
)
124 RotBitsLeft(bits
,rot
);
129 *dst
= (*dst
& ~startmask
) |
130 (GetPixelGroup (bits
) & startmask
);
132 RotBitsLeft (bits
, PGSZB
);
137 *dst
++ = GetPixelGroup(bits
);
138 RotBitsLeft (bits
, PGSZB
);
142 *dst
= (*dst
& ~endmask
) |
143 (GetPixelGroup (bits
) & endmask
);
149 wEnd
= 7 - (nlwMiddle
& 7);
150 nlwMiddle
= (nlwMiddle
>> 3) + 1;
155 if (y
== stippleHeight
)
158 RotBitsLeft (bits
, rot
);
163 *dstTmp
= (*dstTmp
& ~startmask
) |
164 (GetPixelGroup (bits
) & startmask
);
166 RotBitsLeft (bits
, PGSZB
);
174 xor = GetPixelGroup (bits
);
186 dst
= dstTmp
+ (nlwMiddle
<< 3);
187 *dst
= (*dst
& ~endmask
) |
188 (GetPixelGroup(bits
) & endmask
);
195 xor = GetPixelGroup (bits
);
208 #endif /* PPW == 4 */
214 if (y
== stippleHeight
)
217 RotBitsLeft(bits
,rot
);
222 xor = GetBitGroup(bits
);
223 *dst
= MaskRRopPixels(*dst
, xor, startmask
);
225 RotBitsLeft (bits
, PGSZB
);
230 RRopBitGroup(dst
, GetBitGroup(bits
));
232 RotBitsLeft (bits
, PGSZB
);
236 xor = GetBitGroup(bits
);
237 *dst
= MaskRRopPixels(*dst
, xor, endmask
);
245 cfb8FillRectTransparentStippled32 (pDrawable
, pGC
, nBox
, pBox
)
246 DrawablePtr pDrawable
;
248 int nBox
; /* number of boxes to fill */
249 BoxPtr pBox
; /* pointer to list of boxes to fill */
252 int nlwMiddle
, nlwDst
;
253 CfbBits startmask
, endmask
;
254 register CfbBits
*dst
;
255 CfbBits
*dstLine
, *pbits
, *dstTmp
;
257 register CfbBits
xor;
258 register CfbBits bits
, mask
;
261 cfbPrivGCPtr devPriv
;
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
)
279 if (((x
& PIM
) + w
) <= PPW
)
281 maskpartialbits(x
, w
, startmask
);
287 maskbits (x
, w
, startmask
, endmask
, nlwMiddle
);
289 rot
= (x
& ((PGSZ
-1) & ~PIM
));
291 dstLine
= pbits
+ (y
* nlwDst
) + (x
>> PWSH
);
296 if (cfb8StippleRRop
== GXcopy
)
305 if (y
== stippleHeight
)
308 RotBitsLeft (bits
, rot
);
313 mask
= cfb8PixelMasks
[GetBitGroup(bits
)];
314 *dst
= (*dst
& ~(mask
& startmask
)) |
315 (xor & (mask
& startmask
));
317 RotBitsLeft (bits
, PGSZB
);
322 WriteBitGroup (dst
,xor,GetBitGroup(bits
))
324 RotBitsLeft (bits
, PGSZB
);
328 mask
= cfb8PixelMasks
[GetBitGroup(bits
)];
329 *dst
= (*dst
& ~(mask
& endmask
)) |
330 (xor & (mask
& endmask
));
336 wEnd
= 7 - (nlwMiddle
& 7);
337 nlwMiddle
= (nlwMiddle
>> 3) + 1;
342 if (y
== stippleHeight
)
345 RotBitsLeft (bits
, rot
);
350 mask
= cfb8PixelMasks
[GetBitGroup(bits
)];
351 *dstTmp
= (*dstTmp
& ~(mask
& startmask
)) |
352 (xor & (mask
& startmask
));
354 RotBitsLeft (bits
, PGSZB
);
362 #if defined(__GNUC__) && defined(mc68020)
363 mask
= cfb8PixelMasks
[GetBitGroup(bits
)];
368 *dst
= (*dst
& mask
) | xor;
373 #define SwitchBitsLoop(body) \
379 SwitchBitGroup(dst
, xor, GetBitGroup(bits
));
380 #undef SwitchBitsLoop
388 mask
= cfb8PixelMasks
[GetBitGroup(bits
)];
389 dst
= dstTmp
+ (nlwMiddle
<< 3);
390 *dst
= (*dst
& ~(mask
& endmask
)) |
391 (xor & (mask
& endmask
));
398 #if defined(__GNUC__) && defined(mc68020)
399 mask
= cfb8PixelMasks
[GetBitGroup(bits
)];
404 *dst
= (*dst
& mask
) | xor;
409 #define SwitchBitsLoop(body) \
415 SwitchBitGroup(dst
, xor, GetBitGroup(bits
));
416 #undef SwitchBitsLoop
425 #endif /* PPW == 4 */
431 if (y
== stippleHeight
)
434 RotBitsLeft (bits
, rot
);
439 xor = GetBitGroup(bits
);
440 *dst
= MaskRRopPixels(*dst
, xor, startmask
);
442 RotBitsLeft (bits
, PGSZB
);
447 RRopBitGroup(dst
, GetBitGroup(bits
));
449 RotBitsLeft (bits
, PGSZB
);
453 xor = GetBitGroup(bits
);
454 *dst
= MaskRRopPixels(*dst
, xor, endmask
);
463 cfb8FillRectStippledUnnatural (pDrawable
, pGC
, nBox
, pBox
)
464 DrawablePtr pDrawable
;
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 */
475 int x
, y
, w
, h
, xrem
, xSrc
, ySrc
;
476 int stwidth
, stippleWidth
;
478 register CfbBits bits
, inputBits
;
479 register int partBitsLeft
;
481 int bitsLeft
, bitsWhole
;
482 register CfbBits
*pdst
; /* pointer to current word in bitmap */
483 CfbBits
*srcTemp
, *srcStart
;
485 CfbBits startmask
, endmask
;
487 if (pGC
->fillStyle
== FillStippled
)
488 cfb8CheckStipple (pGC
->alu
, pGC
->fgPixel
, pGC
->planemask
);
490 cfb8CheckOpaqueStipple (pGC
->alu
, pGC
->fgPixel
, pGC
->bgPixel
, pGC
->planemask
);
492 if (cfb8StippleRRop
== GXnoop
)
496 * OK, so what's going on here? We have two Drawables:
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
;
515 * Width = determined from *pwidth
516 * Words per scanline = nlwDst
517 * Pointer to pixels = addrlBase
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
;
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
);
555 maskbits (x
, w
, startmask
, endmask
, nlwMiddle
);
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
569 *pdst
= MaskRRopPixels(*pdst
,bits
,startmask
);
571 NextUnnaturalStippleBits
575 *pdst
= RRopPixels(*pdst
,bits
);
577 NextUnnaturalStippleBits
580 *pdst
= MaskRRopPixels(*pdst
,bits
,endmask
);
584 if (y
== stippleHeight
)
593 #endif /* PSZ == 8 */