Already implemented:
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
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>
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
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
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
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.
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.
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
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
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
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 onwardsOut: 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
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
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 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
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.
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.
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.
Syntax: *FontRemove <prefix>
This call removes any occurrences of the prefix from Font$Path.
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.
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).
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.
In R0 = font handle
R1 -> buffer to receive prefix R2 = length of bufferOut R0 -> encoding filename (in buffer)
R1 -> terminating 0 of filename R2 = bytes remaining in bufferError "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
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.
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.
Not to be implemented in RISC OS 2.50:
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.
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".