Home | History | Annotate | Line # | Download | only in rasops
rasops15.c revision 1.5
      1 /* 	$NetBSD: rasops15.c,v 1.5 1999/10/23 23:14:13 ad 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 Andy 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  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the NetBSD
     21  *	Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include "opt_rasops.h"
     40 #include <sys/cdefs.h>
     41 __KERNEL_RCSID(0, "$NetBSD: rasops15.c,v 1.5 1999/10/23 23:14:13 ad Exp $");
     42 
     43 #include <sys/types.h>
     44 #include <sys/param.h>
     45 #include <sys/systm.h>
     46 #include <sys/time.h>
     47 
     48 #include <dev/wscons/wsdisplayvar.h>
     49 #include <dev/wscons/wsconsio.h>
     50 #include <dev/rasops/rasops.h>
     51 
     52 static void 	rasops15_putchar __P((void *, int, int, u_int, long attr));
     53 #ifndef RASOPS_SMALL
     54 static void 	rasops15_putchar8 __P((void *, int, int, u_int, long attr));
     55 static void 	rasops15_putchar12 __P((void *, int, int, u_int, long attr));
     56 static void 	rasops15_putchar16 __P((void *, int, int, u_int, long attr));
     57 static void	rasops15_makestamp __P((struct rasops_info *, long));
     58 #endif
     59 
     60 /*
     61  * (2x2)x1 stamp for optimized character blitting
     62  */
     63 static int32_t	stamp[32];
     64 static long	stamp_attr;
     65 static int	stamp_mutex;	/* XXX see note in readme */
     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  */
     75 #define STAMP_SHIFT(fb,n)	((n*4-3) >= 0 ? (fb)>>(n*4-3):(fb)<<-(n*4-3))
     76 #define STAMP_MASK		(15 << 3)
     77 #define STAMP_READ(o)		(*(int32_t *)((caddr_t)stamp + (o)))
     78 
     79 /*
     80  * Initalize rasops_info struct for this colordepth.
     81  */
     82 void
     83 rasops15_init(ri)
     84 	struct rasops_info *ri;
     85 {
     86 
     87 	switch (ri->ri_font->fontwidth) {
     88 #ifndef RASOPS_SMALL
     89 	case 8:
     90 		ri->ri_ops.putchar = rasops15_putchar8;
     91 		break;
     92 
     93 	case 12:
     94 		ri->ri_ops.putchar = rasops15_putchar12;
     95 		break;
     96 
     97 	case 16:
     98 		ri->ri_ops.putchar = rasops15_putchar16;
     99 		break;
    100 #endif	/* !RASOPS_SMALL */
    101 	default:
    102 		ri->ri_ops.putchar = rasops15_putchar;
    103 		break;
    104 	}
    105 
    106 	if (ri->ri_rnum == 0) {
    107 		ri->ri_rnum = 5;
    108 		ri->ri_rpos = 0;
    109 		ri->ri_gnum = 5 + (ri->ri_depth == 16);
    110 		ri->ri_gpos = 5;
    111 		ri->ri_bnum = 5;
    112 		ri->ri_bpos = 10 + (ri->ri_depth == 16);
    113 	}
    114 }
    115 
    116 /*
    117  * Paint a single character.
    118  */
    119 static void
    120 rasops15_putchar(cookie, row, col, uc, attr)
    121 	void *cookie;
    122 	int row, col;
    123 	u_int uc;
    124 	long attr;
    125 {
    126 	int fb, width, height, cnt, clr[2];
    127 	struct rasops_info *ri;
    128 	u_char *dp, *rp, *fr;
    129 
    130 	ri = (struct rasops_info *)cookie;
    131 
    132 #ifdef RASOPS_CLIPPING
    133 	/* Catches 'row < 0' case too */
    134 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    135 		return;
    136 
    137 	if ((unsigned)col >= (unsigned)ri->ri_cols)
    138 		return;
    139 #endif
    140 
    141 	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
    142 	height = ri->ri_font->fontheight;
    143 	width = ri->ri_font->fontwidth;
    144 
    145 	clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 15];
    146 	clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 15];
    147 
    148 	if (uc == ' ') {
    149 		while (height--) {
    150 			dp = rp;
    151 			rp += ri->ri_stride;
    152 
    153 			for (cnt = width; cnt; cnt--) {
    154 				*(int16_t *)dp = (int16_t)clr[0];
    155 				dp += 2;
    156 			}
    157 		}
    158 	} else {
    159 		uc -= ri->ri_font->firstchar;
    160 		fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
    161 
    162 		while (height--) {
    163 			dp = rp;
    164 			fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
    165 			fr += ri->ri_font->stride;
    166 			rp += ri->ri_stride;
    167 
    168 			for (cnt = width; cnt; cnt--) {
    169 				*(int16_t *)dp = (int16_t)clr[(fb >> 31) & 1];
    170 				fb <<= 1;
    171 				dp += 2;
    172 			}
    173 		}
    174 	}
    175 
    176 	/* Do underline */
    177 	if ((attr & 1) != 0) {
    178 		rp -= ri->ri_stride << 1;
    179 
    180 		while (width--) {
    181 			*(int16_t *)rp = clr[1];
    182 			rp += 2;
    183 		}
    184 	}
    185 }
    186 
    187 #ifndef RASOPS_SMALL
    188 /*
    189  * Recompute the (2x2)x1 blitting stamp.
    190  */
    191 static void
    192 rasops15_makestamp(ri, attr)
    193 	struct rasops_info *ri;
    194 	long attr;
    195 {
    196 	int32_t fg, bg;
    197 	int i;
    198 
    199 	fg = ri->ri_devcmap[((u_int)attr >> 24) & 15] & 0xffff;
    200 	bg = ri->ri_devcmap[((u_int)attr >> 16) & 15] & 0xffff;
    201 	stamp_attr = attr;
    202 
    203 	for (i = 0; i < 32; i += 2) {
    204 #if BYTE_ORDER == LITTLE_ENDIAN
    205 		stamp[i] = (i & 16 ? fg : bg);
    206 		stamp[i] |= ((i & 8 ? fg : bg) << 16);
    207 		stamp[i + 1] = (i & 4 ? fg : bg);
    208 		stamp[i + 1] |= ((i & 2 ? fg : bg) << 16);
    209 #else
    210 		stamp[i] = (i & 2 ? fg : bg);
    211 		stamp[i] |= ((i & 4 ? fg : bg) << 16);
    212 		stamp[i + 1] = (i & 8 ? fg : bg);
    213 		stamp[i + 1] |= ((i & 16 ? fg : bg) << 16);
    214 #endif
    215 	}
    216 }
    217 
    218 /*
    219  * Paint a single character. This is for 8-pixel wide fonts.
    220  */
    221 static void
    222 rasops15_putchar8(cookie, row, col, uc, attr)
    223 	void *cookie;
    224 	int row, col;
    225 	u_int uc;
    226 	long attr;
    227 {
    228 	struct rasops_info *ri;
    229 	int height, so, fs;
    230 	int32_t *rp;
    231 	u_char *fr;
    232 
    233 	/* Can't risk remaking the stamp if it's already in use */
    234 	if (stamp_mutex++) {
    235 		stamp_mutex--;
    236 		rasops15_putchar(cookie, row, col, uc, attr);
    237 		return;
    238 	}
    239 
    240 	ri = (struct rasops_info *)cookie;
    241 
    242 #ifdef RASOPS_CLIPPING
    243 	if ((unsigned)row >= (unsigned)ri->ri_rows) {
    244 		stamp_mutex--;
    245 		return;
    246 	}
    247 
    248 	if ((unsigned)col >= (unsigned)ri->ri_cols) {
    249 		stamp_mutex--;
    250 		return;
    251 	}
    252 #endif
    253 
    254 	/* Recompute stamp? */
    255 	if (attr != stamp_attr)
    256 		rasops15_makestamp(ri, attr);
    257 
    258 	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
    259 	height = ri->ri_font->fontheight;
    260 
    261 	if (uc == (u_int)-1) {
    262 		while (height--) {
    263 			rp[0] = stamp[0];
    264 			rp[1] = stamp[0];
    265 			rp[2] = stamp[0];
    266 			rp[3] = stamp[0];
    267 			DELTA(rp, ri->ri_stride, int32_t *);
    268 		}
    269 	} else {
    270 		uc -= ri->ri_font->firstchar;
    271 		fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
    272 		fs = ri->ri_font->stride;
    273 
    274 		while (height--) {
    275 			so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
    276 			rp[0] = STAMP_READ(so);
    277 			rp[1] = STAMP_READ(so + 4);
    278 
    279 			so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
    280 			rp[2] = STAMP_READ(so);
    281 			rp[3] = STAMP_READ(so + 4);
    282 
    283 			fr += fs;
    284 			DELTA(rp, ri->ri_stride, int32_t *);
    285 		}
    286 	}
    287 
    288 	/* Do underline */
    289 	if ((attr & 1) != 0) {
    290 		DELTA(rp, -(ri->ri_stride << 1), int32_t *);
    291 		rp[0] = STAMP_READ(30);
    292 		rp[1] = STAMP_READ(30);
    293 		rp[2] = STAMP_READ(30);
    294 		rp[3] = STAMP_READ(30);
    295 	}
    296 
    297 	stamp_mutex--;
    298 }
    299 
    300 /*
    301  * Paint a single character. This is for 12-pixel wide fonts.
    302  */
    303 static void
    304 rasops15_putchar12(cookie, row, col, uc, attr)
    305 	void *cookie;
    306 	int row, col;
    307 	u_int uc;
    308 	long attr;
    309 {
    310 	struct rasops_info *ri;
    311 	int height, so, fs;
    312 	int32_t *rp;
    313 	u_char *fr;
    314 
    315 	/* Can't risk remaking the stamp if it's already in use */
    316 	if (stamp_mutex++) {
    317 		stamp_mutex--;
    318 		rasops15_putchar(cookie, row, col, uc, attr);
    319 		return;
    320 	}
    321 
    322 	ri = (struct rasops_info *)cookie;
    323 
    324 #ifdef RASOPS_CLIPPING
    325 	if ((unsigned)row >= (unsigned)ri->ri_rows) {
    326 		stamp_mutex--;
    327 		return;
    328 	}
    329 
    330 	if ((unsigned)col >= (unsigned)ri->ri_cols) {
    331 		stamp_mutex--;
    332 		return;
    333 	}
    334 #endif
    335 
    336 	/* Recompute stamp? */
    337 	if (attr != stamp_attr)
    338 		rasops15_makestamp(ri, attr);
    339 
    340 	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
    341 	height = ri->ri_font->fontheight;
    342 
    343 	if (uc == (u_int)-1) {
    344 		while (height--) {
    345 			rp[0] = stamp[0];
    346 			rp[1] = stamp[0];
    347 			rp[2] = stamp[0];
    348 			rp[3] = stamp[0];
    349 			rp[4] = stamp[0];
    350 			rp[5] = stamp[0];
    351 			DELTA(rp, ri->ri_stride, int32_t *);
    352 		}
    353 	} else {
    354 		uc -= ri->ri_font->firstchar;
    355 		fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
    356 		fs = ri->ri_font->stride;
    357 
    358 		while (height--) {
    359 			so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
    360 			rp[0] = STAMP_READ(so);
    361 			rp[1] = STAMP_READ(so + 4);
    362 
    363 			so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
    364 			rp[2] = STAMP_READ(so);
    365 			rp[3] = STAMP_READ(so + 4);
    366 
    367 			so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
    368 			rp[4] = STAMP_READ(so);
    369 			rp[5] = STAMP_READ(so + 4);
    370 
    371 			fr += fs;
    372 			DELTA(rp, ri->ri_stride, int32_t *);
    373 		}
    374 	}
    375 
    376 	/* Do underline */
    377 	if (attr & 1) {
    378 		DELTA(rp, -(ri->ri_stride << 1), int32_t *);
    379 		rp[0] = STAMP_READ(30);
    380 		rp[1] = STAMP_READ(30);
    381 		rp[2] = STAMP_READ(30);
    382 		rp[3] = STAMP_READ(30);
    383 		rp[4] = STAMP_READ(30);
    384 		rp[5] = STAMP_READ(30);
    385 	}
    386 
    387 	stamp_mutex--;
    388 }
    389 
    390 /*
    391  * Paint a single character. This is for 16-pixel wide fonts.
    392  */
    393 static void
    394 rasops15_putchar16(cookie, row, col, uc, attr)
    395 	void *cookie;
    396 	int row, col;
    397 	u_int uc;
    398 	long attr;
    399 {
    400 	struct rasops_info *ri;
    401 	int height, so, fs;
    402 	int32_t *rp;
    403 	u_char *fr;
    404 
    405 	/* Can't risk remaking the stamp if it's already in use */
    406 	if (stamp_mutex++) {
    407 		stamp_mutex--;
    408 		rasops15_putchar(cookie, row, col, uc, attr);
    409 		return;
    410 	}
    411 
    412 	ri = (struct rasops_info *)cookie;
    413 
    414 #ifdef RASOPS_CLIPPING
    415 	if ((unsigned)row >= (unsigned)ri->ri_rows) {
    416 		stamp_mutex--;
    417 		return;
    418 	}
    419 
    420 	if ((unsigned)col >= (unsigned)ri->ri_cols) {
    421 		stamp_mutex--;
    422 		return;
    423 	}
    424 #endif
    425 
    426 	/* Recompute stamp? */
    427 	if (attr != stamp_attr)
    428 		rasops15_makestamp(ri, attr);
    429 
    430 	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
    431 	height = ri->ri_font->fontheight;
    432 
    433 	if (uc == (u_int)-1) {
    434 		while (height--) {
    435 			rp[0] = stamp[0];
    436 			rp[1] = stamp[0];
    437 			rp[2] = stamp[0];
    438 			rp[3] = stamp[0];
    439 			rp[4] = stamp[0];
    440 			rp[5] = stamp[0];
    441 			rp[6] = stamp[0];
    442 			rp[7] = stamp[0];
    443 			DELTA(rp, ri->ri_stride, int32_t *);
    444 		}
    445 	} else {
    446 		uc -= ri->ri_font->firstchar;
    447 		fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
    448 		fs = ri->ri_font->stride;
    449 
    450 		while (height--) {
    451 			so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
    452 			rp[0] = STAMP_READ(so);
    453 			rp[1] = STAMP_READ(so + 4);
    454 
    455 			so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
    456 			rp[2] = STAMP_READ(so);
    457 			rp[3] = STAMP_READ(so + 4);
    458 
    459 			so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
    460 			rp[4] = STAMP_READ(so);
    461 			rp[5] = STAMP_READ(so + 4);
    462 
    463 			so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
    464 			rp[6] = STAMP_READ(so);
    465 			rp[7] = STAMP_READ(so + 4);
    466 
    467 			DELTA(rp, ri->ri_stride, int32_t *);
    468 			fr += fs;
    469 		}
    470 	}
    471 
    472 	/* Do underline */
    473 	if (attr & 1) {
    474 		DELTA(rp, -(ri->ri_stride << 1), int32_t *);
    475 		rp[0] = STAMP_READ(30);
    476 		rp[1] = STAMP_READ(30);
    477 		rp[2] = STAMP_READ(30);
    478 		rp[3] = STAMP_READ(30);
    479 		rp[4] = STAMP_READ(30);
    480 		rp[5] = STAMP_READ(30);
    481 		rp[6] = STAMP_READ(30);
    482 		rp[7] = STAMP_READ(30);
    483 	}
    484 
    485 	stamp_mutex--;
    486 }
    487 #endif	/* !RASOPS_SMALL */
    488