1 /* $NetBSD: rasops1_putchar_width.h,v 1.6 2019/08/10 01:24:17 rin Exp $ */ 2 3 /* NetBSD: rasops1.c,v 1.28 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_WIDTH != 8 && RASOPS_WIDTH != 16 34 #error "Width not supported" 35 #endif 36 37 #if RASOPS_WIDTH == 8 38 #define SUBST_UNIT uint8_t 39 #define GET_GLYPH(fr) (fr)[0] 40 #endif 41 42 #if RASOPS_WIDTH == 16 43 /* 44 * rp and hp are always half-word aligned, whereas 45 * fr may not be aligned in half-word boundary. 46 */ 47 #define SUBST_UNIT uint16_t 48 # if BYTE_ORDER == BIG_ENDIAN 49 #define GET_GLYPH(fr) ((fr)[0] << 8) | (fr)[1] 50 # else 51 #define GET_GLYPH(fr) (fr)[0] | ((fr)[1] << 8) 52 # endif 53 #endif /* RASOPS_WIDTH == 16 */ 54 55 #define NAME(width) NAME1(width) 56 #define NAME1(width) rasops1_putchar ## width 57 58 /* 59 * Width-optimized putchar function. 60 */ 61 static void 62 NAME(RASOPS_WIDTH)(void *cookie, int row, int col, u_int uc, long attr) 63 { 64 struct rasops_info *ri = (struct rasops_info *)cookie; 65 struct wsdisplay_font *font = PICK_FONT(ri, uc); 66 int height; 67 uint32_t bg, fg; 68 uint8_t *fr; 69 SUBST_UNIT tmp, *rp, *hp; 70 71 hp = NULL; /* XXX GCC */ 72 73 if (__predict_false(!CHAR_IN_FONT(uc, font))) 74 return; 75 76 #ifdef RASOPS_CLIPPING 77 /* Catches 'row < 0' case too */ 78 if ((unsigned)row >= (unsigned)ri->ri_rows) 79 return; 80 81 if ((unsigned)col >= (unsigned)ri->ri_cols) 82 return; 83 #endif 84 85 height = font->fontheight; 86 87 rp = (SUBST_UNIT *)(ri->ri_bits + row * ri->ri_yscale + 88 col * sizeof(SUBST_UNIT)); 89 if (ri->ri_hwbits) 90 hp = (SUBST_UNIT *)(ri->ri_hwbits + row * ri->ri_yscale + 91 col * sizeof(SUBST_UNIT)); 92 93 bg = ATTR_BG(ri, attr); 94 fg = ATTR_FG(ri, attr); 95 96 /* If fg and bg match this becomes a space character */ 97 if (uc == ' ' || __predict_false(fg == bg)) { 98 while (height--) { 99 *rp = bg; 100 if (ri->ri_hwbits) { 101 *hp = bg; 102 DELTA(hp, ri->ri_stride, SUBST_UNIT *); 103 } 104 DELTA(rp, ri->ri_stride, SUBST_UNIT *); 105 } 106 } else { 107 fr = FONT_GLYPH(uc, font, ri); 108 109 while (height--) { 110 tmp = GET_GLYPH(fr); 111 fr += font->stride; 112 if (bg) 113 tmp = ~tmp; 114 115 *rp = tmp; 116 117 if (ri->ri_hwbits) { 118 *hp = tmp; 119 DELTA(hp, ri->ri_stride, SUBST_UNIT *); 120 } 121 122 DELTA(rp, ri->ri_stride, SUBST_UNIT *); 123 } 124 } 125 126 /* Do underline */ 127 if ((attr & WSATTR_UNDERLINE) != 0) { 128 DELTA(rp, - ri->ri_stride * ri->ri_ul.off, SUBST_UNIT *); 129 if (ri->ri_hwbits) 130 DELTA(hp, - ri->ri_stride * ri->ri_ul.off, 131 SUBST_UNIT *); 132 133 for (height = ri->ri_ul.height; height; height--) { 134 DELTA(rp, - ri->ri_stride, SUBST_UNIT *); 135 *rp = fg; 136 if (ri->ri_hwbits) { 137 DELTA(hp, - ri->ri_stride, SUBST_UNIT *); 138 *hp = fg; 139 } 140 } 141 } 142 } 143 144 #undef SUBST_UNIT 145 #undef GET_GLYPH 146 147 #undef NAME 148 #undef NAME1 149