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