DIRECTORY CIFS USING [dontCheck, Error, GetFC, OpenButDontHandleError, read], Convert USING [ValueToRope], File USING [Capability, GetSize, PageCount], Graphics USING [FontRef], GraphicsOps USING [UnsafeNewFont], Rope USING [Cat, Equal, Fetch, FromChar, ROPE, Size], Runtime USING [CallDebugger], Space USING [Create, Handle, LongPointer, Map, PageCount, virtualMemory], UserProfile USING [Number, Token], VFonts; VFontsImpl: CEDAR PROGRAM IMPORTS CIFS, Convert, File, GraphicsOps, Rope, Runtime, Space, UserProfile, VFonts EXPORTS VFonts SHARES VFonts = BEGIN OPEN VFonts; defaultFont: PUBLIC VFonts.Font _ NIL; defaultGFont: PUBLIC Graphics.FontRef _ NIL; Error: PUBLIC ERROR [code: VFonts.ErrorCode] = CODE; Strike: TYPE = LONG POINTER TO StrikeObject; StrikeObject: TYPE = RECORD [header: StrikeHeader, body: StrikeBody]; StrikeHeader: TYPE = RECORD [ bits: StrikeBits, min: CARDINAL, max: CARDINAL, maxwidth: CARDINAL]; StrikeBits: TYPE = RECORD [ newStyle: BOOL, indexed: BOOL, fixed: BOOL, kerned: BOOL, pad: [0..7777B]]; BoundingBox: TYPE = RECORD [ FontBBox, FontBBoy, FontBBdx, FontBBDy: INTEGER]; StrikeBody: TYPE = RECORD [ length: CARDINAL, ascent: CARDINAL, descent: CARDINAL, xoffset: CARDINAL, raster: CARDINAL, bitmap: ARRAY [0..0) OF WORD]; StringWidth: PUBLIC PROC [string: Rope.ROPE, font: VFonts.Font _ defaultFont] RETURNS [width: [0..LAST[INTEGER]]] = BEGIN width _ 0; FOR i: INT IN [0..Rope.Size[string]) DO width _ width + VFonts.CharWidth[Rope.Fetch[string, i], font] ENDLOOP; END; Initialize: PROC [font: VFonts.Font] = TRUSTED BEGIN strike: Strike = font.address; c: CHARACTER; bits: StrikeBits = strike.header.bits; IF ~bits.newStyle THEN ERROR Error[illegalFormat]; IF bits.indexed THEN ERROR Error[illegalFormat]; font.kerned _ bits.kerned; font.min _ LOOPHOLE[strike.header.min]; font.max _ LOOPHOLE[strike.header.max]; IF font.min NOT IN [0C..177C] THEN ERROR Error[illegalFormat]; IF font.max NOT IN [0C..177C] THEN ERROR Error[illegalFormat]; font.ascent _ strike.body.ascent; font.height _ strike.body.ascent + strike.body.descent; font.raster _ strike.body.raster; font.maxWidth _ strike.header.maxwidth; SetFontAddresses[font]; FOR c IN [font.min..MIN[font.max, 176C]] DO font.width[c] _ XInSegment[c+1, font] - XInSegment[c, font] ENDLOOP; FOR c IN [0C..font.min) DO font.width[c] _ font.width[font.min] ENDLOOP; FOR c IN (MIN[font.max, 176C]..177C] DO font.width[c] _ font.width[font.min] ENDLOOP; font.width[15C] _ font.width[40C]; -- CR width hack END; SetFontAddresses: PROC [font: Font] = TRUSTED INLINE BEGIN strike: Strike = font.address; font.bitmap _ @strike.body.bitmap + (IF font.kerned THEN SIZE[BoundingBox] ELSE 0); font.xInSegment _ LOOPHOLE[font.bitmap, LONG POINTER] + font.raster*font.height - LOOPHOLE[font.min, INTEGER]; END; fontChain: Font _ NIL; EstablishFont: PUBLIC PROC [family: Rope.ROPE, size: CARDINAL, bold: BOOL _ FALSE, italic: BOOL _ FALSE, defaultOnFailure: BOOL _ TRUE] RETURNS [font: Font] = BEGIN IF size#10 AND Rope.Equal[family, "Tioga", FALSE] THEN family _ "TimesRoman"; FOR font _ fontChain, font.next UNTIL font=NIL DO IF size=font.size AND bold=font.bold AND italic=font.italic AND Rope.Equal[family, font.family, FALSE] THEN RETURN [font]; ENDLOOP; RETURN[NewFont[family, size, bold, italic, defaultOnFailure]]; END; NewFont: PROC [family: Rope.ROPE, size: CARDINAL, bold, italic, defaultOnFailure: BOOL] RETURNS [font: Font] = BEGIN trialName: Rope.ROPE; IF bold OR italic THEN BEGIN trialName _ Rope.Cat[trialName, family]; IF size#0 THEN trialName _ Rope.Cat[trialName, Convert.ValueToRope[[unsigned[size]]]]; IF bold THEN trialName _ Rope.Cat[trialName, Rope.FromChar['B]]; IF italic THEN trialName _ Rope.Cat[trialName, Rope.FromChar['I]]; trialName _ Rope.Cat[trialName, ".strike"]; IF (font _ LoadFont[trialName]) = NIL THEN BEGIN -- try to match size&family FOR f: Font _ fontChain, f.next UNTIL f=NIL DO IF size=f.size AND ~f.bold AND ~f.italic AND Rope.Equal[family, f.family, FALSE] THEN { font _ CopyFont[f]; IF bold THEN font.synthBold _ TRUE; IF italic THEN font.synthItalic _ TRUE; EXIT}; ENDLOOP; END; IF font=NIL THEN -- lose, give up {IF ~defaultOnFailure THEN Error[fontNotFound] ELSE trialName _ NIL} ELSE IF font.gFont=NIL THEN TRUSTED { font.gFont _ LOOPHOLE[GraphicsOps.UnsafeNewFont[font.address]]}; END; IF font=NIL THEN BEGIN -- no luck yet trialName _ Rope.Cat[trialName, family]; IF size#0 THEN trialName _ Rope.Cat[trialName, Convert.ValueToRope[[unsigned[size]]]]; trialName _ Rope.Cat[trialName, ".strike"]; IF (font _ LoadFont[trialName])=NIL THEN -- lose {IF ~defaultOnFailure THEN Error[fontNotFound] ELSE font _ CopyFont[defaultFont]} ELSE TRUSTED {font.gFont _ LOOPHOLE[GraphicsOps.UnsafeNewFont[font.address]]}; IF bold THEN font.synthBold _ TRUE; IF italic THEN font.synthItalic _ TRUE; END; font.family _ family; font.size _ size; font.bold _ bold; font.italic _ italic; font.next _ fontChain; fontChain _ font; IF font.size=10 AND ~font.bold AND ~font.italic AND Rope.Equal[font.family, "Tioga", FALSE] THEN font.ascent _ 9; -- horrible patch to compensate for bad baseline END; LoadFont: PROC [fileName: Rope.ROPE] RETURNS [font: Font] = TRUSTED BEGIN file: File.Capability; pages: File.PageCount; size: Space.PageCount; space: Space.Handle; IF Rope.Fetch[fileName] # '/ THEN fileName _ Rope.Cat[fontDir, fileName]; file _ CIFS.GetFC[CIFS.OpenButDontHandleError[fileName, CIFS.read+CIFS.dontCheck ! CIFS.Error => CHECKED {GOTO Punt}]]; pages _ File.GetSize[file]; size _ IF pages<20 THEN pages ELSE ERROR; space _ Space.Create[size: size, parent: Space.virtualMemory]; Space.Map[space: space, window: [file: file, base: 1]]; -- first page is 1! font _ NEW[FontObject]; font.address _ Space.LongPointer[space]; Initialize [font]; EXITS Punt => {RETURN[NIL]} END; CopyFont: PROC [font: Font] RETURNS [Font] = INLINE {RETURN[NEW[FontObject _ font^]]}; CreateDefaultFont: PROC = BEGIN err: BOOL _ FALSE; defaultFamily: Rope.ROPE _ UserProfile.Token["DefaultFontFamily", "Tioga"]; defaultSize: CARDINAL _ UserProfile.Number["DefaultFontSize", 10]; defaultFont _ EstablishFont[defaultFamily, defaultSize, FALSE ! ANY => {err _ TRUE; CONTINUE}]; IF err AND (defaultSize#10 OR ~Rope.Equal["Tioga", defaultFamily, FALSE]) THEN BEGIN err _ FALSE; defaultFont _ EstablishFont["Tioga", 10, FALSE ! CIFS.Error => CHECKED {err _ TRUE; CONTINUE}]; END; IF err THEN BEGIN -- try IVY err _ FALSE; defaultFont _ EstablishFont["/Ivy/Tioga/StrikeFonts/Tioga", 10, FALSE ! CIFS.Error => CHECKED {err _ TRUE; CONTINUE}]; END; IF err THEN DO TRUSTED {Runtime.CallDebugger["Couldn't get any fonts!"L]}; ENDLOOP; defaultGFont _ defaultFont.gFont; END; fontDir: Rope.ROPE = "/Indigo/Tioga/StrikeFonts/"; CreateDefaultFont[]; END. ψVFontsImpl.mesa; Last Edited by McGregor, October 4, 1982 11:16 am Last Edited by: Maxwell, January 3, 1983 1:07 pm Procedures horrible hack to conpensate for lack of other size Tioga fonts substitute Tioga10.strike for user's failed choice Κ +– "Mesa" style˜JšΟc™Jš1™1Jšœ0™0J˜šΟk ˜ Jšžœžœ9˜CJšœžœ˜Jšœžœ"˜,Jšœ žœ ˜Jšœ žœ˜"Jšœžœžœ˜5Jšœžœ˜Jšœžœ>˜IJšœ žœ˜"J˜J˜—Jšœ ž ˜JšžœžœG˜SJšžœ˜Jšžœ žœžœ˜"J˜Jšœ žœžœ˜&Jšœžœžœ˜,Jšœžœžœžœ˜4J˜Jšœžœžœ˜,Jšœžœžœ*˜EJ˜šœžœžœ˜J˜Jšœžœ˜Jšœžœ˜Jšœ žœ˜J˜—šœ žœžœ˜Jšœ žœ˜Jšœ žœ˜Jšœžœ˜ Jšœžœ˜ J˜J˜—šœ žœžœ˜Jšœ(žœ˜1J˜—šœ žœžœ˜Jšœžœ˜Jšœžœ˜Jšœ žœ˜Jšœ žœ˜Jšœžœ˜Jšœžœžœžœ˜J˜—Jš ™ J˜šΟn œžœžœžœ"˜MJšžœ žœžœž˜+J˜ šžœžœžœž˜'J˜=Jšžœ˜—Jšžœ˜J˜—šŸ œžœ˜&Jšž ˜ J˜Jšœž œ˜ J˜&Jšžœžœžœ˜2Jšžœžœžœ˜0J˜Jšœ žœ˜'Jšœ žœ˜'Jš žœ žœžœ žœžœ˜>Jš žœ žœžœ žœžœ˜>J˜!J˜7J˜!J˜'J˜šžœžœ žœž˜+J˜;Jšžœ˜—Jšžœžœžœ&žœ˜HJš žœžœžœžœ&žœ˜UJšœ#˜3Jšžœ˜J˜—šŸœžœžœž˜:J˜Jš œ%žœ žœžœžœ˜S˜Jšžœžœžœ˜?Jšžœ žœ˜—Jšžœ˜J˜—Jšœžœ˜J˜šŸ œžœžœžœžœžœžœ˜RJš œžœžœžœžœ˜4Jšžœž˜J˜Jšžœ žœžœžœ˜MJš>™>J˜šžœžœžœž˜1šžœžœž˜(šœžœ!žœ˜=Jšžœžœ˜——Jšžœ˜J˜—Jšžœ8˜>Jšžœ˜J˜—š Ÿœžœžœžœ"žœ˜WJšžœž˜J˜Jšœžœ˜J˜šžœžœžœž˜J˜(JšžœžœH˜VJšžœžœ4˜@Jšžœžœ4˜BJ˜+J˜š žœ žœžœžœ˜Lšžœžœžœž˜.š žœ žœ žœ žœžœ˜PJšžœ˜J˜Jšžœžœžœ˜#Jšžœžœžœ˜'Jšžœ˜—Jšžœ˜—Jšžœ˜—šžœžœžœ˜!Jš œžœžœžœ žœ˜D—š žœžœ žœžœžœ˜%Jšœ ž œ+˜@—Jšžœ˜J˜—š žœžœžœžœ˜%J˜(JšžœžœH˜VJ˜+šžœžœžœ˜0šœžœžœ˜.Jšžœ˜"——Jšžœžœžœ+˜NJšžœžœžœ˜#Jšžœžœžœ˜'Jšžœ˜J˜—J˜J˜J˜J˜J˜J˜J˜J˜š žœžœ žœžœ"žœ˜[Jšžœ0˜F—Jšžœ˜J˜—š Ÿœžœžœžœž ˜IJ˜J˜J˜J˜J˜Jšžœžœ(˜IJ˜š œžœžœ"žœžœ ˜PJšœžœ žœžœ ˜&—J˜Jš œžœ žœžœžœ˜)J˜>Jšœ8˜KJ˜Jšœžœ ˜J˜J˜(J˜J˜Jšžœ žœžœ˜Jšžœ˜J˜—Jš Ÿœžœžœ žœžœžœ˜VJ˜šŸœžœž˜Jšœžœžœ˜Jšœžœ3˜KJšœ žœ-˜Bšœ8ž˜=Jšœžœ žœžœ˜!—š žœžœžœ%žœžœž˜TJš2™2Jšœžœ˜ Jš œ)žœžœ žœžœžœ˜_Jšžœ˜—šžœžœžœ ˜Jšœžœ˜ šœ@ž˜EJš œžœ žœžœžœ˜0—Jšžœ˜—Jš žœžœžœžœ5žœ˜SJ˜!Jšžœ˜J˜—Jšœžœ ˜2J˜J˜J˜Jšžœ˜J˜J˜—…—p$“