|
|
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: mfbclip.c,v 1.14 87/09/11 07:21:11 toddb Exp $ */
25: #include "X.h"
26: #include "miscstruct.h"
27: #include "pixmapstr.h"
28: #include "scrnintstr.h"
29: #include "regionstr.h"
30: #include "gc.h"
31: #include "maskbits.h"
32:
33: /* Convert bitmap clip mask into clipping region.
34: * First, goes through each line and makes boxes by noting the transitions
35: * from 0 to 1 and 1 to 0.
36: * Then it coalesces the current line with the previous if they have boxes
37: * at the same X coordinates. We have to keep indices to rectangles rather
38: * than pointers because everything may move if we Xrealloc when adding a
39: * rectangle.
40: */
41: RegionPtr
42: mfbPixmapToRegion(pPix)
43: PixmapPtr pPix;
44: {
45: RegionPtr pReg;
46: register unsigned *pw, w;
47: register int ib;
48: int width, h, base, rx1, crects;
49: unsigned int *pwLineStart;
50: int irectPrevStart, irectLineStart;
51: register BoxPtr prectO, prectN;
52: BoxPtr FirstRect, rects, prectLineStart;
53: Bool fInBox, fSame;
54:
55:
56: if((pReg = (*pPix->drawable.pScreen->RegionCreate)(NULL, 1)) == NullRegion)
57: return NullRegion;
58: rects = (BoxPtr) Xalloc(sizeof(BoxRec));
59: FirstRect = rects;
60: width = pPix->width;
61: pw = (unsigned int *)pPix->devPrivate;
62: irectPrevStart = -1;
63: for(h = 0; h < pPix->height; h++)
64: {
65:
66: irectLineStart = rects - FirstRect;
67: pwLineStart = pw;
68: /* If the Screen left most bit of the word is set, we're starting in
69: * a box */
70: if(*pw & mask[0])
71: {
72: fInBox = TRUE;
73: rx1 = 0;
74: }
75: else
76: fInBox = FALSE;
77: /* Process all words which are fully in the pixmap */
78: while(pw < pwLineStart + width/32)
79: {
80: base = (pw - pwLineStart) * 32;
81: w = *pw++;
82: for(ib = 0; ib < 32; ib++)
83: {
84: /* If the Screen left most bit of the word is set, we're
85: * starting a box */
86: if(w & mask[0])
87: {
88: if(!fInBox)
89: {
90: rx1 = base + ib;
91: /* start new box */
92: fInBox = TRUE;
93: }
94: }
95: else
96: {
97: if(fInBox)
98: {
99: /* end box */
100: MEMCHECK(pReg, rects, FirstRect);
101: ADDRECT(pReg, rects, rx1, h, base + ib, h + 1);
102: fInBox = FALSE;
103: }
104: }
105: /* Shift the word VISUALLY left one. */
106: w = SCRLEFT(w, 1);
107: }
108: }
109: if(width & 0x1F)
110: {
111: /* Process final partial word on line */
112: base = (pw - pwLineStart) * 32;
113: w = *pw++;
114: for(ib = 0; ib < width &0x1F; ib++)
115: {
116: /* If the Screen left most bit of the word is set, we're
117: * starting a box */
118: if(w & mask[0])
119: {
120: if(!fInBox)
121: {
122: rx1 = base + ib;
123: /* start new box */
124: fInBox = TRUE;
125: }
126: }
127: else
128: {
129: if(fInBox)
130: {
131: /* end box */
132: MEMCHECK(pReg, rects, FirstRect);
133: ADDRECT(pReg, rects, rx1, h, base + ib, h + 1);
134: fInBox = FALSE;
135: }
136: }
137: /* Shift the word VISUALLY left one. */
138: w = SCRLEFT(w, 1);
139: }
140: }
141: /* If scanline ended with last bit set, end the box */
142: if(fInBox)
143: {
144: MEMCHECK(pReg, rects, FirstRect);
145: ADDRECT(pReg, rects, rx1, h, base + ib, h + 1);
146: }
147: /* if all rectangles on this line have the same x-coords as
148: * those on the previous line, then add 1 to all the previous y2s and
149: * throw away all the rectangles from this line
150: */
151: fSame = FALSE;
152: if(irectPrevStart != -1)
153: {
154: crects = irectLineStart - irectPrevStart;
155: if(crects == ((rects - FirstRect) - irectLineStart))
156: {
157: prectO = FirstRect + irectPrevStart;
158: prectN = prectLineStart = FirstRect + irectLineStart;
159: fSame = TRUE;
160: while(prectO < prectLineStart)
161: {
162: if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
163: {
164: fSame = FALSE;
165: break;
166: }
167: prectO++;
168: prectN++;
169: }
170: if (fSame)
171: {
172: prectO = FirstRect + irectPrevStart;
173: while(prectO < prectLineStart)
174: {
175: prectO->y2 += 1;
176: prectO++;
177: }
178: rects -= crects;
179: pReg->numRects -= crects;
180: }
181: }
182: }
183: if(!fSame)
184: irectPrevStart = irectLineStart;
185: }
186: if(pReg->numRects)
187: {
188: Xfree((char *)pReg->rects);
189: pReg->size = pReg->numRects;
190: pReg->rects = FirstRect;
191: }
192: else
193: {
194: Xfree((char *) FirstRect);
195: Xfree((char *) pReg);
196: pReg = NullRegion;
197: }
198:
199: return(pReg);
200: }
201:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.