|
|
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: maskbits.h,v 1.6 87/09/12 23:46:43 toddb Exp $ */
25: #include "X.h"
26: #include "Xmd.h"
27: #include "servermd.h"
28:
29: extern int starttab[];
30: extern int endtab[];
31: extern int startpartial[];
32: extern int endpartial[];
33: extern int rmask[32];
34: extern int mask[32];
35:
36:
37: /* the following notes use the following conventions:
38: SCREEN LEFT SCREEN RIGHT
39: in this file and maskbits.c, left and right refer to screen coordinates,
40: NOT bit numbering in registers.
41:
42: starttab[n]
43: bits[0,n-1] = 0 bits[n,31] = 1
44: endtab[n] =
45: bits[0,n-1] = 1 bits[n,31] = 0
46:
47: startpartial[], endpartial[]
48: these are used as accelerators for doing putbits and masking out
49: bits that are all contained between longword boudaries. the extra
50: 256 bytes of data seems a small price to pay -- code is smaller,
51: and narrow things (e.g. window borders) go faster.
52:
53: the names may seem misleading; they are derived not from which end
54: of the word the bits are turned on, but at which end of a scanline
55: the table tends to be used.
56:
57: look at the tables and macros to understand boundary conditions.
58: (careful readers will note that starttab[n] = ~endtab[n] for n != 0)
59:
60: -----------------------------------------------------------------------
61: these two macros depend on the screen's bit ordering.
62: in both of them x is a screen position. they are used to
63: combine bits collected from multiple longwords into a
64: single destination longword, and to unpack a single
65: source longword into multiple destinations.
66:
67: SCRLEFT(dst, x)
68: takes dst[x, 32] and moves them to dst[0, 32-x]
69: the contents of the rest of dst are 0 ONLY IF
70: dst is UNSIGNED.
71: this is a right shift on LSBFirst (forward-thinking)
72: machines like the VAX, and left shift on MSBFirst
73: (backwards) machines like the 680x0 and pc/rt.
74:
75: SCRRIGHT(dst, x)
76: takes dst[0,x] and moves them to dst[32-x, 32]
77: the contents of the rest of dst are 0 ONLY IF
78: dst is UNSIGNED.
79: this is a left shift on LSBFirst, right shift
80: on MSBFirst.
81:
82:
83: the remaining macros are cpu-independent; all bit order dependencies
84: are built into the tables and the two macros above.
85:
86: maskbits(x, w, startmask, endmask, nlw)
87: for a span of width w starting at position x, returns
88: a mask for ragged bits at start, mask for ragged bits at end,
89: and the number of whole longwords between the ends.
90:
91: maskpartialbits(x, w, mask)
92: works like maskbits(), except all the bits are in the
93: same longword (i.e. (x&0x1f + w) <= 32)
94:
95: mask32bits(x, w, startmask, endmask, nlw)
96: as maskbits, but does not calculate nlw. it is used by
97: mfbGlyphBlt to put down glyphs <= 32 bits wide.
98:
99: -------------------------------------------------------------------
100:
101: NOTE
102: any pointers passe to the following 4 macros are
103: guranteed to be 32-bit aligned.
104: The only non-32-bit-aligned references ever made are
105: to font glyphs, and those are made with getleftbits()
106: and getshiftedleftbits (qq.v.)
107:
108: getbits(psrc, x, w, dst)
109: starting at position x in psrc (x < 32), collect w
110: bits and put them in the screen left portion of dst.
111: psrc is a longword pointer. this may span longword boundaries.
112: it special-cases fetching all w bits from one longword.
113:
114: +--------+--------+ +--------+
115: | | m |n| | ==> | m |n| |
116: +--------+--------+ +--------+
117: x x+w 0 w
118: psrc psrc+1 dst
119: m = 32 - x
120: n = w - m
121:
122: implementation:
123: get m bits, move to screen-left of dst, zeroing rest of dst;
124: get n bits from next word, move screen-right by m, zeroing
125: lower m bits of word.
126: OR the two things together.
127:
128: putbits(src, x, w, pdst)
129: starting at position x in pdst, put down the screen-leftmost
130: w bits of src. pdst is a longword pointer. this may
131: span longword boundaries.
132: it special-cases putting all w bits into the same longword.
133:
134: +--------+ +--------+--------+
135: | m |n| | ==> | | m |n| |
136: +--------+ +--------+--------+
137: 0 w x x+w
138: dst pdst pdst+1
139: m = 32 - x
140: n = w - m
141:
142: implementation:
143: get m bits, shift screen-right by x, zero screen-leftmost x
144: bits; zero rightmost m bits of *pdst and OR in stuff
145: from before the semicolon.
146: shift src screen-left by m, zero bits n-32;
147: zero leftmost n bits of *(pdst+1) and OR in the
148: stuff from before the semicolon.
149:
150: putbitsrop(src, x, w, pdst, ROP)
151: like putbits but calls DoRop with the rasterop ROP (see mfb.h for
152: DoRop)
153:
154: putbitsrrop(src, x, w, pdst, ROP)
155: like putbits but calls DoRRop with the reduced rasterop ROP
156: (see mfb.h for DoRRop)
157:
158: -----------------------------------------------------------------------
159: The two macros below are used only for getting bits from glyphs
160: in fonts, and glyphs in fonts are gotten only with the following two
161: mcros.
162: You should tune these macros toyour font format and cpu
163: byte ordering.
164:
165: NOTE
166: getleftbits(psrc, w, dst)
167: get the leftmost w (w<=32) bits from *psrc and put them
168: in dst. this is used by the mfbGlyphBlt code for glyphs
169: <=32 bits wide.
170: psrc is declared (unsigned char *)
171:
172: psrc is NOT guaranteed to be 32-bit aligned. on many
173: machines this will cause problems, so there are several
174: versions of this macro.
175:
176: this macro is called ONLY for getting bits from font glyphs,
177: and depends on the server-natural font padding.
178:
179: for blazing text performance, you want this macro
180: to touch memory as infrequently as possible (e.g.
181: fetch longwords) and as efficiently as possible
182: (e.g. don't fetch misaligned longwords)
183:
184: getshiftedleftbits(psrc, offset, w, dst)
185: used by the font code; like getleftbits, but shifts the
186: bits SCRLEFT by offset.
187: this is implemented portably, calling getleftbits()
188: and SCRLEFT().
189: psrc is declared (unsigned char *).
190: */
191:
192: #if (BITMAP_BIT_ORDER == MSBFirst) /* pc/rt, 680x0 */
193: #define SCRLEFT(lw, n) ((lw) << (n))
194: #define SCRRIGHT(lw, n) ((lw) >> (n))
195: #else /* vax, intel */
196: #define SCRLEFT(lw, n) ((lw) >> (n))
197: #define SCRRIGHT(lw, n) ((lw) << (n))
198: #endif
199:
200:
201: #define maskbits(x, w, startmask, endmask, nlw) \
202: startmask = starttab[(x)&0x1f]; \
203: endmask = endtab[((x)+(w)) & 0x1f]; \
204: if (startmask) \
205: nlw = (((w) - (32 - ((x)&0x1f))) >> 5); \
206: else \
207: nlw = (w) >> 5;
208:
209: #define maskpartialbits(x, w, mask) \
210: mask = startpartial[(x) & 0x1f] & endpartial[((x) + (w)) & 0x1f];
211:
212: #define mask32bits(x, w, startmask, endmask) \
213: startmask = starttab[(x)&0x1f]; \
214: endmask = endtab[((x)+(w)) & 0x1f];
215:
216:
217: #define getbits(psrc, x, w, dst) \
218: if ( ((x) + (w)) <= 32) \
219: { \
220: dst = SCRLEFT(*(psrc), (x)); \
221: } \
222: else \
223: { \
224: int m; \
225: m = 32-(x); \
226: dst = (SCRLEFT(*(psrc), (x)) & endtab[m]) | \
227: (SCRRIGHT(*((psrc)+1), m) & starttab[m]); \
228: }
229:
230:
231: #define putbits(src, x, w, pdst) \
232: if ( ((x)+(w)) <= 32) \
233: { \
234: int tmpmask; \
235: maskpartialbits((x), (w), tmpmask); \
236: *(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \
237: } \
238: else \
239: { \
240: int m; \
241: int n; \
242: m = 32-(x); \
243: n = (w) - m; \
244: *(pdst) = (*(pdst) & endtab[x]) | (SCRRIGHT(src, x) & starttab[x]); \
245: *((pdst)+1) = (*((pdst)+1) & starttab[n]) | (SCRLEFT(src, m) & endtab[n]); \
246: }
247:
248: #define putbitsrop(src, x, w, pdst, rop) \
249: if ( ((x)+(w)) <= 32) \
250: { \
251: int tmpmask; \
252: int t1, t2; \
253: maskpartialbits((x), (w), tmpmask); \
254: t1 = SCRRIGHT((src), (x)); \
255: t2 = DoRop(rop, t1, *(pdst)); \
256: *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
257: } \
258: else \
259: { \
260: int m; \
261: int n; \
262: int t1, t2; \
263: m = 32-(x); \
264: n = (w) - m; \
265: t1 = SCRRIGHT((src), (x)); \
266: t2 = DoRop(rop, t1, *(pdst)); \
267: *(pdst) = (*(pdst) & endtab[x]) | (t2 & starttab[x]); \
268: t1 = SCRLEFT((src), m); \
269: t2 = DoRop(rop, t1, *((pdst) + 1)); \
270: *((pdst)+1) = (*((pdst)+1) & starttab[n]) | (t2 & endtab[n]); \
271: }
272:
273: #define putbitsrrop(src, x, w, pdst, rop) \
274: if ( ((x)+(w)) <= 32) \
275: { \
276: int tmpmask; \
277: int t1, t2; \
278: maskpartialbits((x), (w), tmpmask); \
279: t1 = SCRRIGHT((src), (x)); \
280: t2 = DoRRop(rop, t1, *(pdst)); \
281: *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
282: } \
283: else \
284: { \
285: int m; \
286: int n; \
287: int t1, t2; \
288: m = 32-(x); \
289: n = (w) - m; \
290: t1 = SCRRIGHT((src), (x)); \
291: t2 = DoRRop(rop, t1, *(pdst)); \
292: *(pdst) = (*(pdst) & endtab[x]) | (t2 & starttab[x]); \
293: t1 = SCRLEFT((src), m); \
294: t2 = DoRRop(rop, t1, *((pdst) + 1)); \
295: *((pdst)+1) = (*((pdst)+1) & starttab[n]) | (t2 & endtab[n]); \
296: }
297:
298: #if GETLEFTBITS_ALIGNMENT == 1
299: #define getleftbits(psrc, w, dst) getbits(psrc, 0, w, dst)
300: #endif /* GETLEFTBITS_ALIGNMENT == 1 */
301:
302: #if GETLEFTBITS_ALIGNMENT == 2
303: #define getleftbits(psrc, w, dst) \
304: { \
305: if ( ((int)(psrc)) & 0x01 ) \
306: getbits( ((unsigned int *)((int)(psrc))-1), 8, (w), (dst) ); \
307: else
308: getbits(psrc, 0, w, dst)
309: }
310: #endif /* GETLEFTBITS_ALIGNMENT == 2 */
311:
312: #if GETLEFTBITS_ALIGNMENT == 4
313: #define getleftbits(psrc, w, dst) \
314: { \
315: int off; \
316: off = ( ((int)(psrc)) & 0x03) << 3; \
317: getbits( \
318: (unsigned int *)( ((int)(psrc)) &~0x03), \
319: (off), (w), (dst) \
320: ); \
321: }
322: #endif /* GETLEFTBITS_ALIGNMENT == 4 */
323:
324:
325: #define getshiftedleftbits(psrc, offset, w, dst) \
326: getleftbits((psrc), (w), (dst)); \
327: dst = SCRLEFT((dst), (offset));
328:
329:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.