|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_text_c = "$Header: text.c,v 10.1 86/11/19 10:44:22 jg Exp $";
3: #endif lint
4: /* Copyright 1985 Massachusetts Institute of Technology */
5:
6: /* text.c - X text based functions
7: *
8: * PrintText Prints text with source font
9: * PrintTextMask Prints text with mask font
10: * CopyText Copy text to bitmap
11: * TextWidth Returns width of a piece of text in a font
12: * CharWidth Returns width of a character in a font
13: * OffScreenText Utility rtn to optimize text blts using
14: * an offscreen buffer
15: * CopyScreenBits Utility rtn used to grab a rectangular area
16: * of the screen and place it in an offscreen buffer.
17: *
18: * Authors:
19: * Dan Stone & Scott Bates
20: * Brown University
21: * IRIS, Box 1946
22: * Providence, RI 02912
23: *
24: *
25: * Copyright (c) 1986 Brown University
26: *
27: * Permission to use, copy, modify and distribute this software and its
28: * documentation for any purpose and without fee is hereby granted, provided
29: * that the above copyright notice appear in all copies, and that both
30: * that copyright notice and this permission notice appear in supporting
31: * documentation, and that the name of Brown University not be used in
32: * advertising or publicity pertaining to distribution of the software
33: * without specific, written prior permission. Brown University makes no
34: * representations about the suitability of this software for any purpose.
35: * It is provided "as-is" without express or implied warranty.
36: */
37:
38: #include "private.h"
39: #include "bitblt.h"
40: #include "text.h"
41:
42: /*
43: * Print text with font as source
44: */
45:
46: PrintText (string, strlen, font, fore, back, charpad, spacepad, dstx, dsty,
47: clips, clipcount, func, zmask)
48: register char *string;
49: FONT *font;
50: register strlen, dstx;
51: register charpad, spacepad;
52: int fore, back, dsty;
53: CLIP *clips;
54: int clipcount, zmask;
55: int func;
56: {
57: FontPriv *fpriv = FDATA(font);
58: BITMAP *cbm = fpriv->chrs;
59: register c;
60: register charwidth;
61: register buf_wd, buf_ht;
62: register nchar;
63: register srcOx;
64: int srcCx;
65:
66: #ifdef TRACE_X
67: fprintf(stderr, "In PrintText\n");
68: fflush(stderr);
69: #endif TRACE_X
70:
71: /*
72: * Limit text to one plane
73: */
74: if ((zmask & 1) == 0)
75: return;
76:
77: /*
78: * Change combination rule to reflect specified
79: * foreground and background colors
80: */
81:
82: if (fore & 1)
83: func += 0x20;
84:
85: if (back & 1)
86: func += 0x10;
87:
88: func = FBMap[func];
89:
90: /*
91: * While we have more than CH_THRESHOLD characters then we will put
92: * the text into an offscreen buffer then blow it up onto the screen.
93: * When it drops below this threshold then it is no longer efficient
94: * to go to an offscreen buffer and we will go directly to the screen
95: * with bitblt.
96: */
97:
98: if (fpriv->offscr != NILBITMAP) {
99: while (strlen > CH_THRESHOLD) {
100: /*
101: * Make sure that CopyScreenBits() stays on the screen.
102: * Note: We are assuming the destination bitmap and the
103: * screen bitmap are already zero based and we
104: * are assuming that the txtbm is at least the
105: * width of the screen.
106: */
107:
108: if ((buf_ht = font->height) > (pbm.height - dsty)) {
109: buf_ht = pbm.height - dsty;
110: }
111:
112: if ((buf_wd = ((fpriv->maxwidth + charpad + spacepad) *
113: strlen)) > (pbm.width - dstx)) {
114: if ((buf_wd = pbm.width - dstx) > txtbm.width) {
115: buf_wd = txtbm.width;
116: }
117: }
118:
119: /*
120: * Make sure the sizes are non-zero.
121: */
122:
123: if (buf_ht < 1 || buf_wd < 1) {
124: break;
125: }
126:
127: /*
128: * Bring area on the screen into the offscreen buffer.
129: */
130:
131: CopyScreenBits(dstx, dsty, buf_wd, buf_ht, &txtbm);
132:
133: /*
134: * Blt as much text as one can into the offscreen
135: * buffer. NOTE: Because CopyScreenBits rounds over
136: * to a long word (4 bytes) boundary we must move
137: * the text over in the offscreen area by modulo 32.
138: * Also note that offscreen_text returns the source
139: * corner in srcCx.
140: */
141:
142: srcOx = dstx & 0x1F;
143: if ((nchar = OffScreenText(&txtbm,font,string,strlen,
144: charpad,spacepad,srcOx,
145: &srcCx,func)) < 1) {
146: /*
147: * Check nchar before going on and get out of
148: * the loop if its less than 1.
149: */
150:
151: break;
152: }
153:
154: /*
155: * Move the string up and the char count down.
156: */
157:
158: string += nchar;
159: strlen -= nchar;
160:
161: /*
162: * Put the offscreen buffer back onto the screen using
163: * CopyBits().
164: *
165: * Make source and destination rectangles.
166: */
167:
168: FillInRect(srcOx,0,srcCx - srcOx,buf_ht,&SrcRect);
169: FillInRect(dstx,dsty,(srcCx - srcOx),
170: buf_ht,&DstRect);
171:
172: /*
173: * Put the offscreen text buffer back onto the screen.
174: */
175:
176: CopyBits((u_short *)txtbm.data,txtbm.width,txtbm.height,
177: &SrcRect, (u_short *) pbm.data, pbm.width,
178: pbm.height, &DstRect, NILMASK, NIL, NIL,
179: GXcopy, clipcount, clips);
180:
181: /*
182: * Adjust destination address (dstx)
183: */
184:
185: dstx = DstRect.corner_x + charpad;
186: }
187: }
188:
189: /*
190: * Now loop thru the string until we are finished.....
191: */
192:
193: while (--strlen >= 0) {
194:
195: /*
196: * Character we are working on
197: */
198:
199: c = (int) (*string++);
200:
201: /*
202: * Check for legal character.
203: */
204:
205: if (c < font->first || c > font->last)
206: continue;
207:
208: /*
209: * Get width of current character
210: */
211:
212: if((charwidth = fpriv->widths[c]) > 0) {
213:
214: /*
215: * Make source and destination rectangles
216: */
217:
218: FillInRect(0,font->height * (c - font->first),
219: charwidth, font->height, &SrcRect);
220: FillInRect(dstx, dsty, charwidth, font->height,
221: &DstRect);
222:
223: /*
224: * Blt character to frame buffer
225: */
226:
227: CopyBits((u_short *) cbm->data, cbm->width, cbm->height,
228: &SrcRect, (u_short *) pbm.data, pbm.width,
229: pbm.height, &DstRect, NILMASK, NIL, NIL, func,
230: clipcount, clips);
231:
232: /*
233: * Adjust destination address (dstx)
234: */
235:
236: dstx += charwidth + charpad;
237: }
238:
239: /*
240: * Adjust destination address by size of space character
241: */
242:
243: if (c == font->space)
244: dstx += spacepad;
245: }
246: }
247:
248: /*
249: * Print text with font as mask
250: */
251:
252: PrintTextMask (string, strlen, font, srcpix, charpad, spacepad, dstx, dsty,
253: clips, clipcount, func, zmask)
254: register char *string;
255: FONT *font;
256: register strlen, charpad, spacepad, dstx;
257: int srcpix, dsty;
258: CLIP *clips;
259: int clipcount, zmask;
260: int func;
261: {
262: register FontPriv *fpriv = FDATA(font);
263: int charsize = BitmapSize(fpriv->maxwidth, font->height);
264: u_short *charmask;
265: register charwidth;
266: register c;
267: register srcOx;
268: register nchar;
269: int srcCx;
270:
271: #ifdef TRACE_X
272: fprintf (stderr, "In PrintTextMask\n");
273: fflush (stderr);
274: #endif TRACE_X
275:
276: /*
277: * Limit text to one plane
278: */
279:
280: if ((zmask & 1) == 0)
281: return;
282:
283: /*
284: * While we have more than CH_THRESHOLD characters then we will put
285: * the text into an offscreen buffer then blow it up onto the screen.
286: * When it drops below this threshold then it is no longer efficient
287: * to go to an offscreen buffer and we will go directly to the screen
288: * with bitblt.
289: */
290:
291: if (fpriv->offscr != NILBITMAP) {
292: while (strlen > CH_THRESHOLD) {
293:
294: /*
295: * Clear the offscreen buffer area.
296: */
297:
298: bzero((char *)txtbm.data,
299: (font->height * ((txtbm.width + 15)/16)) << 1);
300:
301: /*
302: * Blt as much text as one can into the offscreen
303: * buffer. Note that offscreen_text returns the source
304: * corner in srcCx.
305: */
306:
307: srcOx = dstx & 0xF;
308: if ((nchar = OffScreenText(&txtbm,font,string,strlen,
309: charpad,spacepad,srcOx,
310: &srcCx,GXcopy)) < 1) {
311: /*
312: * Check nchar before going on and get out of
313: * the loop if its less than 1.
314: */
315:
316: break;
317: }
318:
319: /*
320: * Move the string up and the char count down.
321: */
322:
323: string += nchar;
324: strlen -= nchar;
325:
326: /*
327: * Put the offscreen buffer back onto the screen using
328: * CopyBits().
329: *
330: * Make source and destination rectangles.
331: */
332:
333: FillInRect((dstx - srcOx),dsty,srcCx,
334: font->height,&DstRect);
335:
336: /*
337: * Using the offscreen bitmap as a mask, copy
338: * the text to the screen.
339: */
340:
341: CopyBits((u_short *) ConstantTiles[srcpix & 1],
342: NIL, NIL, NILRECT,
343: (u_short *) pbm.data, pbm.width, pbm.height,
344: &DstRect, (u_short *)txtbm.data, txtbm.width,
345: font->height, MAKE_TILE_RULE(func), clipcount,
346: clips);
347:
348: /*
349: * Adjust destination address (dstx)
350: */
351:
352: dstx = DstRect.corner_x + charwidth + charpad;
353: }
354: }
355:
356: /*
357: * Now loop thru the string until we are finished.....
358: */
359:
360: while (--strlen >= 0) {
361:
362: /*
363: * Character we are working on
364: */
365:
366: c = (int) (*string++);
367:
368: /*
369: * Check for legal character.
370: */
371:
372: if (c < font->first || c > font->last)
373: continue;
374:
375: /*
376: * Get width of current character
377: */
378:
379: if((charwidth = fpriv->widths[c]) > 0) {
380:
381: /*
382: * Use character as clipping mask
383: */
384:
385: charmask = (u_short *) ((long) fpriv->chrs->data +
386: charsize * (c - font->first));
387:
388: /*
389: * Fill in destination rectangle
390: */
391:
392: FillInRect(dstx, dsty, charwidth, font->height,
393: &DstRect);
394:
395: /*
396: * Blt character to frame buffer using font
397: * character as mask
398: */
399:
400: CopyBits((u_short *) ConstantTiles[srcpix & 1], NIL,
401: NIL, NILRECT, (u_short *) pbm.data, pbm.width,
402: pbm.height, &DstRect,
403: charmask, charwidth, font->height,
404: MAKE_TILE_RULE(func), clipcount, clips);
405:
406: /*
407: * Adjust destination address (dstx) by character
408: * pad amount
409: */
410:
411: dstx += charwidth + charpad;
412: }
413:
414: /*
415: * Adjust destination address by size of space character
416: */
417:
418: if (c == font->space)
419: dstx += spacepad;
420: }
421: }
422:
423: /*
424: * Copy text to bitmap
425: */
426:
427: CopyText (string, strlen, font, bm)
428: register char *string;
429: register strlen;
430: FONT *font;
431: BITMAP *bm;
432: {
433: register FontPriv *fpriv = FDATA(font);
434: BITMAP *cbm = fpriv->chrs;
435: register c;
436: register charwidth;
437: register dstx = 0;
438:
439: #ifdef TRACE_X
440: fprintf(stderr, "In CopyText\n");
441: fflush(stderr);
442: #endif TRACE_X
443:
444: /*
445: * loop thru string until we are finished.....
446: */
447:
448: while (--strlen >= 0) {
449:
450: /*
451: * Character we are working on
452: */
453:
454: c = (int) (*string++);
455:
456: /*
457: * Check for legal character.
458: */
459:
460: if (c < font->first || c > font->last)
461: continue;
462:
463: /*
464: * Get width of current character
465: */
466:
467: if((charwidth = fpriv->widths[c]) == 0)
468: continue;
469:
470: /*
471: * Fill in source and destination rectangles
472: */
473:
474: FillInRect(0,font->height * (c - font->first),
475: charwidth, font->height, &SrcRect);
476: FillInRect(dstx, 0, charwidth, font->height, &DstRect);
477:
478: /*
479: * Blt character to bitmap
480: */
481:
482: CopyBits((u_short *)cbm->data,cbm->width, cbm->height, &SrcRect,
483: (u_short *) bm->data, bm->width, bm->height, &DstRect,
484: NILMASK, NIL, NIL, GXcopy, 0, NILCLIP);
485:
486: /*
487: * Adjust destination address (dstx)
488: */
489:
490: dstx += charwidth;
491: }
492: }
493:
494: /*
495: * Compute width of a piece of text in a font
496: */
497:
498: int TextWidth (string, strlen, spacepad, font)
499: register char *string;
500: register int strlen;
501: int spacepad;
502: register FONT *font;
503: {
504: register u_int c;
505: register short *widths;
506: register int width = 0;
507:
508: #ifdef TRACE_X
509: fprintf(stderr, "In TextWidth\n");
510: fflush(stderr);
511: #endif TRACE_X
512:
513: if (font->fixed) {
514: /*
515: * Font is fixed width
516: */
517:
518: /*
519: * Compute total width of text string
520: */
521:
522: width = strlen * font->avg_width;
523:
524: if (spacepad) {
525: /*
526: * Add spacepad amount to the total width for each
527: * space character found in text string
528: */
529:
530: while (--strlen >= 0) {
531: if (*string++ == font->space)
532: width += spacepad;
533: }
534: }
535: } else {
536: /*
537: * Font is variable width
538: */
539:
540:
541: /*
542: * get pointer to width table
543: */
544:
545: widths = FDATA(font)->widths;
546:
547: /*
548: * Loop thru text string
549: */
550:
551: while (--strlen >= 0) {
552: /*
553: * Get current character
554: */
555:
556: c = *string++;
557: if (c >= font->first && c <= font->last) {
558: /*
559: * Valid character
560: */
561:
562: if (c == font->space) {
563: /*
564: * Character is a space so add
565: * spacepad amount to total width
566: */
567:
568: width += spacepad;
569: }
570:
571: /*
572: * Find width of this character in width
573: * table and add it to total
574: */
575:
576: width += widths[c];
577: }
578: }
579: }
580: return (width);
581: }
582:
583: /*
584: * Determine width of a character in a font
585: */
586:
587: int CharWidth(c, font)
588: register u_int c;
589: register FONT *font;
590: {
591: #ifdef TRACE_X
592: fprintf(stderr, "In CharWidth\n");
593: fflush(stderr);
594: #endif TRACE_X
595:
596: if (c < font->first || c > font->last)
597: /*
598: * Character not in font
599: */
600:
601: return (0);
602: else if (font->fixed)
603: /*
604: * Font is a fixed width so return the
605: * average character width for the font
606: */
607:
608: return (font->avg_width);
609: else
610: /*
611: * Font is variable width so determine
612: * width of character from font width table
613: */
614:
615: return (FDATA(font)->widths[c]);
616: }
617:
618: /*
619: * OffScreenText puts text from "font" into "buf_bm". It assumes the font
620: * bitmap * has its characters "left justified". It returns the rightmost
621: * X position in "cornerX".
622: */
623:
624: static
625: OffScreenText(buf_bm,font,string,ch_count,ch_pad,sp_pad,dstX,cornerX,func)
626: BITMAP *buf_bm; /* Offscreen buffer bitmap */
627: FONT *font; /* Font structure */
628: char *string; /* String of characters to be put up. */
629: int ch_count; /* Number of characters in the string */
630: int ch_pad; /* Space between characters */
631: int sp_pad; /* Amount of space a pad character is. */
632: int dstX; /* The spot in the offscreen buffer where
633: the text is to start. */
634: int *cornerX; /* Send the rightmost X position back to the
635: caller for use with the bltter. */
636: int func; /* Function (or combination rule) to be used
637: with text */
638: {
639: register u_char *dst;
640: register u_char *src;
641: register u_long src_nextline, dst_nextline;
642: register int height;
643: register u_short leftmask, rtmask;
644: int c, shift, ndst_shorts, inv_shift, i, start_dst;
645: int dst_nextcol, src_nextcol, nsrc_shorts, ht_plus1;
646: short chrs_nshorts, buf_nshorts;
647: u_long bitptr;
648: long maxbitptr;
649: int shorts_per_char;
650: u_char *chrs_data;
651: FontPriv *fpriv = FDATA(font);
652: short *char_widths = fpriv->widths;
653:
654: #ifdef TRACE_X
655: fprintf (stderr, "In OffScreenText\n");
656: fflush (stderr);
657: #endif TRACE_X
658:
659: /*
660: * Calculate, in shorts, the width of both the chrs and
661: * buffer bitmaps.
662: */
663:
664: chrs_nshorts = BTOW(fpriv->maxwidth);
665:
666: maxbitptr = fpriv->offscr->width;
667: buf_nshorts = BTOW(maxbitptr);
668:
669: /*
670: * Set up to go through the string of characters.
671: */
672:
673: bitptr = dstX;
674:
675: src_nextline = MUL_2(chrs_nshorts);
676: dst_nextline = MUL_2(buf_nshorts);
677:
678: /*
679: * Setup for text blt
680: */
681:
682: ht_plus1 = font->height + 1;
683: shorts_per_char = MUL_2(chrs_nshorts * font->height);
684: chrs_data = (u_char *)fpriv->chrs->data;
685:
686: /*
687: * Blt text string into offscreen buffer
688: */
689:
690: switch (func) {
691: case (GXclear):
692: CopyText_LOOP(GXclear_MASK, GXclear_OP);
693: break;
694:
695: case (GXand):
696: CopyText_LOOP(GXand_MASK, GXand_OP);
697: break;
698:
699: case (GXandReverse):
700: CopyText_LOOP(GXandReverse_MASK, GXandReverse_OP);
701: break;
702:
703: case (GXcopy):
704: CopyText_LOOP(GXcopy_MASK, GXcopy_OP);
705: break;
706:
707: case (GXandInverted):
708: CopyText_LOOP(GXandInverted_MASK, GXandInverted_OP);
709: break;
710:
711: case (GXnoop):
712: break;
713:
714: case (GXxor):
715: CopyText_LOOP(GXxor_MASK, GXxor_OP);
716: break;
717:
718: case (GXor):
719: CopyText_LOOP(GXor_MASK, GXor_OP);
720: break;
721:
722: case (GXnor):
723: CopyText_LOOP(GXnor_MASK, GXnor_OP);
724: break;
725:
726: case (GXequiv):
727: CopyText_LOOP(GXequiv_MASK, GXequiv_OP);
728: break;
729:
730: case (GXinvert):
731: CopyText_LOOP(GXinvert_MASK, GXinvert_OP);
732: break;
733:
734: case (GXorReverse):
735: CopyText_LOOP(GXorReverse_MASK, GXorReverse_OP);
736: break;
737:
738: case (GXcopyInverted):
739: CopyText_LOOP(GXcopyInverted_MASK, GXcopyInverted_OP);
740: break;
741:
742: case (GXorInverted):
743: CopyText_LOOP(GXorInverted_MASK, GXorInverted_OP);
744: break;
745:
746: case (GXnand):
747: CopyText_LOOP(GXnand_MASK, GXnand_OP);
748: break;
749:
750: case (GXset):
751: CopyText_LOOP(GXset_MASK, GXset_OP);
752: break;
753: }
754:
755: /*
756: * Remove the last charcter pad added to the last character.
757: */
758:
759: bitptr -= ch_pad;
760:
761: /*
762: * Return right most X value and character count to caller
763: */
764:
765: if (bitptr > dstX)
766: *cornerX = bitptr;
767: else
768: *cornerX = dstX;
769: return(ch_count);
770: }
771:
772: #if (APA8 || APA8C)
773:
774: #define DSTBITS ((u_short *)DstBits)
775: #define SRCBITS ((u_short *)SrcBits)
776: #define SIZE_OF_SHORT (sizeof(u_short))
777: #define SIZE_OF_APA8_SHORT (sizeof(u_short) * 2)
778:
779: /*
780: * Copy shorts off of the screen (pbm) into the destination bitmap.
781: */
782:
783: static
784: CopyScreenBits(StartX, StartY, Width, Height, DstBitmap)
785: int StartX, StartY;
786: int Width;
787: register Height;
788: BITMAP *DstBitmap;
789: {
790: register nwords;
791: register char *DstBits;
792: register DstRowBytes;
793: register SrcRowBytes;
794: register char *SrcBits;
795:
796: #ifdef TRACE_X
797: fprintf (stderr, "In CopyScreenBits\n");
798: fflush (stderr);
799: #endif TRACE_X
800:
801: /*
802: * Check StartX and StartY and offset the destination pointer if
803: * one or both are negative and change the source pointer.
804: */
805:
806: if (StartX < 0) {
807: /*
808: * Make sure there are words to be taken off the screen.
809: */
810:
811: if ((nwords = BTOW(StartX + Width)) < 1) {
812: return;
813: }
814: DstRowBytes = MUL_2(DIV_BPW(DstBitmap->width) - nwords);
815: SrcRowBytes = MUL_4(DIV_BPW(pbm.width));
816: DstBits = (char *)DstBitmap->data + MUL_2(DIV_BPW(-StartX));
817:
818: if (StartY < 0) {
819: /*
820: * Figure out the number of scanlines to be copied.
821: */
822:
823: if ((Height += StartY) < 1) {
824: return;
825: }
826:
827: DstBits += (-StartY * (DstBitmap->width >> 3));
828: SrcBits = (char *)pbm.data;
829: } else {
830: SrcBits = (char *)pbm.data + (StartY * SrcRowBytes);
831: }
832: } else {
833: /*
834: * Make sure there are words to be taken off the screen.
835: */
836:
837: if ((nwords = BTOW(StartX + Width) - DIV_BPW(StartX)) < 1) {
838: return;
839: }
840:
841: DstRowBytes = MUL_2(DIV_BPW(DstBitmap->width) - nwords);
842: SrcRowBytes = MUL_4(DIV_BPW(pbm.width));
843: DstBits = (char *)DstBitmap->data;
844:
845: if (StartY < 0) {
846: /*
847: * Figure out the number of scanlines to be copied.
848: */
849:
850: if ((Height += StartY) < 1) {
851: return;
852: }
853:
854: DstBits += (-StartY * (DstBitmap->width >> 3));
855: SrcBits = (char *)pbm.data + MUL_4(DIV_BPW(StartX));
856: } else {
857: SrcBits = (char *)pbm.data + (StartY * SrcRowBytes) +
858: MUL_4(BTOW(StartX));
859: }
860: }
861:
862:
863: if (nwords > 1) { /* more than one short wide */
864: int tmpnWords = nwords;
865:
866: SrcRowBytes -= MUL_4(nwords);
867: while(1) {
868: do {
869: *DSTBITS = *SRCBITS;
870: DstBits += SIZE_OF_SHORT;
871: SrcBits += SIZE_OF_APA8_SHORT;
872: } while(--nwords > 0);
873:
874: if(--Height) {
875: DstBits += DstRowBytes;
876: SrcBits += SrcRowBytes;
877: nwords = tmpnWords;
878: } else {
879: break;
880: }
881: }
882: } else { /* one short wide */
883: /*
884: * Should not have subtracted (nwords << 2) from
885: * DstRowBytes. So now that we know nwords == 1 we will
886: * add (nwords << 2) == 4 back to DstRowBytes.
887: */
888:
889: DstRowBytes += 4;
890:
891: while(1) {
892: *DSTBITS = *SRCBITS;
893: if(--Height) {
894: DstBits += DstRowBytes;
895: SrcBits += SrcRowBytes;
896: } else {
897: break;
898: }
899: }
900: }
901: }
902:
903: #else
904:
905: #define DSTBITS ((u_long *)DstBits)
906: #define SRCBITS ((u_long *)SrcBits)
907: #define SIZE_OF_LONG sizeof(u_long)
908:
909: /*
910: * Copy long words off of the screen (pbm) into the destination bitmap.
911: */
912:
913: static
914: CopyScreenBits(StartX, StartY, Width, Height, DstBitmap)
915: int StartX, StartY;
916: int Width;
917: register Height;
918: BITMAP *DstBitmap;
919: {
920: register nwords;
921: register char *DstBits;
922: register DstRowBytes;
923: register SrcRowBytes;
924: register char *SrcBits;
925: #if (APA16 && USE_APA16_HDWR)
926: int tmp;
927: #endif (APA16 && USE_APA16_HDWR)
928:
929: #ifdef TRACE_X
930: fprintf (stderr, "In CopyScreenBits\n");
931: fflush (stderr);
932: #endif TRACE_X
933:
934: /*
935: * Check StartX and StartY and offset the destination pointer if
936: * one or both are negative and change the source pointer.
937: */
938:
939: if (StartX < 0) {
940: /*
941: * Make sure there are words to be taken off the screen.
942: */
943:
944: if ((nwords = BTOL(StartX + Width)) < 1) {
945: return;
946: }
947:
948: /*
949: * DstRowBytes and SrcRowBytes are MUL_4'ed so that
950: * they are the number of BYTES the address must be incremented.
951: */
952:
953: DstRowBytes = MUL_4(DIV_BPL(DstBitmap->width) - nwords);
954: SrcRowBytes = MUL_4(DIV_BPL(pbm.width));
955: DstBits = (char *)DstBitmap->data + MUL_4(DIV_BPL(-StartX));
956:
957: if (StartY < 0) {
958: /*
959: * Figure out the number of scanlines to be copied.
960: */
961:
962: if ((Height += StartY) < 1) {
963: return;
964: }
965:
966: DstBits += (-StartY * (DstBitmap->width >> 3));
967: SrcBits = (char *)pbm.data;
968: } else {
969: SrcBits = (char *)pbm.data + (StartY*SrcRowBytes);
970: }
971: } else {
972: /*
973: * Make sure there are words to be taken off the screen.
974: */
975:
976: if ((nwords = BTOL(StartX + Width) - DIV_BPL(StartX)) < 1) {
977: return;
978: }
979:
980: DstRowBytes = MUL_4(DIV_BPL(DstBitmap->width) - nwords);
981: SrcRowBytes = MUL_4(DIV_BPL(pbm.width));
982: DstBits = (char *)DstBitmap->data;
983:
984: if (StartY < 0) {
985: /*
986: * Figure out the number of scanlines to be copied.
987: */
988:
989: if ((Height += StartY) < 1) {
990: return;
991: }
992:
993: DstBits += (-StartY * (DstBitmap->width >> 3));
994: SrcBits = (char *)pbm.data + MUL_4(DIV_BPL(StartX));
995: } else {
996: SrcBits = (char *)pbm.data + (StartY * SrcRowBytes) +
997: MUL_4(DIV_BPL(StartX));
998: }
999: }
1000:
1001: #if (APA16 && USE_APA16_HDWR)
1002: #include "../bitblt/bitblt_apa16.h"
1003: /*
1004: * If we are using the APA-16 hardware then we must wait for the
1005: * hardware to be done with the screen.
1006: */
1007:
1008: WAIT_QUE(tmp, 0);
1009: #endif (APA16 && USE_APA16_HDWR)
1010:
1011: if (nwords > 1) { /* more than one long wide */
1012: int tmpnWords = nwords;
1013:
1014: SrcRowBytes -= MUL_4(nwords);
1015: while(1) {
1016: do {
1017: *DSTBITS = *SRCBITS;
1018: DstBits += SIZE_OF_LONG;
1019: SrcBits += SIZE_OF_LONG;
1020: } while(--nwords > 0);
1021:
1022: if(--Height) {
1023: DstBits += DstRowBytes;
1024: SrcBits += SrcRowBytes;
1025: nwords = tmpnWords;
1026: } else {
1027: break;
1028: }
1029: }
1030: } else { /* one long wide */
1031: /*
1032: * Should not have subtracted MUL_4(nwords) from
1033: * DstRowBytes. So now that we know nwords == 1 we will
1034: * add MUL_4(nwords) == 4 back to DstRowBytes.
1035: */
1036:
1037: DstRowBytes += 4;
1038:
1039: while(1) {
1040: *DSTBITS = *SRCBITS;
1041: if(--Height) {
1042: DstBits += DstRowBytes;
1043: SrcBits += SrcRowBytes;
1044: } else {
1045: break;
1046: }
1047: }
1048: }
1049: }
1050: #endif (APA8 || APA8C)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.