jcs's openbsd hax
openbsd
1/* $OpenBSD: rasops32.c,v 1.14 2024/07/21 13:18:15 fcambus 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 6:
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 += step;
122 fr += 1;
123 }
124 break;
125
126 case 8:
127 while (height--) {
128 fb = fr[0];
129 rp[0] = u.q[fb >> 6];
130 rp[1] = u.q[(fb >> 4) & 3];
131 rp[2] = u.q[(fb >> 2) & 3];
132 rp[3] = u.q[fb & 3];
133 rp += step;
134 fr += 1;
135 }
136 break;
137
138 case 12:
139 while (height--) {
140 fb = fr[0];
141 rp[0] = u.q[fb >> 6];
142 rp[1] = u.q[(fb >> 4) & 3];
143 rp[2] = u.q[(fb >> 2) & 3];
144 rp[3] = u.q[fb & 3];
145 fb = fr[1];
146 rp[4] = u.q[fb >> 6];
147 rp[5] = u.q[(fb >> 4) & 3];
148 rp += step;
149 fr += 2;
150 }
151 break;
152
153 case 16:
154 while (height--) {
155 fb = fr[0];
156 rp[0] = u.q[fb >> 6];
157 rp[1] = u.q[(fb >> 4) & 3];
158 rp[2] = u.q[(fb >> 2) & 3];
159 rp[3] = u.q[fb & 3];
160 fb = fr[1];
161 rp[4] = u.q[fb >> 6];
162 rp[5] = u.q[(fb >> 4) & 3];
163 rp[6] = u.q[(fb >> 2) & 3];
164 rp[7] = u.q[fb & 3];
165 rp += step;
166 fr += 2;
167 }
168 break;
169
170 case 32:
171 while (height--) {
172 fb = fr[0];
173 rp[0] = u.q[fb >> 6];
174 rp[1] = u.q[(fb >> 4) & 3];
175 rp[2] = u.q[(fb >> 2) & 3];
176 rp[3] = u.q[fb & 3];
177 fb = fr[1];
178 rp[4] = u.q[fb >> 6];
179 rp[5] = u.q[(fb >> 4) & 3];
180 rp[6] = u.q[(fb >> 2) & 3];
181 rp[7] = u.q[fb & 3];
182 fb = fr[2];
183 rp[8] = u.q[fb >> 6];
184 rp[9] = u.q[(fb >> 4) & 3];
185 rp[10] = u.q[(fb >> 2) & 3];
186 rp[11] = u.q[fb & 3];
187 fb = fr[3];
188 rp[12] = u.q[fb >> 6];
189 rp[13] = u.q[(fb >> 4) & 3];
190 rp[14] = u.q[(fb >> 2) & 3];
191 rp[15] = u.q[fb & 3];
192 rp += step;
193 fr += 4;
194 }
195 break;
196
197 default: /* there is a 5x8 font, so fall back to per-pixel */
198 clr[0] = b;
199 clr[1] = f;
200
201 while (height--) {
202 fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
203 (fr[0] << 24);
204 fr += fs;
205
206 for (cnt = 0; cnt < width; cnt++) {
207 ((int *)rp)[cnt] = clr[fb >> 31];
208 fb <<= 1;
209 }
210 rp += step;
211 }
212 break;
213 }
214 }
215
216 /* Do underline a pixel at a time */
217 if ((attr & WSATTR_UNDERLINE) != 0) {
218 rp -= step;
219 for (cnt = 0; cnt < width; cnt++)
220 ((int *)rp)[cnt] = f;
221 }
222
223 return 0;
224}