|
|
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 "Xmd.h"
26: #include "servermd.h"
27: #include "pixmapstr.h"
28: #include "../mfb/maskbits.h"
29:
30: /* mfbQuickBlt -- a quick and dirty bitblit routine
31: * copies from psrcBase(xSrc, ySrc) to pdstBase(xDst, yDst) an array of bits
32: * w wide by h high. It is assumed that psrcBase and pdstBase point at
33: * things reasonable to bitblt between. It is assumed that all clipping has
34: * been done. It is also assumed that the rectangle fits on the destination
35: * (that is, that (pdstBase + (yDst * h) + w) is a bit in the destination).
36: * This routine does no error-checking of any type, CAVEAT HACKER
37: */
38: mfbQuickBlt(psrcBase, pdstBase, xSrc, ySrc, xDst, yDst, w, h, wSrc, wDst)
39: int *psrcBase, *pdstBase, /* first bits in pixmaps */
40: xSrc, ySrc, /* origin of source */
41: xDst, yDst, /* origin for destination */
42: w, /* width to blt */
43: h, /* height to blt */
44: wSrc, wDst; /* width of pixmaps */
45: {
46:
47: int *psrcLine, *pdstLine;
48: int xdir, ydir;
49: int nl, startmask, endmask, nlMiddle, *psrc, *pdst, tmpSrc;
50:
51: if(psrcBase + wSrc * h < pdstBase ||
52: pdstBase + wDst * h < psrcBase)
53: {
54: /* the areas don't overlap right and down is fine */
55: xdir = ydir = 1;
56: }
57: else if(ySrc < yDst) /* move right and up */
58: {
59: xdir = 1;
60: ydir = -1;
61: }
62: else if(ySrc > yDst) /* move right and down */
63: {
64: xdir = 1;
65: ydir = 1;
66: }
67: else if(xSrc < xDst) /* move left and down */
68: {
69: xdir = -1;
70: ydir = 1;
71: }
72: else /* if xSrc <= xDst */ /* move right and down */
73: {
74: xdir = 1;
75: ydir = 1;
76: }
77:
78: if (ydir == -1) /* start at last scanline of rectangle */
79: {
80: psrcLine = psrcBase + (((ySrc + h) -1) * wSrc);
81: pdstLine = pdstBase + (((yDst + h) -1) * wDst);
82: wSrc = -wSrc;
83: wDst = -wDst;
84: }
85: else /* start at first scanline */
86: {
87: psrcLine = psrcBase + (ySrc * wSrc);
88: pdstLine = pdstBase + (yDst * wDst);
89: }
90:
91: /* x direction doesn't matter for < 1 longword */
92: if (w <= 32)
93: {
94: int srcBit, dstBit; /* bit offset of src and dst */
95:
96: pdstLine += (xDst >> 5);
97: psrcLine += (xSrc >> 5);
98: psrc = psrcLine;
99: pdst = pdstLine;
100:
101: srcBit = xSrc & 0x1f;
102: dstBit = xDst & 0x1f;
103:
104: while(h--)
105: {
106: getbits(psrc, srcBit, w, tmpSrc);
107: putbits(tmpSrc, dstBit, w, pdst);
108: psrc += wSrc;
109: pdst += wDst;
110: }
111: }
112: else
113: {
114: register int xoffSrc; /* offset (>= 0, < 32) from which to
115: fetch whole longwords fetched
116: in src */
117: int nstart; /* number of ragged bits
118: at start of dst */
119: int nend; /* number of ragged bits at end
120: of dst */
121: int srcStartOver; /* pulling nstart bits from src
122: overflows into the next word? */
123:
124: maskbits(xDst, w, startmask, endmask, nlMiddle);
125: if (startmask)
126: nstart = 32 - (xDst & 0x1f);
127: else
128: nstart = 0;
129: if (endmask)
130: nend = (xDst + w) & 0x1f;
131: else
132: nend = 0;
133:
134: xoffSrc = ((xSrc & 0x1f) + nstart) & 0x1f;
135: srcStartOver = ((xSrc & 0x1f) + nstart) > 31;
136:
137: if (xdir == 1) /* move left to right */
138: {
139: pdstLine += (xDst >> 5);
140: psrcLine += (xSrc >> 5);
141:
142: while (h--)
143: {
144: psrc = psrcLine;
145: pdst = pdstLine;
146:
147: if (startmask)
148: {
149: getbits(psrc, (xSrc & 0x1f), nstart, tmpSrc);
150: putbits(tmpSrc, (xDst & 0x1f), nstart, pdst);
151: pdst++;
152: if (srcStartOver)
153: psrc++;
154: }
155:
156: nl = nlMiddle;
157: while (nl--)
158: {
159: getbits(psrc, xoffSrc, 32, tmpSrc);
160: *pdst++ = tmpSrc;
161: psrc++;
162: }
163:
164: if (endmask)
165: {
166: getbits(psrc, xoffSrc, nend, tmpSrc);
167: putbits(tmpSrc, 0, nend, pdst);
168: }
169:
170: psrcLine += wSrc;
171: pdstLine += wDst;
172: }
173: }
174: else /* move right to left */
175: {
176: pdstLine += ((xDst + w) >> 5);
177: psrcLine += (xSrc + w >> 5);
178: /* if fetch of last partial bits from source crosses
179: a longword boundary, start at the previous longword
180: */
181: if (xoffSrc + nend >= 32)
182: --psrcLine;
183:
184: while (h--)
185: {
186: psrc = psrcLine;
187: pdst = pdstLine;
188:
189: if (endmask)
190: {
191: getbits(psrc, xoffSrc, nend, tmpSrc)
192: putbits(tmpSrc, 0, nend, pdst)
193: }
194:
195: nl = nlMiddle;
196: while (nl--)
197: {
198: --psrc;
199: getbits(psrc, xoffSrc, 32, tmpSrc)
200: *--pdst = tmpSrc;
201: }
202:
203: if (startmask)
204: {
205: if (srcStartOver)
206: --psrc;
207: --pdst;
208: getbits(psrc, (xSrc & 0x1f), nstart, tmpSrc)
209: putbits(tmpSrc, (xDst & 0x1f), nstart, pdst)
210: }
211:
212: pdstLine += wDst;
213: psrcLine += wSrc;
214: }
215: } /* move right to left */
216: }
217: }
218:
219:
220: /* Rotates bitmap pPix by w pixels to the right on the screen. Assumes that
221: * words are 32 bits wide, and that the least significant bit appears on the
222: * left.
223: */
224: void
225: cfbXRotateBitmap(pPix, rw)
226: PixmapPtr pPix;
227: register int rw;
228: {
229: register long *pw, *pwFinal, *pwNew;
230: register unsigned long t;
231: int size;
232:
233: if (pPix == NullPixmap)
234: return;
235:
236: pw = (long *)pPix->devPrivate;
237: rw %= pPix->width;
238: if (rw < 0)
239: rw += pPix->width;
240: if(pPix->width == 32)
241: {
242: pwFinal = pw + pPix->height;
243: while(pw < pwFinal)
244: {
245: t = *pw;
246: *pw++ = SCRRIGHT(t, rw) |
247: (SCRLEFT(t, (32-rw)) & endtab[rw]);
248: }
249: }
250: else
251: {
252: pwNew = (long *) Xalloc( pPix->height * pPix->devKind);
253:
254: /* o.k., divide pw (the pixmap) in two vertically at (w - rw)
255: * pick up the part on the left and make it the right of the new
256: * pixmap. then pick up the part on the right and make it the left
257: * of the new pixmap.
258: * now hook in the new part and throw away the old. All done.
259: */
260: size = PixmapWidthInPadUnits(pPix->width, 1);
261: mfbQuickBlt(pw, pwNew, 0, 0, rw, 0, pPix->width - rw, pPix->height,
262: size, size);
263: mfbQuickBlt(pw, pwNew, pPix->width - rw, 0, 0, 0, rw, pPix->height,
264: size, size);
265: pPix->devPrivate = (pointer) pwNew;
266: Xfree((char *) pw);
267:
268: }
269:
270: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.