|
|
1.1 ! root 1: /* ! 2: * text.c ! 3: * ! 4: * Copyright (c) 1985 Massachusetts Institue of Technology ! 5: * Copyright (c) 1986 Sun Microsystems, Inc. ! 6: * Copyright (c) 1986 David C. Martin, UC Berkeley ! 7: * ! 8: * David C. Martin ! 9: * ARPA: [email protected] ! 10: * UUCP: ..!ucbvax!dcmartin ! 11: * ! 12: * $Log: text.c,v $ ! 13: * Revision 10.5 86/11/29 13:48:49 jg ! 14: * fixes from Berkeley ! 15: * ! 16: * Revision 1.10 86/07/27 13:49:58 dcmartin ! 17: * removed debugging statements ! 18: * ! 19: * Revision 1.9 86/07/25 14:45:48 dcmartin ! 20: * modified PrintTextMask() to handle variable width fonts ! 21: * ! 22: * Revision 1.8 86/07/17 10:37:29 dcmartin ! 23: * release version w/ support for variable width text ! 24: * ! 25: * Revision 1.7 86/07/17 10:32:19 dcmartin ! 26: * ! 27: */ ! 28: ! 29: #ifndef lint ! 30: static char rcs_id[] = "$Header: text.c,v 10.5 86/11/29 13:48:49 jg Rel $"; ! 31: #endif lint ! 32: ! 33: #include <X/mit-copyright.h> ! 34: ! 35: /* ! 36: * The Sun X drivers are a product of Sun Microsystems, Inc. and are provided ! 37: * for unrestricted use provided that this legend is included on all tape ! 38: * media and as a part of the software program in whole or part. Users ! 39: * may copy or modify these drivers without charge, but are not authorized ! 40: * to license or distribute them to anyone else except as part of a product or ! 41: * program developed by the user. ! 42: * ! 43: * THE SUN X DRIVERS ARE PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND ! 44: * INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A ! 45: * PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE ! 46: * PRACTICE. ! 47: * ! 48: * The Sun X Drivers are provided with no support and without any obligation ! 49: * on the part of Sun Microsystems, Inc. to assist in their use, correction, ! 50: * modification or enhancement. ! 51: * ! 52: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE ! 53: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THE SUN X ! 54: * DRIVERS OR ANY PART THEREOF. ! 55: * ! 56: * In no event will Sun Microsystems, Inc. be liable for any lost revenue ! 57: * or profits or other special, indirect and consequential damages, even if ! 58: * Sun has been advised of the possibility of such damages. ! 59: * ! 60: * Sun Microsystems, Inc. ! 61: * 2550 Garcia Avenue ! 62: * Mountain View, California 94043 ! 63: */ ! 64: ! 65: #ifdef sun ! 66: ! 67: /* ! 68: * ToDo: ! 69: * Color ! 70: */ ! 71: ! 72: #include "Xsun.h" ! 73: #ifndef stdin ! 74: #include <stdio.h> ! 75: #endif ! 76: #include <pixrect/memreg.h> ! 77: #include <pixrect/cg2reg.h> ! 78: ! 79: /* I've put in some rather ugly hacks, in the name of performance. The ! 80: global variables private_* are really extra parameters to the batchrop ! 81: routines. I did this, rather than adding parameters, because I wanted to ! 82: do the least violence to the "official" specs of batchrop -- this way X ! 83: will vaguely work on displays that don't use one of the tuned batchrops. ! 84: JAG */ ! 85: ! 86: int private_fgcolor, private_bgcolor, private_czmask; ! 87: ! 88: extern struct pixrect *PixRect; ! 89: ! 90: #define MAXCHARS 400 ! 91: ! 92: extern int ! 93: PrintText(text, textlen, font, fore, back, charpad, spacepad, dstx, dsty, ! 94: clips, clipcount, func, zmask) ! 95: register unsigned char *text; ! 96: FONT *font; ! 97: int textlen, fore, back, charpad, spacepad, dstx, dsty; ! 98: CLIP *clips; ! 99: int clipcount, zmask; ! 100: int func; ! 101: { ! 102: extern CURSOR *CurrentCursor; ! 103: extern CursorDisplayed; ! 104: int cleft, ctop, cwidth, cheight; ! 105: int op; ! 106: extern char FBMap[]; ! 107: unsigned char *limit = text + ! 108: (textlen < MAXCHARS ? textlen : MAXCHARS); ! 109: register int w = 0; ! 110: int bsize = 0; ! 111: int lheight; ! 112: int sbot, sright; ! 113: static struct pr_prpos bat[MAXCHARS]; ! 114: ! 115: private_czmask = zmask; ! 116: private_fgcolor = fore; ! 117: private_bgcolor = back; ! 118: if (fore & 1) ! 119: func += 0x20; ! 120: if (back & 1) ! 121: func += 0x10; ! 122: func = FBMap[func]; ! 123: op = SUN_FROM_X_OP(func) | PIX_COLOR(fore); ! 124: /* this is a gross abuse of C, but ... */ ! 125: { ! 126: register struct pixfont *pf; ! 127: register struct pr_prpos *p; ! 128: register struct pixchar *pc; ! 129: register int pwidth = 0; ! 130: ! 131: pf = (struct pixfont *) font->data; ! 132: p = bat; ! 133: lheight = pf->pf_defaultsize.y; ! 134: if (charpad == 0 && spacepad == 0) { ! 135: /* for each character in the text */ ! 136: while (text < limit) { ! 137: pc = &(pf->pf_char[*text++]); ! 138: if (pc == 0 || pc->pc_pr == NULL) ! 139: continue; ! 140: p->pr = pc->pc_pr; ! 141: /* ! 142: * pr_batchrop() is confusing... ! 143: * you must give the offset for the previous ! 144: * pixrect ! 145: */ ! 146: p->pos.x = pwidth; ! 147: /* store the character width */ ! 148: pwidth = pc->pc_adv.x; ! 149: /* increment the total width */ ! 150: w += pwidth; ! 151: p++; ! 152: bsize++; ! 153: } ! 154: } else { ! 155: /* for efficiency ... */ ! 156: struct pixchar *space = &(pf->pf_char[font->space]); ! 157: ! 158: while (text < limit) { ! 159: pc = &(pf->pf_char[*text++]); ! 160: if (pc == (struct pixchar *) NULL || ! 161: pc->pc_pr == (struct pixrect *) NULL) ! 162: continue; ! 163: p->pr = pc->pc_pr; ! 164: /* ! 165: * pr_batchrop() is confusing... ! 166: * you must give the offset for the previous ! 167: * pixrect ! 168: */ ! 169: p->pos.x = pwidth; ! 170: /* store the character width */ ! 171: pwidth = pc->pc_adv.x + charpad; ! 172: /* add space? */ ! 173: if (pc == space) ! 174: pwidth += spacepad; ! 175: /* increment the total width */ ! 176: w += pwidth; ! 177: p++; ! 178: bsize++; ! 179: } ! 180: } ! 181: } /* end gross abuse */ ! 182: /* determine the right and bottom of the region */ ! 183: sbot = dsty + lheight; ! 184: sright = dstx + w; ! 185: /* if the cursor is where we want to put text get rid of it */ ! 186: if (CursorDisplayed) { ! 187: extern DEVICE *CurrentDevice; ! 188: register vsCursor *ms = CurrentDevice->mouse; ! 189: register CURSOR *cs = CurrentCursor; ! 190: ! 191: if (ms->y < sbot && ! 192: ms->x < sright && ! 193: ms->y + cs->height > dsty && ! 194: ms->x + cs->width > dstx) ! 195: DisplayCursor(NULL); ! 196: } ! 197: do { ! 198: GetNextClip(clips, cleft, ctop, cwidth, cheight); ! 199: if (dsty >= ctop && ! 200: sbot <= ctop + cheight && ! 201: dstx >= cleft && ! 202: sright <= cleft + cwidth) { ! 203: pr_batchrop(PixRect, dstx - bat[0].pos.x, dsty, ! 204: op | PIX_DONTCLIP, bat, bsize); ! 205: } else { ! 206: struct pixrect *region; ! 207: ! 208: if (dsty > ctop + cheight) ! 209: continue; ! 210: if (dsty + lheight <= ctop) ! 211: continue; ! 212: region = pr_region(PixRect, cleft, ctop, cwidth, ! 213: cheight); ! 214: pr_batchrop(region, dstx - cleft - bat[0].pos.x, ! 215: dsty - ctop, op, bat, bsize); ! 216: pr_destroy(region); ! 217: } ! 218: } while (--clipcount > 0); ! 219: /* redisplay the cursor if we zapped it */ ! 220: if (!CursorDisplayed) ! 221: DisplayCursor(CurrentCursor); ! 222: } /* end PrintText() */ ! 223: ! 224: extern int ! 225: PrintTextMask(text, textlen, font, srcpix, charpad, spacepad, dstx, dsty, ! 226: clips, clipcount, func, zmask) ! 227: unsigned char *text; ! 228: FONT *font; ! 229: int textlen, srcpix, charpad, spacepad, dstx, dsty; ! 230: CLIP *clips; ! 231: int clipcount, zmask; ! 232: register int func; ! 233: { ! 234: extern CURSOR *CurrentCursor; ! 235: extern CursorDisplayed; ! 236: int cleft, ctop, cwidth, cheight; ! 237: int op; ! 238: extern char SSMap[]; ! 239: unsigned char *limit = text + ! 240: (textlen < MAXCHARS ? textlen : MAXCHARS); ! 241: register int w = 0; ! 242: static struct pr_prpos bat[MAXCHARS]; ! 243: int bsize = 0, lheight, sbot, sright; ! 244: ! 245: SetZmask(PixRect, &zmask); ! 246: private_bgcolor = -1; ! 247: private_fgcolor = srcpix; ! 248: if (PixRect->pr_depth == 1) { ! 249: if ((srcpix & 1) == 0) ! 250: func += 0x10; ! 251: op = SUN_FROM_X_OP(SSMap[func]) & ! 252: PIX_SRC | PIX_NOT(PIX_SRC) & PIX_DST; ! 253: } else ! 254: op = SUN_FROM_X_OP(func); ! 255: if (PixRect->pr_depth > 1) ! 256: op |= PIX_COLOR(srcpix); ! 257: /* this is a gross abuse of C, but ... */ ! 258: { ! 259: register struct pixfont *pf; ! 260: register struct pr_prpos *p; ! 261: register struct pixchar *pc; ! 262: register int pwidth = 0; ! 263: ! 264: pf = (struct pixfont *) font->data; ! 265: p = bat; ! 266: lheight = pf->pf_defaultsize.y; ! 267: if (charpad == 0 && spacepad == 0) { ! 268: /* for each character in the text */ ! 269: while (text < limit) { ! 270: pc = &(pf->pf_char[*text++]); ! 271: if (pc == 0 || pc->pc_pr == NULL) ! 272: continue; ! 273: p->pr = pc->pc_pr; ! 274: /* ! 275: * pr_batchrop() is confusing... ! 276: * you must give the offset for the previous ! 277: * pixrect ! 278: */ ! 279: p->pos.x = pwidth; ! 280: /* store the character width */ ! 281: pwidth = pc->pc_adv.x; ! 282: /* increment the total width */ ! 283: w += pwidth; ! 284: p++; ! 285: bsize++; ! 286: } ! 287: } else { ! 288: /* for efficiency ... */ ! 289: struct pixchar *space = &(pf->pf_char[font->space]); ! 290: ! 291: while (text < limit) { ! 292: pc = &(pf->pf_char[*text++]); ! 293: if (pc == 0 || pc->pc_pr == NULL) ! 294: continue; ! 295: p->pr = pc->pc_pr; ! 296: /* ! 297: * pr_batchrop() is confusing... ! 298: * you must give the offset for the previous ! 299: * pixrect ! 300: */ ! 301: p->pos.x = pwidth; ! 302: /* store the character width */ ! 303: pwidth = pc->pc_adv.x + charpad; ! 304: /* add space? */ ! 305: if (pc == space) ! 306: pwidth += spacepad; ! 307: /* increment the total width */ ! 308: w += pwidth; ! 309: p++; ! 310: bsize++; ! 311: } ! 312: } ! 313: } /* end gross abuse */ ! 314: /* determine right/bottom corner */ ! 315: sbot = dsty + lheight; ! 316: sright = dstx + w; ! 317: /* if the cursor is display where we wish to output -- zap it */ ! 318: if (CursorDisplayed) { ! 319: extern DEVICE *CurrentDevice; ! 320: register vsCursor *ms = CurrentDevice->mouse; ! 321: register CURSOR *cs = CurrentCursor; ! 322: ! 323: if (ms->y < sbot && ! 324: ms->x < sright && ! 325: ms->y + cs->height > dsty && ! 326: ms->x + cs->width > dstx) ! 327: DisplayCursor(NULL); ! 328: } ! 329: do { ! 330: GetNextClip(clips, cleft, ctop, cwidth, cheight); ! 331: if (dsty >= ctop && ! 332: sbot <= ctop + cheight && ! 333: dstx >= cleft && ! 334: sright <= cleft + cwidth) ! 335: pr_batchrop(PixRect, dstx - bat[0].pos.x, dsty, ! 336: op | PIX_DONTCLIP, bat, bsize); ! 337: else { ! 338: struct pixrect *region; ! 339: if (dsty > ctop + cheight) ! 340: continue; ! 341: if (dsty + lheight <= ctop) ! 342: continue; ! 343: region = pr_region(PixRect, cleft, ctop, cwidth, ! 344: cheight); ! 345: pr_batchrop(region, dstx - cleft - bat[0].pos.x, ! 346: dsty - ctop, op, bat, bsize); ! 347: pr_destroy(region); ! 348: } ! 349: } while (--clipcount > 0); ! 350: /* restore cursor if we zapped it */ ! 351: if (!CursorDisplayed) ! 352: DisplayCursor(CurrentCursor); ! 353: /* another gross abuse of C... */ ! 354: { ! 355: static allmask = -1; ! 356: ! 357: SetZmask(PixRect, &allmask); ! 358: } ! 359: } /* end PrintTextMask() */ ! 360: ! 361: ! 362: /* ! 363: * Copyright (c) 1983 by Sun Microsystems, Inc. ! 364: */ ! 365: ! 366: /* ! 367: * Memory batchrop ! 368: */ ! 369: ! 370: ! 371: extern char pr_reversedst[]; ! 372: extern struct pixrectops mem_ops; ! 373: ! 374: ! 375: ! 376: #define MEMBATCH(IfClip, IfMask, op, IfReverse) \ ! 377: for (; --count >= 0; src++) { \ ! 378: dst.pos.x += src->pos.x; \ ! 379: dp = dp0 + (((dskew = xoff0 + dst.pos.x) >> 3) & ~1); \ ! 380: dskew &= 0xF; \ ! 381: spr = src->pr; \ ! 382: sizex = spr->pr_size.x; \ ! 383: sizey = spr->pr_size.y; \ ! 384: sprd = mpr_d(spr); \ ! 385: if (sprd->md_linebytes != 2) \ ! 386: goto hard; \ ! 387: sp = (u_short *) sprd->md_image; \ ! 388: IfClip( if (dst.pos.x + sizex > limx) \ ! 389: goto hard; \ ! 390: if (dst.pos.y + sizey > limy) \ ! 391: sizey = limy - dst.pos.y; \ ! 392: if (dst.pos.x < 0) \ ! 393: goto hard; \ ! 394: if (dst.pos.y < 0) { \ ! 395: sizey += dst.pos.y; \ ! 396: sp -= dst.pos.y; \ ! 397: dp -= pr_product(dst.pos.y, vert); \ ! 398: } \ ! 399: if (sizex <= 0) \ ! 400: continue; \ ! 401: ,) \ ! 402: if (--sizey>=0) \ ! 403: if (dskew + sizex <= 16) { \ ! 404: IfMask( register short mask; \ ! 405: mask = 0x8000; \ ! 406: sizex -= 1; \ ! 407: mask >>= sizex; \ ! 408: ((unsigned short) mask) >>= dskew; \ ! 409: IfReverse(mask = ~mask;,),) \ ! 410: do { \ ! 411: IfMask(*(u_short *) dp IfReverse(&,|)= mask;,) \ ! 412: *(u_short *) dp op (*sp++ >> dskew); \ ! 413: dp += vert; \ ! 414: } while (--sizey != -1); \ ! 415: } \ ! 416: else { \ ! 417: IfMask( register long mask; \ ! 418: mask = 0x80000000; \ ! 419: sizex -= 1; \ ! 420: mask >>= sizex; \ ! 421: ((unsigned long) mask) >>= dskew; \ ! 422: IfReverse(mask = ~mask;,),) \ ! 423: dskew = 16 - dskew; \ ! 424: do { \ ! 425: IfMask(*(u_int *) dp IfReverse(&,|)= mask;,) \ ! 426: *(u_int *) dp op (*sp++ << dskew); \ ! 427: dp += vert; \ ! 428: } while (--sizey != -1); \ ! 429: } \ ! 430: } ! 431: ! 432: #define MTRUE(a,b) a ! 433: #define MFALSE(a,b) b ! 434: ! 435: #define ClippedOp(mask,op,revmask) \ ! 436: if(clip) MEMBATCH(MTRUE,mask,op,revmask) \ ! 437: else MEMBATCH(MFALSE,mask,op,revmask) ! 438: ! 439: mem_batchrop(dst, op, src, count) ! 440: struct pr_prpos dst; ! 441: int op; ! 442: struct pr_prpos *src; ! 443: short count; ! 444: { ! 445: register u_short *sp; ! 446: register char *dp; ! 447: char *dp0; ! 448: register char *handy; ! 449: register short sizex, sizey; ! 450: register vert, dskew; ! 451: int dskew0, xoff0; ! 452: int errors = 0; ! 453: int clip, limx, limy; ! 454: int oppassed = op; ! 455: ! 456: /* ! 457: * Preliminaries: get pixrect data and image pointers; decide whether ! 458: * clipping. If not clipping, normalize op, else compute limits for ! 459: * cursors for later comparisons. ! 460: */ ! 461: ! 462: clip = 0; ! 463: if (!(op & PIX_DONTCLIP)) { ! 464: clip = 1; ! 465: limx = dst.pr->pr_size.x; ! 466: limy = dst.pr->pr_size.y; ! 467: } ! 468: op = (op >> 1) & 0xf; /* Kill dontclip, just keep useful */ ! 469: /* ! 470: * If destination is reverse video, invert function. FIXME: we dont ! 471: * deal with a reverse video source. Admittedly its unlikely that ! 472: * anyone will call batchrop with a device pixrect as source (since we ! 473: * copy the whole pixrect), but this is a bug. ! 474: */ ! 475: if (mpr_d(dst.pr)->md_flags & MP_REVERSEVIDEO) ! 476: op = pr_reversedst[op]; ! 477: ! 478: vert = mpr_d(dst.pr)->md_linebytes; ! 479: #define dprd ((struct mpr_data *)handy) ! 480: dprd = mpr_d(dst.pr); ! 481: xoff0 = dprd->md_offset.x; ! 482: dp0 = (char *) ((int) dprd->md_image ! 483: + pr_product(dprd->md_linebytes, ! 484: dst.pos.y + dprd->md_offset.y)); ! 485: #undef dprd ! 486: restart: ! 487: #define spr ((struct pixrect *)handy) ! 488: #define sprd ((struct mpr_data *)handy) ! 489: switch (op) { ! 490: case (PIX_SRC ^ PIX_DST) >> 1: ! 491: ClippedOp(MFALSE, ^=, MTRUE); ! 492: break; ! 493: case PIX_SRC >> 1: ! 494: ClippedOp(MTRUE, |=, MTRUE); ! 495: break; ! 496: case PIX_NOT(PIX_SRC) >> 1: ! 497: ClippedOp(MTRUE, ^=, MFALSE); ! 498: break; ! 499: case (PIX_SRC | PIX_DST) >> 1: ! 500: ClippedOp(MFALSE, |=, MTRUE); ! 501: break; ! 502: case (PIX_NOT(PIX_SRC) & PIX_DST) >> 1: ! 503: ClippedOp(MFALSE, &=~, MTRUE); ! 504: break; ! 505: default: ! 506: for (; --count >= 0; src++) { ! 507: dst.pos.x += src->pos.x; ! 508: errors |= mem_rop(dst.pr, dst.pos, src->pr->pr_size, ! 509: oppassed, src->pr, 0, 0); ! 510: } ! 511: } ! 512: return errors; ! 513: hard: ! 514: if (dst.pos.x + sizex <= 0) ! 515: /* ! 516: * Completely clipped on left... ! 517: */ ! 518: ; ! 519: else { ! 520: errors |= mem_rop(dst.pr, dst.pos, src->pr->pr_size, ! 521: oppassed, src->pr, 0, 0); ! 522: } ! 523: src++; ! 524: goto restart; ! 525: } ! 526: ! 527: /* ! 528: * cg2batch.c: Sun2 Color batchrop ! 529: */ ! 530: ! 531: extern struct pixrectops mem_ops; ! 532: ! 533: ! 534: extern short mrc_lmasktable[]; ! 535: extern short mrc_rmasktable[]; ! 536: ! 537: #define resolution unused, 0 ! 538: ! 539: cg2_batchrop(dst, op, src, count) ! 540: struct pr_prpos dst; ! 541: int op; ! 542: struct pr_prpos *src; ! 543: register int count; ! 544: { ! 545: register short sizey; ! 546: register int tem, w, prime, linebytes; ! 547: register short *bx, *leftx, *ma; ! 548: register struct memropc *ropregs; ! 549: short sizex; ! 550: int clip; ! 551: struct pixrect *pr; ! 552: short *ma_homey; ! 553: short homex, homey, limx, limy, dstx, dsty, by; ! 554: ! 555: struct cg2fb *fb; ! 556: struct mpr_data *md; ! 557: int oppassed = op; ! 558: int errors = 0; ! 559: short color; ! 560: ! 561: if (count <= 0) ! 562: return (0); ! 563: ! 564: /* ! 565: * Preliminaries: get pixrect data and frame buffer pointers; decide ! 566: * whether clipping. If not clipping, normalize op, else compute ! 567: * limits for cursors for later comparisons. ! 568: */ ! 569: #define dbd ((struct cg2pr *)leftx) ! 570: dbd = cg2_d(dst.pr); ! 571: homex = dbd->cgpr_offset.x; ! 572: homey = dbd->cgpr_offset.y; ! 573: #define FB ((struct cg2fb *)leftx) ! 574: FB = dbd->cgpr_va; ! 575: fb = FB; ! 576: #undef dbd ! 577: ropregs = &FB->ropcontrol[CG2_ALLROP].ropregs; ! 578: if (op & PIX_DONTCLIP) { ! 579: op &= ~PIX_DONTCLIP; ! 580: clip = 0; ! 581: } ! 582: else { ! 583: clip = 1; ! 584: limx = homex + dst.pr->pr_size.x; ! 585: limy = homey + dst.pr->pr_size.y; ! 586: } ! 587: dstx = homex + dst.pos.x; ! 588: dsty = homey + dst.pos.y; ! 589: if (private_bgcolor < 0) { ! 590: FB->ppmask.reg = private_fgcolor; /* set colored text */ ! 591: ropregs->mrc_pattern = -1; ! 592: FB->ppmask.reg = ~private_fgcolor; ! 593: ropregs->mrc_pattern = 0; ! 594: FB->ppmask.reg = private_czmask; ! 595: switch (op & 0x1E) { ! 596: case PIX_SRC ^ PIX_DST: ! 597: ropregs->mrc_op = CG_SRC & (CG_MASK ^ CG_DEST) | ~CG_SRC & CG_DEST; ! 598: break; ! 599: case PIX_NOT(PIX_DST): ! 600: ropregs->mrc_op = CG_SRC & (~CG_DEST) | ~CG_SRC & CG_DEST; ! 601: break; ! 602: default: ! 603: ropregs->mrc_op = CG_SRC & CG_MASK | ~CG_SRC & CG_DEST; ! 604: break; ! 605: } ! 606: } ! 607: else { ! 608: FB->ppmask.reg = private_fgcolor & private_bgcolor; ! 609: ropregs->mrc_op = ~0; ! 610: FB->ppmask.reg = ~(private_fgcolor | private_bgcolor); ! 611: ropregs->mrc_op = 0; ! 612: FB->ppmask.reg = private_fgcolor & ~private_bgcolor; ! 613: ropregs->mrc_op = CG_SRC; ! 614: FB->ppmask.reg = ~private_fgcolor & private_bgcolor; ! 615: ropregs->mrc_op = ~CG_SRC; ! 616: FB->ppmask.reg = private_czmask; ! 617: } ! 618: FB->status.reg.ropmode = PWWWRD; ! 619: linebytes = cg2_linebytes(FB, PWWWRD); ! 620: #undef FB ! 621: ! 622: for (; --count >= 0; src++) { ! 623: /* ! 624: * Update destination x and y by pre-advance amount. If no pixrect ! 625: * for this, then skip to next. ! 626: */ ! 627: dstx += src->pos.x; ! 628: pr = src->pr; ! 629: if (pr == 0) ! 630: continue; ! 631: sizex = pr->pr_size.x; ! 632: sizey = pr->pr_size.y; ! 633: md = mpr_d(pr); ! 634: ma = md->md_image; ! 635: ! 636: /* ! 637: * Grab sizes and address of image. If clipping (rare case ! 638: * hopefully) compare cursors against limits. ! 639: */ ! 640: by = dsty; ! 641: tem = 0; ! 642: if (clip) { ! 643: if (dstx + sizex > limx) ! 644: sizex = limx - dstx; ! 645: if (dsty + sizey > limy) ! 646: sizey = limy - dsty; ! 647: if (dsty < homey) { /* works if pr_depth = 1! */ ! 648: tem = homey - dsty; ! 649: by += tem; ! 650: ma += pr_product(tem, (md->md_linebytes >> 1)); ! 651: sizey -= tem; ! 652: tem = 0; ! 653: } ! 654: if (dstx < homex) { ! 655: tem = homex - dstx; ! 656: ma += tem >> 4; ! 657: sizex -= tem; ! 658: } ! 659: if (sizex <= 0) ! 660: continue; ! 661: } ! 662: ! 663: /* ! 664: * Hard case: characters greater than 16 wide. ! 665: */ ! 666: ma_homey = ma; ! 667: ! 668: /* set the ROP chip word width and opcount */ ! 669: ! 670: w = cg2_prskew(dstx); /* source skew is 0 */ ! 671: ropregs->mrc_shift = (w & 0xF) | (1 << 8); ! 672: prime = !w; ! 673: w = (sizex + w + (tem & 0xF) - 1) >> 4; ! 674: ropregs->mrc_width = w; ! 675: ropregs->mrc_opcount = w; ! 676: ! 677: /* set the ROP chip end masks */ ! 678: ! 679: ropregs->mrc_mask1 = ! 680: mrc_lmasktable[(tem += dstx) & 0xf]; ! 681: ropregs->mrc_mask2 = ! 682: mrc_rmasktable[(sizex + tem - 1) & 0xf]; ! 683: ! 684: leftx = cg2_ropwordaddr(fb, 0, tem, by); ! 685: tem = md->md_linebytes; ! 686: if (--sizey >= 0) ! 687: if (w) { ! 688: w++; ! 689: do { ! 690: register short i = w; ! 691: ma = ma_homey; ! 692: bx = leftx; ! 693: if (prime) ! 694: ropregs->mrc_source1 = *ma++; ! 695: while (i--) ! 696: *bx++ = *ma++; ! 697: (char *) ma_homey += tem; ! 698: (char *) leftx += linebytes; ! 699: } while (--sizey != -1); ! 700: } ! 701: else { ! 702: bx = leftx; ! 703: ma = ma_homey; ! 704: if (prime) { ! 705: ma++; ! 706: do { ! 707: ma--; ! 708: ropregs->mrc_source1 = *ma++; ! 709: *bx = *ma; ! 710: (char *) ma += tem; ! 711: (char *) bx += linebytes; ! 712: } while (--sizey != -1); ! 713: } ! 714: else ! 715: do { ! 716: *bx = *ma; ! 717: (char *) ma += tem; ! 718: (char *) bx += linebytes; ! 719: } while (--sizey != -1); ! 720: } ! 721: } ! 722: ! 723: return (errors); ! 724: } ! 725: ! 726: #endif sun
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.