> Ideas.ListFonts

Improvements to Font_ListFonts
------------------------------

The new version of Font_ListFonts is improved as follows:

This allows internationalisation by having an extra level of indirection
between font identifiers and font names.  Applications should store
references to fonts inside documents using the font identifier, but always
present the font to the user (eg. in a menu) using the font name.

It also allows font paths to become much more effective, since new font
directories can be added to the list of known fonts without losing
references to other font directories.  This and the fact that the font
manager knows exactly where each font is held makes it possible for a user
to put fonts on several floppy discs and still use them effectively.

By making use of the new Service_FontsChanged call, Wimp applications will
be able to respond properly when new fonts are introduced to the system, ie.
by altering their font menu when next displayed.

The actual changes are:

    *   Font_ListFonts buffers the list of fonts found, so lookup is faster
        after the first one.

    *   Font_ListFonts sorts the font list alphabetically.

    *   What used to be known as font names (ie. the name of the font
        subdirectory) are now known as font identifiers - font names are
        obtained by looking in <fontprefix>.Messages<country>, using the
        font identifier as a key.  The user is then presented with the font
        name, while programs pass the font identifier to the font manager.

    *   <fontprefix>.Messages is used as a default if the country-specific
        file is not present, and the Font Manager only actually scans the
        font directory if no message file can be found.

    *   Font_ListFonts can also return a font menu, which may use submenus
        for font weights etc.

    *   Font_DecodeMenu will decode a menu click in such a font menu,
        returning the identifier of the font in question.

    *   There is a new command *FontInstall to install a set of fonts on the
        font path, without losing references to other fonts on the font
        path.

    *   There is a new command *FontLibrary which effectively sets
        Font$Prefix rather than Font$Path.  There is only one font library
        at a time, so when you introduce a new one, the previous one is
        lost.

    *   The *FontRemove command allows a font directory to be removed from
        the font path without affecting the others.  *FontRemove with no
        parameters removes all font directories!  Note that this command
        will also "uncache" any fonts contained in this font directory that
        are currently held inside the font manager's cache.  Normally the
        font manager will stick with the place where it first found a font
        for future accesses, even if the font path changes, so to be sure
        that a font has been removed from the cache, this command must be
        used.

    *   Service_FontsChanged is issued by the Font Manager on receipt of
        a *FontInstall or *FontPrefix command, or when Font_ListFonts is
        re-issued and the font path has changed.

    *   There is a new facility in the Wimp to allow Wimp tasks which
        are interested in specific service calls to have them delivered as a
        Message_ServiceCall message with the service call number as a
        subparameter.  This avoids the need for each of them to have a
        little module which picks up the service calls and passes them on. 

        Note that such service calls cannot be acknowledged.


New definition of Font_ListFonts
--------------------------------

 SWI Font_ListFonts (&40091)

 Old-style:
 In:   R1 -> buffer for font identifier (name treated as same)
       R2 = 0 on first call
          = identifier for this invocation on subsequent calls
       R3 -> font prefix (<=0 => use <Font$Path>)
 Out:  R2 = -1 => no more fonts, else
       R2 = counter
       [R1..] = font identifier/name

 New style:
 In:   R2 = on first call:
            bit 0 = 1
            bit 1 = 1 => return font identifier in [R1..]
            bit 2 = 1 => return font name in [R4..]
            bit 3 = 1 => return font menu in [R1..]
            bit 4 = 1 => put "System font" at head of menu
            bits 5..31 reserved (must be 0)
            NB: R2 bit 3 = 0 => R2 bit 4 = 0
                R2 bit 3 = 1 => R2 bits 1,2 = 0
       R2 = on subsequent calls:
            identifier for this invocation (pointer to block)
       If R2 bits 1 or 3 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 2 set:
          R4 = 0 => return size of buffer
             <>0 => R4 -> buffer for font name
          R5 = size of buffer in R4 (if R4 <> 0)

 Out:  R2 = -1 => no more font names / font menu finished
                  font identifier/name is invalid in this case
                  font menu is valid, however
       R2 = identifier for this invocation
       If R2 bit 1 set on entry:
          If R1<>0 on entry, then [R1..] = font identifier
          R3 = size of buffer required
       If R2 bit 2 set on entry:
          If R4<>0 on entry, then [R4..] = font name
          R5 = size of buffer required
       If R2 bit 3 set on entry:
          If R1<>0 on entry, then [R1..] = font menu
          R3 = size of buffer required
          R2 = -1 on exit (we've finished)

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

        SWI Font_DecodeMenu (&400xx)
        In:     R1 -> font menu (as returned from Font_ListFonts)
                R2 -> buffer to contain font identifier, or 0
                R3 = size of buffer (if R2<>0)
                R4 -> list of menu selections (as for Wimp_Poll menu select)
        Out:    If R2=0 on entry:
                        R3 = size of buffer required
                        R3 = 0 => R2 = 0 => no font selected
                                  R2 = 1 => system font was selected
                If R2->buffer on entry:
                        R1 -> submenu below where the user clicked
                        [R2..] = font identifer (0-terminated)
                        R3 = size of buffer required
                        R3 = 0 => R2 = 0 => no font selected
                                  R2 = 1 => system font was selected
                        R4 -> remainder of menu selections

The above structure allows for further submenus to be placed below the level
of the font subdirectories if required.  If the fonts are subdivided into
family and weight.style submenus, then clicking on the family name will
select the default weight and style, marked with a "*" in the font name
list.


Font Message file syntax
------------------------

As for message files (see documentation of MessageTrans for details), except
for:

The tokens are of the form "Font_" followed by the identifier of the font in
the font directory, and their values are the names of those fonts.  If the
value is null, then the font name is taken to be the same as the identifier.

Identifiers should always be in ASCII, to aid in international portability. 
However, the font names should use the alphabet of the relevant territory,
as determined by the country number on the end of the message file name.

Within a font name, the following characters are special:

        .       The first dot encountered causes the font to be split over
                two menu levels.  Subsequent dots do not cause further
                submenu splitting.

        *       An asterisk as the last character of a font name is not
                treated as part of the name, but marks this font as being
                the default for that family.  That is, if the font weights
                and styles are in a font family subdirectory, then clicking
                on the menu entry for the font family will select the
                default for the family.  For our current range of fonts,
                this is normally <familyname>.Medium, but there are other
                examples (eg. Selwyn).

Note that if a font name is given as "*" alone, then it is treated as being
the same as the identifier and is also made the default for that family.

