CDPanelFontsImpl.mesa (part of ChipNDale)
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, June 24, 1983 5:03 pm
last edited Christian Jacobi, December 9, 1985 6:22:35 pm PST
gbb September 13, 1985 3:27:14 pm PDT
DIRECTORY
Ascii,
CD,
CDInstances,
CDCommandOps,
CDLayers,
CDExtras,
CDOps,
CDPanel,
CDPanelFonts,
CDSequencer,
CDTexts,
CDValue,
Convert,
FileNames,
IO,
Rope,
TerminalIO,
UserProfile;
CDPanelFontsImpl: CEDAR MONITOR
IMPORTS Ascii, CDInstances, CDCommandOps, CDExtras, IO, CDLayers, CDOps, CDPanel, 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: REFNEW[INT];
myKey2: REFNEW[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, defaultSize: INT, 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];
};
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.ROPENIL] =
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.ROPENIL, 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<l AND Rope.Fetch[r, n]=' DO n ← n+1 ENDLOOP;
WHILE n<l AND Rope.Fetch[r, l-1]=' DO l ← l-1 ENDLOOP;
RETURN [Rope.Substr[r, n, l-n]]
};
Scan: PROC [r: Rope.ROPE] RETURNS [name: Rope.ROPE, scale: INT←-1] = {
ENABLE IO.EndOfStream => GOTO exit;
name ← SkipSpaces[r];
IF ~Rope.IsEmpty[name] THEN {
s: IO.STREAMIO.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: BOOLFALSE] RETURNS [name: Rope.ROPENIL] =
BEGIN
IF f#NIL THEN {
name ← f.supposedName;
IF ~full THEN name ← FileNames.GetShortName[name];
IF f.scaleI#lambda THEN name ← name.Concat[CDExtras.ToLambda[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�[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.AddAnObject[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;
fontNameList: LIST OF Rope.ROPE = LIST["Template64", "Gates32", "Helvetica18", "Helvetica14", "Helvetica12", "Helvetica10I", "Helvetica10", "Helvetica8I", "Helvetica8", "Helvetica7"];
CDValue.EnregisterKey[$defaultFontList, NIL, $chj];
CDValue.EnregisterKey[$currentFont, NIL, $chj];
CDValue.EnregisterKey[$panelFontRope, NIL, $chj];
CDValue.Store[NIL, $defaultFontList, fontNameList];
UserProfile.CallWhenProfileChanges[NoteProfileChange];
END.
Edited on January 18, 1985 1:13:03 pm PST, by Beretta
Eliminated alternate font stuff.
changes to: FontForIndex: if a font cannot be made, $CDxCompatibilityFont is choosen, CDIO.MakeName is called to put wDir: "/Indigo/AltoFonts/" and ext: "Strike".
Edited on May 31, 1985 1:35:21 pm PDT, by Jacobi
redone completely for Cedar 6.0
gbb September 13, 1985 3:26:19 pm PDT
changes to: ChangeFontComm: Change is applied to all selected instances.
Edited on October 24, 1985 7:04:36 pm PDT, by Jacobi
Made technology independent
Edited on December 9, 1985 6:08:39 pm PST, by Jacobi
Scaling into same rope as font