Annotation of sys/dev/rasops/rasops8.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: rasops8.c,v 1.7 2006/12/02 15:55:18 miod Exp $ */
2: /* $NetBSD: rasops8.c,v 1.8 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:
44: #include <dev/wscons/wsdisplayvar.h>
45: #include <dev/wscons/wsconsio.h>
46: #include <dev/rasops/rasops.h>
47:
48: void rasops8_putchar(void *, int, int, u_int, long attr);
49: #ifndef RASOPS_SMALL
50: void rasops8_putchar8(void *, int, int, u_int, long attr);
51: void rasops8_putchar12(void *, int, int, u_int, long attr);
52: void rasops8_putchar16(void *, int, int, u_int, long attr);
53: void rasops8_makestamp(struct rasops_info *ri, long);
54:
55: /*
56: * 4x1 stamp for optimized character blitting
57: */
58: static int32_t stamp[16];
59: static long stamp_attr;
60: static int stamp_mutex; /* XXX see note in README */
61: #endif
62:
63: /*
64: * XXX this confuses the hell out of gcc2 (not egcs) which always insists
65: * that the shift count is negative.
66: *
67: * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
68: * destination = STAMP_READ(offset)
69: */
70: #define STAMP_SHIFT(fb,n) ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
71: #define STAMP_MASK (0xf << 2)
72: #define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
73:
74: /*
75: * Initialize a 'rasops_info' descriptor for this depth.
76: */
77: void
78: rasops8_init(ri)
79: struct rasops_info *ri;
80: {
81:
82: switch (ri->ri_font->fontwidth) {
83: #ifndef RASOPS_SMALL
84: case 8:
85: ri->ri_ops.putchar = rasops8_putchar8;
86: break;
87: case 12:
88: ri->ri_ops.putchar = rasops8_putchar12;
89: break;
90: case 16:
91: ri->ri_ops.putchar = rasops8_putchar16;
92: break;
93: #endif /* !RASOPS_SMALL */
94: default:
95: ri->ri_ops.putchar = rasops8_putchar;
96: break;
97: }
98: }
99:
100: /*
101: * Put a single character.
102: */
103: void
104: rasops8_putchar(cookie, row, col, uc, attr)
105: void *cookie;
106: int row, col;
107: u_int uc;
108: long attr;
109: {
110: int width, height, cnt, fs, fb;
111: u_char *dp, *rp, *fr, clr[2];
112: struct rasops_info *ri;
113:
114: ri = (struct rasops_info *)cookie;
115:
116: #ifdef RASOPS_CLIPPING
117: /* Catches 'row < 0' case too */
118: if ((unsigned)row >= (unsigned)ri->ri_rows)
119: return;
120:
121: if ((unsigned)col >= (unsigned)ri->ri_cols)
122: return;
123: #endif
124: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
125:
126: height = ri->ri_font->fontheight;
127: width = ri->ri_font->fontwidth;
128: clr[0] = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
129: clr[1] = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
130:
131: if (uc == ' ') {
132: u_char c = clr[0];
133:
134: while (height--) {
135: dp = rp;
136: rp += ri->ri_stride;
137:
138: for (cnt = width; cnt; cnt--)
139: *dp++ = c;
140: }
141: } else {
142: uc -= ri->ri_font->firstchar;
143: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
144: fs = ri->ri_font->stride;
145:
146: while (height--) {
147: dp = rp;
148: fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
149: fr += fs;
150: rp += ri->ri_stride;
151:
152: for (cnt = width; cnt; cnt--) {
153: *dp++ = clr[(fb >> 31) & 1];
154: fb <<= 1;
155: }
156: }
157: }
158:
159: /* Do underline */
160: if ((attr & 1) != 0) {
161: u_char c = clr[1];
162:
163: rp -= (ri->ri_stride << 1);
164:
165: while (width--)
166: *rp++ = c;
167: }
168: }
169:
170: #ifndef RASOPS_SMALL
171: /*
172: * Recompute the 4x1 blitting stamp.
173: */
174: void
175: rasops8_makestamp(ri, attr)
176: struct rasops_info *ri;
177: long attr;
178: {
179: int32_t fg, bg;
180: int i;
181:
182: fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff;
183: bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff;
184: stamp_attr = attr;
185:
186: for (i = 0; i < 16; i++) {
187: #if BYTE_ORDER == LITTLE_ENDIAN
188: stamp[i] = (i & 8 ? fg : bg);
189: stamp[i] |= ((i & 4 ? fg : bg) << 8);
190: stamp[i] |= ((i & 2 ? fg : bg) << 16);
191: stamp[i] |= ((i & 1 ? fg : bg) << 24);
192: #else
193: stamp[i] = (i & 1 ? fg : bg);
194: stamp[i] |= ((i & 2 ? fg : bg) << 8);
195: stamp[i] |= ((i & 4 ? fg : bg) << 16);
196: stamp[i] |= ((i & 8 ? fg : bg) << 24);
197: #endif
198: #if NRASOPS_BSWAP > 0
199: if (ri->ri_flg & RI_BSWAP)
200: stamp[i] = swap32(stamp[i]);
201: #endif
202: }
203: }
204:
205: /*
206: * Put a single character. This is for 8-pixel wide fonts.
207: */
208: void
209: rasops8_putchar8(cookie, row, col, uc, attr)
210: void *cookie;
211: int row, col;
212: u_int uc;
213: long attr;
214: {
215: struct rasops_info *ri;
216: int height, fs;
217: int32_t *rp;
218: u_char *fr;
219:
220: /* Can't risk remaking the stamp if it's already in use */
221: if (stamp_mutex++) {
222: stamp_mutex--;
223: rasops8_putchar(cookie, row, col, uc, attr);
224: return;
225: }
226:
227: ri = (struct rasops_info *)cookie;
228:
229: #ifdef RASOPS_CLIPPING
230: if ((unsigned)row >= (unsigned)ri->ri_rows) {
231: stamp_mutex--;
232: return;
233: }
234:
235: if ((unsigned)col >= (unsigned)ri->ri_cols) {
236: stamp_mutex--;
237: return;
238: }
239: #endif
240:
241: /* Recompute stamp? */
242: if (attr != stamp_attr)
243: rasops8_makestamp(ri, attr);
244:
245: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
246: height = ri->ri_font->fontheight;
247:
248: if (uc == ' ') {
249: while (height--) {
250: rp[0] = rp[1] = stamp[0];
251: DELTA(rp, ri->ri_stride, int32_t *);
252: }
253: } else {
254: uc -= ri->ri_font->firstchar;
255: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
256: fs = ri->ri_font->stride;
257:
258: while (height--) {
259: rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
260: rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
261:
262: fr += fs;
263: DELTA(rp, ri->ri_stride, int32_t *);
264: }
265: }
266:
267: /* Do underline */
268: if ((attr & 1) != 0) {
269: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
270: rp[0] = rp[1] = stamp[15];
271: }
272:
273: stamp_mutex--;
274: }
275:
276: /*
277: * Put a single character. This is for 12-pixel wide fonts.
278: */
279: void
280: rasops8_putchar12(cookie, row, col, uc, attr)
281: void *cookie;
282: int row, col;
283: u_int uc;
284: long attr;
285: {
286: struct rasops_info *ri;
287: int height, fs;
288: int32_t *rp;
289: u_char *fr;
290:
291: /* Can't risk remaking the stamp if it's already in use */
292: if (stamp_mutex++) {
293: stamp_mutex--;
294: rasops8_putchar(cookie, row, col, uc, attr);
295: return;
296: }
297:
298: ri = (struct rasops_info *)cookie;
299:
300: #ifdef RASOPS_CLIPPING
301: if ((unsigned)row >= (unsigned)ri->ri_rows) {
302: stamp_mutex--;
303: return;
304: }
305:
306: if ((unsigned)col >= (unsigned)ri->ri_cols) {
307: stamp_mutex--;
308: return;
309: }
310: #endif
311:
312: /* Recompute stamp? */
313: if (attr != stamp_attr)
314: rasops8_makestamp(ri, attr);
315:
316: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
317: height = ri->ri_font->fontheight;
318:
319: if (uc == ' ') {
320: while (height--) {
321: int32_t c = stamp[0];
322:
323: rp[0] = rp[1] = rp[2] = c;
324: DELTA(rp, ri->ri_stride, int32_t *);
325: }
326: } else {
327: uc -= ri->ri_font->firstchar;
328: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
329: fs = ri->ri_font->stride;
330:
331: while (height--) {
332: rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
333: rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
334: rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
335:
336: fr += fs;
337: DELTA(rp, ri->ri_stride, int32_t *);
338: }
339: }
340:
341: /* Do underline */
342: if ((attr & 1) != 0) {
343: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
344: rp[0] = rp[1] = rp[2] = stamp[15];
345: }
346:
347: stamp_mutex--;
348: }
349:
350: /*
351: * Put a single character. This is for 16-pixel wide fonts.
352: */
353: void
354: rasops8_putchar16(cookie, row, col, uc, attr)
355: void *cookie;
356: int row, col;
357: u_int uc;
358: long attr;
359: {
360: struct rasops_info *ri;
361: int height, fs;
362: int32_t *rp;
363: u_char *fr;
364:
365: /* Can't risk remaking the stamp if it's already in use */
366: if (stamp_mutex++) {
367: stamp_mutex--;
368: rasops8_putchar(cookie, row, col, uc, attr);
369: return;
370: }
371:
372: ri = (struct rasops_info *)cookie;
373:
374: #ifdef RASOPS_CLIPPING
375: if ((unsigned)row >= (unsigned)ri->ri_rows) {
376: stamp_mutex--;
377: return;
378: }
379:
380: if ((unsigned)col >= (unsigned)ri->ri_cols) {
381: stamp_mutex--;
382: return;
383: }
384: #endif
385:
386: /* Recompute stamp? */
387: if (attr != stamp_attr)
388: rasops8_makestamp(ri, attr);
389:
390: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
391: height = ri->ri_font->fontheight;
392:
393: if (uc == ' ') {
394: while (height--)
395: rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
396: } else {
397: uc -= ri->ri_font->firstchar;
398: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
399: fs = ri->ri_font->stride;
400:
401: while (height--) {
402: rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
403: rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
404: rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
405: rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
406:
407: fr += fs;
408: DELTA(rp, ri->ri_stride, int32_t *);
409: }
410: }
411:
412: /* Do underline */
413: if ((attr & 1) != 0) {
414: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
415: rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
416: }
417:
418: stamp_mutex--;
419: }
420: #endif /* !RASOPS_SMALL */
CVSweb