Tfm:
DEFINITIONS =
BEGIN
Byte: TYPE = [0..377B];
Char: TYPE = CHARACTER; -- should match TSTypes.Char
Word: TYPE = MACHINE DEPENDENT RECORD [hiHalf, lowHalf: CARDINAL]; -- note a Word is 32 bits long, and in BigEndian order.
Fixed: TYPE = MACHINE DEPENDENT RECORD [ValueTimesTwoToTheTwentieth: Word];
FixedArray:
TYPE =
MACHINE
DEPENDENT
RECORD
[entry(0): PACKED SEQUENCE COMPUTED CARDINAL OF Fixed];
Long:
PROCEDURE [w:Word]
RETURNS [
LONG
INTEGER] =
INLINE
BEGIN -- this depends on the way Mesa long integers are stored
t: MACHINE DEPENDENT RECORD [lowHalf, hiHalf: CARDINAL];
t.lowHalf ← w.lowHalf;
t.hiHalf ← w.hiHalf;
RETURN[LOOPHOLE[t,LONG INTEGER]]
END;
Directory:
TYPE =
MACHINE
DEPENDENT
RECORD
[lf:
CARDINAL,
-- length of entire file in Words
lh: CARDINAL, -- length of header data
bc: CARDINAL, -- first character code in font
ec: CARDINAL, -- last character code in font
nw: CARDINAL, -- number of Words in width table
nh: CARDINAL, -- number of Words in height table
nd: CARDINAL, -- number of Words in depth table
ni: CARDINAL, -- number of Words in italic correction table
nl: CARDINAL, -- number of Words of lig/kern program
nk: CARDINAL, -- number of Words in kern table
ne: CARDINAL, -- number of Words in extensible character table
np: CARDINAL -- number of font parameters
];
ValidDirectory:
PROCEDURE [h: Directory]
RETURNS [
BOOLEAN] =
INLINE
BEGIN
OPEN h;
RETURN [lh<=24
-- Allow headers to grow a bit --
AND
ec>=bc AND ec<256 AND
nw <= 256 AND
nh <= 16 AND
nd <= 16 AND
ni <= 64 AND
nl <= 256 AND
nk <= 256 AND
ne <= 256 AND
np <= 24 AND
lf = 6 + lh + (ec-bc+1) + nw + nh + nd + ni + nl + nk + ne + np]
END;
The header: occupies lh Words
Header:
TYPE =
MACHINE
DEPENDENT
RECORD
[checkSum: Word,
-- identifies the version of the font
designSize: Fixed, -- nominal size of the font, in TEX points
characterCodingScheme: CharacterCodingScheme,
externalFontIdentifier: ExternalFontIdentifier,
extraInfo: ExtraInfo];
CharacterCodingScheme: TYPE = PACKED ARRAY [0..40) OF CHARACTER; -- LOOPHOLE[id[0],Byte] tells the number of characters in the id
ExternalFontIdentifier: TYPE = PACKED ARRAY [0..20) OF CHARACTER; -- LOOPHOLE[id[0],Byte] tells the number of characters in the id
ExtraInfo:
TYPE =
MACHINE
DEPENDENT
RECORD
[sevenBitSafe(0:0..0):
BOOLEAN,
-- lig table stays in first half
unused(0:1..23): RECORD [],
parcFaceByte(0:24..31): Byte];
The font information: occupies (ec-bc+1) Words
FInfo:
TYPE =
MACHINE
DEPENDENT
RECORD
[entry(0): PACKED SEQUENCE COMPUTED CARDINAL OF FInfoEntry];
FInfoTag: TYPE = MACHINE DEPENDENT {none(0), lig(1), list(2), var(3)};
FInfoEntry:
TYPE =
MACHINE
DEPENDENT
RECORD
[widthIndex(0:0..7): [0..256),
-- index into width table
heightIndex(0:8..11): [0..16), -- index into height table
depthIndex(0:12..15): [0..16), -- index into depth table
charIcIndex(0:16..21): [0..64), -- index to italic corr. or mathop kern
remainder(0:22..31):
SELECT tag(0:22..23): FInfoTag
FROM
none => [unused(0:24..31): [0..256)],
lig => [ligKernStart(0:24..31): [0..256)],
list => [nextBigger(0:24..31): CHARACTER],
var => [extIndex(0:24..31): [0..256)]
ENDCASE];
The width information: occupies nw Words
Width: TYPE = FixedArray;
The height information: occupies nh Words
Height: TYPE = FixedArray;
The depth information: occupies nd Words
Depth: TYPE = FixedArray;
The italic correction table: occupies ni Words
CharIc: TYPE = FixedArray;
The ligature/kerning program: occupies nl Words
The LigKern table contains instructions for a simple machine that decides how to treat special letter pairs.
LigKern:
TYPE =
MACHINE
DEPENDENT
RECORD
[entry(0): PACKED SEQUENCE COMPUTED CARDINAL OF LigKernEntry];
LigOrKern: TYPE = MACHINE DEPENDENT {lig(0), kern(1)};
LigKernEntry:
TYPE =
MACHINE
DEPENDENT
RECORD
[stop(0:0..0):
BOOLEAN,
-- means this is a final program step
unused(0:1..7): RECORD[],
nextChar(0:8..15): CHARACTER, -- if this is the next character, then ...
action(0:16..31):
SELECT tag(0:16..16): LigOrKern
FROM
lig => [unused1(0:17..23):
RECORD[],
ligCode(0:24..31): CHARACTER],
kern =>[unused2(0:17..23):
RECORD[],
kernIndex(0:24..31): Byte]
ENDCASE];
The kern table: occupies nk Words
Kern: TYPE = FixedArray;
The extensible character table: occupies ne Words
Exten:
TYPE =
MACHINE
DEPENDENT
RECORD
[entry(0): PACKED SEQUENCE COMPUTED CARDINAL OF ExtRecipe];
ExtRecipe:
TYPE =
MACHINE
DEPENDENT
RECORD
[top(0:0..7), mid(0:8..15), bot(0:16..23), ext(0:24..31): CHARACTER];
The font parameters: occupy np Words
Param:
TYPE =
MACHINE
DEPENDENT
RECORD
[entry(0): PACKED SEQUENCE COMPUTED ParamIndex OF Fixed];
ParamIndex:
TYPE =
MACHINE
DEPENDENT
-- see MetaFont manual, pages 98-100
{slant(0), -- index for amount of italic slant (do not scale)
spaceWidth(1),
spaceStretch(2),
spaceShrink(3),
xHeight(4),
quad(5),
x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,mathSyParamLen};
extraSpace: ParamIndex = x0;
normalParamLen: ParamIndex = x1;
Params used only for mathsy fonts
mathSpace: ParamIndex = x0;
num1: ParamIndex = x1;
num2: ParamIndex = x2;
num3: ParamIndex = x3;
denom1: ParamIndex = x4;
denom2: ParamIndex = x5;
sup1: ParamIndex = x6;
sup2: ParamIndex = x7;
sup3: ParamIndex = x8;
sub1: ParamIndex = x9;
sub2: ParamIndex = x10;
supdrop: ParamIndex = x11;
subdrop: ParamIndex = x12;
delim1: ParamIndex = x13;
delim2: ParamIndex = x14;
axisheight: ParamIndex = x15;
Params used only for mathex fonts
defaultRuleThickness: ParamIndex = x1;
bigOpSpacing1: ParamIndex = x2;
bigOpSpacing2: ParamIndex = x3;
bigOpSpacing3: ParamIndex = x4;
bigOpSpacing4: ParamIndex = x5;
bigOpSpacing5: ParamIndex = x6;
mathExParamLength: ParamIndex = x7;
END.