-- Tfm.mesa
-- Definition of Tex/Tioga font metric (.Tfm) files for Pilot
-- Last changed by Michael Plass, September 29, 1982 10:51 am

-- N.B.  These are the specifications for the new-style Tfm format, as per Lyle Ramshaw's Nov. 1980 specifications.

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): RECORD[]],
				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..