Introduction and Overview
This document describes ZapRedraw 0.48 (2005).
This document is in Request-For-Comments release 7; it is not a definitive release.
ZapRedraw is a module capable of drawing a rectangle of text characters on screen. It originates from the text editor, Zap, but is often used in applications where a text display is required, being superior to that natively provided by RISC OS.
It provides the following features:
- Redraw may be by direct screen access (henceforth DSA) where the data is poked into the screen memory or by the standard VDU redraw.
- Full colour provided (with your own definable palette). Supports up to 32 bits per pixel in DSA mode and 24 bit colour in VDU mode.
- DSA redraw can handle any size of bitmap characters. Special optimised code is provided for 8 pixel wide characters in all modes. Also 8 × 8 and 8 × 16 character sizes are given priority. Up to 65536 characters can be defined.
- VDU redraw mode can handle any font, at any size and aspect ratio.
- Support is provided for cursors.
- Many extra SWIs perform all the work of creating cached bitmaps, updating them on a mode change etc. SWIs are also provided for creating palettes and other functions related to the redraw.
- An example program is provided which can be used as a template.
- New font handles concept allows easier handling of cached characters, mode changing, font sub-styles, and reduces DSA/VDU mode differences.
It also has the following limitations:
- All characters are equally spaced. Proportional spacing is not supported.
Outstanding issues
- FIXME: Replace uses of 'sysvar' with a better element for variables.
- FIXME: Is a bulleted list for the DSA/VDU distinction a good way of presenting that information.
- FIXME: The extensions for ZapRedraw_RedrawArea are essentially entrypoints with reason codes, so could be restructured to use the entry-definition format.
Terminology
- 'DSA' means direct screen access mode (characters poked into the screen).
- 'VDU' means VDU mode (operating system called to draw characters).
Technical Details
Pixel co-ordinates
Pixel co-ordinates are used wherever possible to prevent rounding errors when OS co-ordinates are not pixel aligned (these errors do mess things up).
Pixel co-ordinates are from the top left of the screen with the y axis descending. By a 'pixel' I mean a hardware pixel (this differs from an OS pixel in double-pixel emulation modes - this only crops up in the RISC OS 2 MODE 2 wimp!).
Zap redraw block
For several SWIs, R1 points to a redraw block of the type described below. The SWI documentation will mention which data in the block is actually used by that SWI (so should be filled in). Each offset in the block is named with a name beginning 'r_'. The BASIC program E-Library inside !ZapFonts contains a procedure to set these variables up should you be using the BASIC assembler. The contents of some offsets depends on which redraw mode is being used (VDU or DSA), this is indicated by 'VDU:' and 'DSA:'.
| Offset | Name | Contents | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | r_flags | Flags word determining the type of redraw:
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 4 | r_minx | Minimum X of redraw box (pixels from left - inclusive) | ||||||||||||||||||||||||||||||||||||||||||||||||
| 8 | r_miny | Minimum Y of redraw box (pixels from top - inclusive) | ||||||||||||||||||||||||||||||||||||||||||||||||
| 12 | r_maxx | Maximum X of redraw box (pixels from left - exclusive) | ||||||||||||||||||||||||||||||||||||||||||||||||
| 16 | r_maxy | Maximum Y of redraw box (pixels from top - exclusive) | ||||||||||||||||||||||||||||||||||||||||||||||||
| 20 | r_screen |
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 24 | r_bpl |
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 28 | r_bpp | Log base 2 of number of bits per pixel:
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 32 | r_charw | Width of a character in pixels | ||||||||||||||||||||||||||||||||||||||||||||||||
| 36 | r_charh | Height of a character in pixels | ||||||||||||||||||||||||||||||||||||||||||||||||
| 40 | r_caddr |
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 44 | r_cbpl |
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 48 | r_cbpc |
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 52 | r_linesp | Spacing in pixels:
| ||||||||||||||||||||||||||||||||||||||||||||||||
| 56 | r_data | Pointer to data (rectangle of characters) to print on the screen (format below). | ||||||||||||||||||||||||||||||||||||||||||||||||
| 60 | r_scrollx | Horizontal scroll offset in rectangle of characters given in r_data of top left of redraw rectangle. This is in pixels from the left hand side of the characters. Thus it equals n × (r_charw + character spacing) + m where n is the number of characters in and m is the number of pixels into the n'th character. If it is negative, the pixels to the left of the first character are cleared to the background colour (this is how the left margin is drawn). | ||||||||||||||||||||||||||||||||||||||||||||||||
| 64 | r_scrolly | Vertical scroll offset in rectangle of characters given in r_data of top left of redraw rectangle. This is in pixels from the top of the characters. Note that in single height mode each line is r_charh + line spacing pixels high and in double height mode each line is 2 × (r_charh + line spacing) pixels high. If it is negative, the rasters above the first line are cleared to the background colour (this is how the top margin is drawn). | ||||||||||||||||||||||||||||||||||||||||||||||||
| 68 | r_palette | Pointer to palette to be used for colour translation. (see below). | ||||||||||||||||||||||||||||||||||||||||||||||||
| 72 | r_for | Foreground colour to use at the start of a line as an offset in the palette table. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 76 | r_bac | Background colour to use at the start of a line as an offset in the palette table. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 80 | r_workarea | Pointer to an area of workspace for the SWI to use. The size of this workspace depends on the SWI. It must be word aligned. If r_caddr is a font handle then it may be 0, in which case ZapRedraw obtains workspace for itself for the duration of the call. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 84 | r_magx | Log base 2 of number of X OS co-ords per pixel. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 88 | r_magy | Log base 2 of number of Y OS co-ords per pixel. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 92 | r_xsize | Width of screen in pixels. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 96 | r_ysize | Height of screen in pixels. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 100 | r_mode | Current screen mode. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 104 | r_length | OPTIONAL (see r_flags bit 6). The offset of the last field in the block which you have supplied (eg. set it to r_tmargin if you supply the margins but not r_encoding). Fields beyond this offset are not read. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 108 | r_lmargin | OPTIONAL (see r_flags bit 6). Number of pixels to leave blank at the left. The margin is drawn in the colours in force for the first character of the line, and SWI ZapRedraw_GetRectangle subtracts it from r_scrollx. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 112 | r_tmargin | OPTIONAL (see r_flags bit 6). Number of pixels to leave blank at the top. The margin is drawn in the background colour r_bac, and SWI ZapRedraw_GetRectangle subtracts it from r_scrolly. | ||||||||||||||||||||||||||||||||||||||||||||||||
| 116 | r_encoding | OPTIONAL (see r_flags bit 6). Encoding handle, as returned by SWI ZapRedraw_Encoding, which SWI ZapRedraw_PrepareDataLine uses to translate the text it is given. 0 means that no translation is done. Only read if r_length is at least this offset. | ||||||||||||||||||||||||||||||||||||||||||||||||
Character cache format (r_caddr)
When using VDU redraw, this should point to the name of the font to use, or be zero for the system font.
When using direct screen access, the module will expect this block to contain the bitmaps for all the characters it is asked to print. Each character has size r_cbpc so it will expect to find the bitmap for ASCII character 'n' at address char_start = (!r_caddr) + n × r_cbpc. The character definition then consists of r_charh rows of r_cbpl each so r_cbpc = r_charh × r_cbpl. NB r_cbpl need not be a multiple of 4 so this address need not be word aligned.
The format of a row is the same as that for a sprite file except there is never any left hand side wastage. Ie, the first pixel is aligned to the start of the first word. Each character is r_charw pixels wide and thus requires N = r_charw << r_bpp bits of storage. There are special cases when N is small:
-
If 0 < N <= 8 then r_cbpl = 1 and the top 8-N bits of the byte are wasted.
-
If 8 < N <= 16 then r_cbpl = 2 and the top 16-N bits of the row are wasted.
-
If N > 16 then r_cbpl is aligned to the next multiple of 4 bytes greater or equal to N. (eg if 16 < N <= 32 then r_cbpl = 4, and if 32 < N <= 64 then r_cbpl = 8, etc).
The SWI SWI ZapRedraw_CachedCharSize will calculate the values of r_cbpl and r_cbpc for you from a given size of character.
Only TWO colours can be used in the definition of the character. Set all foreground pixels to 1's and background pixels to 0's. Eg, in a 16 colour mode pixels will be either 1111 or 0000. Unused bits at the end of the words (or bytes) are ignored and so can contain rubbish. The real foreground and background colours are masked in at run time.
Examples:
For 8 × 8 characters at 1 bit per pixel we have 1 byte per row. Eg "E" may be cached as:
| Row | Value | Binary, low bit first |
|---|---|---|
| 0 | &7E | 01111110 |
| 1 | &06 | 01100000 |
| 2 | &06 | 01100000 |
| 3 | &7E | 01111110 |
| 4 | &06 | 01100000 |
| 5 | &06 | 01100000 |
| 6 | &7E | 01111110 |
| 7 | &00 | 00000000 |
If it was in a 16 colour mode then there would be one word per row and the first rows would be:
| Row | Value | Binary, low bit first |
|---|---|---|
| 0 | &0FFFFFF0 | 00001111111111111111111111110000 |
| 1 | &00000FF0 | 00001111111100000000000000000000 |
In general you have:
Word 0 Word (N/4)-1
b0 .... b31 ................... b0 ..... b31
pix0 pix1 ......................pix(r_charw-1) 00000
In practice you first cache the font at one bit per pixel (eg use SWI ZapRedraw_ReadSystemChars) and then convert it to 'n' bits per pixel (for the current mode) by use of SWI ZapRedraw_ConvertBitmap.
Although I have said that the foreground colour must be all 1's and the background all 0's this is not strictly true. The data poked into the screen memory is (foreground mask AND bitmap) OR (background mask BIC bitmap). Thus if you have a foreground mask of &FFFFFFFF and a background mask of 0 then the bitmap will be poked directly into the screen so can have any format you like (though character merging and several other features may not work properly). This idea can be used in conjunction with SWI ZapRedraw_CacheFontChars to create a fast redraw mode for anti aliased fonts (as used in Zap).
Format of text to display (r_data)
This block contains the text to be printed on the screen. There should be sufficient text here to redraw the specified area of the screen (given its size, the scroll offset, character sizes etc). Terminating each line with the bytes 0,2 will ensure the redraw doesn't run out of text horizontally and terminating the line list with a zero will ensure the same vertically. The value in r_data points to a list of words. The n'th word in the list is the offset (from the block data start) of the n'th line of text to be printed in the window. This list can be terminated by a 0 offset in which case all further lines will be cleared to background colour (r_bac).
The data for each line consists of a string of bytes giving the characters to print. By character number 'n' is meant the n'th (n starting from 0) bitmap in your character cache in DSA mode, or the character with code 'n' in VDU redraw mode.
The byte 0 in the data for a line introduces a control code. Bytes 1-255 just print characters n = 1-255 as normal, within the current chunk of 256 characters. The chunk is chunk 0 (characters 0-255) at the start of each line, and is changed by the control codes 0,11 and 0,12, so that characters above 255 may be reached. When the chunk is C then the byte b prints character C + b (C is always a multiple of 256, so characters from 0 to &FFFFFF may be reached). For a character cache which you supply, there is only chunk 0 and the control code 0,3 may be used to reach the characters above 255. Characters which are not defined are drawn using the null glyph. The characters 0-31 and the character &7F are not normally letters; Zap treats these specially - see below.
The currently defined control sequences are:
| Value | Meaning |
|---|---|
| 0,0 | Prints character n = 0 |
| 0,1,f,b | Switch colour to foreground f and background b. (f/b are palette offsets - see r_for/r_bac). |
| 0,2 | End of line - the rest of the line is cleared to the current background colour. Every line must be terminated with this. |
| 0,3,l,h | Print character n = l + h × 256. This counts from the start of the character cache, not from the current chunk, and so can only be used when r_caddr is a character cache (in DSA mode) or in VDU mode; with a font handle, use the chunk control codes. |
| 0,4,f,b,x,y | Merges the characters x,y. If a pixel is clear in the bitmap for y then the pixel is drawn according to the bitmap for x and the current for/background colours. If the pixel is set for y then the colours f/b are used instead for the x pixel. Useful for laying a cursor on top of the character. This effect is simulated in VDU mode by using sprites and masks. This leaves the current foreground and background colours unaltered. NB x and y may contain control codes as well. Eg you could have x = 0,0 and y = 0,3,0,1. If you nest, 0,4 codes (ie either x or y contain 0,4) then only the most deeply nested one will have effect. |
| 0,5 | For internal use only. Restores the stacked values after a 0,4 call. Putting this in your input string will probably cause a crash. |
| 0,6,f | Change foreground colour to f. |
| 0,7,b | Change background colour to b. |
| 0,8,f,b,x,y | Cursor merge of characters x,y. This is similar to 0,4 but only works for characters &7F,&100-&105. For &7F, it masks in the block simply by changing the for/bac cols of the current character being printed. For &100+, the square or line is plotted over the top of the character in the background colour b. |
| 0,9,S | Substyle change to style S. |
| 0,10,f,b,S | Switch colour to foreground f and background b, and font to substyle S. |
| 0,11,c | Change to chunk c, so that following bytes b print character c × 256 + b. Only valid if r_caddr is a font handle (in DSA mode) or in VDU mode; otherwise it is ignored. The chunk returns to 0 at the end of the line. |
| 0,12,l,h | Change to chunk l + h × 256, so that following bytes b print character (l + h × 256) × 256 + b. Used for chunks above 255; otherwise as 0,11. |
Where a control code takes a sub-style S, it is a sub-style. In DSA mode with a font handle, ZapRedraw changes the sub-style for you; the change is also reported to the extension routine, if there is one. With a character cache you supply, sub-style changes can only be performed by an extension routine.
Note that sequences with codes 0, 3, 4 and 8 evaluate to one 'screen printable character', codes 1, 6, 7, 9, 10, 11 and 12 to none, and code 2 to as many as is required. Thus it is not a simple matter to calculate the start of the n'th actual printable character given a string containing control codes as above. The SWI SWI ZapRedraw_FindCharacter does this for you.
In DSA mode with a character cache you supply, character 'n' just looks up the cached character at address r_caddr + n × r_cbpc. Usually the bitmaps will correspond to the VDU list below so that character &20 will be the bitmap for a space etc. If r_caddr is a font handle then ZapRedraw looks up the character in the font, and uses the font's null glyph for characters which the font does not define. The cursor characters &100-&105 (used by the 0,8 control code) are always available in a font handle, and ZapRedraw generates the control characters 0-&1F and the null glyph if the font does not contain them.
In VDU mode character 'n' is the character code (a Unicode character if the Font Manager supports UTF-8, as it does for Font Manager 3.40 and later, and for the system font in modes where the characters can be defined) and is interpreted as below:
| Value | Meaning |
|---|---|
| &00 | Prints a '0' (ASCII &30) |
| &01-&1A | These print the letters A-Z (ie &40 is added) |
| &1B-&1F | Prints "[ \ ] ^ _" respectively (ie &40 is added) |
| &20-&7E | Usual ASCII characters printed. |
| &7F | This draws a filled in block (useful for a cursor) |
| &80-&FF | Usual ASCII characters printed. |
| &100 | This draws the top,bottom,left edges ie '['. |
| &101 | This draws the top,bottom edges. |
| &102 | This draws the top,bottom,right edges ie ']'. |
| &103 | This draws an empty square (useful for a cursor) |
| &104 | This draws the baseline ie '_' (useful for a cursor) |
| &105 | This draws the left edge giving a vertical bar. |
| &106+ | Undefined action (prints an @ for debugging purposes) (More codes may be added in future). |
The characters are drawn using SWI OS_WriteN / SWI OS_WriteC / SWI OS_Plot (or SWI Font_Paint if not using the system font).
Use SWI ZapRedraw_FindCharacter to jump over the control codes. Use SWI ZapRedraw_PrepareDataLine to automatically generate the r_data lines from normal text with foreground and background colour masks. Use SWI ZapRedraw_AddVduBitmaps to create the bitmaps for character codes 0-&1F,&7F and >= &100.
ZapRedraw supports sixteen sub-styles, in both VDU and DSA redraw modes, using the same convention in both. The sub-style number is a byte S in which bit 0 means strikethrough, bit 5 bold, bit 6 italic and bit 7 underlined. The sub-style at the start of the line is the bottom 8 bits of r_caddr when it is a font handle, and the control codes 0,9 and 0,10 change it during the line. See Sub-styles for how each mode renders them.
Sub-styles
A sub-style is a variation of the base font. The sub-style number S is a byte in which:
| Bit | Meaning |
|---|---|
| 0 | Strikethrough |
| 5 | Bold |
| 6 | Italic |
| 7 | Underlined |
The other bits are ignored when selecting a font (except that, in DSA mode, bit 4 has the same effect as bit 0). SWI ZapRedraw_PrepareDataLine uses bit 3 of the sub-style list to mean inverse video, and swaps the foreground and background colours while it is set.
In DSA mode each sub-style has its own bitmaps. ZapRedraw looks for a file in the font directory whose name is made up of the letters of the sub-style (see the description of font files); if the exact combination is not present, it falls back to the nearest combination which is, and finally the base font.
In VDU mode the font is a Font Manager font. If r_flags bit 3 is set, ZapRedraw looks for the variants of the font named by appending .Bold, .Oblique (or .Italic), and .Bold.Oblique (or .Bold.Italic) to the font name; where the font name already ends in a style, the final component is replaced. The bold and italic bits (5 and 6) select between the four fonts found. Strikethrough and underline are drawn as lines by ZapRedraw. Rendering of the variants has some technical difficulties, because they tend to have different bounding boxes from the default font at the same point size and aspect ratio; no attempt is made to compensate for this.
Format of palette data (r_palette)
All colours are specified as offsets in the palette table. Thus if you set r_for to 1 then the module will look up the word at offset 4*1 in the palette table when it comes to printing a character.
DSA Mode
The palette consists of a list of words giving the colour 'mask' to use for this colour. The mask is duplicated to fill the word out. For example, in a 16 colour mode, the mask &AAAAAAAA would stand for actual screen colour 10. The table:
&33333333
&66666666
&AAAAAAAA
&00000000
would cause 3 to be poked into the screen when in zap colour 0, 6 when in zap colour 1 etc. The masks will usually correspond to the wimp colours. The SWI SWI ZapRedraw_CreatePalette is provided to set them up.
The actual value poked into the screen is: (Foreground mask AND bitmap) OR (Background mask BIC bitmap) where the bitmap is as specified in r_caddr.
VDU Mode
The palette consists of a list of words giving the 24 bit colour required. The word is in the form of a standard palette entry. Ie, &BBGGRRxx where &BB is the amount of blue etc. These will usually be set up by reading the wimp palette. The SWI SWI ZapRedraw_CreatePalette will do this for you. ColourTrans calls will be used during the redraw to find the closest available GCOL colour.
Font handles
Font handles are a concept introduced in ZapRedraw 0.40. They make the process of loading and caching fonts much easier, and they also allow transparent access to font sub-styles in DSA mode in the same manner as in VDU mode. To initialise your font, pass the font name (eg 08x16.System) to SWI ZapRedraw_FindFont, and place the returned font handle in r_caddr. To find the size of the font, the call SWI ZapRedraw_ReadCharSize is provided. When you have finished with the font, you should call SWI ZapRedraw_LoseFont.
Font handles take the form &HHHHHHSS
HHHHHH is the font handle proper (a number from 1 to 32), and SS is the sub-style. Thus the lower 8 bits of r_caddr are the initial font sub-style to use at the start of the line. They have the same effect as r_for and r_bac. 0,9 and 0,10 control codes may be used to change sub-style during the line. Any value of r_caddr below &8000 is taken to be a font handle; larger values are the addresses of a character cache or font name which you provide.
When r_caddr is a font handle, ZapRedraw does the following for you:
- It loads the font on demand, converts the bitmaps to the number of bits per pixel in r_bpp, and converts them again when r_bpp changes, so you do not need to cache the characters yourself. In modes with 32 bits per pixel the 1 bit per pixel bitmaps are plotted directly.
- It sets r_charw, r_charh, r_cbpl and r_cbpc in the redraw block to match the font each time the block is used for DSA redraw. (In VDU mode the character size is that of the cell in which the font is plotted, and it is not stored in the block.)
- It provides its own workspace, if r_workarea is 0.
- It changes the sub-style for the control codes 0,9 and 0,10, and selects the chunk for the control codes 0,11 and 0,12. The characters above 255 which the font contains can therefore be drawn, and those it does not contain are drawn as the null glyph.
- If r_flags bit 5 is set, it chooses double height mode.
A font handle is counted: each call to SWI ZapRedraw_FindFont which finds an already loaded font adds a user to the handle, and each call to SWI ZapRedraw_LoseFont removes one. There are 32 handles available to all the applications which use ZapRedraw. The font data remains cached after it has no users, so that a font which is closed and then reopened is not reloaded, until the memory is needed for another font or until *ZapFontTidy is used.
A font handle allocated for VDU mode may be passed directly to SWI ZapRedraw_RedrawArea in DSA mode. This converts it to anti-aliased bitmaps on demand, exactly as Zap's aa-DSA mode does. The algorithm used is simple, but gives good results; it chooses an anti-aliased bitmap unless the colours of the text and its background are too similar for it to matter, when it uses a 1 bit per pixel bitmap instead, and it never uses anti-aliasing if r_flags bit 9 is set. Sub-styles are ignored.
The application should lose its handles when it has finished, before the module can be killed. ZapRedraw cannot be killed while any handle has users (see Service_ZapRedrawDying).
Fonts and the font path
The bitmap fonts which DSA redraw uses are found along the path variable ZapFontsSource$Path. This is a comma separated list of directories, which the application !ZapFonts sets to the directories Fonts and Encodings inside it. An application which uses ZapRedraw should use !ZapFonts rather than carry its own fonts, so that the fonts are shared; !ZapFonts also sets Zap$Redraw to the location of the ZapRedraw module, which an application's !Run file can use to load the module.
A font is a file within one of the directories (or within a subdirectory of them; the names use dots to separate the levels, and are not case sensitive), such as 08x16.System for the font in the file 08x16.System. A font directory is a directory whose name is used as the font name. The file named 0 within it is the base font, and the others are its sub-styles (see Font files). If the name of a font is the name of a directory and not of a file, then the base font in it is used, and its sub-styles. A link is a small text file which refers to another font; the names of fonts are the names of the links and the fonts. The names of fonts follow the convention <width>x<height>.<name>, such as 08x16.System, though this is not enforced by the module.
The names which ZapRedraw lists in menus (see SWI ZapRedraw_ListFonts) come from Messages files. In each directory on the path, ZapRedraw looks for the file Messagesn, where n is the number of the current territory (in decimal); if it is not there, the file Messages1 is used. This is a normal MessageTrans file in which each line
Font_identifier:name
describes one font, and each line
Encoding_identifier:name
describes one encoding. The identifier is the name by which the font or encoding is found on the path. As brackets cannot be used in the tokens, < and > are used in the identifier in their place and are converted to brackets when the identifier is read. The name is the text to show to the user in the territory; if it is empty, the identifier is used instead, and if it ends in * then that font is the default one for an ambiguous name (and the * is not part of the name). The lists are scanned when the module starts, and can be scanned again by *ZapFontInstall after the path has changed. They are sorted using the territory's collation.
Font files
Font files must be of type Data (&FFD) and link files of type Text (&FFF). There are two formats of font file: the original format, used for fonts of up to 256 glyphs, and the format which divides fonts of up to 4 billion glyphs into chunks.
The bitmaps of the glyphs are held at one bit per pixel in the format used for the character cache of a 2 colour mode: each row of a glyph is a whole number of bytes (1 byte if the glyph is up to 8 pixels wide, 2 if up to 16 pixels wide, and otherwise the next multiple of 4 bytes), the leftmost pixel is in the least significant bit, and the rows start at the top of the glyph. Pixels which are set are in the foreground colour.
The original format is:
| Offset | Name | Contents |
|---|---|---|
| 0 | Magic | The bytes "ZapFont" followed by 13 |
| 8 | Width | Width of each font character in pixels |
| 12 | Height | Height of each font character in pixels |
| 16 | First | First character code given (eg 0 or &20) |
| 20 | Last | Last character code given + 1 (eg &100) |
| 24 | Reserved | Reserved (0) |
| 28 | Reserved | Reserved (0) |
| 32 | Glyphs | Bitmaps, starting at the character given in the First field |
Any glyphs above 255 in the file are ignored. If the font does not start at character 0 then the glyphs for the control characters 0-&1F are made from the letters (0 is the digit 0, and 1-&1F are copies of &41-&5F). The cursor glyphs for characters &7F and &100-&105 are always made by ZapRedraw, as is the null glyph, which is used for the characters the font does not define.
The chunked format is:
| Offset | Name | Contents |
|---|---|---|
| 0 | Magic | The bytes "ZRUF" (ZapRedraw UCS Font) |
| 4 | Reserved | Reserved (0) |
| 8 | Width | Width of each glyph in pixels |
| 12 | Height | Height of each glyph in pixels |
| 16 | Directory size | Size of the chunk directory in bytes |
| 20 | Null glyph | Offset of the null glyph from the start of the file, or 0 if there is none |
| 24 | Reserved | Reserved (0) |
| 28 | Reserved | Reserved (0) |
The chunk directory follows immediately. The glyphs are divided into chunks of up to 256 glyphs, and the directory has an entry of four words for each chunk:
| Offset | Name | Contents |
|---|---|---|
| 0 | Chunk number | The number of the first glyph of the chunk: a chunk containing the glyph &2A3F has &2A00 here |
| 4 | Glyph count | The number of glyphs in this chunk |
| 8 | File offset | Offset in the file of the glyph data of this chunk |
| 12 | Reserved | Reserved - must be 0 |
The glyph data for a chunk consists of the bitmaps of the glyphs in order. If the chunk has fewer than 256 glyphs then the data starts with a translation table of 256 bytes: for each of the 256 characters of the chunk, the table gives the number of its glyph in the data plus 1, or 0 if it is not defined. The table is not present for a chunk with all 256 glyphs. Chunk 0 must be present and have all 256 glyphs, including the glyphs for the control characters; it should use the Acorn Extended Latin 1 encoding where possible. The null glyph is a bitmap of the same size as the others; if there is none then ZapRedraw uses a dotted box. ZapRedraw loads chunk 0 when it loads the font and the other chunks the first time that they are needed.
Where a font has sub-styles, it is a directory. The file 0 is the base font, and the files for the sub-styles have names made of the letters of the styles they are for, in the order U, S, I, B: B (bold), I (italic), S (strikethrough), U (underlined), or any combination such as IB or USIB. When ZapRedraw needs a sub-style it tries the file for exactly that combination of styles. If there is none, it takes away the styles in turn and tries again: first underline, then italic, then bold, then strikethrough; then pairs of styles; then it uses the single style files if they exist; and finally the base font. Fonts directly in the font directory are not given sub-styles.
A link file contains the bytes "ZFLK" followed by 10, and then the path of the font linked to, ending in a zero byte. A link cannot refer to another link. A link may be the file 0 of a font directory, which is the base font when the directory is chosen.
Encodings
An encoding translates the character codes of text into Unicode, so that text in any of the 8 bit character sets can be displayed using a font which holds Unicode characters. Encodings are found by name along ZapFontsSource$Path, and are handled with SWI ZapRedraw_Encoding. An encoding file is of type Data (&FFD) and has the format:
| Offset | Name | Contents |
|---|---|---|
| 0 | Magic | The bytes "ZENC" |
| 4 | Version | File format version - must be 2 |
| 8 | Reserved | Reserved (0) |
| 12 | Reserved | Reserved (0) |
| 16 | Table | 256 words, one for each character code from 0 to 255, giving the Unicode character for the code, or -1 if the code is not defined |
Two encodings are built in: UTF8 and UTF16, which are not tables and have no file. The supplied encodings are the ISO Latin character sets (Latin1 to Latin10), Arabic, Hebrew, Greek, Cyrillic, KOI8-R, Thai and Welsh.
Memory use, caching and mode changes
The font data and the converted bitmaps are held in a dynamic area named "Zap font cache" (the name is a message token, FontCache), which is created when the module starts, and which can be at most 2 megabytes. If the dynamic area cannot be created because the system does not support them (which is the case before RISC OS 3.5) then font handles cannot be used in DSA mode. The memory is returned when fonts with no users are tidied and the cache is compacted, either when a new font is needed or with *ZapFontTidy.
ZapRedraw watches for the mode change service call (Service_ModeChange, &46). On a mode change the sizes of the VDU fonts are read again for the new mode. The DSA fonts are converted again to the new number of bits per pixel the next time that they are used. Applications must read the screen details into the redraw block again with SWI ZapRedraw_ReadVduVars, and the number of bits per pixel for the cache with SWI ZapRedraw_ReadModeBPP, after a mode change.
VDU redraw mode
In VDU redraw mode ZapRedraw draws with the operating system rather than writing the screen memory. Each line is drawn in three passes: first the backgrounds, as rectangles of each background colour (using the fast rectangle plot of SWI ZapRedraw_PlotRectangle if r_flags bit 4 is set, and OS_Plot otherwise); then the characters, with Font_Paint for a font and OS_WriteC for the system font; and then any merged characters and cursors. The colours of the palette entries are translated to the nearest available colours with ColourTrans.
The system font is used when the font name is 0. The characters 0-&1F, &7F and &100-&105 are drawn as described in Format of text to display by ZapRedraw, since the operating system's meaning of these characters is not the one wanted. Characters above 255 are drawn with UTF-8 text if the Font Manager supports it (Font Manager 3.40 or later); the system font characters are defined temporarily with VDU 23 in the Unicode range of the operating system, via the international service call (&43), and restored afterwards.
ViewFinder
If the ViewFinder module (version 1.29 or later) is present and is in use (the system variable ViewFinder$Enable being set to a non-zero number, or ViewFinder 1.41 or later which is assumed to be active), ZapRedraw has ViewFinder draw the text and the rectangles, since ViewFinder modes cannot be written directly. This is automatic and needs nothing from the application, except that SWI ZapRedraw_RedrawRaster cannot be used, and SWI ZapRedraw_ReadModeBPP returns 0 so that 1 bit per pixel caches are used.
Using ZapRedraw
An application which draws text with ZapRedraw does this:
- When starting, check that the module is present (with RMEnsure) and issue the first call to SWI ZapRedraw_Version if the version matters. Find the font with SWI ZapRedraw_FindFont and keep the handle. Fill in the redraw block: r_flags, r_caddr (the handle), r_palette (made with SWI ZapRedraw_CreatePalette), r_for, r_bac and r_linesp, and read the character size with SWI ZapRedraw_ReadCharSize to size the windows.
- Call SWI ZapRedraw_ReadVduVars to fill in the screen details, and again after each mode change.
- Build the r_data for the visible lines, using SWI ZapRedraw_PrepareDataLine and SWI ZapRedraw_AddCursorSmart.
- On a redraw event, set r_scrollx and r_scrolly with SWI ZapRedraw_GetRectangle and call SWI ZapRedraw_RedrawArea for each rectangle, or use SWI ZapRedraw_RedrawWindow or SWI ZapRedraw_UpdateWindow to do the loop.
- When finishing, call SWI ZapRedraw_LoseFont for each font found.
- Be ready for Service_ZapRedrawStarted, after which any addresses obtained from SWI ZapRedraw_Version are no longer valid.
System Variables
A comma separated list of directories, which ZapRedraw searches for fonts, font links, encodings and their Messages files. It is read each time that a font or encoding is looked for, and when the font lists are scanned. !ZapFonts sets it to its Fonts and Encodings directories. *ZapFontInstall adds a directory to it.
ZapRedraw opens the file ZapFontsMessages:Messages for its error messages, command help and the titles of menus. !ZapFonts sets the variable to the directory for the current country, and then to the UK one.
Set by !ZapFonts to the ZapRedraw module it contains, so that an application can load it with RMLoad <Zap$Redraw>. The module itself does not read it.
Read when the module starts, if ViewFinder 1.29 or later is present. If it is set to a non-zero number, ZapRedraw uses ViewFinder to draw. ViewFinder 1.41 or later is assumed to be in use if the variable is not set to a number below 2 (a value of 0 turns it off).
Service Calls
This informs any potential application which has pointers into the module (via SWI ZapRedraw_Version that ZapRedraw has either started or been reinitialised, and hence the pointers may have moved. It should not be claimed. It is issued from a callback shortly after the module has initialised, and not during initialisation.
This informs applications that ZapRedraw is about to quit. It will not be issued if quitting is impossible (eg. if it has open font handles or encodings in use, in which case the same error is returned.) If it is claimed, ZapRedraw will refuse to die with the error "ZapRedraw is in use" (error number &48484) - this is to prevent version numbers becoming invalid.
ZapRedraw also listens for the mode change service call (&46), and uses the international service call (&43) to define Unicode characters of the system font in VDU mode.
SWI Calls
| R1 | = | Pointer to redraw block (as described above). All
defined offsets in the redraw block are used.
In VDU mode r_workarea must be at least 64 bytes + the amount needed for a sprite of one character - see SWI ZapRedraw_SpriteSize. (If r_caddr is a font handle then r_workarea may be 0.) If r_caddr is a font name (not a font handle) then the first word of the workarea should contain:
In DSA mode r_workarea must be at least 64 + r_cbpl bytes (and a whole number of words long). If r_caddr is a font handle then r_workarea may be 0. If b2 of the r_flags word is set then you provide an extension routine with the address and private word in R2 and R3 respectively. |
| R2 | = | Pointer to an extension routine (in DSA mode - see above.) |
| R3 | = | Private word value to pass to the extension routine (in DSA mode - see above.) |
| R0 | corrupted | |
| N flag | corrupted | |
| C flag | corrupted | |
| Z flag | corrupted | |
This SWI is used to redraw an area of characters on the screen. It provides a means of extending the redraw routine so that you can trap unknown control codes and add extra functionality to the ones that exist. For example, you may wish to change font on a colour change. Zap's fast font redraw mode does this.
| R0 | = | The colour number to be poked into the screen. (0 - >num_of_cols -1) |
| R1 | = | r_bpp (0-5) |
| R0 | = | Mask to put in palette table (with colour duplicated to fill the word). |
| N flag | corrupted | |
| C flag | corrupted | |
| Z flag | corrupted | |
This SWI takes a colour bitmap and duplicates it to fill a word, creating a mask as needed for r_palette in DSA mode. Eg if R0 = 7 and R1 = 2 on entry then R0 = &77777777 on exit.
| R1 | = | Pointer to redraw block:
Offsets used are: r_flags, r_minx, r_maxx, r_bpp, r_charw, r_charh, r_cbpl, r_cbpc, r_palette, r_workarea. | ||||||||||||
| R3 | = | Pointer to text to use for this line starting at the first visible character. | ||||||||||||
| R4 | = | Offset of the raster within each character bitmap, ie r_cbpl × row where row (0 ... r_charh - 1) is the row of the characters to be drawn, or -1 if you want the line to be cleared to the background colour (eg interline gap). The offset is relative to the character cache (or font) given by r_caddr. | ||||||||||||
| R5 | = | Screen address of the start of the raster line. | ||||||||||||
| R6 | = |
| ||||||||||||
| R7 | = | Initial chunk number, as set by the chunk control codes (a multiple of &100; 0 for the first 256 characters). | ||||||||||||
| R0 | corrupted | |
| N flag | corrupted | |
| C flag | corrupted | |
| Z flag | corrupted | |
Redraws a single raster line. Only applies to non-vdu redraw. This is a low level call used by SWI ZapRedraw_RedrawArea and not of much use otherwise. It is not available when ViewFinder is rendering text, and returns the error "ZapRedraw_RedrawRaster is no longer implemented" in that case.
The initial words of r_workarea are set up as follows:
| Offset | Contents |
|---|---|
| 0 | Pixel scroll offset within the first visible char (0 -> charw - 1) |
| 4 | Number of pixels to do from the first character (0 -> charw - 1) |
| 8 | Number of whole characters to do after the first char |
| 12 | Number of pixels to do in the last visible char (0 -> charw - 1) |
| 16 | Number of whole characters scrolled off the left of the redraw rectangle. Set up by SWI ZapRedraw_RedrawArea; not used by this SWI |
| 20 | Pointer to extension routine if redraw flags bit 2 set |
| 24 | Private word for the extension routine if redraw flags bit 2 set |
| R1 | = | Pointer to redraw block. Offsets looked at are:
| ||||||||||||||
| R2 | = | First character to be converted (eg 0) | ||||||||||||||
| R3 | = | Last character to be converted (inclusive) (eg 255) | ||||||||||||||
| R4 | = | Pointer to source bitmap of the format described under r_caddr but with 1 bit per pixel (ie 2 colour mode format). This is the address of the bitmap for character 0, even when R2 is not 0. |
| R0 | corrupted | |
| N flag | corrupted | |
| C flag | corrupted | |
| Z flag | corrupted | |
This SWI takes a character bitmap of the form of 1 bit per pixel, (the bit set for foreground/clear for background) and converts it into a bitmap for use by the SWI ZapRedraw_RedrawArea SWI, by changing each '1' to n '1's and each '0' to n '0's where 'n' is the number of bits per pixel given. It uses the SWI SWI ZapRedraw_ConvBitmapChar to do this. If r_bpp is 0 the bitmap is simply copied.
In addition to corrupting R0 and flags, the r_caddr block is written to.
| R0 | = | Foreground colour to use for control characters (0 - &1F, and &7F) or set to -1 if you do not wish ctrl chars to be specially treated. |
| R1 | = | Pointer to redraw block giving start foreground background colours in r_for, r_bac, and r_flags (and r_caddr, for the initial sub-style, and r_length and r_encoding, if present) - nothing else used. |
| R2 | = | Pointer to text input string (length in R5) |
| R3 | = | Pointer to foreground list, or 0 to use r_for throughout (length in R5) |
| R4 | = | Pointer to background list, or 0 to use r_bac throughout (length in R5) |
| R5 | = | Length of input text in bytes. The foreground, background and sub-style lists must be this long, unless r_flags bit 12 is set, when they have one byte for each character. |
| R6 | = | Destination buffer (see below for the size required). |
| R7 | = | Sub-style list (not supplied if b3 of r_flags is zero) |
| R0 | = | Highest character code used (&20 or above). You may not want to cache all font characters as usually those >= 128 are not needed. This tells you the range you MUST cache. If the text contains characters from other chunks, this may be above &FF. |
| N flag | corrupted | |
| C flag | corrupted | |
| Z flag | corrupted | |
| R5 | = | Length of output string (including 0, 2 terminator) Only a subset of the redraw codes available are used (0,0; 0,1; 0,2; 0,6; 0,7; 0,10; 0,11 and 0,12). |
This SWI is to help prepare the r_data field of the redraw block. It takes as input the pointer to a line of text characters, which are treated as ordinary characters (0 is not a control code). It also takes as input a pointer to a background list and a foreground list, giving the background and foreground colours of each character separately. The output is a line of the format required by r_data with control codes changing the colours, sub-style and chunk, and specifying the line end. Control codes in the input string can have their colour set automatically by setting R0 to the colour.
The width of the input characters is 8 bits unless r_flags bit 10 (16 bits) or bit 11 (32 bits) is set. The characters are then translated according to the encoding in r_encoding, if there is one:
- If the encoding is a table (as found by SWI ZapRedraw_Encoding for an encoding such as Latin1) then 8 bit input characters are looked up in the table to give Unicode characters. Table entries of -1 give the character &FFFF.
- If the encoding is UTF-8 then the text is decoded as UTF-8. Invalid sequences (including overlong forms, surrogates and the characters &FFFE and &FFFF) give the character &FFFD.
- UTF-16 is not yet properly supported; the text is treated as 16 bit characters.
Whenever the character is not within the current chunk, a 0,11 or 0,12 control code is generated to change chunk. The output is that of a single line, so the chunk is 0 at the end. Space characters at the end of the output are removed if the line is in chunk 0, as the end of line code clears the remainder of the line to the background colour. The character 0 is output as 0,0.
Bit 3 of any sub-style data supplied is used to control the 'Inverse video' effect. While this bit is set, foreground and background colours are swapped over in all operations. The initial sub-style is the bottom byte of r_caddr if it is a font handle, and otherwise 0.
The buffer must be large enough for the output. For text of 8 bit characters with no encoding, 6 × R5 + 16 bytes are sufficient (a colour change, a 0 changed to 0,0, and the terminator). Where chunk changes and sub-styles can be generated, each character may need up to 11 bytes (0,10,f,b,S then 0,12,l,h then the character as 0,0), so allow 11 bytes for every character plus 16.
Input:
Text input (characters): "HELLO WORLD "
Foreground (bytes list): 11111122222222222222
Background (bytes list): 00000000000000000000
Start background 0
Start foreground 1
Input length 20
Output:
"HELLO ",0,1,2,0,"WORLD",0,2 (highest letter used = "W").
| R0 | = | Destination string | |||||||||||||||
| R1 | = | Pointer to redraw block giving initial r_for and r_bac. | |||||||||||||||
| R2 | = | Offset in source string of first character to be in the cursor. | |||||||||||||||
| R3 | = | Cursor length (length in characters of string pointed to by R4) | |||||||||||||||
| R4 | = | Pointer to string of cursor characters (usually &7Fs) | |||||||||||||||
| R5 | = | Source string (0,2 terminated) | |||||||||||||||
| R6 | = | Swap colour / -1 if none. If the character having the cursor placed over it has this foreground colour then the cursor bac/foreground cols are swapped over (eg in a selected region). | |||||||||||||||
| R7 | = | Cursor character, control code and colours:
Room should be reserved for the string to grow by 8 × R3 characters. (eg 0, 4, f, b, old , 0, 3, l, h) If the indicated offset (R2) is off the end of the string then it will be lengthened with spaces (&20) so you should ensure R2 + 9 × R3 characters extra are reserved. | |||||||||||||||
| R0 | = | End of new destination string (after 0,2 terminator) |
This SWI takes a line of the same format used in r_data, eg the output from the above SWI, and adds in the codes to place 'cursors' over some of the text by using the code 0,4 (merge characters) or the code 0,8 (merge cursors). Here, a cursor means a string of characters to be overlayed. When using the 0,8 code, you may use just the low byte of the cursor character, ie. you don't need to use 0,3,l,h sequences. This is partially why 0,8 calls only work with cursors.
Note that there is now a more sophisticated version of this call, SWI ZapRedraw_AddCursorSmart, which can cope with selections containing characters that have a different foreground colour (but the same background colour) to the rest of the selection.
| R0 | = | n (number of characters to skip, or -1 to move to the end of the string - find its len) |
| R1 | = | Pointer to the input string (terminated by 0,2) |
| R2 | = | Current foreground colour |
| R3 | = | Current background colour |
| R4 | = | Current font substyle |
| R5 | = | Current chunk (&100 × the chunk number set by a 0,11 or 0,12 control code; 0 at the start of a line) |
| R0 | = | If the n'th character is in the string then this points to the end of the n'th character (start in R1).
If the n'th 'character' is the terminator (0,2) then this equals R1 (start of the terminator). If it reached the string terminator before the n'th character then this is R1-number of chars not skipped. |
| R1 | = | Start of the next printable character after skipping n. (or string terminator if reached that first). |
| R2 | = | Updated by any colour change control codes. |
| R3 | = | Updated by any colour change control codes. Flags are corrupted. |
| R4 | = | Updated by any font change control codes. |
| R5 | = | Updated by any chunk change control codes. |
This SWI takes as input a line of the format required by r_data (ie containing ctrl sequences starting with 0) and a number 'n' and returns the start of the (n+1)'th printable character within this line (ie it skips over n printable characters), ignoring colour change control codes etc. Thus on exit it points to a byte 1 - 255 or one of the control sequences 0, 0 or 0, 2 or 0, 3, l, h or 0, 4, f, b, c1, c2 or 0, 8, f, b, c1, c2 each of which define one printable character. If the offset n is off the end of the line then it will point to the 0, 2 terminator. It also keeps track of the colour, sub-style and chunk changes that take place. NB If n = 0 then it may still be useful - as it will jump over any colour changes before the first character. If R0 > R1 on exit then the character was found, otherwise there were R1 - R0 characters left to skip.
Input: "hello ",0,1,2,3,"goodbye",0,2
Output:
- If n = 0 then it will point to the 'h'
- If n = 6 then it will point to the 'g'
- If n = 100 then it will point to the 0 of 0,2.
| R1 | = | Source address (need not be word aligned) |
| R2 | = | Destination address (need not be word aligned) |
| R3 | = | Number of bytes to move (>= 0) |
| R0 - R3 | = | Corrupted |
| N flag | corrupted | |
| C flag | corrupted | |
| Z flag | corrupted | |
This is a fast byte shifting SWI. It is highly optimised; bytes are shifted starting at the top or bottom depending on whether the destination address is higher or lower than the start (respectively). Thus the data is always preserved.
| R0 | = | r_bpp value |
| R2 | = | r_charw value |
| R3 | = | r_charh value |
| R0 | = | Corrupted (+ flags) |
| R2 | = | Number of bytes per cache line (r_cbpl) |
| R3 | = | Number of bytes per cached character (r_cbpc) |
This SWI works out the values of r_cbpl, r_cbpc from r_charw, r_charh, r_bpp in the manner defined under the help text on r_caddr. ie. r_cbpl is either 1, 2, or a multiple of 4 and r_cbpc = r_charh * r_cbpl.
| R1 | = | Pointer to redraw block (only r_charh is used to find the height of the character in pixels). |
| R2 | = | Bytes per cache line for the source character (1,2, × 4) |
| R3 | = | Bytes per cache line for the dest character (1,2, × 4) |
| R4 | = | Pointer to source character bitmap |
| R5 | = | Address to place destination character bitmap |
| R6 | = | Bit mask to insert in place of 1's (only bottom 2^R7 bits) |
| R7 | = | Log_2 of number of bits per pixel (1-5) |
| R0 | = | Corrupted (+ flags) |
| R4 - R5 | = | Updated to the start of the 'next' characters. |
This SWI is for the use of the SWI ZapRedraw_ConvertBitmap SWI and performs the bitmap conversion for one character. It takes a bit map of the one bit per pixel format and expands it to have n = 2^R7 bits per pixel by replacing each '0' with n '0's and each '1' with the mask in R6 (usually n '1's). Thus for standard conversion you should set R6 to be 2^n-1 (= 2^(2^R7) - 1). (NB if R7 ( = r_bpp) is zero then all you have to do is copy the bitmap. R7 = 0 is not supported by this call.
| R0 | = | Reason code:
| ||||||||||||
| R1 | = | Pointer to redraw block. The following are used:
| ||||||||||||
| R2 | = | Pointer to source palette | ||||||||||||
| R3 | = | Pointer to space reserved for destination palette (needs 4 × R4 bytes reserved) (source may equal destination) | ||||||||||||
| R4 | = | Number of palette entries (eg 16) | ||||||||||||
| R0 (and flags) | = | Corrupted |
This SWI is used to create the r_palette data block. If R0=1 on entry then it takes a palette consisting of a list of wimp colour numbers (one per word) and converts it to entries of the form &BBGGRRxx, a 24 bit palette entry by using the call SWI Wimp_ReadPalette and duplicating the nibbles. If R0 = 2 on entry then it takes a list of entries of the form &BBGGRRxx and converts them to colour masks required for DSA redraw (see r_palette) using ColourTrans calls and SWI ZapRedraw_GetPaletteEntry. If R0 = 3 on entry then it does both, converting wimp colour numbers to DSA redraw masks.
| R0 | = | Character |
| R1 | = | String address |
| R0 (and flags) | = | Corrupted |
| R1 | = | Updated to the point after the character insertion. |
This inserts a single character into a string of r_data format. If R0 = 0 then it inserts 0, 0 and if R0 >= &100 then it inserts 0, 3, x, y where R0 = &yyxx. Otherwise it just inserts the byte as normal.
| R0 | = | Pointer to buffer for bitmap data (size = 8 × 256 = &800 = 2K) |
| R1 | = | Pointer to redraw block. r_workarea must be a 16-byte work area. |
| R0 (and flags) | = | Corrupted |
This reads the standard system characters bitmaps via SWI OS_Word calls. It reads them in 1 bit per pixel (8 bytes per character) form suitable for SWI ZapRedraw_ConvertBitmap to convert it to a form usable for SWI ZapRedraw_RedrawArea. To do this, it just bit-reverses the information read by SWI OS_Word 10. It only reads characters &20 - &FF, leaving 0 - &1F untouched. The bit reversing is done efficiently so this call is fairly fast.
| R1 | = | Source buffer |
| R2 | = | Destination buffer (can equal source) |
| R3 | = | Number of bytes (must be a multiple of 4) |
| R0 (and flags) | = | Corrupted |
This SWI takes a list of bytes and reverses the bits of each byte. This is useful for reversing the bitmaps (flipping about the y axis) of 8 × 8 pixel characters at one bit per pixel (ie r_cbpl = 1; r_cbpc = 8).
| R1 | = | Pointer to redraw block to update (r_workarea should point to a 64 byte scratch area.) |
| R0 (and flags) | = | Corrupted. |
This SWI is used to set up the Zap redraw block initially. It puts the value 0 in r_screen so the actual screen address is used when SWI ZapRedraw_RedrawArea is called (this can change quite often) and fills in r_bpl, r_bpp, r_magx, r_magy, r_xsize, r_ysize by using the call SWI OS_ReadVduVariables. It also fills in r_mode by using SWI OS_Byte 135. This call should be made after any mode change. Compensation is made for double pixel modes by decreasing r_magx. A pixel in Zap means a hardware pixel rather than an emulated double pixel.
| R0 | = | Block as returned by SWI Wimp_RedrawWindow / SWI Wimp_GetRectangle ie: window handle, minx, miny, maxx, maxy, scrollx, scrolly etc. |
| R1 | = | Zap redraw block with r_magx, r_magy, r_xsize, r_ysize and r_flags filled in (and the optional fields r_length, r_lmargin and r_tmargin, if r_flags bit 6 is set). |
| R0 (and flags) | = | Corrupted. |
| R1 | = | r_minx, r_miny, r_maxx, r_maxy, r_scrollx, r_scrolly updated. |
This SWI should be used after calls to SWI Wimp_GetRectangle. It takes the redraw rectangle block as returned by SWI Wimp_RedrawWindow or SWI Wimp_GetRectangle and uses it to fill in the ZapRedraw block. The scroll offsets of the update rectangle are in pixels. The y scroll offset is the amount 'down' from the work area origin (inclusive), so negating will get the 'upward' scroll offset in pixels (exclusive), and the shifting by r_magy will give the normal OS work area scroll offset (which is exclusive).
If the redraw block has margins (r_flags bit 6 set and r_length large enough), the left and top margins are subtracted from the scroll offsets, so that they are negative in the margin. If the right-to-left flag (r_flags bit 7) is set, r_scrollx is the distance in pixels from the right hand edge of the work area (as found with SWI Wimp_GetWindowInfo) to the right hand edge of the rectangle, rather than from the left.
| R1 | = | Pointer to redraw block (uses r_charw and r_charh to find the char size) r_workarea must have 64 bytes + room for a character sprite (see SWI ZapRedraw_SpriteSize) reserved. |
| R2 | = | First extra bitmap to create (eg 0) |
| R3 | = | Last extra bitmap to create (inclusive eg &105) |
| R4 | = | Pointer to bitmaps in 1 bit per pixel form. (space must be reserved for the characters to be created). |
| R0 (and flags) | = | Corrupted. |
If you look at the VDU codes, you will see that characters 0 - &1F, &7F, &100+ are treated specially during a VDU redraw, drawing blocks and squares. The purpose of this SWI is to create bitmaps for these extra characters from a standard bitmap of the normal characters, so you can also use these in a DSA redraw. You specify an interval of characters, and in that interval, it creates bitmaps for the following (characters &20-&7E and &80-&FF are left unaltered):
| Value | Meaning |
|---|---|
| &00 | Creates bitmap for '0' by copying bitmap &30 |
| &01-&1F | Creates bitmaps for 'A', 'B', ... by copying bitmaps &41-&5F |
| &7F | Creates a filled in square. |
| &100 | Top bottom and left edge filled [ |
| &101 | Top and bottom edges |
| &102 | Top bottom and right edge filled ] |
| &103 | Empty square |
| &104 | Underscore _ |
| &105 | Left edge (giving a bar) |
| &106+ | Undefined (currently copies the @ character). |
This means that the bitmaps will then be consistent with the VDU characters of these numbers. These bitmaps are also useful as cursors.
| R0 | = | Reason code - other registers depend upon reason code.
|
| R0 (and flags) | = | Corrupted |
This SWI takes an anti-aliased font and caches a range of characters as bitmaps (see r_caddr). The caching can be done in any colours or screen resolution. Of course only those with foreground colour all bits set and background colour all bits clear can be used directly by SWI ZapRedraw_RedrawArea. However, by giving a foreground colour mask of -1 and a background mask of 0 any bitmap can be drawn (see r_caddr etc). An hourglass is given with the % as the current character/256 if it takes a long time.
| R1 | = | redraw block with the following set up:
| ||||||||||||||
| R2 | = | Pointer to font name | ||||||||||||||
| R3 | = | Font plotting details:
| ||||||||||||||
| R4 | = | X OS offset (from bottom left) to plot character in the box | ||||||||||||||
| R5 | = | Y OS offset (from bottom left) to plot character in the box | ||||||||||||||
| R6 | = | First character to cache (0 caches as &30 and 1 - &1F have &40 added &7F is ignored). | ||||||||||||||
| R7 | = | Last character to cache (inclusive) | ||||||||||||||
| R1 | = | Pointer to redraw block with the following set up:
| |||||||||
| R2 | = | Pointer to font name | |||||||||
| R3 | = | Font plotting details:
| |||||||||
| R4 | = | X os offset (from bottom left) to plot character in the box | |||||||||
| R5 | = | Y os offset (from bottom left) to plot character in the box | |||||||||
| R6 | = | First character to cache (0 caches as &30 and 1-&1F have &40 added &7F is ignored). | |||||||||
| R7 | = | Last character to cache (inclusive) | |||||||||
Font size is scaled up by 2^(1 - r_magx) horizontally and 2^(2 - r_magy) vertically so the characters are the same pixel size as those cached with R0 = 1.
| R0 | = | Reason code:
| |||||||||
| R1 | = | Pointer to redraw block with r_bpp, r_charw, r_charh setup. When Bit 7 is set r_workarea must be at least the size returned by the first pass. | |||||||||
| R0 | = |
|
Several SWIs (eg SWI ZapRedraw_RedrawArea - VDU mode, SWI ZapRedraw_CacheFontChars) need to create a sprite area the size of a single character. This call returns the size required for this sprite (+ palette + mask + save area etc), and thus the amount of workarea that should be reserved. The sprite needs a save area as it appears that SWI Font_Paint redirects output to a sprite and thus corrupts the graphics colours. This means that it takes two passes to read the size required for the sprite - the first with bit 7 clear to read the size for the sprite and the second with it set to create the sprite (space now reserved for it) and calculate the save area required via SWI OS_SpriteOp 62.
SYS "ZapRedraw_SpriteSize",&01,redraw_block TO size%
PROCensure_workarea(size%)
SYS "ZapRedraw_SpriteSize",&81,redraw_block TO size%
PROCensure_workarea(size%)
| R0 | = | Pointer to redraw block as returned by Wimp for SWI Wimp_Poll 1 (data% in eg.) |
| R1 | = | Zap redraw block with r_data containing the text to redraw. All of the block should be setup apart from rectangle to draw and the scroll offsets which are filled in for you. |
| R0 (and flags) | = | Corrupted. |
This SWI performs the calls to SWI Wimp_RedrawWindow, SWI Wimp_GetRectangle, SWI ZapRedraw_GetRectangle, and SWI ZapRedraw_RedrawArea for you. It assumes that the redraw block is already setup.
Where redraw% is the address of the redraw block and data% the data block returned by SWI Wimp_Poll 1 for event 1 (redraw window request).
| R0 | = | Numerator |
| R1 | = | Denominator |
| R0 | = | R0 DIV R1 |
| R1 | = | Corrupted |
| R2 | = | R0 MOD R1 |
| R3 | = | Corrupted if the denominator is greater than 32. |
| N flag | corrupted | |
| C flag | corrupted | |
| Z flag | corrupted | |
This SWI performs fast division and modulo functions. As the SWI overhead may be significant for this routine you may wish to find its address and call it directly.
| R0 | = | Left X (inclusive) |
| R1 | = | Top Y (inclusive) |
| R2 | = | Right X (exclusive) |
| R3 | = | Bottom Y (exclusive) |
| R4 | = | Colour (filled word - see SWI ColourTrans_ReturnColourNumber) |
| R0 - R12 | = | Corrupted |
This SWI performs fast plotting of rectangles. It is used internally as a drop in replacement for the operating system's routines.
The routine doesn't clip to the graphics window. It would be inefficient for it to do so - typically the graphics window co-ordinates normally only need to be read once for a number of rectangles.
Coordinates are in pixels, (0,0) at top left. It is required that R2 > R0, and R3 > R1. All co-ordinates must be positive and within display bounds.
| R0 | = | Destination string | ||||||||||||||||||
| R1 | = | Pointer to redraw block giving initial r_for and r_bac. | ||||||||||||||||||
| R2 | = | Offset in source string of first character to be in the cursor. | ||||||||||||||||||
| R3 | = | Cursor length (length in characters of string pointed to by R4) | ||||||||||||||||||
| R4 | = | Pointer to string of cursor characters (usually &7Fs) | ||||||||||||||||||
| R5 | = | Source string (0,2 terminated) | ||||||||||||||||||
| R6 | = | Text colours:
| ||||||||||||||||||
| R7 | = | Cursor colours:
| ||||||||||||||||||
| R0 | = | End of new destination string (after 0,2 terminator) |
This SWI takes a line of the same format used in 'r_data', eg the output from the above SWI, and adds in the codes to place 'cursors' over some of the text by using the code 0,4 (merge characters) or the code 0,8 (merge cursors). Here, a cursor means a string of characters to be overlayed.
This is an improvement over the old SWI ZapRedraw_AddCursor command, which wasn't able to cope with characters within a selection that didn't have the selection foreground colour, resulting in very strange behaviour in some cases. SWI ZapRedraw_AddCursor is now implemented in terms of the new routine.
Room should be reserved for the string to grow by 8 × R3 characters. (eg 0,4,f,b,old,0,3,l,h) If the indicated offset (R2) is off the end of the string then it will be lengthened with spaces (&20) so you should ensure R2 + 9 × R3 characters extra are reserved.
| R0 | = | Pointer to font name, or 0 for system font. | ||||||||||||
| R1 | = | Flags:
| ||||||||||||
| R2 | = | X size (in points × 16). Only applicable in VDU mode. | ||||||||||||
| R3 | = | Aspect ratio (Y / X × 100), or 0 for the same as the X size. Only applicable in VDU mode. | ||||||||||||
| R4 | = | Pointer to reduction block. Only applicable in VDU mode. | ||||||||||||
| R0 | = | Font handle |
This finds a font and returns a font handle which should be placed in r_caddr. All of the font's substyles are opened as well, if available. The font handle has the form &HHHHHH00 where HHHHHH is a number from 1 to 32; the bottom byte is the sub-style, and you may set it to the initial sub-style for the line before using the handle in r_caddr. Any value below &8000 in r_caddr is a font handle; larger values are the addresses of character caches or font names.
If the font has already been found with the same name (and, in VDU mode, the same size, aspect ratio and reduction block) then the same handle is returned, and the number of users of the handle is increased. Each call to FindFont must therefore be balanced by one call to SWI ZapRedraw_LoseFont. Creating a new handle also discards the data for any fonts which have no users, to free memory.
DSA mode: the font name is either a font as it appears in the ZapFonts directory, eg 08x16.System, or a complete path name of a font file or an application-specific font directory (in which case it need not be on ZapFontsSource$Path). It may also be a font identifier of the form returned by SWI ZapRedraw_DecodeMenu. If the name is the name of a directory then the file 0 in it is the base font, and the other files are its sub-styles. If the name is a link file, the font linked to is used. See the description of font files for details of the files. The font is loaded on demand, in the format required by the screen mode in r_bpp at the time it is used; the call itself only needs to find the font. An unusable font gives the errors "Font '%0' not found", "Font file corrupt" or "Invalid font link file". RISC OS 3.5 or later is required, because the data is held in a dynamic area; before that the call returns the error "Font handles require RISC OS 3.50 or later".
VDU mode: the font name is the Font Manager identifier of a font. If R0 is 0 then the system font is used, and the sizes are ignored. Otherwise R2 and R3 give the size at which to plot the font, as for Font_FindFont. The size of a character cell is taken from the bounding box of the characters 0-9, A-Z and a-z of the font, converted into pixels. In VDU mode, R4 may optionally point to a reduction block which allows the cell size to be fine-tuned. The block has the following form:
| Offset | Meaning |
|---|---|
| 0 | Left reduction |
| 4 | Top reduction |
| 8 | Right reduction |
| 12 | Bottom reduction |
All values are in pixels, and are signed integers. In general, the values in this block will all be 0, so you may omit it. The system font is treated as being 8 pixels wide and 16 pixels high (8 pixels high if there are 4 or more OS units to a pixel vertically).
The handle is shared between VDU mode and DSA mode redraws as far as the font data is concerned: a handle found in VDU mode may also be used in DSA mode, when ZapRedraw converts the font to anti-aliased bitmaps on demand (unless the r_flags bit 9 asks it not to). A handle found in DSA mode cannot be used in VDU mode (this gives the error "Attempt to use a DSA font in VDU mode").
There are 32 font handles. If they are all in use the error "No more font handles" is returned.
| R0 | = | Font handle (the sub-style byte is ignored) |
| R0 | = | Corrupted |
This tells ZapRedraw that you no longer need a font, by reducing the number of users of the handle by one. When the handle has no more users the font data may be discarded from memory, and the font cache compacted; this happens when the next new font is found or when the *ZapFontTidy command is used. Losing a handle with no users gives the error "Invalid font handle".
| R0 | = | Font handle, or 0 to read from r_caddr | |||||||||||||||
| R1 | = | Redraw block (for r_caddr, r_linesp, r_magx, r_magy, r_flags) | |||||||||||||||
| R2 | = | Flags:
| |||||||||||||||
| R0 | = | Corrupted |
| R1 | = | Preserved |
| R2 | = | X size |
| R3 | = | Y size |
This call is used to read the size of a font. The size is that of a character cell. If bit 2 is set and r_flags bit 1 is set (double height mode) then the Y size is doubled. If bit 2 is set and r_flags bit 5 is set, and the redraw is in DSA mode, then double height mode is chosen as it is for SWI ZapRedraw_RedrawArea: if the character height is 8 or less and r_magy is 0 or 1 then the Y size is doubled. The conversion to OS units is made last, so that spacing is included in it.
| R0 | = | Version number × 100 |
| R1 | = | Pointer to SWI ZapRedraw_Divide routine |
| R2 | = | Pointer to SWI ZapRedraw_MoveBytes routine |
This call is used either to find out ZapRedraw's version number, or to retrieve the pointers so that the low-overhead routines can be called directly if required with caution
| R0 | = | Menu prefix (menu mode only): pointer to the name of the font directory whose fonts are to be listed in the menu, or 0 for the top level menu | ||||||||||||||||||||||||||||||
| R1 | = | Pointer to buffer for the identifier of the font (list mode) or for the menu (menu mode), or 0 to only read the size required | ||||||||||||||||||||||||||||||
| R2 | = | Flags and index:
If bits 16-31 are all clear then the call behaves as it did on RISC OS 2: the identifier is returned, terminated by CR, and R3 is taken to be 40. | ||||||||||||||||||||||||||||||
| R3 | = | Length of the buffer pointed to by R1 | ||||||||||||||||||||||||||||||
| R4 | = | Pointer to buffer for the font name (list mode) or for the indirected menu text (menu mode) | ||||||||||||||||||||||||||||||
| R5 | = | Length of the buffer pointed to by R4 | ||||||||||||||||||||||||||||||
| R6 | = | Identifier of the font to tick (menu mode with bit 21 set), or 1 to tick the system font | ||||||||||||||||||||||||||||||
| R0 | = | Pointer to the menu (menu mode), or 0 if there are no fonts |
| R2 | = | Index of the next font to read (list mode), or -1 if there are no more fonts or an error occurred |
| R3 | = | Number of bytes written to (or, if R1 was 0, required for) the buffer in R1 |
| R5 | = | Number of bytes written to (or, if R4 was 0, required for) the buffer in R4 |
This call enumerates the fonts (or encodings) known to ZapRedraw, and its entry and exit conditions follow those of the Font Manager's Font_ListFonts SWI. The fonts known are those listed in the Messages files in the directories of ZapFontsSource$Path, and are scanned when the module starts, and again by *ZapFontInstall. The lists are sorted using the territory's collation. Fonts whose names contain dots are grouped into submenus by their components: the font 08x16.Computer appears as the entry Computer in the submenu 08x16. If a font has a name which is also the prefix of other fonts, its own entry is labelled (Regular) within its submenu.
In list mode the call returns one font each time, so that it should be called repeatedly, starting with an index of 0 and using the index returned in R2 each time, until R2 is -1. The font identifier is the string used to open the font; the font name is a localised string which is suitable for displaying to the user. If the name is not given in the messages file then the identifier is used for it.
In menu mode the call builds a standard Wimp menu, with indirected title and entry text, and with the submenus following the main menu in the buffer. The menu title is the localised text for the token FontList (or Encodings). It may be passed to SWI Wimp_CreateMenu,. As with Font_ListFonts, the size required for the buffers may be found by calling the SWI with R1 and R4 as 0.
The call gives an error if bits which are reserved are set ("Bad parameters"), or if a buffer is too small ("Buffer overflow").
| R0 | = | Wimp window block (suitable for passing to SWI Wimp_UpdateWindow) |
| R1 | = | Zap Redraw block (all offsets used) |
| R0 | = | Corrupted |
Updates a window in a standard loop using SWI Wimp_UpdateWindow and repeated calls to SWI ZapRedraw_RedrawArea as appropriate.
| R0 | = | Index of the information to read (only 0 is defined) |
| R1 | = | Font handle |
| R0 | = | Depends upon the index. At present the only index, 0, returns a pointer to a read-only copy of the font name, as supplied to SWI ZapRedraw_FindFont (for a DSA font, in canonical form; 0 for the system font). The pointer is only valid until the font is lost. |
This SWI is used to return information on a font, eg. for the Zap font list. An unknown index gives the error "Unknown ReadFontInfo index" (&48489); an invalid font handle gives "Invalid font handle".
| R0 | = | Log base 2 of the number of bits per pixel to use for the character cache (the value for r_bpp when creating it) |
This call returns the log base 2 of the bits per pixel of the current screen mode, adjusted for the ways in which ZapRedraw can draw from one bit per pixel bitmaps. The value returned is 0 if the mode has 32 bits per pixel (as ZapRedraw can plot from 1 bpp bitmaps in these modes) or if ViewFinder is rendering the text (as ViewFinder uses 1 bpp bitmaps). Otherwise it is the log base 2 of the number of bits per pixel of the mode. It should be used where you would otherwise read the number of bits per pixel of the mode, when you choose the size of the character cache for the mode. When the call returns 0 for a 32 bpp mode, r_bpp in the redraw block remains 5, but the sizes r_cbpl and r_cbpc are those for a character cache of 1 bpp.
| R0 | = | Reason code:
| ||||||||
| R1 | = | Depends on the reason code - see above |
| R0 | = | Depends on the reason code - see above |
An encoding translates the character codes of a piece of text into Unicode characters. SWI ZapRedraw_PrepareDataLine can use an encoding to translate text, and thereby display text in other character sets in fonts which contain the Unicode characters.
Reason code 0 finds an encoding by its identifier, as returned by SWI ZapRedraw_DecodeMenu, or by its name, such as Latin2. The encoding is loaded from the file of that name found along ZapFontsSource$Path if it is not already loaded, and the number of users of the handle is increased. The names UTF8 and UTF16 give special handles which require no file. Up to 16 encodings can be loaded at once.
Reason code 1 reduces the number of users of an encoding by one. Encodings without users are freed when space is needed and when the module is finished.
Reason code 2 returns a pointer to the translation table of an encoding. It is a table of 256 words, one for each 8 bit character code, giving the Unicode character or -1 if the character is not defined. For the special UTF-8 and UTF-16 encodings, which are not tables, it returns 1 for UTF-8 and 2 for UTF-16. The table is valid until the encoding is lost.
Handles for tables are numbers from 1 to 16. The special handles for UTF-8 and UTF-16 are &40000001 and &40000002. An unknown reason code gives the error "Unknown ZapRedraw_Encoding reason code" (error number 0); an invalid handle gives "Invalid encoding handle".
Star Commands
Discards the data of all fonts which have no users, and compacts the font cache so that the memory can be returned to the system.
Lists the font handles in use with, for each, the name of the font (or System font), the size of a character cell, the number of users, and the memory used by the font. It ends with the total size of the font cache and the amount of it which is free.
<encodings> | - | If any parameter is given, the encodings are listed instead of the fonts. |
Writes the localised name of each font known to ZapRedraw, one per line, in the order of the font menu.
<directory> | - | The directory to add to ZapFontsSource$Path. |
Appends the directory to ZapFontsSource$Path, and scans the directories on the path again for fonts and encodings. With no parameter, only the scan is made.
Debugging commands
Builds of ZapRedraw made for debugging also have the commands ZapFontDescribe (describes the font blocks, encodings and free memory of the cache), ZapFontDie (forgets all font handles without freeing their memory, so that the module can be killed) and ZapFontDebug (prints an internal variable), and profiling builds also have ZapFontProfile. These are only present in debugging builds of ZapRedraw, are subject to change, and should not be relied on.
Extension routines to ZapRedraw_RedrawArea
The extension routine is provided so you can trap unknown control codes and add extra functionality to the ones that exist. For example, you may wish to change font on a colour change. Zap's fast font redraw mode does this. If you provide an extension routine then on entry to it R0 = reason code, R12 = your private word and:
On exit, you may corrupt R0 and R12 and alter the registers mentioned (EXCEPT R1!) to new (sensible) values.
All registers are reset at the start of a new raster line.
You must not alter the redraw block itself.
You CANNOT return errors from an extension call.
R0=0 : Starting a raster line
| Register | Contents |
|---|---|
| R1 | Pointer to redraw block |
| R3 | Pointer to first character |
| R4 | Address of the bitmap data for the current character row being drawn: r_caddr + r_cbpl × row where row (0 ... r_charh - 1), or the equivalent address within the font if r_caddr is a font handle. Or, R4 = 0 if in line spacing. R4 = 1 means the current chunk of the font does not exist. |
| R5 | Pointer to address in screen memory of current word being written |
| R6 | Bit offset in current word being written |
| R7 | Current word being written (bits >= R6 are clear) |
| R9 |
|
| R10 | Start foreground mask (eg &77777777) |
| R11 | Start background mask (eg &00000000) |
R0=1 : Foreground and background colours changing
| Register | Contents |
|---|---|
| R1 | Pointer to redraw block |
| R3 | Address of next character after the control code |
| R4 | r_caddr + r_cbpl × row where row (0 ... r_charh - 1) is the current character row being drawn. Or, R4 = 0 if in line spacing. |
| R5 | Pointer to address in screen memory of current word being written |
| R6 | Bit offset in current word being written |
| R7 | Current word being written (bits >= R6 are clear) |
| R10 | New foreground mask (eg &77777777) |
| R11 | New background mask (eg &00000000) |
R0=2 : Reserved
R0=3 : Reserved
R0=4 : About to merge characters
| Register | Contents |
|---|---|
| R1 | Pointer to redraw block |
| R2 | Character definition table to use for the mask character |
| R3 | Next character after the merge |
| R4 | Character definition table for the base character (as for R0 = 1) |
| R6 | Base char |
| R7 | Mask char (or these are -1 if invalid). |
| R8-9 | Foreground/background masks where mask character bits set. |
| R10-11 | Current for/bac masks. |
NB Any changes you make to these registers will be effective for this one character only the normal values being stacked.
R0=5 : Reserved
R0=6 => Foreground colour changing
As for R0 = 1
R0=7 => Background colour changing
As for R0 = 1
R0=8 : About to merge cursors
Registers as for R0 = 4.
If R7 < &100 then R10 / R11 will be set to R9 / R8 and next char drawn.
If R7 >= &100 then the characters will be merged with R9 copied into R8.
R0=9 : Font change
Registers as for R0 = 1
R0=10 : Foreground colour, background colour and font change
Registers as for R0 = 1
Note that if you are not using a font handle then changing font during redraw must be done in an extension routine for DSA redraws. With a font handle, ZapRedraw has already changed to the new sub-style before the extension routine is called.
R0=11 : Chunk change
Registers as for R0 = 1, with R3 the address of the next character after the control code and R4 the address of the glyph data for the new chunk (0 if in line spacing, 1 if the chunk does not exist). Called after control code 0,11.
R0=12 : Large chunk change
As for R0 = 11. Called after control code 0,12.
R0>12 : Reserved
Error Messages
All 32 font handles are in use (or, for the message "No more encoding handles", all 16 encoding handles).
A file which is a link does not begin with "ZFLK" or cannot be read.
The font (or, for "Encoding '%0' not found", the encoding) could not be found along ZapFontsSource$Path.
The file is not a font file, or (for "Encoding file corrupt") not an encoding file of the supported version, or is truncated.
The module cannot be killed because font handles or encodings are in use, or because a client claimed Service_ZapRedrawDying.
The font handle is not in use. For encodings, the message is "Invalid encoding handle".
The dynamic area for the font cache could not be created because the system does not support dynamic areas.
SWI ZapRedraw_RedrawRaster was called when ViewFinder is drawing the text.
A font handle found in DSA mode was used for a VDU redraw.
The index passed to SWI ZapRedraw_ReadFontInfo is not 0. The supplied messages file has no text for this error.
The reason code passed to SWI ZapRedraw_Encoding is not 0, 1 or 2.
The SWI number is above the last SWI of ZapRedraw.
Copyright / Contact details
The ZapRedraw module is copyright Dominic Symes 1994-1997, and later versions copyright the Zap Developers. Please contact him if you wish to use it in a program other than Zap. See the Zap Copyright file for his address. ZapRedraw and Zap can be obtained from http://www.zap.uk.eu.org/
This manual has been converted from text format to XML by Andrew Hill <drew.hill@tesco.net>. It is currently in RFC release, and should therefore neither be considered authoritative nor for official release. Many thanks for the RISC OS Documentation Project Group for proof-reading and comments.
All maintenance to this document should be performed on the XML document, not to its output formats.
Comments or queries regarding this documentation should be addressed to Andrew Hill <drew.hill@tesco.net>; comments about ZapRedraw should go to the Zap DevTeam <christian@zap.tartarus.org>.