TSFontTableImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Font table loader for the Tioga Typesetter
Michael Plass, June 22, 1985 10:56:00 pm PDT
Beach, May 7, 1984 4:00:02 pm PDT
Russ Atkinson, June 12, 1984 6:10:15 pm PDT
Rick Beach, June 23, 1985 1:25:59 am PDT
DIRECTORY
FS USING [Error, GetInfo, nullOpenFile, Open, OpenFile, Read],
Rope USING [Concat, Fetch, FromRefText, ROPE],
Tfm USING
[Byte, CharIc, Depth, Directory, Exten, FInfo, FInfoEntry, Fixed, FixedArray, Header, Height, Kern, LigKern, Long, Param, ParamIndex, ValidDirectory, Width, Word],
TSFontTable USING
[Byte, FInfoEntry, FInfoTable, FInfoTableRec, HeaderInfo, HeaderInfoRec, LigKernProgram, LigKernProgramRec, MetricTable, MetricTableRec, ParamTable, ParamTableRec, Record, Ref],
TSTypes USING [pt, RealDimn],
VM USING [AddressForPageNumber, Allocate, Free, Interval, nullInterval];
TSFontTableImpl: CEDAR PROGRAM
IMPORTS FS, Rope, Tfm, TSTypes, VM
EXPORTS TSFontTable =
BEGIN OPEN TSTypes, TSFontTable;
BadTfmFile: SIGNAL = CODE;
TwoToTheTenth: INT = 2*2*2*2*2 * 2*2*2*2*2;
TwoToTheTwentieth: INT = TwoToTheTenth*TwoToTheTenth;
RealTwoToTheTwentieth: REAL = TwoToTheTwentieth;
FixedToReal: PROCEDURE [x: Tfm.Fixed] RETURNS [REAL] = TRUSTED
BEGIN
RETURN[Tfm.Long[x]/RealTwoToTheTwentieth];
END;
tfmDir: Rope.ROPE ← "[]<>Fonts>FontMetrics>";
Load: PUBLIC PROCEDURE [name: Rope.ROPE] RETURNS [f: Ref] = TRUSTED
BEGIN
ENABLE FS.Error => TRUSTED {GOTO FileNotFound};
s: NAT = SIZE[Tfm.Word];
tfmName: Rope.ROPE ← name.Concat[".tfm"];
tfmFile: FS.OpenFile ← FS.nullOpenFile;
pages: INT;
space: VM.Interval ← VM.nullInterval;
base: LONG POINTER TO UNSPECIFIED;
dir: LONG POINTER TO Tfm.Directory;
SELECT Rope.Fetch[tfmName] FROM
'/, '[ => tfmFile ← FS.Open[tfmName];
ENDCASE => {
longName: Rope.ROPE ← Rope.Concat[tfmDir, tfmName];
tfmFile ← FS.Open[longName
! FS.Error => IF error.code # $unknownFile THEN CONTINUE];
IF tfmFile = FS.nullOpenFile THEN {
longName ← Rope.Concat[tfmDir, tfmName];
tfmFile ← FS.Open[longName];
};
tfmName ← longName;
};
pages ← FS.GetInfo[tfmFile].pages;
space ← VM.Allocate[pages];
base ← VM.AddressForPageNumber[space.page];
FS.Read[file: tfmFile, from: 0, nPages: pages, to: base];
dir ← LOOPHOLE[base];
f ← NEW[TSFontTable.Record];
IF Tfm.ValidDirectory[dir^] THEN
BEGIN OPEN dir^;
hdr: LONG POINTER TO Tfm.Header ← LOOPHOLE[dir + s*6];
pf: LONG POINTER TO Tfm.FInfo ← LOOPHOLE[hdr + s*lh];
pw: LONG POINTER TO Tfm.Width ← LOOPHOLE[pf + s*(ec-bc+1)];
ph: LONG POINTER TO Tfm.Height ← LOOPHOLE[pw + s*nw];
pd: LONG POINTER TO Tfm.Depth ← LOOPHOLE[ph + s*nh];
pi: LONG POINTER TO Tfm.CharIc ← LOOPHOLE[pd + s*nd];
pl: LONG POINTER TO Tfm.LigKern ← LOOPHOLE[pi + s*ni];
pk: LONG POINTER TO Tfm.Kern ← LOOPHOLE[pl + s*nl];
pe: LONG POINTER TO Tfm.Exten ← LOOPHOLE[pk + s*nk];
pp: LONG POINTER TO Tfm.Param ← LOOPHOLE[pe + s*ne];
f.name ← name;
f.headerInfo ← ExtractHeaderInfo[hdr];
f.bc ← VAL[bc];
f.ec ← VAL[ec];
f.fInfoTable ← ExtractFInfoTable[pf,dir];
f.widthTable ← ExtractDimensions[pw,nw];
f.heightTable ← ExtractDimensions[ph,nh];
f.depthTable ← ExtractDimensions[pd,nd];
f.charIcTable ← ExtractDimensions[pi,ni];
f.ligKernProgram ← ExtractLigKernProgram[pl,nl];
f.kernTable ← ExtractDimensions[pk,nk];
f.extTable ← NIL; -- don't need this for Tioga at this time
f.parameters ← ExtractParameters[pp,np];
END
ELSE {SIGNAL BadTfmFile};
VM.Free[space];
EXITS FileNotFound => {}
END;
ExtractHeaderInfo: UNSAFE PROCEDURE [p: LONG POINTER TO Tfm.Header]
RETURNS [h: HeaderInfo] = UNCHECKED
BEGIN --
h ← NEW[HeaderInfoRec];
BEGIN OPEN h^;
checkSum ← p.checkSum;
characterCodingScheme ← Rope.FromRefText[Textify[LOOPHOLE[@p^.characterCodingScheme]]];
family ← Rope.FromRefText[Textify[LOOPHOLE[@p^.externalFontIdentifier]]];
designSize ← RealDimn[FixedToReal[p.designSize],pt];
face ← p.extraInfo.parcFaceByte;
END
END;
Textify: UNSAFE PROCEDURE [a: LONG POINTER TO READONLY PACKED ARRAY [0..255] OF CHARACTER]
RETURNS [t: REF TEXT] = UNCHECKED
BEGIN
len:NATLOOPHOLE[a[0],Byte]; -- length is stashed in first byte
t ← NEW[TEXT[len]];
t.length ← len;
FOR i:NAT IN [0..len) DO
t[i] ← a[i+1];
ENDLOOP;
END;
nullFInfoEntry: FInfoEntry ~ [
widthIndex: 0,
heightIndex: 0,
depthIndex: 0,
charIcIndex: 0,
remainder: none[unused: 0]
];
ExtractFInfoTable: UNSAFE PROCEDURE [p: LONG POINTER TO Tfm.FInfo, dir: LONG POINTER TO Tfm.Directory]
RETURNS [FInfoTable] = UNCHECKED
BEGIN OPEN dir^;
f: FInfoTable ← NEW[FInfoTableRec[ec+1]];
FOR i:NAT IN [0..bc) DO f[i] ← nullFInfoEntry ENDLOOP;
FOR i:NAT IN [bc..ec] DO
OPEN p[i-bc];
IF widthIndex >= nw OR
heightIndex >= nh OR
depthIndex >= nd OR
charIcIndex >= ni THEN SIGNAL BadTfmFile;
f[i] ← p[i-bc] ENDLOOP;
RETURN[f]
END;
ExtractDimensions: UNSAFE PROCEDURE [p: LONG POINTER TO Tfm.FixedArray, n:CARDINAL]
RETURNS [d: MetricTable] = UNCHECKED
BEGIN
d ← NEW[MetricTableRec[n]];
FOR i:NAT IN [0..n) DO d[i] ← FixedToReal[p[i]] ENDLOOP
END;
ExtractLigKernProgram: UNSAFE PROCEDURE [p: LONG POINTER TO Tfm.LigKern, n:CARDINAL]
RETURNS [l: LigKernProgram] = UNCHECKED
BEGIN
l ← NEW[LigKernProgramRec[n]];
FOR i:NAT IN [0..n) DO l[i] ← p[i] ENDLOOP
END;
ExtractParameters: UNSAFE PROCEDURE [p: LONG POINTER TO Tfm.Param, n:CARDINAL]
RETURNS [t: ParamTable] = UNCHECKED
BEGIN
i: Tfm.ParamIndex ← FIRST[Tfm.ParamIndex];
t ← NEW[ParamTableRec[n]];
THROUGH [0..n) DO
t[i] ← FixedToReal[p[i]];
i ← SUCC[i];
ENDLOOP;
t.slantNum ← Tfm.Long[p[slant].ValueTimesTwoToTheTwentieth];
t.slantDenom ← TwoToTheTwentieth;
END;
END.
Michael Plass, September 16, 1982 1:38 pm. Removed !h from CIFS filename.
Michael Plass, September 29, 1982 11:08 am. Added TRUSTED to catch phrase in CIFS call.
Michael Plass, November 2, 1982 10:11 am. CEDARized.
Michael Plass, November 17, 1982 11:33 am. Used ENABLE instead of catch phrase for CIFS.
Michael Plass, November 15, 1983 12:30 pm. Cedar 5 conversion.