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