                             WORD WRAPPING

                            Matthew Probert
                           Servile  Software



Word wrapping provides a neat and tidy presentation for text display 
and for user input. 

Two functions are provided below. One displays a string within a 
Borland C window using word wrap, the other accepts input of a string 
within a Borland C window with word wrap. These functions might find a 
use in a BBS on-line chat system for example:


-----------------------------Cut Here-----------------------------
#include <conio.h>
#include <mem.h>

void SHOW_WORD_WRAPPED(char *text)
{
    /*
        Display a string in a window with word wrap
    */

    struct text_info r;
    char c;
    char *p;
    int col;
    int length;
    int line_length;

    /*
        Get window coordinates
    */
    gettextinfo(&r);

    /*
        Maximum line length is the width of the window
    */
    line_length = r.winright - r.winleft;

    /*
        Initialise col to current column
    */
    col = wherex();

    for(;;)
    {
        /*
            Get length of next word
        */
        p = text;
        length = 0;
        for(;;)
        {
            if (*p < 33)
                break;
            length++;
            p++;
        }

        if (col + length >= line_length)
        {
            /*
                The next word would break, so
                display a newline to prevent this
            */
            cprintf("\r\n");
            col = 0;
        }

        /*
            Now display next character
        */
        c = *text;

        if (c == 0)        /* End of string? */
            break;

        text++;
        if (c == 9)
        {
            /*
                Expand TAB
            */
            cprintf("        ");
            col += 8;
        }
        else
            putch(c);
        if (c > 31)
            col++;
    }
}


void INPUT_WORD_WRAPPED(char *text)
{
    /*
        Input text from the console through
        a window with word wrapping on the displayed text
        Destructive backspace is catered for to allow mistakes
        to be corrected.
    */

    struct text_info r;
    int line_length;
    int height;
    int row;
    int col;
    int key;
    char word[80];

    /*
        Get window coordinates
    */
    gettextinfo(&r);

    /*
        Maximum line length is the width of the window
    */
    line_length = r.winright - r.winleft;
    height = r.winbottom - r.wintop;

    /*
        Initialise row and col to current row and column
    */
    row = wherey();
    col = wherex();

    for(;;)
    {
        /*
            Position cursor
        */
        gotoxy(col,row);

        /*
            Get key press
        */
        key = getch();
        if (key == 0)
        {
            /*
                Extended key presses
            */
            key = getch();
        }
        else
        {
            /*
                Standard key presses
            */
            if (key == 8)
            {
                /*
                    Destructive backspace
                */
                if (row > 1 || col > 1)
                {
                    /*
                        Ignore if there is no text to delete
                    */
                    *--text = 0;
                    col--;
                    if (col < 1)
                    {
                        row--;
                        col = line_length;
                    }
                    gotoxy(col,row);
                    putch(' ');
                    gotoxy(col,row);
                }
            }
            else
            if (key == 13)
            {
                cprintf("\r\n");
                *text++ = '\n';
            }
            else
            if (key == 27)
                return;
            else
            if (key > 31)
            {
                if (col > line_length)
                {
                    /*
                        Entering text at end of line, wrap
                    */
                    if (key > 32)
                    {
                        memset(word,0,80);

                        do
                        {
                            /*
                                If we are at the bottom line of the
                                window this will scroll the window,
                                so the row variable must be decremented
                                to go to the row with the old text
                            */
                            if (row > height)
                                row--;

                            word[col] = *(text-1);
                            putch(' ');
                            col--;
                            gotoxy(col,row);
                            text--;
                        }
                        while(*text > 32 && col > 1);

                        row++;
                        cprintf("\r\n");
                        while(word[col+1])
                        {
                            if (word[col+1] != ' ')
                                putch(word[col+1]);
                            word[col+1] = 0;
                            col++;
                            text++;
                        }
                    }
                }
                putch(key);
            }
            if (key != 8)
                *text++ = key;
            col = wherex();
            row = wherey();
        }
    }
}
-----------------------------Cut Here-----------------------------

