home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c005 / 4.ddi / C / SCBOX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-08-05  |  5.9 KB  |  180 lines

  1. /**
  2. *
  3. * Name        scbox -- Draw a box on the current display page
  4. *             using character graphics
  5. *
  6. * Synopsis    ercode = scbox(u_row,u_col,l_row,l_col,
  7. *                 boxtype,boxchar,attrib);
  8. *        int  ercode      Error code:  0 if okay, 1 if box
  9. *                  dimensions are invalid.
  10. *        int  u_row,u_col  Upper left corner of window.
  11. *        int  l_row,l_col  Lower right corner of window.
  12. *        int  boxtype      Nature of characters to be used for
  13. *                  the box:  -1 if boxchar to be used,
  14. *                  0 to 15 if IBM box characters to be
  15. *                  used (see below).
  16. *        char boxchar      Character to be used for drawing the
  17. *                  box if boxtype is -1.
  18. *        int  attrib      The attribute to be used on the vacant
  19. *                  lines.  It has the background attribute
  20. *                  in the high order four bits of the low
  21. *                  order byte, and the foreground in the
  22. *                  low order nybble.
  23. *
  24. * Description    This function draws a box on the current display page.
  25. *
  26. *        If boxtype is -1, then the box will be drawn using the
  27. *        character specified as boxchar.  If boxtype is in the
  28. *        range 0 to 15, then the box will be drawn using the
  29. *        box-drawing characters in the IBM PC character set.  The
  30. *        actual value of boxtype specifies whether the sides of
  31. *        the box are drawn with single or double lines, according
  32. *        to the following table:
  33. *
  34. *               Box Type       Bottom  Right   Top    Left
  35. *               ------------------------------------------
  36. *            0   (0000)     S    S      S      S
  37. *            1   (0001)     S    S      S      D
  38. *            2   (0010)     S    S      D      S
  39. *            3   (0011)     S    S      D      D
  40. *            4   (0100)     S    D      S      S
  41. *            5   (0101)     S    D      S      D
  42. *            6   (0110)     S    D      D      S
  43. *            7   (0111)     S    D      D      D
  44. *            8   (1000)     D    S      S      S
  45. *            9   (1001)     D    S      S      D
  46. *               10   (1010)     D    S      D      S
  47. *               11   (1011)     D    S      D      D
  48. *               12   (1100)     D    D      S      S
  49. *               13   (1101)     D    D      S      D
  50. *               14   (1110)     D    D      D      S
  51. *               15   (1111)     D    D      D      D
  52. *
  53. *        If a box type is chosen from this table, corner
  54. *        characters will be automatically chosen to match the
  55. *        sides.
  56. *
  57. *        The box dimensions are considered invalid if any corner
  58. *        lies beyond the screen; or if the height or width of the
  59. *        box is less than two characters; or if the upper left
  60. *        corner (u_row,u_col) is below or to the right of the
  61. *        lower right corner (l_row,l_col).  If this occurs then
  62. *        1 is returned as the value of the function.
  63. *
  64. * Returns    ercode        Error code:  0 if okay,
  65. *                         1 if box dimensions are invalid.
  66. *
  67. * Version    3.0  (C)Copyright Blaise Computing Inc. 1985
  68. *
  69. **/
  70.  
  71. #include <bscreen.h>
  72.  
  73.     /* Macro to write a single character at a given point on the      */
  74.     /* screen                                  */
  75.  
  76. #define  write_one(row,col,ch,fore,back)      \
  77.      {                      \
  78.         sccurset(row,col);              \
  79.         scattrib(fore,back,ch,1);          \
  80.      }
  81.  
  82.     /* Macro to write more than one character at a given point on the */
  83.     /* screen                                  */
  84.  
  85. #define  write_some(row,col,ch,fore,back,number)  \
  86.      {                      \
  87.         if (number)               \
  88.         {                      \
  89.         sccurset(row,col);          \
  90.         scattrib(fore,back,ch,number);      \
  91.         }                      \
  92.      }
  93.  
  94. int scbox(u_row,u_col,l_row,l_col,boxtype,boxchar,attrib)
  95. int  u_row,u_col,l_row,l_col,boxtype;
  96. char boxchar;
  97. int  attrib;
  98. {
  99.     int  mode,columns,apage;          /* Values returned by scmode    */
  100.     int  save_row,save_col;
  101.     int  row,width,fore,back;
  102.     char topleft,topright,botleft,botright,
  103.      top,bottom,left,right;       /* Characters to write          */
  104.  
  105.     /* Tables of box characters                       */
  106.  
  107.     static char upleft[]          /* Top left corners          */
  108.                = {'\332','\326','\325','\311'},
  109.         upright[]          /* Top right corners          */
  110.                = {'\277','\270','\267','\273'},
  111.         lowleft[]          /* Bottom left corners          */
  112.                = {'\300','\323','\324','\310'},
  113.         lowright[]          /* Bottom right corners          */
  114.                = {'\331','\275','\276','\274'};
  115.  
  116.     static char horiz[]           /* Horizontal lines          */
  117.                = {'\304','\315'},
  118.         vert[]              /* Vertical lines           */
  119.                = {'\263','\272'};
  120.  
  121.     /* Validate the box position and dimensions               */
  122.  
  123.     scmode(&mode,&columns,&apage);
  124.     if (     0 >  u_row
  125.       || u_row >= l_row
  126.       || l_row >= scrows()
  127.       ||     0 >  u_col
  128.       || u_col >= l_col
  129.       || l_col >= columns     )
  130.     return 1;
  131.  
  132.     width = l_col - u_col - 1;          /* Distance between the sides   */
  133.  
  134.     if ((mode > 3) && (mode != 7))    /* Force attribute for graphics */
  135.     attrib = min(3,max(0,attrib));
  136.     fore = utlonyb(attrib);
  137.     back = uthinyb(attrib);
  138.  
  139.     /* Look up the box characters from the tables              */
  140.  
  141.     if (boxtype < 0)
  142.     topleft  = topright = botleft = botright
  143.          = left     = right   = top     = bottom   = boxchar;
  144.     else
  145.     {
  146.     topleft  = upleft  [  boxtype        & 3];
  147.     topright = upright [ (boxtype >> 1) & 3];
  148.     botleft  = lowleft [((boxtype >> 2) & 2) | (boxtype & 1)];
  149.     botright = lowright[ (boxtype >> 2) & 3];
  150.  
  151.     top     = horiz[(boxtype >> 1) & 1];
  152.     bottom     = horiz[(boxtype >> 3) & 1];
  153.     left     = vert [ boxtype    & 1];
  154.     right     = vert [(boxtype >> 2) & 1];
  155.     }
  156.  
  157.     /* Draw the box, starting from upper left corner, working          */
  158.     /* horizontally.                              */
  159.  
  160.     sccurpos(&save_row,&save_col);    /* Save cursor location          */
  161.  
  162.     write_one (u_row,u_col,     topleft, fore,back);
  163.     write_some(u_row,(u_col + 1),top,      fore,back,width);
  164.     write_one (u_row,l_col,     topright,fore,back);
  165.  
  166.     for (row = u_row + 1; row < l_row; row++)
  167.     {
  168.     write_one(row,u_col,left, fore,back);        /* Left side      */
  169.     write_one(row,l_col,right,fore,back);        /* Right side     */
  170.     }
  171.  
  172.     write_one (l_row,u_col,     botleft, fore,back);
  173.     write_some(l_row,(u_col + 1),bottom,  fore,back,width);
  174.     write_one (l_row,l_col,     botright,fore,back);
  175.  
  176.     sccurset(save_row,save_col);      /* Restore cursor location      */
  177.  
  178.     return 0;
  179. }
  180.