|
|
1.1 root 1: /***********************************************************
2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4:
5: All Rights Reserved
6:
7: Permission to use, copy, modify, and distribute this software and its
8: documentation for any purpose and without fee is hereby granted,
9: provided that the above copyright notice appear in all copies and that
10: both that copyright notice and this permission notice appear in
11: supporting documentation, and that the names of Digital or MIT not be
12: used in advertising or publicity pertaining to distribution of the
13: software without specific, written prior permission.
14:
15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21: SOFTWARE.
22:
23: ******************************************************************/
24: /* $Header: mfbsetsp.c,v 1.21 87/09/07 19:08:09 toddb Exp $ */
25:
26: #include "X.h"
27: #include "Xmd.h"
28:
29: #include "misc.h"
30: #include "regionstr.h"
31: #include "gcstruct.h"
32: #include "windowstr.h"
33: #include "pixmapstr.h"
34: #include "scrnintstr.h"
35:
36: #include "mfb.h"
37: #include "maskbits.h"
38:
39: #include "servermd.h"
40:
41:
42: /* mfbSetScanline -- copies the bits from psrc to the drawable starting at
43: * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
44: * starts on the scanline. (I.e., if this scanline passes through multiple
45: * boxes, we may not want to start grabbing bits at psrc but at some offset
46: * further on.)
47: */
48: mfbSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst)
49: int y;
50: int xOrigin; /* where this scanline starts */
51: int xStart; /* first bit to use from scanline */
52: int xEnd; /* last bit to use from scanline + 1 */
53: register int *psrc;
54: register int alu; /* raster op */
55: int *pdstBase; /* start of the drawable */
56: int widthDst; /* width of drawable in words */
57: {
58: int w; /* width of scanline in bits */
59: register int *pdst; /* where to put the bits */
60: register int tmpSrc; /* scratch buffer to collect bits in */
61: int dstBit; /* offset in bits from beginning of
62: * word */
63: register int nstart; /* number of bits from first partial */
64: register int nend; /* " " last partial word */
65: int offSrc;
66: int startmask, endmask, nlMiddle, nl;
67:
68: pdst = pdstBase + (y * widthDst) + (xStart >> 5);
69: psrc += (xStart - xOrigin) >> 5;
70: offSrc = (xStart - xOrigin) & 0x1f;
71: w = xEnd - xStart;
72: dstBit = xStart & 0x1f;
73:
74: if (dstBit + w <= 32)
75: {
76: getbits(psrc, offSrc, w, tmpSrc);
77: putbitsrop(tmpSrc, dstBit, w, pdst, alu);
78: }
79: else
80: {
81:
82: maskbits(xStart, w, startmask, endmask, nlMiddle);
83: if (startmask)
84: nstart = 32 - dstBit;
85: else
86: nstart = 0;
87: if (endmask)
88: nend = xEnd & 0x1f;
89: else
90: nend = 0;
91: if (startmask)
92: {
93: getbits(psrc, offSrc, nstart, tmpSrc);
94: putbitsrop(tmpSrc, dstBit, nstart, pdst, alu);
95: pdst++;
96: offSrc += nstart;
97: if (offSrc > 31)
98: {
99: psrc++;
100: offSrc -= 32;
101: }
102: }
103: nl = nlMiddle;
104: while (nl--)
105: {
106: getbits(psrc, offSrc, 32, tmpSrc);
107: *pdst = DoRop(alu, tmpSrc, *pdst);
108: pdst++;
109: psrc++;
110: }
111: if (endmask)
112: {
113: getbits(psrc, offSrc, nend, tmpSrc);
114: putbitsrop(tmpSrc, 0, nend, pdst, alu);
115: }
116:
117: }
118: }
119:
120:
121:
122: /* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
123: * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
124: * are in increasing Y order.
125: * Source bit lines are server scanline padded so that they always begin
126: * on a word boundary.
127: */
128: void
129: mfbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
130: DrawablePtr pDrawable;
131: GCPtr pGC;
132: int *psrc;
133: register DDXPointPtr ppt;
134: int *pwidth;
135: int nspans;
136: int fSorted;
137: {
138: int *pdstBase; /* start of dst bitmap */
139: int widthDst; /* width of bitmap in words */
140: register BoxPtr pbox, pboxLast, pboxTest;
141: register DDXPointPtr pptLast;
142: int alu;
143: RegionPtr prgnDst;
144: int xStart, xEnd;
145: int yMax;
146:
147: alu = pGC->alu;
148: prgnDst = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip;
149:
150: pptLast = ppt + nspans;
151:
152: if (pDrawable->type == DRAWABLE_WINDOW)
153: {
154: pdstBase = (int *)
155: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
156: widthDst = (int)
157: ((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind
158: >> 2;
159: yMax = (int)((WindowPtr)pDrawable)->clientWinSize.height +
160: ((WindowPtr)pDrawable)->absCorner.y;
161: }
162: else
163: {
164: pdstBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
165: widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
166: yMax = ((PixmapPtr)pDrawable)->height;
167: }
168:
169: pbox = prgnDst->rects;
170: pboxLast = pbox + prgnDst->numRects;
171:
172: if(fSorted)
173: {
174: /* scan lines sorted in ascending order. Because they are sorted, we
175: * don't have to check each scanline against each clip box. We can be
176: * sure that this scanline only has to be clipped to boxes at or after the
177: * beginning of this y-band
178: */
179: pboxTest = pbox;
180: while(ppt < pptLast)
181: {
182: pbox = pboxTest;
183: if(ppt->y >= yMax)
184: break;
185: while(pbox < pboxLast)
186: {
187: if(pbox->y1 > ppt->y)
188: {
189: /* scanline is before clip box */
190: break;
191: }
192: else if(pbox->y2 <= ppt->y)
193: {
194: /* clip box is before scanline */
195: pboxTest = ++pbox;
196: continue;
197: }
198: else if(pbox->x1 > ppt->x + *pwidth)
199: {
200: /* clip box is to right of scanline */
201: break;
202: }
203: else if(pbox->x2 <= ppt->x)
204: {
205: /* scanline is to right of clip box */
206: pbox++;
207: continue;
208: }
209:
210: /* at least some of the scanline is in the current clip box */
211: xStart = max(pbox->x1, ppt->x);
212: xEnd = min(ppt->x + *pwidth, pbox->x2);
213: mfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
214: pdstBase, widthDst);
215: if(ppt->x + *pwidth <= pbox->x2)
216: {
217: /* End of the line, as it were */
218: break;
219: }
220: else
221: pbox++;
222: }
223: /* We've tried this line against every box; it must be outside them
224: * all. move on to the next point */
225: ppt++;
226: psrc += PixmapWidthInPadUnits(*pwidth, 1);
227: pwidth++;
228: }
229: }
230: else
231: {
232: /* scan lines not sorted. We must clip each line against all the boxes */
233: while(ppt < pptLast)
234: {
235: if(ppt->y >= 0 && ppt->y < yMax)
236: {
237:
238: for(pbox = prgnDst->rects; pbox< pboxLast; pbox++)
239: {
240: if(pbox->y1 > ppt->y)
241: {
242: /* rest of clip region is above this scanline,
243: * skip it */
244: break;
245: }
246: if(pbox->y2 <= ppt->y)
247: {
248: /* clip box is below scanline */
249: pbox++;
250: break;
251: }
252: if(pbox->x1 <= ppt->x + *pwidth &&
253: pbox->x2 > ppt->x)
254: {
255: xStart = max(pbox->x1, ppt->x);
256: xEnd = min(pbox->x2, ppt->x + *pwidth);
257: mfbSetScanline(ppt->y, ppt->x, xStart, xEnd,
258: psrc, alu, pdstBase, widthDst);
259: }
260:
261: }
262: }
263: psrc += PixmapWidthInPadUnits(*pwidth, 1);
264: ppt++;
265: pwidth++;
266: }
267: }
268: }
269:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.