Annotation of 43BSDTahoe/new/X/libsun/text.c, revision 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.