RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Appendix E: File formats


Introduction

The file formats described in this appendix are those generated by RISC OS itself and various applications. Each is shown as a chart giving the size and description of each element. The elements are sequential and the sizes are in bytes.

This appendix contains information about the following file formats:

  • Sprite files
  • Template files
  • Draw files
  • Font files, including IntMetrics, Outlines and bitmap files
  • Music files
  • Squash files

Sprite files

A sprite file is saved in the same format as a sprite area is saved in memory, except that the first word of the sprite area is not saved.

For a full description of sprite area formats, refer to Format of a sprite area.

Template files

The following section describes the Wimp template file format:

Header

The file starts with a header:

Size Description
4 file offset of font data (-1 if none)
4 reserved (must be zero)
4 reserved (must be zero)
4 reserved (must be zero)

Index entries

The header is followed by a series of index entries to data later in the file:

Size Description
4 file offset of data for this entry
4 size of data for this entry
4 entry type (1 = window)
12 identifier (control character terminated)

Terminator

The index entries are terminated by a null word:

Size Description
4 0

Data

Each set of entries referred to earlier in the index contains the following:

Size Description
88 window definition (as in Wimp_CreateWindow - see Wimp_CreateWindow)
ni × 32 icon definitions (as in Wimp_CreateIcon - see Wimp_CreateIcon)
? indirected icon data

Any pointers to indirected icon data are offsets from the start of the current entry. Any references to anti-aliased fonts use internal handles.

Font data

The file ends with an optional set of font data (the presence of which is indicated by the first word of the header):

Size Description
4 x-point-size × 16
4 y-point-size × 16
40 font name (control character terminated)

The first font entry is that referred to by internal handle 1, the second font entry is that referred to by internal handle 2, etc.

Draw files

The Draw file format provides an object-oriented description of a graphic image. It represents an object in its editable form, unlike a page-description language such as PostScript which simply describes an image.

Programmers wishing to define their own object types should contact Acorn; see Appendix H: Registering names.

Coordinates

All coordinates within a Draw file are signed 32-bit integers that give absolute positions on a large image plane. The units are 1/(180 × 256) inches, or 1/640 of a printer's point. When plotting on a standard RISC OS screen, an assumption is made that one OS-unit on the screen is 1/180 of an inch. This gives an image reaching over half a mile in each direction from the origin. The actual image size (eg the page format) is not defined by the file, though the maximum extent of the objects defined is quite easy to calculate. Positive-x is to the right, positive-y is up. The printed page conventionally has the origin at its bottom left hand corner. When rendering the image on a raster device, the origin is at the bottom left hand corner of a device pixel.

Colours

Colours are specified in Draw files as absolute RGB values in a 32-bit word. The format is:

Byte Description
0 reserved (must be zero)
1 unsigned red value
2 unsigned green value
3 unsigned blue value

For colour values, 0 means none of that colour and 255 means fully saturated in that colour.

You must always write byte 0 (the reserved one) as 0, but don't assume that it always will be 0 when reading.

The bytes in a word of an Draw file are in little-endian order, eg the least significant byte appears first in the file.

The special value &FFFFFFFF is used in the filling of areas and outlines to mean 'transparent'.

File headers

The file consists of a header, followed by a sequence of objects.

The file header is of the following form.

Size Description
4 'Draw'
4 major format version stamp - currently 201 (decimal)
4 minor format version stamp - currently 0
12 identity of the program that produced this file - typically 8 ASCII characters, padded with spaces
4 x-low bounding box
4 y-low bottom-left (x-low, y-low) is inclusive
4 x-high top-right (x-high, y-high) is exclusive
4 y-high

When rendering a Draw file, check the major version number. If this is greater than the latest version you recognise then refuse to render the file (eg generate an error message for the user), as an incompatible change in the format has occurred.

The entire file is rendered by rendering the objects one by one, as they appear in the file.

The bounding box indicates the intended image size for this drawing.

A Draw file containing a file header but no objects is legal; however, the bounding box is undefined. In particular the 'x-low' value may be greater than the 'x-high' value (and similarly for the y values).

Objects

Each object consists of an object header, followed by a variable amount of data depending on the object type.

Object header

The object header is of the following form:

Size Description
4 object type field
4 object size: number of bytes in the object - always a multiple of 4
4 x-low object bounding box
4 y-low bottom-left (x-low, y-low) is inclusive
4 x-high top-right (x-high, y-high) is exclusive
4 y-high

The bounding box describes the maximum extent of the rendition of the object: the object cannot affect the appearance of the display outside this rectangle. The upper coordinates are an outer bound, in that the device pixel at (x-low, y-low) may be affected by the object, but the one at (x-high, y-high) may not be. The rendition procedure may use clipping on these rectangles to abandon obviously invisible objects.

Objects with no direct effect on the rendition of the file have no bounding box (hence the header is only two words long). Such objects will be identified explicitly in the object descriptions that follow. If an unidentified object type field is encountered when rendering a file, ignore the object and continue.

The rest of the data for an object depends on the object type.

Font table object
Object type number 0

A font table object has no bounding box in its object header, which is followed by a sequence of font number definitions:

Size Description
1 font number (non-zero)
n character textual font name, null terminated
repeat for all fonts
0 - 3 up to 3 zero characters, to pad the object to a word boundary

This object type is somewhat special in that only one instance of it ever appears in a Draw file. It has no direct effect on the appearance of the image, but maps font numbers (used in text objects) to textual names of fonts. It must precede all text objects. Comparison of font names is case-insensitive.

In RISC OS 3.5 and earlier, the Draw application expects the font table object to be the first object in the file; we suggest that any Draw files you generate obey this restriction. From RISC OS 3,6 onwards, Draw merely expects that the font table object precedes any text objects or transformed text objects that use it.

Text object
Object type number 1
Size Description
4 text colour
4 text background colour hint
4 text style
4 unsigned nominal x size of the font (in 1/640 point)
4 unsigned nominal y size of the font (in 1/640 point)
8 x, y coordinates of the start of the text base line
n characters in the string, null terminated
0 - 3 up to 3 zero characters, to pad to a word boundary

The character string consists of printing ANSI characters with codes within the ranges 32 - 126 and 128 - 255. This need not be checked during rendering, but other codes may produce undefined or system-dependent results.

The text style word consists of the following:

Bit(s) Description
0 - 7 one byte font number
8 - 31 reserved (must be zero)

Italic, bold variants etc are assumed to be distinct fonts.

The font number is related to the textual name of a font by a preceding font table object within the file (see above). The exception to this is font number 0, which is a system font that is sure to be present. When rendering a Draw file, if a font is not recognised, the system font should be used instead. The system font is monospaced, with the gap between letters equal to the nominal x size of the font.

The background colour hint can be used by font rendition code when performing anti-aliasing. It is referred to as a hint because it has no effect on the rendition of the object on a 'perfect' printer; nevertheless for screen rendition it can improve the appearance of text on coloured backgrounds. The font rendition code can assume that the text appears on a background that matches the background colour hint.

Path object
Object type number 2
Size Description
4 fill colour (-1 => do not fill)
4 outline colour (-1 => no outline)
4 outline width (unsigned)
4 path style description
? optional dash pattern definition
? sequence of path components

An outline width of 0 means draw the thinnest possible outline that the device can represent. A path component consists of:

Size Description
4 1-word tag identifier:
bits 0 - 7 = tag identifier byte:
0 => end of path: no arguments
2 => move to absolute position: followed by one x, y pair
5 => close current sub-path: no arguments
8 => draw to absolute position: followed by one x, y pair
6 => Bezier curve through two control points, to absolute position: followed by three x, y pairs
bits 8 - 31 reserved (must be zero)
n × 8 sequence of n 2-word (x, y) coordinate pairs (where n is zero, one or three, as determined by the value of the tag identifier)

The tag values match the arguments required by the Draw module. This block of memory can be passed directly to the Draw module for rendition; see the chapter entitled Draw module for precise rules concerning the appearance of paths. See also manuals on PostScript. (Reference: PostScript Language Reference Manual. Adobe Systems Incorporated (1990) 2nd ed. Addison-Wesley, Reading, Mass, USA).

The possible set of legal path components in a path object is described as follows. A path consists of a sequence of (at least one) subpaths, followed by an 'end of path' path component. A subpath consists of a 'move to' path component, followed by a sequence of (at least one) 'draw to' and/or 'Bezier to' path components, followed (optionally) by a 'close sub-path' path component.

The path style description word is as follows:

Bit(s) Description
0 - 1 join style:
0 = mitred joins
1 = round joins
2 = bevelled joins
2 - 3 end cap style:
0 = butt caps
1 = round caps
2 = projecting square caps
3 = triangular caps
4 - 5 start cap style (same possible values as end cap style)
6 winding rule:
0 = non-zero
1 = even-odd
7 dash pattern:
0 = dash pattern missing
1 = dash pattern present
8 - 15 reserved (must be zero)
16 - 23 triangle cap width:
a value within 0 - 255, measured in sixteenths of the line width
24 - 31 triangle cap length:
a value within 0 - 255, measured in sixteenths of the line width

The mitre cut-off value is the PostScript default (eg 10). If the dash pattern is present then it is in the following format:

Size Description
4 offset distance into the dash pattern to start
4 number of elements in the dash pattern

followed by, for each element of the dash pattern:

Size Description
4 length of the dash pattern element

The dash pattern is reused cyclically along the length of the path, with the first element being filled, the next a gap, and so on.

Sprite object
Object type number 5

This is followed by a sprite. See the chapter entitled Format of a sprite for details.

This contains a pixelmap image. The image is scaled to entirely fill the bounding box.

If the sprite has a palette then this gives absolute values for the various possible pixels. If the sprite has no palette then colours are defined locally. Within RISC OS the available 'Wimp colours' are used - for further details see the chapter entitled Sprites and the The Window Manager.

Group object
Object type number 6
Size Description
12 group object name, padded with spaces

This is followed by a sequence of other objects.

The objects contained within the group will have rectangles contained entirely within the rectangle of the group. Nested grouped objects are allowed.

The object name has no effect on the rendition of the object. It should consist entirely of printing characters. It may have meaning to specific editors or programs. It should be preserved when copying objects. If no name is intended, twelve space characters should be used.

Tagged object
Object type number 7
Size Description
4 tag identifier

This is followed by an object and optional word-aligned data.

To render a Tagged object, simply render the enclosed object. The identifier and additional data have no effect on the rendition of the object. This allows specific programs to attach meaning to certain objects, while keeping the image renderable.

Programmers wishing to define their own object tags should contact Acorn; see Appendix H: Registering names.

Text area object
Object type number 9
Size Description
? 1 or more text column objects (object type 10, no data - see below)
4 zero, to mark the end of the text columns
4 reserved (must be zero)
4 reserved (must be zero)
4 initial text foreground colour
4 initial text background colour hint
? the body of the text column (ASCII characters, terminated by a null character)
0 - 3 up to 3 zero characters, to pad to a word boundary

A text area contains a number of text columns. The text area has a body of text associated with it, which is partitioned between the columns. If there is just one text column object then its bounding box must be exactly coincident with that of the text area.

The body of the text is paginated in the columns. Effects such as font settings and colour changes are controlled by escape sequences within the body of the text. All escape sequences start with a backslash character (\); the escape code is case sensitive, though any arguments it has are not.

Arguments of variable length are terminated by a '/' or <newline>. Arguments of fixed length are terminated by an optional '/'.

Values with range limits mean that if a value falls outside the range, then the value is truncated to this limit.

Escape sequence Description
\! <version><newline or /> Must appear at the start of the text, and only there. <version> must be 1.
\A<code><optional /> Set alignment. <code> is one of L (left = default), R (right), C (centre), D (double). A change in alignment forces a line break.
\B<R><spaces><G><spaces><B><newline or /> Set text background colour hint to the given RGB intensity (or the best available approximation). Each value is limited to 0 - 255.
\C<R><spaces><G><spaces><B><newline or /> Set text foreground colour to the given RGB intensity (or the best available approximation). Each value is limited to 0 - 255.
\D<number><newline or /> Indicates that the text area is to contain <number> columns. Must appear before any printing text.
\F<digit*><name><spaces><size>[<spaces><width>]<newline or /> Defines a font reference number. <name> is the name of the font, and <size> its height. <width> may be omitted, in which case the font width and height are the same. Font reference numbers may be reassigned. <digit*> is one or two digits. <size> and <width> are in points.
\<digit*><optional /> Selects a font, using the font reference number
\L<leading><newline or /> Define the leading in points from the end of the (output) line in which the \L appears - ie the vertical separation between the bases of characters on separate lines. Default, 10 points.
\M<leftmargin><spaces><rightmargin><newline or /> Defines margins that will be left on either size of the text, from the start of the output line in which the sequence appears. The margins are given in points, and are limited to values > 0. If the sum of the margins is greater than the width of the column, the effects are undefined. Both values default to 1 point.
\P<leading><newline or /> Define the paragraph leading in points, ie the vertical separation between the end of one paragraph and the beginning of a new paragraph. Default, 10 points.
\U<position><spaces><thickness><newline or /> Switch on underlining, at <position> units relative to the character base, and of <thickness> units, where a unit is 1/256 of the current font size. <position> is limited to -128...+127, and <thickness> to 0...255. To turn the underlining off, either give a thickness of 0, or use the command '\U.'
\V[-]<digit><optional /> Vertical move by the specified number of points.
\- Soft hyphen: if a line cannot be split at a space, a hyphen may be inserted at this point instead; otherwise, it has no printing effect.
\<newline> Force line break.
\\ appears as \ on the screen
\;<text><newline> Comment: ignored.

Other escape sequences are flagged as errors during verification.

Lines within a paragraph are split either at a space, or at a soft hyphen, or (if a single word is longer than a line) at any character.

A few other characters have a special interpretation:

  • Control characters are ignored, except for tab, which is replaced by a space.
  • Newlines (that are not part of an escape sequence) are interpreted as follows:

    Occurring before any printing text: a paragraph leading is inserted for each newline.

    In the body of the text: a single newline is replaced by a space, except when it is already followed or preceded by a space or tab. A sequence of n newlines inserts a space of (n-1) times the paragraph leading, except that paragraph leading at the top of a new text column is ignored.

Lines which protrude beyond the limits of the box vertically, eg because the leading is too small, are not displayed; however, any font changes, colour changes, etc. in the text are applied. Characters should not protrude horizontally beyond the limits of the text column, eg owing to italic overhang for this font being greater than the margin setting.

Restrictions

If a chunk of text contains more than 16 colour change sequences, only the last 16 will be rendered correctly. This is a consequence of the size of the colour cache used within the font manager. A chunk in this case means a block of text up to anything that forces a line break, eg the end of a paragraph or a change on the alignment.

Text column object
Object type number 10
    No further data, ie just an object header.

A text column object may only occur within a text area object. Its use is described in the section on text area objects.

Options object
Object type number 11

The object header for an options object has space allocated for a bounding box, but since one would be meaningless, the space is unused. You must treat the 4 words normally used for the bounding box as reserved, and set them to zero.

Size Description
4 (paper size + 1) × &100 (ie &500 for A4)
4 paper limits options:
bit 0 set => paper limits shown
bits 1 - 3 reserved (must be zero)
bit 4 set => landscape orientation (else portrait)
bits 5 - 7 reserved (must be zero)
bit 8 set => printer limits are default
bits 9 - 31 reserved (must be zero)
8 grid spacing (floating point)
4 grid division
4 grid type (zero => RECTANGULAR_ NON-ZERO => isometric)
4 grid auto-adjustment (zero => OFF_ NON-ZERO => on)
4 grid shown (zero => NO_ NON-ZERO => yes)
4 grid locking (zero => OFF_ NON-ZERO => on)
4 grid units (zero => INCHES_ NON-ZERO => centimetres)
4 zoom multiplier (1 - 8)
4 zoom divider (1 - 8)
4 zoom locking (zero => NONE_ NON-ZERO => locked to powers of two)
4 toolbox presence (zero => NO_ NON-ZERO => yes)
4 initial entry mode: one of
bit 0 set => line
bit 1 set => closed line
bit 2 set => curve
bit 3 set => closed curve
bit 4 set => rectangle
bit 5 set => ellipse
bit 6 set => text line
bit 7 set => select
4 undo buffer size, in bytes

When Draw reads a draw file, only the first options object is taken into account - any others are discarded. When it saves a diagram to file, the options in force for that diagram are saved with it.

The Draw application supplied with RISC OS 2 does not use this object type.

Transformed text object
Object type number 12
Size Description
24 transformation matrix
4 font flags:
bit 0 set => text should be kerned
bit 1 set => text written from right to left
bits 2 - 31 reserved (must be zero)
4 text colour
4 text background colour hint
4 text style
4 unsigned nominal x size of the font (in 1/640 point)
4 unsigned nominal y size of the font (in 1/640 point)
8 x, y coordinates of the start of the text base line
n n characters in the string, null terminated
0 - 3 up to 3 zero characters, to pad to a word boundary

The transformation matrix is as described in Font_Paint, in the same format used elsewhere in the Draw module. However, the exception that the translation part of the matrix must be zero.

The remaining fields are exactly as specified for Text objects (see Text object).

The Draw application supplied with RISC OS 2 does not use this object type.

Transformed sprite object
Object type number 13
Size Description
24 Transformation matrix

This is followed by a sprite. See the chapter entitled Format of a sprite for details.

This contains a pixelmap image. The image is transformed from its own coordinates (ie the bottom-left at (0, 0) and the top-right at (w × x_eig, h × y_eig), where (w, h) are the width and height of the sprite in pixels, and (x_eig, y_eig) are the EIG factors for the mode in which it was defined) by the transformation held in the matrix.

If the sprite has a palette then this gives absolute values for the various possible pixels. If the sprite has no palette then colours are defined locally. Within RISC OS the available 'Wimp colours' are used - for further details see the chapter entitled Sprites and the The Window Manager.

The Draw application supplied with RISC OS 2 does not use this object type.

Font files

In all the formats described below, 2-byte quantities are little-endian: that is, the least significant byte comes first, followed by the most-significant. The values are unsigned unless otherwise stated.

Fonts are described in:

  • IntMetrics and IntMetricn files
  • x90y45 files (old style 4-bpp bitmaps)
  • New font file formats.

IntMetrics / IntMetricn files

Header
Size Description
40 name of font, padded with Return characters
4 16
4 16
1 nlo = low byte of number of characters that may be defined
1 version number of file format:
0 flags and nhi must be zero
1 not supported
2 flags supported; n can be > 255
1 flags
bit 0 set => there is no bbox data (use Outlines)
bit 1 set => there is no x-offset data
bit 2 set => there is no y-offset data
bit 3 set => there is more data after the metrics
bit 4 reserved (must be zero)
bit 5 set => character map size precedes map
bit 6 set => kern characters are 16-bit, else 8-bit
bit 7 reserved (must be zero)
1 nhi = high byte of number of characters that may be defined:
n = nhi × 256 + nlo
If flags bit 5 is set:
2 m = character map size
0 => no map

Some of the n character definitions can be blank; the number defines the number of slots available - though not necessarily used - in the character definition tables.

Character mapping
Size Description
m character mapping (ie indices into following tables)
For example, if the 40th byte in this mapping has the value 4, then the fourth entry in each of the following arrays refers to character 40. A zero entry means that character is not defined in this font.
If flags bit 5 is clear, 256 characters are mapped (ie m = 256).

If there is no map (see above), the character code is used to index into the tables.

Note that since the mapping table is 8-bit, there cannot be one if n > 256.

Table of bounding boxes

If flags bit 0 is clear:

Size Description
2n x0 bounding box for each character (16-bit signed)
2n y0 bottom-left (x0, y0) is inclusive
2n x1 top-right (x1, y1) is exclusive
2n y1 coordinates are in 1/1000th em

Coordinates are relative to the 'origin point'.

Tables of character widths

If flags bit 1 is clear:

Size Description
2n x-offset after printing each character, in 1/1000th em (16-bit signed)

If flags bit 2 is clear:

Size Description
2n y-offset after printing each character, in 1/1000th em (16-bit signed)

To calculate the offset to this point in the file, let:

    nlo = byte at offset 48 in file
    version number = byte at offset 49 in file
    flags = byte at offset 50 in file
    nhi = byte at offset 51 in file
    If version number < 2 then flags = 0 (which it should be anyway!)
    n = nhi × 256 + nlo

Then:

    offset = 52
    if (flags bit 5 clear) then offset += 256
    else offset += 2 + byte(52) + 256 × byte(53)
    if (flags bit 0 clear) then offset += 8n
    if (flags bit 1 clear) then offset += 2n
    if (flags bit 2 clear) then offset += 2n
Offsets to extra data areas

If flags bit 3 is set:

Size Description
2 offset to 'miscellaneous' data area
2 offset to kern pair data area
2 offset to reserved data area #1
2 offset to reserved data area #2

The offsets are relative to the start of the table. The entries must be consecutive in the file, so the end of one area coincides with the beginning of the next. The areas are not necessarily word-aligned, and the space at the end of each area is reserved (ie there must not be any 'dead' space at the end of an area).

Miscellaneous data area
Size Description
2 x0 maximum bounding box for font (16-bit signed)
2 y0 bottom-left (x0, y0) is inclusive
2 x1 top-right (x1, y1) is exclusive
2 y1 all coordinates are in 1/1000ths em
2 default x-offset per char (if flags bit 1 is set), in 1/1000th em (16-bit signed)
2 default y-offset per char (if flags bit 2 is set), in 1/1000th em (16-bit signed)
2 italic h-offset per em (-1000 × TAN (italic angle)) (16-bit signed)
1 underline position, in 1/256th em (signed)
1 underline thickness, in 1/256th em (unsigned)
2 CapHeight in 1/1000th em (16-bit signed)
2 XHeight in 1/1000th em (16-bit signed)
2 Descender in 1/1000th em (16-bit signed)
2 Ascender in 1/1000th em (16-bit signed)
4 reserved (must be zero)
Kern pair data

If flags bit 6 is clear, character codes are 8-bit; if flags bit 6 is set, character codes are 16-bit (lo, hi).

Size Description
1 or 2 left-hand character code repeat
1 or 2 right-hand character code repeat
2 x-kern amount (if flags bit 1 is clear) in 1/1000ths em (16-bit signed)
2 y-kern amount (if flags bit 2 is clear) in 1/1000ths em (16-bit signed)
1 or 2 0 => end of list for this letter
1 or 2 0 => end of kern pair data
Reserved data areas #1 and #2

These must be null.

x90y45 font files

If the length of a x90y45 file is less than 256 bytes, then the contents are the name of the f9999x9999 file to use as master bit maps.

Index entries

Each font file starts with a series of 4-word (ie 16 byte) index entries, corresponding to the sizes defined:

Size Description
1 point size, not multiplied by 16
1 bits per pixel (4)
1 pixels per inch in the x-direction
1 pixels per inch in the y-direction
4 reserved (must be zero)
4 offset of pixel data in file
4 size of pixel data
The list is terminated by:
1 0
Pixel data

Pixel data is limited to 64KBytes per block. Each block starts word-aligned relative to the start of the file:

Size Description
4 x-size, in 1/16ths point × x pixels per inch
4 y-size, in 1/16ths point × y pixels per inch
4 pixels per inch in the x-direction
4 pixels per inch in the y-direction
1 x0 maximum bounding box for font
1 y0 bottom-left (x0, y0) is inclusive
1 x1 top-right (x1, y1) is exclusive
1 y1 all coordinates are in pixels
512 2-byte offsets from table start of character data.
A zero value means the character is not defined.
Character data
Size Description
1 x0 bounding box for character
1 y0 bottom-left (x0, y0) is inclusive
1 x1 - x0 = X top-right (x1, y1) is exclusive
1 y1 - y0 = Y all coordinates are in pixels
X × Y / 2 4-bits per pixel (bpp), consecutive rows bottom to top: not aligned until the end
0 - 3.5 alignment

Other font file formats

The new font file formats includes definitions for the following types of font files:

  • f9999x9999 (new style 4-bpp anti-aliased fonts)
  • b9999x9999 (1-bpp bitmaps)
  • Outlines (outline font format, for all sizes)

'9999' = pixel size (ie point size × 16 × dpi / 72) zero-suppressed decimal number.

If the length of an outlines file is less than 256 bytes, then the contents are the name of another font whose glyphs are to be used instead (with this font's metrics).

File header

The file header is of the following form:

Size Description
4 'FONT' - identification word
1 bpp (bits per pixel):
0 => outlines
1 => 1 bpp
4 => 4 bpp
1 version number of file format (changes are cumulative):
4 no 'don't draw skeleton lines unless smaller than this' byte present
5 byte at [table+512] = maximum pixel size for skeleton lines (see below)
6 byte at [chunk + indexsize] = dependency mask (see below)
7 flag word precedes index in chunk (offsets are relative to index, not chunk)
8 file offset array is in a different place
2 If bpp = 0: design size of font
If bpp > 0: flags:
bit 0 set => horizontal subpixel placement
bit 1 set => vertical subpixel placement
bits 2-5 reserved (must be zero)
bit 6 set => FLAG WORD PRECEDES INDEX IN CHUNK (MUST BE SET IF VERSION NUMBER >= 7, else clear).
bit 7 reserved (must be zero)
Outline files derive the value of bit 6 from version number.
2 x0 maximum bounding box for font (16-bit signed)
2 y0 bottom-left (x0, y0) is inclusive
2 x1 - x0 top-right (x1, y1) is exclusive
2 y1 - y0 all coordinates are in pixels or design units

If version number < 8, the number of chunks nchunks = 8, and these bytes end the header:

Size Description
4 file offset of 0...31 chunk (word-aligned)
4 file offset of 32...63 chunk (word-aligned)
20 file offsets of further chunks, in order (word-aligned)
4 file offset of 224...255 chunk (word-aligned)
4 file offset of end (ie size of file)
If offset(n+1)=offset(n), then chunk n is null.

If version number >= 8, these bytes end the header:

Size Description
4 file offset of area containing file offsets of chunks
4 nchunks = number of defined chunks
4 ns = number of scaffold index entries (including entry[0] = size)
4 scaffold flags:
bit 0 set => all scaffold base chars are 16-bit
bit 1 set => these outlines should not be anti-aliased (eg System.Fixed)
bits 2 - 31 reserved (must be zero)
4 × 5 all reserved (must be zero)
Table start
Size Description
2 n = size of table/scaffold data
Table data
Bitmaps

If bpp > 0, the file defines a bitmap, and only the following 8 bytes of table data are used. For such a file, n=10 - other values are reserved.

Size Description
2 x-size (1/16th point)
2 x-resolution (dpi)
2 y-size (1/16th point)
2 y-resolution (dpi)
Outlines

If bpp = 0, the file defines outlines, and the following table data is used. (Files with version number < 8 behave as if ns = 256 and scaffold flags = 0.)

Size Description
ns × 2 - 2 offsets to scaffold data (16-bit):
If scaffold flags bit 0 is clear:
bits 0 - 14 = offset of scaffold data from table start
bit 15 set => base character code is 2 bytes, else 1 byte
If scaffold flags bit 0 is set:
bits 0 - 15 = offset of scaffold data from table start base character code is always 2 bytes
0 => no scaffold data for char
1 skeleton threshold pixel size (if version number >= 5)
When rastering the outlines, skeleton lines will only be drawn if either the x- or the y- pixel size is less than this value (except if value = 0, which means 'always draw skeleton lines').
? ... sets of scaffold data follow, each set of which can include many scaffold lines (see descriptions below)
Scaffold data
Size Description
1 or 2 character code of 'base' scaffold entry (0 => none)
1 bit n set => x-scaffold line n is defined in base character
1 bit n set => y-scaffold line n is defined in base character
1 bit n set => x-scaffold line n is defined locally
1 bit n set => y-scaffold line n is defined locally
... local scaffold lines follow (see description below)
Scaffold lines
Size Description
2 bits 0 - 11 = coordinate in 1/1000ths em (signed)
bits 12 - 14 = scaffold link index (0 => none)
bit 15 set => 'linear' scaffold line
1 width (254 => L-TANGENT_ 255 => R-tangent)
Table end
Size Description
? description of contents of file:
Font name, 0, 'Outlines', 0, '999x999 point at 999x999 dpi', 0
... word-aligned chunk data follows (see description below)

If version number >= 8:

Size Description
4 file offset of chunk 0 (word-aligned)
4 file offset of chunk 1 (word-aligned)
4 × (nchunks-3) file offset of further chunks in order (word-aligned)
4 file offset of chunk (nchunks - 1) (word-aligned)
4 file offset of end (ie size of file)
Chunk data

If version number >= 7:

Size Description
4 flag word:
bit 0 set => horizontal subpixel placement
bit 1 set => vertical subpixel placement
bits 2 - 6 reserved (must be zero)
bit 7 set => dependency byte(s) present (see below)
bits 8 - 30 reserved (must be zero)
bit 31 reserved (must be one)

For all versions there follow nchunks of chunk data in this format:

Size Description
32 offset within chunk to character data
0 => character is not defined
Size is × 4 if vertical placement is used, and × 4 if horizontal placement is used (because the character data is repeated for each of four possible sub-placements). Character index is more tightly bound than vertical placement, which is more tightly bound than horizontal placement.
? dependency bytes (if outline file, and version number >= 6)
One bit required for each chunk in file.
Bit n set => chunk n must be loaded in order to rasterise this chunk. This is required for composite characters which include characters from other chunks (see below).
...character data follows, word-aligned at end of chunk (see description below)

Note: All character definitions must follow the index in the order in which they are specified in the index. This is to allow the font editor to easily determine the size of each character.

Character data
Size Description
1 character flags:
bit 0 set => coordinates are 12-bit, else 8-bit
bit 1 set => data is 1-bpp, else 4-bpp
bit 2 set => initial pixel is black, else white
bit 3 set => data is outline, else bitmap<
If character flags bit 3 is clear:
bits 4 - 7 = 'f' value for char (0 => not encoded)
If character flags bit 3 is set:
bit 4 set => composite base character follows
bit 5 set => composite accent character follows
bit 6 set => character codes within this character are 16-bit, else 8-bit (not yet implemented - must be zero)
bit 7 reserved (must be zero)

if character flags bits 3 is clear, or bit 3 is set and bits 4 and 5 are clear:

Size Description
1 or 2 character code of base character

if character flags bits 3 and 5 are set:

Size Description
1 or 2 character code of accent
2 or 3 x, y offset of accent character

if character flags bits 3 or 4 are clear:

Size Description
1 or 1.5 x0 bounding box for character (8- or 12-bit signed)
1 or 1.5 y0 bottom-left (x0, y0) is inclusive
1 or 1.5 x1 - x0 top-right (x1, y1) is exclusive
1 or 1.5 y1 - y0 all coordinates are in pixels or design units
? data: (depends on type of file)
1-bpp uncrunched: rows from bottom to top
4-bpp uncrunched: rows from bottom to top
1-bpp crunched: list of (packed) run-lengths
outlines: list of move/line/curve segments

Word-aligned at the end of the chunk.

Outline character format

Here the 'pixel bounding box' is actually the bounding box of the outline in terms of the design size of the font (in the file header). The data following the bounding box consists of a series of move/line/curve segments followed by a terminator and an optional extra set of line segments followed by another terminator. When constructing the bitmap from the outlines, the font manager will fill the first set of line segments to half-way through the boundary using an even-odd fill, and will thin-stroke the second set of line segments (if present). For further details see the chapter entitled Draw module.

Each line segment consists of:
Size Description
1 bits 0 - 1 = segment type:
0 terminator (see description below)
1 move to x, y
2 line to x, y
3 curve to x1, y1, x2, y2, x3, y3
bits 2 - 4 = x-scaffold link
bits 5 - 7 = y-scaffold link
? coordinates in design units
Terminator:
Size Description
1 bit 2 set => stroke paths follow (same format, but paths are not closed)
bit 3 set => composite character inclusions follow:
Composite character inclusions:
1 or 2 character code of character to include (0 => finished)
2/3 x, y offset of this inclusion (design units)

The coordinates are either 8- or 12-bit sign-extended, depending on bit 0 of the character flags (see above), including the composite character inclusions.

The scaffold links associated with each line segment relate to the last point specified in the definition of that move/line/curve, and the control points of a Bezier curve have the same links as their nearest endpoint.

Note that if a character includes another, the appropriate bit in the parent character's chunk dependency flags must be set. This byte tells the Font Manager which extra chunk(s) must be loaded in order to rasterise the parent character's chunk.

1-bpp uncompacted format

1 bit per pixel, bit set => paint in foreground colour, in rows from bottom-left to top-right, not aligned until word-aligned at the end of the character.

1-bpp compacted format

The whole character is initially treated as a stream of bits, as for the uncompacted form. The bit stream is then scanned row by row: consecutive duplicate rows are replaced by a 'repeat count', and alternate runs of black and white pixels are noted. The repeat counts and run counts are then themselves encoded in a set of 4-bit entries.

Bit 2 of the character flags determines whether the initial pixel is black or white (black = foreground), and bits 4 - 7 are the value of 'f' (see below). The character is then represented as a series of packed numbers, which represent the length of the next run of pixels. These runs can span more than one row, and after each run the pixel colour is changed over. Special values are used to denote row repeats.

File Meaning
n nibbles, value 0 run length = next_n+1_nibbles + (13-f) × 16 + f+1 - 16
1 nibble, value 1...f run length = this_nibble
1 nibble, value f+1...13 run length = next_nibble + (this_nibble-f-1) × 16 + f+1
1 nibble, value 14 row repeat count = next_packed_number
1 nibble, value 15 row repeat count = 1

where:

  • this_nibble is the actual value (1...f, or f+1...13) of the nibble
  • next_nibble is the actual value (0...15) of the nibble following this_nibble
  • next_n+1_nibbles is the actual value (0...24(n+1) - 1) of the next n+1 nibbles after the n zero nibbles
  • next_packed_number is the value of the packed number following the nibble of value 14.

The optimal value of f lies between 1 and 12, and must be computed individually for each character, by scanning the data and calculating the length of the output for each possible value. The value yielding the shortest result is then used, unless that is larger than the bitmap itself, in which case the bitmap is used.

Repeat counts operate on the current row, as understood by the unpacking algorithm, ie at the end of the row the repeat count is used to duplicate the row as many times as necessary. This effectively means that the repeat count applies to the row containing the first pixel of the next run to start up.

Note that rows consisting of entirely white or entirely black pixels cannot always be represented by using repeat counts, since the run may span more than one row, so a long run count is used instead.

Encoding files

An encoding file is a text file which contains a set of identifiers which indicate which characters appear in which positions in a font. Each identifier is preceded by a '/', and the characters are numbered from 0, increasing by 1 with each identifier found.

Comments are introduced by '%', and continue until the next control character.

The following special comment lines are understood by the font manager:

%%RISCOS_BasedOn base_encoding
%%RISCOS_Alphabet alphabet

where base_encoding and alphabet denote positive decimal integers.

Both lines are optional, and they indicate respectively the number of the base encoding and the alphabet number of this encoding.

If the %%RISCOS_BasedOn line is not present, then the Font Manager assumes that the target encoding describes the actual positions of the glyphs in an existing file, the data for which is in:

font_directory.IntMetricsalphabet
font_directory.Outlinesalphabet

where alphabet is null if the %%RISCOS_Alphabet line is omitted.

(In fact the leafnames are shortened to fit in 10 characters, by removing characters from just before the alphabet suffix).

In this case the IntMetrics and Outlines files are used directly, since there is a one-to-one correspondence between the positions of the characters in the datafiles and the positions required in the font.

If the %%RISCOS_BasedOn line is present, then the Font Manager accesses the following datafiles:

font_directory.IntMetricsbase_encoding
font_directory.Outlinesbase_encoding

and assumes that the positions of the glyphs in the datafiles are as given by the contents of the base encoding file.

The base encoding is called '/Basen', and lives in the Encodings directory under Font$Path, along with all the other encodings. Because it is preceded by a '/', the Font Manager does not return it in the list of encodings returned by Font_ListFonts.

Note that only one encoding file with a given name can apply to all the fonts known to the system. Because of this, a given encoding can only be either a direct encoding, where the alphabet number is used to reference the datafiles, or an indirect encoding, where the base encoding number specifies the datafile names.

Here is the start of a sample base encoding ('/Base0'):

% /Base0 encoding
%%RISCOS_Alphabet 0
/.notdef /.NotDef /.NotDef /.NotDef
/zero /one /two /three /four /five /six /seven /eight

Here is the start of a sample encoding file ('Latin1'):

% Latin 1 encoding
%%RISCOS_BasedOn 0
%%RISCOS_Alphabet 101
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/space /exclam /quotedbl /numbersign
/dollar /percent /ampersand /quotesingle

(Note that the sample /Base0 file is not the same as the released one).

These illustrate several points:

  • The %% lines must appear before the first identifier.
  • Character 0 in any encoding must be called '.notdef', and represent a null character.
  • Other null characters in the base encoding must be called '.NotDef', to distinguish them from character 0.
  • Non-base encoding files wanting to refer to the null character should use '.notdef' in all cases.
  • The other character names should follow the Adobe PostScript names wherever possible. (See PostScript Language Reference Manual. Adobe Systems Incorporated (1990) 2nd ed. Addison-Wesley, Reading, Mass, USA.) This is to enable the encoding to refer to Adobe character names when included as part of a print job by the PostScript printer driver.
  • The number of characters described by the base encoding can be anything from 0 to 768, and should refer to distinct characters (apart from the '.NotDef's). Other encodings, however, must contain exactly 256 characters, which need not be distinct.

Font Messages files

The format of font Messages files is the same as that of ordinary message files, as documented in the MessageTrans, with those exceptions detailed below.

The valid tokens are:

Encoding_ encoding (based on a base encoding)
BEncoding_ base encoding (eg Base0)
Font_ font which doesn't vary with alphabet (eg Symbol font)
LFont_ font which does vary with alphabet (a 'language' font)

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

The values of the encoding tokens should normally be null, but you must define them for all encodings within the directory holding the Messages file if you want to use a font that references them. Also, you must not prefix the base encoding id with '/' even though its filename is '/Basen'. This is because the '/' in the filename is only used by Font_ListFonts when it is scanning a font directory to determine base encodings from encodings.

Identifiers should use characters in the range &20 - &7E, to aid in international portability. However, the font names should use the alphabet of the relevant territory, as determined by the country number on the end of the message file name.

Within a font name, the following characters are special:
. The first dot encountered causes the font to be split over two menu levels. Subsequent dots do not cause further submenu splitting.
* An asterisk as the last character of a font name is not treated as part of the name, but marks this font as being the default for that family. Clicking on the menu entry for the font family will select the default weight and/or style for the family, even though the font weights and styles are in a subdirectory. This is normally fontfamily.Medium, but there are other examples (eg Selwyn).

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

For example, a 'Messages1' file for the ROM fonts might be:

BEncoding_Base0:
Encoding_Latin1:
Encoding_Latin2:
Encoding_Latin3:
Encoding_Latin4:
LFont_Corpus.Bold:
LFont_Corpus.Bold.Oblique:
LFont_Corpus.Medium:*
LFont_Corpus.Medium.Oblique:
LFont_Homerton.Bold:Helvetica bold
LFont_Homerton.Bold.Oblique:Helvetica bold oblique
LFont_Homerton.Medium:Helvetica*
LFont_Homerton.Medium.Oblique:Helvetica oblique
LFont_Trinity.Bold:
LFont_Trinity.Bold.Italic:
LFont_Trinity.Medium:*
LFont_Trinity.Medium.Italic:

This aliases the Homerton font family so that users see it named 'Helvetica', and sets the default font in each family to the one of 'Medium' weight.

Music files

Header
Size Description
8 'Maestro' followed by linefeed (&0A)
1 2 (type 2 music file)

This is followed by zero or more of the following blocks in any order. It is terminated by the end of the file. Note that types 7 to 9 are not implemented in Maestro, but are described for any extensions or other music programs that may be written.

Music data
Size Description
1 1 indicates Music data follows
5 n = number of bytes in the 'Gates' array (stored as a BASIC integer - ie &40 followed by four bytes of data, most significant first).
5 × 8 q1...q8 = number of bytes in queue of notes and rests for each of the 8 channels 1...8 (stored as BASIC integers - ie &40 followed by four bytes of data, most significant first).
n gate data (see Gates)
For c = 1 to 8 (ie for each channel in turn)
[SUMATION]q1...q8
Next c
Stave data
Size Description
1 2 indicates Stave data follows
1 number of music staves - 1 (0 - 3)
1 number of percussion staves (0 - 1)

Which channels are used by which staves depends on the number of music staves and the number of percussion staves as follows:

Music staves Percussion staves Stave 1 Stave 2 Stave 3 Stave 4 Percussion
1 0 1 - 8
1 1 1 - 7 8
2 0 1 - 4 5 - 8
2 1 1 - 4 5 - 7 8
3 0 1 2 - 5 6 - 8
3 1 1 2 - 5 6, 7 8
4 0 1, 2 3, 4 5, 6 7, 8
4 1 1, 2 3, 4 5, 6 7 8
Instrument data

Instrument names are not recorded; only channel numbers.

Size Description
1 3 indicates Instrument data follows

This is followed by 8 blocks of 2 bytes each:

Size Description
1 channel number (always consecutive 1 - 8)
1 voice number: 0 => no voice attached
Volume data
Size Description
1 4 indicates Volume data follows
1 × 8 volume on each channel (0 - 7 = ppp - fff); one byte for  each channel
Stereo position data
Size Description
1 5 indicates Stereo data follows
1 × 8 stereo position of channel (0 - 6 = full left - full right); one byte for each channel
Tempo data
Size Description
1 6 indicates Tempo data follows
1 0 - 14, which corresponds to one of: 40, 50, 60, 65, 70, 80, 90, 100, 115, 130, 145, 160, 175, 190, or 210 beats per minute

To convert to values to program into SWI Sound_QTempo, use the formula:

    Sound_QTempo value = beats per minute × 128 × 4096 / 6000

Title string
Size Description
1 7 indicates title string follows
n null terminated string of n characters total length
Instrument names
Size Description
1 8 indicates Instrument names follow
[SUMATION]n1...n8 8 null terminated strings for each voice number used in ascending order in command 3 above.
MIDI channels
Size Description
1 9 indicates MIDI channel numbers follow
1 × 8 MIDI channel number on this stave (0 => not transmitted over MIDI, else 1 - 16); one byte for each channel

Gates

A Gate is a point in the music where something is interpreted: eg a note, time signature, key signature, bar line or clef can each occupy a gate. The gate data is one byte for a note or rest, or 2 bytes for an attribute such as a time signature, key signature, bar line, clef, etc.

Note or rest

A note or rest is represented by a single non-zero byte.

Bit(s) Description
0 - 7 Gate mask: bit n set => gate 1 note or rest from queue n.
Attribute

An attribute is represented by a null byte (so that it can be distinguished from a note or rest), followed by a byte describing the attribute.

Byte Description
0 0
1 one of the following forms:
Time signature
Bit(s) Description
0 1
1 - 4 number of beats per bar - 1 (0 - 15)
5 - 7 beat type (0 = breve, to 7 = hemidemisemiquaver)
Key signature
Bit(s) Description
0 - 1 10 binary (ie bit 1 set)
2 type of accidental (0 = sharp, 1 = flat)
3 - 5 number of accidentals in key signature (0 - 7)
6 - 7 reserved (must be zero)
Clef
Bit(s) Description
0 - 2 100 binary (ie bit 2 set)
3 - 4 0 = treble, 1 = alto, 2 = tenor, 3 = bass
5 reserved (must be zero)
6 - 7 stave - 1 (0 - 3)
Slur
Bit(s) Description
0 - 3 1000 binary (ie bit 3 set)
4 1 = on, 0 = off
5 reserved (must be zero)
6 - 7 stave - 1 (0 - 3)
Octave shift
Bit(s) Description
0 - 4 10000 binary (ie bit 4 set)
5 0 = up, 1 = down
6 - 7 stave - 1 (0 - 3)
Bar
Bit(s) Description
0 - 5 100000 binary (ie bit 5 set)
6 - 7 reserved (must be zero)
Reserved for future expansion
Bit(s) Description
0 - 6 1000000 binary (ie bit 6 set)
0 - 7 10000000 binary (ie bit 7 set)

Notes and rests

Notes and rests are each stored in a 2 byte block that has some common elements.

Notes
Bit(s) Description
0 stem orientation (0 = up, 1 = down)
1 1 => join beams (barbs) to next note
2 1 => tie with next note
3 - 7 stave line position (1 - 31, 16 = centre line)
8 - 10 accidental:
0 = no accidental
1 = natural
2 = sharp
3 = flat
4 = double-sharp
5 = double-flat
6 = natural sharp
7 = natural flat
11 - 12 number of dots (0 - 3)
13 - 15 type (0 = breve, to 7 = hemidemisemiquaver)
Rests
Bits Description
0 - 10 reserved (set to zero)
11 - 12 number of dots (0 - 3)
13 - 15 type (0 = breve, to 7 = hemidemisemiquaver)

If a rest coincides with a note, its position is determined by the following note on the same channel.

Squash files

Squash files are generated by the !Squash application, which in turn uses the Squash module.

Squash files consist of a small fixed size header put in by !Squash, followed by compressed data produced by the Squash module. The header has the following format:

typedef struct
{
        char id[4];          /* Should be "SQSH" */
        unsigned int length;
        unsigned int load;
        unsigned int exec;
        int reserved;        /* Should be zero */
}
squash_header;

The length, load and exec are the file length, load address and execution address of the original file before it was compressed (although the load and exec typically hold the filetype and date/time stamp). If the id is not SQSH, then the rest of the file is not in the same format.

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015