Annotation of sys/dev/rasops/rasops2.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: rasops2.c,v 1.7 2006/08/03 18:42:06 miod Exp $ */
2: /* $NetBSD: rasops2.c,v 1.5 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:
50: void rasops2_copycols(void *, int, int, int, int);
51: void rasops2_erasecols(void *, int, int, int, long);
52: void rasops2_do_cursor(struct rasops_info *);
53: void rasops2_putchar(void *, int, int col, u_int, long);
54: u_int rasops2_mergebits(u_char *, int, int);
55: #ifndef RASOPS_SMALL
56: void rasops2_putchar8(void *, int, int col, u_int, long);
57: void rasops2_putchar12(void *, int, int col, u_int, long);
58: void rasops2_putchar16(void *, int, int col, u_int, long);
59: void rasops2_makestamp(struct rasops_info *, long);
60:
61: /*
62: * 4x1 stamp for optimized character blitting
63: */
64: static int8_t stamp[16];
65: static long stamp_attr;
66: static int stamp_mutex; /* XXX see note in README */
67: #endif
68:
69: /*
70: * Initialize rasops_info struct for this colordepth.
71: */
72: void
73: rasops2_init(ri)
74: struct rasops_info *ri;
75: {
76: rasops_masks_init();
77:
78: switch (ri->ri_font->fontwidth) {
79: #ifndef RASOPS_SMALL
80: case 8:
81: ri->ri_ops.putchar = rasops2_putchar8;
82: break;
83: case 12:
84: ri->ri_ops.putchar = rasops2_putchar12;
85: break;
86: case 16:
87: ri->ri_ops.putchar = rasops2_putchar16;
88: break;
89: #endif /* !RASOPS_SMALL */
90: default:
91: ri->ri_ops.putchar = rasops2_putchar;
92: break;
93: }
94:
95: if ((ri->ri_font->fontwidth & 3) != 0) {
96: ri->ri_ops.erasecols = rasops2_erasecols;
97: ri->ri_ops.copycols = rasops2_copycols;
98: ri->ri_do_cursor = rasops2_do_cursor;
99: }
100: }
101:
102: /*
103: * Compute a 2bpp expansion of a font element against the given colors.
104: * Used by rasops2_putchar() below.
105: */
106: u_int
107: rasops2_mergebits(u_char *fr, int fg, int bg)
108: {
109: u_int fb, bits;
110: int mask, shift;
111:
112: fg &= 3;
113: bg &= 3;
114:
115: bits = fr[1] | (fr[0] << 8);
116: fb = 0;
117: for (mask = 0x8000, shift = 32 - 2; mask != 0; mask >>= 1, shift -= 2)
118: fb |= (bits & mask ? fg : bg) << shift;
119:
120: return (fb);
121: }
122:
123: /*
124: * Paint a single character. This is the generic version, this is ugly.
125: */
126: void
127: rasops2_putchar(cookie, row, col, uc, attr)
128: void *cookie;
129: int row, col;
130: u_int uc;
131: long attr;
132: {
133: int height, width, fs, rs, bg, fg, lmask, rmask;
134: u_int fb;
135: struct rasops_info *ri;
136: int32_t *rp;
137: u_char *fr;
138:
139: ri = (struct rasops_info *)cookie;
140:
141: #ifdef RASOPS_CLIPPING
142: /* Catches 'row < 0' case too */
143: if ((unsigned)row >= (unsigned)ri->ri_rows)
144: return;
145:
146: if ((unsigned)col >= (unsigned)ri->ri_cols)
147: return;
148: #endif
149:
150: width = ri->ri_font->fontwidth << 1;
151: height = ri->ri_font->fontheight;
152: col *= width;
153: rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
154: col = col & 31;
155: rs = ri->ri_stride;
156:
157: bg = ri->ri_devcmap[(attr >> 16) & 0xf];
158: fg = ri->ri_devcmap[(attr >> 24) & 0xf];
159:
160: /* If fg and bg match this becomes a space character */
161: if (fg == bg || uc == ' ') {
162: uc = (u_int)-1;
163: fr = 0; /* shutup gcc */
164: fs = 0; /* shutup gcc */
165: } else {
166: uc -= ri->ri_font->firstchar;
167: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
168: fs = ri->ri_font->stride;
169: }
170:
171: /* Single word, one mask */
172: if ((col + width) <= 32) {
173: rmask = rasops_pmask[col][width];
174: lmask = ~rmask;
175:
176: if (uc == (u_int)-1) {
177: bg &= rmask;
178:
179: while (height--) {
180: *rp = (*rp & lmask) | bg;
181: DELTA(rp, rs, int32_t *);
182: }
183: } else {
184: while (height--) {
185: fb = rasops2_mergebits(fr, fg, bg);
186: *rp = (*rp & lmask) |
187: (MBE(fb >> col) & rmask);
188:
189: fr += fs;
190: DELTA(rp, rs, int32_t *);
191: }
192: }
193:
194: /* Do underline */
195: if (attr & 1) {
196: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
197: *rp = (*rp & lmask) | (fg & rmask);
198: }
199: } else {
200: lmask = ~rasops_lmask[col];
201: rmask = ~rasops_rmask[(col + width) & 31];
202:
203: if (uc == (u_int)-1) {
204: width = bg & ~rmask;
205: bg = bg & ~lmask;
206:
207: while (height--) {
208: rp[0] = (rp[0] & lmask) | bg;
209: rp[1] = (rp[1] & rmask) | width;
210: DELTA(rp, rs, int32_t *);
211: }
212: } else {
213: width = 32 - col;
214:
215: while (height--) {
216: fb = rasops2_mergebits(fr, fg, bg);
217:
218: rp[0] = (rp[0] & lmask) |
219: MBE(fb >> col);
220: rp[1] = (rp[1] & rmask) |
221: (MBE(fb << width) & ~rmask);
222:
223: fr += fs;
224: DELTA(rp, rs, int32_t *);
225: }
226: }
227:
228: /* Do underline */
229: if (attr & 1) {
230: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
231: rp[0] = (rp[0] & lmask) | (fg & ~lmask);
232: rp[1] = (rp[1] & rmask) | (fg & ~rmask);
233: }
234: }
235: }
236:
237: #ifndef RASOPS_SMALL
238: /*
239: * Recompute the blitting stamp.
240: */
241: void
242: rasops2_makestamp(ri, attr)
243: struct rasops_info *ri;
244: long attr;
245: {
246: int i, fg, bg;
247:
248: fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 3;
249: bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 3;
250: stamp_attr = attr;
251:
252: for (i = 0; i < 16; i++) {
253: stamp[i] = (i & 1 ? fg : bg);
254: stamp[i] |= (i & 2 ? fg : bg) << 2;
255: stamp[i] |= (i & 4 ? fg : bg) << 4;
256: stamp[i] |= (i & 8 ? fg : bg) << 6;
257: }
258: }
259:
260: /*
261: * Put a single character. This is for 8-pixel wide fonts.
262: */
263: void
264: rasops2_putchar8(cookie, row, col, uc, attr)
265: void *cookie;
266: int row, col;
267: u_int uc;
268: long attr;
269: {
270: struct rasops_info *ri;
271: int height, fs, rs;
272: u_char *fr, *rp;
273:
274: /* Can't risk remaking the stamp if it's already in use */
275: if (stamp_mutex++) {
276: stamp_mutex--;
277: rasops2_putchar(cookie, row, col, uc, attr);
278: return;
279: }
280:
281: ri = (struct rasops_info *)cookie;
282:
283: #ifdef RASOPS_CLIPPING
284: /* Catches 'row < 0' case too */
285: if ((unsigned)row >= (unsigned)ri->ri_rows) {
286: stamp_mutex--;
287: return;
288: }
289:
290: if ((unsigned)col >= (unsigned)ri->ri_cols) {
291: stamp_mutex--;
292: return;
293: }
294: #endif
295:
296: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
297: height = ri->ri_font->fontheight;
298: rs = ri->ri_stride;
299:
300: /* Recompute stamp? */
301: if (attr != stamp_attr)
302: rasops2_makestamp(ri, attr);
303:
304: if (uc == ' ') {
305: int8_t c = stamp[0];
306: while (height--) {
307: *(int16_t *)rp = c;
308: rp += rs;
309: }
310: } else {
311: uc -= ri->ri_font->firstchar;
312: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
313: fs = ri->ri_font->stride;
314:
315: while (height--) {
316: rp[0] = stamp[(*fr >> 4) & 0xf];
317: rp[1] = stamp[*fr & 0xf];
318: fr += fs;
319: rp += rs;
320: }
321: }
322:
323: /* Do underline */
324: if ((attr & 1) != 0)
325: *(int16_t *)(rp - (ri->ri_stride << 1)) = stamp[15];
326:
327: stamp_mutex--;
328: }
329:
330: /*
331: * Put a single character. This is for 12-pixel wide fonts.
332: */
333: void
334: rasops2_putchar12(cookie, row, col, uc, attr)
335: void *cookie;
336: int row, col;
337: u_int uc;
338: long attr;
339: {
340: struct rasops_info *ri;
341: int height, fs, rs;
342: u_char *fr, *rp;
343:
344: /* Can't risk remaking the stamp if it's already in use */
345: if (stamp_mutex++) {
346: stamp_mutex--;
347: rasops2_putchar(cookie, row, col, uc, attr);
348: return;
349: }
350:
351: ri = (struct rasops_info *)cookie;
352:
353: #ifdef RASOPS_CLIPPING
354: /* Catches 'row < 0' case too */
355: if ((unsigned)row >= (unsigned)ri->ri_rows) {
356: stamp_mutex--;
357: return;
358: }
359:
360: if ((unsigned)col >= (unsigned)ri->ri_cols) {
361: stamp_mutex--;
362: return;
363: }
364: #endif
365:
366: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
367: height = ri->ri_font->fontheight;
368: rs = ri->ri_stride;
369:
370: /* Recompute stamp? */
371: if (attr != stamp_attr)
372: rasops2_makestamp(ri, attr);
373:
374: if (uc == ' ') {
375: int8_t c = stamp[0];
376: while (height--) {
377: rp[0] = rp[1] = rp[2] = c;
378: rp += rs;
379: }
380: } else {
381: uc -= ri->ri_font->firstchar;
382: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
383: fs = ri->ri_font->stride;
384:
385: while (height--) {
386: rp[0] = stamp[(fr[0] >> 4) & 0xf];
387: rp[1] = stamp[fr[0] & 0xf];
388: rp[2] = stamp[(fr[1] >> 4) & 0xf];
389: fr += fs;
390: rp += rs;
391: }
392: }
393:
394: /* Do underline */
395: if ((attr & 1) != 0) {
396: rp -= ri->ri_stride << 1;
397: rp[0] = rp[1] = rp[2] = stamp[15];
398: }
399:
400: stamp_mutex--;
401: }
402:
403: /*
404: * Put a single character. This is for 16-pixel wide fonts.
405: */
406: void
407: rasops2_putchar16(cookie, row, col, uc, attr)
408: void *cookie;
409: int row, col;
410: u_int uc;
411: long attr;
412: {
413: struct rasops_info *ri;
414: int height, fs, rs;
415: u_char *fr, *rp;
416:
417: /* Can't risk remaking the stamp if it's already in use */
418: if (stamp_mutex++) {
419: stamp_mutex--;
420: rasops2_putchar(cookie, row, col, uc, attr);
421: return;
422: }
423:
424: ri = (struct rasops_info *)cookie;
425:
426: #ifdef RASOPS_CLIPPING
427: /* Catches 'row < 0' case too */
428: if ((unsigned)row >= (unsigned)ri->ri_rows) {
429: stamp_mutex--;
430: return;
431: }
432:
433: if ((unsigned)col >= (unsigned)ri->ri_cols) {
434: stamp_mutex--;
435: return;
436: }
437: #endif
438:
439: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
440: height = ri->ri_font->fontheight;
441: rs = ri->ri_stride;
442:
443: /* Recompute stamp? */
444: if (attr != stamp_attr)
445: rasops2_makestamp(ri, attr);
446:
447: if (uc == ' ') {
448: int8_t c = stamp[0];
449: while (height--) {
450: *(int32_t *)rp = c;
451: rp += rs;
452: }
453: } else {
454: uc -= ri->ri_font->firstchar;
455: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
456: fs = ri->ri_font->stride;
457:
458: while (height--) {
459: rp[0] = stamp[(fr[0] >> 4) & 0xf];
460: rp[1] = stamp[fr[0] & 0xf];
461: rp[2] = stamp[(fr[1] >> 4) & 0xf];
462: rp[3] = stamp[fr[1] & 0xf];
463: fr += fs;
464: rp += rs;
465: }
466: }
467:
468: /* Do underline */
469: if ((attr & 1) != 0)
470: *(int32_t *)(rp - (ri->ri_stride << 1)) = stamp[15];
471:
472: stamp_mutex--;
473: }
474: #endif /* !RASOPS_SMALL */
475:
476: /*
477: * Grab routines common to depths where (bpp < 8)
478: */
479: #define NAME(ident) rasops2_##ident
480: #define PIXEL_SHIFT 1
481:
482: #include <dev/rasops/rasops_bitops.h>
CVSweb