Home | History | Annotate | Line # | Download | only in rasops
rasops1.c revision 1.32
      1 /* 	$NetBSD: rasops1.c,v 1.32 2019/07/31 00:14:25 rin 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: rasops1.c,v 1.32 2019/07/31 00:14:25 rin Exp $");
     34 
     35 #include "opt_rasops.h"
     36 
     37 #include <sys/param.h>
     38 #include <sys/systm.h>
     39 #include <sys/time.h>
     40 #include <machine/endian.h>
     41 
     42 #include <dev/wscons/wsdisplayvar.h>
     43 #include <dev/wscons/wsconsio.h>
     44 
     45 #define	_RASOPS_PRIVATE
     46 #include <dev/rasops/rasops.h>
     47 #include <dev/rasops/rasops_masks.h>
     48 
     49 static void	rasops1_copycols(void *, int, int, int, int);
     50 static void	rasops1_erasecols(void *, int, int, int, long);
     51 static void	rasops1_do_cursor(struct rasops_info *);
     52 static void	rasops1_putchar(void *, int, int col, u_int, long);
     53 #ifndef RASOPS_SMALL
     54 static void	rasops1_putchar8(void *, int, int col, u_int, long);
     55 static void	rasops1_putchar16(void *, int, int col, u_int, long);
     56 #endif
     57 
     58 /*
     59  * Initialize rasops_info struct for this colordepth.
     60  */
     61 void
     62 rasops1_init(struct rasops_info *ri)
     63 {
     64 
     65 	if ((ri->ri_font->fontwidth & 7) != 0) {
     66 		ri->ri_ops.erasecols = rasops1_erasecols;
     67 		ri->ri_ops.copycols = rasops1_copycols;
     68 		ri->ri_do_cursor = rasops1_do_cursor;
     69 	}
     70 
     71 	switch (ri->ri_font->fontwidth) {
     72 #ifndef RASOPS_SMALL
     73 	case 8:
     74 		ri->ri_ops.putchar = rasops1_putchar8;
     75 		break;
     76 	case 16:
     77 		ri->ri_ops.putchar = rasops1_putchar16;
     78 		break;
     79 #endif
     80 	default:
     81 		ri->ri_ops.putchar = rasops1_putchar;
     82 		break;
     83 	}
     84 }
     85 
     86 /*
     87  * Paint a single character. This is the generic version, this is ugly.
     88  */
     89 static void
     90 rasops1_putchar(void *cookie, int row, int col, u_int uc, long attr)
     91 {
     92 	struct rasops_info *ri = (struct rasops_info *)cookie;
     93 	struct wsdisplay_font *font = PICK_FONT(ri, uc);
     94 	uint32_t fs, rs, fb, bg, fg, lmask, rmask;
     95 	uint32_t height, width;
     96 	uint32_t *rp, *hp, tmp, tmp0, tmp1;
     97 	uint8_t *fr;
     98 	bool space;
     99 
    100 	hp = NULL;	/* XXX GCC */
    101 
    102 #ifdef RASOPS_CLIPPING
    103 	/* Catches 'row < 0' case too */
    104 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    105 		return;
    106 
    107 	if ((unsigned)col >= (unsigned)ri->ri_cols)
    108 		return;
    109 #endif
    110 
    111 	col *= ri->ri_font->fontwidth;
    112 	rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale +
    113 	    ((col >> 3) & ~3));
    114 	if (ri->ri_hwbits)
    115 		hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale +
    116 		    ((col >> 3) & ~3));
    117 	height = font->fontheight;
    118 	width = font->fontwidth;
    119 	col &= 31;
    120 	rs = ri->ri_stride;
    121 
    122 	bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
    123 	fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
    124 
    125 	/* If fg and bg match this becomes a space character */
    126 	if (uc == ' ' || fg == bg) {
    127 		space = true;
    128 		fr = NULL;	/* XXX GCC */
    129 		fs = 0;		/* XXX GCC */
    130 	} else {
    131 		space = false;
    132 		fr = FONT_GLYPH(uc, font, ri);
    133 		fs = font->stride;
    134 	}
    135 
    136 	if (col + width <= 32) {
    137 		/* Single word, only one mask */
    138 
    139 		rmask = rasops_pmask[col][width];
    140 		lmask = ~rmask;
    141 
    142 		if (space) {
    143 			bg &= rmask;
    144 			while (height--) {
    145 				tmp = (*rp & lmask) | bg;
    146 				*rp = tmp;
    147 				DELTA(rp, rs, uint32_t *);
    148 				if (ri->ri_hwbits) {
    149 					*hp = tmp;
    150 					DELTA(hp, rs, uint32_t *);
    151 				}
    152 			}
    153 		} else {
    154 			while (height--) {
    155 				tmp = *rp & lmask;
    156 				fb = be32uatoh(fr);
    157 				fr += fs;
    158 				if (bg)
    159 					fb = ~fb;
    160 				tmp |= (MBE(fb >> col) & rmask);
    161 				*rp = tmp;
    162 				DELTA(rp, rs, uint32_t *);
    163 				if (ri->ri_hwbits) {
    164 					*hp = tmp;
    165 					DELTA(hp, rs, uint32_t *);
    166 				}
    167 			}
    168 		}
    169 
    170 		/* Do underline */
    171 		if ((attr & WSATTR_UNDERLINE) != 0) {
    172 			DELTA(rp, -(ri->ri_stride << 1), uint32_t *);
    173 			tmp = (*rp & lmask) | (fg & rmask);
    174 			*rp = tmp;
    175 			if (ri->ri_hwbits) {
    176 				DELTA(hp, -(ri->ri_stride << 1), uint32_t *);
    177 				*hp = tmp;
    178 			}
    179 		}
    180 	} else {
    181 		/* Word boundary, two masks needed */
    182 
    183 		lmask = ~rasops_lmask[col];
    184 		rmask = ~rasops_rmask[(col + width) & 31];
    185 
    186 		if (space) {
    187 			width = bg & ~rmask;
    188 			bg = bg & ~lmask;
    189 			while (height--) {
    190 				tmp0 = (rp[0] & lmask) | bg;
    191 				tmp1 = (rp[1] & rmask) | width;
    192 				rp[0] = tmp0;
    193 				rp[1] = tmp1;
    194 				DELTA(rp, rs, uint32_t *);
    195 				if (ri->ri_hwbits) {
    196 					hp[0] = tmp0;
    197 					hp[1] = tmp1;
    198 					DELTA(hp, rs, uint32_t *);
    199 				}
    200 			}
    201 		} else {
    202 			width = 32 - col;
    203 			while (height--) {
    204 				tmp0 = rp[0] & lmask;
    205 				tmp1 = rp[1] & rmask;
    206 				fb = be32uatoh(fr);
    207 				fr += fs;
    208 				if (bg)
    209 					fb = ~fb;
    210 				tmp0 |= MBE(fb >> col);
    211 				tmp1 |= (MBE(fb << width) & ~rmask);
    212 				rp[0] = tmp0;
    213 				rp[1] = tmp1;
    214 				DELTA(rp, rs, uint32_t *);
    215 				if (ri->ri_hwbits) {
    216 					hp[0] = tmp0;
    217 					hp[1] = tmp1;
    218 					DELTA(hp, rs, uint32_t *);
    219 				}
    220 			}
    221 		}
    222 
    223 		/* Do underline */
    224 		if ((attr & WSATTR_UNDERLINE) != 0) {
    225 			DELTA(rp, -(ri->ri_stride << 1), uint32_t *);
    226 			tmp0 = (rp[0] & lmask) | (fg & ~lmask);
    227 			tmp1 = (rp[1] & rmask) | (fg & ~rmask);
    228 			rp[0] = tmp0;
    229 			rp[1] = tmp1;
    230 			if (ri->ri_hwbits) {
    231 				DELTA(hp, -(ri->ri_stride << 1), uint32_t *);
    232 				hp[0] = tmp0;
    233 				hp[1] = tmp1;
    234 			}
    235 		}
    236 	}
    237 }
    238 
    239 #ifndef RASOPS_SMALL
    240 
    241 #define	RASOPS_WIDTH	8
    242 #include "rasops1_putchar_width.h"
    243 #undef	RASOPS_WIDTH
    244 
    245 #define	RASOPS_WIDTH	16
    246 #include "rasops1_putchar_width.h"
    247 #undef	RASOPS_WIDTH
    248 
    249 #endif	/* !RASOPS_SMALL */
    250 
    251 /*
    252  * Grab routines common to depths where (bpp < 8)
    253  */
    254 #define NAME(ident)	rasops1_##ident
    255 #define PIXEL_SHIFT	0
    256 
    257 #include <dev/rasops/rasops_bitops.h>
    258