<> <> <> <> <> DIRECTORY Ascii, CD, CDInstances, CDCommandOps, CDLayers, CDOps, CDPanel, CDPanelFonts, CDRects, CDSequencer, CDTexts, CDValue, Convert, FileNames, IO, Rope, TerminalIO, UserProfile; CDPanelFontsImpl: CEDAR MONITOR IMPORTS Ascii, CDInstances, CDCommandOps, IO, CDLayers, CDOps, CDPanel, CDRects, CDSequencer, CDTexts, CDValue, Convert, FileNames, Rope, TerminalIO, UserProfile EXPORTS CDPanelFonts = BEGIN fontNum: NAT = 20; FontRange: TYPE = [0..fontNum); FontArray: TYPE = ARRAY FontRange OF CDTexts.CDFont _ ALL[NIL]; LProc: TYPE = PROC [CD.Layer] RETURNS [CD.Layer]; tList: LIST OF CD.Technology _ NIL; myKey: REF _ NEW[INT]; myKey2: REF _ NEW[INT]; NoteTechnology: ENTRY PROC [tech: CD.Technology] RETURNS [first: BOOL] = BEGIN ENABLE UNWIND => NULL; FOR l: LIST OF CD.Technology _ tList, l.rest WHILE l#NIL DO IF l.first=tech THEN RETURN [FALSE]; ENDLOOP; tList _ CONS[tech, tList]; RETURN [TRUE] END; ImplementIt: PUBLIC PROC [tech: CD.Technology, installCommands: BOOL, defaultFonts: LIST OF Rope.ROPE, layerProc: PROC [CD.Layer] RETURNS [CD.Layer]] = TRUSTED BEGIN CDValue.Store[tech, $defaultFontList, defaultFonts]; CDValue.Store[tech, myKey2, NEW[LProc_layerProc]]; IF installCommands THEN { CDSequencer.ImplementCommand[$DrawText, CreateTextComm, tech]; CDSequencer.ImplementCommand[$ChangeText, ChangeTextComm, tech]; CDSequencer.ImplementCommand[$ChangeFont, ChangeFontComm, tech]; CDSequencer.ImplementCommand[$ChangeLayer, ChangeLayerComm, tech]; }; IF NoteTechnology[tech].first THEN { CDPanel.DefineButton[tech: tech, name: "font", proc: ChangeDefaultFont]; CDPanel.DefineLabel[tech: tech, name: " ", cdValueKey: $panelFontRope ]; CDPanel.DefineNewLine[tech]; }; Setup[tech]; END; CurrentFont: PUBLIC PROC [d: CD.Design] RETURNS [CDTexts.CDFont] = BEGIN WITH CDValue.Fetch[d, $currentFont, technology] SELECT FROM f: CDTexts.CDFont => RETURN [f]; ENDCASE => RETURN [NIL]; END; FArray: PROC [t: CD.Technology] RETURNS [REF FontArray] = BEGIN ENABLE UNWIND => NULL; WITH CDValue.Fetch[t, myKey] SELECT FROM fa: REF FontArray => RETURN [fa]; ENDCASE => { [] _ CDValue.StoreConditional[t, myKey, NEW[FontArray_ALL[NIL]]]; RETURN [FArray[t]]; } END; SetCurrentFont: PUBLIC PROC [design: REF, font: CDTexts.CDFont, name: Rope.ROPE_NIL] = TRUSTED BEGIN IF font=NIL THEN RETURN; IF name=NIL THEN name _ font.supposedName; CDValue.Store[design, $panelFontRope, name]; CDValue.Store[design, $currentFont, LOOPHOLE[font]]; WITH design SELECT FROM d: CD.Design => CDPanel.RedisplayLabels[d]; ENDCASE => NULL; END; NoteProfileChange: UserProfile.ProfileChangedProc = BEGIN FOR tl: LIST OF CD.Technology _ tList, tl.rest WHILE tl#NIL DO Setup[tl.first]; ENDLOOP; END; SupposedFontName: PROC [t: CD.Technology, fn: INT] RETURNS [fontName: Rope.ROPE, scale: INT] = <<--gets a font name and a scale from user profile or default>> BEGIN DefaultFontName: PROC [fn: INT] RETURNS [name: Rope.ROPE_NIL, scale: INT_-1] = BEGIN rnl: LIST OF Rope.ROPE; WITH CDValue.Fetch[t, $defaultFontList, global] SELECT FROM rl: LIST OF Rope.ROPE => rnl _ rl; ENDCASE => rnl _ fontNameList; FOR l: LIST OF Rope.ROPE _ rnl, l.rest WHILE l#NIL DO IF fn<=0 THEN {name _ l.first; EXIT}; fn _ fn-1; ENDLOOP; IF name#NIL THEN { [name, scale] _ Scan[name]; name _ Rope.Concat["Xerox/TiogaFonts/", name]; } END; SkipSpaces: PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = { n: INT _ 0; l: INT _ Rope.Length[r]; WHILE n GOTO exit; name _ SkipSpaces[r]; IF ~Rope.IsEmpty[name] THEN { s: IO.STREAM _ IO.RIS[name]; IF Ascii.Digit[Rope.Fetch[name]] THEN scale _ IO.GetInt[s]; name _ SkipSpaces[IO.GetLineRope[s]]; }; EXITS exit => NULL }; num: Rope.ROPE = Convert.RopeFromInt[fn]; [fontName, scale] _ Scan[UserProfile.Line[key: Rope.Cat["ChipNDale.", t.name, ".Font", num]]]; <<--for limitted time >> IF ~Rope.IsEmpty[fontName] AND scale<1 THEN scale _ UserProfile.Number[key: Rope.Cat["ChipNDale.", t.name, ".ScaleFont", num], default: t.lambda]; IF Rope.IsEmpty[fontName] THEN [fontName, scale] _ DefaultFontName[fn]; IF scale<1 THEN scale _ t.lambda; END; Setup: PROC [t: CD.Technology] = <<--(re)reads font names for one technology (from user profile)>> BEGIN FontForIndex: PROC [t: CD.Technology, fn: FontRange, fontArray: REF FontArray] = BEGIN fontName: Rope.ROPE; scale: INT; [fontName, scale] _ SupposedFontName[t, fn]; IF fontArray[fn]#NIL AND Rope.Equal[fontName, fontArray[fn].supposedName, FALSE] AND scale=fontArray[fn].scaleI THEN RETURN; IF Rope.IsEmpty[fontName] THEN fontArray[fn] _ NIL ELSE fontArray[fn] _ CDTexts.MakeFont[name: fontName, scale: scale]; END; lastFont: CDTexts.CDFont_NIL; far: REF FontArray _ FArray[t]; IF far#NIL THEN FOR fn: FontRange IN [0..fontNum) DO FontForIndex[t, fn, far]; IF far[fn]#NIL THEN lastFont _ far[fn] ENDLOOP; IF lastFont#NIL THEN SetCurrentFont[t, lastFont, UseName[lastFont, t.lambda]]; END; UseName: PROC [f: CDTexts.CDFont, lambda: INT, full: BOOL_FALSE] RETURNS [name: Rope.ROPE_NIL] = BEGIN IF f#NIL THEN { name _ f.supposedName; IF ~full THEN name _ FileNames.GetShortName[name]; IF f.scaleI#lambda THEN name _ name.Concat[CDCommandOps.LambdaRope[f.scaleI, lambda]] }; IF Rope.IsEmpty[name] THEN name _ " ?? "; END; ChangeDefaultFont: PROC [comm: CDSequencer.Command] = BEGIN n: INT _ 0; lambda: CD.Number _ comm.design.technology.lambda; selected: CDTexts.CDFont_NIL; fa: REF FontArray _ FArray[comm.design.technology]; list: LIST OF Rope.ROPE _ NIL; TerminalIO.WriteRope["change font\n"]; FOR i: INT IN FontRange DO IF fa[i]#NIL THEN list _ CONS[UseName[fa[i], lambda, FALSE], list] ENDLOOP; IF list#NIL THEN n _ TerminalIO.RequestSelection[label: "change font", choice: list]; IF n>0 THEN FOR i: INT DECREASING IN FontRange DO IF fa[i]#NIL THEN { n_n-1; IF n<=0 THEN {selected_fa[i]; EXIT}; }; ENDLOOP; IF selected=NIL THEN TerminalIO.WriteRope["discarded\n"] ELSE { SetCurrentFont[comm.design, selected, UseName[selected, lambda, FALSE]]; TerminalIO.WriteRopes[" ", UseName[selected, lambda, TRUE], " for text inputs\n"]; }; END; CreateTextComm: PROC [comm: CDSequencer.Command] = BEGIN ob: CD.Object; lay: CD.Layer; r: Rope.ROPE; font: CDTexts.CDFont _ CurrentFont[comm.design]; layerProc: REF LProc _ NARROW[CDValue.Fetch[comm.design.technology, myKey2]]; CDPanel.RedisplayLabels[comm.design]; IF font=NIL THEN { TerminalIO.WriteRope["** no font\n"]; RETURN }; r _ TerminalIO.RequestRope["create text >"]; lay _ CDLayers.CurrentLayer[comm.design]; IF layerProc#NIL AND layerProc^#NIL THEN lay _ layerProc[lay]; IF Rope.IsEmpty[r] THEN { TerminalIO.WriteRope["empty text not included\n"]; RETURN }; ob _ CDTexts.CreateText[text: r, font: font, layer: lay]; IF ob=NIL THEN { TerminalIO.WriteRope["not done\n"]; RETURN }; CDOps.IncludeObjectI[design: comm.design, ob: ob, location: comm.pos, orientation: 0]; END; ChangeTextComm: PROC [comm: CDSequencer.Command] = BEGIN inst: CD.Instance ; CDPanel.RedisplayLabels[comm.design]; inst _ CDCommandOps.TheInstance[comm, "change text"]; IF inst#NIL THEN { WITH inst.ob.specificRef SELECT FROM t: CDTexts.TextPtr => { ob: CD.Object; r: Rope.ROPE; TerminalIO.WriteRopes["replace text """, t.text, """ >"]; r _ TerminalIO.RequestRope[]; IF Rope.IsEmpty[r] THEN TerminalIO.WriteRope["empty text not used\n"] ELSE { ob _ CDTexts.CreateText[text: r, font: t.cdFont, layer: inst.ob.layer]; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[inst]]; IF ob#NIL THEN inst.ob _ ob; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[inst], FALSE]; } } ENDCASE => TerminalIO.WriteRope["selected ob is not text; not done\n"]; }; END; ChangeFontComm: PROC [comm: CDSequencer.Command] = BEGIN font: CDTexts.CDFont _ CurrentFont[comm.design]; CDPanel.RedisplayLabels[comm.design]; IF font=NIL THEN { TerminalIO.WriteRope["** no font\n"]; RETURN }; FOR il: CD.InstanceList _ CDOps.InstList[comm.design], il.rest WHILE il#NIL DO IF il.first.selected AND CDTexts.IsText[il.first.ob] THEN { ob: CD.Object _ CDTexts.CreateText[ text: NARROW[il.first.ob.specificRef, CDTexts.TextPtr].text, font: font, layer: il.first.ob.layer]; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[il.first]]; IF ob#NIL THEN il.first.ob _ ob; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[il.first], FALSE] } ENDLOOP END; ChangeLayerComm: PROC [comm: CDSequencer.Command] = BEGIN layer: CD.Layer = CDLayers.CurrentLayer [comm.design]; CDPanel.RedisplayLabels[comm.design]; IF layer < CD.commentLayer THEN { TerminalIO.WriteRope ["** invalid layer\n"]; RETURN }; FOR il: CD.InstanceList _ CDOps.InstList[comm.design], il.rest WHILE il#NIL DO IF il.first.selected THEN { ob: CD.Object; SELECT il.first.ob.class.objectType FROM $Text => ob _ CDTexts.CreateText [ text: NARROW [il.first.ob.specificRef, CDTexts.TextPtr].text, font: NARROW [il.first.ob.specificRef, CDTexts.TextPtr].cdFont, layer: layer]; $Rect => ob _ CDRects.CreateRect [size: il.first.ob.size, l: layer]; ENDCASE => TerminalIO.WriteRope ["selected ob is not text or rectangle; not done\n"]; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[il.first]]; IF ob#NIL THEN il.first.ob _ ob; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[il.first], FALSE] } ENDLOOP END; fontNameList: LIST OF Rope.ROPE = LIST["Template64", "Gates32", "Helvetica18", "Helvetica14", "Helvetica12", "Helvetica10I", "Helvetica10", "Helvetica8I", "Helvetica8", "Helvetica7"]; CDValue.RegisterKey[$defaultFontList, NIL, $chj]; CDValue.RegisterKey[$currentFont, NIL, $chj]; CDValue.RegisterKey[$panelFontRope, NIL, $chj]; CDValue.Store[NIL, $defaultFontList, fontNameList]; UserProfile.CallWhenProfileChanges[NoteProfileChange]; END. <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>>