]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbrctstp8.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbrctstp8.c
1 /*
2  * Fill 32 bit stippled rectangles for 8 bit frame buffers
3  */
4 /*
5
6 Copyright (c) 1989  X Consortium
7
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:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
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.
24
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.
28
29 Author: Keith Packard, MIT X Consortium
30
31 */
32
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 $ */
35
36 #if PSZ == 8
37
38 #include "X.h"
39 #include "Xmd.h"
40 #include "servermd.h"
41 #include "gcstruct.h"
42 #include "window.h"
43 #include "pixmapstr.h"
44 #include "scrnintstr.h"
45 #include "windowstr.h"
46
47 #include "cfb.h"
48 #include "cfbmskbits.h"
49 #include "cfb8bit.h"
50
51 #define MFB_CONSTS_ONLY
52 #include "maskbits.h"
53
54 void
55 cfb8FillRectOpaqueStippled32 (pDrawable, pGC, nBox, pBox)
56     DrawablePtr     pDrawable;
57     GCPtr           pGC;
58     int             nBox;       /* number of boxes to fill */
59     register BoxPtr pBox;       /* pointer to list of boxes to fill */
60 {
61     unsigned long   *src;
62     int stippleHeight;
63
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 */
75
76     unsigned long *pbits;/* pointer to start of pixmap */
77     register unsigned long bits;        /* bits from stipple */
78     int rot, lastStop, i;
79     register unsigned long  xor, and;
80     cfbPrivGCPtr            devPriv;
81     PixmapPtr               stipple;
82     int     wEnd;
83
84     devPriv = cfbGetGCPrivate(pGC);
85     stipple = devPriv->pRotatedPixmap;
86
87     cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
88
89     stippleHeight = stipple->drawable.height;
90     src = (unsigned long *)stipple->devPrivate.ptr;
91
92     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
93
94     while (nBox--)
95     {
96         w = pBox->x2 - pBox->x1;
97         h = pBox->y2 - pBox->y1;
98         y = pBox->y1;
99         dstLine = pbits + (pBox->y1 * nlwDst) + ((pBox->x1 & ~PIM) >> PWSH);
100         if (((pBox->x1 & PIM) + w) <= PPW)
101         {
102             maskpartialbits(pBox->x1, w, startmask);
103             nlwMiddle = 0;
104             endmask = 0;
105         }
106         else
107         {
108             maskbits (pBox->x1, w, startmask, endmask, nlwMiddle);
109         }
110         rot = (pBox->x1 & ((PGSZ-1) & ~PIM));
111         pBox++;
112         y = y % stippleHeight;
113 #if PPW == 4
114         if (cfb8StippleRRop == GXcopy)
115         {
116             if (w < PGSZ*2)
117             {
118                 while (h--)
119                 {
120                     bits = src[y];
121                     y++;
122                     if (y == stippleHeight)
123                         y = 0;
124                     if (rot)
125                         RotBitsLeft(bits,rot);
126                     dst = dstLine;
127                     dstLine += nlwDst;
128                     if (startmask)
129                     {
130                         *dst = *dst & ~startmask |
131                                 GetPixelGroup (bits) & startmask;
132                         dst++;
133                         RotBitsLeft (bits, PGSZB);
134                     }
135                     nlw = nlwMiddle;
136                     while (nlw--)
137                     {
138                         *dst++ = GetPixelGroup(bits);
139                         RotBitsLeft (bits, PGSZB);
140                     }
141                     if (endmask)
142                     {
143                         *dst = *dst & ~endmask |
144                               GetPixelGroup (bits) & endmask;
145                     }
146                 }
147             }
148             else
149             {
150                 wEnd = 7 - (nlwMiddle & 7);
151                 nlwMiddle = (nlwMiddle >> 3) + 1;
152                 while (h--)
153                 {
154                     bits = src[y];
155                     y++;
156                     if (y == stippleHeight)
157                         y = 0;
158                     if (rot != 0)
159                         RotBitsLeft (bits, rot);
160                     dstTmp = dstLine;
161                     dstLine += nlwDst;
162                     if (startmask)
163                     {
164                         *dstTmp = *dstTmp & ~startmask |
165                                GetPixelGroup (bits) & startmask;
166                         dstTmp++;
167                         RotBitsLeft (bits, PGSZB);
168                     }
169                     w = 7 - wEnd;
170                     while (w--)
171                     {
172                         nlw = nlwMiddle;
173                         dst = dstTmp;
174                         dstTmp++;
175                         xor = GetPixelGroup (bits);
176                         while (nlw--)
177                         {
178                             *dst = xor;
179                             dst += 8;
180                         }
181                         NextBitGroup (bits);
182                     }
183                     nlwMiddle--;
184                     w = wEnd + 1;
185                     if (endmask)
186                     {
187                         dst = dstTmp + (nlwMiddle << 3);
188                         *dst = (*dst & ~endmask) |
189                                GetPixelGroup (bits) & endmask;
190                     }
191                     while (w--)
192                     {
193                         nlw = nlwMiddle;
194                         dst = dstTmp;
195                         dstTmp++;
196                         xor = GetPixelGroup (bits);
197                         while (nlw--)
198                         {
199                             *dst = xor;
200                             dst += 8;
201                         }
202                         NextBitGroup (bits);
203                     }
204                     nlwMiddle++;
205                 }
206             }
207         }
208         else
209 #endif /* PPW == 4 */
210         {
211             while (h--)
212             {
213                 bits = src[y];
214                 y++;
215                 if (y == stippleHeight)
216                     y = 0;
217                 if (rot)
218                     RotBitsLeft(bits,rot);
219                 dst = dstLine;
220                 dstLine += nlwDst;
221                 if (startmask)
222                 {
223                     xor = GetBitGroup(bits);
224                     *dst = MaskRRopPixels(*dst, xor, startmask);
225                     dst++;
226                     RotBitsLeft (bits, PGSZB);
227                 }
228                 nlw = nlwMiddle;
229                 while (nlw--)
230                 {
231                     RRopBitGroup(dst, GetBitGroup(bits));
232                     dst++;
233                     RotBitsLeft (bits, PGSZB);
234                 }
235                 if (endmask)
236                 {
237                     xor = GetBitGroup(bits);
238                     *dst = MaskRRopPixels(*dst, xor, endmask);
239                 }
240             }
241         }
242     }
243 }
244
245 void
246 cfb8FillRectTransparentStippled32 (pDrawable, pGC, nBox, pBox)
247     DrawablePtr     pDrawable;
248     GCPtr           pGC;
249     int             nBox;       /* number of boxes to fill */
250     BoxPtr          pBox;       /* pointer to list of boxes to fill */
251 {
252     int             x, y, w, h;
253     int             nlwMiddle, nlwDst, nlwTmp;
254     unsigned long   startmask, endmask;
255     register unsigned long   *dst;
256     unsigned long   *dstLine, *pbits, *dstTmp;
257     unsigned long   *src;
258     register unsigned long   xor;
259     register unsigned long   bits, mask;
260     int             rot;
261     int             wEnd;
262     cfbPrivGCPtr    devPriv;
263     PixmapPtr       stipple;
264     int             stippleHeight;
265     register int    nlw;
266     
267     devPriv = cfbGetGCPrivate(pGC);
268     stipple = devPriv->pRotatedPixmap;
269     src = (unsigned long *)stipple->devPrivate.ptr;
270     stippleHeight = stipple->drawable.height;
271
272     cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
273
274     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
275
276     while (nBox--)
277     {
278         x = pBox->x1;
279         w = pBox->x2 - x;
280         if (((x & PIM) + w) <= PPW)
281         {
282             maskpartialbits(x, w, startmask);
283             endmask = 0;
284             nlwMiddle = 0;
285         }
286         else
287         {
288             maskbits (x, w, startmask, endmask, nlwMiddle);
289         }
290         rot = (x & ((PGSZ-1) & ~PIM));
291         y = pBox->y1;
292         dstLine = pbits + (y * nlwDst) + (x >> PWSH);
293         h = pBox->y2 - y;
294         pBox++;
295         y %= stippleHeight;
296 #if PPW == 4
297         if (cfb8StippleRRop == GXcopy)
298         {
299             xor = devPriv->xor;
300             if (w < PGSZ*2)
301             {
302                 while (h--)
303                 {
304                     bits = src[y];
305                     y++;
306                     if (y == stippleHeight)
307                         y = 0;
308                     if (rot != 0)
309                         RotBitsLeft (bits, rot);
310                     dst = dstLine;
311                     dstLine += nlwDst;
312                     if (startmask)
313                     {
314                         mask = cfb8PixelMasks[GetBitGroup(bits)];
315                         *dst = (*dst & ~(mask & startmask)) |
316                                (xor & (mask & startmask));
317                         dst++;
318                         RotBitsLeft (bits, PGSZB);
319                     }
320                     nlw = nlwMiddle;
321                     while (nlw--)
322                     {
323                         WriteBitGroup (dst,xor,GetBitGroup(bits))
324                         dst++;
325                         RotBitsLeft (bits, PGSZB);
326                     }
327                     if (endmask)
328                     {
329                         mask = cfb8PixelMasks[GetBitGroup(bits)];
330                         *dst = (*dst & ~(mask & endmask)) |
331                                (xor & (mask & endmask));
332                     }
333                 }
334             }
335             else
336             {
337                 wEnd = 7 - (nlwMiddle & 7);
338                 nlwMiddle = (nlwMiddle >> 3) + 1;
339                 while (h--)
340                 {
341                     bits = src[y];
342                     y++;
343                     if (y == stippleHeight)
344                         y = 0;
345                     if (rot != 0)
346                         RotBitsLeft (bits, rot);
347                     dstTmp = dstLine;
348                     dstLine += nlwDst;
349                     if (startmask)
350                     {
351                         mask = cfb8PixelMasks[GetBitGroup(bits)];
352                         *dstTmp = (*dstTmp & ~(mask & startmask)) |
353                                (xor & (mask & startmask));
354                         dstTmp++;
355                         RotBitsLeft (bits, PGSZB);
356                     }
357                     w = 7 - wEnd;
358                     while (w--)
359                     {
360                         nlw = nlwMiddle;
361                         dst = dstTmp;
362                         dstTmp++;
363 #if defined(__GNUC__) && defined(mc68020)
364                         mask = cfb8PixelMasks[GetBitGroup(bits)];
365                         xor = xor & mask;
366                         mask = ~mask;
367                         while (nlw--)
368                         {
369                             *dst = (*dst & mask) | xor;
370                             dst += 8;
371                         }
372                         xor = devPriv->xor;
373 #else
374 #define SwitchBitsLoop(body) \
375         while (nlw--)   \
376         {               \
377             body        \
378             dst += 8;   \
379         }
380                         SwitchBitGroup(dst, xor, GetBitGroup(bits));
381 #undef SwitchBitsLoop
382 #endif
383                         NextBitGroup (bits);
384                     }
385                     nlwMiddle--;
386                     w = wEnd + 1;
387                     if (endmask)
388                     {
389                         mask = cfb8PixelMasks[GetBitGroup(bits)];
390                         dst = dstTmp + (nlwMiddle << 3);
391                         *dst = (*dst & ~(mask & endmask)) |
392                                (xor &  (mask & endmask));
393                     }
394                     while (w--)
395                     {
396                         nlw = nlwMiddle;
397                         dst = dstTmp;
398                         dstTmp++;
399 #if defined(__GNUC__) && defined(mc68020)
400                         mask = cfb8PixelMasks[GetBitGroup(bits)];
401                         xor = xor & mask;
402                         mask = ~mask;
403                         while (nlw--)
404                         {
405                             *dst = (*dst & mask) | xor;
406                             dst += 8;
407                         }
408                         xor = devPriv->xor;
409 #else
410 #define SwitchBitsLoop(body) \
411         while (nlw--)   \
412         {               \
413             body        \
414             dst += 8;   \
415         }
416                         SwitchBitGroup(dst, xor, GetBitGroup(bits));
417 #undef SwitchBitsLoop
418 #endif
419                         NextBitGroup (bits);
420                     }
421                     nlwMiddle++;
422                 }
423             }
424         }
425         else
426 #endif /* PPW == 4 */
427         {
428             while (h--)
429             {
430                 bits = src[y];
431                 y++;
432                 if (y == stippleHeight)
433                     y = 0;
434                 if (rot != 0)
435                     RotBitsLeft (bits, rot);
436                 dst = dstLine;
437                 dstLine += nlwDst;
438                 if (startmask)
439                 {
440                     xor = GetBitGroup(bits);
441                     *dst = MaskRRopPixels(*dst, xor, startmask);
442                     dst++;
443                     RotBitsLeft (bits, PGSZB);
444                 }
445                 nlw = nlwMiddle;
446                 while (nlw--)
447                 {
448                     RRopBitGroup(dst, GetBitGroup(bits));
449                     dst++;
450                     RotBitsLeft (bits, PGSZB);
451                 }
452                 if (endmask)
453                 {
454                     xor = GetBitGroup(bits);
455                     *dst = MaskRRopPixels(*dst, xor, endmask);
456                 }
457             }
458         }
459     }
460 }
461
462
463 void
464 cfb8FillRectStippledUnnatural (pDrawable, pGC, nBox, pBox)
465     DrawablePtr     pDrawable;
466     GCPtr           pGC;
467     int             nBox;
468     register BoxPtr pBox;
469 {
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 */
474     int             nlwMiddle;
475     register int    nlw;
476     int             x, y, w, h, xrem, xSrc, ySrc;
477     int             stwidth, stippleWidth;
478     int             stippleHeight;
479     register unsigned long  bits, inputBits;
480     register int    partBitsLeft;
481     int             nextPartBits;
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;
487
488     if (pGC->fillStyle == FillStippled)
489         cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
490     else
491         cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
492
493     if (cfb8StippleRRop == GXnoop)
494         return;
495
496     /*
497      *  OK,  so what's going on here?  We have two Drawables:
498      *
499      *  The Stipple:
500      *          Depth = 1
501      *          Width = stippleWidth
502      *          Words per scanline = stwidth
503      *          Pointer to pixels = pStipple->devPrivate.ptr
504      */
505
506     pStipple = pGC->stipple;
507
508     stwidth = pStipple->devKind >> PWSH;
509     stippleWidth = pStipple->drawable.width;
510     stippleHeight = pStipple->drawable.height;
511     psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
512
513     /*
514      *  The Target:
515      *          Depth = PSZ
516      *          Width = determined from *pwidth
517      *          Words per scanline = nlwDst
518      *          Pointer to pixels = addrlBase
519      */
520
521     xSrc = pDrawable->x;
522     ySrc = pDrawable->y;
523
524     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
525
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.
530      */
531
532     xSrc += (pGC->patOrg.x % stippleWidth) - stippleWidth;
533     ySrc += (pGC->patOrg.y % stippleHeight) - stippleHeight;
534
535     bitsWhole = stippleWidth;
536
537     while (nBox--)
538     {
539         x = pBox->x1;
540         y = pBox->y1;
541         w = pBox->x2 - x;
542         h = pBox->y2 - y;
543         pBox++;
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)
549         {
550             maskpartialbits (x, w, startmask);
551             nlwMiddle = 0;
552             endmask = 0;
553         }
554         else
555         {
556             maskbits (x, w, startmask, endmask, nlwMiddle);
557         }
558         while (h--)
559         {
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
566             nlw = nlwMiddle;
567             pdst = pdstLine;
568             if (startmask)
569             {
570                 *pdst = MaskRRopPixels(*pdst,bits,startmask);
571                 pdst++;
572                 NextUnnaturalStippleBits
573             }
574             while (nlw--)
575             {
576                 *pdst = RRopPixels(*pdst,bits);
577                 pdst++;
578                 NextUnnaturalStippleBits
579             }
580             if (endmask)
581                 *pdst = MaskRRopPixels(*pdst,bits,endmask);
582             pdstLine += nlwDst;
583             y++;
584             srcStart += stwidth;
585             if (y == stippleHeight)
586             {
587                 y = 0;
588                 srcStart = psrcBase;
589             }
590         }
591     }
592 }
593
594 #endif /* PSZ == 8 */