1 /* $NetBSD: rasops1.c,v 1.19 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: rasops1.c,v 1.19 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 rasops1_copycols(void *, int, int, int, int);
48 static void rasops1_erasecols(void *, int, int, int, long);
49 static void rasops1_do_cursor(struct rasops_info
*);
50 static void rasops1_putchar(void *, int, int col
, u_int
, long);
52 static void rasops1_putchar8(void *, int, int col
, u_int
, long);
53 static void rasops1_putchar16(void *, int, int col
, u_int
, long);
57 * Initialize rasops_info struct for this colordepth.
60 rasops1_init(struct rasops_info
*ri
)
63 switch (ri
->ri_font
->fontwidth
) {
66 ri
->ri_ops
.putchar
= rasops1_putchar8
;
69 ri
->ri_ops
.putchar
= rasops1_putchar16
;
73 ri
->ri_ops
.putchar
= rasops1_putchar
;
77 if ((ri
->ri_font
->fontwidth
& 7) != 0) {
78 ri
->ri_ops
.erasecols
= rasops1_erasecols
;
79 ri
->ri_ops
.copycols
= rasops1_copycols
;
80 ri
->ri_do_cursor
= rasops1_do_cursor
;
85 * Paint a single character. This is the generic version, this is ugly.
88 rasops1_putchar(void *cookie
, int row
, int col
, u_int uc
, long attr
)
90 u_int fs
, rs
, fb
, bg
, fg
, lmask
, rmask
;
91 u_int32_t height
, width
;
92 struct rasops_info
*ri
;
96 ri
= (struct rasops_info
*)cookie
;
98 #ifdef RASOPS_CLIPPING
99 /* Catches 'row < 0' case too */
100 if ((unsigned)row
>= (unsigned)ri
->ri_rows
)
103 if ((unsigned)col
>= (unsigned)ri
->ri_cols
)
107 col
*= ri
->ri_font
->fontwidth
;
108 rp
= (int32_t *)(ri
->ri_bits
+ row
* ri
->ri_yscale
+ ((col
>> 3) & ~3));
109 height
= ri
->ri_font
->fontheight
;
110 width
= ri
->ri_font
->fontwidth
;
114 bg
= (attr
& 0x000f0000) ? ri
->ri_devcmap
[1] : ri
->ri_devcmap
[0];
115 fg
= (attr
& 0x0f000000) ? ri
->ri_devcmap
[1] : ri
->ri_devcmap
[0];
117 /* If fg and bg match this becomes a space character */
118 if (fg
== bg
|| uc
== ' ') {
120 fr
= 0; /* shutup gcc */
121 fs
= 0; /* shutup gcc */
123 uc
-= ri
->ri_font
->firstchar
;
124 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
125 fs
= ri
->ri_font
->stride
;
128 /* Single word, one mask */
129 if ((col
+ width
) <= 32) {
130 rmask
= rasops_pmask
[col
][width
];
133 if (uc
== (u_int
)-1) {
137 *rp
= (*rp
& lmask
) | bg
;
138 DELTA(rp
, rs
, int32_t *);
141 /* NOT fontbits if bg is white */
144 fb
= ~(fr
[3] | (fr
[2] << 8) |
145 (fr
[1] << 16) | (fr
[0] << 24));
147 | (MBE(fb
>> col
) & rmask
);
150 DELTA(rp
, rs
, int32_t *);
154 fb
= (fr
[3] | (fr
[2] << 8) |
155 (fr
[1] << 16) | (fr
[0] << 24));
157 | (MBE(fb
>> col
) & rmask
);
160 DELTA(rp
, rs
, int32_t *);
166 if ((attr
& 1) != 0) {
167 DELTA(rp
, -(ri
->ri_stride
<< 1), int32_t *);
168 *rp
= (*rp
& lmask
) | (fg
& rmask
);
171 lmask
= ~rasops_lmask
[col
];
172 rmask
= ~rasops_rmask
[(col
+ width
) & 31];
174 if (uc
== (u_int
)-1) {
179 rp
[0] = (rp
[0] & lmask
) | bg
;
180 rp
[1] = (rp
[1] & rmask
) | width
;
181 DELTA(rp
, rs
, int32_t *);
186 /* NOT fontbits if bg is white */
189 fb
= ~(fr
[3] | (fr
[2] << 8) |
190 (fr
[1] << 16) | (fr
[0] << 24));
192 rp
[0] = (rp
[0] & lmask
)
193 | MBE((u_int
)fb
>> col
);
195 rp
[1] = (rp
[1] & rmask
)
196 | (MBE((u_int
)fb
<< width
) & ~rmask
);
199 DELTA(rp
, rs
, int32_t *);
203 fb
= (fr
[3] | (fr
[2] << 8) |
204 (fr
[1] << 16) | (fr
[0] << 24));
206 rp
[0] = (rp
[0] & lmask
)
209 rp
[1] = (rp
[1] & rmask
)
210 | (MBE(fb
<< width
) & ~rmask
);
213 DELTA(rp
, rs
, int32_t *);
219 if ((attr
& 1) != 0) {
220 DELTA(rp
, -(ri
->ri_stride
<< 1), int32_t *);
221 rp
[0] = (rp
[0] & lmask
) | (fg
& ~lmask
);
222 rp
[1] = (rp
[1] & rmask
) | (fg
& ~rmask
);
229 * Paint a single character. This is for 8-pixel wide fonts.
232 rasops1_putchar8(void *cookie
, int row
, int col
, u_int uc
, long attr
)
234 int height
, fs
, rs
, bg
, fg
;
235 struct rasops_info
*ri
;
238 ri
= (struct rasops_info
*)cookie
;
240 #ifdef RASOPS_CLIPPING
241 /* Catches 'row < 0' case too */
242 if ((unsigned)row
>= (unsigned)ri
->ri_rows
)
245 if ((unsigned)col
>= (unsigned)ri
->ri_cols
)
249 rp
= ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
;
250 height
= ri
->ri_font
->fontheight
;
253 bg
= (attr
& 0x000f0000) ? ri
->ri_devcmap
[1] : ri
->ri_devcmap
[0];
254 fg
= (attr
& 0x0f000000) ? ri
->ri_devcmap
[1] : ri
->ri_devcmap
[0];
256 /* If fg and bg match this becomes a space character */
257 if (fg
== bg
|| uc
== ' ') {
263 uc
-= ri
->ri_font
->firstchar
;
264 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
265 fs
= ri
->ri_font
->stride
;
267 /* NOT fontbits if bg is white */
286 rp
[-(ri
->ri_stride
<< 1)] = fg
;
290 * Paint a single character. This is for 16-pixel wide fonts.
293 rasops1_putchar16(void *cookie
, int row
, int col
, u_int uc
, long attr
)
295 int height
, fs
, rs
, bg
, fg
;
296 struct rasops_info
*ri
;
299 ri
= (struct rasops_info
*)cookie
;
301 #ifdef RASOPS_CLIPPING
302 /* Catches 'row < 0' case too */
303 if ((unsigned)row
>= (unsigned)ri
->ri_rows
)
306 if ((unsigned)col
>= (unsigned)ri
->ri_cols
)
310 rp
= ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
;
311 height
= ri
->ri_font
->fontheight
;
314 bg
= (attr
& 0x000f0000) ? ri
->ri_devcmap
[1] : ri
->ri_devcmap
[0];
315 fg
= (attr
& 0x0f000000) ? ri
->ri_devcmap
[1] : ri
->ri_devcmap
[0];
317 /* If fg and bg match this becomes a space character */
318 if (fg
== bg
|| uc
== ' ') {
324 uc
-= ri
->ri_font
->firstchar
;
325 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
326 fs
= ri
->ri_font
->stride
;
328 /* NOT fontbits if bg is white */
348 *(int16_t *)(rp
- (ri
->ri_stride
<< 1)) = fg
;
350 #endif /* !RASOPS_SMALL */
353 * Grab routines common to depths where (bpp < 8)
355 #define NAME(ident) rasops1_##ident
356 #define PIXEL_SHIFT 0
358 #include <dev/rasops/rasops_bitops.h>