******************************************************************
*                                                                *
*                                                                *
*          Title : Font Manager improvements                     *
*                                                                *
*         Author : Neil Raine, David De Vorchik                  *
*                                                                *
*           Date : 04-May-91                                     *
*                                                                *
*        Version : 1.06                                          *
*                                                                *
*  Change Record : 23-Mar-90    Initial draft                    *
*                  28-Mar-90    Fleshed out a lot                *
*                  29-Mar-90    ROM fonts section added          *
*                  24-Aug-90    Different alphabets added        *
*                   7-Dec-90    Font_ListFonts/Font_FindFont     *
*                  18-Dec-90    Updated Font_ListFonts           *
*                   8-Jan-91    Added *Load/SaveFontCache        *
*                   8-Jan-91    Updated summary for above        *
*                   8-Jan-91    Added bit 10 for Font_Paint      *
*                   8-Jan-91    Added bit 10 for Font_ScanString *
*                  14-Jan-91    Rationalised for RISC OS 2.50    *
*                  14-Feb-91    Font_Current/FutureRGB           *
*                  19-Feb-91    Font_SwitchOutputToBuffer        *
*                  19-Feb-91    Font_ReadFontMetrics             *
*                  28-Feb-91    Altered \I,\N,\A to \F,\f,\E,\e  *
*                   4-Apr-91    Updated kern info format         *
*                  15-Apr-91    Removed duplicate ReadFontMetrics*
*                  15-Apr-91    Added Font_ReadEncodingFilename  *
*                  04-May-91    Extensions to Font_ReadDefn      *
*                  03-Jun-91    Corrections to Font_ReadDefn     *
*                  03-Jun-91    Extensions to Font_ReadColourTable *
*                  03-Jun-91    Alterations to Font_SetColourTable *
*                                                                *
******************************************************************

Font Manager improvements for RISC OS 2.50
==========================================

Already implemented:

    *   To save RAM, the font manager can access outline font definitions
        directly in ROM, without copying them into its font cache.  Bitmaps
        are constructed from these outlines as required, and can be stored
        in the cache if required.

    *   Font_SwitchOutputToBuffer allows font strings to be converted to a
        sequence of Draw paths.  This allows legal access to a font's
        outlines.

    *   RGB colour changes are allowed in Font_Paint strings.  Previously
        this would only work when printing.

    *   Font_CurrentRGB returns the current RGB colours as set by
        19,r,g,b,R,G,B,max sequences in the Font_Paint string.

    *   Font_FutureRGB returns the RGB colours that would have been in force
        if the string that has just been passed to Font_ScanString /
        StringWidth / StringBBox were sent to Font_Paint.

    *   Font_CurrentRGB and Font_FutureRGB both return an "Undefined font
        RGB colours" error if the last colour set was an old-style one (ie.
        not a 19 sequence).  Font_Paint also returns this error if
        Font_SwitchOutputToBuffer is in force and a character, rubout box or
        underline needs to be output while the colours are invalid.

    *   The format of metrics files has been extended to allow information
        such as the recommended underline position, capheight, italic slant
        and kerning to be stored.  Font_ReadFontMetrics allows direct access
        to this.

    *   *LoadFontCache and *SaveFontCache, useful for setting up the font
        cache to a predefined state quickly.

    *   The name of a font as stored in the font cache is taken from the
        pathname of the font, rather than the name stored in the IntMetrics
        file.  This avoids the problem whereby if Font_FindFont is called
        repeatedly for the same font name, a different font handle is
        returned each time, even if the font is already held in the cache.

    *   Characters are converted from outlines to bitmaps in the cache
        on an individual basis, rather than 32 at a time as were before. 
        This is very important for (eg) wrapping text around a draw
        path, as there are many single characters with different
        transforms.

    *   This last point requires the font cache structure to be changed
        radically.  A more efficient garbage collection must be used, as the
        blocks in the cache become smaller and more numerous.

    *   Font_FindFont allows matrix transformations to be applied to fonts.

    *   The font aliasing technique whereby a font's outlines can be derived
        from another one is extended to allow a matrix transformation to be
        automatically applied to the original font outlines.  In this way
        large amounts of memory can be saved, as all the Oblique fonts in
        the standard set can be obtained by simply shearing the non-oblique
        equivalents.

    *   Font_ListFonts caches the results of scanning font directories, to
        speed up access to the fonts.  It is hoped that in future
        applications will be able to cope with changes in the fonts
        available without having to be reloaded.

    *   Font_ListFonts also allows a Wimp menu of all the fonts available to
        be built up automatically.  Font_DecodeMenu allows a menu selection
        within this menu to be automatically converted to a font identifier
        which can be passed to Font_FindFont.

    *   New commands *FontInstall, *FontRemove and *FontLibrary can be used
        to alter Font$Path and Font$Prefix without losing the other fonts in
        the font path.  Service_FontsChanged (&6E) is issued by the Font
        Manager to notify any applications that Font_ListFonts should be
        called to update the list of fonts available.

    *   A new SWI, Font_ScanString, replaces Font_StringWidth,
        Font_FindCaret and so on, and allows the various extra functions to
        be specified.

    *   Font_Paint should allow matrix transformations.  This will require
        each font in the cache to provide acccess to bitmaps at different
        transformations.

    *   Font_Paint and Font_ScanString should have an option for text to be
        painted from right to left, as well as the current left to right
        operation.  This would mainly affect rubout, underlining, kerning
        and metrics calculations.

    *   Font_Paint, Font_StringWidth, Font_FindCaret etc. have been extended
        to allow kerning to be performed automatically.  This is in addition
        to Font_ReadFontMetrics, which allows applications to unpick the
        metrics information themselves.

    *   The default encoding for a font depends on the alphabet number of
        the current territory.  This only applies to fonts with encodings that can
        be used as alphabets (ie. Latin1, Latin2 etc.), and not to symbol
        fonts such as Selwyn and Sussex, which appear the same in any
        territory.

    *   Font_FindFont allows an encoding other than the current alphabet to
        be used, by looking for "\E <encoding id>" somewhere in the string
        passed in R1.

    *   The user can relatively easily set up non-standard encodings by
        altering the contents of various text files which define the name of
        each glyph in the encoding, and its position in the character set.

    *   Since bitmap files relate to a single encoding only, where an
        encoding has been applied to a font, its bitmaps are contained
        within a <fontname>.<encoding> subdirectory.

Not yet implemented:

    *   When Font_FindFont is called with resolution (-1,-1), the resulting
        font should use the screen resolution at Font_Paint time, rather
        than at Font_FindFont time.  This would make it much easier for the
        Wimp to use anti-aliased fonts in a mode-independent way in windows,
        since the font need not be redefined whenever a mode change occurs.

Changes to the interface
------------------------

Deprecated SWIs:

      Font_FindCaret            ; needs matrix
      Font_FindCaretJ           ; needs matrix
      Font_StringWidth          ; needs matrix
      Font_StringBBox           ; needs matrix
      Font_SetFont              ; silly when you can use Font_Paint (R0)
      Font_ReadInfo             ; font bbox can be found using Font_CharBBox

Extended SWIs:

      Font_Caret                ; needs matrix
      Font_Paint                ; new parameters for matrix etc
      Font_CharBBox             ; code = -1 => return font bbox

New SWIs:

      Font_ReadFontMetrics      ; return whole of font metrics in buffers
      Font_ScanString           ; deals with Font_StringWidth etc.
      Font_SwitchOutputToBuffer ; for exporting character outlines
      Font_SetColourTable       ; for ColourTrans to poke the Font Manager
      Font_CurrentRGB           ; for reading the current RGB settings
      Font_FutureRGB            ; for reading the future RGB settings

New control codes in Font_Paint

      27,28             ; set new paint matrix
      19                ; 19,r,g,b,R,G,B,max = ColourTrans_SetFontColours

(Existing ones):
      0, 10, 13         ; terminator
      9, 11             ; horizontal / vertical movement
      17, 18            ; colour change
      21                ; comment
      25                ; underline
      26                ; font change


New definition of Font_Paint
----------------------------

    Font_Paint
    In: R0 = not used (if R2 bit 8 clear)
        R0 = initial font handle (1..255) or 0 => current (if R2 bit 8 set)
        R1 -> string
        R2 = flags:
            bit 0 set => use justification coordinates (bit 5 must be 0)
            bit 1 set => use rubout box coordinates
            bits 2,3 ignored
            bit 4 set => coords are OS units or 1/256 OS unit, else 1/72000"
                         (OS units if R2 bits 5,6=0, else 1/256 OS unit)
            bit 5 set => use R5 as indicated below, else PLOT coords
            bit 6 set => use R6 as indicated below
            bit 7 set => use R7 as indicated below
            bit 8 set => R0 = initial font handle or 0 (else ignored)
            bit 9 set => perform kerning on the string
            bit 10 set => writing direction is right to left (else left to right)
            bits 11..31 reserved (must be 0)
        R3,R4 = start coordinates (units depend on R2 bits 4,5)
        R5 -> coordinate block (if R2 bit 5 set):
            R5!0,4 = additional x,y offset on space (note R2 bits 0,4)
            R5!8,12 = additional x,y offset between each letter (note R2 bit 4)
            R5!16,20,24,28 = rubout box coordinates (note R2 bits 1,4)
        R6 -> transformation matrix (if R2 bit 6 set)
            R6!0..R6!12 = fixed point multipliers
            R6!16,R6!20= translation (units depend on R2 bits 4,5)
            unit matrix = [1<<16,0,0,1<<16,0,0]
        R7 = length of string (if R2 bit 7 set)

    In the RISC OS 2.50 implementation, if R2 bits 5 or 6 are set, the Font
    Manager will return an error if R2 bit 4 is set.  This is because the
    new coordinate system will not be implemented until RISC OS 3.00.

    Note that the character at [R1,R7] may be accessed, to determine the
    character offset due to kerning (which in turn affects the underline
    width).  This will not be a problem if the string has a terminator, and
    the R7=length facility is only used to extract substrings.

    If R2 bit 5 is clear, the justification and rubout box coordinates are
    taken from the previous graphics cursor positions, which are supplied in
    OS units and rounded by the MOS to the nearest pixel.  In this case, the
    justification y-coordinate is ignored (since it is too inaccurate), and
    the start y-coordinate is used instead.  The rubout box coordinates are
    also treated as inclusive, as for graphics window setting, whereas when
    they are in the block pointed to by R5, the fill rule is as for
    Draw_Fill of full interior and interior boundary pixels, ie. fill if the
    pixel centre is enclosed.

    If R2 bit 5 is set, then R2 bit 0 must be unset (the 'justification' is
    provided by the x,y offsets in the first 4 words in the coordinate
    block, rather than by a target point).  Left-justification can be
    achieved by simply setting these 4 words to 0.

    If bit 6 is set, R6 -> transformation matrix to use at the start. 
    Subsequent matrices in the string alter the matrix to the specified
    value, rather than being concatenated with any previous matrix.  Matrix
    changes within the string are made using one of the following control
    sequences:

                27, <align>, m1, m2, m3, m4
             or 28, <align>, m1, m2, m3, m4, m5, m6

    where <align> means "advance until pointer is word-aligned".  The
    equation for this is:

        pointer := (pointer + 3) AND NOT 3

    m1..m4 are little-endian 32-bit signed numbers with a fixed point at bit
    16, ie. 1 is represented as 1 << 16, or 65536.

    m5 and m6 are the offsets, which are in 1/72000" (even if R2 bit 4 is
    set).  These values are assumed to be 0 if the 27,m1..m4 code is used.

    To restore the unit matrix, use 27,<align>,65536,0,0,65536.

    Note that underlining and rubout do not work correctly if the x-axis is
    transformed so that it is no longer on the output x-axis, or has its
    direction reversed.  The effect when doing this should NOT be relied on.

    If bit 10 is set, then text is written right to left, rather than left
    to right.  In this case the width of each character is subtracted from
    the position of the current point before painting the character, rather
    than the width being added after painting it.  Rubout and underline are
    also filled in from right to left.

    When kerning, the kern pairs stored in the metrics file indicate the
    left and right hand characters of a pair, and the additional offset to
    be applied between the characters if this pair is found.  Note that if
    the main writing direction is right to left, then the right hand
    character is encountered first, and the left hand one is encountered
    next.

Subpixel scaling:

    This is quite simple if neither x or y scaling is performed, and also if
    both x and y scaling is performed - the subpixel scaling directions
    relate to the output device axes.

    When just horizontal or just vertical subpixel scaling is performed, it
    is sometimes necessary to swap over the sense of which is h and which is
    v, in order to determine the 'size' of the font.

    This goes for the other FontMax<n> thresholds too, such as FontMax2,
    which determines whether characters should be anti-aliased.  FontMax3
    determines whether characters should be cached or not, and this must
    relate to the amount of memory taken up by the bitmaps.

Scaffolding:

    Clearly it is not possible to apply scaffolding to characters which are
    transformed such that its new axes do not lie on the old ones.  However,
    if the axes are mapped onto each other (eg. a scale, rotation or
    reflection about an axis or 45-degree line) then scaffolding can still
    be applied.  This can involve swapping over the x and y scaffolding.  If
    a font is sheared, then scaffolding may be applied in one direction but
    not the other.

Bounding boxes:

    The bounding box of a transformed character cannot be determined purely
    by transforming the original bounding box of the character outline,
    since bounding boxes are axis-aligned rectangles, and character outlines
    are not, so the bounding box of the transformed character is typically
    smaller than that of the transformed bounding box.

    Taking the bounding box of the transformed original bounding box is
    sufficient to work out a large enough box for outline->bitmap
    conversion, since not much memory is wasted (only one character is done
    at a time, and the character is 'shrink-wrapped' after conversion).

Bitmap fonts:

    If a font has an encoding applied to it, then Font_Paint looks inside
    <fontname>.<encoding> to find the bitmap files.  This is because bitmap
    files are specific to one encoding.

    Note that Font_MakeBitmap also generates its bitmap files inside the
    appropriate encoding subdirectory.

    If the font has no encoding applied, the bitmap files are inside the
    font directory, as before.

    Note that this means that encoding names must not clash with any of the
    filenames that normally reside within font directories, ie:

        IntMetrics[<n>]         ; <n> is optional and the prefix is
        Outlines[<n>]           ; truncated so it all fits in 10 characters
        x90y45
        b<n>x<n>                ; <n> is a number from 1..9999
        f<n>x<n>


Font_ScanString
---------------

    This is similar to Font_Paint above, but there are extra bits in R2 to
    do with returning results.

    Font_ScanString
    In: R0 = not used (if R2 bit 8 clear)
        R0 = initial font handle (1..255) or 0 => current (if R2 bit 8 set)
        R1 -> string (terminated by 0, 10 or 13)
        R2 = flags:
            bits 0..3 reserved (must be 0)
            bit 4 set => coords are 1/256 OS unit, else 1/72000"
            bit 5 set => use R5 as indicated below
            bit 6 set => use R6 as indicated below
            bit 7 set => use R7 as indicated below
            bit 8 set => R0 = initial font handle or 0 (else ignored)
            bit 9 set => perform kerning on the string
            bit 10 set => main writing direction is right to left, else left to right
            bits 11..15 reserved (must be 0)
            bit 16 reserved (must be 0)
            bit 17 set => return nearest caret position, else width of string
            bit 18 set => return bbox of string
            bit 19 set => return matrix applying at end of string in [R6..]
            bit 20 set => return number of split characters in R7
            bits 21..31 reserved (must be 0)
        R3,R4 = max x,y-coord offset before termination
                (or offset of mouse click for caret search)
        R5 -> coordinate block (R2 bits 0,1 => whether used)
            R5!0,4 = additional x,y offset on space
            R5!8,12 = additional x,y offset on each character
            R5!16 = split char (-1 => no split char)
        R6 -> transformation matrix (if R2 bit 6 set)
              or buffer for returned matrix (if R2 bit 19 set)
        R7 = length of string (if R2 bit 7 set)
    Out:R1 -> point where scan terminated
        R3,R4 = x,y offset to termination point (or caret position)
        [R5] updated as follows (if R2 bits 5 and 18 set):
             R5!20,24,28,32 = string bbox (note R2 bit 4)
        [R6] updated (if R2 bit 19 set):
             R6!0,4,8,12,16,20 contain matrix at point where scan terminated
        R7 = number of split characters encountered (if R2 bit 20 set)

    In the RISC OS 2.50 implementation, the Font Manager will return an
    error if R2 bit 4 is set.  This is because the new coordinate system
    is not yet implemented.

    Note that the character at [R1,R7] may be accessed, to determine whether
    it is a 'split character'.  It may also make a difference to the string
    width, if kerning is enabled.

    If R5!16 = -1, ie. there is no split character, then the number of
    'split characters' returned in R7 if R2 bit 20 is set is the number of
    non-control characters encountered, ie. those whose codes are 32 or more
    and which are not part of a control sequence.

    When scanning for termination (as opposed to finding the nearest caret
    position), the scan continues until the current offset is less than or
    greater than the limit supplied, depending on the sign of that limit. 
    In other words, if R3 is negative on entry, the scan continues until the
    x offset is less than R3, while if R3 is positive, the scan continues
    until the x offset is greater than R3.  Note that this is incompatible
    with the old Font_StringWidth call, which always continued until the
    x,y offsets were greater than R2 or R3 (Font_StringWidth still works in
    the old way, to ensure compatibility).

    Where bit 10 is set, ie. the main writing direction is right to left,
    one would normally supply a negative value of R3.

    If a bounding box is returned, this does not include the area occupied
    by underlining or rubout.

    This SWI replaces the following deprecated (still supported, but not
    recommended) SWIs:

        Font_FindCaret
        Font_FindCaretJ
        Font_StringWidth
        Font_StringBBox


Font_CurrentRGB
---------------

    This SWI allows the setting of the RGB foreground and background colours
    after calling Font_Paint to be read.

        Font_CurrentRGB
        Out:    R0 = font handle
                R1 = background font colour
                R2 = foreground font colour
                R3 = max colour offset (0 => mono, else anti-aliased)
        Error:  "Undefined RGB font colours" if colours not set using RGB


Font_FutureRGB
--------------

    This SWI allows the setting of the RGB foreground and background colours
    after calling Font_ScanString, Font_StringWidth, Font_StringBBox,
    Font_FindCaret or Font_FindCaretJ to be read.

        Font_FutureRGB
        Out:    R0 = font handle
                R1 = background font colour
                R2 = foreground font colour
                R3 = max colour offset (0 => mono, else anti-aliased)
        Error:  "Undefined RGB font colours" if colours not set using RGB


Font_ReadColourTable
-------------------

        Font_ReadColourTable
        In:    R0 = &44524F57 ("WORD") => R1 -> 16-word table to contain results
                                     else R1 -> 16 byte array to contain results
        Out:   [R1..] = output data for each of the 16 anti-aliasing colours
               If R0="WORD" on entry, then the values are in the top <bpp> bits of each word
                                      else they in the bottom <bpp> bits of each byte
               where <bpp> denotes the number of bits per pixel in the current output mode

Font_SetColourTable
-------------------

    This SWI allows the ColourTrans module to poke colours directly into the
    Font Manager's colour table to determine preceisely which colours are
    used for font rendering.

    It also specifies the exact (24-bit) colours which the current colours
    are supposed to represent, and so allow ColourTrans_SetFontColours to
    tell the Font Manager the colours which the caller regards as being
    represented by the current colours.

        Font_SetColourTable
        In:     R0 = new font handle (0 => leave unchanged)
                R1 -> 16-word table of pixel values, shifted to top of word (background..foreground)
                R1 = 0 => don't set table (just use RGB values)
                R2 = true 24-bit RGB of background colour
                R3 = true 24-bit RGB of foreground colour
                R4 = max colour offset (as passed to ColourTrans_SetFontColours)
                     (0 => use 1-bpp bitmaps, else use 4-bpp bitmaps)
        Error:  "Invalid font colour" if pixel values too big

    ColourTrans_SetFontColours actually works out what the colours should
    be, then calls Font_SetFontColours (thus invalidating the Font Manager's
    internal idea of what the current RGB colours are), and then calls
    Font_SetColourTable with R1=0, R2,R3,R4 = parameters as passed to
    ColourTrans_SetFontColours.  If output is directed to a buffer, this
    allows Font_Paint to get the colours of the resulting DrawFile objects
    right.

    In fact in 256-colour modes things are even more complex:
    ColourTrans_Set/ReadFontColours chooses a pseudo-palette entry to use,
    then calls Font_SetPalette to set up the font data: the Font Manager
    then calls ColourTrans_SetTable to set up its own colour table. 
    ColourTrans then calls Font_ReadColourTable to find out what this data
    is, and stashes it in its own cache, along with the corresponding
    background, foreground and max colour offset.  On subsequent calls, if
    the same RGB colours are requested, ColourTrans calls
    Font_SetFontColours to set up the correct current colour, and uses
    Font_SetColourTable to restore the colour data more quickly.

    Note that this SWI should not called by application programs, since the
    Printer Drivers cannot deal correctly with it.  Use
    ColourTrans_SetFontColours or Font_Paint 19 sequences instead.


Font_SetPalette
---------------

    This now takes one extra parameter:

        In      R6 = &65757254 ("True") => use all 24 bits of R3,R4

    If R6 is equal to this magic word, the RGB values in R3 and R4 are
    treated as true 24-bit palette values, where white = &FFFFFF00 (not
    &F0F0F000).

    Otherwise, for compatibility, palette values are processed as follows:

        R3 := (R3 AND &F0F0F000) OR ((R3 AND &F0F0F000) >> 4)
        R4 := (R4 AND &F0F0F000) OR ((R4 AND &F0F0F000) >> 4)

    Thus the bottom nibbles of each gun are set to be copies of the top
    nibbles.

    The Font Manager now calls ColourTrans_SetPalette to set palette entries
    in non 256 colour modes, and calls ColourTrans_ReturnColourNumber to
    match RGB values with logical colours in modes with 256 colours or more.

    If ColourTrans is not loaded, it calls PaletteV to set the palette, and
    if PaletteV is not intercepted, it finally calls OS_Word 12 to set the
    palette.


Font_ReadFontMetrics
--------------------

    This SWI allows the new metrics information held in a font's IntMetrics
    file to be accessed directly.

      Font_ReadFontMetrics
      In:   R0 = font handle
            R1 = 0 or -> buffer to contain bbox info
            R2 = 0 or -> buffer to contain xwidth info
            R3 = 0 or -> buffer to contain ywidth info
            R4 = 0 or -> buffer to contain miscellaneous info
            R5 = 0 or -> buffer to contain kerning info
            R6 = 0
            R7 = 0
      Out:  R0 = file flags:
                    bit 1 set => kern pairs don't have x-offsets
                    bit 2 set => kern pairs don't have y-offsets
                    bit 4 set => there are more than 255 kern pairs
                    other bits are undefined
            R1-R5 = size of data (0 if not present in file)
                    data copied to buffer if pointer was non-zero
                    (ie. set pointers to 0 to find out size)
            R6,R7 undefined
 
Currently this call is not permitted on fonts which have a transformation
matrix applied to them.  It is recommended that the call is made on the
untransformed version of the font, and the results then transformed
appropriately.  Note that when transforming bounding boxes, the resulting
box is that which bounds all 4 transformed bounding box corners.  When
transforming x and y offsets (ie. character widths), the last 2 numbers in
the matrix (the offsets) should be ignored, since the new origin is also
moved by these amounts, and they therefore cancel out.

    The format of the data in the buffers is as follows:

    Except where otherwise stated:

        All units are 1/72000"
        All 2-byte and 4-byte numbers are little-endian, signed

    R1 -> BBox info:
        array[256] of groups of 4 words (x0,y0,x1,y1)

    R2 -> XWidth info:
        array[256] of words

    R3 -> YWidth info:
        array[256] of words

    R4 -> Miscellaneous data:

        8       font bounding box (signed x0,y0,x1,y1)
        2       default x-offset per char (if flags bit 1 set)
        2       default y-offset per char (if flags bit 2 set)
        2       italic h-offset per em (-1000 * TAN(italic angle))
        1       underline position (signed, in 1/256th of an em)
        1       underline thickness (unsigned, in 1/256th of an em)
        2       CapHeight
        2       XHeight
        2       Descender
        2       Ascender
        4       reserved field (must be 0)

    R5 -> Kern data:

                Kern pair hash table index is given by:
                        (first letter) EOR (second letter ROR 4)
                where the rotate happens in 8 bits.

        256 * 4 offset of first kern pair from table start
        4       offset of end of all kern pairs from table start
        4       flag word:
                        bit 0 set => no bboxes
                        bit 1 set => no x-offsets
                        bit 2 set => no y-offsets
                        bits 3..30 reserved (ignore these)
                        bit 31 set => 'short' kern pairs

                kern data follows

        The table indicates the point in the list of kern pairs following
        the table to start looking for a given kern pair.  The entries are
        consecutive, so each list finishes as the next one starts.

        The kern pairs consist of the code of the first letter of the kern
        pair (the second letter can be deduced from this and the hash
        index), followed by the x-offset (if flags bit 1 is clear) and the
        y-offset (if flags bit 2 is clear).

        If bit 31 of the flag word is set, then the letter code is combined
        with the first offset word as follows:

                bits 0..7 = character code
                bits 8..31 = x or y-offset

        If bit 31 is clear, then the letter code is contained in the first
        word, followed by the x-offset word (if flags bit 1 is clear) and
        the y-offset word (if flags bit 2 is clear).

        Note that if flag bits 1 and 2 are both set, then it is illegal for
        there to be any kern pairs.

        The offsets are in millipoints.

    Once the kern offsets are obtained, they can be inserted into a
    Font_Paint string as character 9 and 11 move sequences.


**** Not yet implemented ****

Font_Caret
----------

    Font_Caret
    In:     R0 = colour to EOR onto screen
            R1 = height (units depend on R2 bit 4)
            R2 = flags:
                bits 0..3 unused
                bit 4 set => coordinates are OS units, not 1/72000"
                bit 6 set => use R6 as indicated below
                bits 5,7..31 reserved (must be 0)
            R3,R4 = start coordinates (units depend on R2 bit 4)
            R6 -> transformation matrix (if R2 bit 6 set)
                R6!0..R6!12 = fixed point multipliers
                R6!16,R6!20 = translation (units depend on R2 bit 4)
                unit matrix = [1<<16,0,0,1<<16,0,0]

    If R2 bit 6 is set, then, the caret can be transformed.  This will be
    useful for applications to allow text round a circle to be edited.


**** Not yet implemented ****

Font_CharBBox
-------------

    Font_CharBBox
    In:     R0 = font handle
            R1 = character code, or -1 => return font bbox
            R2 = flags:
                    bits 0..3 ignored
                    bit 4 set => return OS unit bbox, else 1/72000"
                    bits 5..31 reserved (must be 0)
    Out:    R1-R4 = bbox of char or font (x0,y0,x1,y1)
                    x0,y0 inclusive, x1,y1 exclusive

    The only change is that setting the character code to -1 causes the
    values for the whole font to be returned.  The current SWI Font_ReadInfo
    should be deprecated, as it only allows the font bounding box to be read
    in OS units.


Font_SwitchOutputToBuffer
-------------------------

    Font_SwitchOutputToBuffer
    In:     R0 = flags:
               if R1 <= 0, then bits 0..31 are reserved (must be 0)
               if R1 > 0:
                 bit 0 set => update R1, but don't store anything
                 bit 1 set => apply 'hints' to the outlines
                 bit 2 set => include skeleton lines if required        ; NYI
                 bit 3 set => produce sprites for bitmapped characters  ; NYI
                 bit 4 set => give error if bitmapped characters occur
                              (this bit overrides bit 3)
                 bits 5..31 reserved (must be 0)
            R1 -> word-aligned buffer,
               or 8 initially to count the space required for a buffer
               or 0 to switch back to normal
               or -1 to leave state unaltered (ie. enquire about current status)
               if buffer, [R1,#0]=0, [R1,#4] = size remaining from R1+8 onwards
    Out:    R0 = previous flag settings
            R1 = previous buffer pointer (updated)

After this call, any calls to Font_Paint will be redirected into the buffer,
as a Draw file structure.  Each letter painted will be treated as a separate
filled object, with the colours specified in the paint command.

If R0 bit 0 is set, output is not actually sent to the buffer, but the
pointer is updated.  This allows the size of the required buffer to be
computed properly before allocating the space for it.  Note that if R0 bit 0
is set, R1 must be greater than 0 initially (a value of 8 is suitable, since
the buffer must allow space for the terminator and free space counter on the
end).  After filling the buffer, the data is between (original R1) and
(final R1 minus 1), ie. on exit [ R1 -> 0, <size remaining> ] and these two
words do not form part of the output data itself.

The rubout box(es) and any underlining are also sent to the buffer as a
series of filled outlines.  These will be in the correct order so as to be
behind any characters which overlap them.  The output will also take into
account matrix transformations, font and colour changes, explicit movements,
justification and kerning.

If R0 bit 1 is set, the character outlines have hints applied to them (at
the current size) - this means that they are not really suitable for scaling
later on.

If R0 bit 2 is set, the character objects consist of a group of two objects
- one is the filled outline, and the second is the stroked skeleton.

Any characters which are only available as bitmaps will either be errored
(if R0 bit 4 is set), ignored (if R0 bit 3 is clear), or represented as
bitmap objects in the output (either 1-bpp or 4-bpp, with a palette to match
the output colours).

In this way !Draw should be able to turn on buffering, then proceed to draw
an arbitrary text column in the appropriate position and size, ending up
with a series of Draw objects which represent the same thing.

The set of objects that the Font Manager produces could easily be converted
into a group by wrapping them suitably.


Font_FindFont
-------------

    Font_FindFont
    In:     R1 -> font name, with optional style(s) added
            R2 = x-point size * 16
            R3 = y-point size * 16
            R4 = x-dots per inch (-1 => use current)
            R5 = y-dots per inch (-1 => use current)
    Out:    R0 = font handle

    ************************ not yet implemented ****************************
    *   The new font manager treats the case of R4,R5 being -1 rather       *
    * differently, in that the 'current' resolution means the target bitmap *
    * resolution at Font_Paint time, not Font_FindFont time.                *
    *************************************************************************

    The font "name" string can also have various qualifiers added to it,
    which are a "\" followed by an identifying letter and the value
    associated with the qualifier.  If the string does not start with a "\",
    it is assumed that it is a font identifier.

    The strings following qualifiers must not contain "\", as this denotes
    the start of the next qualifier.

    The possible qualifiers are:

        \F<identifier>  font identifier (as for old Font_FindFont)
        \f<t> <name>    territory (country) number of font name, followed by
                        the font name in the alphabet of the territory
                        (terminated by end-of-string).
        \E<identifier>  encoding identifier
        \e<t> <name>    territory number of name, then encoding name
        \M<matrix>      transformation matrix to apply to this font

      <identifier> is a string of ascii characters, in the range 33 to 126
                   inclusive, which must represent a legal filename
                   (although it can contain "."s).

            <name> is the name of the font/encoding, expressed in the
                   language of the current territory, and using the alphabet
                   of the current territory.

               <t> is the territory number of the current territory, ie. the
                   language in which the font/encoding name is expressed.

          <matrix> is a set of 6 signed decimal integers which represent the
                   values of the 6 words that go into making a draw-type
                   matrix: the first four numbers are in fact 16-bit fixed
                   point, and the last two are offsets in 1/1000th of an em.

    The font identifier is the name of the font directory without the
    Font$Path prefix, and is invariant in any territory.  The font name is
    the name of the font (ie. the one displayed to the user) in the given
    territory.

    If Font_FindFont fails to find the font, an error message "Font '<name>'
    not found" is returned, where <name> is the font name if the current
    territory is the same as the one in the string, and is the font
    identifier otherwise.

    It is recommended that applications store the entire string returned
    from Font_DecodeMenu in the document, so that if the user loads the
    document without having the correct fonts available, the font name
    (rather than the identifier) can be returned (as long as s/he is in the
    same territory).

    The "\E" (encoding) field indicates the appropriate encoding for the
    font itself.  This field is only supplied by Font_DecodeMenu if the font
    is deemed to be a 'language' font, ie. one whose encoding depends on the
    territory.   Other fonts are thought of as "Symbol" fonts, which have a
    fixed encoding.

    Note that Font_DecodeMenu will return a font identifier of the following
    form:
                \F<fontid>\f<territory> <fontname>

    To apply a particular encoding to a font, remember to eliminate the
    existing encoding fields (if present) first.  Note that no field is
    allowed to contain a "\".

                \E<encid>\e<t> <encname>\F<fontid>\f<t> <fontname>

    Note that since <fontid>\f<t> <fontname> is also accepted by
    Font_FindFont, when prepending "\E<encid>\e<t> <encname>" on the front,
    you should also put "\F" on the front of the original string if it did
    not start with "\".

    In BASIC, this looks like:

        REM original$ is the original string passed to Font_FindFont
        REM encoding$ is the string returned from Font_DecodeMenu
        REM           typically "\E<enc_id>\e <territory> <enc_name>"
        REM result is the new string to be passed to Font_FindFont

        DEF FNapply_encoding_to_font(original$,encoding$)
        IF LEFT$(original$,1)<>"\" THEN original$ = "\F"+original$
        original$ = FNremove(original$,"\E")
        original$ = FNremove(original$,"\e")
        = encoding$ + original$

        REM this function removes the specified field from the string
        REM eliminates all characters from b$ to "\"

        DEF FNremove(a$,b$)
        LOCAL I%,J%
        I% = INSTR(a$,b$)
        IF I%=0 THEN =a$              :REM nothing to eliminate
        J% = INSTR(a$+"\","\",I%+1)   :REM searches from I%+1
        = LEFT$(a$,I%-1)+MID$(a$,J%)

    Note that it is not strictly necessary to remove the original encoding
    fields from the font identifier, since an earlier occurrence of a field
    overrides a later one, but if this is not done then the length of the
    total string will continue to grow every time an encoding is altered.


Font_ReadDefn
-------------

    Font_ReadDefn
    In:     R0  = font handle
            R1 -> buffer to fill in
            R2  = &4C4C5546 ('FULL')

    Out:  [R1]  = name of font (if R2 =&4C4C5546 then contains encoding and matrix aswell.
            R2  = x point size *16
            R3  = y point size *16
            R4  = horizontal resolution
            R5  = vertical resolution
            R6  = age of font
            R7  = usage of Font

This SWI has been extended to accept 'FULL' in R2, this is used to indicate
that the buffer should be returned containing the matrix and encoding
information specified on Font_FindFont.

This call is used by the printer drivers when trying to re-cache a font for
printer use.


*FontInstall
------------

    Syntax: *FontInstall [<prefix>]

    This call alters Font$Path so that the given prefix appears at the
    front.  It also eliminates any other occurrences of the prefix.

    It also rescans the given prefix, even if it was already known to the
    Font Manager.

    *FontInstall on its own causes all prefixes in Font$Path to be
    rescanned.  Service_FontsChanged is issued whenever a prefix is scanned.


*FontLibrary
------------

    Syntax: *FontLibrary <directory path>

    This call alters Font$Prefix to the given value, and ensures that
    "<Font$Prefix>." appears on the front of Font$Path.

    Note that the next call to *FontLibrary will cause the previous font
    library to be removed from the list of directories scanned.


*FontRemove
-----------

    Syntax: *FontRemove <prefix>

    This call removes any occurrences of the prefix from Font$Path.


Font_MakeBitmap
---------------

    Same as before, except that if the font has an encoding applied to it
    (ie. if there was a "/E" qualifier in the Font_FindFont string, or if
    this is a 'language' font, which varies in encoding according to the
    territory), then the bitmaps are held inside a subdirectory of the font
    directory.

    The subdirectory is <prefix>.<fontname>.<encoding>.

    Note that the Font Manager's Font_Paint stuff also looks inside this
    directory to find the bitmaps.


Font_ListFonts
--------------

    SWI Font_ListFonts (&40091)
    In:   R2 bits 0..15 = counter (0 on first call)
          R2 bits 16..31 = 0 => old-style: treat R2 as bits 16,18 set, R3 = 40
             bit 16 = 1 => return font identifier in [R1..] or return size
             bit 17 = 1 => return font name in [R4..] or return size
             bit 18 = 1 => return strings terminated with 13, else 0
             bit 19 = 1 => return font menu in [R1..] and [R4..] or return sizes
             bit 20 = 1 => put "System font" at head of menu
             bit 21 = 1 => tick font indicated by R6
             bit 22 = 1 => return list of encodings, else return list of fonts
             bits 23..31 reserved (must be 0)
             NB: R2 bit 19 = 0 => R2 bits 20,21 = 0
                 R2 bit 19 = 1 => R2 bits 16,17 = 0
          If R2 bits 16 or 19 set:
             R1 = 0 => return size of buffer
                <>0 => R1 -> buffer for font identifier or menu
             R3 = size of buffer in R1 (if R1 <> 0)
          If R2 bit 17 or 19 set:
             R4 = 0 => return size of buffer
                <>0 => R4 -> buffer for font name or menu indirected data
             R5 = size of buffer in R4 (if R4 <> 0)
          If R2 bit 21 set:
             R6 -> identifier of font to tick (also ticks submenu parent)
             R6=1 => tick "System font"
             R6=0 => don't tick anything

    Out:  R2 = -1 => no more font/encoding names/identifiers
                     font/encoding identifier/name is invalid in this case
                     font/encoding menu preserves R2 and does it all in one go
          R2 = counter/flags for next time
          If R2 bit 16 or 19 set on entry:
             If R1<>0 on entry, then [R1..] = font/encoding identifier or menu
             R3 = size of buffer required (if menu, 0 => no entries in menu)
          If R2 bit 17 or 19 set on entry:
             If R4<>0 on entry, then [R4..] = font/encoding name or menu data
             R5 = size of buffer required

          If R2 bit 19 set on entry then R2 is preserved on exit.  Note that
          in this case Font_ListFonts need only be called once to measure the
          length of buffer required, and once more to construct the actual
          menu.

          If R2 bit 19 set, bit 20 clear, then R3=0 on exit => null menu.

          If R2 bits 16..31 are clear on entry, then this is treated as though
          R2 bits 16 and 18 were set and R3=40 on entry.
          On exit R2 = R2+1 (bits 16..31 clear) or R2=-1.

    Errors:
          "Buffer overflow" (R3 or R5 were too small)
          "Bad parameters" (R2 flag bits invalid)
          If an error is returned, R2=-1 (listfonts terminated)

    This call returns the list of fonts known to the font manager, which is
    also cached.  The names are returned in alphabetical order, regardless
    of which prefix they are found under.

    By setting bit 22 of R2, it is possible to return a list of the
    encodings known to the font manager.  These are text files contained in
    <font prefix>.Encodings.<encoding id>, and are used to specify the
    encodings of the 'language' fonts (as opposed to the 'symbol' fonts,
    whose encoding is fixed).


Font_DecodeMenu
---------------

    In    R0 = flag word: bit 0 = 0 => this is a font menu
                          bit 0 = 1 => this is an encoding menu
                          bits 1..31 reserved (must be 0)
          R1 -> menu definition
          R2 -> menu selections (word array)
          R3 -> buffer to contain answer (0 => just return size)
          R4 = size of buffer (if R3<>0)
    Out   R2 -> rest of menu selections (if R3<>0 on entry)
          [R3..] = returned string (if R3<>0 on entry)
          R4 = size of buffer required to hold output string
             = 0 => no font selected

    Bit 0 of R0 determines whether this is the font menu or the encoding
    menu that is being decoded.

    In either case, the format of the returned string depends on whether the
    names of the fonts/encodings have been specified in a Messages<n> file
    inside the font directory - the name field is not present if the Font
    Manager has worked out the list of fonts/encodings by scanning the
    directory instead.

    Font id, no name:       \F<font id>
    Font id, with name:     \F<font id>\f<territory> <font name>

    Encoding, no name:      \E<encoding id>
    Encoding, with name:    \E<encoding id>\e <territory> <encoding name>

    Since Font_DecodeMenu works by comparing the string in the menu against
    the Font Manager's known font names, in the case of "System font" being
    selected from a menu that contained it, R4 would be returned as 0.  To
    distinguish this from the "no font selected" case, check for [R2]=0 on
    entry, since "System font" is always the first menu entry if present.


Font_ReadEncodingFilename
-------------------------

    In    R0 = font handle
          R1 -> buffer to receive prefix
          R2 = length of buffer
    Out   R0 -> encoding filename (in buffer)
          R1 -> terminating 0 of filename
          R2 = bytes remaining in buffer
    Error "Buffer overflow" if buffer too small

    This SWI allows the filename of the encoding file used for a given font
    handle to be read.  It is primarily useful for PDriverPS to gain access
    to the file of identifiers that defines an encoding, in order to send it
    to the printer output stream.

    The filename depends on whether the font has a 'public' or 'private'
    encoding (public encodings apply to 'language' fonts, as described in
    Font_ListFonts, while 'private' encodings are not used by the Font
    Manager, and simply describe the PostScript names for the characters in
    the font).

        public encoding : <font prefix>.Encodings.<encoding>
        private encoding: <font prefix>.<font name>.Encoding


*SaveFontCache
--------------

This command saves the current contents of the font cache, with certain
extra header information, to a file of type &FCF (FontCache).  The Run
alias for this filetype executes *LoadFontCache.


*LoadFontCache
--------------

This commands loads a font cache file previously saved using *SaveFontCache
back into the font cache.

An error will be returned if there are any font currently claimed, or if the
font cache format cannot be read by the current font manager (ie. it was
created by a version of the font manager that used an incompatible font
cache format.

The size of the font cache slot will be increased if necessary to
accommodate the new cache data, but will not be decreased if the new cache
data is smaller than the current cache slot size.

These commands are useful for setting up the font cache to a predefined
state, to save time later on.


Font Manager improvements for RISC OS 3.00
==========================================

Not to be implemented in RISC OS 2.50:

    *   There should be a version of Font_FindFont that allows 'styles' to
        be applied to a font.  For example, a font might be designated as
        being stroked rather than filled, or a font might have a shadow
        behind it.  More complex effects that require more than one
        font foreground colour would not be possible using this technique -
        instead, two strings would have to be painted, each in a different
        colour.

    *   To cater for applications that don't know about styles, it should be
        possible to create a font that is effectively another font with one
        or more styles applied.


Font_Paint
----------

    Note that R2 bit 5 has a dual function: if set, it causes the
    justification and rubout box coordinates to be taken from the block
    pointed to by R5 (if required), and it also causes the units if bit 4 is
    set to be 1/256th of an OS unit, rather than OS units.  Note that R5
    is simply a flag if R2 bit 5 is set and bits 0,1 are clear, ie. 0 =>
    coords are in OS units if R2 bit 4 set, 1 => coords are in 1/256th of an
    OS unit if R2 bit 4 is set.

    This goes for all coordinates specified in Font_Paint, including the
    rubout box and any matrices with non-0 offsets.


Font_ScanString
---------------

    If R2 bit 4 is set on entry, then coordinates are supplied in 1/256th of
    an OS unit, rather than 1/72000".

    If R2 bit 16 is set on entry, then coordinates are returned in 1/256th
    of an OS unit, rather than 1/72000".

