ZapRedraw

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:

It also has the following limitations:

Outstanding issues

Terminology

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:'.

OffsetNameContents
0r_flagsFlags word determining the type of redraw:
Bit(s)Meaning
0Clear for DSA mode. Set for VDU redraw mode.
1Set for 'double height mode'. Only valid in DSA mode. Draws each raster twice so actual character height is 2 × r_charh and the line spacing is also doubled.
2Extension routine provided. Only valid in DSA mode. See SWI ZapRedraw_RedrawArea.
3Set if sub-styles are in use. In VDU redraw mode ZapRedraw then also looks for the bold and italic variants of the font. In SWI ZapRedraw_PrepareDataLine it indicates that a list of sub-styles is supplied in R7. See Sub-styles.
4Set if it is OK to use the fast rectangle plot in VDU redraw mode (ie. output is not redirected to a sprite or a printer.)
5Set if you want ZapRedraw to decide whether to use double-height mode (it will set or clear b1 automatically.) Double-height mode is selected if the character height is 8 pixels or less and r_magy is 0 or 1. This only applies in DSA mode, and only takes effect when r_caddr is a font handle (or when the flag is passed to SWI ZapRedraw_ReadCharSize).
6Set if the optional parts of the redraw block are present.
7Right-to-left (VDU mode only). SWI ZapRedraw_GetRectangle also takes this into account.
8Transparent - colour mask in r_bac is not plotted (VDU mode, and DSA mode in 32 bits per pixel modes)
9Forces ZapRedraw to use 1bpp bitmaps for font data, rather than anti-aliased bitmaps.
10The characters supplied to SWI ZapRedraw_PrepareDataLine are 16 bits wide.
11The characters supplied to SWI ZapRedraw_PrepareDataLine are 32 bits wide. Do not set both bits 10 and 11.
12The foreground, background and sub-style lists supplied to SWI ZapRedraw_PrepareDataLine have one byte for each character, rather than one byte for each byte of text.
13-28Reserved - set to zero.
29-31Used by ZapRedraw to hold temporary state during a call; set to zero on entry and ignore on exit.
4r_minxMinimum X of redraw box (pixels from left - inclusive)
8r_minyMinimum Y of redraw box (pixels from top - inclusive)
12r_maxxMaximum X of redraw box (pixels from left - exclusive)
16r_maxyMaximum Y of redraw box (pixels from top - exclusive)
20r_screen
  • DSA: Pointer to screen to write to or 0 to read the current screen address.
  • VDU: Ignored.
24r_bpl
  • DSA: Bytes per raster line of the screen.
  • VDU: Ignored.
28r_bppLog base 2 of number of bits per pixel:
ValueNo. of cols.
02
14
216
3256
465,536
52^32 (theoretical), ie. true colour.
32r_charwWidth of a character in pixels
36r_charhHeight of a character in pixels
40r_caddr

  • DSA: Pointer to character cache, or a font handle
  • VDU: Pointer to font name, 0 for system font, or a font handle

44r_cbpl

  • DSA: Number of bytes per cached character line.
  • VDU: X OS offset of where to print the font char in the character 'box'. (eg 0 for system font)

48r_cbpc

  • DSA: Number of bytes per cached character.
  • VDU: Y OS offset of where to print the font char in the character 'box'. (eg char height - 1 for system font as VDU5 plots char downwards).

52r_linespSpacing in pixels:
Bit(s)Meaning
0-15Line spacing in pixels. This is the number of blank rasters between the lines of characters.
16-31Character spacing in pixels. This is the number of blank pixels added after each character; it is drawn in the background colour. A non-zero value disables the fast paths for 8 pixel wide characters.
Where this document refers to the line spacing, it is bits 0-15 which are meant.
56r_dataPointer to data (rectangle of characters) to print on the screen (format below).
60r_scrollxHorizontal 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).
64r_scrollyVertical 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).
68r_palettePointer to palette to be used for colour translation. (see below).
72r_forForeground colour to use at the start of a line as an offset in the palette table.
76r_bacBackground colour to use at the start of a line as an offset in the palette table.
80r_workareaPointer 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.
84r_magxLog base 2 of number of X OS co-ords per pixel.
88r_magyLog base 2 of number of Y OS co-ords per pixel.
92r_xsizeWidth of screen in pixels.
96r_ysizeHeight of screen in pixels.
100r_modeCurrent screen mode.
104r_lengthOPTIONAL (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.
108r_lmarginOPTIONAL (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.
112r_tmarginOPTIONAL (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.
116r_encodingOPTIONAL (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:

RowValueBinary, low bit first
0&7E01111110
1&0601100000
2&0601100000
3&7E01111110
4&0601100000
5&0601100000
6&7E01111110
7&0000000000

If it was in a 16 colour mode then there would be one word per row and the first rows would be:

RowValueBinary, low bit first
0&0FFFFFF000001111111111111111111111110000
1&00000FF000001111111100000000000000000000

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:

ValueMeaning
0,0Prints character n = 0
0,1,f,bSwitch colour to foreground f and background b. (f/b are palette offsets - see r_for/r_bac).
0,2End of line - the rest of the line is cleared to the current background colour. Every line must be terminated with this.
0,3,l,hPrint 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,yMerges 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,5For 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,fChange foreground colour to f.
0,7,bChange background colour to b.
0,8,f,b,x,yCursor 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,SSubstyle change to style S.
0,10,f,b,SSwitch colour to foreground f and background b, and font to substyle S.
0,11,cChange 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,hChange 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:

ValueMeaning
&00Prints a '0' (ASCII &30)
&01-&1AThese print the letters A-Z (ie &40 is added)
&1B-&1FPrints "[ \ ] ^ _" respectively (ie &40 is added)
&20-&7EUsual ASCII characters printed.
&7FThis draws a filled in block (useful for a cursor)
&80-&FFUsual ASCII characters printed.
&100This draws the top,bottom,left edges ie '['.
&101This draws the top,bottom edges.
&102This draws the top,bottom,right edges ie ']'.
&103This draws an empty square (useful for a cursor)
&104This draws the baseline ie '_' (useful for a cursor)
&105This 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:

BitMeaning
0Strikethrough
5Bold
6Italic
7Underlined

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:

OffsetNameContents
0MagicThe bytes "ZapFont" followed by 13
8WidthWidth of each font character in pixels
12HeightHeight of each font character in pixels
16FirstFirst character code given (eg 0 or &20)
20LastLast character code given + 1 (eg &100)
24ReservedReserved (0)
28ReservedReserved (0)
32GlyphsBitmaps, 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:

OffsetNameContents
0MagicThe bytes "ZRUF" (ZapRedraw UCS Font)
4ReservedReserved (0)
8WidthWidth of each glyph in pixels
12HeightHeight of each glyph in pixels
16Directory sizeSize of the chunk directory in bytes
20Null glyphOffset of the null glyph from the start of the file, or 0 if there is none
24ReservedReserved (0)
28ReservedReserved (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:

OffsetNameContents
0Chunk numberThe number of the first glyph of the chunk: a chunk containing the glyph &2A3F has &2A00 here
4Glyph countThe number of glyphs in this chunk
8File offsetOffset in the file of the glyph data of this chunk
12ReservedReserved - 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:

OffsetNameContents
0MagicThe bytes "ZENC"
4VersionFile format version - must be 2
8ReservedReserved (0)
12ReservedReserved (0)
16Table256 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:

System Variables

ZapFontsSource$Path
Path along which fonts and encodings are found

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.

ZapFontsMessages$Path
Path along which the module's Messages file is found

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.

Zap$Redraw
Location of the ZapRedraw module

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.

ViewFinder$Enable
Whether ZapRedraw should use ViewFinder

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

Service_ZapRedrawStartedService Call &48480
ZapRedraw has started
None
None

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.

Service_ZapRedrawDyingService Call &48481
ZapRedraw is about to quit
None
None

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

ZapRedraw_RedrawAreaSWI &48480
This redraws a rectangle of characters on the screen.
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:

  • Lower 16 bits:font size to plot at (points)
  • Upper 16 bits:font aspect ratio to use ( = Y / X × 100) (or 0)

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.)
R0corrupted
N flagcorrupted
C flagcorrupted
Z flagcorrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_GetPaletteEntrySWI &48481
Convert a palette entry into a mask.
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 flagcorrupted
C flagcorrupted
Z flagcorrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_RedrawRasterSWI &48482
Redraws a single raster line.
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=
Bit(s)Meaning
0-15Start foreground colour to use (eg r_for value)
16-23Start background colour to use (eg r_bac value)
24-31Starting sub-style
R7=Initial chunk number, as set by the chunk control codes (a multiple of &100; 0 for the first 256 characters).
R0corrupted
N flagcorrupted
C flagcorrupted
Z flagcorrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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:

OffsetContents
0Pixel scroll offset within the first visible char (0 -> charw - 1)
4Number of pixels to do from the first character (0 -> charw - 1)
8Number of whole characters to do after the first char
12Number of pixels to do in the last visible char (0 -> charw - 1)
16Number of whole characters scrolled off the left of the redraw rectangle. Set up by SWI ZapRedraw_RedrawArea; not used by this SWI
20Pointer to extension routine if redraw flags bit 2 set
24Private word for the extension routine if redraw flags bit 2 set
ZapRedraw_ConvertBitmapSWI &48483
Converts a 1bpp character bitmap into a bitmap for the RedrawArea SWI.
R1=Pointer to redraw block. Offsets looked at are:
ValueMeaning
r_bppTo find the number of bits per pixel.
r_charwWidth of char in pixels.
r_charhHeight of char in pixels.
r_caddrAddress to write the bitmap. The characters R2 to R3 are written at offsets R2 × r_cbpc to (R3 + 1) × r_cbpc from this address, so this memory must be reserved.
r_cbplCache line width in bytes (as defined under r_caddr help text.)
r_cbpcNumber of bytes per cached character (as defined under r_caddr help text.)
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.
R0corrupted
N flagcorrupted
C flagcorrupted
Z flagcorrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_PrepareDataLineSWI &48484
Helps prepare the r_data field of the redraw block.
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 flagcorrupted
C flagcorrupted
Z flagcorrupted
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).
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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").

ZapRedraw_AddCursorSWI &48485
Adds cursor control codes to a string.
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:
Bit(s)Meaning
0-7High byte to use for cursor characters in R4 string.
8-15Control code to use when merging ie 4 or 8.
16-23Foreground colour of the cursor
24-31Background colour of the cursor

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)
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_FindCharacterSWI &48486
Given n, returns the (n + 1)th printable character in a string.
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.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_MoveBytesSWI &48487
This is a fast byte-moving routine.
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 flagcorrupted
C flagcorrupted
Z flagcorrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is re-entrant

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.

ZapRedraw_CachedCharSizeSWI &48488
Works out the size of a character.
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)
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_ConvBitmapCharSWI &48489
Converts a character to a bitmap.
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.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_CreatePaletteSWI &4848A
Creates the r_palette data block.
R0=Reason code:
Bit(s)Meaning
0Set to convert wimp colours to &bbggrrxx
1Set to convert &bbggrrxx to DSA colour masks
2+Reserved - set to 0
R1=Pointer to redraw block. The following are used:
ValueMeaning
r_bppLog_2 of bits per pixel
r_workareaPointer to 128 byte work area to load wimp palette into.
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
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_InsertCharSWI &4848B
Inserts a character into a string of r_data format.
R0=Character
R1=String address
R0 (and flags)=Corrupted
R1=Updated to the point after the character insertion.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_ReadSystemCharsSWI &4848C
Reads the standard system character bitmaps.
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
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_ReverseBitmapsSWI &4848D
Reverses the bits of each byte of a list of bytes.
R1=Source buffer
R2=Destination buffer (can equal source)
R3=Number of bytes (must be a multiple of 4)
R0 (and flags)=Corrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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).

ZapRedraw_ReadVduVarsSWI &4848E
Sets up Zap's initial redraw block.
R1=Pointer to redraw block to update (r_workarea should point to a 64 byte scratch area.)
R0 (and flags)=Corrupted.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_GetRectangleSWI &4848F
Called after Wimp_GetRectangle; fills in the ZapRedraw block.
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.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_AddVduBitmapsSWI &48490
Creates bitmaps for the special VDU redraw characters.
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.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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):

ValueMeaning
&00Creates bitmap for '0' by copying bitmap &30
&01-&1FCreates bitmaps for 'A', 'B', ... by copying bitmaps &41-&5F
&7FCreates a filled in square.
&100Top bottom and left edge filled [
&101Top and bottom edges
&102Top bottom and right edge filled ]
&103Empty square
&104Underscore _
&105Left 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.

ZapRedraw_CacheFontCharsSWI &48491
Caches a range of characters from an anti-aliased font as bitmaps.
R0=Reason code - other registers depend upon reason code.
ReasonMeaning
1 Cache font in current wimp mode (ie wimp palette used)
2 Cache font in mode 0 with background 0 and foreground 1.
R0 (and flags)=Corrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_CacheFontChars 1CurrentWimpModeSWI &48491
Cache font in current wimp mode (ie wimp palette used)
R1=redraw block with the following set up:
ValueMeaning
r_bppNumber of bits per pixel to cache at
r_caddrPointer to cache with space reserved for the chars r_cbpl / cbpc / r_charw / r_charh setup
r_for/r_bacOffset in r_palette of for and bac cols
r_palettePalette of colours as for VDU redraw mode (ie each entry of form &BBGGRRxx)
r_workareaRoom for 64 bytes + single sprite (use SWI ZapRedraw_SpriteSize).
r_modeMode to cache font in (ie mode sprite defined in).
R2=Pointer to font name
R3=Font plotting details:
Bit(s)Meaning
0-15Font size to plot at (points)
16-31Font aspect ratio to use (= Y / X × 100) (or 0)
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)
None
Interrupts are undefined
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant
ZapRedraw_CacheFontChars 2DefaultModeSWI &48491
Cache font in mode 0 with background 0 and foreground 1.
R1=Pointer to redraw block with the following set up:
ValueMeaning
r_caddrPointer to cache with space reserved for the chars r_cbpl / cbpc / r_charw / r_charh setup
r_workareaRoom for 64 bytes + single sprite (use SWI ZapRedraw_SpriteSize).
r_magx, r_magyFor mode used with reason code R0 = 1.
R2=Pointer to font name
R3=Font plotting details:
Bit(s)Meaning
0-15Font size to plot at (points)
16-31Font aspect ratio to use (= Y / X × 100) (or 0)
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)
None
Interrupts are undefined
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant

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.

ZapRedraw_SpriteSizeSWI &48492
Calculates the size of a save area for OS_SpriteOp 62.
R0=Reason code:
Bit(s)Meaning
0-6

Sprite mode to calculate the size for:

  • 1 : Return sprite size for sprite in current mode and r_bpp.
  • 2 : Return sprite size for a mode 0 sprite (ie assume r_bpp = 0)

7Clear for first pass, set for second pass.
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=

  • Bit 7 Clear : Size required for sprite area (no save area).
  • Bit 7 Set : Total size required for sprite + save area.

Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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%)

ZapRedraw_RedrawWindowSWI &48493
Performs the redraw given a redraw block.
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.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

SYS "Wimp_RedrawWindow",,data% TO flag% WHILE flag% SYS "ZapRedraw_GetRectangle",data%,redraw% SYS "ZapRedraw_RedrawArea",,redraw% SYS "Wimp_GetRectangle",,data% TO flag% ENDWHILE

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).

ZapRedraw_DivideSWI &48494
Fast division / modulo functions.
R0=Numerator
R1=Denominator
R0=R0 DIV R1
R1=Corrupted
R2=R0 MOD R1
R3=Corrupted if the denominator is greater than 32.
N flagcorrupted
C flagcorrupted
Z flagcorrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is re-entrant

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.

ZapRedraw_PlotRectangleSWI &48495
Fast rectangle plotting.
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
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_AddCursorSmartSWI &48496
Adds cursor codes into an r_data string.
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:
Bit(s)Meaning
0-7Foreground colour to match (=> uses cursor foreground/background inverted)
8-15Background colour to match (=> uses cursor foreground colour as final background colour)
16-29Reserved
30Do foreground matching
31Do background matching
R7=Cursor colours:
Bit(s)Meaning
0-7High byte to use for cursor characters in R4 string
8-15Control code to use when merging ie 4 or 8.
16-23Foreground colour of the cursor.
24-31Background colour of the cursor.
R0=End of new destination string (after 0,2 terminator)
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_FindFontSWI &48497
Finds a font and returns a font handle.
R0=Pointer to font name, or 0 for system font.
R1=Flags:
Bit(s)Meaning
0Set if VDU mode; clear for DSA mode.
1Set if R4 points to a reduction block. This applies to VDU mode only; it is ignored in DSA mode.
2-31Reserved - set to 0
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
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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:

OffsetMeaning
0Left reduction
4Top reduction
8Right reduction
12Bottom 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.

ZapRedraw_LoseFontSWI &48498
Discards a font from memory.
R0=Font handle (the sub-style byte is ignored)
R0=Corrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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".

ZapRedraw_ReadCharSizeSWI &48499
Reads the size of a font.
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:
Bit(s)Meaning
0Return values in OS units if set, pixels if clear
1Add the line spacing (bits 0-15 of r_linesp) to the height, and the character spacing (bits 16-31) to the width
2Use r_flags bits 1 and 5 (double-height flags)
3-31Reserved - set to 0
R0=Corrupted
R1=Preserved
R2=X size
R3=Y size
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is re-entrant

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.

ZapRedraw_VersionSWI &4849A
Returns the current version no. and access to ZapRedraw SWIs.
None
R0=Version number × 100
R1=Pointer to SWI ZapRedraw_Divide routine
R2=Pointer to SWI ZapRedraw_MoveBytes routine
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is re-entrant

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

ZapRedraw_ListFontsSWI &4849B
Lists the available fonts or encodings, or builds a menu of them.
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:
Bit(s)Meaning
0-15Index of the font to return (list mode only); 0 for the first
16Return the font identifier (list mode only)
17Return the font name (list mode only)
18Terminate strings with CR (13) instead of 0
19Return a menu rather than a list
20Add an entry for the system font to the menu
21Tick the font identified by R6 in the menu
22List the encodings instead of the fonts
23-31Reserved - set to 0

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
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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").

ZapRedraw_UpdateWindowSWI &4849C
Updates a window in a standard redraw loop.
R0=Wimp window block (suitable for passing to SWI Wimp_UpdateWindow)
R1=Zap Redraw block (all offsets used)
R0=Corrupted
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

Updates a window in a standard loop using SWI Wimp_UpdateWindow and repeated calls to SWI ZapRedraw_RedrawArea as appropriate.

ZapRedraw_ReadFontInfoSWI &4849D
Provides information on a font.
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.
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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".

ZapRedraw_ReadModeBPPSWI &4849E
Reads the number of bits per pixel at which to cache bitmaps for the current mode.
None
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)
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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.

ZapRedraw_DecodeMenuSWI &4849F
Converts a selection from a font menu into a font identifier.
R0=Flags:
Bit(s)Meaning
0Set if the menu is a menu of encodings rather than of fonts
1Terminate the identifier with CR instead of 0
2-31Reserved - set to 0
R1=Pointer to the menu definition, as returned by SWI ZapRedraw_ListFonts
R2=Pointer to the menu selection array, as returned by SWI Wimp_Poll for a menu selection
R3=Pointer to buffer for the identifier, or 0 to only read the length
R4=Length of the buffer
R4=Length of the identifier, including its terminator, or 0 if the system font was selected
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

This call converts the selection made in a menu built by SWI ZapRedraw_ListFonts into the identifier of the font (or of the encoding). It uses SWI Wimp_DecodeMenu to find the text of the entries chosen, and joins them with dots to give the font name; a final (Regular) entry stands for the font whose name is the prefix of the submenu. The identifier is a string of the form

\Fidentifier\fterritory name

where identifier is the name by which the font is opened, territory is the number of the territory of the localised name (a decimal number) and the \f part is omitted if the name is the same as the identifier. For encodings, the letters are \E and \e. The identifier may be passed directly to SWI ZapRedraw_FindFont (or SWI ZapRedraw_Encoding) and may be saved in a configuration file, as it does not depend on the territory of the machine reading it. If the font in the menu cannot be found the error "Unrecognised font in menu in ZapRedraw_DecodeMenu" is returned.

ZapRedraw_EncodingSWI &484A0
Finds, releases and reads encodings for use with ZapRedraw_PrepareDataLine.
R0=Reason code:
ReasonMeaning
0Find an encoding. R1 = pointer to the encoding identifier. Returns R0 = encoding handle.
1Lose an encoding. R1 = encoding handle.
2Read the translation table. R1 = encoding handle. Returns R0 = pointer to the table.
R1=Depends on the reason code - see above
R0=Depends on the reason code - see above
Interrupts are undefined
Fast interrupts are undefined
Processor is in undefined mode
SWI is not re-entrant

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

*ZapFontTidy
Compacts the Zap font cache
*ZapFontTidy
None

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.

*ZapFontList
Lists the fonts in the Zap font cache
*ZapFontList
None

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.

*ZapFontCat
Lists the fonts available to ZapRedraw
*ZapFontCat encodings
<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.

*ZapFontInstall
Adds a directory of fonts and rescans the font lists
*ZapFontInstall directory
<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

RegisterContents
R1Pointer to redraw block
R3Pointer to first character
R4Address 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.
R5Pointer to address in screen memory of current word being written
R6Bit offset in current word being written
R7Current word being written (bits >= R6 are clear)
R9
  • foreground : bottom sixteen bits
  • background : top sixteen bits.
R10Start foreground mask (eg &77777777)
R11Start background mask (eg &00000000)

R0=1 : Foreground and background colours changing

RegisterContents
R1Pointer to redraw block
R3Address of next character after the control code
R4r_caddr + r_cbpl × row where row (0 ... r_charh - 1) is the current character row being drawn. Or, R4 = 0 if in line spacing.
R5Pointer to address in screen memory of current word being written
R6Bit offset in current word being written
R7Current word being written (bits >= R6 are clear)
R10New foreground mask (eg &77777777)
R11New background mask (eg &00000000)

R0=2 : Reserved

R0=3 : Reserved

R0=4 : About to merge characters

RegisterContents
R1Pointer to redraw block
R2Character definition table to use for the mask character
R3Next character after the merge
R4Character definition table for the base character (as for R0 = 1)
R6Base char
R7Mask char (or these are -1 if invalid).
R8-9Foreground/background masks where mask character bits set.
R10-11Current 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

Error_ZapRedraw_NoHandlesError &48480
No more font handles

All 32 font handles are in use (or, for the message "No more encoding handles", all 16 encoding handles).

Error_ZapRedraw_NotFoundError &48482
Font '%0' not found

The font (or, for "Encoding '%0' not found", the encoding) could not be found along ZapFontsSource$Path.

Error_ZapRedraw_NotFontError &48483
Font file corrupt

The file is not a font file, or (for "Encoding file corrupt") not an encoding file of the supported version, or is truncated.

Error_ZapRedraw_CantDieError &48484
ZapRedraw is in use

The module cannot be killed because font handles or encodings are in use, or because a client claimed Service_ZapRedrawDying.

Error_ZapRedraw_BadHandleError &48485
Invalid font handle

The font handle is not in use. For encodings, the message is "Invalid encoding handle".

Error_ZapRedraw_NoCacheError &48486
Font handles require RISC OS 3.50 or later

The dynamic area for the font cache could not be created because the system does not support dynamic areas.

Error_ZapRedraw_NotImplError &48487
ZapRedraw_RedrawRaster is no longer implemented

SWI ZapRedraw_RedrawRaster was called when ViewFinder is drawing the text.

Error_ZapRedraw_NotVDUError &48488
Attempt to use a DSA font in VDU mode

A font handle found in DSA mode was used for a VDU redraw.

Error_ZapRedraw_BadFontInfoError &48489
Unknown ReadFontInfo index

The index passed to SWI ZapRedraw_ReadFontInfo is not 0. The supplied messages file has no text for this error.

Error_ZapRedraw_BadMenuError &4848A
Unrecognised font in menu in ZapRedraw_DecodeMenu

The selection does not correspond to a font known to ZapRedraw.

Error_ZapRedraw_BadReasonError &0
Unknown ZapRedraw_Encoding reason code

The reason code passed to SWI ZapRedraw_Encoding is not 0, 1 or 2.

Error_ZapRedraw_UnknownSWIError &1E6
Unknown ZapRedraw SWI

The SWI number is above the last SWI of ZapRedraw.

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 . 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 ; comments about ZapRedraw should go to the .