1 /* $NetBSD: rasops2.c,v 1.13 2009/03/14 15:36:20 dsl Exp $ */
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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: rasops2.c,v 1.13 2009/03/14 15:36:20 dsl Exp $");
35 #include "opt_rasops.h"
37 #include <sys/param.h>
38 #include <sys/systm.h>
40 #include <machine/endian.h>
42 #include <dev/wscons/wsdisplayvar.h>
43 #include <dev/wscons/wsconsio.h>
44 #include <dev/rasops/rasops.h>
45 #include <dev/rasops/rasops_masks.h>
47 static void rasops2_copycols(void *, int, int, int, int);
48 static void rasops2_erasecols(void *, int, int, int, long);
49 static void rasops2_do_cursor(struct rasops_info
*);
50 static void rasops2_putchar(void *, int, int col
, u_int
, long);
52 static void rasops2_putchar8(void *, int, int col
, u_int
, long);
53 static void rasops2_putchar12(void *, int, int col
, u_int
, long);
54 static void rasops2_putchar16(void *, int, int col
, u_int
, long);
55 static void rasops2_makestamp(struct rasops_info
*, long);
58 * 4x1 stamp for optimized character blitting
60 static int8_t stamp
[16];
61 static long stamp_attr
;
62 static int stamp_mutex
; /* XXX see note in README */
66 * Initialize rasops_info struct for this colordepth.
69 rasops2_init(struct rasops_info
*ri
)
72 switch (ri
->ri_font
->fontwidth
) {
75 ri
->ri_ops
.putchar
= rasops2_putchar8
;
78 ri
->ri_ops
.putchar
= rasops2_putchar12
;
81 ri
->ri_ops
.putchar
= rasops2_putchar16
;
83 #endif /* !RASOPS_SMALL */
85 panic("fontwidth not 8/12/16 or RASOPS_SMALL - fixme!");
86 ri
->ri_ops
.putchar
= rasops2_putchar
;
90 if ((ri
->ri_font
->fontwidth
& 3) != 0) {
91 ri
->ri_ops
.erasecols
= rasops2_erasecols
;
92 ri
->ri_ops
.copycols
= rasops2_copycols
;
93 ri
->ri_do_cursor
= rasops2_do_cursor
;
99 * Paint a single character. This is the generic version, this is ugly.
102 rasops2_putchar(void *cookie
, int row
, int col
, u_int uc
, long attr
)
104 int height
, width
, fs
, rs
, fb
, bg
, fg
, lmask
, rmask
;
105 struct rasops_info
*ri
;
109 ri
= (struct rasops_info
*)cookie
;
111 #ifdef RASOPS_CLIPPING
112 /* Catches 'row < 0' case too */
113 if ((unsigned)row
>= (unsigned)ri
->ri_rows
)
116 if ((unsigned)col
>= (unsigned)ri
->ri_cols
)
120 width
= ri
->ri_font
->fontwidth
<< 1;
121 height
= ri
->ri_font
->fontheight
;
123 rp
= (int32_t *)(ri
->ri_bits
+ row
* ri
->ri_yscale
+ ((col
>> 3) & ~3));
127 bg
= ri
->ri_devcmap
[(attr
>> 16) & 0xf];
128 fg
= ri
->ri_devcmap
[(attr
>> 24) & 0xf];
130 /* If fg and bg match this becomes a space character */
131 if (fg
== bg
|| uc
== ' ') {
133 fr
= 0; /* shutup gcc */
134 fs
= 0; /* shutup gcc */
136 uc
-= ri
->ri_font
->firstchar
;
137 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
138 fs
= ri
->ri_font
->stride
;
141 /* Single word, one mask */
142 if ((col
+ width
) <= 32) {
143 rmask
= rasops_pmask
[col
][width
];
146 if (uc
== (u_int
)-1) {
150 *rp
= (*rp
& lmask
) | bg
;
151 DELTA(rp
, rs
, int32_t *);
164 DELTA(rp
, -(ri
->ri_stride
<< 1), int32_t *);
165 *rp
= (*rp
& lmask
) | (fg
& rmask
);
168 lmask
= ~rasops_lmask
[col
];
169 rmask
= ~rasops_rmask
[(col
+ width
) & 31];
171 if (uc
== (u_int
)-1) {
176 rp
[0] = (rp
[0] & lmask
) | bg
;
177 rp
[1] = (rp
[1] & rmask
) | width
;
178 DELTA(rp
, rs
, int32_t *);
183 /* NOT fontbits if bg is white */
185 fb
= ~(fr
[3] | (fr
[2] << 8) |
186 (fr
[1] << 16) | (fr
[0] << 24));
188 rp
[0] = (rp
[0] & lmask
)
189 | MBE((u_int
)fb
>> col
);
191 rp
[1] = (rp
[1] & rmask
)
192 | (MBE((u_int
)fb
<< width
) & ~rmask
);
195 DELTA(rp
, rs
, int32_t *);
201 DELTA(rp
, -(ri
->ri_stride
<< 1), int32_t *);
202 rp
[0] = (rp
[0] & lmask
) | (fg
& ~lmask
);
203 rp
[1] = (rp
[1] & rmask
) | (fg
& ~rmask
);
210 * Put a single character. This is the generic version.
213 rasops2_putchar(void *cookie
, int row
, int col
, u_int uc
, long attr
)
221 * Recompute the blitting stamp.
224 rasops2_makestamp(struct rasops_info
*ri
, long attr
)
228 fg
= ri
->ri_devcmap
[(attr
>> 24) & 0xf] & 3;
229 bg
= ri
->ri_devcmap
[(attr
>> 16) & 0xf] & 3;
232 for (i
= 0; i
< 16; i
++) {
233 stamp
[i
] = (i
& 1 ? fg
: bg
);
234 stamp
[i
] |= (i
& 2 ? fg
: bg
) << 2;
235 stamp
[i
] |= (i
& 4 ? fg
: bg
) << 4;
236 stamp
[i
] |= (i
& 8 ? fg
: bg
) << 6;
241 * Put a single character. This is for 8-pixel wide fonts.
244 rasops2_putchar8(void *cookie
, int row
, int col
, u_int uc
, long attr
)
246 struct rasops_info
*ri
;
250 /* Can't risk remaking the stamp if it's already in use */
253 rasops2_putchar(cookie
, row
, col
, uc
, attr
);
257 ri
= (struct rasops_info
*)cookie
;
259 #ifdef RASOPS_CLIPPING
260 /* Catches 'row < 0' case too */
261 if ((unsigned)row
>= (unsigned)ri
->ri_rows
) {
266 if ((unsigned)col
>= (unsigned)ri
->ri_cols
) {
272 rp
= ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
;
273 height
= ri
->ri_font
->fontheight
;
276 /* Recompute stamp? */
277 if (attr
!= stamp_attr
)
278 rasops2_makestamp(ri
, attr
);
287 uc
-= ri
->ri_font
->firstchar
;
288 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
289 fs
= ri
->ri_font
->stride
;
292 rp
[0] = stamp
[(*fr
>> 4) & 0xf];
293 rp
[1] = stamp
[*fr
& 0xf];
301 *(int16_t *)(rp
- (ri
->ri_stride
<< 1)) = stamp
[15];
307 * Put a single character. This is for 12-pixel wide fonts.
310 rasops2_putchar12(void *cookie
, int row
, int col
, u_int uc
, long attr
)
312 struct rasops_info
*ri
;
316 /* Can't risk remaking the stamp if it's already in use */
319 rasops2_putchar(cookie
, row
, col
, uc
, attr
);
323 ri
= (struct rasops_info
*)cookie
;
325 #ifdef RASOPS_CLIPPING
326 /* Catches 'row < 0' case too */
327 if ((unsigned)row
>= (unsigned)ri
->ri_rows
) {
332 if ((unsigned)col
>= (unsigned)ri
->ri_cols
) {
338 rp
= ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
;
339 height
= ri
->ri_font
->fontheight
;
342 /* Recompute stamp? */
343 if (attr
!= stamp_attr
)
344 rasops2_makestamp(ri
, attr
);
349 rp
[0] = rp
[1] = rp
[2] = c
;
353 uc
-= ri
->ri_font
->firstchar
;
354 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
355 fs
= ri
->ri_font
->stride
;
358 rp
[0] = stamp
[(fr
[0] >> 4) & 0xf];
359 rp
[1] = stamp
[fr
[0] & 0xf];
360 rp
[2] = stamp
[(fr
[1] >> 4) & 0xf];
367 if ((attr
& 1) != 0) {
368 rp
-= ri
->ri_stride
<< 1;
369 rp
[0] = rp
[1] = rp
[2] = stamp
[15];
376 * Put a single character. This is for 16-pixel wide fonts.
379 rasops2_putchar16(void *cookie
, int row
, int col
, u_int uc
, long attr
)
381 struct rasops_info
*ri
;
385 /* Can't risk remaking the stamp if it's already in use */
388 rasops2_putchar(cookie
, row
, col
, uc
, attr
);
392 ri
= (struct rasops_info
*)cookie
;
394 #ifdef RASOPS_CLIPPING
395 /* Catches 'row < 0' case too */
396 if ((unsigned)row
>= (unsigned)ri
->ri_rows
) {
401 if ((unsigned)col
>= (unsigned)ri
->ri_cols
) {
407 rp
= ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
;
408 height
= ri
->ri_font
->fontheight
;
411 /* Recompute stamp? */
412 if (attr
!= stamp_attr
)
413 rasops2_makestamp(ri
, attr
);
422 uc
-= ri
->ri_font
->firstchar
;
423 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
424 fs
= ri
->ri_font
->stride
;
427 rp
[0] = stamp
[(fr
[0] >> 4) & 0xf];
428 rp
[1] = stamp
[fr
[0] & 0xf];
429 rp
[2] = stamp
[(fr
[1] >> 4) & 0xf];
430 rp
[3] = stamp
[fr
[1] & 0xf];
438 *(int32_t *)(rp
- (ri
->ri_stride
<< 1)) = stamp
[15];
442 #endif /* !RASOPS_SMALL */
445 * Grab routines common to depths where (bpp < 8)
447 #define NAME(ident) rasops2_##ident
448 #define PIXEL_SHIFT 1
450 #include <dev/rasops/rasops_bitops.h>