TfmReaderImpl.mesa
Font metric table loader
Last changed by Michael Plass, October 21, 1982 11:37 am
DIRECTORY
CIFS USING [dontCheck, Error, GetFC, OpenButDontHandleError, read],
File,
Inline,
Rope,
Space,
Tfm,
TfmReader;
TfmReaderImpl:
PROGRAM
IMPORTS CIFS, File, Inline, Rope, Space, Tfm
EXPORTS TfmReader =
BEGIN OPEN TfmReader;
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] =
BEGIN
RETURN[Tfm.Long[x]/RealTwoToTheTwentieth];
END;
tfmDir: Rope.ROPE = "/Indigo/Tioga/TFM/";
Load:
PUBLIC
PROCEDURE [name: Rope.
ROPE]
RETURNS [f: Ref] =
BEGIN
s: NAT = SIZE[Tfm.Word];
tfmName: Rope.ROPE ← name.Concat[".tfm"];
tfmFile: File.Capability;
pages: File.PageCount;
size: Space.PageCount;
space: Space.Handle;
base: LONG POINTER TO UNSPECIFIED;
dir: LONG POINTER TO Tfm.Directory;
IF Rope.Fetch[tfmName]#'/
THEN tfmName ← Rope.Cat[tfmDir, tfmName];
tfmFile ← CIFS.GetFC[CIFS.OpenButDontHandleError[tfmName, CIFS.read + CIFS.dontCheck] ! CIFS.Error => TRUSTED {GOTO FileNotFound}];
pages ← File.GetSize[tfmFile];
size ← IF pages<=16 THEN Inline.LowHalf[pages] ELSE ERROR;
space ← Space.Create[size: size, parent: Space.virtualMemory];
Space.Map[space: space, window: [file: tfmFile, base: 1]]; -- first page is 1!
base ← Space.LongPointer[space];
dir ← LOOPHOLE[base];
f ← NEW[TfmReader.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 ← Inline.LowByte[bc];
f.ec ← Inline.LowByte[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};
Space.Delete[space];
EXITS FileNotFound => {}
END;
ExtractHeaderInfo:
PROCEDURE [p:
LONG
POINTER
TO Tfm.Header]
RETURNS [h: HeaderInfo] =
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 ← FixedToReal[p.designSize];
face ← p.extraInfo.parcFaceByte;
END
END;
Textify:
PROCEDURE [a:
LONG
POINTER
TO
READONLY
PACKED
ARRAY [0..255]
OF
CHARACTER]
RETURNS [t: REF TEXT] =
BEGIN
len:NAT ← LOOPHOLE[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;
ExtractFInfoTable:
PROCEDURE [p:
LONG
POINTER
TO Tfm.FInfo, dir:
LONG
POINTER
TO Tfm.Directory]
RETURNS [FInfoTable] =
BEGIN OPEN dir^;
f: FInfoTable ← NEW[FInfoTableRec[ec+1]];
FOR i:NAT IN [0..bc) DO f[i] ← [0,0,0,0,none[[]]] 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:
PROCEDURE [p:
LONG
POINTER
TO Tfm.FixedArray, n:
CARDINAL]
RETURNS [d: MetricTable] =
BEGIN
d ← NEW[MetricTableRec[n]];
FOR i:NAT IN [0..n) DO d[i] ← FixedToReal[p[i]] ENDLOOP
END;
ExtractLigKernProgram:
PROCEDURE [p:
LONG
POINTER
TO Tfm.LigKern, n:
CARDINAL]
RETURNS [l: LigKernProgram] =
BEGIN
l ← NEW[LigKernProgramRec[n]];
FOR i:NAT IN [0..n) DO l[i] ← p[i] ENDLOOP
END;
ExtractParameters:
PROCEDURE [p:
LONG
POINTER
TO Tfm.Param, n:
CARDINAL]
RETURNS [t: ParamTable] =
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, October 21, 1982 11:08 am. Adapted from TSFontTableImpl.