GraphConvertImpl.mesa, Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by:
Sweetsun Chen, November 15, 1985 5:47:59 pm PST
DIRECTORY
Convert USING [RopeFromInt, RopeFromReal],
Imager USING [VEC],
ImagerFont USING [Extents, Font, RopeBoundingBox],
IO USING [EndOfStream, Error, GetChar, GetIndex, GetReal, int, PeekChar, PutFR, real, RIS, rope, STREAM],
Graph USING [Angle, CaretIndex, Entity, EntityList, GraphHandle, JustifX, JustifY, Mark, NullVec, NtNan, Operand, ROPE, SegmentDataList, ValueList],
GraphCleanUp USING [CleanUpVL],
GraphConvert,
GraphUtil USING [BlinkMsg, LengthOfSDL, LengthOfVL, NotANumber, RaiseError, ReverseValueList],
Real USING [RealException],
Rope USING [Cat, Concat, Equal, IsEmpty],
ViewerTools USING [GetContents];
GraphConvertImpl: CEDAR PROGRAM
IMPORTS Convert, GraphCleanUp, GraphUtil, ImagerFont, IO, Real, Rope, ViewerTools
EXPORTS GraphConvert = { OPEN Graph;
RopeOfPlace: PUBLIC PROC[p: Imager.VEC ← NullVec] RETURNS [s: ROPENIL] = {
RETURN[IO.PutFR["(%g, %g)", IO.real[p.x], IO.real[p.y]]];
}; -- RopeOfPlace
RopeSize: PUBLIC PROC[rope: ROPENIL, font: ImagerFont.Font ← NIL] RETURNS[w, h: REAL ← 0.0] = {
IF rope # NIL AND font # NIL THEN {
extents: ImagerFont.Extents ← ImagerFont.RopeBoundingBox[font, rope];
w ← extents.rightExtent - extents.leftExtent;
h ← extents.descent + extents.ascent;
};
}; -- RopeSize
RopeOfSlope: PUBLIC PROC[p1, p2: Imager.VEC ← NullVec] RETURNS [s: ROPENIL] = {
dx, dy: REAL;
IF p2.x < p1.x THEN {t: Imager.VEC ← p1; p1 ← p2; p2 ← t; dx ← -dx; dy ← -dy};
dx ← p2.x - p1.x;
dy ← p2.y - p1.y;
IF dx = 0.0 THEN RETURN[IF dy = 0.0 THEN "Undefined."
ELSE IF dy > 0.0 THEN "+ Infinity."
ELSE "- Infinity."]
ELSE IF dy = 0.0 THEN RETURN ["0.0"]
ELSE {
ENABLE Real.RealException => {
s ← SELECT TRUE FROM
flags[overflow] => "overflow",
flags[underflow] => "underflow",
flags[invalidOperation] => "invalid operation",
ENDCASE => "can't get it.";
CONTINUE};
s ← Convert.RopeFromReal[dy/dx];
};
}; -- RopeOfSlope
RopeFromJustifX: PUBLIC PROC[justifX: JustifX] RETURNS [ROPE] = {
RETURN[SELECT justifX FROM left => "left", center => "center", ENDCASE => "right"]
}; -- RopeFromJustifX
JustifXFromRope: PUBLIC PROC[jRope: ROPE] RETURNS [JustifX] = {
FOR jx: JustifX IN JustifX DO IF RopeFromJustifX[jx].Equal[jRope] THEN RETURN[jx]; ENDLOOP;
ERROR;
}; -- JustifXFromRope
RopeFromJustifY: PUBLIC PROC[justifY: JustifY] RETURNS [ROPE] = {
RETURN[SELECT justifY FROM top => "top", center => "center", ENDCASE => "bottom"]
}; -- RopeFromJustifX
JustifYFromRope: PUBLIC PROC[jRope: ROPE] RETURNS [JustifY] = {
FOR jy: JustifY IN JustifY DO IF RopeFromJustifY[jy].Equal[jRope] THEN RETURN[jy]; ENDLOOP;
ERROR;
}; -- JustifXFromRope
RopeFromMark: PUBLIC PROC[mark: Mark] RETURNS [ROPE] = {
RETURN[SELECT mark FROM
none => "none", round => "round", square => "square", diamond => "diamond", cross => "cross", dollar => "dollar", ENDCASE => "percent"];
}; -- RopeFromMark
CharRopeFromMark: PUBLIC PROC [mark: Mark] RETURNS [ROPE] = {
RETURN[SELECT mark FROM
round => "Ë", square => "¡", diamond => ".", cross => " ", dollar => "$", percent => "%",
ENDCASE => " "]; -- error !
}; -- CharRopeFromMark
MarkFromRope: PUBLIC PROC [mRope: ROPE] RETURNS [Mark] = {
FOR m: Mark IN Mark DO IF RopeFromMark[m].Equal[mRope] THEN RETURN[m]; ENDLOOP;
ERROR;
}; -- MarkFromRope
RopeFromOperand: PUBLIC PROC[op: Operand] RETURNS [ROPE] = {
RETURN[SELECT op FROM y => "selected y", plottedYs => "plotted y's", ENDCASE => "x"];
}; -- RopeFromOperand
OperandFromRope: PUBLIC PROC[rOp: ROPE] RETURNS [Operand] = {
FOR iOp: Operand IN Operand DO IF RopeFromOperand[iOp].Equal[rOp] THEN RETURN[iOp];
ENDLOOP;
ERROR;
}; -- OperandFromRope
RopeFromAngle: PUBLIC PROC[angle: Angle] RETURNS [ROPE] = {
RETURN[IF angle = degrees THEN "degrees" ELSE "radians"];
}; -- RopeFromAngle
AngleFromRope: PUBLIC PROC[rA: ROPE] RETURNS [Angle] = {
IF rA.Equal["radians"] THEN RETURN[radians];
IF rA.Equal["degrees"] THEN RETURN[degrees];
ERROR;
}; -- AngleFromRope
RopeFromCaretIndex: PUBLIC PROC[index: CaretIndex ← primary] RETURNS [r: ROPENIL] = {
RETURN[SELECT index FROM primary => "primary", secondary => "secondary", ENDCASE => "text caret"]}; -- RopeFromCaretIndex
RopeFromValueList: PUBLIC PROC[vector: ValueList ← NIL] RETURNS [r: ROPENIL] = {
rope: ROPE;
FOR v: ValueList ← vector, v.rest UNTIL v = NIL DO
rope ← IF GraphUtil.NotANumber[v.first] THEN "*" ELSE Convert.RopeFromReal[v.first];
r ← IF r = NIL THEN rope ELSE r.Cat[" ", rope];
ENDLOOP;
}; -- RopeFromValueList
RopeFromSDL: PUBLIC PROC[segmentDataList: SegmentDataList ← NIL] RETURNS [r: ROPENIL] = {
rope: ROPE;
FOR sdl: SegmentDataList ← segmentDataList, sdl.rest UNTIL sdl = NIL DO
rope ← IF GraphUtil.NotANumber[sdl.first.end] THEN "*" ELSE Convert.RopeFromReal[sdl.first.end];
r ← IF r = NIL THEN rope ELSE r.Cat[" ", rope];
ENDLOOP;
}; -- RopeFromValueList
VLFromSDL: PUBLIC PROC [segmentDataList: SegmentDataList] RETURNS [valueList: ValueList ← NIL] = {
lastVL: ValueList ← NIL;
FOR sdl: SegmentDataList ← segmentDataList, sdl.rest UNTIL sdl = NIL DO
vl: ValueList ← CONS[sdl.first.end, NIL];
IF lastVL = NIL THEN lastVL ← valueList ← vl
ELSE {lastVL.rest ← vl; lastVL ← vl};
ENDLOOP;
}; -- ValueListFromSDL
ValueListFromRope: PUBLIC PROC [r: ROPE] RETURNS [vl, last: ValueList ← NIL, length, pos: INT ← 0] = {
s: IO.STREAM;
real: REAL;
IF r.IsEmpty[] THEN RETURN[];
s ← IO.RIS[r];
DO
ENABLE {
IO.EndOfStream => GOTO done;
IO.Error => {pos ← s.GetIndex[]; GOTO error};
};
real ← IO.GetReal[s];
vl ← CONS[real, vl];
length ← length + 1;
REPEAT
error => {vl ← NIL; length ← 0};
done => NULL;
ENDLOOP;
IF pos # 0 THEN GraphUtil.BlinkMsg[Rope.Cat["Syntax error at [", Convert.RopeFromInt[pos], "] in the value field."]];
[vl, last] ← GraphUtil.ReverseValueList[vl];
}; -- ValueListFromRope
RopeOfEntityListIds: PUBLIC PROC[entityList: EntityList ← NIL, exclude: Entity ← NIL] RETURNS [r: ROPENIL] = {
rope: ROPE;
FOR el: EntityList ← entityList, el.rest UNTIL el = NIL DO
IF el.first = exclude THEN LOOP;
rope ← Convert.RopeFromInt[el.first.id];
r ← IF r = NIL THEN rope ELSE r.Cat[" ", rope];
ENDLOOP;
}; -- RopeOfEntityListIds
RopeOfXYValues: PUBLIC PROC [entity: Entity ← NIL] RETURNS [rope: ROPENIL] = {
IF entity # NIL THEN {
count: INT ← 0;
IF entity.segments # NIL THEN { -- plotted.
xseg: SegmentDataList ← entity.group.x.segments;
yseg: SegmentDataList ← entity.segments;
IF GraphUtil.LengthOfSDL[xseg] # GraphUtil.LengthOfSDL[yseg] THEN GraphUtil.RaiseError[$Other, "different lengths of x and y segments"];
UNTIL xseg = NIL DO
pair: ROPEIO.PutFR["(%g, %g) ",
IF GraphUtil.NotANumber[xseg.first.end] THEN IO.rope["*"] ELSE IO.real[xseg.first.end],
IF GraphUtil.NotANumber[yseg.first.end] THEN IO.rope["*"] ELSE IO.real[yseg.first.end]];
IF (count ← count + 1) MOD 4 = 0 THEN pair ← pair.Cat[
IO.PutFR[" -- %g\n", IO.int[count]]];
rope ← rope.Concat[pair];
xseg ← xseg.rest;
yseg ← yseg.rest;
ENDLOOP;
}
ELSE {
xvl: ValueList ← entity.group.x.oldValues;
yvl: ValueList ← entity.oldValues;
IF GraphUtil.LengthOfVL[xvl] # GraphUtil.LengthOfVL[yvl] THEN GraphUtil.RaiseError[$Other, "different lengths of x and y values"];
UNTIL xvl = NIL DO
pair: ROPEIO.PutFR["(%g, %g) ",
IF GraphUtil.NotANumber[xvl.first] THEN IO.rope["*"] ELSE IO.real[xvl.first],
IF GraphUtil.NotANumber[yvl.first] THEN IO.rope["*"] ELSE IO.real[yvl.first]];
IF (count ← count + 1) MOD 4 = 0 THEN pair ← pair.Cat[
IO.PutFR[" -- %g\n", IO.int[count]]];
rope ← rope.Concat[pair];
xvl ← xvl.rest;
yvl ← yvl.rest;
ENDLOOP;
};
};
}; -- RopeOfXYValues
VLsFromValues: PUBLIC PROC [handle: GraphHandle] RETURNS [vlx, vly, lastX, lastY: ValueList ← NIL, msg: ROPENIL] = {
converts contents in the values viewer to xvl and yvl.
s: IO.STREAMIO.RIS[ViewerTools.GetContents[handle.controller.values]];
DO
ENABLE {
IO.EndOfStream => EXIT;
IO.Error => {
msg ← SELECT ec FROM
SyntaxError => "Syntax error",
Overflow => "Overflow",
ENDCASE => "Error";
EXIT;
};
};
rx, ry: REAL;
tvl: ValueList;
char: CHAR ← ' ;
UNTIL char = '( DO char ← s.GetChar[] ENDLOOP;
IF s.PeekChar[] = '* THEN {rx ← NtNan; [] ← s.GetChar} ELSE rx ← s.GetReal[];
char ← s.PeekChar[];
UNTIL (char = '* OR char = '- OR char = '+) OR (char IN ['0..'9]) DO
[] ← s.GetChar[]; char ← s.PeekChar[];
ENDLOOP;
IF char = '* THEN {ry ← NtNan; [] ← s.GetChar} ELSE ry ← s.GetReal[];
UNTIL char = ') DO char ← s.GetChar[] ENDLOOP;
tvl ← CONS[rx, NIL];
IF lastX = NIL THEN lastX ← vlx ← tvl
ELSE {lastX.rest ← tvl; lastX ← tvl};
tvl ← CONS[ry, NIL];
IF lastY = NIL THEN lastY ← vly ← tvl
ELSE {lastY.rest ← tvl; lastY ← tvl};
ENDLOOP;
IF msg # NIL THEN {
msg ← msg.Concat[IO.PutFR[" at [%g] parsing the value list.", IO.int[s.GetIndex[]]]];
lastX ← vlx ← GraphCleanUp.CleanUpVL[vlx];
lastY ← vly ← GraphCleanUp.CleanUpVL[vly];
};
}; -- VLsFromValues
}.
LOG.
SChen, created October 9, 1985 6:29:44 pm PDT