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
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.
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
47 ******************************************************************/
48 #ifdef HAVE_DIX_CONFIG_H
49 #include <dix-config.h>
56 #include "pixmapstr.h"
57 #include "scrnintstr.h"
58 #include "windowstr.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}
89 mfbBlackSolidFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
90 DrawablePtr pDrawable
;
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 */
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 */
110 if (!(pGC
->planemask
& 1))
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
);
124 n
= miClipSpans(pGC
->pCompositeClip
, pptInit
, pwidthInit
, nInit
,
125 ppt
, pwidth
, fSorted
);
127 mfbGetPixelWidthAndPointer(pDrawable
, nlwidth
, addrlBase
);
131 addrl
= mfbScanline(addrlBase
, ppt
->x
, ppt
->y
, nlwidth
);
135 if ( ((ppt
->x
& PIM
) + *pwidth
) < PPW
)
137 /* all bits inside same longword */
138 maskpartialbits(ppt
->x
, *pwidth
, startmask
);
139 *addrl
&= ~startmask
;
143 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
145 *addrl
++ &= ~startmask
;
146 Duff (nlmiddle
, *addrl
++ = 0x0);
154 DEALLOCATE_LOCAL(pptFree
);
155 DEALLOCATE_LOCAL(pwidthFree
);
161 mfbWhiteSolidFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
162 DrawablePtr pDrawable
;
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 */
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 */
182 if (!(pGC
->planemask
& 1))
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
);
196 n
= miClipSpans(pGC
->pCompositeClip
, pptInit
, pwidthInit
, nInit
,
197 ppt
, pwidth
, fSorted
);
199 mfbGetPixelWidthAndPointer(pDrawable
, nlwidth
, addrlBase
);
203 addrl
= mfbScanline(addrlBase
, ppt
->x
, ppt
->y
, nlwidth
);
207 if ( ((ppt
->x
& PIM
) + *pwidth
) < PPW
)
209 /* all bits inside same longword */
210 maskpartialbits(ppt
->x
, *pwidth
, startmask
);
215 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
217 *addrl
++ |= startmask
;
218 Duff (nlmiddle
, *addrl
++ = ~0);
226 DEALLOCATE_LOCAL(pptFree
);
227 DEALLOCATE_LOCAL(pwidthFree
);
233 mfbInvertSolidFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
234 DrawablePtr pDrawable
;
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 */
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 */
254 if (!(pGC
->planemask
& 1))
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
);
268 n
= miClipSpans(pGC
->pCompositeClip
, pptInit
, pwidthInit
, nInit
,
269 ppt
, pwidth
, fSorted
);
271 mfbGetPixelWidthAndPointer(pDrawable
, nlwidth
, addrlBase
);
275 addrl
= mfbScanline(addrlBase
, ppt
->x
, ppt
->y
, nlwidth
);
279 if ( ((ppt
->x
& PIM
) + *pwidth
) < PPW
)
281 /* all bits inside same longword */
282 maskpartialbits(ppt
->x
, *pwidth
, startmask
);
287 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
289 *addrl
++ ^= startmask
;
290 Duff (nlmiddle
, *addrl
++ ^= ~0);
298 DEALLOCATE_LOCAL(pptFree
);
299 DEALLOCATE_LOCAL(pwidthFree
);
304 mfbWhiteStippleFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
305 DrawablePtr pDrawable
;
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 */
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
;
326 int *pwidthFree
; /* copies of the pointers to free */
329 if (!(pGC
->planemask
& 1))
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
);
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
);
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
);
365 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
367 *addrl
++ |= (src
& startmask
);
368 Duff (nlmiddle
, *addrl
++ |= src
);
370 *addrl
|= (src
& endmask
);
375 DEALLOCATE_LOCAL(pptFree
);
376 DEALLOCATE_LOCAL(pwidthFree
);
381 mfbBlackStippleFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
382 DrawablePtr pDrawable
;
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 */
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
;
403 int *pwidthFree
; /* copies of the pointers to free */
406 if (!(pGC
->planemask
& 1))
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
);
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
);
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
);
442 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
444 *addrl
++ &= ~(src
& startmask
);
445 Duff (nlmiddle
, *addrl
++ &= ~src
);
447 *addrl
&= ~(src
& endmask
);
452 DEALLOCATE_LOCAL(pptFree
);
453 DEALLOCATE_LOCAL(pwidthFree
);
458 mfbInvertStippleFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
459 DrawablePtr pDrawable
;
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 */
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
;
480 int *pwidthFree
; /* copies of the pointers to free */
483 if (!(pGC
->planemask
& 1))
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
);
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
);
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
);
519 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
521 *addrl
++ ^= (src
& startmask
);
522 Duff(nlmiddle
, *addrl
++ ^= src
);
524 *addrl
^= (src
& endmask
);
529 DEALLOCATE_LOCAL(pptFree
);
530 DEALLOCATE_LOCAL(pwidthFree
);
534 /* this works with tiles of width == PPW */
535 #define FILLSPANPPW(ROP) \
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); \
550 maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
553 *addrl = (*addrl & ~startmask) | \
554 (ROP(src, *addrl) & startmask); \
559 *addrl = ROP(src, *addrl); \
563 *addrl = (*addrl & ~endmask) | \
564 (ROP(src, *addrl) & endmask); \
574 mfbTileFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
575 DrawablePtr pDrawable
;
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 */
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
;
597 int *pwidthFree
; /* copies of the pointers to free */
602 if (!(pGC
->planemask
& 1))
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
);
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
)
627 rop
= ((mfbPrivGC
*)(pGC
->devPrivates
[mfbGCPrivateIndex
].ptr
))->ropOpStip
;
632 case GXcopyInverted
: /* for opaque stipples */
637 #define DoMaskCopyRop(src,dst,mask) (((dst) & ~(mask)) | ((src) & (mask)))
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
);
652 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
655 *addrl
= DoMaskCopyRop (src
, *addrl
, startmask
);
664 *addrl
= DoMaskCopyRop (src
, *addrl
, endmask
);
674 register DeclareMergeRop ();
676 InitializeMergeRop(rop
,~0);
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
);
690 maskbits(ppt
->x
, *pwidth
, startmask
, endmask
, nlmiddle
);
693 *addrl
= DoMaskMergeRop (src
, *addrl
, startmask
);
698 *addrl
= DoMergeRop (src
, *addrl
);
702 *addrl
= DoMaskMergeRop (src
, *addrl
, endmask
);
711 DEALLOCATE_LOCAL(pptFree
);
712 DEALLOCATE_LOCAL(pwidthFree
);
716 /* Fill spans with tiles that aren't PPW bits wide */
718 mfbUnnaturalTileFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
719 DrawablePtr pDrawable
;
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 */
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
;
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 */
745 if (!(pGC
->planemask
& 1))
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
);
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
;
770 pTile
= pGC
->stipple
;
771 tlwidth
= pTile
->devKind
/ PGSZB
;
772 rop
= ((mfbPrivGC
*)(pGC
->devPrivates
[mfbGCPrivateIndex
].ptr
))->ropOpStip
;
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
;
793 iline
= (ppt
->y
- ySrc
) % tileHeight
;
794 pdst
= mfbScanline(addrlBase
, ppt
->x
, ppt
->y
, nlwidth
);
795 psrcT
= (PixelType
*) pTile
->devPrivate
.ptr
+ (iline
* tlwidth
);
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
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
)
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
);
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
);
832 nstart
= PPW
- (x
& PIM
);
836 nend
= (x
+ w
) & PIM
;
840 srcStartOver
= nstart
> PLST
;
844 putbitsrop(*psrc
, (x
& PIM
), nstart
, pdst
, rop
);
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
;
860 getandputrop0(psrc
, nstart
, PPW
, pdst
, rop
);
866 getandputrop0(psrc
, nstart
, nend
, pdst
, rop
);
876 DEALLOCATE_LOCAL(pptFree
);
877 DEALLOCATE_LOCAL(pwidthFree
);
881 /* Fill spans with stipples that aren't PPW bits wide */
883 mfbUnnaturalStippleFS(pDrawable
, pGC
, nInit
, pptInit
, pwidthInit
, fSorted
)
884 DrawablePtr pDrawable
;
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 */
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
;
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
;
908 int *pwidthFree
; /* copies of the pointers to free */
911 if (!(pGC
->planemask
& 1))
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
);
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
;
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
;
947 iline
= (ppt
->y
- ySrc
) % tileHeight
;
948 pdst
= mfbScanline(addrlBase
, ppt
->x
, ppt
->y
, nlwidth
);
949 psrcT
= (PixelType
*) pTile
->devPrivate
.ptr
+ (iline
* tlwidth
);
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
967 w
= min(min(tileWidth
- rem
, width
), BITMAP_SCANLINE_PAD
);
968 endinc
= rem
/ BITMAP_SCANLINE_PAD
;
969 getandputrrop((psrc
+ endinc
), (rem
& PIM
), (x
& PIM
),
971 if((x
& PIM
) + w
>= PPW
)
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
);
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
);
988 nstart
= PPW
- (x
& PIM
);
992 nend
= (x
+ w
) & PIM
;
996 srcStartOver
= nstart
> PLST
;
1000 putbitsrrop(*psrc
, (x
& PIM
), nstart
, pdst
, rop
);
1008 getandputrrop0(psrc
, nstart
, PPW
, pdst
, rop
);
1014 getandputrrop0(psrc
, nstart
, nend
, pdst
, rop
);
1024 DEALLOCATE_LOCAL(pptFree
);
1025 DEALLOCATE_LOCAL(pwidthFree
);