DIRECTORY Ascii USING [CR, LF, Lower, SP, TAB, Upper], Atom USING [MakeAtom], FS USING [StreamOpen], IO USING [Close, PutF, int, time, rope, STREAM, GetBlock], RefText USING [Append, ObtainScratch, ReleaseScratch], Rope USING [FromRefText], Terminal USING [BlinkBWDisplay, Current], UFFileManager USING [KeyOfRefText], UFFontDirReader; UFFontDirReaderImpl: CEDAR PROGRAM IMPORTS Ascii, Atom, FS, IO, RefText, Rope, Terminal, UFFileManager EXPORTS UFFontDirReader = BEGIN OPEN UFFontDirReader; EnumerateFontDirectory: PUBLIC PROCEDURE [fontDirectoryName: ROPE, examine: ExamineProc, result: ResultProc] = { stream: IO.STREAM _ FS.StreamOpen[fontDirectoryName]; inputBufferScratch: REF TEXT = RefText.ObtainScratch[128]; fontNameScratch: REF TEXT = RefText.ObtainScratch[64]; codeSchemeScratch: REF TEXT = RefText.ObtainScratch[64]; metricsNameScratch: REF TEXT = RefText.ObtainScratch[64]; graphicsNameScratch: REF TEXT = RefText.ObtainScratch[64]; inputBuffer: REF TEXT _ inputBufferScratch; fontName: REF TEXT _ fontNameScratch; codeScheme: REF TEXT _ codeSchemeScratch; metricsName: REF TEXT _ metricsNameScratch; graphicsName: REF TEXT _ graphicsNameScratch; deviceType: DeviceType _ $Ideal; metricsType: ATOM _ $Nil; graphicsType: ATOM _ $Nil; rotation: REAL _ 0; size, plusSize, minusSize: REAL _ 0; cp: NAT _ 0; locationOfBufferStart: INT _ 0; tokenStart, tokenLength: NAT _ 0; Error: PROC = { stream: IO.STREAM _ FS.StreamOpen["UnifiedFonts.errorLog", $append]; stream.PutF["%g Error at position %g in file %g", IO.time[], IO.int[locationOfBufferStart+tokenStart], IO.rope[fontDirectoryName]]; stream.Close; Terminal.Current[].BlinkBWDisplay; }; GetToken: PROC = { c: CHAR; tokenStart _ tokenStart+tokenLength; tokenLength _ 0; WHILE tokenStart {GetToken[]; dimn _ dimn*72/25.4}; Match["cm"] => {GetToken[]; dimn _ dimn*72/2.54}; Match["in"] => {GetToken[]; dimn _ dimn*72}; Match["bp"] => {GetToken[]}; Match["pt"] => {GetToken[]; dimn _ dimn*72/72.27}; ENDCASE => NULL; }; TokenAsReal: PROC [] RETURNS [real: REAL] = { c: CHAR _ ' ; i: NAT _ tokenStart; num: REAL _ 0; denom: REAL _ 1; WHILE i < inputBuffer.length AND (c _ inputBuffer[i]) IN ['0..'9] DO num _ 10.0*num + (c-'0); i _ i+1; ENDLOOP; IF c='. THEN {i _ i+1; c _ ' ; WHILE i < inputBuffer.length AND (c _ inputBuffer[i]) IN ['0..'9] DO num _ 10.0*num + (c-'0); denom _ 10.0*denom; i _ i+1; ENDLOOP; } ELSE IF c='/ THEN {i _ i+1; denom _ 0; WHILE i < inputBuffer.length AND (c _ inputBuffer[i]) IN ['0..'9] DO denom _ 10.0*denom + (c-'0); i _ i+1; ENDLOOP; }; tokenLength _ i-tokenStart; IF denom=0.0 THEN {Error[]; denom_1}; IF tokenLength=0 THEN Error[]; real _ num/denom; }; Save: PROC[r: REF TEXT] RETURNS[REF TEXT] = { r.length _ 0; RETURN[RefText.Append[to: r, from: inputBuffer, start: tokenStart, len: tokenLength]]; }; AtomFromToken: PROC RETURNS [atom: ATOM] = { scratch: REF TEXT = RefText.ObtainScratch[64]; text: REF TEXT _ Save[scratch]; text[0] _ Ascii.Upper[text[0]]; FOR i: NAT IN [1..text.length) DO text[i] _ Ascii.Lower[text[i]]; ENDLOOP; atom _ Atom.MakeAtom[Rope.FromRefText[text]]; RefText.ReleaseScratch[scratch]; }; RefillBuffer[]; GetToken[]; WHILE tokenLength>0 DO SELECT TRUE FROM Match["DEVICE:"] => {GetToken[]; SELECT TRUE FROM Match["Ideal"] => deviceType _ $Ideal; Match["Spruce"] => deviceType _ $Spruce; Match["Press"] => deviceType _ $Press; Match["Ideal"] => deviceType _ $Screen; ENDCASE => deviceType _ AtomFromToken[]; GetToken[] }; Match["SIZE:"] => {GetToken[]; IF Match["ANY"] THEN {GetToken[]; size _ minusSize _ 0; plusSize _ 1000000.0} ELSE { size _ plusSize _ minusSize _ GetDimn[]; DO SELECT TRUE FROM Match["+"] => {GetToken[]; plusSize _ size + GetDimn[]}; Match["-"] => {GetToken[]; minusSize _ size - GetDimn[]}; Match["+-"] => {r: REAL; GetToken[]; r _ GetDimn[]; plusSize _ size + r; minusSize _ size - r}; ENDCASE => EXIT; ENDLOOP; }; }; Match["ROTATION:"] => {GetToken[]; IF Match["ANY"] THEN rotation _ -360.0 ELSE rotation _ TokenAsReal[]; GetToken[] }; Match["FONTNAME:"] => {GetToken[]; fontName _ Save[fontName]; GetToken[]}; Match["CODESCHEME:"] => {GetToken[]; codeScheme _ Save[codeScheme]; GetToken[]}; Match["METRICS:"] => {GetToken[]; metricsType _ SELECT TRUE FROM Match["TFM"] => $Tfm, Match["STRIKE"] => $Strike, ENDCASE => AtomFromToken[]; GetToken[]; metricsName _ Save[metricsName]; GetToken[]; }; Match["GRAPHICS:"] => {GetToken[]; graphicsType _ SELECT TRUE FROM Match["PRESS"] => $Press, Match["STRIKE"] => $Strike, Match["SD"] => $Sd, ENDCASE => AtomFromToken[]; GetToken[]; graphicsName _ Save[graphicsName]; GetToken[]; }; Match["DEFINEFONT"] => { GetToken[]; IF examine[ candidateFontName: fontName, candidateSize: size, candidateMaxSize: plusSize, candidateMinSize: minusSize, candidateRotation: rotation, candidateDeviceType: deviceType ] THEN { quit: BOOLEAN _ result[ candidateFontName: fontName, candidateSize: size, candidateMaxSize: plusSize, candidateMinSize: minusSize, candidateRotation: rotation, candidateDeviceType: deviceType, metricsType: metricsType, codeScheme: UFFileManager.KeyOfRefText[codeScheme], metricsName: UFFileManager.KeyOfRefText[metricsName], graphicsType: graphicsType, graphicsName: UFFileManager.KeyOfRefText[graphicsName] ]; IF quit THEN EXIT; }; }; ENDCASE => {Error[]; EXIT}; ENDLOOP; RefText.ReleaseScratch[inputBufferScratch]; RefText.ReleaseScratch[fontNameScratch]; RefText.ReleaseScratch[codeSchemeScratch]; RefText.ReleaseScratch[metricsNameScratch]; RefText.ReleaseScratch[graphicsNameScratch]; stream.Close[]; }; END. FUFFontDirReaderImpl.mesa Written January 14, 1983 2:01 pm Last edited by Michael Plass, July 22, 1983 12:00 pm Last edited by Doug Wyatt, November 22, 1983 4:24 pm Gets the next token into inputBuffer[tokenStart] .. inputBuffer[tokenLength-1] Not called often; makes an atom with first char upper case, rest lower case. Κ΅˜Jšœ™Jšœ ™ J™4J™4J˜šΟk ˜ Jš œœœœ œœ ˜,Jšœœ ˜Jšœœ˜Jšœœ œ ˜:Jšœœ)˜6Jšœœ˜Jšœ œ˜)Jšœœ˜#Jšœ˜J˜—unitšœœ˜"Jšœœœ(˜CJšœ˜Jšœœœ˜šΟnœœ œœ/˜pIcodešœœœœ˜5Lšœœœ˜:Lšœœœ˜6Lšœœœ˜8Lšœœœ˜9Lšœœœ˜:Lšœ œœ˜+Lšœ œœ˜%Lšœ œœ˜)Lšœ œœ˜+Lšœœœ˜-L˜L˜ Lšœ œ˜Lšœœ˜Lšœ œ˜Lšœœ˜$Lšœœ˜ Lšœœ˜Lšœœ˜!šžœœ˜Lšœœœ3˜DLšœ2œ œ(œ˜ƒLšœ ˜ Lšœ"˜"Lšœ˜—šžœœ˜LšœN™NLšœœ˜L˜$L˜šœœ(œœ œœ œœ œœœ ˜šLšœ˜Lšœ!œ˜7Lšœ˜—šœ+œœ4œœ œœ œœ œœœ ˜ΆLšœ˜Lšœ/œ˜ELšœ˜—L˜—šž œœ˜šœœœ˜!Jšœ+˜+Jšœ˜—Lšœ!˜!Lšœ9˜9Lšœ˜Lšœl˜lL˜—šžœœœœœœ œ˜ALšœœ˜Lšœœœœ˜0šœœœ˜ Jšœœœœ˜-J˜Jšœ˜—Lšœœ˜ L˜—šžœœœœ˜)Lšœ˜Lšœ ˜ šœœ˜Jšœ1˜1Jšœ1˜1Jšœ,˜,Jšœ˜Jšœ2˜2Jšœœ˜—L˜—šž œœœœ˜-Lšœœ˜ Lšœœ˜Lšœœ˜Lšœœ˜šœœœ ˜DL˜L˜Lšœ˜—šœœ˜šœœœ ˜DL˜L˜L˜Lšœ˜—L˜—šœœœ˜&šœœœ ˜DL˜L˜Lšœ˜—L˜—L˜Lšœ œ˜%Lšœœ ˜Lšœ˜L˜—šžœœœœœœœ˜-L˜ LšœP˜VL˜—šž œœœœ˜,L™LLšœ œœ˜.Lšœœœ˜Lšœ˜šœœœ˜!Jšœ˜Jšœ˜—Lšœ-˜-Lšœ ˜ L˜—Lšœ˜Lšœ ˜ šœ˜Lšœœ˜šœ ˜ Lšœœ˜Lšœ&˜&Lšœ(˜(Lšœ&˜&Lšœ'˜'Lšœ!˜(Lšœ ˜ Lšœ˜—šœ˜Lšœœ9˜Mšœ˜Lšœ(˜(šœœœ˜Jšœ8˜8Jšœ9˜9JšœœH˜_Jšœœ˜Jšœ˜—J˜—Lšœ˜—šœ"˜"Lšœœœ˜ELšœ ˜ Lšœ˜—LšœJ˜JLšœP˜Pšœ!˜!šœ˜Lšœœ˜Lšœ˜Lšœ˜Lšœ˜—Lšœ8˜8Lšœ˜—šœ"˜"šœ˜Lšœœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜—Lšœ:˜:Lšœ˜—šœ˜Lšœ ˜ šœ ˜ Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜L˜—šœ˜šœœ ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ ˜ Lšœ˜Lšœ3˜3Lšœ5˜5Lšœ˜Lšœ6˜6L˜—Lšœœœ˜L˜—Lšœ˜—Lšœœ˜Lšœ˜—Lšœ+˜+Lšœ(˜(Lšœ*˜*Lšœ+˜+Lšœ,˜,L˜L˜—Kšœ˜——…—L$G