1
/* $XFree86: xc/programs/Xserver/afb/afbtile.c,v 3.3tsi Exp $ */
2
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
3
/***********************************************************
5
Copyright (c) 1987 X Consortium
7
Permission is hereby granted, free of charge, to any person obtaining a copy
8
of this software and associated documentation files (the "Software"), to deal
9
in the Software without restriction, including without limitation the rights
10
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
copies of the Software, and to permit persons to whom the Software is
12
furnished to do so, subject to the following conditions:
14
The above copyright notice and this permission notice shall be included in
15
all copies or substantial portions of the Software.
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
Except as contained in this notice, the name of the X Consortium shall not be
25
used in advertising or otherwise to promote the sale, use or other dealings
26
in this Software without prior written authorization from the X Consortium.
29
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
33
Permission to use, copy, modify, and distribute this software and its
34
documentation for any purpose and without fee is hereby granted,
35
provided that the above copyright notice appear in all copies and that
36
both that copyright notice and this permission notice appear in
37
supporting documentation, and that the name of Digital not be
38
used in advertising or publicity pertaining to distribution of the
39
software without specific, written prior permission.
41
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49
******************************************************************/
50
/* $XConsortium: afbtile.c,v 5.8 94/04/17 20:28:36 dpw Exp $ */
52
#ifdef HAVE_DIX_CONFIG_H
53
#include <dix-config.h>
58
#include "windowstr.h"
59
#include "regionstr.h"
60
#include "pixmapstr.h"
61
#include "scrnintstr.h"
70
the boxes are already translated.
73
iy = ++iy < tileHeight ? iy : 0
74
is equivalent to iy%= tileheight, and saves a division.
78
tile area with a PPW bit wide pixmap
81
MROP_NAME(afbTileAreaPPW)(pDraw, nbox, pbox, alu, ptile, planemask)
87
unsigned long planemask;
89
register PixelType *psrc;
90
/* pointer to bits in tile, if needed */
91
int tileHeight; /* height of the tile */
92
register PixelType srcpix;
93
int nlwidth; /* width in longwords of the drawable */
94
int w; /* width of current box */
96
register int h; /* height of current box */
97
register int nlw; /* loop version of nlwMiddle */
98
register PixelType *p; /* pointer to bits we're writing */
103
PixelType endmask; /* masks for reggedy bits at either end of line */
104
int nlwMiddle; /* number of longwords between sides of boxes */
105
int nlwExtra; /* to get from right of box to left of next span */
106
register int iy; /* index of current scanline in tile */
107
PixelType *pbits; /* pointer to start of drawable */
113
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
116
MROP_INITIALIZE(alu,~0)
118
tileHeight = ptile->drawable.height;
119
pSaveSrc = (PixelType *)(ptile->devPrivate.ptr);
122
w = pbox->x2 - pbox->x1;
123
saveH = pbox->y2 - pbox->y1;
124
saveIY = pbox->y1 % tileHeight;
125
saveP = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
128
if (((pbox->x1 & PIM) + w) < PPW) {
129
maskpartialbits(pbox->x1, w, startmask);
131
for (d = 0; d < depthDst; d++, saveP += sizeDst, psrc += tileHeight) { /* @@@ NEXT PLANE @@@ */
132
if (!(planemask & (1 << d)))
142
if (iy == tileHeight)
144
*p = MROP_MASK(srcpix,*p,startmask);
145
afbScanlineInc(p, nlwExtra);
149
maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
151
for (d = 0; d < depthDst; d++, saveP += sizeDst, psrc += tileHeight) { /* @@@ NEXT PLANE @@@ */
152
if (!(planemask & (1 << d)))
158
nlwExtra = nlwidth - nlwMiddle;
160
if (startmask && endmask) {
165
if (iy == tileHeight)
168
*p = MROP_MASK (srcpix,*p,startmask);
171
*p = MROP_SOLID(srcpix,*p);
175
*p = MROP_MASK(srcpix,*p,endmask);
176
afbScanlineInc(p, nlwExtra);
178
} else if (startmask && !endmask) {
183
if (iy == tileHeight)
186
*p = MROP_MASK(srcpix,*p,startmask);
189
*p = MROP_SOLID(srcpix,*p);
192
afbScanlineInc(p, nlwExtra);
194
} else if (!startmask && endmask) {
198
if (iy == tileHeight)
202
*p = MROP_SOLID(srcpix,*p);
206
*p = MROP_MASK(srcpix,*p,endmask);
207
afbScanlineInc(p, nlwExtra);
209
} else { /* no ragged bits at either end */
213
if (iy == tileHeight)
217
*p = MROP_SOLID (srcpix,*p);
220
afbScanlineInc(p, nlwExtra);
223
} /* for (d = ...) */
230
MROP_NAME(afbTileArea)(pDraw, nbox, pbox, alu, pTile, xOff, yOff, planemask)
238
unsigned long planemask;
240
register PixelType *psrc;
241
/* pointer to bits in tile, if needed */
242
int nlwidth; /* width in longwords of the drawable */
244
register int h; /* height of current box */
245
register PixelType *pdst; /* pointer to bits we're writing */
246
register PixelType tmpsrc;
248
register PixelType tmpdst;
255
int w, width, x, xSrc, ySrc, srcStartOver, nend;
256
int tlwidth, rem, tileWidth, tileHeight, endinc;
262
PixelType endmask; /* masks for reggedy bits at either end of line */
263
int nlMiddle; /* number of longwords between sides of boxes */
265
PixelType *pBase; /* pointer to start of drawable */
267
PixelType *pStartDst;
268
PixelType *pStartTile;
271
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
274
MROP_INITIALIZE(alu,~0)
276
tileHeight = pTile->drawable.height;
277
tileWidth = pTile->drawable.width;
278
tlwidth = pTile->devKind / sizeof (PixelType);
279
sizeTile = tlwidth * tileHeight;
281
xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth);
282
ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight);
285
saveW = pbox->x2 - pbox->x1;
286
iline = (pbox->y1 - ySrc) % tileHeight;
287
psrcT = (PixelType *) pTile->devPrivate.ptr;
288
tileLine = iline * tlwidth;
289
saveH = pbox->y2 - pbox->y1;
290
saveP = afbScanline(pBase, pbox->x1, pbox->y1, nlwidth);
292
for (d = 0; d < depthDst; d++, psrcT += sizeTile, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */
293
if (!(planemask & (1 << d)))
298
pStartTile = psrcT + tileLine;
307
w = min(tileWidth, width);
308
if((rem = (x - xSrc) % tileWidth) != 0) {
309
/* if we're in the middle of the tile, get
310
as many bits as will finish the span, or
311
as many as will get to the left edge of the tile,
312
or a longword worth, starting at the appropriate
315
w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
316
endinc = rem / BITMAP_SCANLINE_PAD;
318
getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
320
getbits (pdst, (x & PIM), w, tmpdst);
321
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
323
putbits (tmpsrc, (x & PIM), w, pdst);
325
if((x & PIM) + w >= PPW)
327
} else if(((x & PIM) + w) < PPW) {
328
/* doing < PPW bits is easy, and worth special-casing */
331
getbits (pdst, (x & PIM), w, tmpdst);
332
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
334
putbits (tmpsrc, (x & PIM), w, pdst);
336
/* start at the left edge of the tile,
337
and put down as much as we can
339
maskbits(x, w, startmask, endmask, nlMiddle);
342
nstart = PPW - (x & PIM);
346
nend = (x + w) & PIM;
350
srcStartOver = nstart > PLST;
355
getbits (pdst, (x & PIM), nstart, tmpdst);
356
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
358
putbits (tmpsrc, (x & PIM), nstart, pdst);
365
getbits (psrc, nstart, PPW, tmpsrc);
368
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
371
/*putbits (tmpsrc, 0, PPW, pdst);
377
getbits (psrc, nstart, nend, tmpsrc);
380
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
382
putbits (tmpsrc, 0, nend, pdst);
387
} /* while (width > 0) */
389
pStartDst += nlwidth;
390
if (++iy >= tileHeight) {
394
pStartTile += tlwidth;
397
} /* for (d = ... ) */
403
MROP_NAME(afbOpaqueStippleAreaPPW)(pDraw, nbox, pbox, alu, ptile,
410
register unsigned char *rropsOS;
411
unsigned long planemask;
413
register PixelType *psrc;
414
/* pointer to bits in tile, if needed */
415
int tileHeight; /* height of the tile */
416
register PixelType srcpix = 0;
417
int nlwidth; /* width in longwords of the drawable */
418
int w; /* width of current box */
420
register int h; /* height of current box */
421
register int nlw; /* loop version of nlwMiddle */
422
register PixelType *p; /* pointer to bits we're writing */
427
PixelType endmask; /* masks for reggedy bits at either end of line */
428
int nlwMiddle; /* number of longwords between sides of boxes */
429
int nlwExtra; /* to get from right of box to left of next span */
430
register int iy; /* index of current scanline in tile */
431
PixelType *pbits; /* pointer to start of drawable */
436
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
439
MROP_INITIALIZE(alu,~0)
441
tileHeight = ptile->drawable.height;
442
psrc = (PixelType *)(ptile->devPrivate.ptr);
445
w = pbox->x2 - pbox->x1;
446
saveH = pbox->y2 - pbox->y1;
447
saveIY = pbox->y1 % tileHeight;
448
saveP = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
450
if ( ((pbox->x1 & PIM) + w) < PPW) {
451
maskpartialbits(pbox->x1, w, startmask);
453
for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */
454
if (!(planemask & (1 << d)))
462
switch (rropsOS[d]) {
477
if (iy == tileHeight)
479
*p = MROP_MASK(srcpix,*p,startmask);
480
afbScanlineInc(p, nlwExtra);
484
maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
486
for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */
487
if (!(planemask & (1 << d)))
493
nlwExtra = nlwidth - nlwMiddle;
495
if (startmask && endmask) {
498
switch (rropsOS[d]) {
513
if (iy == tileHeight)
516
*p = MROP_MASK (srcpix,*p,startmask);
519
*p = MROP_SOLID(srcpix,*p);
523
*p = MROP_MASK(srcpix,*p,endmask);
524
afbScanlineInc(p, nlwExtra);
526
} else if (startmask && !endmask) {
529
switch (rropsOS[d]) {
544
if (iy == tileHeight)
547
*p = MROP_MASK(srcpix,*p,startmask);
550
*p = MROP_SOLID(srcpix,*p);
553
afbScanlineInc(p, nlwExtra);
555
} else if (!startmask && endmask) {
557
switch (rropsOS[d]) {
572
if (iy == tileHeight)
576
*p = MROP_SOLID(srcpix,*p);
580
*p = MROP_MASK(srcpix,*p,endmask);
581
afbScanlineInc(p, nlwExtra);
583
} else { /* no ragged bits at either end */
585
switch (rropsOS[d]) {
600
if (iy == tileHeight)
604
*p = MROP_SOLID (srcpix,*p);
607
afbScanlineInc(p, nlwExtra);
610
} /* for (d = ...) */
617
MROP_NAME(afbOpaqueStippleArea)(pDraw, nbox, pbox, alu, pTile, xOff, yOff,
626
register unsigned char *rropsOS;
627
unsigned long planemask;
629
register PixelType *psrc;
630
/* pointer to bits in tile, if needed */
631
int nlwidth; /* width in longwords of the drawable */
633
register int h; /* height of current box */
634
register PixelType *pdst; /* pointer to bits we're writing */
635
register PixelType tmpsrc = 0;
637
register PixelType tmpdst;
643
int w, width, x, xSrc, ySrc, srcStartOver, nend;
644
int tlwidth, rem, tileWidth, tileHeight, endinc;
650
PixelType endmask; /* masks for reggedy bits at either end of line */
651
int nlMiddle; /* number of longwords between sides of boxes */
653
PixelType *pBase; /* pointer to start of drawable */
655
PixelType *pStartDst;
656
PixelType *pStartTile;
659
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
662
MROP_INITIALIZE(alu,~0)
664
tileHeight = pTile->drawable.height;
665
tileWidth = pTile->drawable.width;
666
tlwidth = pTile->devKind / sizeof (PixelType);
668
xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth);
669
ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight);
672
saveW = pbox->x2 - pbox->x1;
673
iline = (pbox->y1 - ySrc) % tileHeight;
674
psrcT = (PixelType *) pTile->devPrivate.ptr;
675
tileLine = iline * tlwidth;
676
saveH = pbox->y2 - pbox->y1;
677
saveP = afbScanline(pBase, pbox->x1, pbox->y1, nlwidth);
679
for (d = 0; d < depthDst; d++, saveP += sizeDst) { /* @@@ NEXT PLANE @@@ */
680
if (!(planemask & (1 << d)))
685
pStartTile = psrcT + tileLine;
694
w = min(tileWidth, width);
695
if((rem = (x - xSrc) % tileWidth) != 0) {
696
/* if we're in the middle of the tile, get
697
as many bits as will finish the span, or
698
as many as will get to the left edge of the tile,
699
or a longword worth, starting at the appropriate
702
w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
703
endinc = rem / BITMAP_SCANLINE_PAD;
705
switch (rropsOS[d]) {
714
getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
718
getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
723
getbits (pdst, (x & PIM), w, tmpdst);
724
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
726
putbits (tmpsrc, (x & PIM), w, pdst);
728
if((x & PIM) + w >= PPW)
730
} else if(((x & PIM) + w) < PPW) {
731
/* doing < PPW bits is easy, and worth special-casing */
732
switch (rropsOS[d]) {
747
getbits (pdst, (x & PIM), w, tmpdst);
748
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
750
putbits (tmpsrc, (x & PIM), w, pdst);
752
/* start at the left edge of the tile,
753
and put down as much as we can
755
maskbits(x, w, startmask, endmask, nlMiddle);
758
nstart = PPW - (x & PIM);
762
nend = (x + w) & PIM;
766
srcStartOver = nstart > PLST;
769
switch (rropsOS[d]) {
784
getbits (pdst, (x & PIM), nstart, tmpdst);
785
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
787
putbits (tmpsrc, (x & PIM), nstart, pdst);
794
switch (rropsOS[d]) {
802
getbits (psrc, nstart, PPW, tmpsrc);
805
getbits (psrc, nstart, PPW, tmpsrc);
811
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
814
/*putbits (tmpsrc, 0, PPW, pdst);
820
switch (rropsOS[d]) {
829
getbits (psrc, nstart, nend, tmpsrc);
833
getbits (psrc, nstart, nend, tmpsrc);
839
tmpsrc = DoMergeRop (tmpsrc, tmpdst);
841
putbits (tmpsrc, 0, nend, pdst);
846
} /* while (width > 0) */
848
pStartDst += nlwidth;
849
if (++iy >= tileHeight) {
853
pStartTile += tlwidth;
856
} /* for (d = ... ) */