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