|
|
1.1 root 1: /************************************************************
2: Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
3:
4: All Rights Reserved
5:
6: Permission to use, copy, modify, and distribute this
7: software and its documentation for any purpose and without
8: fee is hereby granted, provided that the above copyright no-
9: tice appear in all copies and that both that copyright no-
10: tice and this permission notice appear in supporting docu-
11: mentation, and that the names of Sun or MIT not be used in
12: advertising or publicity pertaining to distribution of the
13: software without specific prior written permission. Sun and
14: M.I.T. make no representations about the suitability of this
15: software for any purpose. It is provided "as is" without any
16: express or implied warranty.
17:
18: SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
20: NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
21: ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
22: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
23: PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
24: OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
25: THE USE OR PERFORMANCE OF THIS SOFTWARE.
26:
27: ********************************************************/
28:
29: /* $Header: cfbmskbits.h,v 4.2 87/09/10 17:53:42 sun Exp $ */
30:
31: extern int cfbstarttab[];
32: extern int cfbendtab[];
33: extern int cfbstartpartial[];
34: extern int cfbendpartial[];
35: extern int cfbrmask[32];
36: extern int cfbmask[32];
37:
38:
39: /*
40: * ==========================================================================
41: * Converted from mfb to support memory-mapped color framebuffer by smarks@sun,
42: * April-May 1987.
43: *
44: * The way I did the conversion was to consider each longword as an
45: * array of four bytes instead of an array of 32 one-bit pixels. So
46: * getbits() and putbits() retain much the same calling sequence, but
47: * they move bytes around instead of bits. Of course, this entails the
48: * removal of all of the one-bit-pixel dependencies from the other
49: * files, but the major bit-hacking stuff should be covered here.
50: *
51: * I've created some new macros that make it easier to understand what's
52: * going on in the pixel calculations, and that make it easier to change the
53: * pixel size.
54: *
55: * name mfb cfb explanation
56: * ---- --- --- -----------
57: * PPW 32 4 pixels per word
58: * PLST 31 3 last pixel in a word (should be PPW-1)
59: * PIM 0x1f 0x03 pixel index mask (index within a word)
60: * PWSH 5 2 pixel-to-word shift
61: * PSZ 1 8 pixel size (bits)
62: * PMSK 0x01 0xFF single-pixel mask
63: *
64: * Note that even with these new macros, there are still many dependencies
65: * in the code on the fact that there are 32 bits (not necessarily pixels)
66: * in each word. These macros remove the dependency that 1 pixel == 1 bit.
67: *
68: * I have also added a new macro, PFILL, that takes one pixel and
69: * replicates it throughout a word. This macro definition is dependent
70: * upon pixel and word size; it doesn't use macros like PPW and so
71: * forth. Examples: for monochrome, PFILL(1) => 0xffffffff, PFILL(0) =>
72: * 0x00000000. For 8-bit color, PFILL(0x5d) => 0x5d5d5d5d. This macro
73: * is used primarily for replicating a plane mask into a word.
74: *
75: * Color framebuffers operations also support the notion of a plane
76: * mask. This mask determines which planes of the framebuffer can be
77: * altered; the others are left unchanged. I have added another
78: * parameter to the putbits and putbitsrop macros that is the plane
79: * mask.
80: * ==========================================================================
81: */
82:
83: #define PPW 4
84: #define PLST 3
85: #define PIM 0x03
86: #define PWSH 2
87: #define PSZ 8
88: #define PMSK 0xFF
89:
90: /* the following notes use the following conventions:
91: SCREEN LEFT SCREEN RIGHT
92: in this file and maskbits.c, left and right refer to screen coordinates,
93: NOT bit numbering in registers.
94:
95: cfbstarttab[n]
96: pixels[0,n-1] = 0's pixels[n,PPW-1] = 1's
97: cfbendtab[n] =
98: pixels[0,n-1] = 1's pixels[n,PPW-1] = 0's
99:
100: cfbstartpartial[], cfbendpartial[]
101: these are used as accelerators for doing putbits and masking out
102: bits that are all contained between longword boudaries. the extra
103: 256 bytes of data seems a small price to pay -- code is smaller,
104: and narrow things (e.g. window borders) go faster.
105:
106: the names may seem misleading; they are derived not from which end
107: of the word the bits are turned on, but at which end of a scanline
108: the table tends to be used.
109:
110: look at the tables and macros to understand boundary conditions.
111: (careful readers will note that starttab[n] = ~endtab[n] for n != 0)
112:
113: -----------------------------------------------------------------------
114: these two macros depend on the screen's bit ordering.
115: in both of them x is a screen position. they are used to
116: combine bits collected from multiple longwords into a
117: single destination longword, and to unpack a single
118: source longword into multiple destinations.
119:
120: SCRLEFT(dst, x)
121: takes dst[x, PPW] and moves them to dst[0, PPW-x]
122: the contents of the rest of dst are 0 ONLY IF
123: dst is UNSIGNED.
124: is cast as an unsigned.
125: this is a right shift on the VAX, left shift on
126: Sun and pc-rt.
127:
128: SCRRIGHT(dst, x)
129: takes dst[0,x] and moves them to dst[PPW-x, PPW]
130: the contents of the rest of dst are 0 ONLY IF
131: dst is UNSIGNED.
132: this is a left shift on the VAX, right shift on
133: Sun and pc-rt.
134:
135:
136: the remaining macros are cpu-independent; all bit order dependencies
137: are built into the tables and the two macros above.
138:
139: maskbits(x, w, startmask, endmask, nlw)
140: for a span of width w starting at position x, returns
141: a mask for ragged pixels at start, mask for ragged pixels at end,
142: and the number of whole longwords between the ends.
143:
144: maskpartialbits(x, w, mask)
145: works like maskbits(), except all the pixels are in the
146: same longword (i.e. (x&0xPIM + w) <= PPW)
147:
148: mask32bits(x, w, startmask, endmask, nlw)
149: as maskbits, but does not calculate nlw. it is used by
150: cfbGlyphBlt to put down glyphs <= PPW bits wide.
151:
152: getbits(psrc, x, w, dst)
153: starting at position x in psrc (x < PPW), collect w
154: pixels and put them in the screen left portion of dst.
155: psrc is a longword pointer. this may span longword boundaries.
156: it special-cases fetching all w bits from one longword.
157:
158: +--------+--------+ +--------+
159: | | m |n| | ==> | m |n| |
160: +--------+--------+ +--------+
161: x x+w 0 w
162: psrc psrc+1 dst
163: m = PPW - x
164: n = w - m
165:
166: implementation:
167: get m pixels, move to screen-left of dst, zeroing rest of dst;
168: get n pixels from next word, move screen-right by m, zeroing
169: lower m pixels of word.
170: OR the two things together.
171:
172: putbits(src, x, w, pdst, planemask)
173: starting at position x in pdst, put down the screen-leftmost
174: w bits of src. pdst is a longword pointer. this may
175: span longword boundaries.
176: it special-cases putting all w bits into the same longword.
177:
178: +--------+ +--------+--------+
179: | m |n| | ==> | | m |n| |
180: +--------+ +--------+--------+
181: 0 w x x+w
182: dst pdst pdst+1
183: m = PPW - x
184: n = w - m
185:
186: implementation:
187: get m pixels, shift screen-right by x, zero screen-leftmost x
188: pixels; zero rightmost m bits of *pdst and OR in stuff
189: from before the semicolon.
190: shift src screen-left by m, zero bits n-32;
191: zero leftmost n pixels of *(pdst+1) and OR in the
192: stuff from before the semicolon.
193:
194: putbitsrop(src, x, w, pdst, planemask, ROP)
195: like putbits but calls DoRop with the rasterop ROP (see cfb.h for
196: DoRop)
197:
198: getleftbits(psrc, w, dst)
199: get the leftmost w (w<=PPW) bits from *psrc and put them
200: in dst. this is used by the cfbGlyphBlt code for glyphs
201: <=PPW bits wide.
202: */
203:
204: #include <X.h>
205: #include <Xmd.h>
206: #include <servermd.h>
207: #if (BITMAP_BIT_ORDER == MSBFirst)
208: #define SCRLEFT(lw, n) ((lw) << ((n)*PSZ))
209: #define SCRRIGHT(lw, n) ((lw) >> ((n)*PSZ))
210: #else /* (BITMAP_BIT_ORDER == LSBFirst) */
211: #define SCRLEFT(lw, n) ((lw) >> ((n)*PSZ))
212: #define SCRRIGHT(lw, n) ((lw) << ((n)*PSZ))
213: #endif (BITMAP_BIT_ORDER == MSBFirst)
214:
215: /*
216: * Note that the shift direction is independent of the byte ordering of the
217: * machine. The following is portable code.
218: */
219: #define PFILL(p) ( ((p)&PMSK) | \
220: ((p)&PMSK) << PSZ | \
221: ((p)&PMSK) << 2*PSZ | \
222: ((p)&PMSK) << 3*PSZ )
223:
224: #define maskbits(x, w, startmask, endmask, nlw) \
225: startmask = cfbstarttab[(x)&PIM]; \
226: endmask = cfbendtab[((x)+(w)) & PIM]; \
227: if (startmask) \
228: nlw = (((w) - (PPW - ((x)&PIM))) >> PWSH); \
229: else \
230: nlw = (w) >> PWSH;
231:
232: #define maskpartialbits(x, w, mask) \
233: mask = cfbstartpartial[(x) & PIM] & cfbendpartial[((x) + (w)) & PIM];
234:
235: #define mask32bits(x, w, startmask, endmask) \
236: startmask = cfbstarttab[(x)&PIM]; \
237: endmask = cfbendtab[((x)+(w)) & PIM];
238:
239:
240: #define getbits(psrc, x, w, dst) \
241: if ( ((x) + (w)) <= PPW) \
242: { \
243: dst = SCRLEFT(*(psrc), (x)); \
244: } \
245: else \
246: { \
247: int m; \
248: m = PPW-(x); \
249: dst = (SCRLEFT(*(psrc), (x)) & cfbendtab[m]) | \
250: (SCRRIGHT(*((psrc)+1), m) & cfbstarttab[m]); \
251: }
252:
253:
254: #define putbits(src, x, w, pdst, planemask) \
255: if ( ((x)+(w)) <= PPW) \
256: { \
257: unsigned long tmpmask; \
258: maskpartialbits((x), (w), tmpmask); \
259: tmpmask &= PFILL(planemask); \
260: *(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \
261: } \
262: else \
263: { \
264: unsigned long m; \
265: unsigned long n; \
266: unsigned long pm = PFILL(planemask); \
267: m = PPW-(x); \
268: n = (w) - m; \
269: *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | \
270: (SCRRIGHT(src, x) & (cfbstarttab[x] & pm)); \
271: *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
272: (SCRLEFT(src, m) & (cfbendtab[n] & pm)); \
273: }
274:
275: #define putbitsrop(src, x, w, pdst, planemask, rop) \
276: if ( ((x)+(w)) <= PPW) \
277: { \
278: unsigned long tmpmask; \
279: unsigned long t1, t2; \
280: maskpartialbits((x), (w), tmpmask); \
281: tmpmask &= PFILL(planemask); \
282: t1 = SCRRIGHT((src), (x)); \
283: t2 = DoRop(rop, t1, *(pdst)); \
284: *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
285: } \
286: else \
287: { \
288: unsigned long m; \
289: unsigned long n; \
290: unsigned long t1, t2; \
291: unsigned long pm = PFILL(planemask); \
292: m = PPW-(x); \
293: n = (w) - m; \
294: t1 = SCRRIGHT((src), (x)); \
295: t2 = DoRop(rop, t1, *(pdst)); \
296: *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | (t2 & (cfbstarttab[x] & pm));\
297: t1 = SCRLEFT((src), m); \
298: t2 = DoRop(rop, t1, *((pdst) + 1)); \
299: *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
300: (t2 & (cfbendtab[n] & pm)); \
301: }
302:
303: #define getleftbits(psrc, w, dst) \
304: dst = *(psrc);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.