Font.mesa
Unified Font Interface
This interface is designed to be used in conjunction with the Cedar Imager. The operations for actual display of characters are provided there; use this interface for creating font refs, and for obtaining metric information.
Last edited by:
(Written by Michael Plass, November 1, 1982 4:21 pm)
Michael Plass, July 11, 1983 8:25 am
Doug Wyatt, October 3, 1983 2:48 pm
DIRECTORY
Real USING [MinusZero],
Rope USING [ROPE],
ImagerBasic USING [Pair, Transformation],
Scaled USING [Value, unit, zero];
Font: CEDAR DEFINITIONS
= BEGIN
Types
FONT: TYPE = REF FontRec;
A FONT describes a font, that is, a collection of related graphical objects. Each object, or character, in the collection is referred to by an index of type CHAR. There are various attributes of a font that may be accessed through this interface; some of them pertain to the font as a whole, and others pertain to the individual characters.
The actual graphical objects contained in a font may or may not be locally available. For hardcopy applications, the exact graphical descriptions typically reside at the print server, and cannot be assumed to be available. On the other hand, the graphical descriptions for fonts to be used on the screen must be locally available. In any case, some sort of reasonable approximation is attempted for local use.
A font is ideally available in all sizes and rotations; however, not all print servers are capable of living up to this ideal. Therefore, a mechanism is provided for finding out what transformations are available (easy) for a font on a particular kind of output device.
The association between CHAR codes and the images is often jumbled, due to historical reasons and the natural slowness in the propagation of standards. As a step towards untangling this mess, this interface provides a way to find out the Xerox Character Code for a character in a given font, and vice versa.
The unit used for all metric information is the same as the default Imager unit.
ROPE: TYPE = Rope.ROPE;
RopeOrRefText: TYPE = REF;
Pair: TYPE = ImagerBasic.Pair; -- RECORD[x, y: REAL]
Transformation: TYPE = ImagerBasic.Transformation;
Direction: TYPE = {right, up, left, down};
Box: TYPE = RECORD [xmin, ymin, xmax, ymax: REAL];
Font creation
Create: PROC [fontName: RopeOrRefText, transformation: Transformation,
deviceType: ATOM ← $Ideal] RETURNS [FONT];
This gets at least the font metric information from a centralized database. The font name is an Interpress hierarchial font name, and encodes all of the family, face, and design size information. With the default transforamation, the font will be in a size designed for one-unit baseline spacing; in most applications, the scale of the transformation will be the body height that is desired.
The deviceType tells what kind of device to tailor the easy transformations for. $Ideal as a device type will allow any transformation. Atoms that will probably make sense here are $Ideal, $Press, $Spruce, $Screen, or the name of a print server (first letter capital, remainder lower case).
CreateScaled: PROC [fontName: RopeOrRefText, scale: REAL,
deviceType: ATOM ← $Ideal] RETURNS [FONT];
Equivalent to Create[fontName, Scale[scale], deviceType].
Name: PROC [font: FONT] RETURNS [fontName: ROPE];
This extracts the name of the font. May return NIL if the font is unnamed.
Character codes
Contains: PROC [font: FONT, char: CHAR] RETURNS [BOOLEAN];
TRUE iff the character exists in the font.
NSCode: PROC [font: FONT, char: CHAR] RETURNS [nsCode: INT];
unassignedNSCode: INT = 255;
nonexistentNSCode: INT = 65535;
Returns the Network Systems code for the specified character; unassignedNSCode is returned for characters that have no such code assigned, and nonexistentNSCode is returned for characters that do not exist in the font.
CharCode: PROC [font: FONT, nsCode: INT] RETURNS [char: CHAR];
Returns the CHAR code for the specified Network Systems code; NUL is returned for characters that do not exist in the font.
Formatting Metrics
The following metrics use a model derived from the hand compositon of type. Each character is considered to be on a rectangular body that is always aligned with the page. The characters are not required to lie entirely within this body, or formatting box; the box is just for composition purposes. Each character has a reference point that is used to line the characters up when making a line or column of text. Placing a character at a point means to position it so that its reference point lines up with the given point. Note that the formatting metrics do not change when a font is rotated.
NextCharacterDirection: PROC [font: FONT] RETURNS [Direction];
Normally right for Latin alphabets.
NextLineDirection: PROC [font: FONT] RETURNS [Direction];
Normally down for Latin alphabets.
FormattingBox: PROC [font: FONT, char: CHAR] RETURNS [Box];
Normally xmin is zero for Latin alphabets.
Width: PROC [font: FONT, char: CHAR] RETURNS [REAL];
Equal to FormattingBox[font, char].xmax - FormattingBox[font, char].xmin, but maybe faster.
TextWidth: PROC [font: FONT, text: RopeOrRefText] RETURNS [REAL];
Adds up the formatting widths for all chars in the font.
RoundedTextWidth: PROC [font: FONT, text: RopeOrRefText] RETURNS [INTEGER];
TextWidth rounded to an integer, for display applications.
GetLigatureOrKern: PROC [font: FONT, char1, char2: CHAR]
RETURNS [LigatureOrKern];
LigatureOrKern: TYPE = RECORD [
SELECT tag: * FROM
neither => [],
kern => [kernAmount: REAL],
The amount to add to the character's motion to kern this character to the successor character.
ligature => [ligatureCode: CHAR],
ENDCASE];
RequestedTransformation: PROC [font: FONT] RETURNS [Transformation];
undefinedMetric: REAL = Real.MinusZero;
Undefined: PROC [r: REAL] RETURNS [BOOLEAN] = INLINE {RETURN[r=undefinedMetric]};
FormattingMetric: PROC [font: FONT, metric: ATOM, char: CHAR ← '\000] RETURNS [REAL];
Escape hatch for getting metrics not included above. Returns undefinedMetric if the metric is not available for the particular font.
FormattingInfo: PROC [font: FONT, name: ATOM, char: CHAR ← '\000] RETURNS [REF];
Escape hatches for getting other information not included above. Returns NIL if the information is not available for the particular font.
Graphical Metrics
These metrics are provided to tell the client what will happen when the character is drawn. Unlike the formatting metrics, these will change if the font is rotated.
BoundingBox: PROC [font: FONT, char: CHAR] RETURNS [Box];
A true bounding box for the character mask, not necessarily as tight as possible.
FontBoundingBox: PROC [font: FONT] RETURNS [Box]
The union of BoundingBox[font, c] for all c in the fonts
= INLINE {RETURN [font.fontBoundingBox]};
WidthVector: PROC [font: FONT, char: CHAR] RETURNS [Pair];
Tells how the current position is changed when the character is drawn.
ActualTransformation: PROC [font: FONT] RETURNS [Transformation];
Tells the transformation after any font substitution is done.
Provisions for speedy width info.
FixedUnit: TYPE = Scaled.Value;
FixedPoint: FixedUnit = Scaled.unit;
There are exactly 72*FixedPoint FixedUnits per inch.
WidthArray: TYPE = REF READONLY ARRAY CHAR OF FixedUnit;
GetWidthArray: PROC [font: FONT, minimum, undefined: FixedUnit ← Scaled.zero] RETURNS [WidthArray];
Gives the formatting widths in fixed-point form.
Errors
BadFontFileFormat: ERROR;
Press Compatibility Stuff
PressFontSpecification: TYPE = RECORD [
family: ROPE,
face: PressFontFace,
size: INTEGER,
rotation: INTEGER
];
PressFontFace: TYPE = [0..256);
GetPressFontSpecification: PROC [FONT] RETURNS[PressFontSpecification];
Implementor Private Stuff
Key: TYPE = RECORD [index: NATLAST[NAT]];
FontRec: TYPE = RECORD [
name: ROPE,
requestedTransformation: Transformation,
actualTransformation: Transformation,
deviceType: ATOM,
nsCodeTable: Key,
Formatting metrics stuff.
fontFormattingClass: REF FontFormattingClassRec,
formattingKey: Key,
cachedWidthsMinimum, cachedWidthsUndefined: FixedUnit ← Scaled.zero,
cachedWidths: REF ARRAY CHAR OF FixedUnit,
Graphics object stuff.
fontGraphicsClass: REF FontGraphicsClassRec,
graphicsKey: Key,
bc, ec: CHAR,
contains: REF PACKED ARRAY CHAR OF BOOLEAN,
fontBoundingBox: Box,
propertyList: REF,
link: REF FontRec
];
PutProp: PROC [font: FONT, name: ATOM, value: REF ANY];
GetProp: PROC [font: FONT, name: ATOM] RETURNS [value: REF ANY];
RegisterFontFormattingClass: PROC [flavor: ATOM, init: PROC [font: FONT]];
RegisterFontGraphicsClass: PROC [flavor: ATOM, init: PROC [font: FONT]];
FontFormattingClassRec: TYPE = RECORD [
formattingBoxProc: PROC [font: FONT, char: CHAR] RETURNS [box: Box],
ligKernProc: PROC [font: FONT, char1, char2: CHAR] RETURNS [ligatureOrKern: LigatureOrKern],
formattingMetricProc: PROC [font: FONT, metric: ATOM, char: CHAR] RETURNS [REAL]
];
FontGraphicsClassRec: TYPE = RECORD [
maskProc: PROC [font: FONT, transformation: Transformation, char: CHAR, run: PROC [sMin, fMin: INTEGER, fSize: NAT]],
The tranformation takes client space to device space: [x y 1] T = [s f 1].
boundingBoxProc: PROC [font: FONT, char: CHAR] RETURNS [Box],
widthVectorProc: PROC [font: FONT, char: CHAR] RETURNS [Pair],
containsProc: PROC [font: FONT, char: CHAR] RETURNS [BOOLEAN]
];
END.