Page Numbers: Yes X: 530 Y: 10.5" First Page: 1 Not-on-first-page
Columns: 1 Edge Margin: .6" Between Columns: .4"
Margins: Top: 1.3" Bottom: 1"
Line Numbers: No Modulus: 5 Page-relative
Heading: Not-on-first-page
Font Representations and Formats
c Xerox Corporation 1980
XEROX
PALO ALTO RESEARCH CENTER
Computer Sciences Laboratory
October 1, 1980
To:File
From:Bob Sproull (revised by Dan Swinehart and Lyle Ramshaw)
Subject:Font Representations and Formats
Filed on:<PrintingDocs>FontFormats.Press
Sources:<PrintingDocs>FontFormatsA.Bravo and
<PrintingDocs>FontFormatsB.Bravo
This report presents the various standard and device-dependent font formats in use at PARC.
1. Introduction
A font is a collection of character descriptions, indexed by a character code. These descriptions represent, in one fashion or another, the appearance of the character. The ultimate purpose of maintaining a font is for use when generating a raster-scanned image of a document. This image may be created on a display and used for interactive purposes, or it may be generated by a printing service as part of a "hard copy" function. In both cases, for purposes of space and device independence, the document itself does not normally contain the character representations, but only codes used to identify the characters that comprise the document.
It is important to distinguish font representations from font formats.
We use two generically different representations for character shapes. The first, loosely termed "splines" or "spline fonts," represents the outline of the each character shape with a series of parametric cubic spline curves (see Figure 1). This representation is handy because it is independent of the particular output device and its resolution: the outlines describe the desired appearance of the character. The second representation we use is a raster (sometimes loosely termed a "bit map"), as shown in Figure 2. This representation records, in some way, a two-dimensional (binary) occupancy map: it tells where the character lies on a two-dimensional grid. This representation is handy for actually building raster images of documents: the occupancy map is combined with color information, often at very high speed, to generate a larger raster image of the document. The raster character description is in effect merged into the page raster at the proper position.
When characters are recorded in font files, we choose a particular format for the file; quite a number of different formats have emerged. This is because there are many ways to encode digitally the information in either an outline or raster representation of a character. The details of the encoding are often of vital concern when making a particular piece of hardware or software generate page rasters rapidly.
Fortunately, we can write conversion programs that are able to generate the various specialized formats from standard formats. When an artist (or a needy user) devotes a large amount of effort to designing and debugging a font, it should be recorded and disseminated in one of the standard formats. Clients can then easily convert to one of the subsidiary formats, or to their own private format.
Widths
An important adjunct to the font descriptions themselves is the "widths file," which summarizes the dimensions of all characters in the font data base. This summary must be available to a text editor when it formats a document for hard copy: the widths are used to determine how many characters will fit on a line and to perform justification calculations. Because the information in this file can be independent of any particular output device, the hard-copy file produced by the editor can be printed on any of a number of printing devices. The widths summary is, in effect, extracted from information recorded in the standard formats of the relevant fonts.
There are several different flavors of width files now in existence. Some of them contain widths that can be scaled to handle different sizes of a font; others apply to only one size. Some width files give the height and depth dimensions of the design box of each character separately, where others give only the font bounding box and the individual widths. The type of width file that gives each character’s design box is used by the TEX document compiler, and is not discussed in detail in this memo.
Software
The PARC font descriptions are supported by a reasonably full set of software:
FRED: Interactive program for building outline font representations. Documentation is on <PrintingDocs>Fred.Press. The program is on <ALTO>Fred.Dm.
PREPRESS: Interactive program for building standard raster font representations. The program also contains numerous options for converting from standard to subsidiary formats. Documentation is on <Altodocs>PrePress.Press. The program is on <ALTO>PrePress.Run.
COMPRESS (Obsolete): A program that converts .CU format to EARS (.EP and .EL) formats. The program is on <EARS>Compress.Run.
The reader is invited to consult PrePress documentation (<Altodocs>PrePress.Press) for miscellaneous lore relating to fonts and for "standard operating procedures" for maintaining font files.
People
This document is simply a convenient summary of formats and techniques developed by a large number of individuals. The people behind the formats include Patrick Baudelaire, Peter Deutsch, Joe Maleson, Diana Merry, Ron Rider, Bob Sproull, Dan Swinehart, Larry Tesler, and Chuck Thacker.
2. Terminology
The terminology that has developed around fonts is hopelessly inconsistent. This section is intended to serve as a glossary for the descriptions in the remainder of this document. Be forewarned that terminology used elsewhere may not match.
2.1 Characters
Family is the term given to a particular design of characters. Examples of families are "TimesRoman", or "Helvetica".
Point size of a character refers to size measurements used in the printing industry. If text is n points high, this means that closely-spaced lines of text will fall n/72 inches apart on the page. Note that the point size does not relate in any consistent way to the geometry of characters, e.g., to the height of an upper case A.
Face denotes a number of attributes of a particular font: italic, bold, light, condensed, expanded are all attributes of the font. Sometimes this is called a "style." Sometimes the face is defined with a three-letter code: the first letter is L for light, M for medium, or B for bold; the second is R for regular or I for italic; the third is C for condensed, R for regular or E for expanded. An optional fourth character can be used to specify the character coding used in the font: X for Xerox-style, A for ASCII, and O for other.
Rotation refers to the orientation of the character. If a string of characters is intended to be horizontal, it has rotation zero; if a string runs vertically upward, it has a rotation of 90 degrees.
Font, as we use the term, refers to a collection of characters of the same family, the same size, the same rotation, and the same face attributes.
Character code refers to a number (usually only 8 bits) that identifies a character. All our fonts use an approximation to the standard ASCII convention, when that convention is meaningful. For special-character fonts (e.g., mathematics, logic design), another mapping must generally be devised.
Origin of a character (sometimes called "the (0,0) point") is conceptually a reference mark that is used to describe a character’s location on a page or display. Thus a directive to "display an A at x=103, y=204" is interpreted to mean "place an instance of the symbol A on the display so that the character origin coincides with the coordinate x=103, y=204." Figures 1 and 2 show the origin of a sample character. Note that the origin is located midway between pixels in each dimension, not in the center of a pixel.
Width of a character is a two-dimensional vector that represents the incremental translation that should take place to determine the placement of the origin of the next character to be displayed in a (conventionally aligned) string of characters. In the example of Figure 3, if we assume the x direction points to the right and the y direction up, we see that the width vector has a zero y component. In this document, we will refer to the components of the width vector as Wx and Wy.
In all our font representations, we associate the width vector with each character code. If this width vector is used for character positioning, the spacing between the origin of a A (say) and the origin of the next character is independent of that next character. This is not always desirable: because of the different shapes of characters, spacing between differing pairs may want to be adjusted slightly to make the text line appear more pleasing.
An empty character is one with an empty occupancy map; in particular, an empty character is some flavor of space.
Bounding box is the term for a rectangle that just barely surrounds the character (see Figure 3). It is characterized by its width and height, and by a two-dimensional vector that specifies where the lower-left corner of the bounding box is with respect to the origin of the character inside. These four numbers are named (in this document) BBdx, BBdy, BBox, and BBoy.
An empty character, by convention, has both BBdx and BBdy equal to zero. BBox and BBoy make even less sense for an empty character; they are often set to zero as well.
The font bounding box is a bounding box that applies to all characters in the font. That is, if all the characters in the font were placed with their origins coincident, the smallest rectangle that encloses every part is the font bounding box. The four parameters of the font bounding box are named (in this document) FBBdx, FBBdy, FBBox, and FBBoy
The coordinate system assumed for this document is that x points to the right on a (portrait-oriented) page, and y points up. A mica is a unit of measure, equal to 10 microns or 1/2540 inch. Both of these conventions are identical to those used by Press.
Scanning mode refers to the way a raster is laid upon a character description. This in effect defines a coordinate system in which one direction is measured in scan-lines and the other direction is measured in bits (along a scan line). To describe the modes, we use a single number that relates the scanning regime to the conventional (x,y) coordinate system: the mode is bit-direction-description*4 + scan-line-direction-description, where a direction-description is:
0 if the coordinate increases as x increases
1 if the coordinate decreases as x increases
2 if the coordinate increases as y increases
3 if the coordinate decreases as y increases
This convention is identical to the one used by Press and AIS. We use it in this document to characterize character encodings: if a raster is encoded in mode 8, then the first bit of the bit stream defining the character will be at the lower left-hand corner of the character; the next bit will be just above the first, and so on up the page (because the bit-direction-description is 2); then the next scan-line to the right will be given (because the scan-line-direction-description is 0).
Note that there is a relation between rotation and scanning mode. For example, a character encoded with rotation=0, scanning mode=3 is identical to one recorded with rotation=90 degrees, scanning mode=8.
2.2 File terminology
A file is a homogeneous sequence of data bits. (We at PARC do not have any file systems that have the concept of "record" as implemented in XDS and IBM operating systems. We view a file as an unbroken sequence of data.)
A word is 16 bits, a byte is 8 bits. If these are to interpreted as signed integers, the representation is two’s complement.
Several files use the concept of self-relative pointers. The idea is that the pointer specifies a file position relative to the file position of the pointer itself. The following example may help clarify the notion of self-relative pointers. Suppose that the character encoding for character 101b starts at word 1650b of the file, and that a self-relative pointer to that encoding is at word 105b of the file. Then word 105b of the file will contain 1543b=1650b−105b.
2.3 Numbers
Numbers in this document are decimal unless followed by a "b," in which case they are octal. 12b=10.
A FloatingPoint number is a two-word structure that contains a sign, an 8-bit exponent and a 23-bit mantissa. This representation is identical to the 32 most significant bits of the representation used by the PDP-10 and MAXC. The Alto BCPL subroutine package FLOAT manipulates these numbers as well. (Further information about the actual encoding of numbers can be found in PDP-10 documentation or in FLOAT documentation.)
3. File Naming Conventions
A standard naming convention is used for font files. In some cases, programs depend on adherence to the convention (e.g., extracting width information from EARS fonts). The convention permits programs to "parse" the font name to discover various parameters. The convention is:
{family-name-in-full}{point-size}{[B|L]}{[I]}{[C|E]}.{extension}
The optional B stands for "bold;" L for "light," I for "italic," C for "condensed," and E for "expanded." If a font file applies to all sizes of character (e.g., a spline file), the {point-size} is omitted. Examples:
Helvetica12.Ep12-point Helvetica font for EARS
Helvetica12b.Ep12-point bold Helvetica font for EARS
The {extension}s are chosen to identify the format of the file. Standard extensions are given below, together with the MAXC directory (inside brackets < >) where such files are traditionally found.
Standard formats:
.xx-SFSpline representations edited with FRED. <PRESSFONTS>
.ACRaster representations, edited or created with PrePress. <PRESSFONTS>
(These are usually Alto or Press printer fonts.)
Subsidiary formats:
Fonts.WidthsSummary of widths. <FONTS>
.SDCompact spline representations (SDtemp format). <PRESSFONTS>
.CU"Carnegie-Mellon University" format.
Subsidiary formats (device-dependent):
.ALAlto-format (CONVERT) font. <ALTOFONTS> and <PRINTING>
.STRIKEAlto-format font (BITBLT).
.KSAlto-format font (BITBLT) with kerning. <ALTOFONTS> and <PRINTING>
.EPEARS-format portrait font (obsolete).
.ELEARS-format landscape font (obsolete).
.XHXGP-format font, for XPRINT (obsolete). Archived from <FONTS>
.VTVTS-format font (obsolete). Archived from <FONTS>
.FONTSDictionary of fonts in .AC format or one of its subsidiary formats, used by
Press printing software
4. PrePress File Format
Several of the file formats are variants of a generic file created and modified by PrePress. The format was designed to be easily extendable to include new sorts of information and to permit many different fonts to be included in one file. PrePress documentation refers to this files with names like SD, SDtemp, CD, CDtemp, WD, WDtemp. An index at the head of the file describes each font segment that is contained within the file. The intention is that a reader will scan the index to find a pointer to the font she desires. Thus a file is:
structure PrePressFile:
[
index word howeverMany
@IX//Index entry with type=0 (end of index)
stuff word howeverManyAgain
]
Each index entry begins with a common form of header:
structure IX:
[
type bit 4//Various type codes are assigned
length bit 12//Length of entry in words, counting this one
]
A particular kind of index entry establishes a correspondence between a code and a string:
structure IXN:
[
@IX//Header with type =1
code word//The numeric code
nameLength byte//The number of characters in the name
characters ↑1,19 byte//Room for the name
]
Note that a name entry has a fixed length, although the name itself can be of any length up to 19. The final 20 bytes in the IXN structure are in the same format as a BCPL string. By convention, an IXN entry must establish a correspondence between a name and a code before any index entries that use the code appear.
Each segment of the file will have an index entry that points to it (SplineSegment, CharacterSegment, or WidthSegment). They all have roughly the same form:
structure STDIX:
[
@IX//Header with various types
family byte//Family name, using a name code
face byte//Encoding of the face properties
bc byte//Code for the "beginning character"
ec byte//Code for the "ending character"
size word//Size of the font segment
rotation word//Rotation of the font segment
segmentSA word 2//Starting address in file of the font segment
segmentLength word 2//Length of the segment
]
The family name is identified by referring to a name-code correspondence established with an IXN entry. The face is encoded as:
(if bold then 2 elseif light then 4 else 0)+
(if italic then 1 else 0)+
(if condensed then 6 elseif expanded then 12 else 0)+
(if Xerox then 0 elseif ASCII then 18 else 36)
This encoding generates face byte values in the range from 0 through 53. Codes 54 through 254 inclusive are used to denote the logical size of a TEX font, the size that the font was designed for independent of its physical magnification; for an explanation of this concept, see the memo [Maxc1]<Fonts>TexFonts.Press. A face byte value of F in the range [54,254] denotes a logical size of (254−F)/2 points; thus, logical sizes range from 0 through 100 points in units of half-points. Face code 255 is reserved as an escape.
The two entries bc and ec give the character codes for the first and last characters represented in the segment. This allows partial fonts to occupy less space. Size gives the size of the font description in micas. Rotation gives the rotation, in minutes of arc. segmentSA and segmentLength specify the location of the segment in the file (both entries are double-word integers, in units of file words): these are included to permit random access to a large number of segments in one file.
A common special case of a PrePress file is a font file that contains only one segment, and consequently a very brief index (a name entry, and entry pointing to the segment, and an End entry). The AC and SD files are examples.
5. Standard Formats
5.1. Outline representation — SF format.
The standard format for outline representations is a specially-organized text file. The file is normally read and written by FRED, the interactive editor for outlines, and by PrePress, the program for converting the outline representations to other formats. We designed the SF format to be based on a text file, and further to be readable by the INTERLISP programming system, in anticipation of the need to make transformations on outlines once they were defined (the transformations could be made by hand with a text editor, or by writing a suitable LISP program). This approach has several times saved us from some very messy effort to repair a damaged binary file—the text file has been a good idea.
The definition of the file follows normal INTERLISP conventions for atoms, numbers, strings, and lists. (A number is either an integer of the form 123 or an octal number followed by Q, i.e., 12Q=10, or a floating-point number with an exponent heralded by E, e.g., 1.23E−4.) In the description below, vertical bar (|) is used to separate alternatives, and
<...>is a list,
{...}is a string,
[...]is a number.
A single SF file may contain definitions for several characters, although the definitions are independent. The file is a sequence of <character description>s, terminated by the atom STOP:
<character description> ... <character description> STOP
Normally, a full font will consist of about 7 SF files. These are conventionally given names like:
family.LC1-SFLower case, first file
family.LC2-SFLower case, continuation file
family.UC1-SFUpper case, first file
family.UC2-SFLower case, continuation file
family.NUM-SFNumerals
family.S1-SFSpecial characters, first file
family.S2-SFSpecial characters, continuation file
A <character description> is:
((FAMILY {family name})
(CHARACTER [code])
(FACE { B | M | R } { R | I } { C | R | E })
(WIDTH [width in x] [width in y])
(FIDUCIAL [dimension in x] [dimension in y])
(VERSION [number] {date})
(MADE-FROM {file name}
[x character origin] [y character origin]
[x fiducial origin] [y fiducial origin])
(SPLINES <closed curve> ... <closed curve>))
Alternatively, a <character description> may specify that some other character is to be copied into this one (not universally implemented):
((FAMILY {family name})
(CHARACTER [code])
(USE {family name} [code] { B | M | R } { R | I } { C | R | E }))
Within the top-level list for <character description>, a construct of the form (COMMENT {any string}) may be inserted at will.
The FACE characters stand for:
BOLD | MEDIUM | LIGHT
REGULAR | ITALIC
CONDENSED | REGULAR | EXPANDED
It is important to understand the normal use of coordinates in a SF file. The coordinates of knots, for the width, origins in the MADE-FROM description, and in the FIDUCIAL annotation, are all Alto screen units: these are recorded directly by FRED. However, these coordinates must ultimately be related to a more standard system common to all characters in the world. The FIDUCIAL serves this purpose: it gives the distances, in x and y, that correspond to the point size of the character. For example, if we use FRED to design a (nominal) 12-point character, we set the fiducials to the dimension (in Alto screen units) that should be mapped into 12/72 inch on the final page image.
A <closed-curve> is:
(<spline> ... <spline>)
A <spline> is:
([n] <knot list> <weight list> <derivative list> {solution method})
where [n] is the number of knots, <knot list> is:
(([X1] [Y1]) ([X2] [Y2]) ... ([Xn] [Yn]))
<weight list> is either NIL, in which case all knots are weighted equally, or:
([W1] [W2] ... [Wn])
and <derivative list> is:
(([X1’] [Y1’] [X1’’] [Y1’’] [X1’’’] [Y1’’’]) ...
... ([Xn-1’] [Yn-1’] [Xn-1’’] [Yn-1’’] [Xn-1’’’] [Yn-1’’’]))
and {solution method} is:
{ NATURAL | CYCLIC | PSEUDOCYCLIC }
The numbers in this description are handled slightly differently: derivatives and weights are floating point numbers, character code is octal (e.g. 101Q) or decimal, all other numbers (in particular knot coordinates) are integers.
5.2 Raster representations — AC format.
The standard format for raster representations is the AC file, usually edited with the PrePress font editor. This format is used because it contains more information about characters than any other font format we have. Consequently, one can always convert to formats that demand less information. By convention, AC files assume a scanning mode of 8.
The file is a segment of a "PrePress font file" (see section 4 for a general discussion of PrePress files). The font file contains some identification information, and a directory that points to a character segment, which itself contains the information about the font. An index entry that points to a character segment is:
structure CharacterIndexEntry:
[
@STDIX//Standard header with type=3.
resolutionX word//Resolution in scan-lines/inch * 10
resolutionY word//Resolution in bits/inch * 10
]
This index entry points to a CharacterSegment:
structure CharacterSegment:
[
charData ↑bc,ec @CharacterData//Useful data about each character
directory ↑bc,ec @relFilePos//Relative file positions of rasters
rasters ↑bc,ec @rasterDefn//The actual raster encodings
]
structure CharacterData:
[
Wx @Fraction//X Width (scan-lines)
Wy @Fraction//Y Width (bits)
BBox word//Bounding box offsets
BBoy word
BBdx word//Width of bounding box (scan-lines)
BBdy word//Height of bounding box (bits) or special code
]
The first two entries are signed fractions (a fraction is two words: the first is the integer part, the second the fractional part) that give the width vector (with reference to the origin of the character). The four parameters of the bounding box follow. However, BBdy=−1 is reserved to indicate that a character of this code does not really exist in the font (such a code is necessary because CharacterData structures are recorded for all character codes in the range bc through ec).
The directory portion is a table that points to the raster definitions of each character in the range bc through ec. Each pointer is 32 bits long (a double-word integer) that gives the position in the file in words, relative to the beginning of the directory table, of the rasterDefn for the appropriate character. If a character of the given code is not in the font, both words of the relFilePos are −1.
A rasterDefn is:
structure rasterDefn:
[
BBdyW bit 6//Height of raster (in words)
BBdx bit 10//Same as BBdx in CharacterData
raster word BBdyW*BBdx//The actual raster bits!
]
The value of BBdyW is simply k(BBdy+15)/16l, the number of words required to specify one scan-line. Each scan-line in the raster encoding begins on a word boundary.
Important Note: Most Press printing software uses dictionaries of fonts in one of two subsidiary formats derived from AC format. These important derived formats are described in sections 7.3 and 7.4.