First import
[xorg_rtime.git] / xorg-server-1.4 / afb / afbpntarea.c
blobcc43f523796112cf501ad34ee0c0006eb7aa16c5
1 /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
2 /***********************************************************
4 Copyright (c) 1987 X Consortium
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
28 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
30 All Rights Reserved
32 Permission to use, copy, modify, and distribute this software and its
33 documentation for any purpose and without fee is hereby granted,
34 provided that the above copyright notice appear in all copies and that
35 both that copyright notice and this permission notice appear in
36 supporting documentation, and that the name of Digital not be
37 used in advertising or publicity pertaining to distribution of the
38 software without specific, written prior permission.
40 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
41 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
42 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
43 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
44 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46 SOFTWARE.
48 ******************************************************************/
50 #ifdef HAVE_DIX_CONFIG_H
51 #include <dix-config.h>
52 #endif
54 #include <X11/X.h>
56 #include "windowstr.h"
57 #include "regionstr.h"
58 #include "pixmapstr.h"
59 #include "scrnintstr.h"
61 #include "afb.h"
62 #include "maskbits.h"
65 the solid fillers are called for rectangles and window backgrounds.
66 the boxes are already translated.
67 maybe this should always take a pixmap instead of a drawable?
69 NOTE:
70 iy = ++iy < tileHeight ? iy : 0
71 is equivalent to iy%= tileheight, and saves a division.
74 /*ARGSUSED*/
75 void
76 afbSolidFillArea (pDraw, nbox, pbox, rrops)
77 DrawablePtr pDraw;
78 int nbox;
79 BoxPtr pbox;
80 register unsigned char *rrops;
82 int nlwidth; /* width in longwords of the drawable */
83 int w; /* width of current box */
84 register int h; /* height of current box */
85 register PixelType *p; /* pointer to bits we're writing */
86 register int nlw; /* loop version of nlwMiddle */
87 register PixelType startmask;
88 register PixelType endmask;
89 /* masks for reggedy bits at either end of line */
90 register int nlwExtra;
91 /* to get from right of box to left of next span */
92 int nlwMiddle; /* number of longwords between sides of boxes */
93 PixelType *pbits; /* pointer to start of drawable */
94 PixelType *saveP;
95 int saveH;
96 int depthDst;
97 int sizeDst;
98 register int d;
100 afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
101 pbits);
103 while (nbox--) {
104 w = pbox->x2 - pbox->x1;
105 saveH = pbox->y2 - pbox->y1;
107 saveP = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
109 if ( ((pbox->x1 & PIM) + w) < PPW) {
110 for (d = 0; d < depthDst; d++) {
111 h = saveH;
112 p = saveP;
113 saveP += sizeDst; /* @@@ NEXT PLANE @@@ */
114 maskpartialbits(pbox->x1, w, startmask);
115 nlwExtra = nlwidth;
117 switch (rrops[d]) {
118 case RROP_BLACK:
119 Duff(h, *p &= ~startmask; afbScanlineInc(p, nlwExtra));
120 break;
121 case RROP_WHITE:
122 Duff(h, *p |= startmask; afbScanlineInc(p, nlwExtra));
123 break;
124 case RROP_INVERT:
125 Duff(h, *p ^= startmask; afbScanlineInc(p, nlwExtra));
126 break;
127 case RROP_NOP:
128 break;
129 } /* switch */
130 } /* for (d = ..) */
131 } else {
132 maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
134 for (d = 0; d < depthDst; d++) {
135 h = saveH;
136 p = saveP;
137 saveP += sizeDst; /* @@@ NEXT PLANE @@@ */
138 nlwExtra = nlwidth - nlwMiddle;
140 if (startmask && endmask) {
141 nlwExtra -= 1;
142 switch (rrops[d]) {
143 case RROP_BLACK:
144 while (h--) {
145 nlw = nlwMiddle;
146 *p &= ~startmask;
147 p++;
148 Duff(nlw, *p++ = 0);
149 *p &= ~endmask;
150 afbScanlineInc(p, nlwExtra);
152 break;
153 case RROP_WHITE:
154 while (h--) {
155 nlw = nlwMiddle;
156 *p |= startmask;
157 p++;
158 Duff(nlw, *p++ = ~0);
159 *p |= endmask;
160 afbScanlineInc(p, nlwExtra);
162 break;
163 case RROP_INVERT:
164 while (h--) {
165 nlw = nlwMiddle;
166 *p ^= startmask;
167 p++;
168 Duff(nlw, *p++ ^= ~0);
169 *p ^= endmask;
170 afbScanlineInc(p, nlwExtra);
172 break;
173 case RROP_NOP:
174 break;
176 } else if (startmask && !endmask) {
177 nlwExtra -= 1;
178 switch (rrops[d]) {
179 case RROP_BLACK:
180 while (h--) {
181 nlw = nlwMiddle;
182 *p &= ~startmask;
183 p++;
184 Duff(nlw, *p++ = 0);
185 afbScanlineInc(p, nlwExtra);
187 break;
188 case RROP_WHITE:
189 while (h--) {
190 nlw = nlwMiddle;
191 *p |= startmask;
192 p++;
193 Duff(nlw, *p++ = ~0);
194 afbScanlineInc(p, nlwExtra);
196 break;
197 case RROP_INVERT:
198 while (h--) {
199 nlw = nlwMiddle;
200 *p ^= startmask;
201 p++;
202 Duff(nlw, *p++ ^= ~0);
203 afbScanlineInc(p, nlwExtra);
205 break;
206 case RROP_NOP:
207 break;
209 } else if (!startmask && endmask) {
210 switch (rrops[d]) {
211 case RROP_BLACK:
212 while (h--) {
213 nlw = nlwMiddle;
214 Duff(nlw, *p++ = 0);
215 *p &= ~endmask;
216 afbScanlineInc(p, nlwExtra);
218 break;
219 case RROP_WHITE:
220 while (h--) {
221 nlw = nlwMiddle;
222 Duff(nlw, *p++ = ~0);
223 *p |= endmask;
224 afbScanlineInc(p, nlwExtra);
226 break;
227 case RROP_INVERT:
228 while (h--) {
229 nlw = nlwMiddle;
230 Duff(nlw, *p++ ^= ~0);
231 *p ^= endmask;
232 afbScanlineInc(p, nlwExtra);
234 case RROP_NOP:
235 break;
237 } else { /* no ragged bits at either end */
238 switch (rrops[d]) {
239 case RROP_BLACK:
240 while (h--) {
241 nlw = nlwMiddle;
242 Duff(nlw, *p++ = 0);
243 afbScanlineInc(p, nlwExtra);
245 break;
246 case RROP_WHITE:
247 while (h--) {
248 nlw = nlwMiddle;
249 Duff(nlw, *p++ = ~0);
250 afbScanlineInc(p, nlwExtra);
252 break;
253 case RROP_INVERT:
254 while (h--) {
255 nlw = nlwMiddle;
256 Duff(nlw, *p++ ^= ~0);
257 afbScanlineInc(p, nlwExtra);
259 break;
260 case RROP_NOP:
261 break;
262 } /* switch */
264 } /* for (d = 0 ... ) */
266 pbox++;
270 /* stipple a list of boxes -
272 you can use the reduced rasterop for stipples. if rrop is
273 black, AND the destination with (not stipple pattern). if rrop is
274 white OR the destination with the stipple pattern. if rrop is invert,
275 XOR the destination with the stipple pattern.
278 /*ARGSUSED*/
279 void
280 afbStippleAreaPPW (pDraw, nbox, pbox, pstipple, rrops)
281 DrawablePtr pDraw;
282 int nbox;
283 BoxPtr pbox;
284 PixmapPtr pstipple;
285 unsigned char *rrops;
287 register PixelType *psrc;
288 /* pointer to bits in tile, if needed */
289 int tileHeight; /* height of the tile */
290 register PixelType srcpix;
292 int nlwidth; /* width in longwords of the drawable */
293 int w; /* width of current box */
294 register int nlw; /* loop version of nlwMiddle */
295 register PixelType *p; /* pointer to bits we're writing */
296 register int h; /* height of current box */
297 PixelType startmask;
298 PixelType endmask; /* masks for reggedy bits at either end of line */
299 int nlwMiddle; /* number of longwords between sides of boxes */
300 int nlwExtra; /* to get from right of box to left of next span */
301 int sizeDst;
302 int depthDst;
303 int d;
304 int saveIy;
305 register int iy; /* index of current scanline in tile */
306 PixelType *pbits; /* pointer to start of drawable */
307 PixelType *pBase;
309 afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
310 pBase);
312 tileHeight = pstipple->drawable.height;
313 psrc = (PixelType *)(pstipple->devPrivate.ptr);
315 while (nbox--) {
316 w = pbox->x2 - pbox->x1;
317 saveIy = pbox->y1 % tileHeight;
318 pbits = pBase;
320 if ( ((pbox->x1 & PIM) + w) < PPW) {
321 maskpartialbits(pbox->x1, w, startmask);
322 nlwExtra = nlwidth;
323 for (d = 0; d < depthDst; d++) {
324 p = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
325 pbits += sizeDst; /* @@@ NEXT PLANE @@@ */
326 iy = saveIy;
327 h = pbox->y2 - pbox->y1;
329 switch (rrops[d]) {
330 case RROP_BLACK:
331 while (h--) {
332 srcpix = psrc[iy];
333 iy = ++iy < tileHeight ? iy : 0;
334 *p &= ~(srcpix & startmask);
335 afbScanlineInc(p, nlwExtra);
337 break;
338 case RROP_WHITE:
339 while (h--) {
340 srcpix = psrc[iy];
341 iy = ++iy < tileHeight ? iy : 0;
342 *p |= (srcpix & startmask);
343 afbScanlineInc(p, nlwExtra);
345 break;
346 case RROP_INVERT:
347 while (h--) {
348 srcpix = psrc[iy];
349 iy = ++iy < tileHeight ? iy : 0;
350 *p ^= (srcpix & startmask);
351 afbScanlineInc(p, nlwExtra);
353 break;
354 case RROP_NOP:
355 break;
356 } /* switch */
357 } /* for (d = ...) */
359 } else {
360 maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
362 for (d = 0; d < depthDst; d++) {
363 nlwExtra = nlwidth - nlwMiddle;
364 p = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
365 pbits += sizeDst; /* @@@ NEXT PLANE @@@ */
366 iy = saveIy;
367 h = pbox->y2 - pbox->y1;
369 if (startmask && endmask) {
370 nlwExtra -= 1;
371 switch (rrops[d]) {
372 case RROP_BLACK:
373 while (h--) {
374 srcpix = psrc[iy];
375 iy = ++iy < tileHeight ? iy : 0;
376 nlw = nlwMiddle;
377 *p &= ~(srcpix & startmask);
378 p++;
379 Duff (nlw, *p++ &= ~srcpix);
380 *p &= ~(srcpix & endmask);
381 afbScanlineInc(p, nlwExtra);
383 break;
384 case RROP_WHITE:
385 while (h--) {
386 srcpix = psrc[iy];
387 iy = ++iy < tileHeight ? iy : 0;
388 nlw = nlwMiddle;
389 *p |= (srcpix & startmask);
390 p++;
391 Duff (nlw, *p++ |= srcpix);
392 *p |= (srcpix & endmask);
393 afbScanlineInc(p, nlwExtra);
395 break;
396 case RROP_INVERT:
397 while (h--) {
398 srcpix = psrc[iy];
399 iy = ++iy < tileHeight ? iy : 0;
400 nlw = nlwMiddle;
401 *p ^= (srcpix & startmask);
402 p++;
403 Duff (nlw, *p++ ^= srcpix);
404 *p ^= (srcpix & endmask);
405 afbScanlineInc(p, nlwExtra);
407 break;
408 case RROP_NOP:
409 break;
410 } /* switch */
411 } else if (startmask && !endmask) {
412 nlwExtra -= 1;
413 switch (rrops[d]) {
414 case RROP_BLACK:
415 while (h--) {
416 srcpix = psrc[iy];
417 iy = ++iy < tileHeight ? iy : 0;
418 nlw = nlwMiddle;
419 *p &= ~(srcpix & startmask);
420 p++;
421 Duff(nlw, *p++ &= ~srcpix);
422 afbScanlineInc(p, nlwExtra);
424 break;
425 case RROP_WHITE:
426 while (h--) {
427 srcpix = psrc[iy];
428 iy = ++iy < tileHeight ? iy : 0;
429 nlw = nlwMiddle;
430 *p |= (srcpix & startmask);
431 p++;
432 Duff(nlw, *p++ |= srcpix);
433 afbScanlineInc(p, nlwExtra);
435 break;
436 case RROP_INVERT:
437 while (h--) {
438 srcpix = psrc[iy];
439 iy = ++iy < tileHeight ? iy : 0;
440 nlw = nlwMiddle;
441 *p ^= (srcpix & startmask);
442 p++;
443 Duff(nlw, *p++ ^= srcpix);
444 afbScanlineInc(p, nlwExtra);
446 break;
447 case RROP_NOP:
448 break;
449 } /* switch */
450 } else if (!startmask && endmask) {
451 switch (rrops[d]) {
452 case RROP_BLACK:
453 while (h--) {
454 srcpix = psrc[iy];
455 iy = ++iy < tileHeight ? iy : 0;
456 nlw = nlwMiddle;
457 Duff(nlw, *p++ &= ~srcpix);
458 *p &= ~(srcpix & endmask);
459 afbScanlineInc(p, nlwExtra);
461 break;
462 case RROP_WHITE:
463 while (h--) {
464 srcpix = psrc[iy];
465 iy = ++iy < tileHeight ? iy : 0;
466 nlw = nlwMiddle;
467 Duff(nlw, *p++ |= srcpix);
468 *p |= (srcpix & endmask);
469 afbScanlineInc(p, nlwExtra);
471 break;
472 case RROP_INVERT:
473 while (h--) {
474 srcpix = psrc[iy];
475 iy = ++iy < tileHeight ? iy : 0;
476 nlw = nlwMiddle;
477 Duff(nlw, *p++ ^= srcpix);
478 *p ^= (srcpix & endmask);
479 afbScanlineInc(p, nlwExtra);
481 break;
482 case RROP_NOP:
483 break;
484 } /* switch */
485 } else { /* no ragged bits at either end */
486 switch (rrops[d]) {
487 case RROP_BLACK:
488 while (h--) {
489 srcpix = psrc[iy];
490 iy = ++iy < tileHeight ? iy : 0;
491 nlw = nlwMiddle;
492 Duff(nlw, *p++ &= ~srcpix);
493 afbScanlineInc(p, nlwExtra);
495 break;
496 case RROP_WHITE:
497 while (h--) {
498 srcpix = psrc[iy];
499 iy = ++iy < tileHeight ? iy : 0;
500 nlw = nlwMiddle;
501 Duff(nlw, *p++ |= srcpix);
502 afbScanlineInc(p, nlwExtra);
504 break;
505 case RROP_INVERT:
506 while (h--) {
507 srcpix = psrc[iy];
508 iy = ++iy < tileHeight ? iy : 0;
509 nlw = nlwMiddle;
510 Duff(nlw, *p++ ^= srcpix);
511 afbScanlineInc(p, nlwExtra);
513 break;
514 } /* switch */
516 } /* for (d = ...) */
518 pbox++;
522 void
523 afbStippleArea (pDraw, nbox, pbox, pTile, xOff, yOff, rrops)
524 DrawablePtr pDraw;
525 int nbox;
526 BoxPtr pbox;
527 PixmapPtr pTile;
528 int xOff;
529 int yOff;
530 unsigned char *rrops;
532 register PixelType *psrc; /* pointer to bits in tile, if needed */
533 int nlwidth; /* width in longwords of the drawable */
534 register int h; /* height of current box */
535 register PixelType *pdst; /* pointer to bits we're writing */
536 int sizeDst;
537 int depthDst;
538 int tileLine;
539 int iline;
540 int w, width, x, xSrc, ySrc, srcStartOver, nend;
541 int tlwidth, rem, tileWidth, tileHeight, endinc;
542 int saveW;
543 register int rop;
544 PixelType *psrcT;
545 int d;
546 int nstart;
547 PixelType startmask;
548 PixelType endmask; /* masks for reggedy bits at either end of line */
549 int nlMiddle; /* number of longwords between sides of boxes */
550 int iy;
551 PixelType *pBase; /* pointer to start of drawable */
552 PixelType *saveP;
553 PixelType *pStartDst;
554 PixelType *pStartTile;
555 int saveH;
557 afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
558 pBase);
560 tileHeight = pTile->drawable.height;
561 tileWidth = pTile->drawable.width;
562 tlwidth = pTile->devKind / sizeof (PixelType);
564 xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth);
565 ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight);
567 while (nbox--) {
568 saveW = pbox->x2 - pbox->x1;
569 iline = (pbox->y1 - ySrc) % tileHeight;
570 psrcT = (PixelType *) pTile->devPrivate.ptr;
571 tileLine = iline * tlwidth;
572 saveH = pbox->y2 - pbox->y1;
573 saveP = afbScanline(pBase, pbox->x1, pbox->y1, nlwidth);
575 for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */
576 h = saveH;
577 pStartDst = saveP;
578 pStartTile = psrcT + tileLine;
579 iy = iline;
581 while (h--) {
582 x = pbox->x1;
583 width = saveW;
584 pdst = pStartDst;
585 rop = rrops[d];
587 while(width > 0) {
588 psrc = pStartTile;
589 w = min(tileWidth, width);
590 if((rem = (x - xSrc) % tileWidth) != 0) {
591 /* if we're in the middle of the tile, get
592 as many bits as will finish the span, or
593 as many as will get to the left edge of the tile,
594 or a longword worth, starting at the appropriate
595 offset in the tile.
597 w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
598 endinc = rem / BITMAP_SCANLINE_PAD;
599 getandputrrop((psrc + endinc), (rem & PIM), (x & PIM),
600 w, pdst, rop)
601 if((x & PIM) + w >= PPW)
602 pdst++;
603 } else if(((x & PIM) + w) < PPW) {
604 /* doing < PPW bits is easy, and worth special-casing */
605 putbitsrrop(*psrc, x & PIM, w, pdst, rop);
606 } else {
607 /* start at the left edge of the tile,
608 and put down as much as we can
610 maskbits(x, w, startmask, endmask, nlMiddle);
612 if (startmask)
613 nstart = PPW - (x & PIM);
614 else
615 nstart = 0;
616 if (endmask)
617 nend = (x + w) & PIM;
618 else
619 nend = 0;
621 srcStartOver = nstart > PLST;
623 if(startmask) {
624 putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
625 pdst++;
626 if(srcStartOver)
627 psrc++;
630 while(nlMiddle--) {
631 getandputrrop0(psrc, nstart, PPW, pdst, rop);
632 pdst++;
633 psrc++;
636 if(endmask) {
637 getandputrrop0(psrc, nstart, nend, pdst, rop);
640 x += w;
641 width -= w;
642 } /* while (width > 0) */
644 pStartDst += nlwidth;
645 if (++iy >= tileHeight) {
646 iy = 0;
647 pStartTile = psrcT;
648 } else
649 pStartTile += tlwidth;
651 } /* while (h) */
652 } /* for (d = ... ) */
653 pbox++;
654 } /* for each box */