1/* $OpenBSD: rasops32.c,v 1.13 2023/01/18 11:08:49 nicm Exp $ */ 2/* $NetBSD: rasops32.c,v 1.7 2000/04/12 14:22:29 pk Exp $ */ 3 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#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/time.h> 36 37#include <dev/wscons/wsdisplayvar.h> 38#include <dev/wscons/wsconsio.h> 39#include <dev/rasops/rasops.h> 40 41int rasops32_putchar(void *, int, int, u_int, uint32_t); 42 43/* 44 * Initialize a 'rasops_info' descriptor for this depth. 45 */ 46void 47rasops32_init(struct rasops_info *ri) 48{ 49 if (ri->ri_rnum == 0) { 50 ri->ri_rnum = 8; 51 ri->ri_rpos = 0; 52 ri->ri_gnum = 8; 53 ri->ri_gpos = 8; 54 ri->ri_bnum = 8; 55 ri->ri_bpos = 16; 56 } 57 58 ri->ri_ops.putchar = rasops32_putchar; 59} 60 61/* 62 * Paint a single character. 63 */ 64int 65rasops32_putchar(void *cookie, int row, int col, u_int uc, uint32_t attr) 66{ 67 int width, height, step, cnt, fs, b, f; 68 uint32_t fb, clr[2]; 69 struct rasops_info *ri; 70 int64_t *rp; 71 union { 72 int64_t q[4]; 73 int32_t d[4][2]; 74 } u; 75 u_char *fr; 76 77 ri = (struct rasops_info *)cookie; 78 79#ifdef RASOPS_CLIPPING 80 /* Catches 'row < 0' case too */ 81 if ((unsigned)row >= (unsigned)ri->ri_rows) 82 return 0; 83 84 if ((unsigned)col >= (unsigned)ri->ri_cols) 85 return 0; 86#endif 87 88 rp = (int64_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 89 90 height = ri->ri_font->fontheight; 91 width = ri->ri_font->fontwidth; 92 step = ri->ri_stride >> 3; 93 94 b = ri->ri_devcmap[(attr >> 16) & 0xf]; 95 f = ri->ri_devcmap[(attr >> 24) & 0xf]; 96 u.d[0][0] = b; u.d[0][1] = b; 97 u.d[1][0] = b; u.d[1][1] = f; 98 u.d[2][0] = f; u.d[2][1] = b; 99 u.d[3][0] = f; u.d[3][1] = f; 100 101 if (uc == ' ') { 102 while (height--) { 103 /* the general, pixel-at-a-time case is fast enough */ 104 for (cnt = 0; cnt < width; cnt++) 105 ((int *)rp)[cnt] = b; 106 rp += step; 107 } 108 } else { 109 uc -= ri->ri_font->firstchar; 110 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; 111 fs = ri->ri_font->stride; 112 113 /* double-pixel special cases for the common widths */ 114 switch (width) { 115 case 8: 116 while (height--) { 117 fb = fr[0]; 118 rp[0] = u.q[fb >> 6]; 119 rp[1] = u.q[(fb >> 4) & 3]; 120 rp[2] = u.q[(fb >> 2) & 3]; 121 rp[3] = u.q[fb & 3]; 122 rp += step; 123 fr += 1; 124 } 125 break; 126 127 case 12: 128 while (height--) { 129 fb = fr[0]; 130 rp[0] = u.q[fb >> 6]; 131 rp[1] = u.q[(fb >> 4) & 3]; 132 rp[2] = u.q[(fb >> 2) & 3]; 133 rp[3] = u.q[fb & 3]; 134 fb = fr[1]; 135 rp[4] = u.q[fb >> 6]; 136 rp[5] = u.q[(fb >> 4) & 3]; 137 rp += step; 138 fr += 2; 139 } 140 break; 141 142 case 16: 143 while (height--) { 144 fb = fr[0]; 145 rp[0] = u.q[fb >> 6]; 146 rp[1] = u.q[(fb >> 4) & 3]; 147 rp[2] = u.q[(fb >> 2) & 3]; 148 rp[3] = u.q[fb & 3]; 149 fb = fr[1]; 150 rp[4] = u.q[fb >> 6]; 151 rp[5] = u.q[(fb >> 4) & 3]; 152 rp[6] = u.q[(fb >> 2) & 3]; 153 rp[7] = u.q[fb & 3]; 154 rp += step; 155 fr += 2; 156 } 157 break; 158 159 case 32: 160 while (height--) { 161 fb = fr[0]; 162 rp[0] = u.q[fb >> 6]; 163 rp[1] = u.q[(fb >> 4) & 3]; 164 rp[2] = u.q[(fb >> 2) & 3]; 165 rp[3] = u.q[fb & 3]; 166 fb = fr[1]; 167 rp[4] = u.q[fb >> 6]; 168 rp[5] = u.q[(fb >> 4) & 3]; 169 rp[6] = u.q[(fb >> 2) & 3]; 170 rp[7] = u.q[fb & 3]; 171 fb = fr[2]; 172 rp[8] = u.q[fb >> 6]; 173 rp[9] = u.q[(fb >> 4) & 3]; 174 rp[10] = u.q[(fb >> 2) & 3]; 175 rp[11] = u.q[fb & 3]; 176 fb = fr[3]; 177 rp[12] = u.q[fb >> 6]; 178 rp[13] = u.q[(fb >> 4) & 3]; 179 rp[14] = u.q[(fb >> 2) & 3]; 180 rp[15] = u.q[fb & 3]; 181 rp += step; 182 fr += 4; 183 } 184 break; 185 186 default: /* there is a 5x8 font, so fall back to per-pixel */ 187 clr[0] = b; 188 clr[1] = f; 189 190 while (height--) { 191 fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | 192 (fr[0] << 24); 193 fr += fs; 194 195 for (cnt = 0; cnt < width; cnt++) { 196 ((int *)rp)[cnt] = clr[fb >> 31]; 197 fb <<= 1; 198 } 199 rp += step; 200 } 201 break; 202 } 203 } 204 205 /* Do underline a pixel at a time */ 206 if ((attr & WSATTR_UNDERLINE) != 0) { 207 rp -= step; 208 for (cnt = 0; cnt < width; cnt++) 209 ((int *)rp)[cnt] = f; 210 } 211 212 return 0; 213} 214