-- TexFont.mesa -- Mesa 6 version -- Last changed by Doug Wyatt, September 23, 1980 3:58 PM DIRECTORY TexDefs: FROM "TexDefs", TexErrorDefs: FROM "TexErrorDefs", TexFileDefs: FROM "TexFileDefs", TexFontDefs: FROM "TexFontDefs", TexGlueDefs: FROM "TexGlueDefs", TexIODefs: FROM "TexIODefs", TexMemDefs: FROM "TexMemDefs", TexStringDefs: FROM "TexStringDefs", TfmDefs: FROM "TfmDefs", AltoFileDefs: FROM "AltoFileDefs", DirectoryDefs: FROM "DirectoryDefs", ImageDefs: FROM "ImageDefs", SegmentDefs: FROM "SegmentDefs", StreamDefs: FROM "StreamDefs", StringDefs: FROM "StringDefs"; TexFont: PROGRAM IMPORTS TexFileDefs,TexErrorDefs,TexGlueDefs,TexIODefs, TexMemDefs,TexStringDefs, DirectoryDefs,ImageDefs,StreamDefs,StringDefs EXPORTS TexFontDefs = BEGIN OPEN TexDefs,TfmDefs,TexFontDefs; FontDescriptor: TYPE = RECORD [ finfo: POINTER TO FInfoArray, wdbase: POINTER TO DimnArray, -- widths htbase: POINTER TO DimnArray, -- heights dpbase: POINTER TO DimnArray, -- depths icbase: POINTER TO DimnArray, -- italic corrections krnbase: POINTER TO DimnArray, -- kerns ligbase: POINTER TO LigTable, -- ligature table extbase: POINTER TO ExtTable, -- extension table parbase: POINTER TO DimnArray, -- parameters glue: TexGlueDefs.GluePtr, -- font glue header: FontHeader, -- name, micasize, type, and face fh: SegmentDefs.FileHandle -- the file handle ]; FontDescriptorPtr: TYPE = POINTER TO FontDescriptor; FontsArray: TYPE = ARRAY Font OF FontDescriptorPtr; fonts: POINTER TO FontsArray; FontProblem: PUBLIC SIGNAL = CODE; FontDefined: PUBLIC PROCEDURE[f: Font] RETURNS[BOOLEAN] = BEGIN RETURN[fonts[f]#NIL] END; ReadFontInfo: PUBLIC PROCEDURE[name: STRING, f: Font] = BEGIN OPEN StreamDefs,TexFileDefs; fdp: FontDescriptorPtr←NIL; tfm: TfmHeader; fdsize: CARDINAL=SIZE[FontDescriptor]; tfsize: CARDINAL; p: POINTER; fh: FileHandle; stream: StreamHandle←NIL; ReadWords: PROCEDURE[p: POINTER, nw: CARDINAL] = BEGIN IF ReadBlock[stream,p,nw]#nw THEN SIGNAL FontProblem; END; IF FontDefined[f] THEN SIGNAL FontProblem; fh←OpenFileFromFP[LookupTfmFile[name], read !LookupFailed => BEGIN OPEN TexIODefs,TexErrorDefs; BeginError; Ws["Lookup failed on "L]; Ws[name]; Error[EndError[]]; GOTO Fail; END]; stream←CreateWordStream[file: fh, access: Read]; ReadWords[@tfm,SIZE[TfmHeader]]; BEGIN OPEN tfm; tfsize←SIZE[FInfoArray]+nw+nh+nd+ni+nk+nl+ne+np END; fdp←TexMemDefs.AllocMem[fdsize+tfsize]; ReadWords[(p←fdp+fdsize),tfsize]; stream.destroy[stream]; stream←NIL; fdp.finfo←p; p←p+SIZE[FInfoArray]; fdp.wdbase←p; p←p+tfm.nw; fdp.htbase←p; p←p+tfm.nh; fdp.dpbase←p; p←p+tfm.nd; fdp.icbase←p; p←p+tfm.ni; fdp.krnbase←p; p←p+tfm.nk; fdp.ligbase←p; p←p+tfm.nl; fdp.extbase←p; p←p+tfm.ne; fdp.parbase←p; -- p←p+tfm.np; MakeFontGlue[fdp]; fdp.header←tfm.header; fdp.fh←fh; fonts[f]←fdp; EXITS Fail => NULL; --ERROR Quit;-- END; MakeFontGlue: PROCEDURE[fdp: FontDescriptorPtr] = BEGIN OPEN TexGlueDefs; -- make a GlueSpec for the font's space glue fdp.glue←MakeGlue[]; fdp.glue.refs←infRefs; fdp.glue.space←fdp.parbase[spacewd]; fdp.glue.flex[str]←[regular, fdp.parbase[spacestr]]; fdp.glue.flex[shr]←[regular, fdp.parbase[spaceshr]]; END; GetFont: PROCEDURE[f: Font] RETURNS[FontDescriptorPtr] = INLINE BEGIN RETURN[fonts[f]] END; CharWd: PUBLIC PROCEDURE[fc: FChar] RETURNS[Dimn] = BEGIN fdp: FontDescriptorPtr←GetFont[fc.font]; RETURN[fdp.wdbase[fdp.finfo[fc.char].wd]]; END -- of CharWd --; CharHt: PUBLIC PROCEDURE[fc: FChar] RETURNS[Dimn] = BEGIN fdp: FontDescriptorPtr←GetFont[fc.font]; RETURN[fdp.htbase[fdp.finfo[fc.char].ht]]; END -- of CharHt --; CharDp: PUBLIC PROCEDURE[fc: FChar] RETURNS[Dimn] = BEGIN fdp: FontDescriptorPtr←GetFont[fc.font]; RETURN[fdp.dpbase[fdp.finfo[fc.char].dp]]; END -- of CharDp --; CharIc: PUBLIC PROCEDURE[fc: FChar] RETURNS[Dimn] = BEGIN fdp: FontDescriptorPtr←GetFont[fc.font]; RETURN[fdp.icbase[fdp.finfo[fc.char].ic]]; END -- of CharIc --; pindex: ARRAY FontParType OF FPIndex ← [slant,xheight,quad,extraspace]; FontPar: PUBLIC PROCEDURE[f: Font, p: FontParType] RETURNS[Dimn] = BEGIN fdp: FontDescriptorPtr←GetFont[f]; IF p=extraspace AND fdp.header.type=symbol THEN RETURN[0] ELSE RETURN[fdp.parbase[pindex[p]]]; END -- of FontPar --; sindex: ARRAY SyParType OF FPIndex ← [mathspace,num1,num2,num3,denom1,denom2,sup1,sup2,sup3,sub1,sub2, supdrop,subdrop,delim1,delim2,axisheight]; SyPar: PUBLIC PROCEDURE[f: Font, s: SyParType] RETURNS[Dimn] = BEGIN fdp: FontDescriptorPtr←GetFont[f]; SELECT fdp.header.type FROM symbol => RETURN[fdp.parbase[sindex[s]]]; ENDCASE => SIGNAL FontProblem; RETURN[0]; END -- of SyPar --; eindex: ARRAY ExParType OF FPIndex ← [defaultrulethickness,bigopspacing1,bigopspacing2, bigopspacing3,bigopspacing4,bigopspacing5]; ExPar: PUBLIC PROCEDURE[f: Font, e: ExParType] RETURNS[Dimn] = BEGIN fdp: FontDescriptorPtr←GetFont[f]; SELECT fdp.header.type FROM mathex => RETURN[fdp.parbase[eindex[e]]]; ENDCASE => SIGNAL FontProblem; RETURN[0]; END -- of ExPar --; FontGlue: PUBLIC PROCEDURE[f: Font] RETURNS[TexGlueDefs.GluePtr] = BEGIN fdp: FontDescriptorPtr←GetFont[f]; RETURN[fdp.glue]; END -- of FontGlue --; FontHdr: PUBLIC PROCEDURE[f: Font] RETURNS[POINTER TO FontHeader] = BEGIN fdp: FontDescriptorPtr←GetFont[f]; RETURN[@fdp.header]; END -- of FontHdr --; Ligature: PUBLIC PROCEDURE[fc: FChar, nextc: Char] RETURNS[type: LigType, info: LigInfo] = BEGIN fdp: FontDescriptorPtr←GetFont[fc.font]; WITH lg:fdp.finfo[fc.char].lg SELECT FROM lig => BEGIN i: CARDINAL←lg.i; entry: LigEntry; DO IF (entry←fdp.ligbase[i]).next=nextc THEN WITH e:entry SELECT FROM ligature => RETURN[lig,[lig[e.lig]]]; kern => RETURN[krn,[krn[fdp.krnbase[e.k]]]]; ENDCASE; IF entry.stop THEN EXIT ELSE i←i+1; ENDLOOP; END; ENDCASE; RETURN[none,[none[]]]; END; NextLarger: PUBLIC PROCEDURE[fc: FChar] RETURNS[type: LargerType, info: LargerInfo] = BEGIN fdp: FontDescriptorPtr←GetFont[fc.font]; WITH lg:fdp.finfo[fc.char].lg SELECT FROM next => BEGIN type←nextlarger; info←[nextlarger[lg.c]] END; ext => BEGIN type←extensible; info←[extensible[[fc.font,lg.i]]] END; ENDCASE => BEGIN type←none; info←[none[]] END; RETURN[type,info]; END; xpart: ARRAY TfmDefs.ExtPart OF TexFontDefs.ExtPart = [top, mid, bot, ext]; ExtensionInfo: PUBLIC PROCEDURE[xinfo: ExtInfo] RETURNS[ExtArray] = BEGIN fdp: FontDescriptorPtr←GetFont[xinfo.font]; xarray: ExtArray; xentry: ExtEntry←fdp.extbase[xinfo.index]; p: TfmDefs.ExtPart; xc: TfmDefs.ExtChar; FOR p IN TfmDefs.ExtPart DO xc←xentry[p]; xarray[xpart[p]]←[xc.present, [xinfo.font,xc.char]]; ENDLOOP; RETURN[xarray]; END; FP: TYPE = AltoFileDefs.FP; TfmDescriptor: TYPE = RECORD[link: TfmPtr, name: STRING, fp: FP]; TfmPtr: TYPE = POINTER TO TfmDescriptor; tfmlist: TfmPtr←NIL; AddTfmFile: PROCEDURE[name: STRING, fp: POINTER TO FP] = BEGIN tfm: TfmPtr; tfm←TexMemDefs.AllocMem[SIZE[TfmDescriptor]]; tfm↑←[link: tfmlist, name: TexStringDefs.CopyString[name], fp: fp↑]; tfmlist←tfm; END; LookupTfmFile: PROCEDURE[name: STRING] RETURNS[fp: POINTER TO FP] = BEGIN tfm: TfmPtr; FOR tfm←tfmlist,tfm.link UNTIL tfm=NIL DO IF StringDefs.EquivalentString[name,tfm.name] THEN RETURN[@tfm.fp]; ENDLOOP; SIGNAL TexFileDefs.LookupFailed[name]; END; FindTfmFiles: PROCEDURE = BEGIN name: STRING←[80]; ext: STRING←[30]; TestTfm: PROCEDURE[fp: POINTER TO FP, filename: STRING] RETURNS[BOOLEAN] = BEGIN name.length←ext.length←0; TexFileDefs.NameAndExtension[filename,name,ext]; IF StringDefs.EquivalentString[ext,"tfm"L] THEN AddTfmFile[name,fp]; RETURN[FALSE]; END; DirectoryDefs.EnumerateDirectory[TestTfm]; END; FontCleanupItem: ImageDefs.CleanupItem ← [link: , proc: FontCleanupProc, mask: ImageDefs.CleanupMask[Restore]]; FontCleanupProc: ImageDefs.CleanupProcedure = BEGIN IF why=Restore THEN FindTfmFiles; END; FontInit: PROCEDURE = BEGIN f: Font; fonts←TexMemDefs.AllocMem[SIZE[FontsArray]]; FOR f IN Font DO fonts[f]←NIL ENDLOOP; -- ImageDefs.AddCleanupProcedure[@FontCleanupItem]; FontCleanupProc[Restore]; END; FontInit; END.