First import
[xorg_rtime.git] / xorg-server-1.4 / mfb / mfbfillsp.c
blob112f5327cf7d4d30fce3836c636f15ed53be41a8
1 /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
2 /***********************************************************
4 Copyright 1987, 1998 The Open Group
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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 OPEN GROUP 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.
22 Except as contained in this notice, the name of The Open Group 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 Open Group.
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
29 All Rights Reserved
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.
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.
47 ******************************************************************/
48 #ifdef HAVE_DIX_CONFIG_H
49 #include <dix-config.h>
50 #endif
52 #include <X11/X.h>
53 #include <X11/Xmd.h>
54 #include "gcstruct.h"
55 #include "window.h"
56 #include "pixmapstr.h"
57 #include "scrnintstr.h"
58 #include "windowstr.h"
59 #include "mfb.h"
60 #include "maskbits.h"
62 #include "mergerop.h"
64 #include "servermd.h"
65 #include "mi.h"
66 #include "mispans.h"
68 /* scanline filling for monochrome frame buffer
69 written by drewry, oct 1986
71 these routines all clip. they assume that anything that has called
72 them has already translated the points (i.e. pGC->miTranslate is
73 non-zero, which is howit gets set in mfbCreateGC().)
75 the number of new scnalines created by clipping ==
76 MaxRectsPerBand * nSpans.
78 FillSolid is overloaded to be used for OpaqueStipple as well,
79 if fgPixel == bgPixel.
82 FillTiled is overloaded to be used for OpaqueStipple, if
83 fgPixel != bgPixel. based on the fill style, it uses
84 {RotatedPixmap, gc.alu} or {RotatedPixmap, PrivGC.ropOpStip}
88 void
89 mfbBlackSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
90 DrawablePtr pDrawable;
91 GCPtr pGC;
92 int nInit; /* number of spans to fill */
93 DDXPointPtr pptInit; /* pointer to list of start points */
94 int *pwidthInit; /* pointer to list of n widths */
95 int fSorted;
97 /* next three parameters are post-clip */
98 int n; /* number of spans to fill */
99 register DDXPointPtr ppt; /* pointer to list of start points */
100 register int *pwidth; /* pointer to list of n widths */
101 PixelType *addrlBase; /* pointer to start of bitmap */
102 int nlwidth; /* width in longwords of bitmap */
103 register PixelType *addrl;/* pointer to current longword in bitmap */
104 register int nlmiddle;
105 register PixelType startmask;
106 register PixelType endmask;
107 int *pwidthFree; /* copies of the pointers to free */
108 DDXPointPtr pptFree;
110 if (!(pGC->planemask & 1))
111 return;
113 n = nInit * miFindMaxBand(pGC->pCompositeClip);
114 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
115 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
116 if(!pptFree || !pwidthFree)
118 if (pptFree) DEALLOCATE_LOCAL(pptFree);
119 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
120 return;
122 pwidth = pwidthFree;
123 ppt = pptFree;
124 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
125 ppt, pwidth, fSorted);
127 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
129 while (n--)
131 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
133 if (*pwidth)
135 if ( ((ppt->x & PIM) + *pwidth) < PPW)
137 /* all bits inside same longword */
138 maskpartialbits(ppt->x, *pwidth, startmask);
139 *addrl &= ~startmask;
141 else
143 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
144 if (startmask)
145 *addrl++ &= ~startmask;
146 Duff (nlmiddle, *addrl++ = 0x0);
147 if (endmask)
148 *addrl &= ~endmask;
151 pwidth++;
152 ppt++;
154 DEALLOCATE_LOCAL(pptFree);
155 DEALLOCATE_LOCAL(pwidthFree);
160 void
161 mfbWhiteSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
162 DrawablePtr pDrawable;
163 GCPtr pGC;
164 int nInit; /* number of spans to fill */
165 DDXPointPtr pptInit; /* pointer to list of start points */
166 int *pwidthInit; /* pointer to list of n widths */
167 int fSorted;
169 /* next three parameters are post-clip */
170 int n; /* number of spans to fill */
171 register DDXPointPtr ppt; /* pointer to list of start points */
172 register int *pwidth; /* pointer to list of n widths */
173 PixelType *addrlBase; /* pointer to start of bitmap */
174 int nlwidth; /* width in longwords of bitmap */
175 register PixelType *addrl;/* pointer to current longword in bitmap */
176 register int nlmiddle;
177 register PixelType startmask;
178 register PixelType endmask;
179 int *pwidthFree; /* copies of the pointers to free */
180 DDXPointPtr pptFree;
182 if (!(pGC->planemask & 1))
183 return;
185 n = nInit * miFindMaxBand(pGC->pCompositeClip);
186 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
187 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
188 if(!pptFree || !pwidthFree)
190 if (pptFree) DEALLOCATE_LOCAL(pptFree);
191 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
192 return;
194 pwidth = pwidthFree;
195 ppt = pptFree;
196 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
197 ppt, pwidth, fSorted);
199 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
201 while (n--)
203 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
205 if (*pwidth)
207 if ( ((ppt->x & PIM) + *pwidth) < PPW)
209 /* all bits inside same longword */
210 maskpartialbits(ppt->x, *pwidth, startmask);
211 *addrl |= startmask;
213 else
215 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
216 if (startmask)
217 *addrl++ |= startmask;
218 Duff (nlmiddle, *addrl++ = ~0);
219 if (endmask)
220 *addrl |= endmask;
223 pwidth++;
224 ppt++;
226 DEALLOCATE_LOCAL(pptFree);
227 DEALLOCATE_LOCAL(pwidthFree);
232 void
233 mfbInvertSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
234 DrawablePtr pDrawable;
235 GCPtr pGC;
236 int nInit; /* number of spans to fill */
237 DDXPointPtr pptInit; /* pointer to list of start points */
238 int *pwidthInit; /* pointer to list of n widths */
239 int fSorted;
241 /* next three parameters are post-clip */
242 int n; /* number of spans to fill */
243 register DDXPointPtr ppt; /* pointer to list of start points */
244 register int *pwidth; /* pointer to list of n widths */
245 PixelType *addrlBase; /* pointer to start of bitmap */
246 int nlwidth; /* width in longwords of bitmap */
247 register PixelType *addrl;/* pointer to current longword in bitmap */
248 register int nlmiddle;
249 register PixelType startmask;
250 register PixelType endmask;
251 int *pwidthFree; /* copies of the pointers to free */
252 DDXPointPtr pptFree;
254 if (!(pGC->planemask & 1))
255 return;
257 n = nInit * miFindMaxBand(pGC->pCompositeClip);
258 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
259 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
260 if(!pptFree || !pwidthFree)
262 if (pptFree) DEALLOCATE_LOCAL(pptFree);
263 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
264 return;
266 pwidth = pwidthFree;
267 ppt = pptFree;
268 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
269 ppt, pwidth, fSorted);
271 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
273 while (n--)
275 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
277 if (*pwidth)
279 if ( ((ppt->x & PIM) + *pwidth) < PPW)
281 /* all bits inside same longword */
282 maskpartialbits(ppt->x, *pwidth, startmask);
283 *addrl ^= startmask;
285 else
287 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
288 if (startmask)
289 *addrl++ ^= startmask;
290 Duff (nlmiddle, *addrl++ ^= ~0);
291 if (endmask)
292 *addrl ^= endmask;
295 pwidth++;
296 ppt++;
298 DEALLOCATE_LOCAL(pptFree);
299 DEALLOCATE_LOCAL(pwidthFree);
303 void
304 mfbWhiteStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
305 DrawablePtr pDrawable;
306 GC *pGC;
307 int nInit; /* number of spans to fill */
308 DDXPointPtr pptInit; /* pointer to list of start points */
309 int *pwidthInit; /* pointer to list of n widths */
310 int fSorted;
312 /* next three parameters are post-clip */
313 int n; /* number of spans to fill */
314 register DDXPointPtr ppt; /* pointer to list of start points */
315 register int *pwidth; /* pointer to list of n widths */
316 PixelType *addrlBase; /* pointer to start of bitmap */
317 int nlwidth; /* width in longwords of bitmap */
318 register PixelType *addrl;/* pointer to current longword in bitmap */
319 register PixelType src;
320 register int nlmiddle;
321 register PixelType startmask;
322 register PixelType endmask;
323 PixmapPtr pStipple;
324 PixelType *psrc;
325 int tileHeight;
326 int *pwidthFree; /* copies of the pointers to free */
327 DDXPointPtr pptFree;
329 if (!(pGC->planemask & 1))
330 return;
332 n = nInit * miFindMaxBand(pGC->pCompositeClip);
333 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
334 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
335 if(!pptFree || !pwidthFree)
337 if (pptFree) DEALLOCATE_LOCAL(pptFree);
338 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
339 return;
341 pwidth = pwidthFree;
342 ppt = pptFree;
343 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
344 ppt, pwidth, fSorted);
346 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
348 pStipple = pGC->pRotatedPixmap;
349 tileHeight = pStipple->drawable.height;
350 psrc = (PixelType *)(pStipple->devPrivate.ptr);
352 while (n--)
354 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
355 src = psrc[ppt->y % tileHeight];
357 /* all bits inside same longword */
358 if ( ((ppt->x & PIM) + *pwidth) < PPW)
360 maskpartialbits(ppt->x, *pwidth, startmask);
361 *addrl |= (src & startmask);
363 else
365 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
366 if (startmask)
367 *addrl++ |= (src & startmask);
368 Duff (nlmiddle, *addrl++ |= src);
369 if (endmask)
370 *addrl |= (src & endmask);
372 pwidth++;
373 ppt++;
375 DEALLOCATE_LOCAL(pptFree);
376 DEALLOCATE_LOCAL(pwidthFree);
380 void
381 mfbBlackStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
382 DrawablePtr pDrawable;
383 GC *pGC;
384 int nInit; /* number of spans to fill */
385 DDXPointPtr pptInit; /* pointer to list of start points */
386 int *pwidthInit; /* pointer to list of n widths */
387 int fSorted;
389 /* next three parameters are post-clip */
390 int n; /* number of spans to fill */
391 register DDXPointPtr ppt; /* pointer to list of start points */
392 register int *pwidth; /* pointer to list of n widths */
393 PixelType *addrlBase; /* pointer to start of bitmap */
394 int nlwidth; /* width in longwords of bitmap */
395 register PixelType *addrl; /* pointer to current longword in bitmap */
396 register PixelType src;
397 register int nlmiddle;
398 register PixelType startmask;
399 register PixelType endmask;
400 PixmapPtr pStipple;
401 PixelType *psrc;
402 int tileHeight;
403 int *pwidthFree; /* copies of the pointers to free */
404 DDXPointPtr pptFree;
406 if (!(pGC->planemask & 1))
407 return;
409 n = nInit * miFindMaxBand(pGC->pCompositeClip);
410 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
411 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
412 if(!pptFree || !pwidthFree)
414 if (pptFree) DEALLOCATE_LOCAL(pptFree);
415 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
416 return;
418 pwidth = pwidthFree;
419 ppt = pptFree;
420 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
421 ppt, pwidth, fSorted);
423 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
425 pStipple = pGC->pRotatedPixmap;
426 tileHeight = pStipple->drawable.height;
427 psrc = (PixelType *)(pStipple->devPrivate.ptr);
429 while (n--)
431 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
432 src = psrc[ppt->y % tileHeight];
434 /* all bits inside same longword */
435 if ( ((ppt->x & PIM) + *pwidth) < PPW)
437 maskpartialbits(ppt->x, *pwidth, startmask);
438 *addrl &= ~(src & startmask);
440 else
442 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
443 if (startmask)
444 *addrl++ &= ~(src & startmask);
445 Duff (nlmiddle, *addrl++ &= ~src);
446 if (endmask)
447 *addrl &= ~(src & endmask);
449 pwidth++;
450 ppt++;
452 DEALLOCATE_LOCAL(pptFree);
453 DEALLOCATE_LOCAL(pwidthFree);
457 void
458 mfbInvertStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
459 DrawablePtr pDrawable;
460 GC *pGC;
461 int nInit; /* number of spans to fill */
462 DDXPointPtr pptInit; /* pointer to list of start points */
463 int *pwidthInit; /* pointer to list of n widths */
464 int fSorted;
466 /* next three parameters are post-clip */
467 int n; /* number of spans to fill */
468 register DDXPointPtr ppt; /* pointer to list of start points */
469 register int *pwidth; /* pointer to list of n widths */
470 PixelType *addrlBase; /* pointer to start of bitmap */
471 int nlwidth; /* width in longwords of bitmap */
472 register PixelType *addrl; /* pointer to current longword in bitmap */
473 register PixelType src;
474 register int nlmiddle;
475 register PixelType startmask;
476 register PixelType endmask;
477 PixmapPtr pStipple;
478 PixelType *psrc;
479 int tileHeight;
480 int *pwidthFree; /* copies of the pointers to free */
481 DDXPointPtr pptFree;
483 if (!(pGC->planemask & 1))
484 return;
486 n = nInit * miFindMaxBand(pGC->pCompositeClip);
487 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
488 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
489 if(!pptFree || !pwidthFree)
491 if (pptFree) DEALLOCATE_LOCAL(pptFree);
492 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
493 return;
495 pwidth = pwidthFree;
496 ppt = pptFree;
497 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
498 ppt, pwidth, fSorted);
500 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
502 pStipple = pGC->pRotatedPixmap;
503 tileHeight = pStipple->drawable.height;
504 psrc = (PixelType *)(pStipple->devPrivate.ptr);
506 while (n--)
508 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
509 src = psrc[ppt->y % tileHeight];
511 /* all bits inside same longword */
512 if ( ((ppt->x & PIM) + *pwidth) < PPW)
514 maskpartialbits(ppt->x, *pwidth, startmask);
515 *addrl ^= (src & startmask);
517 else
519 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
520 if (startmask)
521 *addrl++ ^= (src & startmask);
522 Duff(nlmiddle, *addrl++ ^= src);
523 if (endmask)
524 *addrl ^= (src & endmask);
526 pwidth++;
527 ppt++;
529 DEALLOCATE_LOCAL(pptFree);
530 DEALLOCATE_LOCAL(pwidthFree);
534 /* this works with tiles of width == PPW */
535 #define FILLSPANPPW(ROP) \
536 while (n--) \
538 if (*pwidth) \
540 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth); \
541 src = psrc[ppt->y % tileHeight]; \
542 if ( ((ppt->x & PIM) + *pwidth) < PPW) \
544 maskpartialbits(ppt->x, *pwidth, startmask); \
545 *addrl = (*addrl & ~startmask) | \
546 (ROP(src, *addrl) & startmask); \
548 else \
550 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
551 if (startmask) \
553 *addrl = (*addrl & ~startmask) | \
554 (ROP(src, *addrl) & startmask); \
555 addrl++; \
557 while (nlmiddle--) \
559 *addrl = ROP(src, *addrl); \
560 addrl++; \
562 if (endmask) \
563 *addrl = (*addrl & ~endmask) | \
564 (ROP(src, *addrl) & endmask); \
567 pwidth++; \
568 ppt++; \
573 void
574 mfbTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
575 DrawablePtr pDrawable;
576 GC *pGC;
577 int nInit; /* number of spans to fill */
578 DDXPointPtr pptInit; /* pointer to list of start points */
579 int *pwidthInit; /* pointer to list of n widths */
580 int fSorted;
582 /* next three parameters are post-clip */
583 int n; /* number of spans to fill */
584 register DDXPointPtr ppt; /* pointer to list of start points */
585 register int *pwidth; /* pointer to list of n widths */
586 PixelType *addrlBase; /* pointer to start of bitmap */
587 int nlwidth; /* width in longwords of bitmap */
588 register PixelType *addrl; /* pointer to current longword in bitmap */
589 register PixelType src;
590 register int nlmiddle;
591 register PixelType startmask;
592 register PixelType endmask;
593 PixmapPtr pTile;
594 PixelType *psrc;
595 int tileHeight;
596 int rop;
597 int *pwidthFree; /* copies of the pointers to free */
598 DDXPointPtr pptFree;
599 MfbBits flip;
602 if (!(pGC->planemask & 1))
603 return;
605 n = nInit * miFindMaxBand(pGC->pCompositeClip);
606 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
607 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
608 if(!pptFree || !pwidthFree)
610 if (pptFree) DEALLOCATE_LOCAL(pptFree);
611 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
612 return;
614 pwidth = pwidthFree;
615 ppt = pptFree;
616 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
617 ppt, pwidth, fSorted);
619 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
621 pTile = pGC->pRotatedPixmap;
622 tileHeight = pTile->drawable.height;
623 psrc = (PixelType *)(pTile->devPrivate.ptr);
624 if (pGC->fillStyle == FillTiled)
625 rop = pGC->alu;
626 else
627 rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->ropOpStip;
629 flip = 0;
630 switch(rop)
632 case GXcopyInverted: /* for opaque stipples */
633 flip = ~0;
634 case GXcopy:
637 #define DoMaskCopyRop(src,dst,mask) (((dst) & ~(mask)) | ((src) & (mask)))
639 while (n--)
641 if (*pwidth)
643 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
644 src = psrc[ppt->y % tileHeight] ^ flip;
645 if ( ((ppt->x & PIM) + *pwidth) < PPW)
647 maskpartialbits(ppt->x, *pwidth, startmask);
648 *addrl = DoMaskCopyRop (src, *addrl, startmask);
650 else
652 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
653 if (startmask)
655 *addrl = DoMaskCopyRop (src, *addrl, startmask);
656 addrl++;
658 while (nlmiddle--)
660 *addrl = src;
661 addrl++;
663 if (endmask)
664 *addrl = DoMaskCopyRop (src, *addrl, endmask);
667 pwidth++;
668 ppt++;
671 break;
672 default:
674 register DeclareMergeRop ();
676 InitializeMergeRop(rop,~0);
677 while (n--)
679 if (*pwidth)
681 addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
682 src = psrc[ppt->y % tileHeight];
683 if ( ((ppt->x & PIM) + *pwidth) < PPW)
685 maskpartialbits(ppt->x, *pwidth, startmask);
686 *addrl = DoMaskMergeRop (src, *addrl, startmask);
688 else
690 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
691 if (startmask)
693 *addrl = DoMaskMergeRop (src, *addrl, startmask);
694 addrl++;
696 while (nlmiddle--)
698 *addrl = DoMergeRop (src, *addrl);
699 addrl++;
701 if (endmask)
702 *addrl = DoMaskMergeRop (src, *addrl, endmask);
705 pwidth++;
706 ppt++;
709 break;
711 DEALLOCATE_LOCAL(pptFree);
712 DEALLOCATE_LOCAL(pwidthFree);
716 /* Fill spans with tiles that aren't PPW bits wide */
717 void
718 mfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
719 DrawablePtr pDrawable;
720 GC *pGC;
721 int nInit; /* number of spans to fill */
722 DDXPointPtr pptInit; /* pointer to list of start points */
723 int *pwidthInit; /* pointer to list of n widths */
724 int fSorted;
726 int iline; /* first line of tile to use */
727 /* next three parameters are post-clip */
728 int n; /* number of spans to fill */
729 register DDXPointPtr ppt; /* pointer to list of start points */
730 register int *pwidth; /* pointer to list of n widths */
731 PixelType *addrlBase; /* pointer to start of bitmap */
732 int nlwidth; /* width in longwords of bitmap */
733 register PixelType *pdst;/* pointer to current word in bitmap */
734 register PixelType *psrc;/* pointer to current word in tile */
735 register int nlMiddle;
736 register int rop, nstart;
737 PixelType startmask;
738 PixmapPtr pTile; /* pointer to tile we want to fill with */
739 int w, width, x, xSrc, ySrc, srcStartOver, nend;
740 int tlwidth, rem, tileWidth, tileHeight, endinc;
741 PixelType endmask, *psrcT;
742 int *pwidthFree; /* copies of the pointers to free */
743 DDXPointPtr pptFree;
745 if (!(pGC->planemask & 1))
746 return;
748 n = nInit * miFindMaxBand(pGC->pCompositeClip);
749 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
750 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
751 if(!pptFree || !pwidthFree)
753 if (pptFree) DEALLOCATE_LOCAL(pptFree);
754 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
755 return;
757 pwidth = pwidthFree;
758 ppt = pptFree;
759 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
760 ppt, pwidth, fSorted);
762 if (pGC->fillStyle == FillTiled)
764 pTile = pGC->tile.pixmap;
765 tlwidth = pTile->devKind / PGSZB;
766 rop = pGC->alu;
768 else
770 pTile = pGC->stipple;
771 tlwidth = pTile->devKind / PGSZB;
772 rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->ropOpStip;
775 xSrc = pDrawable->x;
776 ySrc = pDrawable->y;
778 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
780 tileWidth = pTile->drawable.width;
781 tileHeight = pTile->drawable.height;
783 /* this replaces rotating the tile. Instead we just adjust the offset
784 * at which we start grabbing bits from the tile.
785 * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
786 * so that iline and rem always stay within the tile bounds.
788 xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
789 ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
791 while (n--)
793 iline = (ppt->y - ySrc) % tileHeight;
794 pdst = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
795 psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
796 x = ppt->x;
798 if (*pwidth)
800 width = *pwidth;
801 while(width > 0)
803 psrc = psrcT;
804 w = min(tileWidth, width);
805 if((rem = (x - xSrc) % tileWidth) != 0)
807 /* if we're in the middle of the tile, get
808 as many bits as will finish the span, or
809 as many as will get to the left edge of the tile,
810 or a longword worth, starting at the appropriate
811 offset in the tile.
813 w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
814 endinc = rem / BITMAP_SCANLINE_PAD;
815 getandputrop((psrc+endinc), (rem&PIM), (x & PIM), w, pdst, rop);
816 if((x & PIM) + w >= PPW)
817 pdst++;
819 else if(((x & PIM) + w) < PPW)
821 /* doing < PPW bits is easy, and worth special-casing */
822 putbitsrop(*psrc, x & PIM, w, pdst, rop);
824 else
826 /* start at the left edge of the tile,
827 and put down as much as we can
829 maskbits(x, w, startmask, endmask, nlMiddle);
831 if (startmask)
832 nstart = PPW - (x & PIM);
833 else
834 nstart = 0;
835 if (endmask)
836 nend = (x + w) & PIM;
837 else
838 nend = 0;
840 srcStartOver = nstart > PLST;
842 if(startmask)
844 putbitsrop(*psrc, (x & PIM), nstart, pdst, rop);
845 pdst++;
846 #if defined(__alpha__) || defined(__alpha)
848 * XXX workaround an egcs 1.1.2 code generation
849 * bug. This version might actually be faster.
851 psrc += srcStartOver;
852 #else
853 if(srcStartOver)
854 psrc++;
855 #endif
858 while(nlMiddle--)
860 getandputrop0(psrc, nstart, PPW, pdst, rop);
861 pdst++;
862 psrc++;
864 if(endmask)
866 getandputrop0(psrc, nstart, nend, pdst, rop);
869 x += w;
870 width -= w;
873 ppt++;
874 pwidth++;
876 DEALLOCATE_LOCAL(pptFree);
877 DEALLOCATE_LOCAL(pwidthFree);
881 /* Fill spans with stipples that aren't PPW bits wide */
882 void
883 mfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
884 DrawablePtr pDrawable;
885 GC *pGC;
886 int nInit; /* number of spans to fill */
887 DDXPointPtr pptInit; /* pointer to list of start points */
888 int *pwidthInit; /* pointer to list of n widths */
889 int fSorted;
891 /* next three parameters are post-clip */
892 int n; /* number of spans to fill */
893 register DDXPointPtr ppt; /* pointer to list of start points */
894 register int *pwidth; /* pointer to list of n widths */
895 int iline; /* first line of tile to use */
896 PixelType *addrlBase; /* pointer to start of bitmap */
897 int nlwidth; /* width in longwords of bitmap */
898 register PixelType *pdst; /* pointer to current word in bitmap */
899 register PixelType *psrc; /* pointer to current word in tile */
900 register int nlMiddle;
901 register int rop, nstart;
902 PixelType startmask;
903 PixmapPtr pTile; /* pointer to tile we want to fill with */
904 int w, width, x, xSrc, ySrc, srcStartOver, nend;
905 PixelType endmask, *psrcT;
906 int tlwidth, rem, tileWidth, endinc;
907 int tileHeight;
908 int *pwidthFree; /* copies of the pointers to free */
909 DDXPointPtr pptFree;
911 if (!(pGC->planemask & 1))
912 return;
914 n = nInit * miFindMaxBand(pGC->pCompositeClip);
915 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
916 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
917 if(!pptFree || !pwidthFree)
919 if (pptFree) DEALLOCATE_LOCAL(pptFree);
920 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
921 return;
923 pwidth = pwidthFree;
924 ppt = pptFree;
925 n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
926 ppt, pwidth, fSorted);
928 pTile = pGC->stipple;
929 rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
930 tlwidth = pTile->devKind / PGSZB;
931 xSrc = pDrawable->x;
932 ySrc = pDrawable->y;
933 mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
935 tileWidth = pTile->drawable.width;
936 tileHeight = pTile->drawable.height;
938 /* this replaces rotating the stipple. Instead, we just adjust the offset
939 * at which we start grabbing bits from the stipple.
940 * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
941 * so that iline and rem always stay within the tile bounds.
943 xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
944 ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
945 while (n--)
947 iline = (ppt->y - ySrc) % tileHeight;
948 pdst = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
949 psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
950 x = ppt->x;
952 if (*pwidth)
954 width = *pwidth;
955 while(width > 0)
957 psrc = psrcT;
958 w = min(tileWidth, width);
959 if((rem = (x - xSrc) % tileWidth) != 0)
961 /* if we're in the middle of the tile, get
962 as many bits as will finish the span, or
963 as many as will get to the left edge of the tile,
964 or a longword worth, starting at the appropriate
965 offset in the tile.
967 w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
968 endinc = rem / BITMAP_SCANLINE_PAD;
969 getandputrrop((psrc + endinc), (rem & PIM), (x & PIM),
970 w, pdst, rop)
971 if((x & PIM) + w >= PPW)
972 pdst++;
975 else if(((x & PIM) + w) < PPW)
977 /* doing < PPW bits is easy, and worth special-casing */
978 putbitsrrop(*psrc, x & PIM, w, pdst, rop);
980 else
982 /* start at the left edge of the tile,
983 and put down as much as we can
985 maskbits(x, w, startmask, endmask, nlMiddle);
987 if (startmask)
988 nstart = PPW - (x & PIM);
989 else
990 nstart = 0;
991 if (endmask)
992 nend = (x + w) & PIM;
993 else
994 nend = 0;
996 srcStartOver = nstart > PLST;
998 if(startmask)
1000 putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
1001 pdst++;
1002 if(srcStartOver)
1003 psrc++;
1006 while(nlMiddle--)
1008 getandputrrop0(psrc, nstart, PPW, pdst, rop);
1009 pdst++;
1010 psrc++;
1012 if(endmask)
1014 getandputrrop0(psrc, nstart, nend, pdst, rop);
1017 x += w;
1018 width -= w;
1021 ppt++;
1022 pwidth++;
1024 DEALLOCATE_LOCAL(pptFree);
1025 DEALLOCATE_LOCAL(pwidthFree);