home *** CD-ROM | disk | FTP | other *** search
- > Fonts.Formats
-
- Font File Formats
- -----------------
-
- 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.
-
-
- IntMetrics / IntMet<n>:
-
- 40 Name of font, padded with <cr>
- 4 16
- 4 16
- 1 nlo = low-byte of number of defined characters
- 1 version number of file format:
- 0 flags and nhi must be 0
- 1 **** not supported ****
- 2 you can set the flags as described
- and nchars 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 0)
- bit 5 set => character map size precedes map
- bit 6 set => kern characters are 16-bit, else 8-bit
- bit 7 reserved (must be 0)
- 1 nhi = high byte of number of defined characters
-
- n = nlo + 256*nhi
-
- If flags bit 5 set:
- 2 m = character map size (lo,hi) (0 => no map)
- m = 256 if flags bit 5 clear
-
- m character mapping (ie. indices into following arrays)
- if not present, index = character code
-
- Note that since the mapping table is 8-bit, there cannot be
- one if n > 256.
-
- Tables giving bounding boxes (1/1000th em) of characters:
- If flags bit 0 clear:
- 2n signed x0 2-byte values
- 2n signed y0 2-byte values
- 2n signed x1 2-byte values
- 2n signed y1 2-byte values
-
- Tables of character widths:
- If flags bit 1 clear:
- 2n signed 2-byte x-offsets after printing each character
- If flags bit 2 clear:
- 2n signed 2-byte y-offsets after printing each character
-
-
- To calculate offset to here:
-
- nlo = byte at offset 48 in file
- nhi = byte at offset 51 in file
- flags = byte at offset 49 in file
- n = nlo + 256*nhi ^^->Acorn, you mean 50 me thinks....
-
- 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
-
- If flags bit 3 set:
-
- 8 table of 4 2-byte unsigned offsets from start of table:
- entry 0 = offset to 'miscellaneous' data
- entry 1 = offset to kern pair data
- entry 2 = offset to reserved area #1
- entry 3 = offset to reserved area #2
-
- 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).
-
- Area 0: Miscellaneous data:
-
- 8 font bounding box in 1/1000th em (signed x0,y0,x1,y1)
- 2 default x-offset per char (if flags bit 1 set)
- 2 default y-offset per char (if flags bit 2 set)
- 2 italic h-offset per em (-1000 * TAN(italic angle))
- 1 underline position (signed, in 1/256th of an em)
- 1 underline thickness (unsigned, in 1/256th of an em)
- 2 CapHeight (1/1000th em, 2-byte signed)
- 2 XHeight (1/1000th em, 2-byte signed)
- 2 Descender (1/1000th em, 2-byte signed)
- 2 Ascender (1/1000th em, 2-byte signed)
- 4 reserved field (must be 0)
-
- Area 1: Kern pair data:
-
- flags bit 6 clr => character codes are 8-bit
- flags bit 6 set => character codes are 16-bit (lo,hi)
-
- 1 or 2 left-hand letter code ]
- 1 or 2 right-hand letter code ] ]
- 2 x-kern amount (if flags bit 1 clear) ] repeat ] repeat
- 2 y-kern amount (if flags bit 2 clear) ] ]
- 1 or 2 0 => end of list for this letter ]
- 1 or 2 0 => end of kerns
-
- Or, in pseudo-Backus-Naur notation:
-
- <kerns> ::= <kernsforaletter>* <letter 0>
- <kernsforaletter> ::= <letter> <kernpair>* <letter 0>
- <kernpair> ::= <letter> <x-offset> <y-offset>
- <letter> ::= <8-bit character code> if flags bit 6 clear
- or <16-bit character code> if flags bit 6 set
- <x-offset> ::= <signed 16-bit offset in 1/1000 em>
- or <null> if flags bit 1 set
- <y-offset> ::= <signed 16-bit offset in 1/1000 em>
- or <null> if flags bit 2 set
- <letter 0> ::= <<letter> with code 0>
-
- Area 2: Reserved (must be null)
-
- Area 3: Reserved (must be null)
-
-
- x90y45:
-
- Index:
- 1 point size (not multiplied by 16)
- 1 bits per pixel (4)
- 1 pixels per inch (x-direction)
- 1 pixels per inch (y-direction)
- 4 reserved (was checksum) - must be 0
- 4 offset of pixel data in file
- 4 size of pixel data
- ... more of the same
- 1 0
-
- Pixel data:
- 4 x-size in 1/16ths point * pixels per inch (x)
- 4 y-size in 1/16ths point * pixels per inch (y)
- 4 pixels per inch (x-direction)
- 4 pixels per inch (y-direction)
- 1 x0 - maximum bounding box for any character
- 1 y0 - bottom-left is inclusive
- 1 x1 - top-right is exclusive
- 1 y1 - all coordinates are in pixels
- 512 2-byte offsets from table start of character data
- 0 => character is not defined
- (pixel data is limited to 64K per block)
-
- Character data:
-
- 1 x0 - bounding box
- 1 y0
- 1 x1-x0
- 1 y1-y0
- 4*n 4-bpp, consecutive rows bottom->top
- not aligned until the end
-
-
- Outlines / Outlines<n> / f9999x9999 / b9999x9999:
-
- b9999x9999 1-bpp definition
- a9999x9999 4-bpp (anti-aliased) definition
- Outlines the outline file
-
- '9999' = pixel size (ie. point size * 16 * dpi / 72)
- zero-suppressed decimal number
-
- File header:
- 4 "FONT" - identification word
- 1 Bits per pixel: 0 = outlines
- 1 = 1 bpp
- 4 = 4 bpp
- 1 Version number of file format
- 4: no "don't draw skeleton lines unless smaller than this" byte present
- 5: byte at [table+512] = max pixel size for skeleton lines (0 => always do it)
- 6: byte at [chunk+indexsize] = dependency mask (see below)
- 7: flag word precedes index in chunk (offsets are rel. 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
- bit 6 set => flag word precedes index in chunk (version 7 onwards)
- bits 2..5, 7 must be 0
- NB: for outline files, bit 6 is derived from the version number
- but if present, its value must suit the version number
- 2 x0 - font bounding box (16-bit signed)
- 2 y0 - units are pixels or design units
- 2 x1-x0 - x0,y0 inclusive, x1,y1 exclusive
- 2 y1-y0
-
- If Version < 8: nchunks = 8
-
- 4 file offset of 0..31 chunk (word-aligned)
- 4 file offset of 32..63 chunk
- ...
- 4 file offset of 224..255 chunk
- 4 file offset of end (ie. size of file)
- if offset(n+1)=offset(n), then chunk n is null.
-
- Else (Version >= 8): nchunks = as defined below
-
- 4 file offset of area containing file offsets of chunks
- 4 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)
- bit 2 set => fill using non-zero winding rule, else odd-even.
- bits 3..31 reserved (must be 0)
- 4*5 all reserved (must be 0)
-
- Table start:
- 2 n = size of table/scaffold data
-
- Bitmaps: (n=10 normally - other values are reserved)
- 2 x-size (1/16th point)
- 2 x-res (dpi)
- 2 y-size (1/16th point)
- 2 y-res (dpi)
-
- Outlines:
- ns*2-2 2-byte offsets to scaffold data:
-
- If scaffold flags bit 0 clear:
- bits 0..14 = offset of scaffold data from table start
- bit 15 set => base char code is 2 bytes, else 1
-
- If scaffold flags bit 0 set:
- bits 0..15 = offset of scaffold data from table start
- base char code is always 2 bytes
-
- 0 => no scaffold data for char
-
- 1 Skeleton threshold pixel size
- (if file format version >= 5)
- When rastering the outlines, skeleton lines will
- only be drawn if either the x-or y- pixel size is
- less than this value (except if value=0, which means
- 'always draw skeleton lines').
- ? ... sets of scaffold data (see below)
-
- Table end: ? description of contents of file:
- <Font name>, 0, "Outlines", 0
- "999x999 point at 999x999 dpi", 0
- padded with zeros until word-aligned
-
- If Version >= 8:
-
- 4 file offset of chunk 0
- 4 file offset of chunk 1
- ...
- 4 file offset of chunk (nchunks-1)
- 4 file offset of end of file
-
- All versions:
-
- ... word-aligned chunks follow
-
- Scaffold data:
- 1 or 2 char code of 'base' scaffold entry (0 ==> none)
- 1 bit n set ==> x-scaffold line n defined in base char
- 1 bit n set ==> y-scaffold line n defined in base char
- 1 bit n set ==> x-scaffold line n defined locally
- 1 bit n set ==> y-scaffold line n defined locally
- ... local scaffold lines follow
- Scaffold lines:
- 2 bits 0..11 = coordinate (signed)
- bits 12..14 = scaffold link index (0 => none)
- bit 15 set => 'linear' scaffold link
- 1 width (254 ==> L-tangent, 255 ==> R-tangent)
-
- Chunk data:
- 4 flag word (not present before file format version 7):
- bit 0 set => horizontal subpixel placement
- bit 1 set => vertical subpixel placement
- bit 7 set => dependency byte(s) present (see below)
- bits 2..6 and 8..30 must be 0
- bit 31 must be 1
-
- 4 * 32 offset from index start to character
- 0 => character is not defined
- * 4 for vertical placement
- * 4 for horizontal placement
- Character index is more tightly bound than vertical
- placement which is more tightly bound than
- horizontal placement.
-
- n Dependency byte(s) (if outline file, version >= 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)
-
- 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.
-
- Char data:
- 1 flags:
- bit 0 set => coords 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 bit 3 clr: bits 4..7 = 'f' value for char (0 ==> not encoded)
- if bit 3 set: bit 4 set => composite character
- bit 5 set => with an accent as well
- bit 6 set => ascii codes within this char are 16-bit, else 8-bit
- bit 7 reserved (must be 0)
-
- if flag bits 3 and 4 set:
- 1 or 2 character code of base character
- if flag bit 5 set:
- 1 or 2 character code of accent
- 2 or 3 x,y offset of accent character
-
- if flag bits 3 or 4 clear:
- 2 or 3 x0, y0 sign-extended 8- or 12- bit coordinates
- 2 or 3 xs, ys width, height (bbox = x0,y0,x0+xs,y0+ys)
- n data: (depends on type of file)
- 1-bpp uncrunched: rows from bottom->top
- 4-bpp uncrunched: rows from bottom->top
- 1-bpp crunched: list of (packed) run-lengths
- outlines: list of move/line/curve segments
- word-aligned at the end of the character data
-
- Outline char 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). See the documentation on the Draw module for
- further details.
-
- If the font is version 8 or greater then it can specifiy that the winding
- rule be either non-zero or odd-even, this is to provide compatibility with
- other type face formats (see above in scaffold flags).
-
- Each line segment consists of:
-
- 1 bits 0..1 = segment type:
- 0 => terminator (see 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 (design units) follow
-
- Terminator:
- 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 or 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 character codes in the composite character sections are either 8- or
- 16-bit (low-byte first), depending on bit 6 of the character flags.
-
- 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 data 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, with
- consecutive duplicate rows being 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 determine 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.
-
- <packed number> ==
- 0 followed by n-1 zeroes, followed by n+1 nibbles
- = resulting number + (13-f)*16 + f+1 - 16
- i = 1 .. f i
- i = f+1 .. 13 (i-f-1)*16 + next nibble + f + 1
- 14 followed by n=<packed number> = repeat count of n
- 15 repeat count of 1 (ie. 1 extra copy of this row)
-
- 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 <baseencoding>
- %%RISCOS_Alphabet <alphabet>
-
- where <baseencoding> 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>.IntMetrics<alphabet>
- <font directory>.Outlines<alphabet>
-
- 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>.IntMetrics<baseencoding>
- <font directory>.Outlines<baseencoding>
-
- 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 "/Base<n>", 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:
-
- 1. The %% lines must appear before the first identifier.
-
- 2. Character 0 in any encoding must be called ".notdef", and represent
- a null character.
-
- 3. Other null characters in the base encoding must be called ".NotDef",
- to distinguish them from character 0.
-
- 4. Non-base encoding files wanting to refer to the null character
- should use ".notdef" in all cases.
-
- 5. The other character names should follow the Adobe PostScript names
- wherever possible. 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.
-
- 6. The number of characters desribed 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.
-