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