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