rasops1.c revision 1.6
1/*	$OpenBSD: rasops1.c,v 1.6 2008/06/26 05:42:17 ray 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 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/time.h>
36#include <machine/endian.h>
37
38#include <dev/wscons/wsdisplayvar.h>
39#include <dev/wscons/wsconsio.h>
40#include <dev/rasops/rasops.h>
41#include <dev/rasops/rasops_masks.h>
42
43void	rasops1_copycols(void *, int, int, int, int);
44void	rasops1_erasecols(void *, int, int, int, long);
45void	rasops1_do_cursor(struct rasops_info *);
46void	rasops1_putchar(void *, int, int col, u_int, long);
47#ifndef RASOPS_SMALL
48void	rasops1_putchar8(void *, int, int col, u_int, long);
49void	rasops1_putchar16(void *, int, int col, u_int, long);
50#endif
51
52/*
53 * Initialize rasops_info struct for this colordepth.
54 */
55void
56rasops1_init(ri)
57	struct rasops_info *ri;
58{
59	rasops_masks_init();
60
61	switch (ri->ri_font->fontwidth) {
62#ifndef RASOPS_SMALL
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#endif
70	default:
71		ri->ri_ops.putchar = rasops1_putchar;
72		break;
73	}
74
75	if ((ri->ri_font->fontwidth & 7) != 0) {
76		ri->ri_ops.erasecols = rasops1_erasecols;
77		ri->ri_ops.copycols = rasops1_copycols;
78		ri->ri_do_cursor = rasops1_do_cursor;
79	}
80}
81
82/*
83 * Paint a single character. This is the generic version, this is ugly.
84 */
85void
86rasops1_putchar(cookie, row, col, uc, attr)
87	void *cookie;
88	int row, col;
89	u_int uc;
90	long attr;
91{
92	u_int fs, rs, fb, bg, fg, lmask, rmask;
93	u_int32_t height, width;
94	struct rasops_info *ri;
95	int32_t *rp;
96	u_char *fr;
97
98	ri = (struct rasops_info *)cookie;
99
100#ifdef RASOPS_CLIPPING
101	/* Catches 'row < 0' case too */
102	if ((unsigned)row >= (unsigned)ri->ri_rows)
103		return;
104
105	if ((unsigned)col >= (unsigned)ri->ri_cols)
106		return;
107#endif
108
109	col *= ri->ri_font->fontwidth;
110	rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
111	height = ri->ri_font->fontheight;
112	width = ri->ri_font->fontwidth;
113	col = col & 31;
114	rs = ri->ri_stride;
115
116	bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
117	fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
118
119	/* If fg and bg match this becomes a space character */
120	if (fg == bg || uc == ' ') {
121		uc = (u_int)-1;
122		fr = 0;		/* shutup gcc */
123		fs = 0;		/* shutup gcc */
124	} else {
125		uc -= ri->ri_font->firstchar;
126		fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
127		fs = ri->ri_font->stride;
128	}
129
130	/* Single word, one mask */
131	if ((col + width) <= 32) {
132		rmask = rasops_pmask[col][width];
133		lmask = ~rmask;
134
135		if (uc == (u_int)-1) {
136			bg &= rmask;
137
138			while (height--) {
139				*rp = (*rp & lmask) | bg;
140				DELTA(rp, rs, int32_t *);
141			}
142		} else {
143			/* NOT fontbits if bg is white */
144			if (bg) {
145				while (height--) {
146					fb = ~(fr[3] | (fr[2] << 8) |
147					    (fr[1] << 16) | (fr[0] << 24));
148					*rp = (*rp & lmask)
149					    | (MBE(fb >> col) & rmask);
150
151					fr += fs;
152					DELTA(rp, rs, int32_t *);
153				}
154			} else {
155				while (height--) {
156					fb = (fr[3] | (fr[2] << 8) |
157					    (fr[1] << 16) | (fr[0] << 24));
158					*rp = (*rp & lmask)
159					    | (MBE(fb >> col) & rmask);
160
161					fr += fs;
162					DELTA(rp, rs, int32_t *);
163				}
164			}
165		}
166
167		/* Do underline */
168		if ((attr & 1) != 0) {
169			DELTA(rp, -(ri->ri_stride << 1), int32_t *);
170			*rp = (*rp & lmask) | (fg & rmask);
171		}
172	} else {
173		lmask = ~rasops_lmask[col];
174		rmask = ~rasops_rmask[(col + width) & 31];
175
176		if (uc == (u_int)-1) {
177			width = bg & ~rmask;
178			bg = bg & ~lmask;
179
180			while (height--) {
181				rp[0] = (rp[0] & lmask) | bg;
182				rp[1] = (rp[1] & rmask) | width;
183				DELTA(rp, rs, int32_t *);
184			}
185		} else {
186			width = 32 - col;
187
188			/* NOT fontbits if bg is white */
189			if (bg) {
190				while (height--) {
191					fb = ~(fr[3] | (fr[2] << 8) |
192					    (fr[1] << 16) | (fr[0] << 24));
193
194					rp[0] = (rp[0] & lmask)
195					    | MBE((u_int)fb >> col);
196
197					rp[1] = (rp[1] & rmask)
198					    | (MBE((u_int)fb << width) & ~rmask);
199
200					fr += fs;
201					DELTA(rp, rs, int32_t *);
202				}
203			} else {
204				while (height--) {
205					fb = (fr[3] | (fr[2] << 8) |
206					    (fr[1] << 16) | (fr[0] << 24));
207
208					rp[0] = (rp[0] & lmask)
209					    | MBE(fb >> col);
210
211					rp[1] = (rp[1] & rmask)
212					    | (MBE(fb << width) & ~rmask);
213
214					fr += fs;
215					DELTA(rp, rs, int32_t *);
216				}
217			}
218		}
219
220		/* Do underline */
221		if ((attr & 1) != 0) {
222			DELTA(rp, -(ri->ri_stride << 1), int32_t *);
223			rp[0] = (rp[0] & lmask) | (fg & ~lmask);
224			rp[1] = (rp[1] & rmask) | (fg & ~rmask);
225		}
226	}
227}
228
229#ifndef RASOPS_SMALL
230/*
231 * Paint a single character. This is for 8-pixel wide fonts.
232 */
233void
234rasops1_putchar8(cookie, row, col, uc, attr)
235	void *cookie;
236	int row, col;
237	u_int uc;
238	long attr;
239{
240	int height, fs, rs, bg, fg;
241	struct rasops_info *ri;
242	u_char *fr, *rp;
243
244	ri = (struct rasops_info *)cookie;
245
246#ifdef RASOPS_CLIPPING
247	/* Catches 'row < 0' case too */
248	if ((unsigned)row >= (unsigned)ri->ri_rows)
249		return;
250
251	if ((unsigned)col >= (unsigned)ri->ri_cols)
252		return;
253#endif
254
255	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
256	height = ri->ri_font->fontheight;
257	rs = ri->ri_stride;
258
259	bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
260	fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
261
262	/* If fg and bg match this becomes a space character */
263	if (fg == bg || uc == ' ') {
264		while (height--) {
265			*rp = bg;
266			rp += rs;
267		}
268	} else {
269		uc -= ri->ri_font->firstchar;
270		fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
271		fs = ri->ri_font->stride;
272
273		/* NOT fontbits if bg is white */
274		if (bg) {
275			while (height--) {
276				*rp = ~*fr;
277				fr += fs;
278				rp += rs;
279			}
280		} else {
281			while (height--) {
282				*rp = *fr;
283				fr += fs;
284				rp += rs;
285			}
286		}
287
288	}
289
290	/* Do underline */
291	if ((attr & 1) != 0)
292		rp[-(ri->ri_stride << 1)] = fg;
293}
294
295/*
296 * Paint a single character. This is for 16-pixel wide fonts.
297 */
298void
299rasops1_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) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
325	fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[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) != 0)
358		*(int16_t *)(rp - (ri->ri_stride << 1)) = fg;
359}
360#endif	/* !RASOPS_SMALL */
361
362/*
363 * Grab routines common to depths where (bpp < 8)
364 */
365#define NAME(ident)	rasops1_##ident
366#define PIXEL_SHIFT	0
367
368#include <dev/rasops/rasops_bitops.h>
369