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: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; 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. ˜TSFontTableImpl.mesa Copyright c 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 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. ΚΆ– "cedar" style˜šΟc™Jšœ Οmœ1™JšœŸœŸœ˜.šœŸ˜ Jšœ£˜£—šœ Ÿ˜Jšœ±˜±—JšœŸœ˜JšŸœŸœ@˜HJ˜—šœŸ ˜JšŸœŸœŸ˜"JšŸœ˜JšŸœŸœ˜ —J˜Jšœ ŸœŸœ˜J˜JšœŸœ˜+JšœŸœ˜5JšœŸœ˜0J˜š Οn œŸ œŸœŸœŸ˜>JšŸ˜JšŸœ$˜*JšŸœ˜J˜—Jšœ Ÿœ˜-J˜š  œŸœŸ œ ŸœŸœ Ÿ˜CJšŸ˜JšŸœŸœ ŸœŸœ˜/JšœŸœŸœ ˜JšœŸœ˜)Jšœ Ÿœ Ÿœ˜'JšœŸœ˜ Jšœ%˜%Jš œŸœŸœŸœŸ œ˜"JšœŸœŸœŸœ˜#šŸœŸ˜JšœŸœ˜%šŸœ˜ JšœŸœ ˜3šœ Ÿœ˜Jš œŸœ ŸœŸœŸœ˜:—šŸœ ŸœŸœ˜#Jšœ(˜(Jšœ Ÿœ˜J˜—Jšœ˜J˜——Jšœ"˜"JšœŸœ˜JšœŸœ"˜+JšŸœ7˜9JšœŸœ˜JšœŸœ˜šŸœŸ˜ JšŸœŸœ˜Jš œŸœŸœŸœŸœ ˜6Jš œŸœŸœŸœ Ÿœ ˜5Jš œŸœŸœŸœ Ÿœ˜;Jš œŸœŸœŸœŸœ ˜5Jš œŸœŸœŸœ Ÿœ ˜4Jš œŸœŸœŸœŸœ ˜5Jš œŸœŸœŸœŸœ ˜6Jš œŸœŸœŸœ Ÿœ ˜3Jš œŸœŸœŸœ Ÿœ ˜4Jš œŸœŸœŸœ Ÿœ ˜4J˜J˜J˜&JšœŸœ˜JšœŸœ˜J˜)J˜(J˜)J˜(J˜)J˜0J˜'Jšœ Ÿœ)˜;J˜(JšŸ˜—JšŸœŸœ ˜JšŸœ ˜JšŸœ˜JšŸœ˜J˜—š  œŸœŸœŸœŸœ ˜CJšŸœŸ ˜#JšŸœ˜šœŸœ˜JšŸœŸœ˜J˜Jšœ1Ÿœ˜WJšœ"Ÿœ˜IJ˜4J˜ JšŸ˜—JšŸœ˜J˜—š œŸœŸ œŸœŸœŸœŸœŸœŸœ ŸœŸ œ˜ZJšŸœŸœŸœŸ ˜!JšŸ˜JšœŸœŸœ "˜AJšœŸœŸœ˜J˜šŸœŸœŸœ Ÿ˜J˜JšŸœ˜—JšŸœ˜—J˜šœ˜J˜J˜J˜J˜J˜J˜J˜—š œŸœŸ œŸœŸœŸœŸœŸœŸœ˜fJšŸœŸ ˜ JšŸœŸœ˜JšœŸœ˜)Jš ŸœŸœŸœ ŸœŸœ˜6šŸœŸœŸœ Ÿ˜JšŸœ ˜ šŸœŸ˜JšœŸ˜JšœŸ˜JšœŸœŸœ ˜)—JšœŸœ˜—JšŸœ˜ JšŸœ˜J˜—š œŸœŸ œŸœŸœŸœŸœ˜SJšŸœŸ ˜$JšŸ˜JšœŸœ˜Jš ŸœŸœŸœŸœŸ˜7JšŸœ˜J˜—š œŸœŸ œŸœŸœŸœŸœ˜TJšŸœŸ ˜'JšŸ˜JšœŸœ˜Jš ŸœŸœŸœŸœ Ÿ˜*JšŸœ˜J˜—š œŸœŸ œŸœŸœŸœŸœ˜NJšŸœŸ ˜#JšŸ˜JšœŸœ˜*JšœŸœ˜šŸœŸ˜J˜JšœŸœ˜ JšŸœ˜—J˜—…—T’