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