textarea.c
----------

History
-------
26th October 1992  J R C  Started

   All the handling for text aress is done in here: the functions are
invoked from |render| and |declare|.

   The formatting is done in a fixed size buffer of size |TEXT_BUFFER_SIZE|:
this macro is defined as 255 at present. Lines longer than this will not be
aligned properly. The way in which this would show itself is that the
inter-word spacing in a line would all be in the last 255 characters on the
line. It can be increased at preprocessing time if necessary.

   There are two data structures: the first, a structure called |Esc|, is
used to hold the successive lexemes as they are pared from the text area.
There is a tag, which is either a printable character (bit 8 clear) of else
a command code (bit 8 set), and a union of possible argument types. The
function |Lex_Next| fills in this structure as the text area is traversed.

   The other is a structure |State| used to remember the output state of the
module, including the buffer, the buffer pointer, the text column and
coordinate position which is the current output destination, the current
underline settings, etc.

   The main entry point is |textarea_render|. This is used by
|render_text_area| to do the work. The tracing version fills the background
of each text column with grey befoire it renders them. It fills in |state|
with its initial values, then repeatedly calls |Lex_Next|, until a 0 lexeme
is returned which indicates the end of the text area. Each lexeme type is
acted on apropriately, and there is a small state macxhine to cope with
newline characters (which are to be rendered either as spaces, line breaks,
or paragraph break, depending on context).

   The other entry point is |textarea_declare|, used by |declare_text_area|
to declare the fonts used in a text area. It also parses the text area using
|Lex_Next|, but only takes notice of '\F' commands.

   The function |Flush| is responsible for emptying this onto the screen as
necessary. It is called in three diferent ways depending on the reaoson for
invoking it:

         Flush_All: used at a line break to force everything in the
      buffer to the screen;

         Flush_Some: used when the buffer is full and space is needed -
      may force badly justified lines, but only if they are longer than
      the buffer size;

         Flush_Complete: used when some parameter is changing to clear
      out completed lines, with the expectation that the new value will
      apply to line it lies within.

This is the function that format and justifies lines of text and sends them
to the Font Manager for rendering. There is only one pass over the text,
unlike Draw which takes two, and all parameters that the Font Manager can
remember are not remembered here (this is the current font, colours).

   |Lex_Next| reads the input data one lexeme at a time, making the
following checks:

         the syntax of each of the commands is correct;

         the area version number is correct;

         any out-of-range arguments are forced back into the allowed range;

The maxumum font name allowed is 40 characters - this is what the Font
Manager provides. Any '\-' (soft hyphen) sequences in the text area are
converted to true ASCII soft hyphen characters (this behaviour is different
from Draw, which simply renders ASCII soft hyphens in a text area as
hyphens).

   |EmitC| and |EmitS| take a single printabe character, and a Font Manager
control sequence (respectively) and add them to the buffer, making sure
there is no overflow. |Emit_Line| and |Emit_Paragraph| are similar in
concept, but work by adjusting the current output-position values in
|state|.

   There are two other support functions: |Syntax| builds a "Syntax error"
message, and |Range_Check| forces a value to lie within a certain range.

   It is unintentional that the module uses a word of static data to hold
the current character pointer into the text area text (it is the only static
data); this is the only way in which the module fails to be reentrant. It's
probably not important, but if it is required to render draw files under
interrupt (!!), it can be changed fairly easily.
