ImagerGraphCaptureImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Michael Plass, July 2, 1986 3:38:31 pm PDT
DIRECTORY Imager, ImagerState, ImagerPrivate, ImagerTransformation, Rope, ImagerGraphCapture;
ImagerGraphCaptureImpl: CEDAR PROGRAM
IMPORTS Imager, ImagerState, ImagerTransformation, Rope
EXPORTS Imager, ImagerGraphCapture
~ BEGIN OPEN Imager;
Class: TYPE ~ ImagerPrivate.Class;
ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager.ClassRep
State: TYPE ~ ImagerState.State;
StateRep: PUBLIC TYPE ~ ImagerState.StateRep; -- export to Imager.StateRep
ROPE: TYPE ~ Rope.ROPE;
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD [
nPoints: NAT ← 0,
point: REF PointSeq,
label: REF RopeSeq ← NIL,
edges: LIST OF EdgeRep ← NIL,
rawLabels: LIST OF LabelRep ← NIL
];
LabelRep: TYPE ~ RECORD [vec: VEC, rope: ROPE];
EdgeRep: TYPE ~ RECORD [from, to: INT];
PointSeq: TYPE ~ RECORD [SEQUENCE max: NAT OF VEC];
RopeSeq: TYPE ~ RECORD [SEQUENCE max: NAT OF ROPE];
AddLabel: PROC [data: Data, cp: VEC, rope: ROPE] ~ {
data.rawLabels ← CONS[[cp, rope], data.rawLabels];
};
tolerance: REAL ← 1.0;
FindPointNumber: PROC [data: Data, vec: VEC] RETURNS [INT] ~ {
FOR i: NAT IN [0..data.nPoints) DO
p: VEC ~ data.point[i];
IF ABS[vec.x-p.x] <= tolerance AND ABS[vec.y-p.y] <= tolerance THEN RETURN [i];
ENDLOOP;
data.point[data.nPoints] ← vec;
data.nPoints ← data.nPoints + 1;
RETURN [data.nPoints-1]
};
AddEdge: PROC [data: Data, from, to: INT] ~ {
data.edges ← CONS[[from, to], data.edges];
};
CreateContext: PUBLIC PROC [initalScale: REAL] RETURNS [Context] ~ {
data: Data ~ NEW[DataRep ← [point: NEW[PointSeq[16300]]]];
state: State ~ NEW[StateRep ← []];
state.T ← ImagerTransformation.Scale[initalScale];
state.color ← Imager.black;
RETURN [NEW[Imager.ContextRep ← [class: myClass, state: state, data: data]]]
};
GetGraph: PUBLIC PROC [context: Imager.Context] RETURNS [ImagerGraphCapture.Graph] ~ {
data: Data ~ NARROW[context.data];
graph: ImagerGraphCapture.Graph ~ NEW[ImagerGraphCapture.GraphRep[data.nPoints]];
FOR i: NAT IN [0..data.nPoints) DO
vertex: ImagerGraphCapture.Vertex ← NEW[ImagerGraphCapture.VertexRep];
vertex.index ← i;
vertex.pos ← data.point[i];
graph[i] ← vertex;
ENDLOOP;
IF data.nPoints > 0 THEN {
FOR m: LIST OF LabelRep ← data.rawLabels, m.rest UNTIL m = NIL DO
d: REAL ← 9999999;
k: NAT ← 0;
vec: VEC ~ m.first.vec;
FOR i: NAT IN [0..data.nPoints) DO
IF graph[i].label = NIL THEN {
p: VEC ~ data.point[i];
dd: REAL ~ MAX[ABS[vec.x-p.x], ABS[vec.y-p.y]];
IF dd < d THEN {d ← dd; k ← i};
};
ENDLOOP;
IF d # 9999999 THEN graph[k].label ← m.first.rope;
ENDLOOP;
};
FOR m: LIST OF EdgeRep ← data.edges, m.rest UNTIL m = NIL DO
from: ImagerGraphCapture.Vertex ~ graph[m.first.from];
to: ImagerGraphCapture.Vertex ~ graph[m.first.to];
from.edgesOut ← CONS[to.index, from.edgesOut];
to.edgesIn ← CONS[from.index, to.edgesIn];
ENDLOOP;
RETURN [graph]
};
PlaceLabels: PROC [data: Data] ~ {
IF data.nPoints > 0 THEN {
data.label ← NEW[RopeSeq[data.nPoints]];
FOR m: LIST OF LabelRep ← data.rawLabels, m.rest UNTIL m = NIL DO
d: REAL ← 9999999;
k: NAT ← 0;
vec: VEC ~ m.first.vec;
FOR i: NAT IN [0..data.nPoints) DO
IF data.label[i] = NIL THEN {
p: VEC ~ data.point[i];
dd: REAL ~ MAX[ABS[vec.x-p.x], ABS[vec.y-p.y]];
IF dd < d THEN {d ← dd; k ← i};
};
ENDLOOP;
IF d # 9999999 THEN data.label[k] ← m.first.rope;
ENDLOOP;
};
};
MyShow: PROC [context: Context, string: XStringProc, xrel: BOOL] ~ {
state: State ~ context.state;
data: Data ~ NARROW[context.data];
text: REF TEXTNEW[TEXT[512]];
charAction: PROC [char: XChar] ~ {text[text.length] ← VAL[char.code]; text.length ← text.length + 1};
string[charAction];
IF state.np.noImage = 0 THEN AddLabel[data, state.p.cp, Rope.FromRefText[text]];
};
MyShowText: PROC [context: Context, text: REF READONLY TEXT, start, len: NAT, xrel: BOOL] ~ {
state: State ~ context.state;
data: Data ~ NARROW[context.data];
i: NAT ← 0;
p: PROC RETURNS [c: CHAR] ~ {c ← text[start+i]; i ← i + 1};
len ← MIN[len, NAT[text.length-start]];
IF state.np.noImage = 0 THEN AddLabel[data, state.p.cp, Rope.FromProc[len: len, p: p]];
};
MyMaskFill: PROC [context: Context, path: PathProc, oddWrap: BOOL] ~ {};
MyMaskRectangle: PROC [context: Context, r: Rectangle] ~ {};
MyMaskRectangleI: PROC [context: Context, x, y, w, h: INTEGER] ~ {};
MyMaskStroke: PROC [context: Context, path: PathProc, closed: BOOL] ~ {
lp: VEC ← [0,0];
p0: VEC ← [0,0];
moveTo: PROC[p: VEC] ~ {IF closed AND lp#p0 THEN MyMaskVector[context, lp, p0]; p0 ← lp ← p};
lineTo: PROC[p1: VEC] ~ {MyMaskVector[context, lp, p1]; lp ← p1};
curveTo: PROC[p1, p2, p3: VEC] ~ {MyMaskVector[context, lp, p3]; lp ← p3};
conicTo: PROC[p1, p2: VEC, r: REAL] ~ {MyMaskVector[context, lp, p2]; lp ← p2};
arcTo: PROC[p1, p2: VEC] ~ {MyMaskVector[context, lp, p2]; lp ← p2};
path[moveTo, lineTo, curveTo, conicTo, arcTo];
IF closed AND lp#p0 THEN MyMaskVector[context, lp, p0];
};
MyMaskDashedStroke: PROC [context: Context, path: PathProc, patternLen: NAT, pattern: PROC [NAT] RETURNS [REAL], offset, length: REAL] ~ {
MyMaskStroke[context, path, FALSE];
};
MyMaskVector: PROC [context: Context, p1, p2: VEC] ~ {
state: State ~ context.state;
data: Data ~ NARROW[context.data];
pn1: INT ~ FindPointNumber[data, ImagerTransformation.Transform[state.T, p1]];
pn2: INT ~ FindPointNumber[data, ImagerTransformation.Transform[state.T, p2]];
IF state.np.noImage = 0 THEN AddEdge[data, pn1, pn2];
};
MyMaskPixel: PROC [context: Context, pa: PixelArray] ~ {};
MyMaskBits: PROC [context: Context, base: LONG POINTER, wordsPerLine: NAT,
sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ {};
MyDrawBits: PROC [context: Context, base: LONG POINTER, wordsPerLine: NAT,
sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ {};
myClass: Class ~ NEW[ClassRep ← [
type: $GraphCapture,
DoSave: ImagerState.StateDoSave,
SetInt: ImagerState.StateSetInt,
SetReal: ImagerState.StateSetReal,
SetT: ImagerState.StateSetT,
SetFont: ImagerState.StateSetFont,
SetColor: ImagerState.StateSetColor,
SetClipper: ImagerState.StateSetClipper,
GetInt: ImagerState.StateGetInt,
GetReal: ImagerState.StateGetReal,
GetT: ImagerState.StateGetT,
GetFont: ImagerState.StateGetFont,
GetColor: ImagerState.StateGetColor,
GetClipper: ImagerState.StateGetClipper,
ConcatT: ImagerState.StateConcatT,
Scale2T: ImagerState.StateScale2T,
RotateT: ImagerState.StateRotateT,
TranslateT: ImagerState.StateTranslateT,
Move: ImagerState.StateMove,
SetXY: ImagerState.StateSetXY,
SetXYRel: ImagerState.StateSetXYRel,
Show: MyShow,
ShowText: MyShowText,
StartUnderline: ImagerState.StateStartUnderline,
MaskUnderline: ImagerState.StateMaskUnderline,
CorrectMask: ImagerState.StateCorrectMask,
CorrectSpace: ImagerState.StateCorrectSpace,
Space: ImagerState.StateSpace,
SetCorrectMeasure: ImagerState.StateSetCorrectMeasure,
SetCorrectTolerance: ImagerState.StateSetCorrectTolerance,
Correct: ImagerState.StateCorrect,
DontCorrect: ImagerState.StateDontCorrect,
SetGray: ImagerState.StateSetGray,
SetSampledColor: ImagerState.StateSetSampledColor,
SetSampledBlack: ImagerState.StateSetSampledBlack,
MaskDashedStroke: MyMaskDashedStroke,
MaskFill: MyMaskFill,
MaskRectangle: MyMaskRectangle,
MaskRectangleI: MyMaskRectangleI,
MaskStroke: MyMaskStroke,
MaskVector: MyMaskVector,
MaskPixel: MyMaskPixel,
MaskBits: MyMaskBits,
DrawBits: MyDrawBits,
Clip: ImagerState.StateClip,
ClipRectangle: ImagerState.StateClipRectangle,
ClipRectangleI: ImagerState.StateClipRectangleI,
GetCP: ImagerState.StateGetCP,
GetBoundingRectangle: NIL
]];
END.