|
|
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.