MathExprClassesObject.mesa
Carl Waldspurger, August 30, 1986 7:12:37 pm PDT
Bier, November 20, 1986 2:02:38 pm PST
Arnon, March 24, 1987 4:15:31 pm PST
Mcisaac, August 19, 1987 5:33:35 pm PDT
DIRECTORY
MathExpr,
MathRules,
MathDB,
MathTypes,
MathBox,
ImagerFont,
ImagerTransformation,
Imager,
Rope,
Real,
Vector,
Convert,
MathConstructors;
MathExprClassesObject: CEDAR PROGRAM
IMPORTS MathBox, MathRules, ImagerFont, Imager, ImagerTransformation, MathExpr,
MathDB, Convert, Rope, Real, MathConstructors
~
BEGIN
Type Abbreviations from Imported Interfaces
EXPR: TYPE ~ MathExpr.EXPR;
BOX: TYPE ~ MathBox.BOX;
ROPE: TYPE ~ Rope.ROPE;
VEC: TYPE ~ Vector.VEC;
AtomBoxProc: TYPE ~ MathRules.AtomBoxProc;
AtomPaintProc: TYPE ~ MathRules.AtomPaintProc;
AtomToASRopeProc: TYPE ~ MathRules.AtomToASRopeProc;
AtomClass: TYPE ~ MathExpr.AtomClass;
AtomFlavor: TYPE ~ MathExpr.AtomFlavor;
FormatClass: TYPE ~ MathTypes.FormatClass;
MatrixClass: TYPE ~ MathExpr.MatrixClass;
Style: TYPE ~ MathTypes.Style;
CompoundBoxProc: TYPE ~ MathRules.CompoundBoxProc;
CompositionProc: TYPE ~ MathRules.CompositionProc;
Alignment2D: TYPE ~ MathRules.Alignment2D;
Offset: TYPE ~ MathRules.Offset;
Size: TYPE ~ MathRules.Size;
Argument: TYPE ~ MathExpr.Argument;
Symbol: TYPE ~ MathExpr.Symbol;
CompoundClass: TYPE ~ MathExpr.CompoundClass;
Procedure Abbreviations from Imported Interfaces
MakeAtomClass: PROC[name: ATOM, formatClass: FormatClass, flavor: AtomFlavor, style: Style, boxRule: AtomBoxProc, paintRule: AtomPaintProc, cvtASRule, cvtReduceRule, cvtSMPRule, cvtOtherRule: AtomToASRopeProc ← NIL] RETURNS[AtomClass] ~ MathExpr.MakeAtomClass;
MakeArgument: PROC[name: ATOM, aliases: LIST OF ATOM, size: Size] RETURNS[Argument] ~ MathExpr.MakeArgument;
MakeSymbol: PROC[name: ATOM, aliases: LIST OF ATOM, size: Size, value: EXPR] RETURNS[Symbol] ~ MathExpr.MakeSymbol;
MakeCompoundClass: PROC[name: ATOM, formatClass: FormatClass, description: ROPE, args: LIST OF Argument, syms: LIST OF Symbol, boxRule: CompoundBoxProc, compBox: CompositionProc, cvtAS, cvtReduce, cvtSMP, cvtOther: ROPENIL] RETURNS[CompoundClass] ~ MathExpr.MakeCompoundClass;
Constants
smallGap: REAL = 0.05;
medGap: REAL = 0.10;
bigGap: REAL = 0.25;
Common AtomToASRope Procs
GreekVarToASRope: AtomToASRopeProc ~ {
IF value.Length[] < 1 THEN RETURN["unknown"]
ELSE RETURN[MathConstructors.CharToGreekName[value.Fetch[0]]];
};
UnknownToASRope: AtomToASRopeProc ~ {
RETURN["?"];
};
InfinityToASRope: AtomToASRopeProc ~ {
RETURN["infinity"];
};
rightArrowToASRope: AtomToASRopeProc ~ {
RETURN["rightArrow"];
};
barToASRope: AtomToASRopeProc ~ {
RETURN["bar"];
};
perpToASRope: AtomToASRopeProc ~ {
RETURN["perp"];
};
Common Atom Box Procs
LineBox: AtomBoxProc ~ {
effects: Returns a bounding box for a line
Note that this is always a dummy value (dsa - because lines will always occur as part of a CompoundExpr, and the line will then be scaled appropriately by the CompoundExpr's BoxProc.)
don't really need any data from value; always returns protoypical line size
RETURN[[leftExtent: 0.0, rightExtent: 1.0, descent: 0.0, ascent: 0.03]];
};
CharBox: AtomBoxProc ~ {
effects: Returns a bounding box for value
font: ImagerFont.Font ← ImagerFont.Scale[ImagerFont.Find[style.font], style.scale];
RETURN[ImagerFont.RopeBoundingBox[font, value]];
};
OverlayBox: AtomBoxProc ~ {
effects: Returns a bounding box for value as a sequence of overlayed chars
font: ImagerFont.Font ← ImagerFont.Scale[ImagerFont.Find[style.font], style.scale];
farLeft, farRight, farUp, farDown: REAL ← 0.0; -- extreme edges of overlayed extents
FOR i:INT IN [0..value.Length[]-1] DO
box: ImagerFont.Extents ← ImagerFont.RopeBoundingBox[font, value.Substr[i, 1]];
farLeft ← MAX[farLeft, box.leftExtent];
farRight ← MAX[farRight, box.rightExtent];
farUp ← MAX[farUp, box.ascent];
farDown ← MAX[farDown, box.descent];
ENDLOOP;
RETURN[[leftExtent: farLeft, rightExtent: farRight, descent: farDown, ascent: farUp]];
};
RopeBox: AtomBoxProc ~ {
effects: Returns a bounding box for value
font: ImagerFont.Font ← ImagerFont.Scale[ImagerFont.Find[style.font], style.scale];
RETURN[ImagerFont.RopeBoundingBox[font, value]];
};
SpaceBox: AtomBoxProc ~ {
effects: Returns a bounding box for value (dsa - style appears irrelevant for this one).
size: ATOM ← Convert.AtomFromRope[value];
RETURN[
SELECT size FROM
$null => [leftExtent: 0.0, rightExtent: 0.001, descent: 0.0, ascent: 0.001],
$thin => [leftExtent: 0.0, rightExtent: 0.05, ascent: 0.05, descent: 0.0],
$medium => [leftExtent: 0.0, rightExtent: 0.12, ascent: 0.12, descent: 0.0],
$thick => [leftExtent: 0.0, rightExtent: 0.25, ascent: 0.25, descent: 0.0],
$veryThick => [leftExtent: 0.0, rightExtent: 0.4, ascent: 0.4, descent: 0.0],
$matrix => [leftExtent: 0.0, rightExtent: 0.9, ascent: 0.65, descent: 0.0],
$limit => [leftExtent: 0.0, rightExtent: 0.25, ascent: 0.12, descent: 0.0],
$product => [leftExtent: 0.0, rightExtent: 0.001, ascent: 0.21, descent: -0.19]
default to $thin
ENDCASE => [leftExtent: 0.0, rightExtent: 0.05, ascent: 0.05, descent: 0.0]
];
};
Common Atom Paint Procs
PaintChar: AtomPaintProc ~ {
effects: Paints value onto context in absBox
check type
IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType
ELSE {
font: ImagerFont.Font ← ImagerFont.Find[style.font];
extents: ImagerFont.Extents ← ImagerFont.RopeBoundingBox[font, value];
xFactor: REAL ← Real.Float[Real.Fix[100*absBox.Width[] / (extents.rightExtent + extents.leftExtent)]]/100;
yFactor: REAL ← Real.Float[Real.Fix[100*absBox.Height[] / (extents.ascent + extents.descent)]]/100;
Imager.SetXY[context, absBox.Offset[]];
Imager.SetFont[context,
ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]];
Imager.ShowRope[context, value];
};
};
PaintOverlay: AtomPaintProc ~ {
effects: Paints value as a sequence of centered superimposed characters.
This is useful for things like negated symbols (/ slashed through)...
check types
IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType
ELSE {
font: ImagerFont.Font ← ImagerFont.Find[style.font];
extents: ImagerFont.Extents ← OverlayBox[value, style];
xFactor: REAL ← Real.Float[Real.Fix[100*absBox.Width[] / (extents.rightExtent + extents.leftExtent)]]/100;
yFactor: REAL ← Real.Float[Real.Fix[100*absBox.Height[] / (extents.ascent + extents.descent)]]/100;
scale Font
font ← ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]];
paint chars, one by one, on ope of each other
FOR i:INT IN [0..value.Length[]-1] DO
char: ROPE ← value.Substr[i, 1];
box: ImagerFont.Extents ← ImagerFont.RopeBoundingBox[font, char];
position: VEC ← [MathRules.AlignHorizontal[box, [center], absBox, [center]],
MathRules.AlignVertical[box, [center], absBox, [center]]];
Imager.SetXY[context, position];
Imager.SetFont[context, font];
Imager.ShowRope[context, char];
ENDLOOP;
};
};
PaintRope: AtomPaintProc ~ {
effects: Paints value onto context in absBox
check types
IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType
ELSE {
font: ImagerFont.Font ← ImagerFont.Find[style.font];
extents: ImagerFont.Extents ← ImagerFont.RopeBoundingBox[font, value];
xFactor: REAL ← Real.Float[Real.Fix[100*absBox.Width[] / (extents.rightExtent + extents.leftExtent)]]/100;
yFactor: REAL ← Real.Float[Real.Fix[100*absBox.Height[] / (extents.ascent + extents.descent)]]/100;
Imager.SetXY[context, absBox.Offset[]];
Imager.SetFont[context,
ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]];
Imager.ShowRope[context, value];
};
};
PaintLine: AtomPaintProc ~ {
effects: Paints a line onto context filling absBox
caveats: Ignores value & style
r: Imager.Rectangle ← [x: absBox.Offset[].x + absBox.Extents[].leftExtent, y: absBox.Offset[].y + absBox.Extents[].descent, w: absBox.Width[], h: absBox.Height[]]; -- dsa 4/14/87: claim the + signs here should be - signs
r: Imager.Rectangle ← [x: absBox.Offset[].x - absBox.Extents[].leftExtent, y: absBox.Offset[].y - absBox.Extents[].descent, w: absBox.Width[], h: absBox.Height[]];
Imager.MaskRectangle[context, r];
};
PaintSpace: AtomPaintProc ~ {
effects: none
RETURN;
};
Procs for installing Atom Expression Classes
InstallAtomClasses: PROC [] ~ {
xcs, xci: Style;
integerClass, boolClass, realClass, variableClass, plainSymClass, overlaySymClass, smallMathSymClass, bigMathSymClass, italSymClass, mathItalSymClass, lineClass, placeholderClass, spaceClass, greekVarClass, infinityClass, rightArrowClass, barClass, perpClass: AtomClass;
xerox standard character set
xcs ← [font: "Xerox/XC1-2-2/Classic"];
xci ← [font: "Xerox/XC1-2-2/Classic-italic"];
define Atom Classes
integerClass ← MakeAtomClass[$integer, atom, argument, xcs, RopeBox, PaintRope];
boolClass ← MakeAtomClass[$bool, atom, argument, xcs, RopeBox, PaintRope];
realClass ← MakeAtomClass[$real, atom, argument, xcs, RopeBox, PaintRope];
variableClass ← MakeAtomClass[$variable, atom, argument, xci, RopeBox, PaintRope];
greekVarClass ← MakeAtomClass[$greekVar, atom, argument, xcs, RopeBox, PaintRope, GreekVarToASRope];
plainSymClass ← MakeAtomClass[$plainSym, atom, symbol, xcs, RopeBox, PaintRope]; -- MathConstructors.MakePlainSym
overlaySymClass ← MakeAtomClass[$overlaySym, atom, symbol, xcs, OverlayBox, PaintOverlay]; -- MathConstructors.MakeOverlaySym
bigMathSymClass ← MakeAtomClass[$bigMathSym, atom, symbol, xcs, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeBigMathSym
smallMathSymClass ← MakeAtomClass[$smallMathSym, atom, symbol, xcs, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeSmallMathSym
mathItalSymClass ← MakeAtomClass[$mathItalicSym, atom, symbol, xci, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeMathItalSym
italSymClass ← MakeAtomClass[$italicSym, atom, symbol, xci, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeItalSym
lineClass ← MakeAtomClass[$line, atom, symbol, xcs, LineBox, PaintLine];
placeholderClass ← MakeAtomClass[$placeholder, atom, placeholder, xcs, RopeBox, PaintRope, UnknownToASRope];
spaceClass ← MakeAtomClass[$space, atom, symbol, xcs, SpaceBox, PaintSpace];
infinityClass ← MakeAtomClass[$infinity, atom, argument, xcs, RopeBox, PaintRope, InfinityToASRope];
rightArrowClass ← MakeAtomClass[$rightArrow, atom, argument, xcs, RopeBox, PaintRope, rightArrowToASRope];
barClass ← MakeAtomClass[$bar, atom, argument, xcs, RopeBox, PaintRope, barToASRope];
perpClass ← MakeAtomClass[$perp, atom, argument, xcs, RopeBox, PaintRope, barToASRope];
register atom classes
MathDB.InstallAtomClass[integerClass];
MathDB.InstallAtomClass[boolClass];
MathDB.InstallAtomClass[realClass];
MathDB.InstallAtomClass[variableClass];
MathDB.InstallAtomClass[greekVarClass];
MathDB.InstallAtomClass[plainSymClass];
MathDB.InstallAtomClass[overlaySymClass];
MathDB.InstallAtomClass[italSymClass];
MathDB.InstallAtomClass[smallMathSymClass];
MathDB.InstallAtomClass[bigMathSymClass];
MathDB.InstallAtomClass[mathItalSymClass];
MathDB.InstallAtomClass[lineClass];
MathDB.InstallAtomClass[placeholderClass];
MathDB.InstallAtomClass[spaceClass];
MathDB.InstallAtomClass[infinityClass];
MathDB.InstallAtomClass[rightArrowClass];
MathDB.InstallAtomClass[barClass];
MathDB.InstallAtomClass[perpClass];
};
Box Procs for Compound Expr Classes
FixedSizeBoxRule: CompoundBoxProc ~ {
effects: Returns unaltered boxes (i.e. no resizing takes place)
RETURN[boxes];
};
Composition Procs for Compound Expr Classes
ComplexCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($complex $a $b)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ←
LIST[
[$a, [$plus, [right], [left, -medGap]],
[$plus, [origin], [origin]]],
[$leftParen, [$a, [right], [left, -medGap]],
[$plus, [origin], [origin]]],
[$b, [$plus, [left], [right, medGap]],
[$plus, [origin], [origin]]],
[$i, [$b, [left], [right, medGap]],
[$b, [origin], [origin]]],
[$rightParen, [$i, [left], [right, medGap]],
[$plus, [origin], [origin]]]
];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$a, [origin]], [$plus, [origin]]];
RETURN[tempBox, tempBoxes];
};
Procs for installing Compound Expression Classes
InstallCompoundClasses: PROC [] ~ {
local declarations
complexClass: CompoundClass;
realPartArg, imaginaryPartArg: Argument;
plusSym, iSym, funLParenSym, funRParenSym: Symbol;
define info for "complex a b" (a + bi)
realPartArg ← MakeArgument[$a, LIST[$aliasA, $aliasHot], normal];
imaginaryPartArg ← MakeArgument[$b, LIST[$aliasB], normal];
iSym ← MakeSymbol[$i, NIL, normal, MathConstructors.MakeItalSym['i]];
plusSym ← MakeSymbol[$plus, LIST[$aliasBinOp], normal, MathConstructors.MakePlainSym['+]];
define info for functions (parens also used by complex)
funLParenSym ← MakeSymbol[$leftParen, NIL, normal, MathConstructors.MakePlainSym['[]];
funRParenSym ← MakeSymbol[$rightParen, NIL, normal, MathConstructors.MakePlainSym[']]];
altFunLP ← MakeSymbol[$leftParen, NIL, normal, MathConstructors.MakeSpace[$null]];
altFunRP ← MakeSymbol[$rightParen, NIL, normal, MathConstructors.MakeSpace[$null]];
complexClass ← MakeCompoundClass[$complex, other, "a + bi", LIST[realPartArg, imaginaryPartArg], LIST[funLParenSym, plusSym, iSym, funRParenSym], FixedSizeBoxRule, ComplexCompRule, "($a + $bi)"];
MathDB.InstallCompoundClass[complexClass];
};
Procs for installing Matrix Expression Classes
InstallMatrixClasses: PROC [] ~ {
setClass, pointClass, sequenceClass, vectorClass, matrixClass: MatrixClass;
setClass ← MathExpr.MakeMatrixClass[$set, matrix, MathConstructors.MakePlainSym['{], MathConstructors.MakePlainSym['}], MathConstructors.MakeSpace[$matrix]]; -- brackets are { }
pointClass ← MathExpr.MakeMatrixClass[$point, matrix, MathConstructors.MakePlainSym[')], MathConstructors.MakePlainSym[')], MathConstructors.MakeSpace[$matrix]]; -- brackets are ( )
sequenceClass ← MathExpr.MakeMatrixClass[$sequence, matrix, MathConstructors.MakePlainSym['<], MathConstructors.MakePlainSym['>], MathConstructors.MakeSpace[$matrix]]; -- brackets are < >
vectorClass ← MathExpr.MakeMatrixClass[$vector, matrix, MathConstructors.MakePlainSym[']], MathConstructors.MakePlainSym[']], MathConstructors.MakeSpace[$matrix]]; -- brackets are [ ]
matrixClass ← MathExpr.MakeMatrixClass[$matrix, matrix, MathConstructors.MakePlainSym['[], MathConstructors.MakePlainSym[']], MathConstructors.MakeSpace[$matrix]]; -- brackets are [ ]
MathDB.InstallMatrixClass[setClass];
MathDB.InstallMatrixClass[pointClass];
MathDB.InstallMatrixClass[sequenceClass];
MathDB.InstallMatrixClass[vectorClass];
MathDB.InstallMatrixClass[matrixClass];
};
Signals & Errors
wrongAtomValueType: PUBLIC ERROR = CODE;
wrongBoxType: PUBLIC ERROR = CODE;
Install Atom and Matrix Classes (Start Code)
InstallAtomClasses[];
InstallCompoundClasses[];
InstallMatrixClasses[];
END.