FitJaMImpl.mesa
organizing the JaM registered procedures for Fit.
Maureen Stone November 29, 1984 4:37:09 pm PST
DIRECTORY
Cubic,
Complex USING [Vec, SqrAbs, Sub],
Highlight,
JaMImager USING [Painter],
SampledCurveEdit,
Rope USING[ROPE, Concat],
ViewerOps USING [CreateViewer],
ViewerClasses USING [Viewer],
MessageWindow USING [Clear, Append],
FitJaM,
FitState USING [Handle, Create, SetClosed, AddSample, NewContour, ResetData],
FitIO USING [Context, ContextRec, FeedbackRec, MagnifyPoint, UnMagnifyPoint],
ImagerTransform, --implicit for Imager.TranslateT
Imager USING [black, MoveTo, LineTo, CurveTo, Context, SetColor, XOR, Trans, SetXY, MaskFill, MaskStroke, DoSaveAll, Trajectory],
JaM USING [State, RegisterInit, PopRope, RopeToAtom, Register, PopReal];
FitJaMImpl: CEDAR PROGRAM
IMPORTS JaM, Imager, FitState, JaMImager, SampledCurveEdit, FitIO, ViewerOps, Rope, MessageWindow, Complex
EXPORTS FitJaM = {
InitProc: TYPE = FitJaM.InitProc;
StartRec: TYPE = RECORD[id: ATOM, proc: InitProc];
startList: LIST OF REF StartRec;
defaultFitState: PUBLIC FitState.Handle ← FitState.Create[];
defaultFitIO: PUBLIC FitIO.Context ← NEW[FitIO.ContextRec ← [
imager: NIL, --set in paint proc
magnify: 1,
position: [0,0],
feedback: NEW[FitIO.FeedbackRec ← [
color: Imager.black,
sampleSize: 1,
jointSize: 2,
nodeLength: 6,
nodeLineWidth: 0,
lineWidth: 0--for DrawSamples and DrawContour
]],
logActions: FALSE,
log: NIL
]];
Implements a highlight with XOR'd points and cubics. Rope goes in the message window. JaM state goes in the data.clientData field.
defaultHighlight: PUBLIC Highlight.Context;
RegisterInit: PUBLIC PROC[id: ATOM, proc: InitProc] = {
FOR ls: LIST OF REF StartRec ← startList, ls.rest UNTIL ls=NIL DO
IF ls.first.id=id THEN ERROR;
ENDLOOP;
startList ← CONS[NEW[StartRec ← [id: id, proc: proc]],startList];
};
InitAll: PROC [state: JaM.State] = {
FOR ls: LIST OF REF StartRec ← startList, ls.rest UNTIL ls=NIL DO
ls.first.proc[state];
ENDLOOP;
};
InitAtom: PROC [state: JaM.State] = {
atom: ATOM ← JaM.RopeToAtom[JaM.PopRope[state]];
FOR ls: LIST OF REF StartRec ← startList, ls.rest UNTIL ls=NIL DO
IF atom=ls.first.id THEN {ls.first.proc[state]; EXIT};
ENDLOOP;
};
nullPt: Complex.Vec ← [-10000, -10000];
nullBezier: Cubic.Bezier ← [[-1,-1],[-1,-1],[-1,-1],[-1,-1]];
octagonPath: Imager.Trajectory ← OctagonPath[];
OctagonPath: PROC RETURNS [path: Imager.Trajectory] = {
path ← Imager.MoveTo[[1, 2]];
path ← Imager.LineTo[path, [2, 1]];
path ← Imager.LineTo[path, [2, -1]];
path ← Imager.LineTo[path, [1, -2]];
path ← Imager.LineTo[path, [-1, -2]];
path ← Imager.LineTo[path, [-2, -1]];
path ← Imager.LineTo[path, [-2, 1]];
path ← Imager.LineTo[path, [-1, 2]];
};
ShowPt: PROC[ctx: Highlight.Context, pt: Complex.Vec] = {
Paint: PROC[dc: Imager.Context] = {
doIt: PROC = {
Imager.SetColor[dc, Imager.XOR];
Imager.SetXY[dc, [dpt.x, dpt.y]];
Imager.Trans[dc];
Imager.MaskFill[dc, octagonPath];
};
dpt: Complex.Vec;
IF ctx.data.lastPt#nullPt THEN {
dpt ← FitIO.MagnifyPoint[defaultFitIO, ctx.data.lastPt];
Imager.DoSaveAll[dc,doIt];
};
IF pt#nullPt THEN {
dpt ← FitIO.MagnifyPoint[defaultFitIO,pt];
Imager.DoSaveAll[dc,doIt];
};
};
JaMImager.Painter[Paint, NARROW[ctx.data.clientData]];
ctx.data.lastPt ← pt;
IF Complex.SqrAbs[Complex.Sub[pt, breakPt]] < breakTol THEN SIGNAL BreakFromHighlight;
};
ShowBezier: PROC[ctx: Highlight.Context, bezier: Cubic.Bezier] = {
Paint: PROC[dc: Imager.Context] = {
doIt: PROC = {
Imager.SetColor[dc, Imager.XOR];
IF oldPath#NIL THEN Imager.MaskStroke[dc, oldPath,0];
IF newPath #NIL THEN Imager.MaskStroke[dc, newPath, 0];
};
Imager.DoSaveAll[dc,doIt];
};
makePath: PROC[bz: Cubic.Bezier] RETURNS[path: Imager.Trajectory] = {
b0,b1, b2, b3: Complex.Vec;
IF bz=nullBezier THEN RETURN[NIL];
b0 ← FitIO.MagnifyPoint[defaultFitIO, [bz.b0.x, bz.b0.y]];
b1 ← FitIO.MagnifyPoint[defaultFitIO, [bz.b1.x, bz.b1.y]];
b2 ← FitIO.MagnifyPoint[defaultFitIO, [bz.b2.x, bz.b2.y]];
b3 ← FitIO.MagnifyPoint[defaultFitIO, [bz.b3.x, bz.b3.y]];
path ← Imager.MoveTo[[b0.x, b0.y]];
path ← Imager.CurveTo[path, [b1.x, b1.y], [b2.x, b2.y], [b3.x, b3.y]];
};
newPath, oldPath: Imager.Trajectory;
oldPath ← makePath[ctx.data.lastBezier];
newPath ← makePath[bezier];
JaMImager.Painter[Paint, NARROW[ctx.data.clientData]];
ctx.data.lastBezier ← bezier;
};
ShowRope: PROC[ctx: Highlight.Context, rope: Rope.ROPE]= {
MessageWindow.Append[rope, TRUE];
};
CleanUp: PROC[ctx: Highlight.Context] = {
IF ctx.data.lastPt#nullPt THEN ctx.procs.showPt[ctx, nullPt];
IF ctx.data.lastBezier#nullBezier THEN ctx.procs.showBezier[ctx, nullBezier];
MessageWindow.Clear[];
};
breakTol: REAL ← -1;
breakPt: Complex.Vec ← nullPt;
BreakFromHighlight: SIGNAL = CODE;
BreakPoint: PROC [state: JaM.State] = {
breakTol ← JaM.PopReal[state];
breakTol ← breakTol*breakTol; --keep the square
breakPt ← GetPt[state];
breakPt ← FitIO.UnMagnifyPoint[defaultFitIO, breakPt];
};
GetPt: PROC [state: JaM.State] RETURNS [Complex.Vec]= {
y: REAL ← JaM.PopReal[state];
x: REAL ← JaM.PopReal[state];
RETURN [[x,y]];
};
InitSampledCurve: PROC [state: JaM.State] = {
name: Rope.ROPE ← JaM.PopRope[state];
sceViewer ← IF name=NIL THEN SampledCurveEdit.CreateViewer[
[name: "Sampled Curve Editor [No File]", file: NIL]]
ELSE SampledCurveEdit.CreateViewer[
[name: Rope.Concat["Sampled Curve Editor ", name], file: name]];
};
sceViewer: ViewerClasses.Viewer;
Copy: PROC [state: JaM.State] = {OPEN SampledCurveEdit;
IF sceViewer#NIL THEN {
outline: Outline ← GetOutline[sceViewer];
FitState.ResetData[defaultFitState, samples, TRUE];
FOR t: LIST OF Trajectory ← outline, t.rest UNTIL t=NIL DO
start: MarkedPoint ← t.first.first;
IF start.kind = open THEN {FitState.SetClosed[defaultFitState, TRUE]; start ← t.first.rest.first};
FitState.AddSample[defaultFitState, start.x, start.y];
FOR p: LIST OF MarkedPoint ← t.first.rest.rest, p.rest UNTIL p=NIL DO
FitState.AddSample[defaultFitState, p.first.x, p.first.y];
ENDLOOP;
FitState.NewContour[defaultFitState];
ENDLOOP;
};
};
JaMInit: PROC [state: JaM.State] = {
JaM.Register[state,"FitJaM.InitAll",InitAll];
JaM.Register[state,"FitJaM.InitAtom",InitAtom];
JaM.Register[state,"FitJaM.InitSampledCurve",InitSampledCurve];
JaM.Register[state,"FitJaM.Copy",Copy];
JaM.Register[state, "FitJaM.BreakPoint", BreakPoint]; --x, y, tol=> jumps to a place to set a break when highlight near this pt
defaultHighlight ← NEW[Highlight.Object ← [
data: NEW[Highlight.Data ← [
imager: NIL,
lastRope: NIL,
lastBezier: nullBezier,
lastPt: nullPt,
clientData: state]],
procs:NEW[Highlight.Procs ← [
showPt: ShowPt,
showBezier: ShowBezier,
showRope: ShowRope,
cleanUp: CleanUp
]]
]];
};
JaM.RegisterInit["FitJaM",JaMInit];
}.