GriffinStyleImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Written by: Maureen Stone, September 20, 1985 3:38:19 pm PDT
DIRECTORY
ControllerMenuDefs USING [SetStyleMenus],
Convert USING [RopeFromInt],
GriffinDefs USING [ShowUserMessage],
GriffinStyle,
GriffinColor USING [StringToColor],
GriffinFontDefs,
Imager USING [Error],
ImagerFont USING [Find, Modify],
ImagerTransformation USING [Rotate, Scale, Transformation, FactoredTransformation, Factor, Concat],
ObjectDefs USING [ObjectProc, ForAllPictureObjects],
Real USING [RoundC],
Rope USING [ROPE, Cat, SkipOver, Find, Substr, Equal],
StyleDefs;
GriffinStyleImpl: CEDAR PROGRAM
IMPORTS ControllerMenuDefs, Convert, GriffinDefs, GriffinColor, Imager, ImagerFont, ImagerTransformation, ObjectDefs, Real, Rope
EXPORTS GriffinStyle
~ BEGIN OPEN GriffinStyle, StyleDefs;
ROPE: TYPE = Rope.ROPE;
currentStyle: StyleHandle;
currentNumber: INT ← 0;
CurrentStyle: PUBLIC PROCEDURE RETURNS [StyleHandle] = {
RETURN[currentStyle];
};
CopyCurrentStyle: PUBLIC PROCEDURE RETURNS [StyleHandle] = {
new: StyleHandle ← NEW[Style];
new^ ← currentStyle^;
IF new.font=NIL THEN ERROR;
new.name ← NextName[];
RETURN[new];
};
SetCurrentStyle: PUBLIC PROC[style: StyleHandle] = {
currentStyle^ ← style^;
ControllerMenuDefs.SetStyleMenus[style];
};
NextName: PUBLIC PROCEDURE RETURNS [ROPE] = {
name: ROPE ← Rope.Cat["Style", Convert.RopeFromInt[currentNumber]];
currentNumber ← currentNumber+1;
RETURN[name];
};
Initialize: PUBLIC PROC = {
currentStyle ← NEW[Style];
currentStyle.color ← GriffinColor.StringToColor["black"];
currentStyle.dashed ← undashed;
currentStyle.firstend ← LineEnd [round, 0, 0, 0, 0, 0];
currentStyle.lastend ← LineEnd [round, 0, 0, 0, 0, 0];
currentStyle.junctiontype ← round;
currentStyle.width ← 64;
currentStyle.fillcolor ← GriffinColor.StringToColor["grey"];
currentStyle.filled ← TRUE;
currentStyle.outlined ← TRUE;
currentStyle.anchor ← left;
currentStyle.stringRotation ← or0;
currentStyle.stringType ← normal;
currentStyle.font ← NIL; --will be initialized by ControllerMenus
currentStyle.fillbackgnd ← FALSE;
currentStyle.backgndcolor ← GriffinColor.StringToColor["white"];
currentStyle.name ← NextName[];
};
Font: TYPE = StyleDefs.Font;
InternalFont: TYPE = GriffinFontDefs.FontDescriptorHandle;
FontSequence: TYPE = REF FontSequenceRec;
FontSequenceRec: TYPE = RECORD[element: SEQUENCE length:NAT OF Font];
StyleSequence: TYPE = REF StyleSequenceRec;
StyleSequenceRec: TYPE = RECORD[element: SEQUENCE length: NAT OF StyleHandle];
CreateStyleList: PUBLIC PROC RETURNS[styles: StyleSequence] = {
next: NAT ← 0;
allStyles: StyleSequence ← NEW[StyleSequenceRec[currentNumber-1]];
proc: ObjectDefs.ObjectProc = {
IF obj.deleted THEN RETURN;
IF FindEquivalentStyle[obj.style, allStyles] = NIL THEN {
allStyles[next] ← obj.style;
next ← next+1;
};
};
IF currentNumber > 1 THEN { --one style for the menus
ObjectDefs.ForAllPictureObjects[proc];
styles ← NEW[StyleSequenceRec[next]];
FOR i: NAT IN [0..styles.length) DO
styles[i] ← allStyles[i];
ENDLOOP;
};
};
CreateFontList: PUBLIC PROC[styles: StyleSequence] RETURNS[fonts: FontSequence] = {
allFonts: FontSequence ← NEW[FontSequenceRec[styles.length]];
next: NAT ← 0;
IF styles=NIL THEN RETURN[NIL];
FOR i: NAT IN [0..allFonts.length) DO
dup: BOOLFALSE;
FOR j: NAT IN [0..next) DO
IF styles[i].font=allFonts[j] THEN {dup ← TRUE; EXIT};
ENDLOOP;
IF NOT dup THEN {allFonts[next] ← styles[i].font; next ← next+1};
ENDLOOP;
fonts ← NEW[FontSequenceRec[next]];
FOR i: NAT IN [0..fonts.length) DO
fonts[i] ← allFonts[i];
ENDLOOP;
RETURN[fonts]
};
NumberOfStyle: PUBLIC PROC[style: StyleHandle, styles: StyleSequence] RETURNS [CARDINAL] = {
found: BOOLEANFALSE;
styleNum: NAT;
FOR styleNum IN [0..styles.length) DO
IF style=styles[styleNum] THEN {found ← TRUE; EXIT};
ENDLOOP;
RETURN[styleNum+1];
};
NumberOfFont: PUBLIC PROC[font: Font, fonts: FontSequence] RETURNS[CARDINAL] = {
found: BOOLEANFALSE;
fontNum: NAT;
FOR fontNum IN [0..fonts.length) DO
IF font=fonts[fontNum] THEN {found ← TRUE; EXIT};
ENDLOOP;
RETURN[fontNum+1];
};
FindEquivalentStyle: PUBLIC PROC[style: StyleHandle, styles: StyleSequence] RETURNS [StyleHandle] = {
IF style=NIL OR styles=NIL THEN RETURN[NIL];
FOR i: NAT IN [0..styles.length) DO
IF styles[i]=NIL THEN EXIT;
IF EquivalentStyles[style, styles[i]] THEN RETURN[styles[i]];
ENDLOOP;
RETURN[NIL];
};
EquivalentStyles: PROC[style1, style2: StyleHandle] RETURNS[BOOLEAN] = {
equal: BOOLFALSE;
IF style1#NIL AND style2#NIL THEN {
name1: ROPE ← style1.name;
name2: ROPE ← style2.name;
style1.name ← style2.name ← NIL;
equal ← style1^=style2^;
style1.name ← name1;
style2.name ← name2;
};
RETURN[equal];
};
InternalFontFromFont: PUBLIC PROC[font: Font] RETURNS[InternalFont] = {
factors: ImagerTransformation.FactoredTransformation ←
ImagerTransformation.Factor[font.charToClient];
ifont: InternalFont ← NEW[GriffinFontDefs.FontDescriptor];
startName: INT ← Rope.SkipOver[s: font.name, skip: "Xerox/PressFonts/"];
startFace: INT ← Rope.Find[s1: font.name, s2: "-"]+1;
faceCode: ROPE ← Rope.Substr[base: font.name, start: startFace, len: 3];
ifont.name ← Rope.Substr[base: font.name, start: startName, len: startFace-startName-1];
ifont.face ← SELECT TRUE FROM
Rope.Equal[faceCode, "MRR", FALSE] => GriffinFontDefs.Regular,
Rope.Equal[faceCode, "MIR", FALSE] => GriffinFontDefs.Italic,
Rope.Equal[faceCode, "BRR", FALSE] => GriffinFontDefs.Bold,
Rope.Equal[faceCode, "BIR", FALSE] => GriffinFontDefs.BoldItalic,
ENDCASE => ERROR;
ifont.rotation ← SELECT Real.RoundC[factors.r1+factors.r2] FROM
0 => GriffinFontDefs.Rot0Degrees,
90 => GriffinFontDefs.Rot90Degrees,
180 => GriffinFontDefs.Rot180Degrees,
270 => GriffinFontDefs.Rot270Degrees,
ENDCASE => ERROR;
ifont.points ← Real.RoundC[factors.s.x];
RETURN[ifont];
};
FontFromInternalFont: PUBLIC PROC[ifont: InternalFont] RETURNS[Font] = {
Griffin internal fonts use a short name like TimesRoman or Helvetica.
Assume here Xerox/PressFonts/ for all names
transformation: ImagerTransformation.Transformation;
face: ROPESELECT ifont.face FROM
GriffinFontDefs.Regular => "-MRR",
GriffinFontDefs.Italic => "-MIR",
GriffinFontDefs.Bold => "-BRR",
GriffinFontDefs.BoldItalic => "-BIR",
ENDCASE => ERROR;
name: ROPE ← Rope.Cat["Xerox/PressFonts/",ifont.name, face];
font: StyleDefs.Font ← ImagerFont.Find[name ! Imager.Error => {
GriffinDefs.ShowUserMessage[error.explanation];
GOTO error;
}];
transformation ← SELECT ifont.rotation FROM
GriffinFontDefs.Rot0Degrees => ImagerTransformation.Rotate[0],
GriffinFontDefs.Rot90Degrees => ImagerTransformation.Rotate[90],
GriffinFontDefs.Rot180Degrees => ImagerTransformation.Rotate[180],
GriffinFontDefs.Rot270Degrees => ImagerTransformation.Rotate[270],
ENDCASE => ERROR;
transformation ←
ImagerTransformation.Concat[transformation, ImagerTransformation.Scale[ifont.points]];
font ← ImagerFont.Modify[font, transformation];
RETURN[font];
EXITS error => RETURN[NIL];
};
ComputeStringType: PUBLIC PROC[stringRotation: StyleDefs.StringRotation,font: StyleDefs.Font] RETURNS[StyleDefs.StringType] = {
ifont: InternalFont ← InternalFontFromFont[font];
stringR: INTSELECT stringRotation FROM
or0 =>0, or90 => 90, or180 => 180, or270 => 270, ENDCASE => ERROR;
fontR: INTSELECT ifont.rotation FROM
GriffinFontDefs.Rot0Degrees => 0,
GriffinFontDefs.Rot90Degrees => 90,
GriffinFontDefs.Rot180Degrees => 180,
GriffinFontDefs.Rot270Degrees => 270,
ENDCASE => ERROR;
IF stringR=fontR THEN RETURN[normal] ELSE RETURN[stack];
};
END.