Home | History | Annotate | Line # | Download | only in rasops
      1 /* $NetBSD: rasops1_putchar_width.h,v 1.6 2019/08/10 01:24:17 rin Exp $ */
      2 
      3 /* NetBSD: rasops1.c,v 1.28 2019/07/25 03:02:44 rin Exp */
      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  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #if RASOPS_WIDTH != 8 && RASOPS_WIDTH != 16
     34 #error "Width not supported"
     35 #endif
     36 
     37 #if RASOPS_WIDTH == 8
     38 #define	SUBST_UNIT	uint8_t
     39 #define	GET_GLYPH(fr)	(fr)[0]
     40 #endif
     41 
     42 #if RASOPS_WIDTH == 16
     43 /*
     44  * rp and hp are always half-word aligned, whereas
     45  * fr may not be aligned in half-word boundary.
     46  */
     47 #define	SUBST_UNIT	uint16_t
     48 #  if BYTE_ORDER == BIG_ENDIAN
     49 #define	GET_GLYPH(fr)	((fr)[0] << 8) | (fr)[1]
     50 #  else
     51 #define	GET_GLYPH(fr)	(fr)[0] | ((fr)[1] << 8)
     52 #  endif
     53 #endif /* RASOPS_WIDTH == 16 */
     54 
     55 #define	NAME(width)	NAME1(width)
     56 #define	NAME1(width)	rasops1_putchar ## width
     57 
     58 /*
     59  * Width-optimized putchar function.
     60  */
     61 static void
     62 NAME(RASOPS_WIDTH)(void *cookie, int row, int col, u_int uc, long attr)
     63 {
     64 	struct rasops_info *ri = (struct rasops_info *)cookie;
     65 	struct wsdisplay_font *font = PICK_FONT(ri, uc);
     66 	int height;
     67 	uint32_t bg, fg;
     68 	uint8_t *fr;
     69 	SUBST_UNIT tmp, *rp, *hp;
     70 
     71 	hp = NULL;	/* XXX GCC */
     72 
     73 	if (__predict_false(!CHAR_IN_FONT(uc, font)))
     74 		return;
     75 
     76 #ifdef RASOPS_CLIPPING
     77 	/* Catches 'row < 0' case too */
     78 	if ((unsigned)row >= (unsigned)ri->ri_rows)
     79 		return;
     80 
     81 	if ((unsigned)col >= (unsigned)ri->ri_cols)
     82 		return;
     83 #endif
     84 
     85 	height = font->fontheight;
     86 
     87 	rp = (SUBST_UNIT *)(ri->ri_bits + row * ri->ri_yscale +
     88 	    col * sizeof(SUBST_UNIT));
     89 	if (ri->ri_hwbits)
     90 		hp = (SUBST_UNIT *)(ri->ri_hwbits + row * ri->ri_yscale +
     91 		    col * sizeof(SUBST_UNIT));
     92 
     93 	bg = ATTR_BG(ri, attr);
     94 	fg = ATTR_FG(ri, attr);
     95 
     96 	/* If fg and bg match this becomes a space character */
     97 	if (uc == ' ' || __predict_false(fg == bg)) {
     98 		while (height--) {
     99 			*rp = bg;
    100 			if (ri->ri_hwbits) {
    101 				*hp = bg;
    102 				DELTA(hp, ri->ri_stride, SUBST_UNIT *);
    103 			}
    104 			DELTA(rp, ri->ri_stride, SUBST_UNIT *);
    105 		}
    106 	} else {
    107 		fr = FONT_GLYPH(uc, font, ri);
    108 
    109 		while (height--) {
    110 			tmp = GET_GLYPH(fr);
    111 			fr += font->stride;
    112 			if (bg)
    113 				tmp = ~tmp;
    114 
    115 			*rp = tmp;
    116 
    117 			if (ri->ri_hwbits) {
    118 				*hp = tmp;
    119 				DELTA(hp, ri->ri_stride, SUBST_UNIT *);
    120 			}
    121 
    122 			DELTA(rp, ri->ri_stride, SUBST_UNIT *);
    123 		}
    124 	}
    125 
    126 	/* Do underline */
    127 	if ((attr & WSATTR_UNDERLINE) != 0) {
    128 		DELTA(rp, - ri->ri_stride * ri->ri_ul.off, SUBST_UNIT *);
    129 		if (ri->ri_hwbits)
    130 			DELTA(hp, - ri->ri_stride * ri->ri_ul.off,
    131 			    SUBST_UNIT *);
    132 
    133 		for (height = ri->ri_ul.height; height; height--) {
    134 			DELTA(rp, - ri->ri_stride, SUBST_UNIT *);
    135 			*rp = fg;
    136 			if (ri->ri_hwbits) {
    137 				DELTA(hp, - ri->ri_stride, SUBST_UNIT *);
    138 				*hp = fg;
    139 			}
    140 		}
    141 	}
    142 }
    143 
    144 #undef	SUBST_UNIT
    145 #undef	GET_GLYPH
    146 
    147 #undef	NAME
    148 #undef	NAME1
    149