|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 16088 (0x3ed8) Types: TextFile Names: »text.h«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─⟦this⟧ »./X.V10R4/libibm/libsrc/text.h«
/* $Header: text.h,v 10.1 86/11/19 10:46:56 jg Exp $ */ /* text.h - macros and global data used by X text functions * * Author: * Dan Stone & Scott Bates * Brown University * IRIS, Box 1946 * Providence, RI 02912 * * * Copyright (c) 1986 Brown University * * Permission to use, copy, modify and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies, and that both * that copyright notice and this permission notice appear in supporting * documentation, and that the name of Brown University not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Brown University makes no * representations about the suitability of this software for any purpose. * It is provided "as-is" without express or implied warranty. */ /* * Macros for all the combination rules which can be used. */ #define GXcopy_OP(src, dst) dst = (src) #define GXor_OP(src, dst) dst = (dst) | (src) #define GXxor_OP(src, dst) dst = (dst) ^ (src) #define GXand_OP(src, dst) dst = (dst) & (src) #define GXcopyInverted_OP(src, dst) dst = ~(src) #define GXorInverted_OP(src, dst) dst = (dst) | ~(src) #define GXequiv_OP(src, dst) dst = (dst) ^ ~(src) #define GXandInverted_OP(src, dst) dst = (dst) & ~(src) #define GXorReverse_OP(src, dst) dst = (~(dst) | (src)) #define GXandReverse_OP(src, dst) dst = (~(dst) & (src)) #define GXinvert_OP(src, dst) dst = ~(dst) #define GXnand_OP(src, dst) dst = (~(dst) | ~(src)) #define GXnor_OP(src, dst) dst = (~(dst) & ~(src)) #define GXclear_OP(src, dst) dst = 0 #define GXset_OP(src, dst) dst = 0xFFFF #define GXnoop_OP(src, dst) dst = dst #define GXcopy_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ ((src) & mask) #define GXor_MASK(src, dst, mask) dst = ((dst) | ((src) & mask)) #define GXxor_MASK(src, dst, mask) dst = ((dst) ^ ((src) & mask)) #define GXand_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ (((dst) & (src)) & mask) #define GXcopyInverted_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ (~(src) & mask) #define GXorInverted_MASK(src, dst, mask) dst = ((dst) | (~(src) & mask)) #define GXequiv_MASK(src, dst, mask) dst = ((dst) ^ (~(src) & mask)) #define GXandInverted_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ (((dst) & ~(src)) & mask) #define GXandReverse_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ ((~(dst) & (src)) & mask) #define GXorReverse_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ ((~(dst) | (src)) & mask) #define GXinvert_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ (~(dst) & (mask)) #define GXnor_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ ((~(dst) & ~(src)) & mask) #define GXnand_MASK(src, dst, mask) dst = ((dst) & ~(mask)) | \ ((~(dst) | ~(src)) & mask) #define GXclear_MASK(src, dst, mask) dst = 0 #define GXset_MASK(src, dst, mask) dst = 0xFFFF #define GXnoop_MASK(src, dst, mask) dst = dst #ifndef BPL #define BPL 32 #define LOG2_BPL 5 #define MOD_BPL(value) ((value) & (BPL - 1)) #define DIV_BPL(value) ((value) >> LOG2_BPL) #define MUL_BPL(value) ((value) << LOG2_BPL) /* * Macro to convert Bits to Longs. */ #define BTOL(bits) (DIV_BPL((bits) + (BPL - 1))) #define MUL_4(n) ((n) << 2) #define DIV_4(n) ((n) >> 2) #endif BPL #define SRC ((u_short *)src) #define SRCPL ((u_short *)(src + 2)) #define DST ((u_short *)dst) #define DSTPL ((u_short *)(dst + 2)) /* * Masks for to protect the left portion of a short. That portion that should * not be changed. */ static u_short leftmask_lib[] = { 0xFFFF,0x7FFF,0x3FFF,0x1FFF, 0x0FFF,0x07FF,0x03FF,0x01FF, 0x00FF,0x007F,0x003F,0x001F, 0x000F,0x0007,0x0003,0x0001, 0x0000 }; /* * Masks for to protect the right portion of a short. That portion that should * not be changed. */ static u_short rightmask_lib[] = { 0xFFFF,0x8000,0xC000,0xE000, 0xF000,0xF800,0xFC00,0xFE00, 0xFF00,0xFF80,0xFFC0,0xFFE0, 0xFFF0,0xFFF8,0xFFFC,0xFFFE, 0x0000 }; /* * This macro is used to copy characters from the fonts character bitmaps * to the offscreen bitmap. Later the offscreen bitmap is copied to the screen * using the bltter. * * The CopyText_LOOP is an optimization, of a more general bitblt loop. * Because most text characters are less than 16 bits wide the CopyText_LOOP * has 2 special inner loops for this size character image. A character * image thats less than 16 bits wide can only span at most 2 destination * shorts, so the 2 special inner loops are designed for 1 destination and * 2 destination shorts changing per line. IF more than 2 destination words * are to change then the general purpose loop is used. * * Some special notes: * * bitptr - A long integer that "points to" or "indexes into" one offscreen * buffer scanline. As if one scanline was an array of bits. * * src,dst - Are unsigned CHAR pointers and are cast to unsigned shorts * when used as pointers. Why? IF src was an unsigned SHORT * pointer and src += n was done, the current RT compiler * would generate 2 extra assembly language instructions, * one to shift n left (multiply by 2) and the other to * compute the address. * * The offscreen buffer is the destination. * * Here is the algorithm for the CopyText_LOOP: * * FOREACH character DO * IF the character is not printable THEN * continue * IF the character is wider than zero THEN * set start_dst = To the destination short which contains the first * bit to be changed. * set shift = The first bit within start_dst to be changed. * Increment bitptr past the current character. * IF bitptr is beyond the last bit in the destination THEN * Decrement bitptr back to its previous value. * Decrement the character count. * Break out of the loop. * ENDIF * * Set the right mask using the right mask library and the NEW bitptr. * Calculate the source pointer. * Calculate the destination pointer. * Calculate the number of shorts changed in the destination. * * IF no shifting needed THEN * IF 1 destination short changed THEN * FOREACH scanline DO * Use the edge macro (see above) to combine src, dst and * mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ELSE IF 2 destination shorts changed THEN * FOREACH scanline DO * Use the macro (see above) to combine src and dst. * Use the edge macro (see above) to combine src+2, dst+2 * and mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ELSE * Calculate the amount to decrement the dst to get back * to the first scanline next short(the + 2). * Calculate the amount to decrement the src to get back * to the first scanline next short(the + 2). * FOREACH short in the destination DO * FOREACH scanline DO * Use the macro (see above) to combine src and dst. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * Decrement dst back to the first scanline, next short. * Decrement src back to the first scanline, next short. * Reset the number of scanlines (height). * ENDFOR * FOREACH scanline DO * Use the edge macro to combine src, dst and mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ENDIF * ELSE * Get the left mask from the left mask library using shift. * IF 1 destination short changed THEN * Combine left and right masks. * FOREACH scanline DO * Use the edge macro (see above) to combine src shifted, * with dst and mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ELSE IF 2 destination shorts changed THEN * Set the inverse of shift = 16 - shift. * IF the src bitmap is only 1 short wide THEN * FOREACH scanline DO * Use the edge macro (see above) to combine src * shifted, with dst and left mask. * Use the edge macro (see above) to combine src * inversely shifted with dst+2 and right mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ELSE # src bitmap is wider than 1 short and the 2nd short * # may have useful info in it. * FOREACH scanline DO * Use the edge macro (see above) to combine src * shifted with dst and left mask. * Use the edge macro (see above) to combine src * shifted, src+2 inversely shifted with * dst+2 and right mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ELSE * Calculate the amount to decrement the dst to get back * to the first scanline next short(the + 2). * Calculate the amount to decrement the src to get back * to the first scanline next short(the + 2). * # Deal with the left edge. * FOREACH scanline DO * Use the edge macro (see above) to combine src shifted * with dst and left mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * # Now deal with the shorts between the left edge and right * # edge. * FOREACH short in the destination DO * FOREACH scanline DO * Use the macro (see above) to combine src inversely * shifted or'ed with src+2 shifted with dst. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * Decrement dst back to the first scanline, next short. * Decrement src back to the first scanline, next short. * Reset the number of scanlines (height). * ENDFOR * IF the number of destination shorts == the number of * shorts wide the src is THEN * # We have incremented to the last short in the src * # scanline and should not use src+2. * FOREACH scanline DO * Use the edge macro to combine src inversely shifted, * with dst and right mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ELSE * FOREACH scanline DO * Use the edge macro to combine src inversely shifted * or'ed with src+2 shifted, with dst and right * mask. * Increment the source to the next scanline. * Increment the destination to the next scanline. * ENDFOR * ENDIF * ENDIF * ENDIF * ENDIF * ENDFOR * * NOTE: Make sure ch_pad is not added to the last character copied. */ #define CopyText_LOOP(EDGE_OP, OP) { \ for (i = ch_count + 1; --i; ) { \ if ((c = (int)(*string++)) < font->first || c > font->last) \ continue; /* Character is unprintable. */ \ if (char_widths[c] > 0) { \ shift = bitptr & 0x0F; \ start_dst = DIV_BPW(bitptr); \ if (((bitptr += char_widths[c]) + ch_pad) > maxbitptr){ \ bitptr -= char_widths[c]; \ ch_count -= i; \ break; /* Overflow: Get out of the loop */ \ } \ rtmask = rightmask_lib[bitptr & 0x0F]; \ src = (u_char *)(chrs_data) + (shorts_per_char * \ (c - font->first)); \ dst = (u_char *)buf_bm->data + MUL_2(start_dst); \ ndst_shorts = DIV_BPW(bitptr - 1) - start_dst + 1; \ height = ht_plus1; \ if (shift == 0) { \ if (ndst_shorts == 1) { \ while (--height) { \ EDGE_OP(*SRC, *DST, rtmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } else if (ndst_shorts == 2) { \ while (--height) { \ OP(*SRC, *DST); \ EDGE_OP(*SRCPL, *DSTPL, rtmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } else { \ height = font->height; \ dst_nextcol = (height*dst_nextline) - 2; \ src_nextcol = (height*src_nextline) - 2; \ height++; \ while (--ndst_shorts > 0) { \ while (--height) { \ OP(*SRC, *DST); \ dst += dst_nextline; \ src += src_nextline; \ } \ dst -= dst_nextcol; \ src -= src_nextcol; \ height = ht_plus1; \ } \ while (--height) { \ EDGE_OP(*SRC, *DST, rtmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } \ } else { \ leftmask = leftmask_lib[shift]; \ if (ndst_shorts == 1) { \ leftmask &= rtmask; \ while (--height) { \ EDGE_OP((*SRC >> shift), *DST, leftmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } else if (ndst_shorts == 2) { \ inv_shift = BPW - shift; \ if (chrs_nshorts == 1) { \ while (--height) { \ EDGE_OP((*SRC >> shift), *DST, leftmask); \ EDGE_OP(*(SRC) << inv_shift, *(DSTPL), rtmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } else { \ while (--height) { \ EDGE_OP((*SRC >> shift), *DST, leftmask); \ EDGE_OP((*SRC<<inv_shift)|(*(SRCPL)>>shift), \ *(DSTPL), rtmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } \ } else { \ height = font->height; \ dst_nextcol = (height*dst_nextline) - 2; \ src_nextcol = (height*src_nextline) - 2; \ height++; \ while (--height) { \ EDGE_OP((*SRC >> shift), *DST, leftmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ dst -= dst_nextcol; \ src -= (src_nextcol + 2); \ inv_shift = BPW - shift; \ nsrc_shorts = ndst_shorts - 1; \ while (--ndst_shorts > 1) { \ height = ht_plus1; \ while (--height) { \ OP((*SRC<<inv_shift)|(*(SRCPL)>>shift),*DST); \ dst += dst_nextline; \ src += src_nextline; \ } \ dst -= dst_nextcol; \ src -= src_nextcol; \ } \ height = ht_plus1; \ if (nsrc_shorts == chrs_nshorts) { \ while (--height) { \ EDGE_OP((*SRC << inv_shift), *DST, rtmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } else { \ while (--height) { \ EDGE_OP((*SRC << inv_shift) | (*(SRCPL) >> \ shift), *DST, rtmask); \ dst += dst_nextline; \ src += src_nextline; \ } \ } \ } \ } \ bitptr += ch_pad; \ } \ if (c == font->space) { \ if ((bitptr += sp_pad) > maxbitptr) { \ bitptr -= sp_pad; \ ch_count -= i; \ break; /* Overflow: Get out of the loop. */ \ } \ } \ } \ }