Annotation of sys/dev/rasops/rasops24.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: rasops24.c,v 1.5 2002/07/27 22:17:49 miod Exp $ */
2: /* $NetBSD: rasops24.c,v 1.12 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 <machine/endian.h>
45:
46: #include <dev/wscons/wsdisplayvar.h>
47: #include <dev/wscons/wsconsio.h>
48: #include <dev/rasops/rasops.h>
49:
50: void rasops24_erasecols(void *, int, int, int, long);
51: void rasops24_eraserows(void *, int, int, long);
52: void rasops24_putchar(void *, int, int, u_int, long attr);
53: #ifndef RASOPS_SMALL
54: void rasops24_putchar8(void *, int, int, u_int, long attr);
55: void rasops24_putchar12(void *, int, int, u_int, long attr);
56: void rasops24_putchar16(void *, int, int, u_int, long attr);
57: void rasops24_makestamp(struct rasops_info *, long);
58:
59: /*
60: * 4x1 stamp for optimized character blitting
61: */
62: static int32_t stamp[64];
63: static long stamp_attr;
64: static int stamp_mutex; /* XXX see note in readme */
65: #endif
66:
67: /*
68: * XXX this confuses the hell out of gcc2 (not egcs) which always insists
69: * that the shift count is negative.
70: *
71: * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
72: * destination int32_t[0] = STAMP_READ(offset)
73: * destination int32_t[1] = STAMP_READ(offset + 4)
74: * destination int32_t[2] = STAMP_READ(offset + 8)
75: */
76: #define STAMP_SHIFT(fb,n) ((n*4-4) >= 0 ? (fb)>>(n*4-4):(fb)<<-(n*4-4))
77: #define STAMP_MASK (0xf << 4)
78: #define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
79:
80: /*
81: * Initialize rasops_info struct for this colordepth.
82: */
83: void
84: rasops24_init(ri)
85: struct rasops_info *ri;
86: {
87:
88: switch (ri->ri_font->fontwidth) {
89: #ifndef RASOPS_SMALL
90: case 8:
91: ri->ri_ops.putchar = rasops24_putchar8;
92: break;
93: case 12:
94: ri->ri_ops.putchar = rasops24_putchar12;
95: break;
96: case 16:
97: ri->ri_ops.putchar = rasops24_putchar16;
98: break;
99: #endif
100: default:
101: ri->ri_ops.putchar = rasops24_putchar;
102: break;
103: }
104:
105: if (ri->ri_rnum == 0) {
106: ri->ri_rnum = 8;
107: ri->ri_rpos = 0;
108: ri->ri_gnum = 8;
109: ri->ri_gpos = 8;
110: ri->ri_bnum = 8;
111: ri->ri_bpos = 16;
112: }
113:
114: ri->ri_ops.erasecols = rasops24_erasecols;
115: ri->ri_ops.eraserows = rasops24_eraserows;
116: }
117:
118: /*
119: * Put a single character. This is the generic version.
120: * XXX this bites - we should use masks.
121: */
122: void
123: rasops24_putchar(cookie, row, col, uc, attr)
124: void *cookie;
125: int row, col;
126: u_int uc;
127: long attr;
128: {
129: int fb, width, height, cnt, clr[2];
130: struct rasops_info *ri;
131: u_char *dp, *rp, *fr;
132:
133: ri = (struct rasops_info *)cookie;
134:
135: #ifdef RASOPS_CLIPPING
136: /* Catches 'row < 0' case too */
137: if ((unsigned)row >= (unsigned)ri->ri_rows)
138: return;
139:
140: if ((unsigned)col >= (unsigned)ri->ri_cols)
141: return;
142: #endif
143:
144: rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
145: height = ri->ri_font->fontheight;
146: width = ri->ri_font->fontwidth;
147:
148: clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
149: clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
150:
151: if (uc == ' ') {
152: u_char c = clr[0];
153: while (height--) {
154: dp = rp;
155: rp += ri->ri_stride;
156:
157: for (cnt = width; cnt; cnt--) {
158: *dp++ = c >> 16;
159: *dp++ = c >> 8;
160: *dp++ = c;
161: }
162: }
163: } else {
164: uc -= ri->ri_font->firstchar;
165: fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
166:
167: while (height--) {
168: dp = rp;
169: fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
170: (fr[0] << 24);
171: fr += ri->ri_font->stride;
172: rp += ri->ri_stride;
173:
174: for (cnt = width; cnt; cnt--, fb <<= 1) {
175: if ((fb >> 31) & 1) {
176: *dp++ = clr[1] >> 16;
177: *dp++ = clr[1] >> 8;
178: *dp++ = clr[1];
179: } else {
180: *dp++ = clr[0] >> 16;
181: *dp++ = clr[0] >> 8;
182: *dp++ = clr[0];
183: }
184: }
185: }
186: }
187:
188: /* Do underline */
189: if ((attr & 1) != 0) {
190: u_char c = clr[1];
191:
192: rp -= ri->ri_stride << 1;
193:
194: while (width--) {
195: *rp++ = c >> 16;
196: *rp++ = c >> 8;
197: *rp++ = c;
198: }
199: }
200: }
201:
202: #ifndef RASOPS_SMALL
203: /*
204: * Recompute the blitting stamp.
205: */
206: void
207: rasops24_makestamp(ri, attr)
208: struct rasops_info *ri;
209: long attr;
210: {
211: u_int fg, bg, c1, c2, c3, c4;
212: int i;
213:
214: fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff;
215: bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff;
216: stamp_attr = attr;
217:
218: for (i = 0; i < 64; i += 4) {
219: #if BYTE_ORDER == LITTLE_ENDIAN
220: c1 = (i & 32 ? fg : bg);
221: c2 = (i & 16 ? fg : bg);
222: c3 = (i & 8 ? fg : bg);
223: c4 = (i & 4 ? fg : bg);
224: #else
225: c1 = (i & 8 ? fg : bg);
226: c2 = (i & 4 ? fg : bg);
227: c3 = (i & 16 ? fg : bg);
228: c4 = (i & 32 ? fg : bg);
229: #endif
230: stamp[i+0] = (c1 << 8) | (c2 >> 16);
231: stamp[i+1] = (c2 << 16) | (c3 >> 8);
232: stamp[i+2] = (c3 << 24) | c4;
233:
234: #if BYTE_ORDER == LITTLE_ENDIAN
235: if ((ri->ri_flg & RI_BSWAP) == 0) {
236: #else
237: if ((ri->ri_flg & RI_BSWAP) != 0) {
238: #endif
239: stamp[i+0] = swap32(stamp[i+0]);
240: stamp[i+1] = swap32(stamp[i+1]);
241: stamp[i+2] = swap32(stamp[i+2]);
242: }
243: }
244: }
245:
246: /*
247: * Put a single character. This is for 8-pixel wide fonts.
248: */
249: void
250: rasops24_putchar8(cookie, row, col, uc, attr)
251: void *cookie;
252: int row, col;
253: u_int uc;
254: long attr;
255: {
256: struct rasops_info *ri;
257: int height, so, fs;
258: int32_t *rp;
259: u_char *fr;
260:
261: /* Can't risk remaking the stamp if it's already in use */
262: if (stamp_mutex++) {
263: stamp_mutex--;
264: rasops24_putchar(cookie, row, col, uc, attr);
265: return;
266: }
267:
268: ri = (struct rasops_info *)cookie;
269:
270: #ifdef RASOPS_CLIPPING
271: if ((unsigned)row >= (unsigned)ri->ri_rows) {
272: stamp_mutex--;
273: return;
274: }
275:
276: if ((unsigned)col >= (unsigned)ri->ri_cols) {
277: stamp_mutex--;
278: return;
279: }
280: #endif
281:
282: /* Recompute stamp? */
283: if (attr != stamp_attr)
284: rasops24_makestamp(ri, attr);
285:
286: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
287: height = ri->ri_font->fontheight;
288:
289: if (uc == (u_int)-1) {
290: int32_t c = stamp[0];
291: while (height--) {
292: rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
293: DELTA(rp, ri->ri_stride, int32_t *);
294: }
295: } else {
296: uc -= ri->ri_font->firstchar;
297: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
298: fs = ri->ri_font->stride;
299:
300: while (height--) {
301: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
302: rp[0] = STAMP_READ(so);
303: rp[1] = STAMP_READ(so + 4);
304: rp[2] = STAMP_READ(so + 8);
305:
306: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
307: rp[3] = STAMP_READ(so);
308: rp[4] = STAMP_READ(so + 4);
309: rp[5] = STAMP_READ(so + 8);
310:
311: fr += fs;
312: DELTA(rp, ri->ri_stride, int32_t *);
313: }
314: }
315:
316: /* Do underline */
317: if ((attr & 1) != 0) {
318: int32_t c = STAMP_READ(52);
319:
320: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
321: rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
322: }
323:
324: stamp_mutex--;
325: }
326:
327: /*
328: * Put a single character. This is for 12-pixel wide fonts.
329: */
330: void
331: rasops24_putchar12(cookie, row, col, uc, attr)
332: void *cookie;
333: int row, col;
334: u_int uc;
335: long attr;
336: {
337: struct rasops_info *ri;
338: int height, so, fs;
339: int32_t *rp;
340: u_char *fr;
341:
342: /* Can't risk remaking the stamp if it's already in use */
343: if (stamp_mutex++) {
344: stamp_mutex--;
345: rasops24_putchar(cookie, row, col, uc, attr);
346: return;
347: }
348:
349: ri = (struct rasops_info *)cookie;
350:
351: #ifdef RASOPS_CLIPPING
352: if ((unsigned)row >= (unsigned)ri->ri_rows) {
353: stamp_mutex--;
354: return;
355: }
356:
357: if ((unsigned)col >= (unsigned)ri->ri_cols) {
358: stamp_mutex--;
359: return;
360: }
361: #endif
362:
363: /* Recompute stamp? */
364: if (attr != stamp_attr)
365: rasops24_makestamp(ri, attr);
366:
367: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
368: height = ri->ri_font->fontheight;
369:
370: if (uc == (u_int)-1) {
371: int32_t c = stamp[0];
372: while (height--) {
373: rp[0] = rp[1] = rp[2] = rp[3] =
374: rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
375: DELTA(rp, ri->ri_stride, int32_t *);
376: }
377: } else {
378: uc -= ri->ri_font->firstchar;
379: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
380: fs = ri->ri_font->stride;
381:
382: while (height--) {
383: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
384: rp[0] = STAMP_READ(so);
385: rp[1] = STAMP_READ(so + 4);
386: rp[2] = STAMP_READ(so + 8);
387:
388: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
389: rp[3] = STAMP_READ(so);
390: rp[4] = STAMP_READ(so + 4);
391: rp[5] = STAMP_READ(so + 8);
392:
393: so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
394: rp[6] = STAMP_READ(so);
395: rp[7] = STAMP_READ(so + 4);
396: rp[8] = STAMP_READ(so + 8);
397:
398: fr += fs;
399: DELTA(rp, ri->ri_stride, int32_t *);
400: }
401: }
402:
403: /* Do underline */
404: if ((attr & 1) != 0) {
405: int32_t c = STAMP_READ(52);
406:
407: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
408: rp[0] = rp[1] = rp[2] = rp[3] =
409: rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
410: }
411:
412: stamp_mutex--;
413: }
414:
415: /*
416: * Put a single character. This is for 16-pixel wide fonts.
417: */
418: void
419: rasops24_putchar16(cookie, row, col, uc, attr)
420: void *cookie;
421: int row, col;
422: u_int uc;
423: long attr;
424: {
425: struct rasops_info *ri;
426: int height, so, fs;
427: int32_t *rp;
428: u_char *fr;
429:
430: /* Can't risk remaking the stamp if it's already in use */
431: if (stamp_mutex++) {
432: stamp_mutex--;
433: rasops24_putchar(cookie, row, col, uc, attr);
434: return;
435: }
436:
437: ri = (struct rasops_info *)cookie;
438:
439: #ifdef RASOPS_CLIPPING
440: if ((unsigned)row >= (unsigned)ri->ri_rows) {
441: stamp_mutex--;
442: return;
443: }
444:
445: if ((unsigned)col >= (unsigned)ri->ri_cols) {
446: stamp_mutex--;
447: return;
448: }
449: #endif
450:
451: /* Recompute stamp? */
452: if (attr != stamp_attr)
453: rasops24_makestamp(ri, attr);
454:
455: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
456: height = ri->ri_font->fontheight;
457:
458: if (uc == (u_int)-1) {
459: int32_t c = stamp[0];
460: while (height--) {
461: rp[0] = rp[1] = rp[2] = rp[3] =
462: rp[4] = rp[5] = rp[6] = rp[7] =
463: rp[8] = rp[9] = rp[10] = rp[11] = c;
464: DELTA(rp, ri->ri_stride, int32_t *);
465: }
466: } else {
467: uc -= ri->ri_font->firstchar;
468: fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
469: fs = ri->ri_font->stride;
470:
471: while (height--) {
472: so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
473: rp[0] = STAMP_READ(so);
474: rp[1] = STAMP_READ(so + 4);
475: rp[2] = STAMP_READ(so + 8);
476:
477: so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
478: rp[3] = STAMP_READ(so);
479: rp[4] = STAMP_READ(so + 4);
480: rp[5] = STAMP_READ(so + 8);
481:
482: so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
483: rp[6] = STAMP_READ(so);
484: rp[7] = STAMP_READ(so + 4);
485: rp[8] = STAMP_READ(so + 8);
486:
487: so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
488: rp[9] = STAMP_READ(so);
489: rp[10] = STAMP_READ(so + 4);
490: rp[11] = STAMP_READ(so + 8);
491:
492: DELTA(rp, ri->ri_stride, int32_t *);
493: fr += fs;
494: }
495: }
496:
497: /* Do underline */
498: if ((attr & 1) != 0) {
499: int32_t c = STAMP_READ(52);
500:
501: DELTA(rp, -(ri->ri_stride << 1), int32_t *);
502: rp[0] = rp[1] = rp[2] = rp[3] =
503: rp[4] = rp[5] = rp[6] = rp[7] =
504: rp[8] = rp[9] = rp[10] = rp[11] = c;
505: }
506:
507: stamp_mutex--;
508: }
509: #endif /* !RASOPS_SMALL */
510:
511: /*
512: * Erase rows. This is nice and easy due to alignment.
513: */
514: void
515: rasops24_eraserows(cookie, row, num, attr)
516: void *cookie;
517: int row, num;
518: long attr;
519: {
520: int n9, n3, n1, cnt, stride, delta;
521: u_int32_t *dp, clr, stamp[3];
522: struct rasops_info *ri;
523:
524: /*
525: * If the color is gray, we can cheat and use the generic routines
526: * (which are faster, hopefully) since the r,g,b values are the same.
527: */
528: if ((attr & 4) != 0) {
529: rasops_eraserows(cookie, row, num, attr);
530: return;
531: }
532:
533: ri = (struct rasops_info *)cookie;
534:
535: #ifdef RASOPS_CLIPPING
536: if (row < 0) {
537: num += row;
538: row = 0;
539: }
540:
541: if ((row + num) > ri->ri_rows)
542: num = ri->ri_rows - row;
543:
544: if (num <= 0)
545: return;
546: #endif
547:
548: clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
549: stamp[0] = (clr << 8) | (clr >> 16);
550: stamp[1] = (clr << 16) | (clr >> 8);
551: stamp[2] = (clr << 24) | clr;
552:
553: #if BYTE_ORDER == LITTLE_ENDIAN
554: if ((ri->ri_flg & RI_BSWAP) == 0) {
555: #else
556: if ((ri->ri_flg & RI_BSWAP) != 0) {
557: #endif
558: stamp[0] = swap32(stamp[0]);
559: stamp[1] = swap32(stamp[1]);
560: stamp[2] = swap32(stamp[2]);
561: }
562:
563: /*
564: * XXX the wsdisplay_emulops interface seems a little deficient in
565: * that there is no way to clear the *entire* screen. We provide a
566: * workaround here: if the entire console area is being cleared, and
567: * the RI_FULLCLEAR flag is set, clear the entire display.
568: */
569: if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
570: stride = ri->ri_stride;
571: num = ri->ri_height;
572: dp = (int32_t *)ri->ri_origbits;
573: delta = 0;
574: } else {
575: stride = ri->ri_emustride;
576: num *= ri->ri_font->fontheight;
577: dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
578: delta = ri->ri_delta;
579: }
580:
581: n9 = stride / 36;
582: cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
583: n3 = (stride - cnt) / 12;
584: cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
585: n1 = (stride - cnt) >> 2;
586:
587: while (num--) {
588: for (cnt = n9; cnt; cnt--) {
589: dp[0] = stamp[0];
590: dp[1] = stamp[1];
591: dp[2] = stamp[2];
592: dp[3] = stamp[0];
593: dp[4] = stamp[1];
594: dp[5] = stamp[2];
595: dp[6] = stamp[0];
596: dp[7] = stamp[1];
597: dp[8] = stamp[2];
598: dp += 9;
599: }
600:
601: for (cnt = n3; cnt; cnt--) {
602: dp[0] = stamp[0];
603: dp[1] = stamp[1];
604: dp[2] = stamp[2];
605: dp += 3;
606: }
607:
608: for (cnt = 0; cnt < n1; cnt++)
609: *dp++ = stamp[cnt];
610:
611: DELTA(dp, delta, int32_t *);
612: }
613: }
614:
615: /*
616: * Erase columns.
617: */
618: void
619: rasops24_erasecols(cookie, row, col, num, attr)
620: void *cookie;
621: int row, col, num;
622: long attr;
623: {
624: int n12, n4, height, cnt, slop, clr, stamp[3];
625: struct rasops_info *ri;
626: int32_t *dp, *rp;
627: u_char *dbp;
628:
629: /*
630: * If the color is gray, we can cheat and use the generic routines
631: * (which are faster, hopefully) since the r,g,b values are the same.
632: */
633: if ((attr & 4) != 0) {
634: rasops_erasecols(cookie, row, col, num, attr);
635: return;
636: }
637:
638: ri = (struct rasops_info *)cookie;
639:
640: #ifdef RASOPS_CLIPPING
641: /* Catches 'row < 0' case too */
642: if ((unsigned)row >= (unsigned)ri->ri_rows)
643: return;
644:
645: if (col < 0) {
646: num += col;
647: col = 0;
648: }
649:
650: if ((col + num) > ri->ri_cols)
651: num = ri->ri_cols - col;
652:
653: if (num <= 0)
654: return;
655: #endif
656:
657: rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
658: num *= ri->ri_font->fontwidth;
659: height = ri->ri_font->fontheight;
660:
661: clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
662: stamp[0] = (clr << 8) | (clr >> 16);
663: stamp[1] = (clr << 16) | (clr >> 8);
664: stamp[2] = (clr << 24) | clr;
665:
666: #if BYTE_ORDER == LITTLE_ENDIAN
667: if ((ri->ri_flg & RI_BSWAP) == 0) {
668: #else
669: if ((ri->ri_flg & RI_BSWAP) != 0) {
670: #endif
671: stamp[0] = swap32(stamp[0]);
672: stamp[1] = swap32(stamp[1]);
673: stamp[2] = swap32(stamp[2]);
674: }
675:
676: /*
677: * The current byte offset mod 4 tells us the number of 24-bit pels
678: * we need to write for alignment to 32-bits. Once we're aligned on
679: * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so
680: * the stamp does not need to be rotated. The following shows the
681: * layout of 4 pels in a 3 word region and illustrates this:
682: *
683: * aaab bbcc cddd
684: */
685: slop = (long)rp & 3; num -= slop;
686: n12 = num / 12; num -= (n12 << 3) + (n12 << 2);
687: n4 = num >> 2; num &= 3;
688:
689: while (height--) {
690: dbp = (u_char *)rp;
691: DELTA(rp, ri->ri_stride, int32_t *);
692:
693: /* Align to 4 bytes */
694: /* XXX handle with masks, bring under control of RI_BSWAP */
695: for (cnt = slop; cnt; cnt--) {
696: *dbp++ = (clr >> 16);
697: *dbp++ = (clr >> 8);
698: *dbp++ = clr;
699: }
700:
701: dp = (int32_t *)dbp;
702:
703: /* 12 pels per loop */
704: for (cnt = n12; cnt; cnt--) {
705: dp[0] = stamp[0];
706: dp[1] = stamp[1];
707: dp[2] = stamp[2];
708: dp[3] = stamp[0];
709: dp[4] = stamp[1];
710: dp[5] = stamp[2];
711: dp[6] = stamp[0];
712: dp[7] = stamp[1];
713: dp[8] = stamp[2];
714: dp += 9;
715: }
716:
717: /* 4 pels per loop */
718: for (cnt = n4; cnt; cnt--) {
719: dp[0] = stamp[0];
720: dp[1] = stamp[1];
721: dp[2] = stamp[2];
722: dp += 3;
723: }
724:
725: /* Trailing slop */
726: /* XXX handle with masks, bring under control of RI_BSWAP */
727: dbp = (u_char *)dp;
728: for (cnt = num; cnt; cnt--) {
729: *dbp++ = (clr >> 16);
730: *dbp++ = (clr >> 8);
731: *dbp++ = clr;
732: }
733: }
734: }
CVSweb