FitJaMImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Maureen Stone November 29, 1984 4:37:09 pm PST
Doug Wyatt, September 5, 1985 3:29:42 pm PDT
organizing the JaM registered procedures for Fit.
DIRECTORY
Complex USING [SqrAbs, Sub, VEC],
Cubic USING [Bezier],
FitIO USING [Context, ContextRec, FeedbackRec, MagnifyPoint, UnMagnifyPoint],
FitJaM USING [InitProc],
FitState USING [Create, Handle],
Highlight USING [Context, Data, Object, Procs],
Imager USING [black, Context, DoSaveAll, MaskFill, MaskStrokeTrajectory, SetColor, SetStrokeWidth, SetXY, Trans],
ImagerBackdoor USING [invert],
ImagerPath USING [CurveTo, MoveTo, PathProc, Trajectory],
JaM USING [PopReal, PopRope, Register, RegisterInit, RopeToAtom, State],
JaMImager USING [Painter],
MessageWindow USING [Append, Clear],
Rope USING [ROPE];
FitJaMImpl: CEDAR PROGRAM
IMPORTS Complex, FitIO, FitState, Imager, ImagerBackdoor, ImagerPath, JaM, JaMImager, MessageWindow
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]];
ShowPt: PROC[ctx: Highlight.Context, pt: Complex.VEC] = {
Paint: PROC[dc: Imager.Context] = {
doIt: PROC = {
octagonPath: ImagerPath.PathProc ~ {
moveTo[[1, 2]]; lineTo[[2, 1]]; lineTo[[2, -1]]; lineTo[[1, -2]];
lineTo[[-1, -2]]; lineTo[[-2, -1]]; lineTo[[-2, 1]]; lineTo[[-1, 2]];
};
Imager.SetColor[dc, ImagerBackdoor.invert];
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, ImagerBackdoor.invert];
Imager.SetStrokeWidth[dc, 0];
IF oldPath#NIL THEN Imager.MaskStrokeTrajectory[dc, oldPath];
IF newPath #NIL THEN Imager.MaskStrokeTrajectory[dc, newPath];
};
Imager.DoSaveAll[dc,doIt];
};
makePath: PROC[bz: Cubic.Bezier] RETURNS[path: ImagerPath.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 ← ImagerPath.MoveTo[[b0.x, b0.y]];
path ← ImagerPath.CurveTo[path, [b1.x, b1.y], [b2.x, b2.y], [b3.x, b3.y]];
};
newPath, oldPath: ImagerPath.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];
}.