1 1.3 rin /* $NetBSD: rasops1-4_putchar.h,v 1.3 2019/08/10 01:24:17 rin Exp $ */ 2 1.1 rin 3 1.1 rin /* NetBSD: rasops_bitops.h,v 1.23 2019/08/02 04:39:09 rin Exp */ 4 1.1 rin /*- 5 1.1 rin * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 1.1 rin * All rights reserved. 7 1.1 rin * 8 1.1 rin * This code is derived from software contributed to The NetBSD Foundation 9 1.1 rin * by Andrew Doran. 10 1.1 rin * 11 1.1 rin * Redistribution and use in source and binary forms, with or without 12 1.1 rin * modification, are permitted provided that the following conditions 13 1.1 rin * are met: 14 1.1 rin * 1. Redistributions of source code must retain the above copyright 15 1.1 rin * notice, this list of conditions and the following disclaimer. 16 1.1 rin * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 rin * notice, this list of conditions and the following disclaimer in the 18 1.1 rin * documentation and/or other materials provided with the distribution. 19 1.1 rin * 20 1.1 rin * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 rin * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 rin * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 rin * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 rin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 rin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 rin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 rin * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 rin * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 rin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 rin * POSSIBILITY OF SUCH DAMAGE. 31 1.1 rin */ 32 1.1 rin 33 1.1 rin #define PIXEL_BITS RASOPS_DEPTH 34 1.1 rin 35 1.1 rin #if RASOPS_DEPTH == 1 36 1.1 rin #define PIXEL_SHIFT 0 37 1.1 rin #elif RASOPS_DEPTH == 2 38 1.1 rin #define PIXEL_SHIFT 1 39 1.1 rin #elif RASOPS_DEPTH == 4 40 1.1 rin #define PIXEL_SHIFT 2 41 1.1 rin #else 42 1.1 rin #error "Depth not supported" 43 1.1 rin #endif 44 1.1 rin 45 1.1 rin #ifndef RASOPS_AA 46 1.1 rin #define COLOR_MASK __BITS(32 - PIXEL_BITS, 31) 47 1.1 rin #else 48 1.1 rin # if RASOPS_DEPTH == 2 49 1.1 rin #define COLOR_MASK 0x3 50 1.1 rin # else 51 1.1 rin #error "Anti-aliasing not supported" 52 1.1 rin # endif 53 1.1 rin #endif 54 1.1 rin 55 1.1 rin #ifndef RASOPS_AA 56 1.1 rin #define PIXEL_OR(tmp) \ 57 1.1 rin do { \ 58 1.1 rin (tmp) |= clr[(fb >> 31) & 1] >> bit; \ 59 1.1 rin fb <<= 1; \ 60 1.1 rin } while (0 /* CONSTCOND */) 61 1.1 rin #else 62 1.1 rin #define PIXEL_OR(tmp) \ 63 1.1 rin do { \ 64 1.3 rin uint8_t c, w = *fr++; \ 65 1.3 rin if (w == 0xff) \ 66 1.1 rin c = clr[1]; \ 67 1.3 rin else if (w == 0) \ 68 1.1 rin c = clr[0]; \ 69 1.1 rin else \ 70 1.3 rin c = (w * clr[1] + (0xff - w) * clr[0]) >> 8; \ 71 1.1 rin (tmp) |= c << (32 - PIXEL_BITS - bit); \ 72 1.1 rin } while (0 /* CONSTCOND */) 73 1.1 rin #endif 74 1.1 rin 75 1.1 rin #define NAME(depth) NAME1(depth) 76 1.1 rin #ifndef RASOPS_AA 77 1.1 rin #define NAME1(depth) rasops ## depth ## _ ## putchar 78 1.1 rin #else 79 1.1 rin #define NAME1(depth) rasops ## depth ## _ ## putchar_aa 80 1.1 rin #endif 81 1.1 rin 82 1.1 rin /* 83 1.1 rin * Paint a single character. This function is also applicable to 84 1.1 rin * monochrome, but that in rasops1.c is much simpler and faster. 85 1.1 rin */ 86 1.1 rin static void 87 1.1 rin NAME(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) 88 1.1 rin { 89 1.1 rin struct rasops_info *ri = (struct rasops_info *)cookie; 90 1.1 rin struct wsdisplay_font *font = PICK_FONT(ri, uc); 91 1.3 rin int height, width, full, cnt, bit; 92 1.3 rin uint32_t bg, fg, lbg, rbg, clr[2], lmask, rmask, tmp; 93 1.3 rin uint32_t *rp, *bp, *hp; 94 1.1 rin uint8_t *fr; 95 1.1 rin bool space; 96 1.1 rin 97 1.1 rin hp = NULL; /* XXX GCC */ 98 1.1 rin 99 1.2 rin if (__predict_false(!CHAR_IN_FONT(uc, font))) 100 1.2 rin return; 101 1.2 rin 102 1.1 rin #ifdef RASOPS_CLIPPING 103 1.1 rin /* Catches 'row < 0' case too */ 104 1.1 rin if ((unsigned)row >= (unsigned)ri->ri_rows) 105 1.1 rin return; 106 1.1 rin 107 1.1 rin if ((unsigned)col >= (unsigned)ri->ri_cols) 108 1.1 rin return; 109 1.1 rin #endif 110 1.1 rin 111 1.3 rin height = font->fontheight; 112 1.1 rin width = font->fontwidth << PIXEL_SHIFT; 113 1.1 rin col *= width; 114 1.3 rin 115 1.1 rin rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale + 116 1.1 rin ((col >> 3) & ~3)); 117 1.1 rin if (ri->ri_hwbits) 118 1.1 rin hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + 119 1.1 rin ((col >> 3) & ~3)); 120 1.3 rin 121 1.1 rin col &= 31; 122 1.1 rin 123 1.3 rin bg = ATTR_BG(ri, attr); 124 1.3 rin fg = ATTR_FG(ri, attr); 125 1.1 rin 126 1.1 rin /* If fg and bg match this becomes a space character */ 127 1.1 rin if (uc == ' ' || __predict_false(fg == bg)) { 128 1.1 rin space = true; 129 1.1 rin fr = NULL; /* XXX GCC */ 130 1.1 rin } else { 131 1.1 rin space = false; 132 1.1 rin fr = FONT_GLYPH(uc, font, ri); 133 1.1 rin } 134 1.1 rin 135 1.1 rin if (col + width <= 32) { 136 1.1 rin /* Single word, only one mask */ 137 1.1 rin rmask = rasops_pmask[col][width & 31]; 138 1.1 rin lmask = ~rmask; 139 1.1 rin 140 1.1 rin if (space) { 141 1.1 rin bg &= rmask; 142 1.1 rin while (height--) { 143 1.1 rin tmp = (*rp & lmask) | bg; 144 1.1 rin *rp = tmp; 145 1.1 rin if (ri->ri_hwbits) { 146 1.1 rin *hp = tmp; 147 1.3 rin DELTA(hp, ri->ri_stride, uint32_t *); 148 1.1 rin } 149 1.3 rin DELTA(rp, ri->ri_stride, uint32_t *); 150 1.1 rin } 151 1.1 rin } else { 152 1.1 rin clr[0] = bg & COLOR_MASK; 153 1.1 rin clr[1] = fg & COLOR_MASK; 154 1.3 rin 155 1.1 rin while (height--) { 156 1.1 rin #ifndef RASOPS_AA 157 1.3 rin uint32_t fb = rasops_be32uatoh(fr); 158 1.1 rin fr += ri->ri_font->stride; 159 1.1 rin #endif 160 1.1 rin 161 1.1 rin tmp = 0; 162 1.1 rin for (bit = col; bit < col + width; 163 1.1 rin bit += PIXEL_BITS) 164 1.1 rin PIXEL_OR(tmp); 165 1.1 rin tmp = (*rp & lmask) | MBE(tmp); 166 1.1 rin *rp = tmp; 167 1.1 rin 168 1.1 rin if (ri->ri_hwbits) { 169 1.1 rin *hp = tmp; 170 1.3 rin DELTA(hp, ri->ri_stride, uint32_t *); 171 1.1 rin } 172 1.1 rin 173 1.3 rin DELTA(rp, ri->ri_stride, uint32_t *); 174 1.1 rin } 175 1.1 rin } 176 1.1 rin 177 1.1 rin /* Do underline */ 178 1.1 rin if ((attr & WSATTR_UNDERLINE) != 0) { 179 1.1 rin DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); 180 1.1 rin if (ri->ri_hwbits) 181 1.1 rin DELTA(hp, - ri->ri_stride * ri->ri_ul.off, 182 1.1 rin uint32_t *); 183 1.1 rin 184 1.1 rin for (height = ri->ri_ul.height; height; height--) { 185 1.1 rin DELTA(rp, - ri->ri_stride, uint32_t *); 186 1.1 rin tmp = (*rp & lmask) | (fg & rmask); 187 1.1 rin *rp = tmp; 188 1.1 rin if (ri->ri_hwbits) { 189 1.1 rin DELTA(hp, - ri->ri_stride, uint32_t *); 190 1.1 rin *hp = tmp; 191 1.1 rin } 192 1.1 rin } 193 1.1 rin } 194 1.1 rin 195 1.1 rin return; 196 1.1 rin } 197 1.1 rin 198 1.1 rin /* Word boundary, two masks needed */ 199 1.1 rin lmask = ~rasops_lmask[col]; 200 1.1 rin rmask = ~rasops_rmask[(col + width) & 31]; 201 1.1 rin 202 1.1 rin if (lmask != -1) 203 1.1 rin width -= 32 - col; 204 1.3 rin 205 1.1 rin full = width / 32; 206 1.1 rin width -= full * 32; 207 1.1 rin 208 1.1 rin if (space) { 209 1.1 rin lbg = bg & ~lmask; 210 1.1 rin rbg = bg & ~rmask; 211 1.1 rin 212 1.1 rin while (height--) { 213 1.1 rin bp = rp; 214 1.1 rin 215 1.1 rin if (lmask != -1) { 216 1.1 rin *bp = (*bp & lmask) | lbg; 217 1.1 rin bp++; 218 1.1 rin } 219 1.1 rin 220 1.1 rin for (cnt = full; cnt; cnt--) 221 1.1 rin *bp++ = bg; 222 1.1 rin 223 1.1 rin if (rmask != -1) 224 1.1 rin *bp = (*bp & rmask) | rbg; 225 1.1 rin 226 1.1 rin if (ri->ri_hwbits) { 227 1.1 rin memcpy(hp, rp, ((lmask != -1) + full + 228 1.1 rin (rmask != -1)) << 2); 229 1.3 rin DELTA(hp, ri->ri_stride, uint32_t *); 230 1.1 rin } 231 1.1 rin 232 1.3 rin DELTA(rp, ri->ri_stride, uint32_t *); 233 1.1 rin } 234 1.1 rin } else { 235 1.1 rin clr[0] = bg & COLOR_MASK; 236 1.1 rin clr[1] = fg & COLOR_MASK; 237 1.1 rin 238 1.1 rin while (height--) { 239 1.1 rin bp = rp; 240 1.1 rin 241 1.1 rin #ifndef RASOPS_AA 242 1.3 rin uint32_t fb = rasops_be32uatoh(fr); 243 1.1 rin fr += ri->ri_font->stride; 244 1.1 rin #endif 245 1.1 rin 246 1.1 rin if (lmask != -1) { 247 1.1 rin tmp = 0; 248 1.1 rin for (bit = col; bit < 32; bit += PIXEL_BITS) 249 1.1 rin PIXEL_OR(tmp); 250 1.1 rin *bp = (*bp & lmask) | MBE(tmp); 251 1.1 rin bp++; 252 1.1 rin } 253 1.1 rin 254 1.1 rin for (cnt = full; cnt; cnt--) { 255 1.1 rin tmp = 0; 256 1.1 rin for (bit = 0; bit < 32; bit += PIXEL_BITS) 257 1.1 rin PIXEL_OR(tmp); 258 1.1 rin *bp++ = MBE(tmp); 259 1.1 rin } 260 1.1 rin 261 1.1 rin if (rmask != -1) { 262 1.1 rin tmp = 0; 263 1.1 rin for (bit = 0; bit < width; bit += PIXEL_BITS) 264 1.1 rin PIXEL_OR(tmp); 265 1.1 rin *bp = (*bp & rmask) | MBE(tmp); 266 1.1 rin } 267 1.1 rin 268 1.1 rin if (ri->ri_hwbits) { 269 1.1 rin memcpy(hp, rp, ((lmask != -1) + full + 270 1.1 rin (rmask != -1)) << 2); 271 1.3 rin DELTA(hp, ri->ri_stride, uint32_t *); 272 1.1 rin } 273 1.1 rin 274 1.3 rin DELTA(rp, ri->ri_stride, uint32_t *); 275 1.1 rin } 276 1.1 rin } 277 1.1 rin 278 1.1 rin /* Do underline */ 279 1.1 rin if ((attr & WSATTR_UNDERLINE) != 0) { 280 1.1 rin DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); 281 1.1 rin if (ri->ri_hwbits) 282 1.1 rin DELTA(hp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); 283 1.1 rin 284 1.1 rin for (height = ri->ri_ul.height; height; height--) { 285 1.1 rin DELTA(rp, - ri->ri_stride, uint32_t *); 286 1.1 rin bp = rp; 287 1.1 rin if (lmask != -1) { 288 1.1 rin *bp = (*bp & lmask) | (fg & ~lmask); 289 1.1 rin bp++; 290 1.1 rin } 291 1.1 rin for (cnt = full; cnt; cnt--) 292 1.1 rin *bp++ = fg; 293 1.1 rin if (rmask != -1) 294 1.1 rin *bp = (*bp & rmask) | (fg & ~rmask); 295 1.1 rin if (ri->ri_hwbits) { 296 1.1 rin DELTA(hp, - ri->ri_stride, uint32_t *); 297 1.1 rin memcpy(hp, rp, ((lmask != -1) + full + 298 1.1 rin (rmask != -1)) << 2); 299 1.1 rin } 300 1.1 rin } 301 1.1 rin } 302 1.1 rin } 303 1.1 rin 304 1.1 rin #undef PIXEL_BITS 305 1.1 rin #undef PIXEL_SHIFT 306 1.1 rin #undef COLOR_MASK 307 1.1 rin 308 1.1 rin #undef PIXEL_OR 309 1.1 rin 310 1.1 rin #undef NAME 311 1.1 rin #undef NAME1 312