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