Annotation of sys/dev/rasops/rasops15.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: rasops15.c,v 1.5 2006/01/08 17:18:05 miod Exp $ */
! 2: /* $NetBSD: rasops15.c,v 1.7 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 rasops15_putchar(void *, int, int, u_int, long attr);
! 49: #ifndef RASOPS_SMALL
! 50: void rasops15_putchar8(void *, int, int, u_int, long attr);
! 51: void rasops15_putchar12(void *, int, int, u_int, long attr);
! 52: void rasops15_putchar16(void *, int, int, u_int, long attr);
! 53: void rasops15_makestamp(struct rasops_info *, long);
! 54:
! 55: /*
! 56: * (2x2)x1 stamp for optimized character blitting
! 57: */
! 58: static int32_t stamp[32];
! 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 int32_t[0] = STAMP_READ(offset)
! 69: * destination int32_t[1] = STAMP_READ(offset + 4)
! 70: */
! 71: #define STAMP_SHIFT(fb,n) ((n*4-3) >= 0 ? (fb)>>(n*4-3):(fb)<<-(n*4-3))
! 72: #define STAMP_MASK (15 << 3)
! 73: #define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
! 74:
! 75: /*
! 76: * Initialize rasops_info struct for this colordepth.
! 77: */
! 78: void
! 79: rasops15_init(ri)
! 80: struct rasops_info *ri;
! 81: {
! 82:
! 83: switch (ri->ri_font->fontwidth) {
! 84: #ifndef RASOPS_SMALL
! 85: case 8:
! 86: ri->ri_ops.putchar = rasops15_putchar8;
! 87: break;
! 88:
! 89: case 12:
! 90: ri->ri_ops.putchar = rasops15_putchar12;
! 91: break;
! 92:
! 93: case 16:
! 94: ri->ri_ops.putchar = rasops15_putchar16;
! 95: break;
! 96: #endif /* !RASOPS_SMALL */
! 97: default:
! 98: ri->ri_ops.putchar = rasops15_putchar;
! 99: break;
! 100: }
! 101:
! 102: if (ri->ri_rnum == 0) {
! 103: ri->ri_rnum = 5;
! 104: ri->ri_rpos = 0;
! 105: ri->ri_gnum = 5 + (ri->ri_depth == 16);
! 106: ri->ri_gpos = 5;
! 107: ri->ri_bnum = 5;
! 108: ri->ri_bpos = 10 + (ri->ri_depth == 16);
! 109: }
! 110: }
! 111:
! 112: /*
! 113: * Paint a single character.
! 114: */
! 115: void
! 116: rasops15_putchar(cookie, row, col, uc, attr)
! 117: void *cookie;
! 118: int row, col;
! 119: u_int uc;
! 120: long attr;
! 121: {
! 122: int fb, width, height, cnt, clr[2];
! 123: struct rasops_info *ri;
! 124: u_char *dp, *rp, *fr;
! 125:
! 126: ri = (struct rasops_info *)cookie;
! 127:
! 128: #ifdef RASOPS_CLIPPING
! 129: /* Catches 'row < 0' case too */
! 130: if ((unsigned)row >= (unsigned)ri->ri_rows)
! 131: return;
! 132:
! 133: if ((unsigned)col >= (unsigned)ri->ri_cols)
! 134: return;
! 135: #endif
! 136:
! 137: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
! 138: height = ri->ri_font->fontheight;
! 139: width = ri->ri_font->fontwidth;
! 140:
! 141: clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
! 142: clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
! 143:
! 144: if (uc == ' ') {
! 145: int16_t c = (int16_t)clr[0];
! 146: while (height--) {
! 147: dp = rp;
! 148: rp += ri->ri_stride;
! 149:
! 150: for (cnt = width; cnt; cnt--) {
! 151: *(int16_t *)dp = c;
! 152: dp += 2;
! 153: }
! 154: }
! 155: } else {
! 156: uc -= ri->ri_font->firstchar;
! 157: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
! 158:
! 159: while (height--) {
! 160: dp = rp;
! 161: fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
! 162: fr += ri->ri_font->stride;
! 163: rp += ri->ri_stride;
! 164:
! 165: for (cnt = width; cnt; cnt--) {
! 166: *(int16_t *)dp = (int16_t)clr[(fb >> 31) & 1];
! 167: fb <<= 1;
! 168: dp += 2;
! 169: }
! 170: }
! 171: }
! 172:
! 173: /* Do underline */
! 174: if ((attr & 1) != 0) {
! 175: int16_t c = (int16_t)clr[1];
! 176: rp -= ri->ri_stride << 1;
! 177:
! 178: while (width--) {
! 179: *(int16_t *)rp = c;
! 180: rp += 2;
! 181: }
! 182: }
! 183: }
! 184:
! 185: #ifndef RASOPS_SMALL
! 186: /*
! 187: * Recompute the (2x2)x1 blitting stamp.
! 188: */
! 189: void
! 190: rasops15_makestamp(ri, attr)
! 191: struct rasops_info *ri;
! 192: long attr;
! 193: {
! 194: int32_t fg, bg;
! 195: int i;
! 196:
! 197: fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffff;
! 198: bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffff;
! 199: stamp_attr = attr;
! 200:
! 201: for (i = 0; i < 32; i += 2) {
! 202: #if BYTE_ORDER == LITTLE_ENDIAN
! 203: stamp[i] = (i & 16 ? fg : bg);
! 204: stamp[i] |= ((i & 8 ? fg : bg) << 16);
! 205: stamp[i + 1] = (i & 4 ? fg : bg);
! 206: stamp[i + 1] |= ((i & 2 ? fg : bg) << 16);
! 207: #else
! 208: stamp[i + 1] = (i & 2 ? fg : bg);
! 209: stamp[i + 1] |= ((i & 4 ? fg : bg) << 16);
! 210: stamp[i] = (i & 8 ? fg : bg);
! 211: stamp[i] |= ((i & 16 ? fg : bg) << 16);
! 212: #endif
! 213: }
! 214: }
! 215:
! 216: /*
! 217: * Paint a single character. This is for 8-pixel wide fonts.
! 218: */
! 219: void
! 220: rasops15_putchar8(cookie, row, col, uc, attr)
! 221: void *cookie;
! 222: int row, col;
! 223: u_int uc;
! 224: long attr;
! 225: {
! 226: struct rasops_info *ri;
! 227: int height, so, fs;
! 228: int32_t *rp;
! 229: u_char *fr;
! 230:
! 231: /* Can't risk remaking the stamp if it's already in use */
! 232: if (stamp_mutex++) {
! 233: stamp_mutex--;
! 234: rasops15_putchar(cookie, row, col, uc, attr);
! 235: return;
! 236: }
! 237:
! 238: ri = (struct rasops_info *)cookie;
! 239:
! 240: #ifdef RASOPS_CLIPPING
! 241: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 242: stamp_mutex--;
! 243: return;
! 244: }
! 245:
! 246: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 247: stamp_mutex--;
! 248: return;
! 249: }
! 250: #endif
! 251:
! 252: /* Recompute stamp? */
! 253: if (attr != stamp_attr)
! 254: rasops15_makestamp(ri, attr);
! 255:
! 256: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 257: height = ri->ri_font->fontheight;
! 258:
! 259: if (uc == (u_int)-1) {
! 260: int32_t c = stamp[0];
! 261: while (height--) {
! 262: rp[0] = rp[1] = rp[2] = rp[3] = c;
! 263: DELTA(rp, ri->ri_stride, int32_t *);
! 264: }
! 265: } else {
! 266: uc -= ri->ri_font->firstchar;
! 267: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
! 268: fs = ri->ri_font->stride;
! 269:
! 270: while (height--) {
! 271: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
! 272: rp[0] = STAMP_READ(so);
! 273: rp[1] = STAMP_READ(so + 4);
! 274:
! 275: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
! 276: rp[2] = STAMP_READ(so);
! 277: rp[3] = STAMP_READ(so + 4);
! 278:
! 279: fr += fs;
! 280: DELTA(rp, ri->ri_stride, int32_t *);
! 281: }
! 282: }
! 283:
! 284: /* Do underline */
! 285: if ((attr & 1) != 0) {
! 286: int32_t c = STAMP_READ(28);
! 287:
! 288: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 289: rp[0] = rp[1] = rp[2] = rp[3] = c;
! 290: }
! 291:
! 292: stamp_mutex--;
! 293: }
! 294:
! 295: /*
! 296: * Paint a single character. This is for 12-pixel wide fonts.
! 297: */
! 298: void
! 299: rasops15_putchar12(cookie, row, col, uc, attr)
! 300: void *cookie;
! 301: int row, col;
! 302: u_int uc;
! 303: long attr;
! 304: {
! 305: struct rasops_info *ri;
! 306: int height, so, fs;
! 307: int32_t *rp;
! 308: u_char *fr;
! 309:
! 310: /* Can't risk remaking the stamp if it's already in use */
! 311: if (stamp_mutex++) {
! 312: stamp_mutex--;
! 313: rasops15_putchar(cookie, row, col, uc, attr);
! 314: return;
! 315: }
! 316:
! 317: ri = (struct rasops_info *)cookie;
! 318:
! 319: #ifdef RASOPS_CLIPPING
! 320: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 321: stamp_mutex--;
! 322: return;
! 323: }
! 324:
! 325: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 326: stamp_mutex--;
! 327: return;
! 328: }
! 329: #endif
! 330:
! 331: /* Recompute stamp? */
! 332: if (attr != stamp_attr)
! 333: rasops15_makestamp(ri, attr);
! 334:
! 335: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 336: height = ri->ri_font->fontheight;
! 337:
! 338: if (uc == (u_int)-1) {
! 339: int32_t c = stamp[0];
! 340: while (height--) {
! 341: rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
! 342: DELTA(rp, ri->ri_stride, int32_t *);
! 343: }
! 344: } else {
! 345: uc -= ri->ri_font->firstchar;
! 346: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
! 347: fs = ri->ri_font->stride;
! 348:
! 349: while (height--) {
! 350: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
! 351: rp[0] = STAMP_READ(so);
! 352: rp[1] = STAMP_READ(so + 4);
! 353:
! 354: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
! 355: rp[2] = STAMP_READ(so);
! 356: rp[3] = STAMP_READ(so + 4);
! 357:
! 358: so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
! 359: rp[4] = STAMP_READ(so);
! 360: rp[5] = STAMP_READ(so + 4);
! 361:
! 362: fr += fs;
! 363: DELTA(rp, ri->ri_stride, int32_t *);
! 364: }
! 365: }
! 366:
! 367: /* Do underline */
! 368: if (attr & 1) {
! 369: int32_t c = STAMP_READ(28);
! 370:
! 371: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 372: rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
! 373: }
! 374:
! 375: stamp_mutex--;
! 376: }
! 377:
! 378: /*
! 379: * Paint a single character. This is for 16-pixel wide fonts.
! 380: */
! 381: void
! 382: rasops15_putchar16(cookie, row, col, uc, attr)
! 383: void *cookie;
! 384: int row, col;
! 385: u_int uc;
! 386: long attr;
! 387: {
! 388: struct rasops_info *ri;
! 389: int height, so, fs;
! 390: int32_t *rp;
! 391: u_char *fr;
! 392:
! 393: /* Can't risk remaking the stamp if it's already in use */
! 394: if (stamp_mutex++) {
! 395: stamp_mutex--;
! 396: rasops15_putchar(cookie, row, col, uc, attr);
! 397: return;
! 398: }
! 399:
! 400: ri = (struct rasops_info *)cookie;
! 401:
! 402: #ifdef RASOPS_CLIPPING
! 403: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 404: stamp_mutex--;
! 405: return;
! 406: }
! 407:
! 408: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 409: stamp_mutex--;
! 410: return;
! 411: }
! 412: #endif
! 413:
! 414: /* Recompute stamp? */
! 415: if (attr != stamp_attr)
! 416: rasops15_makestamp(ri, attr);
! 417:
! 418: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 419: height = ri->ri_font->fontheight;
! 420:
! 421: if (uc == (u_int)-1) {
! 422: int32_t c = stamp[0];
! 423: while (height--) {
! 424: rp[0] = rp[1] = rp[2] = rp[3] =
! 425: rp[4] = rp[5] = rp[6] = rp[7] = c;
! 426: DELTA(rp, ri->ri_stride, int32_t *);
! 427: }
! 428: } else {
! 429: uc -= ri->ri_font->firstchar;
! 430: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
! 431: fs = ri->ri_font->stride;
! 432:
! 433: while (height--) {
! 434: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
! 435: rp[0] = STAMP_READ(so);
! 436: rp[1] = STAMP_READ(so + 4);
! 437:
! 438: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
! 439: rp[2] = STAMP_READ(so);
! 440: rp[3] = STAMP_READ(so + 4);
! 441:
! 442: so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
! 443: rp[4] = STAMP_READ(so);
! 444: rp[5] = STAMP_READ(so + 4);
! 445:
! 446: so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
! 447: rp[6] = STAMP_READ(so);
! 448: rp[7] = STAMP_READ(so + 4);
! 449:
! 450: DELTA(rp, ri->ri_stride, int32_t *);
! 451: fr += fs;
! 452: }
! 453: }
! 454:
! 455: /* Do underline */
! 456: if (attr & 1) {
! 457: int32_t c = STAMP_READ(28);
! 458:
! 459: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 460: rp[0] = rp[1] = rp[2] = rp[3] =
! 461: rp[4] = rp[5] = rp[6] = rp[7] = c;
! 462: }
! 463:
! 464: stamp_mutex--;
! 465: }
! 466: #endif /* !RASOPS_SMALL */
CVSweb