Annotation of 43BSDTahoe/new/X/libibm/libsrc/text.c, revision 1.1

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

unix.superglobalmegacorp.com

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