|
|
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:
25: #include "X.h"
26: #include "Xmd.h"
27: #include "servermd.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 "cfb.h"
37: #include "cfbmskbits.h"
38:
39:
40: /* cfbSetScanline -- copies the bits from psrc to the drawable starting at
41: * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
42: * starts on the scanline. (I.e., if this scanline passes through multiple
43: * boxes, we may not want to start grabbing bits at psrc but at some offset
44: * further on.)
45: */
46: cfbSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst, planemask)
47: int y;
48: int xOrigin; /* where this scanline starts */
49: int xStart; /* first bit to use from scanline */
50: int xEnd; /* last bit to use from scanline + 1 */
51: register int *psrc;
52: register int alu; /* raster op */
53: int *pdstBase; /* start of the drawable */
54: int widthDst; /* width of drawable in words */
55: long planemask;
56: {
57: int w; /* width of scanline in bits */
58: register int *pdst; /* where to put the bits */
59: register int tmpSrc; /* scratch buffer to collect bits in */
60: int dstBit; /* offset in bits from beginning of
61: * word */
62: register int nstart; /* number of bits from first partial */
63: register int nend; /* " " last partial word */
64: int offSrc;
65: int startmask, endmask, nlMiddle, nl;
66:
67: pdst = pdstBase + (y * widthDst) + (xStart >> PWSH);
68: psrc += (xStart - xOrigin) >> PWSH;
69: offSrc = (xStart - xOrigin) & PIM;
70: w = xEnd - xStart;
71: dstBit = xStart & PIM;
72:
73: if (dstBit + w <= PPW)
74: {
75: getbits(psrc, offSrc, w, tmpSrc);
76: putbitsrop(tmpSrc, dstBit, w, pdst, planemask, alu);
77: }
78: else
79: {
80:
81: maskbits(xStart, w, startmask, endmask, nlMiddle);
82: if (startmask)
83: nstart = PPW - dstBit;
84: else
85: nstart = 0;
86: if (endmask)
87: nend = xEnd & PIM;
88: else
89: nend = 0;
90: if (startmask)
91: {
92: getbits(psrc, offSrc, nstart, tmpSrc);
93: putbitsrop(tmpSrc, dstBit, nstart, pdst, planemask, alu);
94: pdst++;
95: offSrc += nstart;
96: if (offSrc > PLST)
97: {
98: psrc++;
99: offSrc -= PPW;
100: }
101: }
102: nl = nlMiddle;
103: while (nl--)
104: {
105: getbits(psrc, offSrc, PPW, tmpSrc);
106: putbitsrop(tmpSrc, 0, PPW, pdst, planemask, alu );
107: pdst++;
108: psrc++;
109: }
110: if (endmask)
111: {
112: getbits(psrc, offSrc, nend, tmpSrc);
113: putbitsrop(tmpSrc, 0, nend, pdst, planemask, alu);
114: }
115:
116: }
117: }
118:
119:
120:
121: /* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
122: * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
123: * are in increasing Y order.
124: * Source bit lines are server scanline padded so that they always begin
125: * on a word boundary.
126: */
127: void
128: cfbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
129: DrawablePtr pDrawable;
130: GCPtr pGC;
131: int *psrc;
132: register DDXPointPtr ppt;
133: int *pwidth;
134: int nspans;
135: int fSorted;
136: {
137: int *pdstBase; /* start of dst bitmap */
138: int widthDst; /* width of bitmap in words */
139: register BoxPtr pbox, pboxLast, pboxTest;
140: register DDXPointPtr pptLast;
141: int alu;
142: RegionPtr prgnDst;
143: int xStart, xEnd;
144: int yMax;
145:
146: switch (pDrawable->depth) {
147: case 1:
148: mfbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
149: return;
150: case 8:
151: break;
152: default:
153: FatalError("cfbSetSpans: invalid depth\n");
154: }
155:
156: alu = pGC->alu;
157: prgnDst = ((cfbPrivGC *)(pGC->devPriv))->pCompositeClip;
158:
159: pptLast = ppt + nspans;
160:
161: if (pDrawable->type == DRAWABLE_WINDOW)
162: {
163: pdstBase = (int *)
164: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
165: widthDst = (int)
166: ((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind
167: >> 2;
168: yMax = (int)((WindowPtr)pDrawable)->clientWinSize.height +
169: ((WindowPtr)pDrawable)->absCorner.y;
170:
171: /* translation should be done by caller of this routine
172: pptT = ppt;
173: while(pptT < pptLast)
174: {
175: pptT->x += ((WindowPtr)pDrawable)->absCorner.x;
176: pptT->y += ((WindowPtr)pDrawable)->absCorner.y;
177: pptT++;
178: }
179: */
180: }
181: else
182: {
183: pdstBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
184: widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
185: yMax = ((PixmapPtr)pDrawable)->height;
186: }
187:
188: pbox = prgnDst->rects;
189: pboxLast = pbox + prgnDst->numRects;
190:
191: if(fSorted)
192: {
193: /* scan lines sorted in ascending order. Because they are sorted, we
194: * don't have to check each scanline against each clip box. We can be
195: * sure that this scanline only has to be clipped to boxes at or after the
196: * beginning of this y-band
197: */
198: pboxTest = pbox;
199: while(ppt < pptLast)
200: {
201: pbox = pboxTest;
202: if(ppt->y >= yMax)
203: break;
204: while(pbox < pboxLast)
205: {
206: if(pbox->y1 > ppt->y)
207: {
208: /* scanline is before clip box */
209: break;
210: }
211: else if(pbox->y2 <= ppt->y)
212: {
213: /* clip box is before scanline */
214: pboxTest = ++pbox;
215: continue;
216: }
217: else if(pbox->x1 > ppt->x + *pwidth)
218: {
219: /* clip box is to right of scanline */
220: break;
221: }
222: else if(pbox->x2 <= ppt->x)
223: {
224: /* scanline is to right of clip box */
225: pbox++;
226: continue;
227: }
228:
229: /* at least some of the scanline is in the current clip box */
230: xStart = max(pbox->x1, ppt->x);
231: xEnd = min(ppt->x + *pwidth, pbox->x2);
232: cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
233: pdstBase, widthDst, pGC->planemask);
234: if(ppt->x + *pwidth <= pbox->x2)
235: {
236: /* End of the line, as it were */
237: break;
238: }
239: else
240: pbox++;
241: }
242: /* We've tried this line against every box; it must be outside them
243: * all. move on to the next point */
244: ppt++;
245: psrc += PixmapWidthInPadUnits(*pwidth, PSZ);
246: pwidth++;
247: }
248: }
249: else
250: {
251: /* scan lines not sorted. We must clip each line against all the boxes */
252: while(ppt < pptLast)
253: {
254: if(ppt->y >= 0 && ppt->y < yMax)
255: {
256:
257: for(pbox = prgnDst->rects; pbox< pboxLast; pbox++)
258: {
259: if(pbox->y1 > ppt->y)
260: {
261: /* rest of clip region is above this scanline,
262: * skip it */
263: break;
264: }
265: if(pbox->y2 <= ppt->y)
266: {
267: /* clip box is below scanline */
268: pbox++;
269: break;
270: }
271: if(pbox->x1 <= ppt->x + *pwidth &&
272: pbox->x2 > ppt->x)
273: {
274: xStart = max(pbox->x1, ppt->x);
275: xEnd = min(pbox->x2, ppt->x + *pwidth);
276: cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
277: pdstBase, widthDst, pGC->planemask);
278: }
279:
280: }
281: }
282: psrc += PixmapWidthInPadUnits(*pwidth, PSZ);
283: ppt++;
284: pwidth++;
285: }
286: }
287: }
288:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.