Annotation of 43BSDTahoe/new/X/libsun/text.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.