Home | History | Annotate | Line # | Download | only in rasops
rasops_putchar_width.h revision 1.14
      1 /* $NetBSD: rasops_putchar_width.h,v 1.14 2019/08/10 01:24:17 rin Exp $ */
      2 
      3 /* NetBSD: rasops8.c,v 1.41 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_DEPTH !=  2 && RASOPS_DEPTH !=  4 && RASOPS_DEPTH !=  8 &&	\
     34     RASOPS_DEPTH != 15 && RASOPS_DEPTH != 24 && RASOPS_DEPTH != 32
     35 #error "Depth not supported"
     36 #endif
     37 
     38 #if RASOPS_WIDTH != 8 && RASOPS_WIDTH != 12 && RASOPS_WIDTH != 16
     39 #error "Width not supported"
     40 #endif
     41 
     42 #if   RASOPS_DEPTH == 2
     43 #define	STAMP_TYPE	uint8_t
     44 #elif RASOPS_DEPTH == 4
     45 #define	STAMP_TYPE	uint16_t
     46 #else
     47 #define	STAMP_TYPE	uint32_t
     48 #endif
     49 
     50 #if   RASOPS_DEPTH <= 8
     51 #define	SUBST_UNIT	1
     52 #elif RASOPS_DEPTH == 15
     53 #define	SUBST_UNIT	2
     54 #elif RASOPS_DEPTH == 24
     55 #define	SUBST_UNIT	3
     56 #elif RASOPS_DEPTH == 32
     57 #define	SUBST_UNIT	4
     58 #endif
     59 
     60 #define	SUBST_BYTES	(SUBST_UNIT * (RASOPS_WIDTH / 4) * sizeof(STAMP_TYPE))
     61 
     62 #if   RASOPS_DEPTH <= 8
     63 #define	FILLED_STAMP	15
     64 #elif RASOPS_DEPTH == 15
     65 #define	FILLED_STAMP	30
     66 #else
     67 #define	FILLED_STAMP	60
     68 #endif
     69 
     70 /* ################################################################### */
     71 
     72 #if RASOPS_DEPTH <= 8
     73 
     74 #define	SUBST_STAMP1(off, base)						\
     75 	rp[(off) * 1 + 0] = stamp[base]
     76 
     77 #define	SUBST_GLYPH1(index, nibble, off)				\
     78 	do {								\
     79 		int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK;	\
     80 		rp[(off) * 1 + 0] = STAMP_READ(so);			\
     81 	} while (0 /* CONSTCOND */)
     82 
     83 #endif /* RASOPS_DEPTH <= 8 */
     84 
     85 /* ################################################################### */
     86 
     87 #if RASOPS_DEPTH == 15
     88 
     89 #define	SUBST_STAMP1(off, base)						\
     90 	rp[(off) * 2 + 0] = rp[(off) * 2 + 1] = stamp[base]
     91 
     92 #define	SUBST_GLYPH1(index, nibble, off)				\
     93 	do {								\
     94 		int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK;	\
     95 		rp[(off) * 2 + 0] = STAMP_READ(so);			\
     96 		rp[(off) * 2 + 1] = STAMP_READ(so +  4);		\
     97 	} while (0 /* CONSTCOND */)
     98 
     99 #endif /* RASOPS_DEPTH == 15 */
    100 
    101 /* ################################################################### */
    102 
    103 #if RASOPS_DEPTH == 24
    104 
    105 #define	SUBST_STAMP1(off, base)						\
    106 	do {								\
    107 		rp[(off) * 3 + 0] = stamp[(base) + 0];			\
    108 		rp[(off) * 3 + 1] = stamp[(base) + 1];			\
    109 		rp[(off) * 3 + 2] = stamp[(base) + 2];			\
    110 	} while (0 /* CONSTCOND */)
    111 
    112 #define	SUBST_GLYPH1(index, nibble, off)				\
    113 	do {								\
    114 		int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK;	\
    115 		rp[(off) * 3 + 0] = STAMP_READ(so);			\
    116 		rp[(off) * 3 + 1] = STAMP_READ(so +  4);		\
    117 		rp[(off) * 3 + 2] = STAMP_READ(so +  8);		\
    118 	} while (0 /* CONSTCOND */)
    119 
    120 #endif /* RASOPS_DEPTH == 24 */
    121 
    122 /* ################################################################### */
    123 
    124 #if RASOPS_DEPTH == 32
    125 
    126 #define	SUBST_STAMP1(off, base)						\
    127 	rp[(off) * 4 + 0] = rp[(off) * 4 + 1] =				\
    128 	rp[(off) * 4 + 2] = rp[(off) * 4 + 3] = stamp[base]
    129 
    130 #define	SUBST_GLYPH1(index, nibble, off)				\
    131 	do {								\
    132 		int so = STAMP_SHIFT(fr[index], nibble) & STAMP_MASK;	\
    133 		rp[(off) * 4 + 0] = STAMP_READ(so);			\
    134 		rp[(off) * 4 + 1] = STAMP_READ(so +  4);		\
    135 		rp[(off) * 4 + 2] = STAMP_READ(so +  8);		\
    136 		rp[(off) * 4 + 3] = STAMP_READ(so + 12);		\
    137 	} while (0 /* CONSTCOND */)
    138 
    139 #endif /* RASOPS_DEPTH == 32 */
    140 
    141 /* ################################################################### */
    142 
    143 #if   RASOPS_WIDTH == 8
    144 #define	SUBST_STAMP(base) 			\
    145 	do {					\
    146 		SUBST_STAMP1(0, base);		\
    147 		SUBST_STAMP1(1, base);		\
    148 	} while (0 /* CONSTCOND */)
    149 #elif RASOPS_WIDTH == 12
    150 #define	SUBST_STAMP(base)			\
    151 	do {					\
    152 		SUBST_STAMP1(0, base);		\
    153 		SUBST_STAMP1(1, base);		\
    154 		SUBST_STAMP1(2, base);		\
    155 	} while (0 /* CONSTCOND */)
    156 #elif RASOPS_WIDTH == 16
    157 #define	SUBST_STAMP(base)			\
    158 	do {					\
    159 		SUBST_STAMP1(0, base);		\
    160 		SUBST_STAMP1(1, base);		\
    161 		SUBST_STAMP1(2, base);		\
    162 		SUBST_STAMP1(3, base);		\
    163 	} while (0 /* CONSTCOND */)
    164 #endif
    165 
    166 /* ################################################################### */
    167 
    168 #if   RASOPS_WIDTH == 8
    169 #define	SUBST_GLYPH				\
    170 	do {					\
    171 		SUBST_GLYPH1(0, 1, 0);		\
    172 		SUBST_GLYPH1(0, 0, 1);		\
    173 	} while (0 /* CONSTCOND */)
    174 #elif RASOPS_WIDTH == 12
    175 #define	SUBST_GLYPH				\
    176 	do {					\
    177 		SUBST_GLYPH1(0, 1, 0);		\
    178 		SUBST_GLYPH1(0, 0, 1);		\
    179 		SUBST_GLYPH1(1, 1, 2);		\
    180 	} while (0 /* CONSTCOND */)
    181 #elif RASOPS_WIDTH == 16
    182 #define	SUBST_GLYPH				\
    183 	do {					\
    184 		SUBST_GLYPH1(0, 1, 0);		\
    185 		SUBST_GLYPH1(0, 0, 1);		\
    186 		SUBST_GLYPH1(1, 1, 2);		\
    187 		SUBST_GLYPH1(1, 0, 3);		\
    188 	} while (0 /* CONSTCOND */)
    189 #endif
    190 
    191 /* ################################################################### */
    192 
    193 #define	NAME(depth, width)	NAME1(depth, width)
    194 #define	NAME1(depth, width)	rasops ## depth ## _putchar ## width
    195 
    196 #define	PUTCHAR(depth)		PUTCHAR1(depth)
    197 #define	PUTCHAR1(depth)		rasops ## depth ## _putchar
    198 
    199 #define	MAKESTAMP(depth)	MAKESTAMP1(depth)
    200 #define	MAKESTAMP1(depth)	rasops ## depth ## _makestamp
    201 
    202 /*
    203  * Width-optimized putchar function.
    204  */
    205 static void
    206 NAME(RASOPS_DEPTH, RASOPS_WIDTH)(void *cookie, int row, int col, u_int uc,
    207     long attr)
    208 {
    209 	struct rasops_info *ri = (struct rasops_info *)cookie;
    210 	struct wsdisplay_font *font = PICK_FONT(ri, uc);
    211 	int height;
    212 	uint8_t *fr;
    213 	STAMP_TYPE *rp, *hp;
    214 
    215 	hp = NULL; /* XXX GCC */
    216 
    217 	/* check if character fits into font limits */
    218 	if (__predict_false(!CHAR_IN_FONT(uc, font)))
    219 		return;
    220 
    221 #ifdef RASOPS_CLIPPING
    222 	/* Catches 'row < 0' case too */
    223 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    224 		return;
    225 
    226 	if ((unsigned)col >= (unsigned)ri->ri_cols)
    227 		return;
    228 #endif
    229 
    230 	/* Recompute stamp? */
    231 	if (attr != stamp_attr || __predict_false(ri != stamp_ri))
    232 		MAKESTAMP(RASOPS_DEPTH)(ri, attr);
    233 
    234 	height = font->fontheight;
    235 
    236 	rp = (STAMP_TYPE *)(ri->ri_bits + FBOFFSET(ri, row, col));
    237 	if (ri->ri_hwbits)
    238 		hp = (STAMP_TYPE *)(ri->ri_hwbits + FBOFFSET(ri, row, col));
    239 
    240 	if (uc == ' ') {
    241 		while (height--) {
    242 			SUBST_STAMP(0);
    243 			if (ri->ri_hwbits) {
    244 				memcpy(hp, rp, SUBST_BYTES);
    245 				DELTA(hp, ri->ri_stride, STAMP_TYPE *);
    246 			}
    247 			DELTA(rp, ri->ri_stride, STAMP_TYPE *);
    248 		}
    249 	} else {
    250 		fr = FONT_GLYPH(uc, font, ri);
    251 		while (height--) {
    252 			SUBST_GLYPH;
    253 			fr += font->stride;
    254 			if (ri->ri_hwbits) {
    255 				memcpy(hp, rp, SUBST_BYTES);
    256 				DELTA(hp, ri->ri_stride, STAMP_TYPE *);
    257 			}
    258 			DELTA(rp, ri->ri_stride, STAMP_TYPE *);
    259 		}
    260 	}
    261 
    262 	/* Do underline */
    263 	if ((attr & WSATTR_UNDERLINE) != 0) {
    264 		DELTA(rp, - ri->ri_stride * ri->ri_ul.off, STAMP_TYPE *);
    265 		if (ri->ri_hwbits)
    266 			DELTA(hp, - ri->ri_stride * ri->ri_ul.off,
    267 			    STAMP_TYPE *);
    268 
    269 		for (height = ri->ri_ul.height; height; height--) {
    270 			DELTA(rp, - ri->ri_stride, STAMP_TYPE *);
    271 			SUBST_STAMP(FILLED_STAMP);
    272 			if (ri->ri_hwbits) {
    273 				DELTA(hp, - ri->ri_stride, STAMP_TYPE *);
    274 				memcpy(hp, rp, SUBST_BYTES);
    275 			}
    276 		}
    277 	}
    278 }
    279 
    280 #undef	STAMP_TYPE
    281 
    282 #undef	SUBST_UNIT
    283 #undef	SUBST_BYTES
    284 
    285 #undef	FILLED_STAMP
    286 
    287 #undef	SUBST_STAMP1
    288 #undef	SUBST_STAMP
    289 
    290 #undef	SUBST_GLYPH1
    291 #undef	SUBST_GLYPH
    292 
    293 #undef	NAME
    294 #undef	NAME1
    295 
    296 #undef	PUTCHAR
    297 #undef	PUTCHAR1
    298 
    299 #undef	MAKESTAMP
    300 #undef	MAKESTAMP1
    301