Annotation of 43BSDTahoe/new/X/libibm/libsrc/text.h, revision 1.1.1.1

1.1       root        1: /* $Header: text.h,v 10.1 86/11/19 10:46:56 jg Exp $ */
                      2: /* text.h - macros and global data used by X text functions
                      3:  *
                      4:  *     Author:
                      5:  *             Dan Stone & Scott Bates
                      6:  *             Brown University
                      7:  *             IRIS, Box 1946
                      8:  *             Providence, RI 02912
                      9:  *
                     10:  *
                     11:  *             Copyright (c) 1986 Brown University
                     12:  *
                     13:  * Permission to use, copy, modify and distribute this software and its
                     14:  * documentation for any purpose and without fee is hereby granted, provided
                     15:  * that the above copyright notice appear in all copies, and that both
                     16:  * that copyright notice and this permission notice appear in supporting
                     17:  * documentation, and that the name of Brown University not be used in
                     18:  * advertising or publicity pertaining to distribution of the software
                     19:  * without specific, written prior permission. Brown University makes no
                     20:  * representations about the suitability of this software for any purpose.
                     21:  * It is provided "as-is" without express or implied warranty.
                     22:  */
                     23: 
                     24: /*
                     25:  * Macros for all the combination rules which can be used.
                     26:  */
                     27: 
                     28: #define GXcopy_OP(src, dst)        dst = (src)
                     29: #define GXor_OP(src, dst)          dst = (dst) | (src)
                     30: #define GXxor_OP(src, dst)         dst = (dst) ^ (src)
                     31: #define GXand_OP(src, dst)         dst = (dst) & (src)
                     32: #define GXcopyInverted_OP(src, dst) dst = ~(src)
                     33: #define GXorInverted_OP(src, dst)   dst = (dst) | ~(src)
                     34: #define GXequiv_OP(src, dst)       dst = (dst) ^ ~(src)
                     35: #define GXandInverted_OP(src, dst)  dst = (dst) & ~(src)
                     36: #define GXorReverse_OP(src, dst)    dst = (~(dst) | (src))
                     37: #define GXandReverse_OP(src, dst)   dst = (~(dst) & (src))
                     38: #define GXinvert_OP(src, dst)      dst = ~(dst)
                     39: #define GXnand_OP(src, dst)        dst = (~(dst) | ~(src))
                     40: #define GXnor_OP(src, dst)         dst = (~(dst) & ~(src))
                     41: #define GXclear_OP(src, dst)       dst = 0
                     42: #define GXset_OP(src, dst)         dst = 0xFFFF
                     43: #define GXnoop_OP(src, dst)        dst = dst
                     44: 
                     45: #define GXcopy_MASK(src, dst, mask)        dst = ((dst) & ~(mask)) |          \
                     46:                                                  ((src) & mask)
                     47: #define GXor_MASK(src, dst, mask)          dst = ((dst) | ((src) & mask))
                     48: #define GXxor_MASK(src, dst, mask)         dst = ((dst) ^ ((src) & mask)) 
                     49: #define GXand_MASK(src, dst, mask)         dst = ((dst) & ~(mask)) |          \
                     50:                                                  (((dst) & (src)) & mask)
                     51: #define GXcopyInverted_MASK(src, dst, mask) dst = ((dst) & ~(mask)) |         \
                     52:                                                  (~(src) & mask)
                     53: #define GXorInverted_MASK(src, dst, mask)   dst = ((dst) | (~(src) & mask))
                     54: #define GXequiv_MASK(src, dst, mask)       dst = ((dst) ^ (~(src) & mask))
                     55: #define GXandInverted_MASK(src, dst, mask)  dst = ((dst) & ~(mask)) |         \
                     56:                                                  (((dst) & ~(src)) & mask)
                     57: #define GXandReverse_MASK(src, dst, mask)   dst = ((dst) & ~(mask)) |         \
                     58:                                                  ((~(dst) & (src)) & mask)
                     59: #define GXorReverse_MASK(src, dst, mask)    dst = ((dst) & ~(mask)) |         \
                     60:                                                  ((~(dst) | (src)) & mask)
                     61: #define GXinvert_MASK(src, dst, mask)      dst = ((dst) & ~(mask)) |          \
                     62:                                                  (~(dst) & (mask))
                     63: #define GXnor_MASK(src, dst, mask)         dst = ((dst) & ~(mask)) |          \
                     64:                                                  ((~(dst) & ~(src)) & mask)
                     65: #define GXnand_MASK(src, dst, mask)        dst = ((dst) & ~(mask)) |          \
                     66:                                                  ((~(dst) | ~(src)) & mask)
                     67: #define GXclear_MASK(src, dst, mask)       dst = 0
                     68: #define GXset_MASK(src, dst, mask)         dst = 0xFFFF
                     69: #define GXnoop_MASK(src, dst, mask)        dst = dst
                     70: 
                     71: #ifndef BPL
                     72: #define BPL 32
                     73: #define LOG2_BPL 5
                     74: #define MOD_BPL(value) ((value) & (BPL - 1))
                     75: #define DIV_BPL(value) ((value) >> LOG2_BPL)
                     76: #define MUL_BPL(value) ((value) << LOG2_BPL)
                     77: 
                     78: /*
                     79:  * Macro to convert Bits to Longs.
                     80:  */
                     81: 
                     82: #define BTOL(bits)  (DIV_BPL((bits) + (BPL - 1)))
                     83: 
                     84: #define MUL_4(n)    ((n) << 2)
                     85: #define DIV_4(n)    ((n) >> 2)
                     86: #endif BPL
                     87: 
                     88: #define SRC    ((u_short *)src)
                     89: #define SRCPL  ((u_short *)(src + 2))
                     90: #define DST    ((u_short *)dst)
                     91: #define DSTPL  ((u_short *)(dst + 2))
                     92: 
                     93: /*
                     94:  * Masks for to protect the left portion of a short.  That portion that should
                     95:  * not be changed.
                     96:  */
                     97: 
                     98: static u_short leftmask_lib[] = {
                     99:     0xFFFF,0x7FFF,0x3FFF,0x1FFF,
                    100:     0x0FFF,0x07FF,0x03FF,0x01FF,
                    101:     0x00FF,0x007F,0x003F,0x001F,
                    102:     0x000F,0x0007,0x0003,0x0001,
                    103:     0x0000
                    104: };
                    105: 
                    106: /*
                    107:  * Masks for to protect the right portion of a short.  That portion that should
                    108:  * not be changed.
                    109:  */
                    110: 
                    111: static u_short rightmask_lib[] = {
                    112:     0xFFFF,0x8000,0xC000,0xE000,
                    113:     0xF000,0xF800,0xFC00,0xFE00,
                    114:     0xFF00,0xFF80,0xFFC0,0xFFE0,
                    115:     0xFFF0,0xFFF8,0xFFFC,0xFFFE,
                    116:     0x0000
                    117: };
                    118: 
                    119: /*
                    120:  * This macro is used to copy characters from the fonts character bitmaps
                    121:  * to the offscreen bitmap. Later the offscreen bitmap is copied to the screen
                    122:  * using the bltter.
                    123:  *
                    124:  * The CopyText_LOOP is an optimization, of a more general bitblt loop.
                    125:  * Because most text characters are less than 16 bits wide the CopyText_LOOP
                    126:  * has 2 special inner loops for this size character image.  A character
                    127:  * image thats less than 16 bits wide can only span at most 2 destination
                    128:  * shorts, so the 2 special inner loops are designed for 1 destination and
                    129:  * 2 destination shorts changing per line.  IF more than 2 destination words
                    130:  * are to change then the general purpose loop is used.
                    131:  *
                    132:  * Some special notes:
                    133:  *
                    134:  * bitptr - A long integer that "points to" or "indexes into" one offscreen
                    135:  *         buffer scanline.  As if one scanline was an array of bits.
                    136:  *
                    137:  * src,dst - Are unsigned CHAR pointers and are cast to unsigned shorts
                    138:  *          when used as pointers.  Why?  IF src was an unsigned SHORT
                    139:  *          pointer and src += n was done, the current RT compiler
                    140:  *          would generate 2 extra assembly language instructions,
                    141:  *          one to shift n left (multiply by 2) and the other to
                    142:  *          compute the address.
                    143:  *
                    144:  * The offscreen buffer is the destination.
                    145:  *
                    146:  * Here is the algorithm for the CopyText_LOOP:
                    147:  * 
                    148:  * FOREACH character DO
                    149:  *     IF the character is not printable THEN
                    150:  *        continue
                    151:  *     IF the character is wider than zero THEN
                    152:  *        set start_dst = To the destination short which contains the first
                    153:  *                        bit to be changed.
                    154:  *        set shift = The first bit within start_dst to be changed.
                    155:  *        Increment bitptr past the current character.
                    156:  *        IF bitptr is beyond the last bit in the destination THEN
                    157:  *            Decrement bitptr back to its previous value.
                    158:  *            Decrement the character count.
                    159:  *            Break out of the loop.
                    160:  *        ENDIF
                    161:  *
                    162:  *        Set the right mask using the right mask library and the NEW bitptr.
                    163:  *        Calculate the source pointer.
                    164:  *        Calculate the destination pointer.
                    165:  *        Calculate the number of shorts changed in the destination.
                    166:  *
                    167:  *        IF no shifting needed THEN
                    168:  *            IF 1 destination short changed THEN
                    169:  *                FOREACH scanline DO
                    170:  *                    Use the edge macro (see above) to combine src, dst and
                    171:  *                        mask.
                    172:  *                    Increment the source to the next scanline.
                    173:  *                    Increment the destination to the next scanline.
                    174:  *                ENDFOR
                    175:  *            ELSE IF 2 destination shorts changed THEN
                    176:  *                FOREACH scanline DO
                    177:  *                    Use the macro (see above) to combine src and dst.
                    178:  *                    Use the edge macro (see above) to combine src+2, dst+2
                    179:  *                        and mask.
                    180:  *                    Increment the source to the next scanline.
                    181:  *                    Increment the destination to the next scanline.
                    182:  *                ENDFOR
                    183:  *            ELSE
                    184:  *                Calculate the amount to decrement the dst to get back
                    185:  *                    to the first scanline next short(the + 2).
                    186:  *                Calculate the amount to decrement the src to get back
                    187:  *                    to the first scanline next short(the + 2).
                    188:  *        FOREACH short in the destination DO
                    189:  *                    FOREACH scanline DO
                    190:  *                        Use the macro (see above) to combine src and dst.
                    191:  *                        Increment the source to the next scanline.
                    192:  *                        Increment the destination to the next scanline.
                    193:  *                    ENDFOR
                    194:  *                    Decrement dst back to the first scanline, next short.
                    195:  *                    Decrement src back to the first scanline, next short.
                    196:  *                    Reset the number of scanlines (height).
                    197:  *                ENDFOR
                    198:  *                FOREACH scanline DO
                    199:  *                    Use the edge macro to combine src, dst and mask.
                    200:  *                    Increment the source to the next scanline.
                    201:  *                    Increment the destination to the next scanline.
                    202:  *                ENDFOR
                    203:  *            ENDIF
                    204:  *        ELSE
                    205:  *            Get the left mask from the left mask library using shift.
                    206:  *            IF 1 destination short changed THEN
                    207:  *                Combine left and right masks.
                    208:  *                FOREACH scanline DO
                    209:  *                    Use the edge macro (see above) to combine src shifted,
                    210:  *                        with dst and mask.
                    211:  *                    Increment the source to the next scanline.
                    212:  *                    Increment the destination to the next scanline.
                    213:  *                ENDFOR
                    214:  *            ELSE IF 2 destination shorts changed THEN
                    215:  *                Set the inverse of shift = 16 - shift.
                    216:  *                IF the src bitmap is only 1 short wide THEN
                    217:  *                    FOREACH scanline DO
                    218:  *                        Use the edge macro (see above) to combine src
                    219:  *                            shifted, with dst and left mask.
                    220:  *                        Use the edge macro (see above) to combine src
                    221:  *                            inversely shifted with dst+2 and right mask.
                    222:  *                        Increment the source to the next scanline.
                    223:  *                        Increment the destination to the next scanline.
                    224:  *                    ENDFOR
                    225:  *                ELSE  # src bitmap is wider than 1 short and the 2nd short
                    226:  *                      # may have useful info in it.
                    227:  *                    FOREACH scanline DO
                    228:  *                        Use the edge macro (see above) to combine src
                    229:  *                            shifted with dst and left mask.
                    230:  *                        Use the edge macro (see above) to combine src
                    231:  *                            shifted, src+2 inversely shifted with 
                    232:  *                            dst+2 and right mask.
                    233:  *                        Increment the source to the next scanline.
                    234:  *                        Increment the destination to the next scanline.
                    235:  *                    ENDFOR
                    236:  *            ELSE
                    237:  *                Calculate the amount to decrement the dst to get back
                    238:  *                    to the first scanline next short(the + 2).
                    239:  *                Calculate the amount to decrement the src to get back
                    240:  *                    to the first scanline next short(the + 2).
                    241:  *                # Deal with the left edge.
                    242:  *                FOREACH scanline DO
                    243:  *                    Use the edge macro (see above) to combine src shifted
                    244:  *                        with dst and left mask.
                    245:  *                    Increment the source to the next scanline.
                    246:  *                    Increment the destination to the next scanline.
                    247:  *                ENDFOR
                    248:  *                # Now deal with the shorts between the left edge and right
                    249:  *                # edge.
                    250:  *        FOREACH short in the destination DO
                    251:  *                    FOREACH scanline DO
                    252:  *                        Use the macro (see above) to combine src inversely
                    253:  *                            shifted or'ed with src+2 shifted with dst.
                    254:  *                        Increment the source to the next scanline.
                    255:  *                        Increment the destination to the next scanline.
                    256:  *                    ENDFOR
                    257:  *                    Decrement dst back to the first scanline, next short.
                    258:  *                    Decrement src back to the first scanline, next short.
                    259:  *                    Reset the number of scanlines (height).
                    260:  *                ENDFOR
                    261:  *                IF the number of destination shorts == the number of
                    262:  *                    shorts wide the src is THEN
                    263:  *                    # We have incremented to the last short in the src
                    264:  *                    # scanline and should not use src+2.
                    265:  *                    FOREACH scanline DO
                    266:  *                        Use the edge macro to combine src inversely shifted,
                    267:  *                            with dst and right mask.
                    268:  *                        Increment the source to the next scanline.
                    269:  *                        Increment the destination to the next scanline.
                    270:  *                     ENDFOR
                    271:  *                ELSE
                    272:  *                    FOREACH scanline DO
                    273:  *                        Use the edge macro to combine src inversely shifted
                    274:  *                            or'ed with src+2 shifted, with dst and right
                    275:  *                            mask.
                    276:  *                        Increment the source to the next scanline.
                    277:  *                        Increment the destination to the next scanline.
                    278:  *                     ENDFOR
                    279:  *                ENDIF
                    280:  *            ENDIF
                    281:  *        ENDIF
                    282:  *     ENDIF
                    283:  * ENDFOR
                    284:  *
                    285:  * NOTE: Make sure ch_pad is not added to the last character copied.
                    286:  */
                    287: 
                    288: #define CopyText_LOOP(EDGE_OP, OP) {                                       \
                    289:     for (i = ch_count + 1; --i; ) {                                        \
                    290:        if ((c = (int)(*string++)) < font->first || c > font->last)         \
                    291:            continue;                      /* Character is unprintable. */  \
                    292:        if (char_widths[c] > 0) {                                           \
                    293:            shift = bitptr & 0x0F;                                          \
                    294:            start_dst = DIV_BPW(bitptr);                                    \
                    295:            if (((bitptr += char_widths[c]) + ch_pad) > maxbitptr){         \
                    296:                bitptr -= char_widths[c];                                   \
                    297:                ch_count -= i;                                              \
                    298:                break;                 /* Overflow: Get out of the loop */  \
                    299:            }                                                               \
                    300:            rtmask = rightmask_lib[bitptr & 0x0F];                          \
                    301:            src = (u_char *)(chrs_data) + (shorts_per_char *                \
                    302:                  (c - font->first));                                       \
                    303:            dst = (u_char *)buf_bm->data + MUL_2(start_dst);                \
                    304:            ndst_shorts = DIV_BPW(bitptr - 1) - start_dst + 1;              \
                    305:            height = ht_plus1;                                              \
                    306:            if (shift == 0) {                                               \
                    307:                if (ndst_shorts == 1) {                                     \
                    308:                    while (--height) {                                      \
                    309:                        EDGE_OP(*SRC, *DST, rtmask);                        \
                    310:                        dst += dst_nextline;                                \
                    311:                        src += src_nextline;                                \
                    312:                    }                                                       \
                    313:                } else if (ndst_shorts == 2) {                              \
                    314:                    while (--height) {                                      \
                    315:                        OP(*SRC, *DST);                                     \
                    316:                        EDGE_OP(*SRCPL, *DSTPL, rtmask);                    \
                    317:                        dst += dst_nextline;                                \
                    318:                        src += src_nextline;                                \
                    319:                    }                                                       \
                    320:                } else {                                                    \
                    321:                    height = font->height;                                  \
                    322:                    dst_nextcol = (height*dst_nextline) - 2;                \
                    323:                    src_nextcol = (height*src_nextline) - 2;                \
                    324:                    height++;                                               \
                    325:                    while (--ndst_shorts > 0) {                             \
                    326:                        while (--height) {                                  \
                    327:                            OP(*SRC, *DST);                                 \
                    328:                            dst += dst_nextline;                            \
                    329:                            src += src_nextline;                            \
                    330:                        }                                                   \
                    331:                        dst -= dst_nextcol;                                 \
                    332:                        src -= src_nextcol;                                 \
                    333:                        height = ht_plus1;                                  \
                    334:                    }                                                       \
                    335:                    while (--height) {                                      \
                    336:                        EDGE_OP(*SRC, *DST, rtmask);                        \
                    337:                        dst += dst_nextline;                                \
                    338:                        src += src_nextline;                                \
                    339:                    }                                                       \
                    340:                }                                                           \
                    341:            } else {                                                        \
                    342:                leftmask = leftmask_lib[shift];                             \
                    343:                if (ndst_shorts == 1) {                                     \
                    344:                    leftmask &= rtmask;                                     \
                    345:                    while (--height) {                                      \
                    346:                        EDGE_OP((*SRC >> shift), *DST, leftmask);           \
                    347:                        dst += dst_nextline;                                \
                    348:                        src += src_nextline;                                \
                    349:                    }                                                       \
                    350:                } else if (ndst_shorts == 2) {                              \
                    351:                    inv_shift = BPW - shift;                                \
                    352:                    if (chrs_nshorts == 1) {                                \
                    353:                        while (--height) {                                  \
                    354:                            EDGE_OP((*SRC >> shift), *DST, leftmask);       \
                    355:                            EDGE_OP(*(SRC) << inv_shift, *(DSTPL), rtmask); \
                    356:                            dst += dst_nextline;                            \
                    357:                            src += src_nextline;                            \
                    358:                        }                                                   \
                    359:                    } else {                                                \
                    360:                        while (--height) {                                  \
                    361:                            EDGE_OP((*SRC >> shift), *DST, leftmask);       \
                    362:                            EDGE_OP((*SRC<<inv_shift)|(*(SRCPL)>>shift),    \
                    363:                                *(DSTPL), rtmask);                          \
                    364:                            dst += dst_nextline;                            \
                    365:                            src += src_nextline;                            \
                    366:                        }                                                   \
                    367:                    }                                                       \
                    368:                } else {                                                    \
                    369:                    height = font->height;                                  \
                    370:                    dst_nextcol = (height*dst_nextline) - 2;                \
                    371:                    src_nextcol = (height*src_nextline) - 2;                \
                    372:                    height++;                                               \
                    373:                    while (--height) {                                      \
                    374:                        EDGE_OP((*SRC >> shift), *DST, leftmask);           \
                    375:                        dst += dst_nextline;                                \
                    376:                        src += src_nextline;                                \
                    377:                    }                                                       \
                    378:                    dst -= dst_nextcol;                                     \
                    379:                    src -= (src_nextcol + 2);                               \
                    380:                    inv_shift = BPW - shift;                                \
                    381:                    nsrc_shorts = ndst_shorts - 1;                          \
                    382:                    while (--ndst_shorts > 1) {                             \
                    383:                        height = ht_plus1;                                  \
                    384:                        while (--height) {                                  \
                    385:                            OP((*SRC<<inv_shift)|(*(SRCPL)>>shift),*DST);   \
                    386:                            dst += dst_nextline;                            \
                    387:                            src += src_nextline;                            \
                    388:                        }                                                   \
                    389:                        dst -= dst_nextcol;                                 \
                    390:                        src -= src_nextcol;                                 \
                    391:                    }                                                       \
                    392:                    height = ht_plus1;                                      \
                    393:                    if (nsrc_shorts == chrs_nshorts) {                      \
                    394:                        while (--height) {                                  \
                    395:                            EDGE_OP((*SRC << inv_shift), *DST, rtmask);     \
                    396:                            dst += dst_nextline;                            \
                    397:                            src += src_nextline;                            \
                    398:                        }                                                   \
                    399:                    } else {                                                \
                    400:                        while (--height) {                                  \
                    401:                            EDGE_OP((*SRC << inv_shift) | (*(SRCPL) >>      \
                    402:                            shift), *DST, rtmask);                          \
                    403:                            dst += dst_nextline;                            \
                    404:                            src += src_nextline;                            \
                    405:                        }                                                   \
                    406:                    }                                                       \
                    407:                }                                                           \
                    408:            }                                                               \
                    409:            bitptr += ch_pad;                                               \
                    410:        }                                                                   \
                    411:        if (c == font->space) {                                             \
                    412:            if ((bitptr += sp_pad) > maxbitptr) {                           \
                    413:                bitptr -= sp_pad;                                           \
                    414:                ch_count -= i;                                              \
                    415:                break;                 /* Overflow: Get out of the loop. */ \
                    416:            }                                                               \
                    417:        }                                                                   \
                    418:     }                                                                      \
                    419: }

unix.superglobalmegacorp.com

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