rasops32.c revision 1.36 1 1.36 rin /* $NetBSD: rasops32.c,v 1.36 2019/07/25 15:12:47 rin Exp $ */
2 1.1 ad
3 1.4 ad /*-
4 1.4 ad * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 1.1 ad * All rights reserved.
6 1.1 ad *
7 1.4 ad * This code is derived from software contributed to The NetBSD Foundation
8 1.8 ad * by Andrew Doran.
9 1.4 ad *
10 1.1 ad * Redistribution and use in source and binary forms, with or without
11 1.1 ad * modification, are permitted provided that the following conditions
12 1.1 ad * are met:
13 1.1 ad * 1. Redistributions of source code must retain the above copyright
14 1.1 ad * notice, this list of conditions and the following disclaimer.
15 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 ad * notice, this list of conditions and the following disclaimer in the
17 1.1 ad * documentation and/or other materials provided with the distribution.
18 1.1 ad *
19 1.4 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.4 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.4 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.4 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.4 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.4 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.4 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.4 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.4 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.4 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.4 ad * POSSIBILITY OF SUCH DAMAGE.
30 1.1 ad */
31 1.2 ad
32 1.10 lukem #include <sys/cdefs.h>
33 1.36 rin __KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.36 2019/07/25 15:12:47 rin Exp $");
34 1.10 lukem
35 1.1 ad #include "opt_rasops.h"
36 1.1 ad
37 1.1 ad #include <sys/param.h>
38 1.1 ad #include <sys/systm.h>
39 1.1 ad #include <sys/time.h>
40 1.1 ad
41 1.1 ad #include <dev/wscons/wsdisplayvar.h>
42 1.1 ad #include <dev/wscons/wsconsio.h>
43 1.1 ad #include <dev/rasops/rasops.h>
44 1.1 ad
45 1.13 perry static void rasops32_putchar(void *, int, int, u_int, long attr);
46 1.23 macallan static void rasops32_putchar_aa(void *, int, int, u_int, long attr);
47 1.36 rin #ifndef RASOPS_SMALL
48 1.36 rin static void rasops32_putchar8(void *, int, int, u_int, long);
49 1.36 rin static void rasops32_putchar12(void *, int, int, u_int, long);
50 1.36 rin static void rasops32_putchar16(void *, int, int, u_int, long);
51 1.36 rin static void rasops32_makestamp(struct rasops_info *, long);
52 1.36 rin
53 1.36 rin /*
54 1.36 rin * 4x1 stamp for optimized character blitting
55 1.36 rin */
56 1.36 rin static uint32_t stamp[64];
57 1.36 rin static long stamp_attr;
58 1.36 rin static int stamp_mutex; /* XXX see note in readme */
59 1.36 rin #endif
60 1.36 rin
61 1.36 rin /*
62 1.36 rin * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
63 1.36 rin * destination uint32_t[0] = STAMP_READ(offset)
64 1.36 rin * destination uint32_t[1] = STAMP_READ(offset + 4)
65 1.36 rin * destination uint32_t[2] = STAMP_READ(offset + 8)
66 1.36 rin * destination uint32_t[3] = STAMP_READ(offset + 12)
67 1.36 rin */
68 1.36 rin #define STAMP_SHIFT(fb, n) ((n) ? (fb) : (fb) << 4)
69 1.36 rin #define STAMP_MASK (0xf << 4)
70 1.36 rin #define STAMP_READ(o) (*(uint32_t *)((char *)stamp + (o)))
71 1.3 ad
72 1.1 ad /*
73 1.9 wiz * Initialize a 'rasops_info' descriptor for this depth.
74 1.1 ad */
75 1.1 ad void
76 1.17 dsl rasops32_init(struct rasops_info *ri)
77 1.1 ad {
78 1.1 ad
79 1.3 ad if (ri->ri_rnum == 0) {
80 1.3 ad ri->ri_rnum = 8;
81 1.3 ad ri->ri_rpos = 0;
82 1.3 ad ri->ri_gnum = 8;
83 1.3 ad ri->ri_gpos = 8;
84 1.3 ad ri->ri_bnum = 8;
85 1.3 ad ri->ri_bpos = 16;
86 1.1 ad }
87 1.7 pk
88 1.27 martin if (FONT_IS_ALPHA(ri->ri_font)) {
89 1.27 martin ri->ri_ops.putchar = rasops32_putchar_aa;
90 1.36 rin return;
91 1.36 rin }
92 1.36 rin
93 1.36 rin switch (ri->ri_font->fontwidth) {
94 1.36 rin #ifndef RASOPS_SMALL
95 1.36 rin case 8:
96 1.36 rin ri->ri_ops.putchar = rasops32_putchar8;
97 1.36 rin break;
98 1.36 rin case 12:
99 1.36 rin ri->ri_ops.putchar = rasops32_putchar12;
100 1.36 rin break;
101 1.36 rin case 16:
102 1.36 rin ri->ri_ops.putchar = rasops32_putchar16;
103 1.36 rin break;
104 1.36 rin #endif
105 1.36 rin default:
106 1.23 macallan ri->ri_ops.putchar = rasops32_putchar;
107 1.36 rin break;
108 1.36 rin }
109 1.1 ad }
110 1.1 ad
111 1.1 ad /*
112 1.1 ad * Paint a single character.
113 1.1 ad */
114 1.23 macallan
115 1.1 ad static void
116 1.18 dsl rasops32_putchar(void *cookie, int row, int col, u_int uc, long attr)
117 1.1 ad {
118 1.5 ad int width, height, cnt, fs, fb, clr[2];
119 1.19 macallan struct rasops_info *ri = (struct rasops_info *)cookie;
120 1.19 macallan struct wsdisplay_font *font = PICK_FONT(ri, uc);
121 1.34 rin uint32_t *dp, *rp, *hp, *hrp;
122 1.33 rin uint8_t *fr;
123 1.7 pk
124 1.15 jmcneill hp = hrp = NULL;
125 1.1 ad
126 1.7 pk #ifdef RASOPS_CLIPPING
127 1.7 pk /* Catches 'row < 0' case too */
128 1.1 ad if ((unsigned)row >= (unsigned)ri->ri_rows)
129 1.1 ad return;
130 1.1 ad
131 1.1 ad if ((unsigned)col >= (unsigned)ri->ri_cols)
132 1.1 ad return;
133 1.1 ad #endif
134 1.12 petrov
135 1.12 petrov /* check if character fits into font limits */
136 1.24 macallan if (!CHAR_IN_FONT(uc, font))
137 1.24 macallan return;
138 1.7 pk
139 1.34 rin rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
140 1.15 jmcneill if (ri->ri_hwbits)
141 1.34 rin hrp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
142 1.15 jmcneill col*ri->ri_xscale);
143 1.1 ad
144 1.19 macallan height = font->fontheight;
145 1.19 macallan width = font->fontwidth;
146 1.3 ad
147 1.7 pk clr[0] = ri->ri_devcmap[(attr >> 16) & 0xf];
148 1.7 pk clr[1] = ri->ri_devcmap[(attr >> 24) & 0xf];
149 1.7 pk
150 1.1 ad if (uc == ' ') {
151 1.1 ad while (height--) {
152 1.1 ad dp = rp;
153 1.34 rin DELTA(rp, ri->ri_stride, uint32_t *);
154 1.15 jmcneill if (ri->ri_hwbits) {
155 1.15 jmcneill hp = hrp;
156 1.34 rin DELTA(hrp, ri->ri_stride, uint32_t *);
157 1.15 jmcneill }
158 1.1 ad
159 1.15 jmcneill for (cnt = width; cnt; cnt--) {
160 1.1 ad *dp++ = clr[0];
161 1.15 jmcneill if (ri->ri_hwbits)
162 1.15 jmcneill *hp++ = clr[0];
163 1.15 jmcneill }
164 1.1 ad }
165 1.1 ad } else {
166 1.35 rin fr = FONT_GLYPH(uc, font, ri);
167 1.19 macallan fs = font->stride;
168 1.1 ad
169 1.23 macallan while (height--) {
170 1.23 macallan dp = rp;
171 1.23 macallan fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
172 1.23 macallan (fr[0] << 24);
173 1.23 macallan fr += fs;
174 1.34 rin DELTA(rp, ri->ri_stride, uint32_t *);
175 1.23 macallan if (ri->ri_hwbits) {
176 1.23 macallan hp = hrp;
177 1.34 rin DELTA(hrp, ri->ri_stride, uint32_t *);
178 1.23 macallan }
179 1.23 macallan
180 1.23 macallan for (cnt = width; cnt; cnt--) {
181 1.23 macallan *dp++ = clr[(fb >> 31) & 1];
182 1.23 macallan if (ri->ri_hwbits)
183 1.23 macallan *hp++ = clr[(fb >> 31) & 1];
184 1.23 macallan fb <<= 1;
185 1.23 macallan }
186 1.23 macallan }
187 1.23 macallan }
188 1.23 macallan
189 1.23 macallan /* Do underline */
190 1.31 jakllsch if ((attr & WSATTR_UNDERLINE) != 0) {
191 1.34 rin DELTA(rp, -(ri->ri_stride << 1), uint32_t *);
192 1.23 macallan if (ri->ri_hwbits)
193 1.34 rin DELTA(hrp, -(ri->ri_stride << 1), uint32_t *);
194 1.23 macallan
195 1.23 macallan while (width--) {
196 1.23 macallan *rp++ = clr[1];
197 1.23 macallan if (ri->ri_hwbits)
198 1.23 macallan *hrp++ = clr[1];
199 1.23 macallan }
200 1.23 macallan }
201 1.23 macallan }
202 1.23 macallan
203 1.23 macallan static void
204 1.23 macallan rasops32_putchar_aa(void *cookie, int row, int col, u_int uc, long attr)
205 1.23 macallan {
206 1.29 martin int width, height, cnt, clr[2];
207 1.23 macallan struct rasops_info *ri = (struct rasops_info *)cookie;
208 1.23 macallan struct wsdisplay_font *font = PICK_FONT(ri, uc);
209 1.34 rin uint32_t *dp, *rp;
210 1.25 macallan uint8_t *rrp;
211 1.33 rin uint8_t *fr;
212 1.28 macallan uint32_t buffer[64]; /* XXX */
213 1.23 macallan int x, y, r, g, b, aval;
214 1.23 macallan int r1, g1, b1, r0, g0, b0;
215 1.23 macallan
216 1.23 macallan #ifdef RASOPS_CLIPPING
217 1.23 macallan /* Catches 'row < 0' case too */
218 1.23 macallan if ((unsigned)row >= (unsigned)ri->ri_rows)
219 1.23 macallan return;
220 1.23 macallan
221 1.23 macallan if ((unsigned)col >= (unsigned)ri->ri_cols)
222 1.23 macallan return;
223 1.23 macallan #endif
224 1.23 macallan
225 1.23 macallan /* check if character fits into font limits */
226 1.24 macallan if (!CHAR_IN_FONT(uc, font))
227 1.24 macallan return;
228 1.23 macallan
229 1.25 macallan rrp = (ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
230 1.34 rin rp = (uint32_t *)rrp;
231 1.23 macallan
232 1.23 macallan height = font->fontheight;
233 1.23 macallan width = font->fontwidth;
234 1.23 macallan
235 1.23 macallan clr[0] = ri->ri_devcmap[(attr >> 16) & 0xf];
236 1.23 macallan clr[1] = ri->ri_devcmap[(attr >> 24) & 0xf];
237 1.23 macallan
238 1.23 macallan if (uc == ' ') {
239 1.32 jakllsch for (cnt = 0; cnt < width; cnt++)
240 1.32 jakllsch buffer[cnt] = clr[0];
241 1.23 macallan while (height--) {
242 1.23 macallan dp = rp;
243 1.34 rin DELTA(rp, ri->ri_stride, uint32_t *);
244 1.28 macallan memcpy(dp, buffer, width << 2);
245 1.23 macallan }
246 1.23 macallan } else {
247 1.35 rin fr = FONT_GLYPH(uc, font, ri);
248 1.23 macallan
249 1.23 macallan r0 = (clr[0] >> 16) & 0xff;
250 1.23 macallan r1 = (clr[1] >> 16) & 0xff;
251 1.23 macallan g0 = (clr[0] >> 8) & 0xff;
252 1.23 macallan g1 = (clr[1] >> 8) & 0xff;
253 1.23 macallan b0 = clr[0] & 0xff;
254 1.23 macallan b1 = clr[1] & 0xff;
255 1.23 macallan
256 1.23 macallan for (y = 0; y < height; y++) {
257 1.25 macallan dp = (uint32_t *)(rrp + ri->ri_stride * y);
258 1.23 macallan for (x = 0; x < width; x++) {
259 1.23 macallan aval = *fr;
260 1.23 macallan if (aval == 0) {
261 1.28 macallan buffer[x] = clr[0];
262 1.23 macallan } else if (aval == 255) {
263 1.28 macallan buffer[x] = clr[1];
264 1.23 macallan } else {
265 1.23 macallan r = aval * r1 + (255 - aval) * r0;
266 1.23 macallan g = aval * g1 + (255 - aval) * g0;
267 1.23 macallan b = aval * b1 + (255 - aval) * b0;
268 1.32 jakllsch buffer[x] = (r & 0xff00) << 8 |
269 1.32 jakllsch (g & 0xff00) |
270 1.23 macallan (b & 0xff00) >> 8;
271 1.20 macallan }
272 1.23 macallan fr++;
273 1.1 ad }
274 1.28 macallan memcpy(dp, buffer, width << 2);
275 1.1 ad }
276 1.7 pk }
277 1.1 ad
278 1.1 ad /* Do underline */
279 1.31 jakllsch if ((attr & WSATTR_UNDERLINE) != 0) {
280 1.32 jakllsch rp = (uint32_t *)rrp;
281 1.30 jakllsch height = font->fontheight;
282 1.34 rin DELTA(rp, (ri->ri_stride * (height - 2)), uint32_t *);
283 1.28 macallan while (width--)
284 1.1 ad *rp++ = clr[1];
285 1.7 pk }
286 1.1 ad }
287 1.36 rin
288 1.36 rin #ifndef RASOPS_SMALL
289 1.36 rin /*
290 1.36 rin * Recompute the blitting stamp.
291 1.36 rin */
292 1.36 rin static void
293 1.36 rin rasops32_makestamp(struct rasops_info *ri, long attr)
294 1.36 rin {
295 1.36 rin uint32_t fg, bg;
296 1.36 rin int i;
297 1.36 rin
298 1.36 rin fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf];
299 1.36 rin bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf];
300 1.36 rin stamp_attr = attr;
301 1.36 rin
302 1.36 rin for (i = 0; i < 64; i += 4) {
303 1.36 rin stamp[i + 0] = (i & 32 ? fg : bg);
304 1.36 rin stamp[i + 1] = (i & 16 ? fg : bg);
305 1.36 rin stamp[i + 2] = (i & 8 ? fg : bg);
306 1.36 rin stamp[i + 3] = (i & 4 ? fg : bg);
307 1.36 rin }
308 1.36 rin }
309 1.36 rin
310 1.36 rin /*
311 1.36 rin * Put a single character. This is for 8-pixel wide fonts.
312 1.36 rin */
313 1.36 rin static void
314 1.36 rin rasops32_putchar8(void *cookie, int row, int col, u_int uc, long attr)
315 1.36 rin {
316 1.36 rin struct rasops_info *ri = (struct rasops_info *)cookie;
317 1.36 rin struct wsdisplay_font *font = PICK_FONT(ri, uc);
318 1.36 rin int height, so, fs;
319 1.36 rin uint32_t *rp, *hrp = NULL;
320 1.36 rin uint8_t *fr;
321 1.36 rin
322 1.36 rin hrp = NULL; /* XXX GCC */
323 1.36 rin
324 1.36 rin #ifdef RASOPS_CLIPPING
325 1.36 rin /* Catches 'row < 0' case too */
326 1.36 rin if ((unsigned)row >= (unsigned)ri->ri_rows)
327 1.36 rin return;
328 1.36 rin
329 1.36 rin if ((unsigned)col >= (unsigned)ri->ri_cols)
330 1.36 rin return;
331 1.36 rin #endif
332 1.36 rin
333 1.36 rin /* check if character fits into font limits */
334 1.36 rin if (!CHAR_IN_FONT(uc, font))
335 1.36 rin return;
336 1.36 rin
337 1.36 rin /* Can't risk remaking the stamp if it's already in use */
338 1.36 rin if (stamp_mutex++) {
339 1.36 rin stamp_mutex--;
340 1.36 rin rasops32_putchar(cookie, row, col, uc, attr);
341 1.36 rin return;
342 1.36 rin }
343 1.36 rin
344 1.36 rin /* Recompute stamp? */
345 1.36 rin if (attr != stamp_attr)
346 1.36 rin rasops32_makestamp(ri, attr);
347 1.36 rin
348 1.36 rin rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
349 1.36 rin if (ri->ri_hwbits)
350 1.36 rin hrp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
351 1.36 rin col*ri->ri_xscale);
352 1.36 rin
353 1.36 rin height = font->fontheight;
354 1.36 rin
355 1.36 rin if (uc == ' ') {
356 1.36 rin while (height--) {
357 1.36 rin rp[0] = rp[1] = rp[2] = rp[3] =
358 1.36 rin rp[4] = rp[5] = rp[6] = rp[7] = stamp[0];
359 1.36 rin DELTA(rp, ri->ri_stride, uint32_t *);
360 1.36 rin if (ri->ri_hwbits) {
361 1.36 rin hrp[0] = hrp[1] = hrp[2] = hrp[3] =
362 1.36 rin hrp[4] = hrp[5] = hrp[6] = hrp[7] = stamp[0];
363 1.36 rin DELTA(hrp, ri->ri_stride, uint32_t *);
364 1.36 rin }
365 1.36 rin }
366 1.36 rin } else {
367 1.36 rin fr = FONT_GLYPH(uc, font, ri);
368 1.36 rin fs = font->stride;
369 1.36 rin
370 1.36 rin while (height--) {
371 1.36 rin uint32_t tmp0, tmp1, tmp2, tmp3;
372 1.36 rin
373 1.36 rin so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
374 1.36 rin tmp0 = STAMP_READ(so);
375 1.36 rin tmp1 = STAMP_READ(so + 4);
376 1.36 rin tmp2 = STAMP_READ(so + 8);
377 1.36 rin tmp3 = STAMP_READ(so + 12);
378 1.36 rin rp[0] = tmp0;
379 1.36 rin rp[1] = tmp1;
380 1.36 rin rp[2] = tmp2;
381 1.36 rin rp[3] = tmp3;
382 1.36 rin if (ri->ri_hwbits) {
383 1.36 rin hrp[0] = tmp0;
384 1.36 rin hrp[1] = tmp1;
385 1.36 rin hrp[2] = tmp2;
386 1.36 rin hrp[3] = tmp3;
387 1.36 rin }
388 1.36 rin
389 1.36 rin so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
390 1.36 rin tmp0 = STAMP_READ(so);
391 1.36 rin tmp1 = STAMP_READ(so + 4);
392 1.36 rin tmp2 = STAMP_READ(so + 8);
393 1.36 rin tmp3 = STAMP_READ(so + 12);
394 1.36 rin rp[4] = tmp0;
395 1.36 rin rp[5] = tmp1;
396 1.36 rin rp[6] = tmp2;
397 1.36 rin rp[7] = tmp3;
398 1.36 rin if (ri->ri_hwbits) {
399 1.36 rin hrp[4] = tmp0;
400 1.36 rin hrp[5] = tmp1;
401 1.36 rin hrp[6] = tmp2;
402 1.36 rin hrp[7] = tmp3;
403 1.36 rin }
404 1.36 rin
405 1.36 rin fr += fs;
406 1.36 rin DELTA(rp, ri->ri_stride, uint32_t *);
407 1.36 rin if (ri->ri_hwbits)
408 1.36 rin DELTA(hrp, ri->ri_stride, uint32_t *);
409 1.36 rin }
410 1.36 rin }
411 1.36 rin
412 1.36 rin /* Do underline */
413 1.36 rin if ((attr & WSATTR_UNDERLINE) != 0) {
414 1.36 rin DELTA(rp, -(ri->ri_stride << 1), uint32_t *);
415 1.36 rin rp[0] = rp[1] = rp[2] = rp[3] =
416 1.36 rin rp[4] = rp[5] = rp[6] = rp[7] = stamp[60];
417 1.36 rin if (ri->ri_hwbits)
418 1.36 rin hrp[0] = hrp[1] = hrp[2] = hrp[3] =
419 1.36 rin hrp[4] = hrp[5] = hrp[6] = hrp[7] = stamp[60];
420 1.36 rin }
421 1.36 rin
422 1.36 rin stamp_mutex--;
423 1.36 rin }
424 1.36 rin
425 1.36 rin /*
426 1.36 rin * Put a single character. This is for 12-pixel wide fonts.
427 1.36 rin */
428 1.36 rin static void
429 1.36 rin rasops32_putchar12(void *cookie, int row, int col, u_int uc, long attr)
430 1.36 rin {
431 1.36 rin struct rasops_info *ri = (struct rasops_info *)cookie;
432 1.36 rin struct wsdisplay_font *font = PICK_FONT(ri, uc);
433 1.36 rin int height, so, fs;
434 1.36 rin uint32_t *rp, *hrp = NULL;
435 1.36 rin uint8_t *fr;
436 1.36 rin
437 1.36 rin hrp = NULL; /* XXX GCC */
438 1.36 rin
439 1.36 rin #ifdef RASOPS_CLIPPING
440 1.36 rin /* Catches 'row < 0' case too */
441 1.36 rin if ((unsigned)row >= (unsigned)ri->ri_rows)
442 1.36 rin return;
443 1.36 rin
444 1.36 rin if ((unsigned)col >= (unsigned)ri->ri_cols)
445 1.36 rin return;
446 1.36 rin #endif
447 1.36 rin
448 1.36 rin /* check if character fits into font limits */
449 1.36 rin if (!CHAR_IN_FONT(uc, font))
450 1.36 rin return;
451 1.36 rin
452 1.36 rin /* Can't risk remaking the stamp if it's already in use */
453 1.36 rin if (stamp_mutex++) {
454 1.36 rin stamp_mutex--;
455 1.36 rin rasops32_putchar(cookie, row, col, uc, attr);
456 1.36 rin return;
457 1.36 rin }
458 1.36 rin
459 1.36 rin /* Recompute stamp? */
460 1.36 rin if (attr != stamp_attr)
461 1.36 rin rasops32_makestamp(ri, attr);
462 1.36 rin
463 1.36 rin rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
464 1.36 rin if (ri->ri_hwbits)
465 1.36 rin hrp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
466 1.36 rin col*ri->ri_xscale);
467 1.36 rin
468 1.36 rin height = font->fontheight;
469 1.36 rin
470 1.36 rin if (uc == ' ') {
471 1.36 rin while (height--) {
472 1.36 rin rp[0] = rp[1] = rp[2] = rp[3] =
473 1.36 rin rp[4] = rp[5] = rp[6] = rp[7] =
474 1.36 rin rp[8] = rp[9] = rp[10] = rp[11] = stamp[0];
475 1.36 rin DELTA(rp, ri->ri_stride, uint32_t *);
476 1.36 rin if (ri->ri_hwbits) {
477 1.36 rin hrp[0] = hrp[1] = hrp[2] = hrp[3] =
478 1.36 rin hrp[4] = hrp[5] = hrp[6] = hrp[7] =
479 1.36 rin hrp[8] = hrp[9] = hrp[10] = hrp[11] =
480 1.36 rin stamp[0];
481 1.36 rin DELTA(hrp, ri->ri_stride, uint32_t *);
482 1.36 rin }
483 1.36 rin }
484 1.36 rin } else {
485 1.36 rin fr = FONT_GLYPH(uc, font, ri);
486 1.36 rin fs = font->stride;
487 1.36 rin
488 1.36 rin while (height--) {
489 1.36 rin uint32_t tmp0, tmp1, tmp2, tmp3;
490 1.36 rin
491 1.36 rin so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
492 1.36 rin tmp0 = STAMP_READ(so);
493 1.36 rin tmp1 = STAMP_READ(so + 4);
494 1.36 rin tmp2 = STAMP_READ(so + 8);
495 1.36 rin tmp3 = STAMP_READ(so + 12);
496 1.36 rin rp[0] = tmp0;
497 1.36 rin rp[1] = tmp1;
498 1.36 rin rp[2] = tmp2;
499 1.36 rin rp[3] = tmp3;
500 1.36 rin if (ri->ri_hwbits) {
501 1.36 rin hrp[0] = tmp0;
502 1.36 rin hrp[1] = tmp1;
503 1.36 rin hrp[2] = tmp2;
504 1.36 rin hrp[3] = tmp3;
505 1.36 rin }
506 1.36 rin
507 1.36 rin so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
508 1.36 rin tmp0 = STAMP_READ(so);
509 1.36 rin tmp1 = STAMP_READ(so + 4);
510 1.36 rin tmp2 = STAMP_READ(so + 8);
511 1.36 rin tmp3 = STAMP_READ(so + 12);
512 1.36 rin rp[4] = tmp0;
513 1.36 rin rp[5] = tmp1;
514 1.36 rin rp[6] = tmp2;
515 1.36 rin rp[7] = tmp3;
516 1.36 rin if (ri->ri_hwbits) {
517 1.36 rin hrp[4] = tmp0;
518 1.36 rin hrp[5] = tmp1;
519 1.36 rin hrp[6] = tmp2;
520 1.36 rin hrp[7] = tmp3;
521 1.36 rin }
522 1.36 rin
523 1.36 rin so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
524 1.36 rin tmp0 = STAMP_READ(so);
525 1.36 rin tmp1 = STAMP_READ(so + 4);
526 1.36 rin tmp2 = STAMP_READ(so + 8);
527 1.36 rin tmp3 = STAMP_READ(so + 12);
528 1.36 rin rp[8] = tmp0;
529 1.36 rin rp[9] = tmp1;
530 1.36 rin rp[10] = tmp2;
531 1.36 rin rp[11] = tmp3;
532 1.36 rin if (ri->ri_hwbits) {
533 1.36 rin hrp[8] = tmp0;
534 1.36 rin hrp[9] = tmp1;
535 1.36 rin hrp[10] = tmp2;
536 1.36 rin hrp[11] = tmp3;
537 1.36 rin }
538 1.36 rin
539 1.36 rin fr += fs;
540 1.36 rin DELTA(rp, ri->ri_stride, uint32_t *);
541 1.36 rin if (ri->ri_hwbits)
542 1.36 rin DELTA(hrp, ri->ri_stride, uint32_t *);
543 1.36 rin }
544 1.36 rin }
545 1.36 rin
546 1.36 rin /* Do underline */
547 1.36 rin if ((attr & WSATTR_UNDERLINE) != 0) {
548 1.36 rin DELTA(rp, -(ri->ri_stride << 1), uint32_t *);
549 1.36 rin rp[0] = rp[1] = rp[2] = rp[3] =
550 1.36 rin rp[4] = rp[5] = rp[6] = rp[7] =
551 1.36 rin rp[8] = rp[9] = rp[10] = rp[11] = stamp[60];
552 1.36 rin if (ri->ri_hwbits)
553 1.36 rin hrp[0] = hrp[1] = hrp[2] = hrp[3] =
554 1.36 rin hrp[4] = hrp[5] = hrp[6] = hrp[7] =
555 1.36 rin hrp[8] = hrp[9] = hrp[10] = hrp[11] = stamp[60];
556 1.36 rin }
557 1.36 rin
558 1.36 rin stamp_mutex--;
559 1.36 rin }
560 1.36 rin
561 1.36 rin /*
562 1.36 rin * Put a single character. This is for 16-pixel wide fonts.
563 1.36 rin */
564 1.36 rin static void
565 1.36 rin rasops32_putchar16(void *cookie, int row, int col, u_int uc, long attr)
566 1.36 rin {
567 1.36 rin struct rasops_info *ri = (struct rasops_info *)cookie;
568 1.36 rin struct wsdisplay_font *font = PICK_FONT(ri, uc);
569 1.36 rin int height, so, fs;
570 1.36 rin uint32_t *rp, *hrp = NULL;
571 1.36 rin uint8_t *fr;
572 1.36 rin
573 1.36 rin hrp = NULL; /* XXX GCC */
574 1.36 rin
575 1.36 rin #ifdef RASOPS_CLIPPING
576 1.36 rin /* Catches 'row < 0' case too */
577 1.36 rin if ((unsigned)row >= (unsigned)ri->ri_rows)
578 1.36 rin return;
579 1.36 rin
580 1.36 rin if ((unsigned)col >= (unsigned)ri->ri_cols)
581 1.36 rin return;
582 1.36 rin #endif
583 1.36 rin
584 1.36 rin /* check if character fits into font limits */
585 1.36 rin if (!CHAR_IN_FONT(uc, font))
586 1.36 rin return;
587 1.36 rin
588 1.36 rin /* Can't risk remaking the stamp if it's already in use */
589 1.36 rin if (stamp_mutex++) {
590 1.36 rin stamp_mutex--;
591 1.36 rin rasops32_putchar(cookie, row, col, uc, attr);
592 1.36 rin return;
593 1.36 rin }
594 1.36 rin
595 1.36 rin /* Recompute stamp? */
596 1.36 rin if (attr != stamp_attr)
597 1.36 rin rasops32_makestamp(ri, attr);
598 1.36 rin
599 1.36 rin rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
600 1.36 rin if (ri->ri_hwbits)
601 1.36 rin hrp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
602 1.36 rin col*ri->ri_xscale);
603 1.36 rin
604 1.36 rin height = font->fontheight;
605 1.36 rin
606 1.36 rin if (uc == ' ') {
607 1.36 rin while (height--) {
608 1.36 rin rp[0] = rp[1] = rp[2] = rp[3] =
609 1.36 rin rp[4] = rp[5] = rp[6] = rp[7] =
610 1.36 rin rp[8] = rp[9] = rp[10] = rp[11] =
611 1.36 rin rp[12] = rp[13] = rp[14] = rp[15] = stamp[0];
612 1.36 rin DELTA(rp, ri->ri_stride, uint32_t *);
613 1.36 rin if (ri->ri_hwbits) {
614 1.36 rin hrp[0] = hrp[1] = hrp[2] = hrp[3] =
615 1.36 rin hrp[4] = hrp[5] = hrp[6] = hrp[7] =
616 1.36 rin hrp[8] = hrp[9] = hrp[10] = hrp[11] =
617 1.36 rin hrp[12] = hrp[13] = hrp[14] = hrp[15] =
618 1.36 rin stamp[0];
619 1.36 rin DELTA(hrp, ri->ri_stride, uint32_t *);
620 1.36 rin }
621 1.36 rin }
622 1.36 rin } else {
623 1.36 rin fr = FONT_GLYPH(uc, font, ri);
624 1.36 rin fs = font->stride;
625 1.36 rin
626 1.36 rin while (height--) {
627 1.36 rin uint32_t tmp0, tmp1, tmp2, tmp3;
628 1.36 rin
629 1.36 rin so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
630 1.36 rin tmp0 = STAMP_READ(so);
631 1.36 rin tmp1 = STAMP_READ(so + 4);
632 1.36 rin tmp2 = STAMP_READ(so + 8);
633 1.36 rin tmp3 = STAMP_READ(so + 12);
634 1.36 rin rp[0] = tmp0;
635 1.36 rin rp[1] = tmp1;
636 1.36 rin rp[2] = tmp2;
637 1.36 rin rp[3] = tmp3;
638 1.36 rin if (ri->ri_hwbits) {
639 1.36 rin hrp[0] = tmp0;
640 1.36 rin hrp[1] = tmp1;
641 1.36 rin hrp[2] = tmp2;
642 1.36 rin hrp[3] = tmp3;
643 1.36 rin }
644 1.36 rin
645 1.36 rin so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
646 1.36 rin tmp0 = STAMP_READ(so);
647 1.36 rin tmp1 = STAMP_READ(so + 4);
648 1.36 rin tmp2 = STAMP_READ(so + 8);
649 1.36 rin tmp3 = STAMP_READ(so + 12);
650 1.36 rin rp[4] = tmp0;
651 1.36 rin rp[5] = tmp1;
652 1.36 rin rp[6] = tmp2;
653 1.36 rin rp[7] = tmp3;
654 1.36 rin if (ri->ri_hwbits) {
655 1.36 rin hrp[4] = tmp0;
656 1.36 rin hrp[5] = tmp1;
657 1.36 rin hrp[6] = tmp2;
658 1.36 rin hrp[7] = tmp3;
659 1.36 rin }
660 1.36 rin
661 1.36 rin so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
662 1.36 rin tmp0 = STAMP_READ(so);
663 1.36 rin tmp1 = STAMP_READ(so + 4);
664 1.36 rin tmp2 = STAMP_READ(so + 8);
665 1.36 rin tmp3 = STAMP_READ(so + 12);
666 1.36 rin rp[8] = tmp0;
667 1.36 rin rp[9] = tmp1;
668 1.36 rin rp[10] = tmp2;
669 1.36 rin rp[11] = tmp3;
670 1.36 rin if (ri->ri_hwbits) {
671 1.36 rin hrp[8] = tmp0;
672 1.36 rin hrp[9] = tmp1;
673 1.36 rin hrp[10] = tmp2;
674 1.36 rin hrp[11] = tmp3;
675 1.36 rin }
676 1.36 rin
677 1.36 rin so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
678 1.36 rin tmp0 = STAMP_READ(so);
679 1.36 rin tmp1 = STAMP_READ(so + 4);
680 1.36 rin tmp2 = STAMP_READ(so + 8);
681 1.36 rin tmp3 = STAMP_READ(so + 12);
682 1.36 rin rp[12] = tmp0;
683 1.36 rin rp[13] = tmp1;
684 1.36 rin rp[14] = tmp2;
685 1.36 rin rp[15] = tmp3;
686 1.36 rin if (ri->ri_hwbits) {
687 1.36 rin hrp[12] = tmp0;
688 1.36 rin hrp[13] = tmp1;
689 1.36 rin hrp[14] = tmp2;
690 1.36 rin hrp[15] = tmp3;
691 1.36 rin }
692 1.36 rin
693 1.36 rin fr += fs;
694 1.36 rin DELTA(rp, ri->ri_stride, uint32_t *);
695 1.36 rin if (ri->ri_hwbits)
696 1.36 rin DELTA(hrp, ri->ri_stride, uint32_t *);
697 1.36 rin }
698 1.36 rin }
699 1.36 rin
700 1.36 rin /* Do underline */
701 1.36 rin if ((attr & WSATTR_UNDERLINE) != 0) {
702 1.36 rin DELTA(rp, -(ri->ri_stride << 1), uint32_t *);
703 1.36 rin rp[0] = rp[1] = rp[2] = rp[3] =
704 1.36 rin rp[4] = rp[5] = rp[6] = rp[7] =
705 1.36 rin rp[8] = rp[9] = rp[10] = rp[11] =
706 1.36 rin rp[12] = rp[13] = rp[14] = rp[15] = stamp[60];
707 1.36 rin if (ri->ri_hwbits)
708 1.36 rin hrp[0] = hrp[1] = hrp[2] = hrp[3] =
709 1.36 rin hrp[4] = hrp[5] = hrp[6] = hrp[7] =
710 1.36 rin hrp[8] = hrp[9] = hrp[10] = hrp[11] =
711 1.36 rin hrp[12] = hrp[13] = hrp[14] = hrp[15] = stamp[60];
712 1.36 rin }
713 1.36 rin
714 1.36 rin stamp_mutex--;
715 1.36 rin }
716 1.36 rin #endif
717