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