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