|
|
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.