2 * Copyright © 1998 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
23 #ifdef HAVE_DIX_CONFIG_H
24 #include <dix-config.h>
30 * This is a slight abuse of the preprocessor to generate repetitive
31 * code, the idea is to generate code for each case of a copy-mode
34 #define LaneCases1(c,a) case c: \
35 while (n--) { FbLaneCase(c,a); a++; } \
37 #define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
38 #define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
39 #define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a)
40 #define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a)
41 #define LaneCases32(c,a) LaneCases16(c,a); LaneCases16(c+16,a)
42 #define LaneCases64(c,a) LaneCases32(c,a); LaneCases32(c+32,a)
43 #define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a)
44 #define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a)
47 #define LaneCases(a) LaneCases256(0,a)
51 #define LaneCases(a) LaneCases16(0,a)
55 * Repeat a transparent stipple across a scanline n times
59 fbTransparentSpan(FbBits
* dst
, FbBits stip
, FbBits fgxor
, int n
)
63 s
= ((FbStip
) (stip
) & 0x01);
64 s
|= ((FbStip
) (stip
>> 8) & 0x02);
65 s
|= ((FbStip
) (stip
>> 16) & 0x04);
66 s
|= ((FbStip
) (stip
>> 24) & 0x08);
68 s
|= ((FbStip
) (stip
>> 32) & 0x10);
69 s
|= ((FbStip
) (stip
>> 40) & 0x20);
70 s
|= ((FbStip
) (stip
>> 48) & 0x40);
71 s
|= ((FbStip
) (stip
>> 56) & 0x80);
79 fbEvenStipple(FbBits
* dst
,
89 FbBits fgxor
, FbBits bgand
, FbBits bgxor
, int xRot
, int yRot
)
91 FbBits startmask
, endmask
;
92 FbBits mask
, and, xor;
94 FbStip
*s
, *stipEnd
, bits
;
95 int rot
, stipX
, stipY
;
99 int startbyte
, endbyte
;
102 * Check for a transparent stipple (stencil)
105 if (dstBpp
>= 8 && fgand
== 0 && bgand
== FB_ALLONES
&& bgxor
== 0)
108 pixelsPerDst
= FB_UNIT
/ dstBpp
;
110 * Adjust dest pointers
112 dst
+= dstX
>> FB_SHIFT
;
114 FbMaskBitsBytes(dstX
, width
, fgand
== 0 && bgand
== 0,
115 startmask
, startbyte
, nmiddle
, endmask
, endbyte
);
119 dstStride
-= nmiddle
;
123 * Compute stip start scanline and rotation parameters
125 stipEnd
= stip
+ stipStride
* stipHeight
;
126 modulus(-yRot
, stipHeight
, stipY
);
127 s
= stip
+ stipStride
* stipY
;
128 modulus(-xRot
, FB_UNIT
, stipX
);
132 * Get pointer to stipple mask array for this depth
134 /* fbStippleTable covers all valid bpp (4,8,16,32) */
135 fbBits
= fbStippleTable
[pixelsPerDst
];
139 * Extract stipple bits for this scanline;
146 if (pixelsPerDst
== 16)
147 mask
= FbStipple16Bits(FbLeftStipBits(bits
, 16));
150 mask
= fbBits
[FbLeftStipBits(bits
, pixelsPerDst
)];
152 * Rotate into position and compute reduced rop values
154 mask
= FbRotLeft(mask
, rot
);
155 and = (fgand
& mask
) | (bgand
& ~mask
);
156 xor = (fgxor
& mask
) | (bgxor
& ~mask
);
160 fbTransparentSpan(dst
, mask
& startmask
, fgxor
, 1);
163 fbTransparentSpan(dst
, mask
, fgxor
, nmiddle
);
166 fbTransparentSpan(dst
, mask
& endmask
, fgxor
, 1);
173 FbDoLeftMaskByteRRop(dst
, startbyte
, startmask
, and, xor);
182 WRITE(dst
, FbDoRRop(READ(dst
), and, xor));
187 FbDoRightMaskByteRRop(dst
, endbyte
, endmask
, and, xor);
194 fbOddStipple(FbBits
* dst
,
205 FbBits fgxor
, FbBits bgand
, FbBits bgxor
, int xRot
, int yRot
)
207 int stipX
, stipY
, sx
;
212 modulus(-yRot
, stipHeight
, stipY
);
213 modulus(dstX
/ dstBpp
- xRot
, stipWidth
, stipX
);
216 h
= stipHeight
- stipY
;
224 w
= (stipWidth
- sx
) * dstBpp
;
228 fbBltOne(stip
+ stipY
* stipStride
,
232 dstStride
, x
, dstBpp
, w
, h
, fgand
, fgxor
, bgand
, bgxor
);
242 fbStipple(FbBits
* dst
,
254 FbBits fgxor
, FbBits bgand
, FbBits bgxor
, int xRot
, int yRot
)
257 fbEvenStipple(dst
, dstStride
, dstX
, dstBpp
, width
, height
,
258 stip
, stipStride
, stipHeight
,
259 fgand
, fgxor
, bgand
, bgxor
, xRot
, yRot
);
261 fbOddStipple(dst
, dstStride
, dstX
, dstBpp
, width
, height
,
262 stip
, stipStride
, stipWidth
, stipHeight
,
263 fgand
, fgxor
, bgand
, bgxor
, xRot
, yRot
);