UnifiedFonts.mesa Unified Font Interface
Written November 1, 1982 4:21 pm
Last edited by Michael Plass, February 18, 1983 9:23 am
DIRECTORY Rope, Graphics, GraphicsBasic, Scaled;
UnifiedFonts: CEDAR DEFINITIONS =
BEGIN
ROPE: TYPE = Rope.ROPE;
RopeOrRefText: TYPE = REF;
Context: TYPE = Graphics.Context;
This interface is designed to be used in conjunction with CedarGraphics, and perhaps someday it will become integrated with that package.
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 CHARACTER. 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 CHARACTER 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 CedarGraphics unit.
Create: PROCEDURE [fontName: RopeOrRefText, transformation: Transformation ← identity, deviceType: DeviceType ← $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.
Transformation: TYPE = RECORD [scale: REAL, rotation: REAL ← 0];
A Transformation specifies the linear transformation used to scale and rotate fonts. Only uniform scaling and rotation are supported. The rotation is given in degrees counterclockwise.
identity: Transformation = [scale: 1, rotation: 0];
DeviceType: TYPE = ATOM;
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).
EasyTransformations: PROCEDURE [fontName: RopeOrRefText, deviceType: DeviceType, transformationProc: TransformationProc];
TransformationProc: TYPE = PROCEDURE [transformation: Transformation] RETURNS [quit: BOOLEANFALSE];
anyTransformation: Transformation = [scale: 0];
EasyTransformations enumerates the transformations of the font that are easy on the specified device. If any transformation is allowed, anyTransformation will be included in the list of easy transformations.
Name: PROCEDURE [font: FONT] RETURNS [fontName: ROPE];
This extracts the name of the font. May return NIL if the font is unnamed.
Contains: PROCEDURE [font: FONT, char: CHAR] RETURNS [BOOLEAN];
TRUE iff the character exists in the font.
NSCode: PROCEDURE [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: PROCEDURE [font: FONT, nsCode: INT] RETURNS [char: CHAR];
Returns the CHARACTER code for the specified Network Systems code; NUL is returned for characters that do not exist in the font.
DrawChar: PROCEDURE [font: FONT, char: CHAR, context: Context];
Displays a single character through Graphics.
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.
Direction: TYPE = {right, up, left, down};
Box: TYPE = GraphicsBasic.Box;
= RECORD [xmin, ymin, xmax, ymax: REAL]
NextCharacterDirection: PROCEDURE [font: FONT] RETURNS [Direction];
Normally right for Latin alphabets.
NextLineDirection: PROCEDURE [font: FONT] RETURNS [Direction];
Normally down for Latin alphabets.
FormattingBox: PROCEDURE [font: FONT, char: CHAR] RETURNS [Box];
Normally xmin is zero for Latin alphabets.
Width: PROCEDURE [font: FONT, char: CHAR] RETURNS [REAL];
Equal to FormattingBox[font, char].xmax - FormattingBox[font, char].xmin, but maybe faster.
GetLigatureOrKern: PROCEDURE [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: PROCEDURE [font: FONT] RETURNS [Transformation];
FormattingMetric: PROCEDURE [font: FONT, metric: ATOM, char: CHAR ← '\000] RETURNS [REAL];
Escape hatch for getting metrics not included above. Returns Real.MinusZero if the metric is not available for the particular font.
Undefined: PROCEDURE [r: REAL] RETURNS [BOOLEAN] = TRUSTED INLINE {RETURN[LOOPHOLE[r, LONG CARDINAL]=20000000000B]};
FormattingInfo: PROCEDURE [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.
Vec: TYPE = GraphicsBasic.Vec;
= RECORD [x, y: REAL]
BoundingBox: PROCEDURE [font: FONT, char: CHAR] RETURNS [Box];
A true bounding box for the character mask, not necessarily as tight as possible.
WidthVector: PROCEDURE [font: FONT, char: CHAR] RETURNS [Vec];
Tells how the current position is changed when the character is drawn.
ActualTransformation: PROCEDURE [font: FONT] RETURNS [Transformation];
Tells the transformation after any font substitution is done.
Provisions for speedy display
Positioning: TYPE = {rounded, exact};
DrawCharSeq: PROCEDURE [
font: FONT, context: Context, count: NAT,
charPtr: LONG POINTER TO CHAR, charIncrement: NAT,
deltaXptr: LONG POINTER TO FixedUnit, deltaXincrement: NAT,
deltaYptr: LONG POINTER TO FixedUnit, deltaYincrement: NAT,
positioning: Positioning ← rounded
];
Displays a batch of characters. Use this where speed is important.
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: PROCEDURE [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: PROCEDURE [FONT] RETURNS[PressFontSpecification];
Implementor Private Stuff
Key: TYPE = RECORD [index: NATLAST[NAT]];
FontRec: TYPE = RECORD [
name: ROPE,
requestedTransformation: Transformation,
actualTransformation: Transformation,
deviceType: DeviceType,
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,
bitmapCacheable: BOOLEAN,
characterCache: REF,
propertyList: REF,
link: REF FontRec
];
pZone: ZONE;
This is to store font-related things that are typically allocated once and held onto for a long time. Mostly for internal use.
PutProp: PROCEDURE [font: FONT, name: ATOM, value: REF ANY];
GetProp: PROCEDURE [font: FONT, name: ATOM] RETURNS [value: REF ANY];
RegisterFontFormattingClass: PROCEDURE [flavor: ATOM, init: PROC [font: FONT]];
RegisterFontGraphicsClass: PROCEDURE [flavor: ATOM, init: PROC [font: FONT]];
FontFormattingClassRec: TYPE = RECORD [
formattingBoxProc: PROCEDURE [font: FONT, char: CHAR] RETURNS [box: Box],
ligKernProc: PROCEDURE [font: FONT, char1, char2: CHAR] RETURNS [ligatureOrKern: LigatureOrKern],
formattingMetricProc: PROCEDURE [font: FONT, metric: ATOM, char: CHAR] RETURNS [REAL]
];
FontGraphicsClassRec: TYPE = RECORD [
drawCharProc: PROCEDURE [font: FONT, char: CHAR, context: Context],
boundingBoxProc: PROCEDURE [font: FONT, char: CHAR] RETURNS [box: Box],
widthVectorProc: PROCEDURE [font: FONT, char: CHAR] RETURNS [vec: Vec],
containsProc: PROCEDURE [font: FONT, char: CHAR] RETURNS [BOOLEAN]
];
END.