StyleToolConvertImpl.mesa, written by Linda Gass on August 12, 1982 9:42 am
Last Edit by Linda Gass on November 4, 1982 2:28 pm
Last Edited by: Plass, March 28, 1983 2:57 pm
Last Edited by: Beach, February 22, 1984 3:28:18 pm PST
DIRECTORY
IO USING [RIS, GetInt, GetReal, Error, STREAM, PutFR, real],
MessageWindow USING [Append, Blink],
NameSymbolTable USING [Name, nullName, RopeFromName],
NodeStyle USING [FontFace, Real, FontAlphabets, FontUnderlining, LineFormatting, PathType],
Rope USING [Cat, Equal, ROPE, Size],
StyleToolConvert,
StyleToolDefs USING [FontFamilyRec, fontFamilyList],
ViewerClasses USING [Viewer],
ViewerTools USING [GetContents];
StyleToolConvertImpl: CEDAR PROGRAM

IMPORTS IO, MessageWindow, NameSymbolTable, Rope, StyleToolDefs, ViewerTools
EXPORTS StyleToolConvert =
BEGIN OPEN StyleToolDefs;

BadNumber: PUBLIC SIGNAL = CODE;

UnitsType: TYPE = {pt, pc, in, cm, mm, dd, em, en, sp};
pointsPerInch: REAL = 72.27; -- how many points to the inch for consistency
ConversionFactors: ARRAY UnitsType[pt..sp] OF ARRAY UnitsType[pt..sp] OF REAL
 [[1.0,    0.083334, 1/pointsPerInch, 0.03515, 0.3515, 0.9346, 1.0, 1.0, 1.0],
 [12.0,    1.0,  0.166667,   0.42334, 4.2334, 11.214953, 1.0, 1.0, 1.0],
 [pointsPerInch, 6.0,  1.0,    2.54,  25.4,  67.542056, 1.0, 1.0, 1.0],
 [28.453,   2.3623, 0.3937,   1.0,  10.0,  26.6,  1.0, 1.0, 1.0],
 [2.8453,   0.23623, 0.03937,   0.1,  1.0,  2.66,  1.0, 1.0, 1.0],
 [1.07,    0.08917, 0.0148,   0.03759, 0.3759, 1.0,  1.0, 1.0, 1.0],
 [1.0,    1.0,  1.0,    1.0,  1.0,  1.0,  1.0, 1.0, 1.0],
 [1.0,    1.0,  1.0,    1.0,  1.0,  1.0,  1.0, 1.0, 1.0],
 [1.0,    1.0,  1.0,    1.0,  1.0,  1.0,  1.0, 1.0, 1.0]];
The above array contains all the multiplicative factors used in converting from one unit of measurement to another. The array is two dimensional and is indexed by the different units along both dimensions. So for example, an entry ConversionFactors[y][x] will give us the factor for converting a number in y units to a number in x units. We simply multiply the number we currently have by the number in ConversionFactors[y][x].
These conversions factors were obtained from the following standard conversions:
72.27 points = 1 inch   12 points = 1 pica
2.54 cm = 1 inch    2.66 didot points = 1 mm  0.3759 mm = 1 didot point
6 picas = 1 inch    1.07 points = 1 didot point = 0.0148 ins
ConvertUnits: PUBLIC PROC [num: REAL, prevUnits, newUnits: Rope.ROPE] RETURNS [REAL] = {
old, new: UnitsType;
old ← ConvertRopeToUnitsType[prevUnits];
new ← ConvertRopeToUnitsType[newUnits];
num ← num * ConversionFactors[old][new];
RETURN[num];
};
ConvertRopeToUnitsType: PROCEDURE [units: Rope.ROPE] RETURNS [UnitsType] = BEGIN
SELECT TRUE FROM
 Rope.Equal[units, "points", FALSE]  => RETURN[pt];
 Rope.Equal[units, "picas", FALSE]   => RETURN[pc];
 Rope.Equal[units, "inches", FALSE]  => RETURN[in];
 Rope.Equal[units, "centimeters", FALSE] => RETURN[cm];
 Rope.Equal[units, "millimeters", FALSE] => RETURN[mm];
 Rope.Equal[units, "didot points", FALSE] => RETURN[dd];
 Rope.Equal[units, "ems", FALSE]   => RETURN[em];
 Rope.Equal[units, "ens", FALSE]   => RETURN[en];
 Rope.Equal[units, "spaces", FALSE]  => RETURN[sp];
ENDCASE => ERROR;
END;
GetRealFromViewer: PUBLIC PROC [viewer: ViewerClasses.Viewer] RETURNS [REAL] = BEGIN
Alert: PROCEDURE = BEGIN
MessageWindow.Append[Rope.Cat["Invalid real number in ", viewer.name, " field."], TRUE];
MessageWindow.Blink[];
SIGNAL BadNumber;
END;
numberRope: Rope.ROPE ← ViewerTools.GetContents[viewer];
realNumber: REAL;
h: IO.STREAM;
IF Rope.Size[numberRope] = 0 THEN RETURN[0.0];  -- Ignore if no value
h ← IO.RIS[numberRope];
realNumber ← IO.GetReal[h ! IO.Error =>
SELECT ec FROM
  SyntaxError => { Alert;
       CONTINUE;
       };
  ENDCASE => ERROR; -- shouldn't get any other errors
  ];
RETURN [realNumber];
END;
GetIntegerFromViewer: PUBLIC PROC [viewer: ViewerClasses.Viewer] RETURNS [INTEGER] = BEGIN
Alert: PROCEDURE = BEGIN
MessageWindow.Append[Rope.Cat["Invalid integer in ", viewer.name, " field."], TRUE];
MessageWindow.Blink[];
SIGNAL BadNumber;
END;
numberRope: Rope.ROPE ← ViewerTools.GetContents[viewer];
int: INTEGER;
h: IO.STREAM;
IF Rope.Size[numberRope] = 0 THEN RETURN[0];  -- Ignore if no value
h ← IO.RIS[numberRope];
int ← IO.GetInt[h ! IO.Error =>
SELECT ec FROM
  SyntaxError => { Alert;
       CONTINUE;
       };
  ENDCASE => ERROR; -- shouldn't get any other errors
  ];
RETURN [int];
END;
GetFontFamily: PUBLIC PROC [name: NameSymbolTable.Name] RETURNS [fontInfo: FontFamilyRec] = BEGIN
IF name = NameSymbolTable.nullName THEN fontInfo.name ← "None"
ELSE {
  fontInfo.name ← NameSymbolTable.RopeFromName[name];
Check if this font family is in our list of font family names
IF ~MemberOfList[fontInfo.name, fontFamilyList] THEN{
this display contains a non-standard font name. In this case we wish to return the font name as well as the button to be turned "on" - "Other".
fontInfo.text ← fontInfo.name;
fontInfo.name ← "Other";
}
ELSE fontInfo.text ← NIL;
};
END;
MemberOfList: PROC [item: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [BOOLEAN] = {
FOR eachItem: LIST OF Rope.ROPE ← list, eachItem.rest UNTIL eachItem = NIL DO
IF Rope.Equal[eachItem.first, item, FALSE] THEN RETURN [TRUE];
ENDLOOP;
-- if we get here, we haven't found the item in our list
RETURN[FALSE];
};
GetFontFaceJaM: PUBLIC PROC[face: NodeStyle.FontFace] RETURNS [Rope.ROPE] = {
SELECT face FROM
 Regular => RETURN["regular"];
 Bold  => RETURN["bold"];
 Italic  => RETURN["italic"];
 BoldItalic => RETURN["bold+italic"];
ENDCASE => ERROR;
};
GetFontFaceChoice: PUBLIC PROC[face: NodeStyle.FontFace] RETURNS [Rope.ROPE] = {
SELECT face FROM
 Regular => RETURN["Regular"];
 Bold  => RETURN["Bold"];
 Italic  => RETURN["Italic"];
 BoldItalic => RETURN["BoldItalic"];
ENDCASE => ERROR;
};
RopeFromReal: PUBLIC PROC[r: NodeStyle.Real] RETURNS [Rope.ROPE] = {
RETURN[IO.PutFR["%g", IO.real[r]]];
};
GetFontAlphabetsJaM: PUBLIC PROC[alphabets: NodeStyle.FontAlphabets] RETURNS [Rope.ROPE] = {
SELECT alphabets FROM
 CapsAndLower  => RETURN["caps+lowercase"];
 CapsAndSmallCaps => RETURN["caps+smallCaps"];
 LowerOnly   => RETURN["lowerOnly"];
 CapsOnly    => RETURN["capsOnly"];
ENDCASE    => ERROR;
};
GetFontAlphabetsChoice: PUBLIC PROC[alphabets: NodeStyle.FontAlphabets]RETURNS[Rope.ROPE] = {
SELECT alphabets FROM
 CapsAndLower  => RETURN["CapsAndLower"];
 CapsAndSmallCaps => RETURN["CapsAndSmallCaps"];
 LowerOnly   => RETURN["LowerOnly"];
 CapsOnly    => RETURN["CapsOnly"];
ENDCASE    => ERROR;
};
FontAlphChoiceToJaM: PUBLIC PROCEDURE [alphabets: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN
SELECT TRUE FROM
 Rope.Equal[alphabets, "CapsAndLower", FALSE]  => RETURN["caps+lowercase"];
 Rope.Equal[alphabets, "CapsAndSmallCaps", FALSE] => RETURN["caps+smallCaps"];
 Rope.Equal[alphabets, "LowerOnly", FALSE]   => RETURN["lowerOnly"];
 Rope.Equal[alphabets, "CapsOnly", FALSE]    => RETURN["capsOnly"];
ENDCASE             => ERROR;
END;
GetFontUnderliningJaM: PUBLIC PROC[underlining: NodeStyle.FontUnderlining] RETURNS [Rope.ROPE] = {
SELECT underlining FROM
 None     => RETURN["none"];
 LettersAndDigits => RETURN["lettersAndDigits"];
 Visible    => RETURN["visible"];
 All     => RETURN["all"];
ENDCASE    => ERROR;
};
GetFontUnderliningChoice: PUBLIC PROC[underlining: NodeStyle.FontUnderlining] RETURNS [Rope.ROPE] = {
SELECT underlining FROM
 None     => RETURN["None"];
 LettersAndDigits => RETURN["LettersAndDigits"];
 Visible    => RETURN["Visible"];
 All     => RETURN["All"];
ENDCASE    => ERROR;
};
FontUndChoiceToJaM: PUBLIC PROCEDURE [underlining: Rope.ROPE] RETURNS [Rope.ROPE] = {
SELECT TRUE FROM
 Rope.Equal[underlining, "None", FALSE]     => RETURN["none"];
 Rope.Equal[underlining, "LettersAndDigits", FALSE] => RETURN["lettersAndDigits"];
 Rope.Equal[underlining, "Visible", FALSE]    => RETURN["visible"];
 Rope.Equal[underlining, "All", FALSE]     => RETURN["all"];
ENDCASE              => ERROR;
};
GetLineFormattingJaM: PUBLIC PROC[lineFormat: NodeStyle.LineFormatting]RETURNS[Rope.ROPE] ={
SELECT lineFormat FROM
 FlushLeft => RETURN["flushLeft"];
 FlushRight => RETURN["flushRight"];
 Justified  => RETURN["justified"];
 Centered  => RETURN["centered"];
ENDCASE  => ERROR;
};
GetLineFormattingChoice: PUBLIC PROC[lineFormat: NodeStyle.LineFormatting] RETURNS [Rope.ROPE] = {
SELECT lineFormat FROM
 FlushLeft => RETURN["FlushLeft"];
 FlushRight => RETURN["FlushRight"];
 Justified  => RETURN["Justified"];
 Centered  => RETURN["Centered"];
ENDCASE  => ERROR;
};
LineChoiceToJaM: PUBLIC PROCEDURE [lineFormatting: Rope.ROPE] RETURNS [Rope.ROPE] = {
SELECT TRUE FROM
 Rope.Equal[lineFormatting, "FlushLeft", FALSE]  => RETURN["flushLeft"];
 Rope.Equal[lineFormatting, "FlushRight", FALSE] => RETURN["flushRight"];
 Rope.Equal[lineFormatting, "Justified", FALSE]  => RETURN["justified"];
 Rope.Equal[lineFormatting, "Centered", FALSE]  => RETURN["centered"];
ENDCASE             => ERROR;
};
GetPathTypeJaM: PUBLIC PROC[pathType: NodeStyle.PathType] RETURNS [Rope.ROPE] = {
SELECT pathType FROM
 Filled      => RETURN["filled"];
 Outlined     => RETURN["outlined"];
 FilledAndOutlined  => RETURN["filled+outlined"];
ENDCASE     => ERROR;
};
GetPathTypeChoice: PUBLIC PROC[pathType: NodeStyle.PathType] RETURNS [Rope.ROPE] = {
SELECT pathType FROM
 Filled      => RETURN["Filled"];
 Outlined     => RETURN["Outlined"];
 FilledAndOutlined  => RETURN["FilledAndOutlined"];
ENDCASE     => ERROR;
};
END.