home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / btnlib / border.c < prev    next >
C/C++ Source or Header  |  1990-04-28  |  9KB  |  227 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    MakeBorder.c
  6.  * Purpose:    Create bitmap with border pattern for drawing button.
  7.  * Subroutines:    btn_MakeBdrBitmap()        returns: void
  8.  * Subroutines:    static btn_ReverseByte()    returns: unsigned char
  9.  * Subroutines:    static RightBorder()        returns: void
  10.  * Xlib calls:    none
  11.  * Copyright:    1987, 1989, 1990 Smithsonian Astrophysical Observatory
  12.  *        You may do anything you like with this file except remove
  13.  *        this copyright.  The Smithsonian Astrophysical Observatory
  14.  *        makes no representations about the suitability of this
  15.  *        software for any purpose.  It is provided "as is" without
  16.  *        express or implied warranty.
  17.  * Modified:    {0} Michael VanHilst    initial version         31 December 1987
  18.  *        {1} MVH    X11 version, chars instead of shorts    16 March 1989
  19.  *        {2} MVH form defines all 4 corners uniquely    26 March 1990
  20.  *        {n} <who> -- <does what> -- <when>
  21.  */
  22.  
  23. /*
  24.  * Subroutine:    btn_MakeBdrBitmap
  25.  * Purpose:    Fill a bitmap of an empty button with a border pattern made
  26.  *        from the given form.
  27.  * Returns:    void
  28.  * Called by:    btn_LabelButtons() in MakeBox.c
  29.  * Uses:    btn_ReverseByte(), btn_RightBorder() below
  30.  * Xlib calls:    none
  31.  * Post-state:    bitmap buffer allocated and filled
  32.  * Method:    Creates rectangular button bitmap (no symmetry assumed).  The
  33.  *        pattern form is 32x32 with all 4 edges of button.
  34.  * Note:    For each byte, bit 0 (0x01) appears on the left.
  35.  * Note:    For each byte, bit 7 (0x80) appears on the right.
  36.  */
  37. void btn_MakeBdrBitmap ( buttonmap, width, height, byte_width, form, inverse )
  38.      unsigned char *buttonmap;    /* i,o: pointer to bitmap of button */
  39.      int width, height;        /* i: dimensions of button window (to cover) */
  40.      int byte_width;        /* i: bytes in one line or row */
  41.      unsigned char *form;    /* i: ptr to pattern form for entier button */
  42.      int inverse;        /* i: flag to invert bits (reverse video) */
  43. {
  44.   unsigned char *top_line;    /* l: ptr to line from top in buttonmap */
  45.   unsigned char *bottom_line;    /* l: ptr to line from bottom in buttonmap */
  46.   unsigned char *top_form;    /* l: ptr to current top row in form */
  47.   unsigned char *bottom_form;    /* l: ptr to current bottom row in form */
  48.   int form_rows;        /* l: number of rows of form to use */
  49.   int row;            /* l: loop counter */
  50.   int right_form_byte;        /* l: index of first right form byte to use */
  51.   int right_form_bit;        /* l: bit in first right form byte to use */
  52.   int right_bdr_byte;        /* l: index of first line byte for right bdr */
  53.   int right_bdr_bit;        /* l: bit in first line byte for right bdr */
  54.   static unsigned char btn_ReverseByte();
  55.   static void btn_MakeBdrLine();
  56.  
  57.   /* portion of pattern form used (clip overlap if button very small) */
  58.   /* middle overlap on odd size counted for height, omitted for width */
  59.   if( height >= 32 )
  60.     form_rows = 16;
  61.   else
  62.     form_rows = (height + 1) / 2;
  63.   /* buttonmap byte index for first byte of top and bottom lines */
  64.   top_line = buttonmap;
  65.   bottom_line = &buttonmap[(height - 1) * byte_width];
  66.   /* normal starting point in reverse form for right border work */
  67.   right_form_byte = 0;
  68.   right_form_bit = 0;
  69.   /* determine parameters form making right border */
  70.   if( width >= 32 ) {
  71.     right_bdr_byte = (width - 16) / 8;
  72.     right_bdr_bit = width & 0x0007;
  73.   } else if( width == 31 ) {
  74.     right_bdr_byte = 2;
  75.     right_bdr_bit = 0;
  76.     right_form_bit = 1;
  77.   } else {
  78.     if( width > 14 ) {
  79.       right_bdr_byte = 1;
  80.       right_bdr_bit = (width - 15) / 2;
  81.     } else {
  82.       right_bdr_byte = 0;
  83.       right_bdr_bit = (width + 1) / 2;
  84.     }
  85.     if( width > 17 ) {
  86.       right_form_bit = 16 - (width / 2);
  87.     } else {
  88.       right_form_byte = 1;
  89.       right_form_bit = 8 - (width / 2);
  90.     }
  91.   }
  92.   top_form = form;
  93.   /* bottom line of 4 x 32 byte form */
  94.   bottom_form = form + 124;
  95.   /* do top and bottom border patterns */
  96.   for( row=0; row<form_rows; row++ ) {
  97.     btn_MakeBdrLine(top_line, top_form, byte_width, inverse, right_bdr_byte,
  98.             right_bdr_bit, right_form_byte, right_form_bit);
  99.     if( top_line != bottom_line )
  100.       btn_MakeBdrLine(bottom_line, bottom_form, byte_width, inverse,
  101.               right_bdr_byte, right_bdr_bit,
  102.               right_form_byte, right_form_bit);
  103.     top_form += 4;
  104.     bottom_form -= 4;
  105.     top_line += byte_width;
  106.     bottom_line -= byte_width;
  107.   }
  108.   /* working from where we left at bottom, up to where we left at top */
  109.   top_line -= byte_width;
  110.   while( top_line < bottom_line ) {
  111.     /* duplicate the lowest line of the upper pattern */
  112.     bcopy((char *)top_line, (char *)bottom_line, byte_width);
  113.     bottom_line -= byte_width;
  114.   }
  115. }
  116.  
  117. /*
  118.  * Subroutine:    btn_MakeBdrLine
  119.  * Purpose:    set the bits for one line of the button's border
  120.  */
  121. static void btn_MakeBdrLine ( line, form, byte_width, inverse,
  122.                   right_bdr_byte, right_bdr_bit,
  123.                   right_form_byte, right_form_bit )
  124.      unsigned char *line;    /* l: ptr to line from top in buttonmap */
  125.      unsigned char *form;    /* l: ptr to current top row in form */
  126.      int byte_width;        /* i: bytes in one line or row */
  127.      int inverse;        /* i: flag to invert bits (reverse video) */
  128.      int right_form_byte;    /* l: index of first right form byte to use */
  129.      int right_form_bit;    /* l: bit in first right form byte to use */
  130.      int right_bdr_byte;    /* l: index of first line byte for right bdr */
  131.      int right_bdr_bit;        /* l: bit in first line byte for right bdr */
  132. {
  133.   static void btn_RightBorder();
  134.   /* copy in top left, store reverse for top right */
  135.   *line = *form;
  136.   *(line+1) = *(++form);
  137.   /* fill middle across the row */
  138.   if( *form & 0x80 ) {
  139.     int i;    /* l: byte index offset and loop counter */
  140.     for( i=2; i<=right_bdr_byte; i++ )
  141.       line[i] = 0xff;
  142.   }
  143.   /* else not needed since btn_Alloc cleared all bits anyway */
  144.   /* would be - bzero((char *)(top_line + 2, right_bdr_byte - 1); */
  145.   /* do the right side using 3rd and 4th byte in form row */
  146.   btn_RightBorder((++form), line + right_bdr_byte,
  147.           right_form_byte, right_form_bit, right_bdr_bit);
  148.   if( inverse ) {
  149.     int i;
  150.     for( i=0; i<byte_width; i++ )
  151.       line[i] = 0xff - line[i];
  152.   }
  153. }
  154.  
  155. #ifdef UNNEEDED
  156. /*
  157.  * Subroutine:    btn_ReverseByte
  158.  * Purpose:    Get byte with bits in reverse order of that given
  159.  * Returns:    Unsigned byte which is mirror copy of byte given
  160.  * Called by:    btn_MakeBdrBitmap() above
  161.  * Uses:    flip[] below
  162.  * Xlib calls:    none
  163.  * Method:    Does lookup on 4bit pattern, using index of original 4bit value
  164.  */
  165. static unsigned char flip[16] = {
  166.   0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
  167.   0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
  168. };
  169. static unsigned char btn_ReverseByte ( byte )
  170.      unsigned char byte;
  171. {
  172.   unsigned char reverse;
  173.  
  174.   reverse = flip[byte >> 4];
  175.   reverse += flip[byte & 0xf] << 4;
  176.   return( reverse );
  177. }
  178. #endif
  179.  
  180. /*
  181.  * Subroutine:    btn_RightBorder
  182.  * Purpose:    Set the bits for the right border pattern
  183.  * Returns:    void
  184.  * Called by:    btn_MakeBdrBitmap() above
  185.  * Uses:    rmask[] and lmask[] below
  186.  * Xlib calls:    none
  187.  * Post-state:    bitmap buffer line right border bits set
  188.  * Method:    Given 2 byte pattern, byte and bit numbers, and bimtap byte
  189.  *        pointer and bit number, copy to end of 2nd pattern byte.
  190.  * Note:    bit 0 (0x01) appears to the left of bit 7 (0x80).
  191.  */
  192. /* mask of ones for bits included at index and to the right */
  193. static unsigned char rmask[8] = { 0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80 };
  194. /* mask of ones for bits included at index and to the left */
  195. static unsigned char lmask[8] = { 0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f };
  196. static void btn_RightBorder ( src, dst, src_byte, src_bit, dst_bit )
  197.      unsigned char *src;    /* i: ptr to two reversed form pattern bytes */
  198.      unsigned char *dst;    /* i: ptr to first map byte affected */
  199.      int src_byte;        /* i: index of first form pattern byte used */
  200.      int src_bit;        /* i: bit in first source byte (7 on left) */
  201.      int dst_bit;        /* i: bit in dst (7 on left) */
  202. {
  203.   /* if there is perfect allignment, easy work and no shift */
  204.   if( src_bit == dst_bit ) {
  205.     *dst = (*dst & lmask[dst_bit]) | (src[src_byte] & rmask[src_bit]);
  206.     if( src_byte < 1 )
  207.       dst[1] = src[1];
  208.     return;
  209.   }
  210.   /* do segment by segment, advancing apropriate byte each time */
  211.   do {
  212.     if( dst_bit > src_bit ) {
  213.       *dst = (*dst & lmask[dst_bit]) |
  214.     ((src[src_byte] & rmask[src_bit]) << (dst_bit - src_bit));
  215.       src_bit += (8-dst_bit);
  216.       dst_bit = 0;
  217.       dst++;
  218.     } else {
  219.       *dst = (*dst & lmask[dst_bit]) |
  220.     ((src[src_byte] & rmask[src_bit]) >> (src_bit - dst_bit));
  221.       dst_bit += (8-src_bit);
  222.       src_bit = 0;
  223.       src_byte++;
  224.     }
  225.   } while( src_byte < 2 );
  226. }
  227.