Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / rasops / rasops8.c
blob20f33f7c6f4b76a2e4b82302cf3ec1ac97d23cbc
1 /* $NetBSD: rasops8.c,v 1.25 2009/03/14 15:36:20 dsl Exp $ */
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.25 2009/03/14 15:36:20 dsl Exp $");
35 #include "opt_rasops.h"
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/time.h>
41 #include <dev/wscons/wsdisplayvar.h>
42 #include <dev/wscons/wsconsio.h>
43 #include <dev/rasops/rasops.h>
45 static void rasops8_putchar(void *, int, int, u_int, long attr);
46 #ifndef RASOPS_SMALL
47 static void rasops8_putchar8(void *, int, int, u_int, long attr);
48 static void rasops8_putchar12(void *, int, int, u_int, long attr);
49 static void rasops8_putchar16(void *, int, int, u_int, long attr);
50 static void rasops8_makestamp(struct rasops_info *ri, long);
53 * 4x1 stamp for optimized character blitting
55 static int32_t stamp[16];
56 static long stamp_attr;
57 static int stamp_mutex; /* XXX see note in README */
58 #endif
61 * XXX this confuses the hell out of gcc2 (not egcs) which always insists
62 * that the shift count is negative.
64 * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
65 * destination = STAMP_READ(offset)
67 #define STAMP_SHIFT(fb,n) ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
68 #define STAMP_MASK (0xf << 2)
69 #define STAMP_READ(o) (*(int32_t *)((char *)stamp + (o)))
72 * Initialize a 'rasops_info' descriptor for this depth.
74 void
75 rasops8_init(struct rasops_info *ri)
78 switch (ri->ri_font->fontwidth) {
79 #ifndef RASOPS_SMALL
80 case 8:
81 ri->ri_ops.putchar = rasops8_putchar8;
82 break;
83 case 12:
84 ri->ri_ops.putchar = rasops8_putchar12;
85 break;
86 case 16:
87 ri->ri_ops.putchar = rasops8_putchar16;
88 break;
89 #endif /* !RASOPS_SMALL */
90 default:
91 ri->ri_ops.putchar = rasops8_putchar;
92 break;
97 * Put a single character.
99 static void
100 rasops8_putchar(void *cookie, int row, int col, u_int uc, long attr)
102 int width, height, cnt, fs, fb;
103 u_char *dp, *rp, *hp, *hrp, *fr, clr[2];
104 struct rasops_info *ri;
106 ri = (struct rasops_info *)cookie;
107 hp = hrp = NULL;
109 if (!CHAR_IN_FONT(uc, ri->ri_font))
110 return;
112 #ifdef RASOPS_CLIPPING
113 /* Catches 'row < 0' case too */
114 if ((unsigned)row >= (unsigned)ri->ri_rows)
115 return;
117 if ((unsigned)col >= (unsigned)ri->ri_cols)
118 return;
119 #endif
120 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
121 if (ri->ri_hwbits)
122 hrp = ri->ri_hwbits + row * ri->ri_yscale + col *
123 ri->ri_xscale;
125 height = ri->ri_font->fontheight;
126 width = ri->ri_font->fontwidth;
127 clr[0] = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
128 clr[1] = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
130 if (uc == ' ') {
131 u_char c = clr[0];
133 while (height--) {
134 dp = rp;
135 rp += ri->ri_stride;
136 if (ri->ri_hwbits) {
137 hp = hrp;
138 hrp += ri->ri_stride;
141 for (cnt = width; cnt; cnt--) {
142 *dp++ = c;
143 if (ri->ri_hwbits)
144 *hp++ = c;
147 } else {
148 uc -= ri->ri_font->firstchar;
149 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
150 fs = ri->ri_font->stride;
152 while (height--) {
153 dp = rp;
154 if (ri->ri_hwbits)
155 hp = hrp;
156 fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
157 fr += fs;
158 rp += ri->ri_stride;
159 if (ri->ri_hwbits)
160 hrp += ri->ri_stride;
162 for (cnt = width; cnt; cnt--) {
163 *dp++ = clr[(fb >> 31) & 1];
164 if (ri->ri_hwbits)
165 *hp++ = clr[(fb >> 31) & 1];
166 fb <<= 1;
171 /* Do underline */
172 if ((attr & 1) != 0) {
173 u_char c = clr[1];
175 rp -= (ri->ri_stride << 1);
176 if (ri->ri_hwbits)
177 hrp -= (ri->ri_stride << 1);
179 while (width--) {
180 *rp++ = c;
181 if (ri->ri_hwbits)
182 *hrp++ = c;
187 #ifndef RASOPS_SMALL
189 * Recompute the 4x1 blitting stamp.
191 static void
192 rasops8_makestamp(struct rasops_info *ri, long attr)
194 int32_t fg, bg;
195 int i;
197 fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff;
198 bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff;
199 stamp_attr = attr;
201 for (i = 0; i < 16; i++) {
202 #if BYTE_ORDER == BIG_ENDIAN
203 #define NEED_LITTLE_ENDIAN_STAMP RI_BSWAP
204 #else
205 #define NEED_LITTLE_ENDIAN_STAMP 0
206 #endif
207 if ((ri->ri_flg & RI_BSWAP) == NEED_LITTLE_ENDIAN_STAMP) {
208 /* little endian */
209 stamp[i] = (i & 8 ? fg : bg);
210 stamp[i] |= ((i & 4 ? fg : bg) << 8);
211 stamp[i] |= ((i & 2 ? fg : bg) << 16);
212 stamp[i] |= ((i & 1 ? fg : bg) << 24);
213 } else {
214 /* big endian */
215 stamp[i] = (i & 1 ? fg : bg);
216 stamp[i] |= ((i & 2 ? fg : bg) << 8);
217 stamp[i] |= ((i & 4 ? fg : bg) << 16);
218 stamp[i] |= ((i & 8 ? fg : bg) << 24);
224 * Put a single character. This is for 8-pixel wide fonts.
226 static void
227 rasops8_putchar8(void *cookie, int row, int col, u_int uc, long attr)
229 struct rasops_info *ri;
230 int height, fs;
231 int32_t *rp, *hp;
232 u_char *fr;
234 /* Can't risk remaking the stamp if it's already in use */
235 if (stamp_mutex++) {
236 stamp_mutex--;
237 rasops8_putchar(cookie, row, col, uc, attr);
238 return;
241 ri = (struct rasops_info *)cookie;
242 hp = NULL;
244 if (!CHAR_IN_FONT(uc, ri->ri_font))
245 return;
247 #ifdef RASOPS_CLIPPING
248 if ((unsigned)row >= (unsigned)ri->ri_rows) {
249 stamp_mutex--;
250 return;
253 if ((unsigned)col >= (unsigned)ri->ri_cols) {
254 stamp_mutex--;
255 return;
257 #endif
259 /* Recompute stamp? */
260 if (attr != stamp_attr)
261 rasops8_makestamp(ri, attr);
263 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
264 if (ri->ri_hwbits)
265 hp = (int32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
266 col*ri->ri_xscale);
267 height = ri->ri_font->fontheight;
269 if (uc == ' ') {
270 while (height--) {
271 rp[0] = rp[1] = stamp[0];
272 DELTA(rp, ri->ri_stride, int32_t *);
273 if (ri->ri_hwbits) {
274 hp[0] = stamp[0];
275 hp[1] = stamp[0];
276 DELTA(hp, ri->ri_stride, int32_t *);
279 } else {
280 uc -= ri->ri_font->firstchar;
281 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
282 fs = ri->ri_font->stride;
284 while (height--) {
285 rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
286 rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
287 if (ri->ri_hwbits) {
288 hp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) &
289 STAMP_MASK);
290 hp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) &
291 STAMP_MASK);
294 fr += fs;
295 DELTA(rp, ri->ri_stride, int32_t *);
296 if (ri->ri_hwbits)
297 DELTA(hp, ri->ri_stride, int32_t *);
301 /* Do underline */
302 if ((attr & 1) != 0) {
303 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
304 rp[0] = rp[1] = stamp[15];
305 if (ri->ri_hwbits) {
306 DELTA(hp, -(ri->ri_stride << 1), int32_t *);
307 hp[0] = stamp[15];
308 hp[1] = stamp[15];
312 stamp_mutex--;
316 * Put a single character. This is for 12-pixel wide fonts.
318 static void
319 rasops8_putchar12(void *cookie, int row, int col, u_int uc, long attr)
321 struct rasops_info *ri;
322 int height, fs;
323 int32_t *rp, *hrp;
324 u_char *fr;
326 /* Can't risk remaking the stamp if it's already in use */
327 if (stamp_mutex++) {
328 stamp_mutex--;
329 rasops8_putchar(cookie, row, col, uc, attr);
330 return;
333 ri = (struct rasops_info *)cookie;
334 hrp = NULL;
336 if (!CHAR_IN_FONT(uc, ri->ri_font))
337 return;
339 #ifdef RASOPS_CLIPPING
340 if ((unsigned)row >= (unsigned)ri->ri_rows) {
341 stamp_mutex--;
342 return;
345 if ((unsigned)col >= (unsigned)ri->ri_cols) {
346 stamp_mutex--;
347 return;
349 #endif
351 /* Recompute stamp? */
352 if (attr != stamp_attr)
353 rasops8_makestamp(ri, attr);
355 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
356 if (ri->ri_hwbits)
357 hrp = (int32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
358 col*ri->ri_xscale);
359 height = ri->ri_font->fontheight;
361 if (uc == ' ') {
362 while (height--) {
363 int32_t c = stamp[0];
365 rp[0] = rp[1] = rp[2] = c;
366 DELTA(rp, ri->ri_stride, int32_t *);
367 if (ri->ri_hwbits) {
368 hrp[0] = c;
369 hrp[1] = c;
370 hrp[2] = c;
371 DELTA(hrp, ri->ri_stride, int32_t *);
374 } else {
375 uc -= ri->ri_font->firstchar;
376 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
377 fs = ri->ri_font->stride;
379 while (height--) {
380 rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
381 rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
382 rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
383 if (ri->ri_hwbits) {
384 hrp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
385 hrp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
386 hrp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
389 fr += fs;
390 DELTA(rp, ri->ri_stride, int32_t *);
391 if (ri->ri_hwbits)
392 DELTA(hrp, ri->ri_stride, int32_t *);
396 /* Do underline */
397 if ((attr & 1) != 0) {
398 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
399 rp[0] = rp[1] = rp[2] = stamp[15];
400 if (ri->ri_hwbits) {
401 DELTA(hrp, -(ri->ri_stride << 1), int32_t *);
402 hrp[0] = stamp[15];
403 hrp[1] = stamp[15];
404 hrp[2] = stamp[15];
408 stamp_mutex--;
412 * Put a single character. This is for 16-pixel wide fonts.
414 static void
415 rasops8_putchar16(void *cookie, int row, int col, u_int uc, long attr)
417 struct rasops_info *ri;
418 int height, fs;
419 int32_t *rp, *hrp;
420 u_char *fr;
422 /* Can't risk remaking the stamp if it's already in use */
423 if (stamp_mutex++) {
424 stamp_mutex--;
425 rasops8_putchar(cookie, row, col, uc, attr);
426 return;
429 ri = (struct rasops_info *)cookie;
430 hrp = NULL;
432 if (!CHAR_IN_FONT(uc, ri->ri_font))
433 return;
435 #ifdef RASOPS_CLIPPING
436 if ((unsigned)row >= (unsigned)ri->ri_rows) {
437 stamp_mutex--;
438 return;
441 if ((unsigned)col >= (unsigned)ri->ri_cols) {
442 stamp_mutex--;
443 return;
445 #endif
447 /* Recompute stamp? */
448 if (attr != stamp_attr)
449 rasops8_makestamp(ri, attr);
451 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
452 if (ri->ri_hwbits)
453 hrp = (int32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
454 col*ri->ri_xscale);
456 height = ri->ri_font->fontheight;
458 if (uc == ' ') {
459 while (height--) {
460 rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
461 if (ri->ri_hwbits) {
462 hrp[0] = stamp[0];
463 hrp[1] = stamp[0];
464 hrp[2] = stamp[0];
465 hrp[3] = stamp[0];
468 } else {
469 uc -= ri->ri_font->firstchar;
470 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
471 fs = ri->ri_font->stride;
473 while (height--) {
474 rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
475 rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
476 rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
477 rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
478 if (ri->ri_hwbits) {
479 hrp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
480 hrp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
481 hrp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
482 hrp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
485 fr += fs;
486 DELTA(rp, ri->ri_stride, int32_t *);
487 if (ri->ri_hwbits)
488 DELTA(hrp, ri->ri_stride, int32_t *);
492 /* Do underline */
493 if ((attr & 1) != 0) {
494 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
495 rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
496 if (ri->ri_hwbits) {
497 DELTA(hrp, -(ri->ri_stride << 1), int32_t *);
498 hrp[0] = stamp[15];
499 hrp[1] = stamp[15];
500 hrp[2] = stamp[15];
501 hrp[3] = stamp[15];
505 stamp_mutex--;
507 #endif /* !RASOPS_SMALL */