Annotation of sys/dev/rasops/rasops8.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: rasops8.c,v 1.7 2006/12/02 15:55:18 miod Exp $ */
! 2: /* $NetBSD: rasops8.c,v 1.8 2000/04/12 14:22:29 pk Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1999 The NetBSD Foundation, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to The NetBSD Foundation
! 9: * by Andrew Doran.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. All advertising materials mentioning features or use of this software
! 20: * must display the following acknowledgement:
! 21: * This product includes software developed by the NetBSD
! 22: * Foundation, Inc. and its contributors.
! 23: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 24: * contributors may be used to endorse or promote products derived
! 25: * from this software without specific prior written permission.
! 26: *
! 27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 37: * POSSIBILITY OF SUCH DAMAGE.
! 38: */
! 39:
! 40: #include <sys/param.h>
! 41: #include <sys/systm.h>
! 42: #include <sys/time.h>
! 43:
! 44: #include <dev/wscons/wsdisplayvar.h>
! 45: #include <dev/wscons/wsconsio.h>
! 46: #include <dev/rasops/rasops.h>
! 47:
! 48: void rasops8_putchar(void *, int, int, u_int, long attr);
! 49: #ifndef RASOPS_SMALL
! 50: void rasops8_putchar8(void *, int, int, u_int, long attr);
! 51: void rasops8_putchar12(void *, int, int, u_int, long attr);
! 52: void rasops8_putchar16(void *, int, int, u_int, long attr);
! 53: void rasops8_makestamp(struct rasops_info *ri, long);
! 54:
! 55: /*
! 56: * 4x1 stamp for optimized character blitting
! 57: */
! 58: static int32_t stamp[16];
! 59: static long stamp_attr;
! 60: static int stamp_mutex; /* XXX see note in README */
! 61: #endif
! 62:
! 63: /*
! 64: * XXX this confuses the hell out of gcc2 (not egcs) which always insists
! 65: * that the shift count is negative.
! 66: *
! 67: * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
! 68: * destination = STAMP_READ(offset)
! 69: */
! 70: #define STAMP_SHIFT(fb,n) ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
! 71: #define STAMP_MASK (0xf << 2)
! 72: #define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
! 73:
! 74: /*
! 75: * Initialize a 'rasops_info' descriptor for this depth.
! 76: */
! 77: void
! 78: rasops8_init(ri)
! 79: struct rasops_info *ri;
! 80: {
! 81:
! 82: switch (ri->ri_font->fontwidth) {
! 83: #ifndef RASOPS_SMALL
! 84: case 8:
! 85: ri->ri_ops.putchar = rasops8_putchar8;
! 86: break;
! 87: case 12:
! 88: ri->ri_ops.putchar = rasops8_putchar12;
! 89: break;
! 90: case 16:
! 91: ri->ri_ops.putchar = rasops8_putchar16;
! 92: break;
! 93: #endif /* !RASOPS_SMALL */
! 94: default:
! 95: ri->ri_ops.putchar = rasops8_putchar;
! 96: break;
! 97: }
! 98: }
! 99:
! 100: /*
! 101: * Put a single character.
! 102: */
! 103: void
! 104: rasops8_putchar(cookie, row, col, uc, attr)
! 105: void *cookie;
! 106: int row, col;
! 107: u_int uc;
! 108: long attr;
! 109: {
! 110: int width, height, cnt, fs, fb;
! 111: u_char *dp, *rp, *fr, clr[2];
! 112: struct rasops_info *ri;
! 113:
! 114: ri = (struct rasops_info *)cookie;
! 115:
! 116: #ifdef RASOPS_CLIPPING
! 117: /* Catches 'row < 0' case too */
! 118: if ((unsigned)row >= (unsigned)ri->ri_rows)
! 119: return;
! 120:
! 121: if ((unsigned)col >= (unsigned)ri->ri_cols)
! 122: return;
! 123: #endif
! 124: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
! 125:
! 126: height = ri->ri_font->fontheight;
! 127: width = ri->ri_font->fontwidth;
! 128: clr[0] = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
! 129: clr[1] = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
! 130:
! 131: if (uc == ' ') {
! 132: u_char c = clr[0];
! 133:
! 134: while (height--) {
! 135: dp = rp;
! 136: rp += ri->ri_stride;
! 137:
! 138: for (cnt = width; cnt; cnt--)
! 139: *dp++ = c;
! 140: }
! 141: } else {
! 142: uc -= ri->ri_font->firstchar;
! 143: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
! 144: fs = ri->ri_font->stride;
! 145:
! 146: while (height--) {
! 147: dp = rp;
! 148: fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
! 149: fr += fs;
! 150: rp += ri->ri_stride;
! 151:
! 152: for (cnt = width; cnt; cnt--) {
! 153: *dp++ = clr[(fb >> 31) & 1];
! 154: fb <<= 1;
! 155: }
! 156: }
! 157: }
! 158:
! 159: /* Do underline */
! 160: if ((attr & 1) != 0) {
! 161: u_char c = clr[1];
! 162:
! 163: rp -= (ri->ri_stride << 1);
! 164:
! 165: while (width--)
! 166: *rp++ = c;
! 167: }
! 168: }
! 169:
! 170: #ifndef RASOPS_SMALL
! 171: /*
! 172: * Recompute the 4x1 blitting stamp.
! 173: */
! 174: void
! 175: rasops8_makestamp(ri, attr)
! 176: struct rasops_info *ri;
! 177: long attr;
! 178: {
! 179: int32_t fg, bg;
! 180: int i;
! 181:
! 182: fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff;
! 183: bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff;
! 184: stamp_attr = attr;
! 185:
! 186: for (i = 0; i < 16; i++) {
! 187: #if BYTE_ORDER == LITTLE_ENDIAN
! 188: stamp[i] = (i & 8 ? fg : bg);
! 189: stamp[i] |= ((i & 4 ? fg : bg) << 8);
! 190: stamp[i] |= ((i & 2 ? fg : bg) << 16);
! 191: stamp[i] |= ((i & 1 ? fg : bg) << 24);
! 192: #else
! 193: stamp[i] = (i & 1 ? fg : bg);
! 194: stamp[i] |= ((i & 2 ? fg : bg) << 8);
! 195: stamp[i] |= ((i & 4 ? fg : bg) << 16);
! 196: stamp[i] |= ((i & 8 ? fg : bg) << 24);
! 197: #endif
! 198: #if NRASOPS_BSWAP > 0
! 199: if (ri->ri_flg & RI_BSWAP)
! 200: stamp[i] = swap32(stamp[i]);
! 201: #endif
! 202: }
! 203: }
! 204:
! 205: /*
! 206: * Put a single character. This is for 8-pixel wide fonts.
! 207: */
! 208: void
! 209: rasops8_putchar8(cookie, row, col, uc, attr)
! 210: void *cookie;
! 211: int row, col;
! 212: u_int uc;
! 213: long attr;
! 214: {
! 215: struct rasops_info *ri;
! 216: int height, fs;
! 217: int32_t *rp;
! 218: u_char *fr;
! 219:
! 220: /* Can't risk remaking the stamp if it's already in use */
! 221: if (stamp_mutex++) {
! 222: stamp_mutex--;
! 223: rasops8_putchar(cookie, row, col, uc, attr);
! 224: return;
! 225: }
! 226:
! 227: ri = (struct rasops_info *)cookie;
! 228:
! 229: #ifdef RASOPS_CLIPPING
! 230: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 231: stamp_mutex--;
! 232: return;
! 233: }
! 234:
! 235: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 236: stamp_mutex--;
! 237: return;
! 238: }
! 239: #endif
! 240:
! 241: /* Recompute stamp? */
! 242: if (attr != stamp_attr)
! 243: rasops8_makestamp(ri, attr);
! 244:
! 245: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 246: height = ri->ri_font->fontheight;
! 247:
! 248: if (uc == ' ') {
! 249: while (height--) {
! 250: rp[0] = rp[1] = stamp[0];
! 251: DELTA(rp, ri->ri_stride, int32_t *);
! 252: }
! 253: } else {
! 254: uc -= ri->ri_font->firstchar;
! 255: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
! 256: fs = ri->ri_font->stride;
! 257:
! 258: while (height--) {
! 259: rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
! 260: rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
! 261:
! 262: fr += fs;
! 263: DELTA(rp, ri->ri_stride, int32_t *);
! 264: }
! 265: }
! 266:
! 267: /* Do underline */
! 268: if ((attr & 1) != 0) {
! 269: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 270: rp[0] = rp[1] = stamp[15];
! 271: }
! 272:
! 273: stamp_mutex--;
! 274: }
! 275:
! 276: /*
! 277: * Put a single character. This is for 12-pixel wide fonts.
! 278: */
! 279: void
! 280: rasops8_putchar12(cookie, row, col, uc, attr)
! 281: void *cookie;
! 282: int row, col;
! 283: u_int uc;
! 284: long attr;
! 285: {
! 286: struct rasops_info *ri;
! 287: int height, fs;
! 288: int32_t *rp;
! 289: u_char *fr;
! 290:
! 291: /* Can't risk remaking the stamp if it's already in use */
! 292: if (stamp_mutex++) {
! 293: stamp_mutex--;
! 294: rasops8_putchar(cookie, row, col, uc, attr);
! 295: return;
! 296: }
! 297:
! 298: ri = (struct rasops_info *)cookie;
! 299:
! 300: #ifdef RASOPS_CLIPPING
! 301: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 302: stamp_mutex--;
! 303: return;
! 304: }
! 305:
! 306: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 307: stamp_mutex--;
! 308: return;
! 309: }
! 310: #endif
! 311:
! 312: /* Recompute stamp? */
! 313: if (attr != stamp_attr)
! 314: rasops8_makestamp(ri, attr);
! 315:
! 316: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 317: height = ri->ri_font->fontheight;
! 318:
! 319: if (uc == ' ') {
! 320: while (height--) {
! 321: int32_t c = stamp[0];
! 322:
! 323: rp[0] = rp[1] = rp[2] = c;
! 324: DELTA(rp, ri->ri_stride, int32_t *);
! 325: }
! 326: } else {
! 327: uc -= ri->ri_font->firstchar;
! 328: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
! 329: fs = ri->ri_font->stride;
! 330:
! 331: while (height--) {
! 332: rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
! 333: rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
! 334: rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
! 335:
! 336: fr += fs;
! 337: DELTA(rp, ri->ri_stride, int32_t *);
! 338: }
! 339: }
! 340:
! 341: /* Do underline */
! 342: if ((attr & 1) != 0) {
! 343: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 344: rp[0] = rp[1] = rp[2] = stamp[15];
! 345: }
! 346:
! 347: stamp_mutex--;
! 348: }
! 349:
! 350: /*
! 351: * Put a single character. This is for 16-pixel wide fonts.
! 352: */
! 353: void
! 354: rasops8_putchar16(cookie, row, col, uc, attr)
! 355: void *cookie;
! 356: int row, col;
! 357: u_int uc;
! 358: long attr;
! 359: {
! 360: struct rasops_info *ri;
! 361: int height, fs;
! 362: int32_t *rp;
! 363: u_char *fr;
! 364:
! 365: /* Can't risk remaking the stamp if it's already in use */
! 366: if (stamp_mutex++) {
! 367: stamp_mutex--;
! 368: rasops8_putchar(cookie, row, col, uc, attr);
! 369: return;
! 370: }
! 371:
! 372: ri = (struct rasops_info *)cookie;
! 373:
! 374: #ifdef RASOPS_CLIPPING
! 375: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 376: stamp_mutex--;
! 377: return;
! 378: }
! 379:
! 380: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 381: stamp_mutex--;
! 382: return;
! 383: }
! 384: #endif
! 385:
! 386: /* Recompute stamp? */
! 387: if (attr != stamp_attr)
! 388: rasops8_makestamp(ri, attr);
! 389:
! 390: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 391: height = ri->ri_font->fontheight;
! 392:
! 393: if (uc == ' ') {
! 394: while (height--)
! 395: rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
! 396: } else {
! 397: uc -= ri->ri_font->firstchar;
! 398: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
! 399: fs = ri->ri_font->stride;
! 400:
! 401: while (height--) {
! 402: rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
! 403: rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
! 404: rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
! 405: rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
! 406:
! 407: fr += fs;
! 408: DELTA(rp, ri->ri_stride, int32_t *);
! 409: }
! 410: }
! 411:
! 412: /* Do underline */
! 413: if ((attr & 1) != 0) {
! 414: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 415: rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
! 416: }
! 417:
! 418: stamp_mutex--;
! 419: }
! 420: #endif /* !RASOPS_SMALL */
CVSweb