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