CDTextsCommands.mesa (part of ChipNDale)
Copyright © 1983, 1985, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 24, 1983 5:03 pm
Last edited by: Giordano Beretta, April 8, 1986 5:46:03 pm PST
Last edited by: Christian Jacobi, March 17, 1987 6:05:57 pm PST
DIRECTORY
Ascii,
Atom,
CD,
CDBasics,
CDInstances,
CDLayers,
CDOps,
CDPanel,
CDPanelFonts,
CDPrivate,
CDSequencer,
CDTexts,
Rope,
TerminalIO;
CDTextsCommands: CEDAR MONITOR
IMPORTS Ascii, Atom, CDBasics, CDInstances, CDLayers, CDOps, CDPanel, CDPanelFonts, CDSequencer, CDTexts, Rope, TerminalIO
SHARES CDTexts =
BEGIN
ROPE: TYPE = Rope.ROPE;
CDFont: TYPE = CDTexts.CDFont;
GetTextComm: PROC [comm: CDSequencer.Command] = {
inst: CD.Instance ← CDOps.TheInstance[comm.design, "load text into panel\n"];
IF inst#NIL THEN
IF CDTexts.IsText[inst.ob] THEN {
tp: CDTexts.TextSpecific ← NARROW[inst.ob.specific];
CDPanelFonts.SetCurrentText[comm.design, tp.text];
}
ELSE TerminalIO.PutRope["failed: needs single text selection\n"];
};
GetFontComm: PROC [comm: CDSequencer.Command] = {
inst: CD.Instance ← CDOps.TheInstance[comm.design, "load font into panel\n"];
IF inst#NIL THEN
IF CDTexts.IsText[inst.ob] THEN {
tp: CDTexts.TextSpecific ← NARROW[inst.ob.specific];
CDPanelFonts.SetCurrentFont[comm.design, tp.cdFont];
}
ELSE TerminalIO.PutRope["failed: needs single text selection\n"];
};
ReadDefaultFontComm: PROC [comm: CDSequencer.Command] = {
fontName: Rope.ROPE; scale: INT; font: CDTexts.CDFont;
TerminalIO.PutRope["input font name\n"];
fontName ← TerminalIO.RequestRope[" font name -> "];
scale ← TerminalIO.RequestInt[" pre scale factor*lambda -> "];
IF scale<=0 THEN TerminalIO.PutRope[" bad scale\n"]
ELSE {
font ← CDTexts.MakeFont[fontName, scale];
IF font=NIL
THEN TerminalIO.PutRope[" failed\n"]
ELSE CDPanelFonts.SetCurrentFont[comm.design, font];
}
};
RemoveGarbage: PROC [line: Rope.ROPE] RETURNS [Rope.ROPENIL] = {
leng: INT ← Rope.Length[line];
start: INT ← 0;
WHILE start<leng DO
c: CHAR ← Rope.Fetch[line, start];
IF c=177C OR c<=40C THEN start ← start+1 ELSE EXIT;
ENDLOOP;
WHILE leng>start DO
c: CHAR ← Rope.Fetch[line, leng-1];
IF c=177C OR c<=40C THEN leng ← leng-1 ELSE EXIT;
ENDLOOP;
IF leng>start THEN RETURN [Rope.Substr[line, start, leng-start]];
};
InputText: PROC [design: CD.Design] RETURNS [r: Rope.ROPE] = {
r ← RemoveGarbage[CDPanelFonts.CurrentText[design]];
IF Rope.IsEmpty[r] THEN r ← TerminalIO.RequestRope["text >"];
};
DrawTextComm: PROC [comm: CDSequencer.Command] = {
ob: CD.Object; lay: CD.Layer; r: Rope.ROPE;
font: CDTexts.CDFont;
CDPanel.PutUpAll[comm.design]; -- to propagate the font right
font ← CDPanelFonts.CurrentFont[comm.design];
IF font=NIL THEN CDSequencer.Quit["** no font"];
IF comm.key=$DrawTextTerminal
THEN r ← TerminalIO.RequestRope["create text >"]
ELSE r ← InputText[comm.design];
IF Rope.IsEmpty[r] THEN CDSequencer.Quit["empty text not included"];
lay ← CDLayers.CurrentLayer[comm.design];
lay ← CDPanelFonts.LayerForText[lay, comm.design.technology];
ob ← CDTexts.Create[text: r, font: font, layer: lay];
IF ob=NIL THEN CDSequencer.Quit["not done"];
[] ← CDOps.IncludeObjectI[comm.design, ob, comm.pos];
};
ReplaceTextComm: PROC [comm: CDSequencer.Command] = {
cnt: INT ← 0; rect: CD.Rect;
newText: Rope.ROPE ← InputText[comm.design];
IF Rope.IsEmpty[newText] THEN {TerminalIO.PutRope["no text available\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 {
tp: CDTexts.TextSpecific ← NARROW[il.first.ob.specific];
new: CD.Object ← CDTexts.Create[newText, tp.cdFont, il.first.ob.layer, CDTexts.IsFlipText[il.first.ob]];
IF new=NIL THEN LOOP;
cnt ← cnt + 1;
rect ← CDInstances.InstRectO[il.first];
il.first.ob ← new;
CDOps.Redraw[comm.design, CDBasics.Surround[rect, CDInstances.InstRectO[il.first]]];
}
ENDLOOP;
TerminalIO.PutF1["%g texts replaced\n", [integer[cnt]]];
};
SetFlip: PROC [design: CD.Design, flip: BOOLTRUE] RETURNS [cnt: INT𡤀] = {
FOR il: CD.InstanceList ← CDOps.InstList[design], il.rest WHILE il#NIL DO
IF il.first.selected AND CDTexts.IsText[il.first.ob] THEN
IF (flip AND CDTexts.IsRigidText[il.first.ob]) OR (~flip AND CDTexts.IsFlipText[il.first.ob]) THEN {
ob: CD.Object ← CDTexts.Create[
text: NARROW[il.first.ob.specific, CDTexts.TextSpecific].text,
font: NARROW[il.first.ob.specific, CDTexts.TextSpecific].cdFont,
layer: il.first.ob.layer,
flip: flip
];
IF ob#NIL THEN il.first.ob ← ob;
cnt ← cnt+1
}
ENDLOOP;
IF cnt>0 THEN CDOps.Redraw[design];
};
SetFlipComm: PROC [comm: CDSequencer.Command] = {
cnt: INT ← SetFlip[comm.design, TRUE];
TerminalIO.PutF["%g texts converted to flip mode\n", [integer[cnt]]]
};
SetRigidComm: PROC [comm: CDSequencer.Command] = {
cnt: INT ← SetFlip[comm.design, FALSE];
TerminalIO.PutF["%g texts converted to rigid mode\n", [integer[cnt]]];
};
ChangeSizeComm: PROC [comm: CDSequencer.Command] = {
up: BOOL ← Rope.Find[Atom.GetPName[comm.key], "double", 0, FALSE]>=0;
n: INT ← 0;
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 {
tp: CDTexts.TextSpecific = NARROW[il.first.ob.specific];
oldSize: INTMIN[tp.cdFont.scaleI, 20000]; --large limit, prevent arithmetic overflow
newSize: INTMIN[(IF up THEN oldSize*2 ELSE (oldSize+1)/2), 10000B];
--smaller, binary limit to make going back [after hitting upper limit] nice
IF newSize#oldSize THEN {
newFont: CDTexts.CDFont ← CDTexts.MakeFont[tp.cdFont.supposedName, newSize];
IF newFont#NIL THEN
IF SetInstanceFont[comm.design, il.first, newFont] THEN n ← n+1;
}
}
ENDLOOP;
TerminalIO.PutF["changed size for %g texts\n", [integer[n]]];
};
ChangeFontComm: PROC [comm: CDSequencer.Command] = {
n: INT ← 0; font: CDFont;
CDPanel.PutUpAll[comm.design];
font ← CDPanelFonts.CurrentFont[comm.design];
IF font=NIL THEN CDSequencer.Quit["** no font\n"];
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
IF SetInstanceFont[comm.design, il.first, font] THEN n ← n+1;
ENDLOOP;
TerminalIO.PutF["font changed for %g texts\n", [integer[n]]];
};
ChangeItalic: PROC [fontName: ROPE, italic: BOOL] RETURNS [new: ROPE] = {
pressFontLeng: INT = 17; pressFontName: ROPE = "Xerox/PressFonts/";
tiogaFontLeng: INT = 17; tiogaFontName: ROPE = "Xerox/TiogaFonts/";
leng: INT ← Rope.Length[fontName];
new ← fontName;
IF leng>tiogaFontLeng THEN
IF Rope.Equal[Rope.Substr[fontName, 0, tiogaFontLeng], tiogaFontName, FALSE] THEN {
IF Rope.Equal[Rope.Substr[fontName, 0, tiogaFontLeng], tiogaFontName, FALSE] THEN {
IF italic THEN {
IF Ascii.Upper[Rope.Fetch[fontName, leng-1]]='I THEN RETURN;
RETURN [Rope.Concat[fontName, "I"]];
}
ELSE {
IF Ascii.Upper[Rope.Fetch[fontName, leng-1]]#'I THEN RETURN;
RETURN [Rope.Substr[fontName, 0, leng-1]];
}
}
};
IF leng>pressFontLeng THEN
IF Rope.Equal[Rope.Substr[fontName, 0, pressFontLeng], pressFontName, FALSE] THEN {
IF italic THEN {
IF Ascii.Upper[Rope.Fetch[fontName, leng-1]]='I THEN RETURN;
RETURN [Rope.Replace[fontName, leng-2, 1, "i"]];
}
ELSE {
IF Ascii.Upper[Rope.Fetch[fontName, leng-2]]#'I THEN RETURN;
RETURN [Rope.Replace[fontName, leng-2, 1, "r"]];
}
}
};
SetInstanceFont: PROC [design: CD.Design, text: CD.Instance, font: CDFont] RETURNS [ok: BOOLFALSE] = {
IF font#NIL THEN {
ob: CD.Object ← CDTexts.Create[
text: NARROW[text.ob.specific, CDTexts.TextSpecific].text,
font: font,
layer: text.ob.layer,
flip: CDTexts.IsFlipText[text.ob]];
CDOps.RedrawInstance[design, text];
IF ob#NIL THEN {text.ob ← ob; ok ← TRUE};
CDOps.RedrawInstance[design, text, FALSE];
}
};
SetItalicIzation: PROC [design: CD.Design, comment: BOOL] = {
n: INT ← 0;
FOR w: CD.InstanceList ← CDOps.InstList[design], w.rest WHILE w#NIL DO
IF CDTexts.IsText[w.first.ob] AND w.first.selected THEN {
textPtr: CDTexts.TextSpecific ← NARROW[w.first.ob.specific];
oldFontName: ROPE ← textPtr.cdFont.supposedName;
newFontName: ROPE ← ChangeItalic[oldFontName, comment];
IF ~Rope.Equal[oldFontName, newFontName] THEN {
font: CDFont ← CDTexts.MakeFont[newFontName, textPtr.cdFont.scaleI];
IF SetInstanceFont[design, w.first, font] THEN n ← n+1;
}
}
ENDLOOP;
TerminalIO.PutF["comment property changed for %g texts\n", [integer[n]]];
};
MakeComment: PROC [comm: CDSequencer.Command] = {
SetItalicIzation[comm.design, TRUE]
};
UnMakeComment: PROC [comm: CDSequencer.Command] = {
SetItalicIzation[comm.design, FALSE]
};
CDSequencer.ImplementCommand[$DrawTextTerminal, DrawTextComm];
CDSequencer.ImplementCommand[$DrawText, DrawTextComm];
CDSequencer.ImplementCommand[$ChangeFont, ChangeFontComm];
CDSequencer.ImplementCommand[$CDTextsDoubleSize, ChangeSizeComm];
CDSequencer.ImplementCommand[$CDTextsHalfSize, ChangeSizeComm];
CDSequencer.ImplementCommand[$CDTextsRigid, SetRigidComm];
CDSequencer.ImplementCommand[$CDTextsFlip, SetFlipComm];
CDSequencer.ImplementCommand[$MakeComment, MakeComment];
CDSequencer.ImplementCommand[$UnMakeComment, UnMakeComment];
CDSequencer.ImplementCommand[$GetText, GetTextComm,, doQueue];
CDSequencer.ImplementCommand[$GetFont, GetFontComm,, doQueue];
CDSequencer.ImplementCommand[$ChangeText, ReplaceTextComm];
CDSequencer.ImplementCommand[$ReadFont, ReadDefaultFontComm];
END.