CDPanelFontsImpl.mesa (part of ChipNDale)
Copyright © 1983, 1985, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 24, 1983 5:03 pm
Last Edited by: Christian Jacobi, September 24, 1986 4:05:32 pm PDT
DIRECTORY
Ascii,
CD,
CDCallSpecific,
CDCommandOps,
CDLayers,
CDPanel,
CDPanelFonts,
CDPanelFontsExtras,
CDPrivate,
CDSequencer,
CDTexts,
CDTextsExtras,
CDValue,
Convert,
FileNames,
IO,
Rope,
TerminalIO,
UserProfile;
CDPanelFontsImpl:
CEDAR
MONITOR
IMPORTS Ascii, CDCallSpecific, CDCommandOps, IO, CDLayers, CDPanel, CDTexts, CDTextsExtras, CDValue, Convert, FileNames, Rope, TerminalIO, UserProfile
EXPORTS CDPanelFonts, CDPanelFontsExtras
SHARES CDTextsExtras =
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] = {
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]
};
ChangeLayer: CDCallSpecific.CallProc = {
layer:
CD.Layer ←
WITH x
SELECT
FROM
lr: CDPrivate.LayerRef => lr.number,
ENDCASE => CDLayers.CurrentLayer[design];
repaintMe ← TRUE;
inst.ob ← CDTextsExtras.Create[
text: NARROW [inst.ob.specificRef, CDTexts.TextPtr].text,
font: NARROW [inst.ob.specificRef, CDTexts.TextPtr].cdFont,
layer: layer,
flip: CDTextsExtras.IsFlipText[inst.ob]
];
};
ImplementIt:
PUBLIC
PROC [tech:
CD.Technology, installCommands:
BOOL, defaultFonts:
LIST
OF Rope.
ROPE, layerProc:
PROC [
CD.Layer]
RETURNS [
CD.Layer]] = {
CDValue.Store[tech, $defaultFontList, defaultFonts];
CDValue.Store[tech, myKey2, NEW[LProc←layerProc]];
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];
};
CurrentFont:
PUBLIC
PROC [d:
CD.Design]
RETURNS [CDTexts.CDFont] = {
WITH CDValue.Fetch[d, $currentFont, technology]
SELECT
FROM
f: CDTexts.CDFont => RETURN [f];
ENDCASE => RETURN [NIL];
};
FArray:
PROC [t:
CD.Technology]
RETURNS [
REF FontArray] = {
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]];
}
};
SetCurrentFont:
PUBLIC
PROC [design:
REF, font: CDTexts.CDFont, name: Rope.
ROPE←
NIL] = {
IF font=NIL THEN RETURN;
IF name=NIL THEN name ← font.supposedName;
CDValue.Store[design, $panelFontRope, name];
TRUSTED { CDValue.Store[design, $currentFont, LOOPHOLE[font]]; };
WITH design
SELECT
FROM
d: CD.Design => CDPanel.RedisplayLabels[d];
ENDCASE => NULL;
};
NoteProfileChange: UserProfile.ProfileChangedProc
= {
FOR tl:
LIST
OF
CD.Technology ← tList, tl.rest
WHILE tl#
NIL
DO
Setup[tl.first];
ENDLOOP;
};
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
DefaultFontName:
PROC [fn:
INT]
RETURNS [name: Rope.
ROPE←
NIL, scale:
INT←-1] = {
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];
}
};
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.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;
};
Setup:
PROC [t:
CD.Technology] = {
--(re)reads font names for one technology (from user profile)
FontForIndex:
PROC [t:
CD.Technology, fn: FontRange, fontArray:
REF FontArray] = {
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];
};
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]];
};
UseName:
PROC [f: CDTexts.CDFont, lambda:
INT, full:
BOOL←
FALSE]
RETURNS [name: Rope.
ROPE←
NIL] = {
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 ← " ?? ";
};
ChangeDefaultFont:
PROC [comm: CDSequencer.Command] = {
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"];
};
};
LayerForText:
PUBLIC
PROC [layer:
CD.Layer, technology:
REF←
NIL]
RETURNS [lay:
CD.Layer] = {
layerProc: REF LProc;
WITH technology
SELECT
FROM
t: CD.Technology => layerProc ← NARROW[CDValue.Fetch[t, myKey2]];
ENDCASE => NULL;
lay ← layer;
IF layerProc#NIL AND layerProc^#NIL THEN lay ← layerProc[lay];
};
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];
CDCallSpecific.Register[$ChangeLayer, CDTextsExtras.rigidTextClass, ChangeLayer];
CDCallSpecific.Register[$ChangeLayer, CDTextsExtras.flipTextClass, ChangeLayer];
END.