Text printing
-------------

In order to allow !Printers to do most of the handling of text printing,
two blocks are maintained for each active print job:

* Public. This contains:

  *   0 escape flag:   if true, an ESC sequence is being processed
  *   4 footnote flag: if true, a footnote is being processed
  *   8 format flag:   if true, a format change is being processed
  *  12 layout flag:   if true, a layout change is being processed
  *  16 line flag:     if true, a line change is being processed
  *  20 manual flag:   if true, manual feeding is taking place
  *  24 page flag:     if true, a page change is being processed
  *  28 ruler flag:    if true, a ruler is being processed
  *  32 space flag:    if true, a space code is being processed
  *  36 split flag:    if true, the output line has got to be split
  *  40 pause flag:    if true, the printer is being paused at the page end

  *  44 cc print:      determines control code handling
  *  48 number print:  if true, line numbers are being printed
  *  52 title print:   if true, titles are being printed

  *  56 cpos:          current horizontal char position
  *  60 footnote num:  current footnote number
  *  64 font_num:      current font number
  *  68 left new:      new left hand margin
  *  72 line doc:      current line number in document
  *  76 line max:      maximum number of lines to a page
  *  80 line page:     current line number on page
  *  84 page num:      current page number
  *  88 right new:     new right hand margin
  *  92 stage:         stage of document processing
  *  96 style bits:    current style settings
  * 100 xc:            printable width of a column

  * 104 layout line:   12 chars of layout string (inc. length byte)
  * 108 line epilogue: for end of each line
  * 112 name:          name of document, suitable for titles
  * 116 ruler line:    4 chars of ruler string (implemented as a word)
  * 120 time:          time of printing, suitable for titles

* Private (to back end). This obviously depends on the back end.

  PS:
  *   0 bbox:          bounding box command (ptr)
  *   4 col:           current column
  *   8 cols_print:    number of columns available
  *  12 cw:            full width of a column
  *  16 fsize:         size of current font
  *  20 h
  *  24 mt
  *  28 ph
  *  32 transform:     transformation command (ptr)
  *  36 w
  *  40 xl:            printable left hand edge of a column
  *  48 left print
  *  52 left ruler
  *  56 right print

  DP:
  *   0 height_print
  *   4 page_prologue: output at the beginning of each page

  LJ:
  *   0 col:           current column
  *   4 cw:            full width of a column
  left print
  left ruler

* Unknown

  * left print
  * left ruler
  * right print

Memory management
-----------------

!Printers maintains a private heap within its application workspace that is
managed using the RISC OS heap manager. All blocks claimed from the heap are
actually claimed to be 4 bytes too big so that an identifying tag can be
stored in the first word. Tags used by the printer manager include:

 TMPT: a header record for a template definition
 NTRY: a record for an entry in a template
 LIST: a record for a list entry in a template

 HEAD: a header record for a template's values
 PRDT: a record containing pointers to data for a template's values
 BOOL: a record storing pointers to the FALSE and TRUE values
 LSTD: a record storing points to the list values
 INTG: a record containing an integer
 GSTR: a string whose first byte is the number of characters in the string (not terminated)
 LSTR: a string whose first word is the number of characters in the string (not terminated)
 STRG: a record containing a CR terminated string
 STR0: a record containing a NULL terminated string

 PSUP: a record defining a printer support class
 WIND: a record defining a window belonging to a printer support class
 PRNT: a record defining an installed printer
 CNCT: a record defining the connection details for an installed printer
 CNFG: a record defining the configuration details for an installed printer
 PSZE: a record defining the paper size for an installed printer
 QUEU: a record defining a job for an installed printer
 TPUB: a record defining the exported variables for a particular job
 TPRV: a record defining the support code's private variables for a
         particular job

Back-end communications
-----------------------

For all communications to back-end code, a pointer to a buffer is passed to
the back-end. The contents of the buffer are thus:

Offset 0 - reason code (see below)
       4 - pointer to current PSUP block
       8 - pointer to current PRNT block
      12 - pointer to additional buffer, called xbuff below
           (only supplied if appropriate)
      16 - pointer to the head of the paper size linked list

Reason codes
------------

     Code: -1 (initialise back-end)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To allow the back-end code to perform any initialisation that it
           may require
    Notes: As part of the initialisation, the back-end code should update
              the psup block as follows:

              +28   flags: 2 - back end supplies Connections window
                           3 - requires Null_Reason_Code events
                           4 - direct drive printing available
                           5 - back-end needs to be able to write to '<Choices$Write>.Printers'
                               if this is read-only when a PDF for that class
                               is loaded, the PDF will be rejected.
                      8 ~ 15 - timeout required for Wimp_PollIdle (if bit 3 set)
              +32   the filetype for its raw data file
              +36   the text capability flags
              +40   size of the CNFG block (in words)
              +44   version of back end (reflects the status of the files
                    being read, ie only change this number if the file
                    contents change)
              +48   version of !Printers required
              +52   size of the CNCT block (in words) if flags bit 2 set

           All other locations, INCLUDING bits of +28 not defined above, must be
           unchanged. Note that PRNT is nought - there is no selected printer
           yet.

     Code: -2 (terminate back-end)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To allow the back-end code to perform any finalisation that it
           may require

     Code: -3 (initialise the configuration window)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To ensure that the icons in the "configure" window are correct

     Code: -4 (create a suitable initial CNFG block)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To create a first-stage CNFG block
    Notes: At the time that this call is made, the PRNT block will have been
           partially initialised, so the CNFG block should hold values
           appropriate to the installed printer. The code should finish by
           putting a pointer to the CNFG block into the appropriate word in
           the PRNT block.

     Code: -5 (post-printer back-end initialisaton)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To allow the back-end code to do any initialisation after all of
           the printers have been installed
    Notes: This call is used, for example, by the PS code to remove the font
           file for the printer.
           It should be noted that for this call, PSUP will point to the
           PSUP block for the back-end, but PRNT will point to the head of
           the PRNT chain. This allows the back-end to traverse the entire
           printer list.

     Code: -6 (initialise the specified printer)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To select and initialise the specified printer and driver
    Notes: The code should, amongst other things, do the following:
           * ensure the printer driver is loaded
           * select the printer
           * set the driver info
           * export any necessary system variables for this printer

     Code: -7 (terminate the current job)
 On entry: xbuff%!0 contains the QUEU block pointer
  On exit: No additional parameters
  Purpose: To allow the back-end to tidy up
    Notes: The back-end code should at this point release its private
           variable chunk and free up the character translation linked list.
           *NO* characters are allowed to be output to the printer.

     Code: -8 (text processing)
 On entry: xbuff!0 contains the text processing reason code
           xbuff!4 contains the QUEU pointer for this print job
           There may be other parameters passed (see below)
  On exit: Dependent on text processing reason code
  Purpose: To perform back-end specific text processing tasks

     Code: -9 (printer being removed)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To inform the back-end of a printer being removed

     Code: -10 (printer being deactivated)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To inform the back-end of a printer being deactivated

     Code: -11 (initialise the connections window)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To ensure that the icons in the "connections" window are correct.
           This entry point is called only if the connections window is
           back-end-supplied.

     Code: -12 (create a suitable initial CNCT block)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To create a first-stage CNCT block
    Notes: At the time that this call is made, the PRNT block will have been
           partially initialised, so the CNCT block should hold values
           appropriate to the installed printer. The code should finish by
           putting a pointer to the CNCT block into the appropriate word in
           the PRNT block. This entry point is called only if the
           connections window is back-end-supplied.

     Code: 0 (null event)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To act upon a null event
    Notes: PSUP will point to the PSUP block for the back-end, but PRNT will
           point to the currently selected PRNT block (or 0 if there isn't
           one)

     Code: 17/18 (user message)
 On entry: xbuff% contains the wimp poll buffer contents
  On exit: No additional parameters
  Purpose: To act upon an unrecognised user message
    Notes: PSUP will point to the PSUP block for the back-end, but PRNT will
           point to the currently selected PRNT block (or 0 if there isn't
           one)

Text processing reason codes
----------------------------

     Code: -1 (initialise the text print job)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: To initialise both public and private text variables
    Notes: It is up to the back-end job to claim a block of memory for the
           private variables and use it are required. It should, at this
           point, initialise a linked-list of character translations and
           store the pointer into the QUEU block.

     Code: -2 (produce any required job initialisation output)
 On entry: xbuff!8 contains the output handle
  On exit: No additional parameters
  Purpose: To output any job initialisation code

     Code: -3 (produce the page header)
 On entry: xbuff!8 contains the output handle
  On exit: No additional parameters
  Purpose: To output the appropriate header for the page

     Code: -4 (do post-line processing)
 On entry: xbuff!8 contains the number of chars output on this line so far
  On exit: xbuff+8 contains a GSTR string
  Purpose: This call is made when the current line has ended
    Notes: The code needs to terminate the current line as appropriate, then
           decide whether or not a fresh page is required, eg the PS
           back-end decides if it can move on to another column on the page.

     Code: -5 (do character translation)
 On entry: xbuff!8 contains the character
  On exit: xbuff+8 contains a GSTR string
  Purpose: To translate (if required) the specified character into a
           different character, or string of characters.
    Notes: The character passed WILL be printable, ie no cognizance of the
           control code processing needs to be made.
           This call will ONLY be made if either the translation pointer is
           -1 or the last pointer in the translation chain is -1. This
           should be used as a LAST resort since it will slow printing down
           quite badly. Typically, providing a linked list of translations
           and allowing all other characters to be printed normally will
           suffice.

     Code: -6 (do control code processing)
 On entry: xbuff!8 contains the character
  On exit: xbuff+8 contains a GSTR string
  Purpose: To translate the control code into the appropriate output.
    Notes: The pub_cc_print variable should be used to determine how to
           handle the output.

     Code: -7 (do a backspace)
 On entry: No additional parameters
  On exit: xbuff+8 contains a GSTR string
  Purpose: To process the backspace character

     Code: -8 (handle line splitting)
 On entry: No additional parameters
  On exit: xbuff+8 contains a GSTR string
  Purpose: To process the splitting of the line output
    Notes: The string returns simply needs to move the output point on to
           the next line at the appropriate x offset.
           This call is only used if the capability flag asks for it.

     Code: -9 (handle style changes)
 On entry: xbuff!8 contains the new style flags
  On exit: xbuff+8 contains a GSTR string
  Purpose: To output any codes to process the style change

     Code: -10 (start a new line)
 On entry: No additional parameters
  On exit: xbuff+8 contains a GSTR string
  Purpose: To output any codes to start a new line
    Notes: The code *must* increment tpub_line_page and tpub_line_doc.
           Ending a line is done by !Printers outputting tpub$line_epilogue

     Code: -11 (print a footnote number)
 On entry: No additional parameters
  On exit: xbuff+8 contains a GSTR string
  Purpose: To output the footnote number as a superscript

     Code: -12 (perform string translation)
 On entry: xbuff$8 contains a CR terminated string to translate
  On exit: xbuff+8 contains a GSTR string
  Purpose: Perform wholesale translation on a string
    Notes: Although the various back-ends will handle this process in a
           remarkably similar manner, it is more efficient to use this call
           than the general translation call several times.

     Code: -13 (handle font change)
 On entry: xbuff!8 contains the new font number
  On exit: xbuff+8 contains a GSTR string
  Purpose: To output any codes required to change the font

     Code: -14 (finish the page)
 On entry: xbuff!8 contains the output handle
  On exit: No additional parameters
  Purpose: Output the codes required to finish off the page

     Code: -15 (finish the job)
 On entry: No additional parameters
  On exit: No additional parameters
  Purpose: Output the codes required to finish off the job
           Note: this gets called regardless of the original filetype being
           printed, ie it gets called for native files as well as translated
           files.

     Code: -16 (do a tab)
 On entry: No additional parameters
  On exit: xbuff+8 contains a GSTR string
  Purpose: To process the tab character

     Code: -17 (do a formfeed)
 On entry: No additional parameters
  On exit: xbuff+8 contains a GSTR string
  Purpose: To cause the current page to feed

     Code: -18 (change layout)
 On entry: xbuff!8 contains the new layout height
           xbuff!12 contains the new layout top
           xbuff!16 contains the new layout bottom
  On exit: xbuff+8 contains a GSTR string
  Purpose: To allow the back-end to adjust its settings for the page
    Notes: The string returned may be used to adjust the printer for any
           necessary changes in, say, the page height

     Code: -19 (start a new page)
 On entry: No additional parameters
  On exit: xbuff+8 contains a GSTR string
  Purpose: To start a new page
    Notes: Some back-ends may use this code to output the title.
           pub_line% should be set to the current line.

     Code: -20 (start printing native file)
 On entry: xbuff!8 contains the output handle
           xbuff!12 contains the input handle
  On exit: No additional parameters
  Purpose: To output any pre-job native file code
