ImagerGraphCaptureImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Michael Plass, February 7, 1986 12:35:39 pm PST
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
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 TEXT ← NEW[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, parity:
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];
};
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,
SetStrokeDashes: ImagerState.StateSetStrokeDashes,
GetInt: ImagerState.StateGetInt,
GetReal: ImagerState.StateGetReal,
GetT: ImagerState.StateGetT,
GetFont: ImagerState.StateGetFont,
GetColor: ImagerState.StateGetColor,
GetClipper: ImagerState.StateGetClipper,
GetStrokeDashes: ImagerState.StateGetStrokeDashes,
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,
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.