1/* $NetBSD: rasops_putchar.h,v 1.8 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 != 8 && RASOPS_DEPTH != 15 && RASOPS_DEPTH != 24 && \ 34 RASOPS_DEPTH != 32 35#error "Depth not supported" 36#endif 37 38#if RASOPS_DEPTH == 8 39#define COLOR_TYPE uint8_t 40#elif RASOPS_DEPTH == 15 41#define COLOR_TYPE uint16_t 42#else 43#define COLOR_TYPE uint32_t 44#endif 45 46#if RASOPS_DEPTH != 24 47#define PIXEL_TYPE COLOR_TYPE 48#define PIXEL_BYTES sizeof(PIXEL_TYPE) 49#define SET_COLOR(p, index) *(p)++ = clr[index] 50#define SET_RGB(p, r, g, b) \ 51 *(p)++ = (((r) >> (8 - ri->ri_rnum)) << ri->ri_rpos) | \ 52 (((g) >> (8 - ri->ri_gnum)) << ri->ri_gpos) | \ 53 (((b) >> (8 - ri->ri_bnum)) << ri->ri_bpos) 54#endif 55 56#if RASOPS_DEPTH == 24 57#define PIXEL_TYPE uint8_t 58#define PIXEL_BYTES 3 59#define SET_COLOR(p, index) \ 60 do { \ 61 COLOR_TYPE c = clr[index]; \ 62 *(p)++ = c >> 16; \ 63 *(p)++ = c >> 8; \ 64 *(p)++ = c; \ 65 } while (0 /* CONSTCOND */) 66#define SET_RGB(p, r, g, b) \ 67 do { \ 68 (p)[R_OFF] = (r); \ 69 (p)[G_OFF] = (g); \ 70 (p)[B_OFF] = (b); \ 71 (p) += 3; \ 72 } while (0 /* CONSTCOND */) 73#endif 74 75#define AV(p, w) (((w) * (p)[1] + (0xff - (w)) * (p)[0]) >> 8) 76 77#if BYTE_ORDER == LITTLE_ENDIAN 78#define R_OFF (ri->ri_rpos / 8) 79#define G_OFF (ri->ri_gpos / 8) 80#define B_OFF (ri->ri_bpos / 8) 81#else /* BIG_ENDIAN XXX not tested */ 82#define R_OFF (2 - ri->ri_rpos / 8) 83#define G_OFF (2 - ri->ri_gpos / 8) 84#define B_OFF (2 - ri->ri_bpos / 8) 85#endif 86 87#define NAME(depth) NAME1(depth) 88#ifndef RASOPS_AA 89#define NAME1(depth) rasops ## depth ## _putchar 90#else 91#define NAME1(depth) rasops ## depth ## _putchar_aa 92#endif 93 94/* 95 * Put a single character. 96 */ 97static void 98NAME(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) 99{ 100 struct rasops_info *ri = (struct rasops_info *)cookie; 101 struct wsdisplay_font *font = PICK_FONT(ri, uc); 102 int height, width, cnt; 103 uint8_t *fr; 104 COLOR_TYPE clr[2]; 105 PIXEL_TYPE *dp, *rp, *hp; 106 107 hp = NULL; /* XXX GCC */ 108 109 if (__predict_false(!CHAR_IN_FONT(uc, font))) 110 return; 111 112#ifdef RASOPS_CLIPPING 113 /* Catches 'row < 0' case too */ 114 if ((unsigned)row >= (unsigned)ri->ri_rows) 115 return; 116 117 if ((unsigned)col >= (unsigned)ri->ri_cols) 118 return; 119#endif 120 121 height = font->fontheight; 122 width = font->fontwidth; 123 124 rp = (PIXEL_TYPE *)(ri->ri_bits + FBOFFSET(ri, row, col)); 125 if (ri->ri_hwbits) 126 hp = (PIXEL_TYPE *)(ri->ri_hwbits + FBOFFSET(ri, row, col)); 127 128 clr[0] = (COLOR_TYPE)ATTR_BG(ri, attr); 129 clr[1] = (COLOR_TYPE)ATTR_FG(ri, attr); 130 131 if (uc == ' ') { 132 while (height--) { 133 dp = rp; 134 for (cnt = width; cnt; cnt--) 135 SET_COLOR(dp, 0); 136 if (ri->ri_hwbits) { 137 uint16_t bytes = width * PIXEL_BYTES; 138 /* XXX GCC */ 139 memcpy(hp, rp, bytes); 140 DELTA(hp, ri->ri_stride, PIXEL_TYPE *); 141 } 142 DELTA(rp, ri->ri_stride, PIXEL_TYPE *); 143 } 144 } else { 145 fr = FONT_GLYPH(uc, font, ri); 146 147#ifdef RASOPS_AA 148 int off[2]; 149 uint8_t r[2], g[2], b[2]; 150 151 /* 152 * This is independent to positions/lengths of RGB in pixel. 153 */ 154 off[0] = (((uint32_t)attr >> 16) & 0xf) * 3; 155 off[1] = (((uint32_t)attr >> 24) & 0xf) * 3; 156 157 r[0] = rasops_cmap[off[0]]; 158 r[1] = rasops_cmap[off[1]]; 159 g[0] = rasops_cmap[off[0] + 1]; 160 g[1] = rasops_cmap[off[1] + 1]; 161 b[0] = rasops_cmap[off[0] + 2]; 162 b[1] = rasops_cmap[off[1] + 2]; 163#endif 164 165 while (height--) { 166 dp = rp; 167 168#ifndef RASOPS_AA 169 uint32_t fb = rasops_be32uatoh(fr); 170 fr += ri->ri_font->stride; 171 172 for (cnt = width; cnt; cnt--) { 173 SET_COLOR(dp, (fb >> 31) & 1); 174 fb <<= 1; 175 } 176#else /* RASOPS_AA */ 177 for (cnt = width; cnt; cnt--) { 178 int w = *fr++; 179 if (w == 0xff) 180 SET_COLOR(dp, 1); 181 else if (w == 0) 182 SET_COLOR(dp, 0); 183 else 184 SET_RGB(dp, 185 AV(r, w), AV(g, w), AV(b, w)); 186 } 187#endif 188 if (ri->ri_hwbits) { 189 uint16_t bytes = width * PIXEL_BYTES; 190 /* XXX GCC */ 191 memcpy(hp, rp, bytes); 192 DELTA(hp, ri->ri_stride, PIXEL_TYPE *); 193 } 194 DELTA(rp, ri->ri_stride, PIXEL_TYPE *); 195 } 196 } 197 198 /* Do underline */ 199 if ((attr & WSATTR_UNDERLINE) != 0) { 200 DELTA(rp, - ri->ri_stride * ri->ri_ul.off, PIXEL_TYPE *); 201 if (ri->ri_hwbits) 202 DELTA(hp, - ri->ri_stride * ri->ri_ul.off, 203 PIXEL_TYPE *); 204 205 for (height = ri->ri_ul.height; height; height--) { 206 DELTA(rp, - ri->ri_stride, PIXEL_TYPE *); 207 dp = rp; 208 for (cnt = width; cnt; cnt--) 209 SET_COLOR(dp, 1); 210 if (ri->ri_hwbits) { 211 DELTA(hp, - ri->ri_stride, PIXEL_TYPE *); 212 uint16_t bytes = width * PIXEL_BYTES; 213 /* XXX GCC */ 214 memcpy(hp, rp, bytes); 215 } 216 } 217 } 218} 219 220#undef COLOR_TYPE 221 222#undef PIXEL_TYPE 223#undef PIXEL_BYTES 224#undef SET_COLOR 225#undef SET_RGB 226 227#undef AV 228 229#undef R_OFF 230#undef G_OFF 231#undef B_OFF 232 233#undef NAME 234#undef NAME1 235