Annotation of sys/dev/rasops/rasops24.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: rasops24.c,v 1.5 2002/07/27 22:17:49 miod Exp $ */
! 2: /* $NetBSD: rasops24.c,v 1.12 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 <machine/endian.h>
! 45:
! 46: #include <dev/wscons/wsdisplayvar.h>
! 47: #include <dev/wscons/wsconsio.h>
! 48: #include <dev/rasops/rasops.h>
! 49:
! 50: void rasops24_erasecols(void *, int, int, int, long);
! 51: void rasops24_eraserows(void *, int, int, long);
! 52: void rasops24_putchar(void *, int, int, u_int, long attr);
! 53: #ifndef RASOPS_SMALL
! 54: void rasops24_putchar8(void *, int, int, u_int, long attr);
! 55: void rasops24_putchar12(void *, int, int, u_int, long attr);
! 56: void rasops24_putchar16(void *, int, int, u_int, long attr);
! 57: void rasops24_makestamp(struct rasops_info *, long);
! 58:
! 59: /*
! 60: * 4x1 stamp for optimized character blitting
! 61: */
! 62: static int32_t stamp[64];
! 63: static long stamp_attr;
! 64: static int stamp_mutex; /* XXX see note in readme */
! 65: #endif
! 66:
! 67: /*
! 68: * XXX this confuses the hell out of gcc2 (not egcs) which always insists
! 69: * that the shift count is negative.
! 70: *
! 71: * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
! 72: * destination int32_t[0] = STAMP_READ(offset)
! 73: * destination int32_t[1] = STAMP_READ(offset + 4)
! 74: * destination int32_t[2] = STAMP_READ(offset + 8)
! 75: */
! 76: #define STAMP_SHIFT(fb,n) ((n*4-4) >= 0 ? (fb)>>(n*4-4):(fb)<<-(n*4-4))
! 77: #define STAMP_MASK (0xf << 4)
! 78: #define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
! 79:
! 80: /*
! 81: * Initialize rasops_info struct for this colordepth.
! 82: */
! 83: void
! 84: rasops24_init(ri)
! 85: struct rasops_info *ri;
! 86: {
! 87:
! 88: switch (ri->ri_font->fontwidth) {
! 89: #ifndef RASOPS_SMALL
! 90: case 8:
! 91: ri->ri_ops.putchar = rasops24_putchar8;
! 92: break;
! 93: case 12:
! 94: ri->ri_ops.putchar = rasops24_putchar12;
! 95: break;
! 96: case 16:
! 97: ri->ri_ops.putchar = rasops24_putchar16;
! 98: break;
! 99: #endif
! 100: default:
! 101: ri->ri_ops.putchar = rasops24_putchar;
! 102: break;
! 103: }
! 104:
! 105: if (ri->ri_rnum == 0) {
! 106: ri->ri_rnum = 8;
! 107: ri->ri_rpos = 0;
! 108: ri->ri_gnum = 8;
! 109: ri->ri_gpos = 8;
! 110: ri->ri_bnum = 8;
! 111: ri->ri_bpos = 16;
! 112: }
! 113:
! 114: ri->ri_ops.erasecols = rasops24_erasecols;
! 115: ri->ri_ops.eraserows = rasops24_eraserows;
! 116: }
! 117:
! 118: /*
! 119: * Put a single character. This is the generic version.
! 120: * XXX this bites - we should use masks.
! 121: */
! 122: void
! 123: rasops24_putchar(cookie, row, col, uc, attr)
! 124: void *cookie;
! 125: int row, col;
! 126: u_int uc;
! 127: long attr;
! 128: {
! 129: int fb, width, height, cnt, clr[2];
! 130: struct rasops_info *ri;
! 131: u_char *dp, *rp, *fr;
! 132:
! 133: ri = (struct rasops_info *)cookie;
! 134:
! 135: #ifdef RASOPS_CLIPPING
! 136: /* Catches 'row < 0' case too */
! 137: if ((unsigned)row >= (unsigned)ri->ri_rows)
! 138: return;
! 139:
! 140: if ((unsigned)col >= (unsigned)ri->ri_cols)
! 141: return;
! 142: #endif
! 143:
! 144: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
! 145: height = ri->ri_font->fontheight;
! 146: width = ri->ri_font->fontwidth;
! 147:
! 148: clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
! 149: clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
! 150:
! 151: if (uc == ' ') {
! 152: u_char c = clr[0];
! 153: while (height--) {
! 154: dp = rp;
! 155: rp += ri->ri_stride;
! 156:
! 157: for (cnt = width; cnt; cnt--) {
! 158: *dp++ = c >> 16;
! 159: *dp++ = c >> 8;
! 160: *dp++ = c;
! 161: }
! 162: }
! 163: } else {
! 164: uc -= ri->ri_font->firstchar;
! 165: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
! 166:
! 167: while (height--) {
! 168: dp = rp;
! 169: fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
! 170: (fr[0] << 24);
! 171: fr += ri->ri_font->stride;
! 172: rp += ri->ri_stride;
! 173:
! 174: for (cnt = width; cnt; cnt--, fb <<= 1) {
! 175: if ((fb >> 31) & 1) {
! 176: *dp++ = clr[1] >> 16;
! 177: *dp++ = clr[1] >> 8;
! 178: *dp++ = clr[1];
! 179: } else {
! 180: *dp++ = clr[0] >> 16;
! 181: *dp++ = clr[0] >> 8;
! 182: *dp++ = clr[0];
! 183: }
! 184: }
! 185: }
! 186: }
! 187:
! 188: /* Do underline */
! 189: if ((attr & 1) != 0) {
! 190: u_char c = clr[1];
! 191:
! 192: rp -= ri->ri_stride << 1;
! 193:
! 194: while (width--) {
! 195: *rp++ = c >> 16;
! 196: *rp++ = c >> 8;
! 197: *rp++ = c;
! 198: }
! 199: }
! 200: }
! 201:
! 202: #ifndef RASOPS_SMALL
! 203: /*
! 204: * Recompute the blitting stamp.
! 205: */
! 206: void
! 207: rasops24_makestamp(ri, attr)
! 208: struct rasops_info *ri;
! 209: long attr;
! 210: {
! 211: u_int fg, bg, c1, c2, c3, c4;
! 212: int i;
! 213:
! 214: fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff;
! 215: bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff;
! 216: stamp_attr = attr;
! 217:
! 218: for (i = 0; i < 64; i += 4) {
! 219: #if BYTE_ORDER == LITTLE_ENDIAN
! 220: c1 = (i & 32 ? fg : bg);
! 221: c2 = (i & 16 ? fg : bg);
! 222: c3 = (i & 8 ? fg : bg);
! 223: c4 = (i & 4 ? fg : bg);
! 224: #else
! 225: c1 = (i & 8 ? fg : bg);
! 226: c2 = (i & 4 ? fg : bg);
! 227: c3 = (i & 16 ? fg : bg);
! 228: c4 = (i & 32 ? fg : bg);
! 229: #endif
! 230: stamp[i+0] = (c1 << 8) | (c2 >> 16);
! 231: stamp[i+1] = (c2 << 16) | (c3 >> 8);
! 232: stamp[i+2] = (c3 << 24) | c4;
! 233:
! 234: #if BYTE_ORDER == LITTLE_ENDIAN
! 235: if ((ri->ri_flg & RI_BSWAP) == 0) {
! 236: #else
! 237: if ((ri->ri_flg & RI_BSWAP) != 0) {
! 238: #endif
! 239: stamp[i+0] = swap32(stamp[i+0]);
! 240: stamp[i+1] = swap32(stamp[i+1]);
! 241: stamp[i+2] = swap32(stamp[i+2]);
! 242: }
! 243: }
! 244: }
! 245:
! 246: /*
! 247: * Put a single character. This is for 8-pixel wide fonts.
! 248: */
! 249: void
! 250: rasops24_putchar8(cookie, row, col, uc, attr)
! 251: void *cookie;
! 252: int row, col;
! 253: u_int uc;
! 254: long attr;
! 255: {
! 256: struct rasops_info *ri;
! 257: int height, so, fs;
! 258: int32_t *rp;
! 259: u_char *fr;
! 260:
! 261: /* Can't risk remaking the stamp if it's already in use */
! 262: if (stamp_mutex++) {
! 263: stamp_mutex--;
! 264: rasops24_putchar(cookie, row, col, uc, attr);
! 265: return;
! 266: }
! 267:
! 268: ri = (struct rasops_info *)cookie;
! 269:
! 270: #ifdef RASOPS_CLIPPING
! 271: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 272: stamp_mutex--;
! 273: return;
! 274: }
! 275:
! 276: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 277: stamp_mutex--;
! 278: return;
! 279: }
! 280: #endif
! 281:
! 282: /* Recompute stamp? */
! 283: if (attr != stamp_attr)
! 284: rasops24_makestamp(ri, attr);
! 285:
! 286: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 287: height = ri->ri_font->fontheight;
! 288:
! 289: if (uc == (u_int)-1) {
! 290: int32_t c = stamp[0];
! 291: while (height--) {
! 292: rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
! 293: DELTA(rp, ri->ri_stride, int32_t *);
! 294: }
! 295: } else {
! 296: uc -= ri->ri_font->firstchar;
! 297: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
! 298: fs = ri->ri_font->stride;
! 299:
! 300: while (height--) {
! 301: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
! 302: rp[0] = STAMP_READ(so);
! 303: rp[1] = STAMP_READ(so + 4);
! 304: rp[2] = STAMP_READ(so + 8);
! 305:
! 306: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
! 307: rp[3] = STAMP_READ(so);
! 308: rp[4] = STAMP_READ(so + 4);
! 309: rp[5] = STAMP_READ(so + 8);
! 310:
! 311: fr += fs;
! 312: DELTA(rp, ri->ri_stride, int32_t *);
! 313: }
! 314: }
! 315:
! 316: /* Do underline */
! 317: if ((attr & 1) != 0) {
! 318: int32_t c = STAMP_READ(52);
! 319:
! 320: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 321: rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
! 322: }
! 323:
! 324: stamp_mutex--;
! 325: }
! 326:
! 327: /*
! 328: * Put a single character. This is for 12-pixel wide fonts.
! 329: */
! 330: void
! 331: rasops24_putchar12(cookie, row, col, uc, attr)
! 332: void *cookie;
! 333: int row, col;
! 334: u_int uc;
! 335: long attr;
! 336: {
! 337: struct rasops_info *ri;
! 338: int height, so, fs;
! 339: int32_t *rp;
! 340: u_char *fr;
! 341:
! 342: /* Can't risk remaking the stamp if it's already in use */
! 343: if (stamp_mutex++) {
! 344: stamp_mutex--;
! 345: rasops24_putchar(cookie, row, col, uc, attr);
! 346: return;
! 347: }
! 348:
! 349: ri = (struct rasops_info *)cookie;
! 350:
! 351: #ifdef RASOPS_CLIPPING
! 352: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 353: stamp_mutex--;
! 354: return;
! 355: }
! 356:
! 357: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 358: stamp_mutex--;
! 359: return;
! 360: }
! 361: #endif
! 362:
! 363: /* Recompute stamp? */
! 364: if (attr != stamp_attr)
! 365: rasops24_makestamp(ri, attr);
! 366:
! 367: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 368: height = ri->ri_font->fontheight;
! 369:
! 370: if (uc == (u_int)-1) {
! 371: int32_t c = stamp[0];
! 372: while (height--) {
! 373: rp[0] = rp[1] = rp[2] = rp[3] =
! 374: rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
! 375: DELTA(rp, ri->ri_stride, int32_t *);
! 376: }
! 377: } else {
! 378: uc -= ri->ri_font->firstchar;
! 379: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
! 380: fs = ri->ri_font->stride;
! 381:
! 382: while (height--) {
! 383: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
! 384: rp[0] = STAMP_READ(so);
! 385: rp[1] = STAMP_READ(so + 4);
! 386: rp[2] = STAMP_READ(so + 8);
! 387:
! 388: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
! 389: rp[3] = STAMP_READ(so);
! 390: rp[4] = STAMP_READ(so + 4);
! 391: rp[5] = STAMP_READ(so + 8);
! 392:
! 393: so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
! 394: rp[6] = STAMP_READ(so);
! 395: rp[7] = STAMP_READ(so + 4);
! 396: rp[8] = STAMP_READ(so + 8);
! 397:
! 398: fr += fs;
! 399: DELTA(rp, ri->ri_stride, int32_t *);
! 400: }
! 401: }
! 402:
! 403: /* Do underline */
! 404: if ((attr & 1) != 0) {
! 405: int32_t c = STAMP_READ(52);
! 406:
! 407: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 408: rp[0] = rp[1] = rp[2] = rp[3] =
! 409: rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
! 410: }
! 411:
! 412: stamp_mutex--;
! 413: }
! 414:
! 415: /*
! 416: * Put a single character. This is for 16-pixel wide fonts.
! 417: */
! 418: void
! 419: rasops24_putchar16(cookie, row, col, uc, attr)
! 420: void *cookie;
! 421: int row, col;
! 422: u_int uc;
! 423: long attr;
! 424: {
! 425: struct rasops_info *ri;
! 426: int height, so, fs;
! 427: int32_t *rp;
! 428: u_char *fr;
! 429:
! 430: /* Can't risk remaking the stamp if it's already in use */
! 431: if (stamp_mutex++) {
! 432: stamp_mutex--;
! 433: rasops24_putchar(cookie, row, col, uc, attr);
! 434: return;
! 435: }
! 436:
! 437: ri = (struct rasops_info *)cookie;
! 438:
! 439: #ifdef RASOPS_CLIPPING
! 440: if ((unsigned)row >= (unsigned)ri->ri_rows) {
! 441: stamp_mutex--;
! 442: return;
! 443: }
! 444:
! 445: if ((unsigned)col >= (unsigned)ri->ri_cols) {
! 446: stamp_mutex--;
! 447: return;
! 448: }
! 449: #endif
! 450:
! 451: /* Recompute stamp? */
! 452: if (attr != stamp_attr)
! 453: rasops24_makestamp(ri, attr);
! 454:
! 455: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 456: height = ri->ri_font->fontheight;
! 457:
! 458: if (uc == (u_int)-1) {
! 459: int32_t c = stamp[0];
! 460: while (height--) {
! 461: rp[0] = rp[1] = rp[2] = rp[3] =
! 462: rp[4] = rp[5] = rp[6] = rp[7] =
! 463: rp[8] = rp[9] = rp[10] = rp[11] = c;
! 464: DELTA(rp, ri->ri_stride, int32_t *);
! 465: }
! 466: } else {
! 467: uc -= ri->ri_font->firstchar;
! 468: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
! 469: fs = ri->ri_font->stride;
! 470:
! 471: while (height--) {
! 472: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
! 473: rp[0] = STAMP_READ(so);
! 474: rp[1] = STAMP_READ(so + 4);
! 475: rp[2] = STAMP_READ(so + 8);
! 476:
! 477: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
! 478: rp[3] = STAMP_READ(so);
! 479: rp[4] = STAMP_READ(so + 4);
! 480: rp[5] = STAMP_READ(so + 8);
! 481:
! 482: so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
! 483: rp[6] = STAMP_READ(so);
! 484: rp[7] = STAMP_READ(so + 4);
! 485: rp[8] = STAMP_READ(so + 8);
! 486:
! 487: so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
! 488: rp[9] = STAMP_READ(so);
! 489: rp[10] = STAMP_READ(so + 4);
! 490: rp[11] = STAMP_READ(so + 8);
! 491:
! 492: DELTA(rp, ri->ri_stride, int32_t *);
! 493: fr += fs;
! 494: }
! 495: }
! 496:
! 497: /* Do underline */
! 498: if ((attr & 1) != 0) {
! 499: int32_t c = STAMP_READ(52);
! 500:
! 501: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
! 502: rp[0] = rp[1] = rp[2] = rp[3] =
! 503: rp[4] = rp[5] = rp[6] = rp[7] =
! 504: rp[8] = rp[9] = rp[10] = rp[11] = c;
! 505: }
! 506:
! 507: stamp_mutex--;
! 508: }
! 509: #endif /* !RASOPS_SMALL */
! 510:
! 511: /*
! 512: * Erase rows. This is nice and easy due to alignment.
! 513: */
! 514: void
! 515: rasops24_eraserows(cookie, row, num, attr)
! 516: void *cookie;
! 517: int row, num;
! 518: long attr;
! 519: {
! 520: int n9, n3, n1, cnt, stride, delta;
! 521: u_int32_t *dp, clr, stamp[3];
! 522: struct rasops_info *ri;
! 523:
! 524: /*
! 525: * If the color is gray, we can cheat and use the generic routines
! 526: * (which are faster, hopefully) since the r,g,b values are the same.
! 527: */
! 528: if ((attr & 4) != 0) {
! 529: rasops_eraserows(cookie, row, num, attr);
! 530: return;
! 531: }
! 532:
! 533: ri = (struct rasops_info *)cookie;
! 534:
! 535: #ifdef RASOPS_CLIPPING
! 536: if (row < 0) {
! 537: num += row;
! 538: row = 0;
! 539: }
! 540:
! 541: if ((row + num) > ri->ri_rows)
! 542: num = ri->ri_rows - row;
! 543:
! 544: if (num <= 0)
! 545: return;
! 546: #endif
! 547:
! 548: clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
! 549: stamp[0] = (clr << 8) | (clr >> 16);
! 550: stamp[1] = (clr << 16) | (clr >> 8);
! 551: stamp[2] = (clr << 24) | clr;
! 552:
! 553: #if BYTE_ORDER == LITTLE_ENDIAN
! 554: if ((ri->ri_flg & RI_BSWAP) == 0) {
! 555: #else
! 556: if ((ri->ri_flg & RI_BSWAP) != 0) {
! 557: #endif
! 558: stamp[0] = swap32(stamp[0]);
! 559: stamp[1] = swap32(stamp[1]);
! 560: stamp[2] = swap32(stamp[2]);
! 561: }
! 562:
! 563: /*
! 564: * XXX the wsdisplay_emulops interface seems a little deficient in
! 565: * that there is no way to clear the *entire* screen. We provide a
! 566: * workaround here: if the entire console area is being cleared, and
! 567: * the RI_FULLCLEAR flag is set, clear the entire display.
! 568: */
! 569: if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
! 570: stride = ri->ri_stride;
! 571: num = ri->ri_height;
! 572: dp = (int32_t *)ri->ri_origbits;
! 573: delta = 0;
! 574: } else {
! 575: stride = ri->ri_emustride;
! 576: num *= ri->ri_font->fontheight;
! 577: dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
! 578: delta = ri->ri_delta;
! 579: }
! 580:
! 581: n9 = stride / 36;
! 582: cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
! 583: n3 = (stride - cnt) / 12;
! 584: cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
! 585: n1 = (stride - cnt) >> 2;
! 586:
! 587: while (num--) {
! 588: for (cnt = n9; cnt; cnt--) {
! 589: dp[0] = stamp[0];
! 590: dp[1] = stamp[1];
! 591: dp[2] = stamp[2];
! 592: dp[3] = stamp[0];
! 593: dp[4] = stamp[1];
! 594: dp[5] = stamp[2];
! 595: dp[6] = stamp[0];
! 596: dp[7] = stamp[1];
! 597: dp[8] = stamp[2];
! 598: dp += 9;
! 599: }
! 600:
! 601: for (cnt = n3; cnt; cnt--) {
! 602: dp[0] = stamp[0];
! 603: dp[1] = stamp[1];
! 604: dp[2] = stamp[2];
! 605: dp += 3;
! 606: }
! 607:
! 608: for (cnt = 0; cnt < n1; cnt++)
! 609: *dp++ = stamp[cnt];
! 610:
! 611: DELTA(dp, delta, int32_t *);
! 612: }
! 613: }
! 614:
! 615: /*
! 616: * Erase columns.
! 617: */
! 618: void
! 619: rasops24_erasecols(cookie, row, col, num, attr)
! 620: void *cookie;
! 621: int row, col, num;
! 622: long attr;
! 623: {
! 624: int n12, n4, height, cnt, slop, clr, stamp[3];
! 625: struct rasops_info *ri;
! 626: int32_t *dp, *rp;
! 627: u_char *dbp;
! 628:
! 629: /*
! 630: * If the color is gray, we can cheat and use the generic routines
! 631: * (which are faster, hopefully) since the r,g,b values are the same.
! 632: */
! 633: if ((attr & 4) != 0) {
! 634: rasops_erasecols(cookie, row, col, num, attr);
! 635: return;
! 636: }
! 637:
! 638: ri = (struct rasops_info *)cookie;
! 639:
! 640: #ifdef RASOPS_CLIPPING
! 641: /* Catches 'row < 0' case too */
! 642: if ((unsigned)row >= (unsigned)ri->ri_rows)
! 643: return;
! 644:
! 645: if (col < 0) {
! 646: num += col;
! 647: col = 0;
! 648: }
! 649:
! 650: if ((col + num) > ri->ri_cols)
! 651: num = ri->ri_cols - col;
! 652:
! 653: if (num <= 0)
! 654: return;
! 655: #endif
! 656:
! 657: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
! 658: num *= ri->ri_font->fontwidth;
! 659: height = ri->ri_font->fontheight;
! 660:
! 661: clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
! 662: stamp[0] = (clr << 8) | (clr >> 16);
! 663: stamp[1] = (clr << 16) | (clr >> 8);
! 664: stamp[2] = (clr << 24) | clr;
! 665:
! 666: #if BYTE_ORDER == LITTLE_ENDIAN
! 667: if ((ri->ri_flg & RI_BSWAP) == 0) {
! 668: #else
! 669: if ((ri->ri_flg & RI_BSWAP) != 0) {
! 670: #endif
! 671: stamp[0] = swap32(stamp[0]);
! 672: stamp[1] = swap32(stamp[1]);
! 673: stamp[2] = swap32(stamp[2]);
! 674: }
! 675:
! 676: /*
! 677: * The current byte offset mod 4 tells us the number of 24-bit pels
! 678: * we need to write for alignment to 32-bits. Once we're aligned on
! 679: * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so
! 680: * the stamp does not need to be rotated. The following shows the
! 681: * layout of 4 pels in a 3 word region and illustrates this:
! 682: *
! 683: * aaab bbcc cddd
! 684: */
! 685: slop = (long)rp & 3; num -= slop;
! 686: n12 = num / 12; num -= (n12 << 3) + (n12 << 2);
! 687: n4 = num >> 2; num &= 3;
! 688:
! 689: while (height--) {
! 690: dbp = (u_char *)rp;
! 691: DELTA(rp, ri->ri_stride, int32_t *);
! 692:
! 693: /* Align to 4 bytes */
! 694: /* XXX handle with masks, bring under control of RI_BSWAP */
! 695: for (cnt = slop; cnt; cnt--) {
! 696: *dbp++ = (clr >> 16);
! 697: *dbp++ = (clr >> 8);
! 698: *dbp++ = clr;
! 699: }
! 700:
! 701: dp = (int32_t *)dbp;
! 702:
! 703: /* 12 pels per loop */
! 704: for (cnt = n12; cnt; cnt--) {
! 705: dp[0] = stamp[0];
! 706: dp[1] = stamp[1];
! 707: dp[2] = stamp[2];
! 708: dp[3] = stamp[0];
! 709: dp[4] = stamp[1];
! 710: dp[5] = stamp[2];
! 711: dp[6] = stamp[0];
! 712: dp[7] = stamp[1];
! 713: dp[8] = stamp[2];
! 714: dp += 9;
! 715: }
! 716:
! 717: /* 4 pels per loop */
! 718: for (cnt = n4; cnt; cnt--) {
! 719: dp[0] = stamp[0];
! 720: dp[1] = stamp[1];
! 721: dp[2] = stamp[2];
! 722: dp += 3;
! 723: }
! 724:
! 725: /* Trailing slop */
! 726: /* XXX handle with masks, bring under control of RI_BSWAP */
! 727: dbp = (u_char *)dp;
! 728: for (cnt = num; cnt; cnt--) {
! 729: *dbp++ = (clr >> 16);
! 730: *dbp++ = (clr >> 8);
! 731: *dbp++ = clr;
! 732: }
! 733: }
! 734: }
CVSweb