First import
[xorg_rtime.git] / xorg-server-1.4 / cfb / cfbbresd.c
blobee48a74ecdb9b73be7f8c8ef4c13a87e1a6f3586
1 /***********************************************************
3 Copyright 1987, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
26 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28 All Rights Reserved
30 Permission to use, copy, modify, and distribute this software and its
31 documentation for any purpose and without fee is hereby granted,
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44 SOFTWARE.
46 ******************************************************************/
47 #ifdef HAVE_DIX_CONFIG_H
48 #include <dix-config.h>
49 #endif
51 #include <X11/X.h>
52 #include "misc.h"
53 #include "cfb.h"
54 #include "cfbmskbits.h"
55 #include "miline.h"
57 /* Dashed bresenham line */
59 void
60 cfbBresD(rrops,
61 pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash,
62 addrl, nlwidth,
63 signdx, signdy, axis, x1, y1, e, e1, e2, len)
64 cfbRRopPtr rrops;
65 int *pdashIndex; /* current dash */
66 unsigned char *pDash; /* dash list */
67 int numInDashList; /* total length of dash list */
68 int *pdashOffset; /* offset into current dash */
69 int isDoubleDash;
70 CfbBits *addrl; /* pointer to base of bitmap */
71 int nlwidth; /* width in longwords of bitmap */
72 int signdx, signdy; /* signs of directions */
73 int axis; /* major axis (Y_AXIS or X_AXIS) */
74 int x1, y1; /* initial point */
75 register int e; /* error accumulator */
76 register int e1; /* bresenham increments */
77 int e2;
78 int len; /* length of line */
80 #ifdef PIXEL_ADDR
81 register PixelType *addrp;
82 #endif
83 register int e3 = e2-e1;
84 int dashIndex;
85 int dashOffset;
86 int dashRemaining;
87 CfbBits xorFg, andFg, xorBg, andBg;
88 Bool isCopy;
89 int thisDash;
90 #if PSZ == 24
91 CfbBits xorPiQxlFg[3], andPiQxlFg[3], xorPiQxlBg[3], andPiQxlBg[3];
92 char *addrb;
93 int signdx3, signdy3;
94 #endif
96 dashOffset = *pdashOffset;
97 dashIndex = *pdashIndex;
98 isCopy = (rrops[0].rop == GXcopy && rrops[1].rop == GXcopy);
99 #if PSZ == 24
100 xorFg = rrops[0].xor & 0xffffff;
101 andFg = rrops[0].and & 0xffffff;
102 xorBg = rrops[1].xor & 0xffffff;
103 andBg = rrops[1].and & 0xffffff;
104 xorPiQxlFg[0] = xorFg | (xorFg << 24);
105 xorPiQxlFg[1] = (xorFg >> 8) | (xorFg << 16);
106 xorPiQxlFg[2] = (xorFg >> 16) | (xorFg << 8);
107 andPiQxlFg[0] = andFg | (andFg << 24);
108 andPiQxlFg[1] = (andFg >> 8) | (andFg << 16);
109 andPiQxlFg[2] = (andFg >> 16) | (andFg << 8);
110 xorPiQxlBg[0] = xorBg | (xorBg << 24);
111 xorPiQxlBg[1] = (xorBg >> 8) | (xorBg << 16);
112 xorPiQxlBg[2] = (xorBg >> 16) | (xorBg << 8);
113 andPiQxlBg[0] = andBg | (andBg << 24);
114 andPiQxlBg[1] = (andBg >> 8) | (andBg << 16);
115 andPiQxlBg[2] = (andFg >> 16) | (andBg << 8);
116 #else
117 xorFg = rrops[0].xor;
118 andFg = rrops[0].and;
119 xorBg = rrops[1].xor;
120 andBg = rrops[1].and;
121 #endif
122 dashRemaining = pDash[dashIndex] - dashOffset;
123 if ((thisDash = dashRemaining) >= len)
125 thisDash = len;
126 dashRemaining -= len;
128 e = e-e1; /* to make looping easier */
130 #define BresStep(minor,major) {if ((e += e1) >= 0) { e += e3; minor; } major;}
132 #define NextDash {\
133 dashIndex++; \
134 if (dashIndex == numInDashList) \
135 dashIndex = 0; \
136 dashRemaining = pDash[dashIndex]; \
137 if ((thisDash = dashRemaining) >= len) \
139 dashRemaining -= len; \
140 thisDash = len; \
144 #ifdef PIXEL_ADDR
146 #if PSZ == 24
147 #define Loop(store) while (thisDash--) {\
148 store; \
149 BresStep(addrb+=signdy3,addrb+=signdx3) \
151 /* point to first point */
152 nlwidth <<= PWSH;
153 addrp = (PixelType *)(addrl) + (y1 * nlwidth);
154 addrb = (char *)addrp + x1 * 3;
156 #else
157 #define Loop(store) while (thisDash--) {\
158 store; \
159 BresStep(addrp+=signdy,addrp+=signdx) \
161 /* point to first point */
162 nlwidth <<= PWSH;
163 addrp = (PixelType *)(addrl) + (y1 * nlwidth) + x1;
164 #endif
165 signdy *= nlwidth;
166 #if PSZ == 24
167 signdx3 = signdx * 3;
168 signdy3 = signdy * sizeof (CfbBits);
169 #endif
170 if (axis == Y_AXIS)
172 int t;
174 t = signdx;
175 signdx = signdy;
176 signdy = t;
177 #if PSZ == 24
178 t = signdx3;
179 signdx3 = signdy3;
180 signdy3 = t;
181 #endif
184 if (isCopy)
186 #if PSZ == 24
187 #define body_copy(pix) { \
188 addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
189 switch((unsigned long)addrb & 3){ \
190 case 0: \
191 *addrp = (*addrp & 0xFF000000)|((pix)[0] & 0xFFFFFF); \
192 break; \
193 case 1: \
194 *addrp = (*addrp & 0xFF)|((pix)[2] & 0xFFFFFF00); \
195 break; \
196 case 3: \
197 *addrp = (*addrp & 0xFFFFFF)|((pix)[0] & 0xFF000000); \
198 *(addrp+1) = (*(addrp+1) & 0xFFFF0000)|((pix)[1] & 0xFFFF); \
199 break; \
200 case 2: \
201 *addrp = (*addrp & 0xFFFF)|((pix)[1] & 0xFFFF0000); \
202 *(addrp+1) = (*(addrp+1) & 0xFFFFFF00)|((pix)[2] & 0xFF); \
203 break; \
206 #endif /* PSZ == 24 */
208 for (;;)
210 len -= thisDash;
211 if (dashIndex & 1) {
212 if (isDoubleDash) {
213 #if PSZ == 24
214 Loop(body_copy(xorPiQxlBg))
215 #else
216 Loop(*addrp = xorBg)
217 #endif
218 } else {
219 Loop(;)
221 } else {
222 #if PSZ == 24
223 Loop(body_copy(xorPiQxlFg))
224 #else
225 Loop(*addrp = xorFg)
226 #endif
228 if (!len)
229 break;
230 NextDash
232 #undef body_copy
234 else
236 #define body_set(and, xor) { \
237 addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
238 switch((unsigned long)addrb & 3){ \
239 case 0: \
240 *addrp = (*addrp & ((and)[0]|0xFF000000)) ^ ((xor)[0] & 0xFFFFFF); \
241 break; \
242 case 1: \
243 *addrp = (*addrp & ((and)[2]|0xFF)) ^ ((xor)[2] & 0xFFFFFF00); \
244 break; \
245 case 3: \
246 *addrp = (*addrp & ((and)[0]|0xFFFFFF)) ^ ((xor)[0] & 0xFF000000); \
247 *(addrp+1)=(*(addrp+1)&((and)[1]|0xFFFF0000)) ^ ((xor)[1]&0xFFFF); \
248 break; \
249 case 2: \
250 *addrp = (*addrp & ((and)[1]|0xFFFF)) ^ ((xor)[1] & 0xFFFF0000); \
251 *(addrp+1)=(*(addrp+1)&((and)[2]|0xFFFFFF00)) ^ ((xor)[2] & 0xFF); \
252 break; \
256 for (;;)
258 len -= thisDash;
259 if (dashIndex & 1) {
260 if (isDoubleDash) {
261 #if PSZ == 24
262 Loop(body_set(andPiQxlBg, xorPiQxlBg))
263 #else
264 Loop(*addrp = DoRRop(*addrp,andBg, xorBg))
265 #endif
266 } else {
267 Loop(;)
269 } else {
270 #if PSZ == 24
271 Loop(body_set(andPiQxlFg, xorPiQxlFg))
272 #else
273 Loop(*addrp = DoRRop(*addrp,andFg, xorFg))
274 #endif
276 if (!len)
277 break;
278 NextDash
280 #undef body_set
282 #else /* !PIXEL_ADDR */
284 register CfbBits tmp;
285 CfbBits startbit, bit;
287 /* point to longword containing first point */
288 #if PSZ == 24
289 addrl = (addrl + (y1 * nlwidth) + ((x1*3) >> 2);
290 #else
291 addrl = (addrl + (y1 * nlwidth) + (x1 >> PWSH));
292 #endif
293 signdy = signdy * nlwidth;
295 if (signdx > 0)
296 startbit = cfbmask[0];
297 else
298 #if PSZ == 24
299 startbit = cfbmask[(PPW-1)<<1];
300 bit = cfbmask[(x1 & 3)<<1];
301 #else
302 startbit = cfbmask[PPW-1];
303 bit = cfbmask[x1 & PIM];
304 #endif
306 #if PSZ == 24
307 #define X_Loop(store) while(thisDash--) {\
308 store; \
309 BresStep(addrl += signdy, \
310 if (signdx > 0) \
311 bit = SCRRIGHT(bit,1); \
312 else \
313 bit = SCRLEFT(bit,1); \
314 if (!bit) \
316 bit = startbit; \
317 addrl += signdx; \
318 }) \
320 #define Y_Loop(store) while(thisDash--) {\
321 store; \
322 BresStep(if (signdx > 0) \
323 bit = SCRRIGHT(bit,1); \
324 else \
325 bit = SCRLEFT(bit,1); \
326 if (!bit) \
328 bit = startbit; \
329 addrl += signdx; \
330 }, \
331 addrl += signdy) \
333 #else
334 #define X_Loop(store) while(thisDash--) {\
335 store; \
336 BresStep(addrl += signdy, \
337 if (signdx > 0) \
338 bit = SCRRIGHT(bit,1); \
339 else \
340 bit = SCRLEFT(bit,1); \
341 if (!bit) \
343 bit = startbit; \
344 addrl += signdx; \
345 }) \
347 #define Y_Loop(store) while(thisDash--) {\
348 store; \
349 BresStep(if (signdx > 0) \
350 bit = SCRRIGHT(bit,1); \
351 else \
352 bit = SCRLEFT(bit,1); \
353 if (!bit) \
355 bit = startbit; \
356 addrl += signdx; \
357 }, \
358 addrl += signdy) \
360 #endif
362 if (axis == X_AXIS)
364 for (;;)
366 len -= thisDash;
367 if (dashIndex & 1) {
368 if (isDoubleDash) {
369 X_Loop(*addrl = DoMaskRRop(*addrl, andBg, xorBg, bit));
370 } else {
371 X_Loop(;)
373 } else {
374 X_Loop(*addrl = DoMaskRRop(*addrl, andFg, xorFg, bit));
376 if (!len)
377 break;
378 NextDash
380 } /* if X_AXIS */
381 else
383 for (;;)
385 len -= thisDash;
386 if (dashIndex & 1) {
387 if (isDoubleDash) {
388 Y_Loop(*addrl = DoMaskRRop(*addrl, andBg, xorBg, bit));
389 } else {
390 Y_Loop(;)
392 } else {
393 Y_Loop(*addrl = DoMaskRRop(*addrl, andFg, xorFg, bit));
395 if (!len)
396 break;
397 NextDash
399 } /* else Y_AXIS */
401 #endif
402 *pdashIndex = dashIndex;
403 *pdashOffset = pDash[dashIndex] - dashRemaining;