home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / SCWRAP.C < prev    next >
Encoding:
Text File  |  1989-03-31  |  9.0 KB  |  268 lines

  1. /**
  2. *
  3. * Name        scwrap -- Write a string of characters to a rectangular
  4. *                region on the current display page via BIOS,
  5. *                TTY-style, with word wrap.
  6. *
  7. * Synopsis    scwrap(u_row,u_col,l_row,l_col,num_spaces,
  8. *              buffer,fore,back,option);
  9. *
  10. *        int  u_row    Top row of region (0 = top of screen)
  11. *        int  u_col    Leftmost column of region (0 = left edge)
  12. *        int  l_row    Bottom row of region
  13. *        int  l_col    Rightmost column of region
  14. *        int  num_spaces Number of characters to write.
  15. *                If CHARS_ONLY is specified (see "option"
  16. *                below), num_spaces == 0 indicates that
  17. *                the buffer is terminated by a NUL ('\0')
  18. *                character.
  19. *        const char *buffer
  20. *                Data to write
  21. *        int  fore    -1 if existing foreground is to be
  22. *                preserved; if CHARS_ONLY is specified, a
  23. *                value between 0 and 15 specifies a new
  24. *                foreground attribute.
  25. *        int  back    -1 if existing background is to be
  26. *                preserved; if CHARS_ONLY is specified, a
  27. *                value between 0 and 15 specifies a new
  28. *                foreground attribute.
  29. *        int  option    One bit of the option value tells SCWRAP
  30. *                how the buffer is constructed.    The two
  31. *                possible values are:
  32. *
  33. *              Value        Meaning
  34. *              -----------   ------------------------------------
  35. *              CHARS_ONLY    Buffer contains characters only.
  36. *                    If num_spaces is zero, the string
  37. *                    is terminated by a NUL ('\0')
  38. *                    character.
  39. *                    The values of fore and back are used
  40. *                    as attributes.
  41. *              CHAR_ATTR     Buffer contains (char,attr) pairs.
  42. *                    The values of fore and back are
  43. *                    ignored.
  44. *
  45. * Description    This function writes characters to a rectangular region
  46. *        on the current display page without splitting words
  47. *        between lines.
  48. *
  49. *        If the cursor is currently within the region, the
  50. *        characters are written beginning at that point.  If the
  51. *        cursor is not within the region, the characters are
  52. *        written beginning at the upper left corner of the
  53. *        region.  The cursor is left after the end of the
  54. *        displayed string.
  55. *
  56. *        The num_spaces argument specifies the number of actual
  57. *        characters to use from the buffer.  (If CHAR_ATTR is
  58. *        specified, twice this number of bytes will be used from
  59. *        the buffer.)  No more than 32767 bytes should be used
  60. *        from the buffer.
  61. *
  62. *        A "word" is defined to be a sequence of non-whitespace
  63. *        characters that is bounded by whitespace characters or
  64. *        by the beginning or end of the buffer.    "Whitespace"
  65. *        characters are blank (' '), tab ('\t'), bell ('\7'),
  66. *        backspace ('\b'), line feed ('\012'), and carriage
  67. *        return ('\15').  Words are split between rows of the
  68. *        region only if they are longer than the width of the
  69. *        region.  If a word is too long to fit on the current row
  70. *        without splitting, then it is written on the next row of
  71. *        the region, scrolling the region if necessary.
  72. *
  73. *        Multiple blanks are written literally up to the end of
  74. *        the current line.  No blanks are written at the
  75. *        beginning of a line.
  76. *
  77. *        The region is scrolled if a line feed occurs on the last
  78. *        line or if the last line is overflowed.  The attribute
  79. *        for the new blank line is chosen in the same manner as
  80. *        SCTTYWRT.
  81. *
  82. *        If the screen is in a text mode and CHARS_ONLY is
  83. *        specified, then specifying -1 for fore or back preserves
  84. *        the existing foreground or background attributes,
  85. *        respectively.  If the screen is in a graphics mode and
  86. *        CHARS_ONLY is specified, then specifying -1 for fore
  87. *        will cause color 1 to be used.
  88. *
  89. * Limitation    This function cannot perform a scroll on an inactive
  90. *        page in a graphics mode.
  91. *
  92. * Special    Tab characters ('\t') are regarded as single blank
  93. * characters    characters.
  94. *
  95. *        DEL characters ('\177') are written to the screen as
  96. *        blanks.  However, they are treated as nonblanks in that
  97. *        nonblank characters joined by DEL characters will not be
  98. *        split when whole words are wrapped.  The character value
  99. *        written to the screen is 0x20.
  100. *
  101. *        NUL ('\0') is treated differently depending on the
  102. *        values of option and num_spaces.  If CHARS_ONLY is
  103. *        designated and num_spaces is zero, then NUL denotes the
  104. *        end of the string.  Otherwise it is a printable nonblank
  105. *        character (displayed as a blank space), not the end of
  106. *        the string.  Thus it is treated the same as DEL, except
  107. *        that the character value written to the screen is 0.
  108. *
  109. *        Line feed ('\12') causes the cursor to move down one
  110. *        row, unless it is already on the bottom row of the
  111. *        region, in which case the screen is scrolled.
  112. *
  113. *        Carriage return ('\r') causes the cursor to move to the
  114. *        leftmost column of the region.
  115. *
  116. *        Backspace ('\b') causes the cursor to move one column to
  117. *        the left (non-destructively), unless it is already at
  118. *        the leftmost column of the region, in which case nothing
  119. *        happens.
  120. *
  121. *        The BEL character ('\7') causes the computer's bell to
  122. *        sound if the current page is active.
  123. *
  124. * Returns    (None.    Function return type is void.)
  125. *
  126. * Version    6.00 (C)Copyright Blaise Computing Inc.  1986,1987,1989
  127. *
  128. **/
  129.  
  130. #include <dos.h>
  131. #include <string.h>
  132.  
  133. #include <bscreens.h>
  134.  
  135. #define  range(a,l,h) (((a) < (l) || (a) > (h)))
  136.  
  137.     /* Macro inc_ptr steps a pointer through the character buffer,    */
  138.     /* returning the new pointer value.                   */
  139.  
  140. #define  inc_ptr(ptr)       (want_attr ? (ptr += 2) : ++ptr)
  141.  
  142.     /* Macro str_len measures the distance between two locations in   */
  143.     /* the character buffer.                          */
  144.  
  145. #define  str_len(from,to)  ((to - from) >> (want_attr ? 1 : 0))
  146.  
  147. #define  BEL        '\7'
  148. #define  BS        '\b'
  149. #define  TAB        '\t'
  150. #define  CR        '\r'
  151. #define  LF        '\12'
  152. #define  DEL        '\177'
  153.  
  154. void scwrap(u_row,u_col,l_row,l_col,num_spaces,buffer,fore,back,option)
  155. int   u_row,u_col,l_row,l_col,num_spaces;
  156. const char *buffer;
  157. int   fore,back,option;
  158. {
  159.     int     mode,act_page,columns,last_row;
  160.     char    ch;
  161.     const char *pendstr;
  162.     int     nbytes,nonblank_len;
  163.     int     row,col,high,low,i;
  164.     int     want_attr;
  165.  
  166.     scmode(&mode,&columns,&act_page);
  167.     last_row = scrows() - 1;
  168.  
  169.     utbound(u_row,0,last_row)          /* Force reasonable values      */
  170.     utbound(u_col,0,columns - 1)
  171.     utbound(l_row,u_row,last_row)
  172.     utbound(l_col,u_col,columns - 1)
  173.  
  174.     sccurst(&row,&col,&high,&low);
  175.     if (range(row,u_row,l_row) || range(col,u_col,l_col))
  176.     sccurset((row = u_row),(col = u_col));
  177.  
  178.     want_attr = ((option & CHAR_ATTR) != 0);
  179.     if ((!want_attr) && num_spaces == 0)
  180.     num_spaces = (int) strlen(buffer);
  181.  
  182.     while (num_spaces > 0)
  183.     {
  184.     sccurst(&row,&col,&high,&low);
  185.     switch (ch = *buffer)
  186.     {
  187.         case TAB:
  188.         ch = ' ';             /* Treat TAB as a blank.        */
  189.         case ' ':
  190.         if (col == u_col)     /* Write the blank only if this */
  191.         {              /* isn't the beginning of the   */
  192.             num_spaces--;     /* line.                  */
  193.             inc_ptr(buffer);
  194.             break;
  195.         }
  196.         case CR:              /* SCTTYWIN handles both          */
  197.         case LF:              /* ordinary and special          */
  198.         case BEL:              /* characters.              */
  199.         case BS:
  200.         scttywin(u_row,u_col,l_row,l_col,ch,
  201.              want_attr ? (int) utlonyb(*(buffer+1)) : fore,
  202.              want_attr ? (int) uthinyb(*(buffer+1)) : back,
  203.              -1,-1);
  204.         num_spaces--;
  205.         inc_ptr(buffer);
  206.         break;
  207.  
  208.         default:              /* This is the beginning of a   */
  209.                       /* string of one or more          */
  210.                       /* nonblanks.              */
  211.  
  212.                       /* First measure the length of  */
  213.                       /* the string of nonblanks.     */
  214.         nbytes    = (want_attr ? (num_spaces << 2) : num_spaces);
  215.         pendstr = buffer;
  216.         while (pendstr < buffer + nbytes)
  217.             if ((ch = *inc_ptr(pendstr)) == ' '
  218.                        || ch == CR
  219.                        || ch == LF
  220.                        || ch == TAB
  221.                        || ch == BEL
  222.                        || ch == BS)
  223.             break;
  224.         nonblank_len = (int) str_len(buffer,pendstr);
  225.  
  226.                       /* If this string won't fit on  */
  227.                       /* this line,              */
  228.         if (col + nonblank_len > l_col + 1
  229.  
  230.                       /* and the string is small      */
  231.                       /* enough to fit on a new line, */
  232.             && nonblank_len <= (l_col - u_col + 1)
  233.  
  234.                       /* and this isn't already a     */
  235.                       /* fresh line,              */
  236.             && col > u_col)
  237.  
  238.                       /* Then fill the rest of the    */
  239.                       /* line with blanks and let     */
  240.                       /* SCTTYWIN advance us to the   */
  241.                       /* next line.              */
  242.             while (col++ <= l_col)
  243.             scttywin(u_row,u_col,l_row,l_col,
  244.                  (char) ' ',-1,-1,-1,-1);
  245.  
  246.                       /* Write the string itself.  If */
  247.                       /* the string is longer than    */
  248.                       /* the region is wide, then it  */
  249.                       /* will be split, but at least  */
  250.                       /* we tried.              */
  251.         for (i = nonblank_len; i; i--)
  252.         {
  253.             if ((ch = *buffer++) == DEL)
  254.             ch = ' ';     /* Print DEL as a blank         */
  255.             scttywin(u_row,u_col,l_row,l_col,ch,
  256.                  want_attr ? (int) utlonyb(*buffer) : fore,
  257.                  want_attr ? (int) uthinyb(*buffer) : back,
  258.                  -1,-1);
  259.             if (want_attr)
  260.             buffer++;
  261.         }
  262.         num_spaces -= nonblank_len;
  263.  
  264.         break;
  265.     }
  266.     }
  267. }
  268.