rasops1.c revision 1.4 1 /* $NetBSD: rasops1.c,v 1.4 1999/04/26 04:27:47 ad Exp $ */
2
3 /*
4 * Copyright (c) 1999 Andy Doran <ad (at) NetBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30 #include "opt_rasops.h"
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.4 1999/04/26 04:27:47 ad Exp $");
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/time.h>
38 #include <machine/endian.h>
39
40 #include <dev/wscons/wsdisplayvar.h>
41 #include <dev/wscons/wsconsio.h>
42 #include <dev/rasops/rasops.h>
43 #include <dev/rasops/rasops_masks.h>
44
45 static void rasops1_putchar __P((void *, int, int col, u_int, long));
46 static void rasops1_putchar8 __P((void *, int, int col, u_int, long));
47 static void rasops1_putchar16 __P((void *, int, int col, u_int, long));
48 static void rasops1_copycols __P((void *, int, int, int, int));
49 static void rasops1_erasecols __P((void *, int, int, int, long));
50 static void rasops1_do_cursor __P((struct rasops_info *));
51
52 void rasops1_init __P((struct rasops_info *ri));
53
54 /*
55 * Initalize rasops_info struct for this colordepth.
56 */
57 void
58 rasops1_init(ri)
59 struct rasops_info *ri;
60 {
61
62 switch (ri->ri_font->fontwidth) {
63 case 8:
64 ri->ri_ops.putchar = rasops1_putchar8;
65 break;
66 case 16:
67 ri->ri_ops.putchar = rasops1_putchar16;
68 break;
69 default:
70 ri->ri_ops.putchar = rasops1_putchar;
71 break;
72 }
73
74 if (ri->ri_font->fontwidth & 7) {
75 ri->ri_ops.erasecols = rasops1_erasecols;
76 ri->ri_ops.copycols = rasops1_copycols;
77 ri->ri_do_cursor = rasops1_do_cursor;
78 }
79 }
80
81
82 /*
83 * Paint a single character. This is the generic version, this is ugly.
84 */
85 static void
86 rasops1_putchar(cookie, row, col, uc, attr)
87 void *cookie;
88 int row, col;
89 u_int uc;
90 long attr;
91 {
92 int height, width, fs, rs, fb, bg, fg, lmask, rmask;
93 struct rasops_info *ri;
94 int32_t *rp;
95 u_char *fr;
96
97 ri = (struct rasops_info *)cookie;
98
99 #ifdef RASOPS_CLIPPING
100 /* Catches 'row < 0' case too */
101 if ((unsigned)row >= (unsigned)ri->ri_rows)
102 return;
103
104 if ((unsigned)col >= (unsigned)ri->ri_cols)
105 return;
106 #endif
107
108 col *= ri->ri_font->fontwidth;
109 rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
110 height = ri->ri_font->fontheight;
111 width = ri->ri_font->fontwidth;
112 col = col & 31;
113 rs = ri->ri_stride;
114
115 bg = (attr & 0x000f0000) ? 0xffffffff : 0;
116 fg = (attr & 0x0f000000) ? 0xffffffff : 0;
117
118 /* If fg and bg match this becomes a space character */
119 if (fg == bg || uc == ' ') {
120 uc = (u_int)-1;
121 fr = 0; /* shutup gcc */
122 fs = 0; /* shutup gcc */
123 } else {
124 uc -= ri->ri_font->firstchar;
125 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
126 fs = ri->ri_font->stride;
127 }
128
129 /* Single word, one mask */
130 if ((col + width) <= 32) {
131 rmask = rasops_pmask[col][width];
132 lmask = ~rmask;
133
134 if (uc == (u_int)-1) {
135 bg &= rmask;
136
137 while (height--) {
138 *rp = (*rp & lmask) | bg;
139 DELTA(rp, rs, int32_t *);
140 }
141 } else {
142 /* NOT fontbits if bg is white */
143 if (bg) {
144 while (height--) {
145 fb = ~(fr[3] | (fr[2] << 8) |
146 (fr[1] << 16) | (fr[0] << 24));
147 *rp = (*rp & lmask)
148 | (MBE(fb >> col) & rmask);
149
150 fr += fs;
151 DELTA(rp, rs, int32_t *);
152 }
153 } else {
154 while (height--) {
155 fb = (fr[3] | (fr[2] << 8) |
156 (fr[1] << 16) | (fr[0] << 24));
157 *rp = (*rp & lmask)
158 | (MBE(fb >> col) & rmask);
159
160 fr += fs;
161 DELTA(rp, rs, int32_t *);
162 }
163 }
164 }
165
166 /* Do underline */
167 if (attr & 1) {
168 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
169 *rp = (*rp & lmask) | (fg & rmask);
170 }
171 } else {
172 lmask = ~rasops_lmask[col];
173 rmask = ~rasops_rmask[(col + width) & 31];
174
175 if (uc == (u_int)-1) {
176 bg = bg & ~lmask;
177 width = bg & ~rmask;
178
179 while (height--) {
180 rp[0] = (rp[0] & lmask) | bg;
181 rp[1] = (rp[1] & rmask) | width;
182 DELTA(rp, rs, int32_t *);
183 }
184 } else {
185 width = 32 - col;
186
187 /* NOT fontbits if bg is white */
188 if (bg) {
189 while (height--) {
190 fb = ~(fr[3] | (fr[2] << 8) |
191 (fr[1] << 16) | (fr[0] << 24));
192
193 rp[0] = (rp[0] & lmask)
194 | MBE((u_int)fb >> col);
195
196 rp[1] = (rp[1] & rmask)
197 | (MBE((u_int)fb << width) & ~rmask);
198
199 fr += fs;
200 DELTA(rp, rs, int32_t *);
201 }
202 } else {
203 while (height--) {
204 fb = (fr[3] | (fr[2] << 8) |
205 (fr[1] << 16) | (fr[0] << 24));
206
207 rp[0] = (rp[0] & lmask)
208 | MBE(fb >> col);
209
210 rp[1] = (rp[1] & rmask)
211 | (MBE(fb << width) & ~rmask);
212
213 fr += fs;
214 DELTA(rp, rs, int32_t *);
215 }
216 }
217 }
218
219 /* Do underline */
220 if (attr & 1) {
221 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
222 rp[0] = (rp[0] & lmask) | (fg & ~lmask);
223 rp[1] = (rp[1] & rmask) | (fg & ~rmask);
224 }
225 }
226 }
227
228
229 /*
230 * Paint a single character. This is for 8-pixel wide fonts.
231 */
232 static void
233 rasops1_putchar8(cookie, row, col, uc, attr)
234 void *cookie;
235 int row, col;
236 u_int uc;
237 long attr;
238 {
239 int height, fs, rs, bg, fg;
240 struct rasops_info *ri;
241 u_char *fr, *rp;
242
243 ri = (struct rasops_info *)cookie;
244
245 #ifdef RASOPS_CLIPPING
246 /* Catches 'row < 0' case too */
247 if ((unsigned)row >= (unsigned)ri->ri_rows)
248 return;
249
250 if ((unsigned)col >= (unsigned)ri->ri_cols)
251 return;
252 #endif
253
254 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
255 height = ri->ri_font->fontheight;
256 rs = ri->ri_stride;
257
258 bg = (attr & 0x000f0000) ? 0xff : 0;
259 fg = (attr & 0x0f000000) ? 0xff : 0;
260
261 /* If fg and bg match this becomes a space character */
262 if (fg == bg || uc == ' ') {
263 while (height--) {
264 *rp = bg;
265 rp += rs;
266 }
267 } else {
268 uc -= ri->ri_font->firstchar;
269 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
270 fs = ri->ri_font->stride;
271
272 /* NOT fontbits if bg is white */
273 if (bg) {
274 while (height--) {
275 *rp = ~*fr;
276 fr += fs;
277 rp += rs;
278 }
279 } else {
280 while (height--) {
281 *rp = *fr;
282 fr += fs;
283 rp += rs;
284 }
285 }
286
287 }
288
289 /* Do underline */
290 if (attr & 1)
291 rp[-(ri->ri_stride << 1)] = fg;
292 }
293
294
295 /*
296 * Paint a single character. This is for 16-pixel wide fonts.
297 */
298 static void
299 rasops1_putchar16(cookie, row, col, uc, attr)
300 void *cookie;
301 int row, col;
302 u_int uc;
303 long attr;
304 {
305 int height, fs, rs, bg, fg;
306 struct rasops_info *ri;
307 u_char *fr, *rp;
308
309 ri = (struct rasops_info *)cookie;
310
311 #ifdef RASOPS_CLIPPING
312 /* Catches 'row < 0' case too */
313 if ((unsigned)row >= (unsigned)ri->ri_rows)
314 return;
315
316 if ((unsigned)col >= (unsigned)ri->ri_cols)
317 return;
318 #endif
319
320 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
321 height = ri->ri_font->fontheight;
322 rs = ri->ri_stride;
323
324 bg = (attr & 0x000f0000) ? 0xffff : 0;
325 fg = (attr & 0x0f000000) ? 0xffff : 0;
326
327 /* If fg and bg match this becomes a space character */
328 if (fg == bg || uc == ' ') {
329 while (height--) {
330 *(int16_t *)rp = bg;
331 rp += rs;
332 }
333 } else {
334 uc -= ri->ri_font->firstchar;
335 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
336 fs = ri->ri_font->stride;
337
338 /* NOT fontbits if bg is white */
339 if (bg) {
340 while (height--) {
341 rp[0] = ~fr[0];
342 rp[1] = ~fr[1];
343 fr += fs;
344 rp += rs;
345 }
346 } else {
347 while (height--) {
348 rp[0] = fr[0];
349 rp[1] = fr[1];
350 fr += fs;
351 rp += rs;
352 }
353 }
354 }
355
356 /* Do underline */
357 if (attr & 1)
358 *(int16_t *)(rp - (ri->ri_stride << 1)) = fg;
359 }
360
361 /*
362 * Grab routines common to depths where (bpp < 8)
363 */
364 #define NAME(ident) rasops1_##ident
365 #define PIXEL_SHIFT 0
366
367 #include <dev/rasops/rasops_bitops.h>
368