(Fit.JaM) =
(August 30, 1984 10:35:18 am PDT) =
(fit) .dup .where {.pop .pop}{256 .dict .def}.ifelse .cvx .exec
fit .begin

(/run){(Running ).print .dup .print .run (.)=}.cvx .def
(/loadbcd){(Loading ).print .dup .print .loadbcd (.)=}.cvx .def
(Fit.mark) (.addsa) .cvx .def
(Fit.joint) (6 4 .roll .selectsa 1 .jointsa .tanOut .tanIn).cvx .def
(Fit.moveto) {.moveto}.cvx .def
(Fit.movetonext) {.movetonext}.cvx .def
(Fit.curveto) {.curveto}.cvx .def
(Fit.maskstrokeclosed) {.maskstrokeclosed}.cvx .def
(Fit.maskfill) {.pop .maskfill}.cvx .def
(ais) (kfab-logo.ais) .def
(setupais) (ais Contour.openAIS).cvx .def
(setupac) (acfont Contour.openACFont).cvx .def
(setupsd) (sdfont 300 Contour.openSDFont).cvx .def
(doDragonO) {.false .avefilter .false .avefilter 1 dynpoly 89 .true PK.quicktangents .false PK.hvextremes 5 2 0 0 .metrics .grow}.cvx .def
(dynpoly) (like the old dynpoly)(1000 0 PK.dynpoly)/xdef
(init) (
(JaMImager.jam)/run
(Fit.bcd) /loadbcd
(SampledColorsImpl.bcd) /loadbcd
(SDtoSFImpl.bcd) /loadbcd
(FitJaMPkg.bcd)/loadbcd (FitJaM) .callinit FitJaM.InitAll
(ComplexJaM) .callinit
).cvx .def
(breakTol) 2 .def
(sb) (sets a point break) (breakTol FitJaM.BreakPoint)/xdef
(cb) (clears the point break) (0,0, -1 FitJaM.BreakPoint)/xdef
(ds)
(draws the samples)
(.drawsa)/xdef
(dss)
(draws all contours)
{.countcon {ds .nextcon}.cvx .rept}/xdef
(ms)
(marks the samples)
(2 .setmarksize .marksa)/xdef
(mss)
(marks all contours)
{.countcon {ms .nextcon}.cvx .rept}/xdef
(dc)
(draws the curve)
(.drawli)/xdef
(dcs)
(draws all curves)
{.countcon {dc .nextcon}.cvx .rept}/xdef
(mc)
(marks the joints along the curve)
(2 .setmarksize .markli)/xdef
(mcs)
(marks the joints along the curves)
{2 .setmarksize .countcon {.markli .nextcon}.cvx .rept}/xdef
(mn)
(marks the nodes with the normal lines)
(2 .setmarksize .marknodes)/xdef
(mns)
(marks all nodes with the normal lines)
(2 .setmarksize .countcon {.marknodes .nextcon}.cvx .rept)/xdef
(skm)
(sets standard metrics for sketched data)
(10 2 5 0 .metrics)/xdef
(skd)
(abbreviation for: 10 .true .dynspline)
(10 .true .dynspline)/xdef
(settangents)
(Set the tangents for sketched samples)
(4 .01 10 .settangents mn)/xdef
(grow)
(Grow a spline for sketched samples)
(.5 15 .grow cvtempstring .print ( knots) =)/xdef
(resetmouse)
(Resets mouse clicks so they do nothing) (
(.track) {.pop .pop}.cvx .store
(.reddown) {.pop .pop}.cvx .store
(.redup) {.pop .pop}.cvx .store
(.yellowdown) {.pop .pop}.cvx .store
(.yellowup) {.pop .pop}.cvx .store
(.bluedown) {.pop .pop}.cvx .store
(.blueup) {.pop .pop}.cvx .store
)/xdef
(edit)
(Point edit: red inserts, yellow moves, blue deletes) (resetmouse
(Point edit: red inserts, yellow moves, blue deletes
) .print
(.yellowdown) {.selectsa .thetan .deletesa e ms}.cvx .store
(.yellowup) {.insertsa .nodesa .tansa e ms}.cvx .store
(.blueup) {.selectsa .deletesa e ms}.cvx .store
(.reddown) {.selectsa}.cvx .store
(.redup) {.insertbetween e ms}.cvx .store
e ms
)/xdef
(nodes)
(node edit: red sets a node, yellow sets a tangent, blue removes a node) (resetmouse
(node edit: red sets a node, yellow sets a tangent, blue removes a node
) .print
(.redup) (.selectsa .true .nodesa mn).cvx .def
(.yellowdown) (.selectsa).cvx .def
(.yellowup) (.thesa Complex.Sub .tansa noderefresh).cvx .def
(.blueup) (.selectsa .false .nodesa noderefresh).cvx .def
noderefresh
)/xdef
(ht) (make tangent horizontal at the current node)
{1 0 .tansa noderefresh}/xdef
(vt) (make tangent horizontal at the current node)
{0 1 .tansa noderefresh}/xdef
(ft) (make tangent free at the current node)
{0 0 .tansa noderefresh}/xdef
(corners)
(corner edit: red sets a corner, yellow sets a tangent, blue removes a corner) (resetmouse
(corner edit: red sets a corner, yellow sets a tangent, blue removes a corner
) .print
(.redup) (.selectsa .true .cornersa mn).cvx .def
(.yellowdown) (.selectsa).cvx .def
(.yellowup) (.thesa Complex.Sub .tansa noderefresh).cvx .def
(.blueup) (.selectsa .false .jointsa noderefresh).cvx .def
noderefresh
)/xdef
(noderefresh) (e ms mn).cvx .def
(allnodes)
(makes every sample a node)
(.homesa .countsa {.nextsa .true .nodesa}.cvx .rept noderefresh)/xdef
(nonodes)
(removes all nodes except endpoints)
(.homesa .countsa 2 .sub .nextsa {.nextsa .false .nodesa}.cvx .rept noderefresh)/xdef
(sketch)
(Sketches a curve with the mouse) (
(Sketch a curve
) .print
.resetsa resetmouse
(.reddown) {2 .copy .setcp .addsa}.cvx .store
(.track) {2 .copy .drawto .addsa}.cvx .store
)/xdef
(transform)
(Transforms samples: red moves and sets origin, yellow scales and blue rotates) {resetmouse
(Transforms samples: red moves and sets origin, yellow scales and blue rotates
) .print
(.reddown) {}.cvx .store
(.redup) {2 .copy (rotorgy) .exch .store (rotorgx) .exch .store 4 2 .roll Complex.Sub translatecontours e transrefresh}.cvx .store
(.yellowdown) {orgtrans orgrel}.cvx .store
(.yellowup) {orgrel 4 2 .roll Complex.Div Complex.Abs 0 scalecontours unorgtrans e transrefresh}.cvx .store
(.bluedown) {orgtrans orgrel}.cvx .store
(.blueup) {orgrel 4 2 .roll Complex.Div 2 .copy Complex.Abs 0 Complex.Div scalecontours unorgtrans e transrefresh}.cvx .store
(rotorgx) 0 .store 0 (rotorgy) 0 .store
transrefresh}/xdef
(transrefresh) {e dss rotorgx rotorgy dot .pop .pop}.cvx .def
(orgrel) (rotorgx rotorgy 4 2 .roll Complex.Sub).cvx .def
(orgtrans) {rotorgx .neg rotorgy .neg translatecontours}.cvx .def
(unorgtrans) {rotorgx rotorgy translatecontours}.cvx .def
(rotorgx) 0 .def
(rotorgy) 0 .def
(degrees)
(Converts degrees to something the scaler likes)
(180.0 .div 3.1415926 .mul 0 .exch Complex.Exp)/xdef
(rotate)
(rotates the samples by degrees)
(degrees orgtrans scalecontours unorgtrans e transrefresh)/xdef
(scale)
(Scales the samples)
(0 orgtrans scalecontours unorgtrans e transrefresh)/xdef
(scalecontours)
(Scales/rotates all the contours)
{.countcon {2 .copy .scalesa .nextcon}.cvx .rept .pop .pop}/xdef
(translatecontours)
(Tranlates all the contours)
{.countcon {2 .copy .transa .nextcon}.cvx .rept .pop .pop}/xdef
(setfirst)
(sets the position of the first sample)
{.homesa .nextsa .deletesa .touch .selectsa .makefirstsa .homesa .nextsa .thesa .addsa}/xdef
(MoveHomeToLowerLeft)
{.homesa .nextsa .deletesa 0 0 .selectsa .makefirstsa .homesa .nextsa .thesa .addsa .homesa .nextsa .true .nodesa .homesa .prevsa .true .nodesa}.cvx .def
(MoveHomeToACorner)
{.homesa .nextsa .deletesa FindACorner .makefirstsa .homesa .nextsa .thesa .addsa .homesa .nextsa .true .nodesa .homesa .prevsa .true .nodesa}.cvx .def
(FindACorner)
{.homesa .countsa {.nextsa IsCorner {.exit}/if}.cvx .rept}.cvx .def
(IsCorner)
{.thetan .pop Complex.Abs 0 .eq .thetan .exch .pop .exch .pop .and}.cvx .def
(nc)
(use next contour)
{.nextcon ms}/xdef
(closeup)
(For taking a close look at the result. Use the mouse to point near the area you are interested in.) {
.initdc resetmouse
0 0 (closey) .exch .store (closex) .exch .store 0 0 showclose
(.track) {2 .copy showclose closex closey showclose (closey) .exch .store (closex) .exch .store}.cvx .def
}/xdef
(showclose) {.neg .exch .neg .exch .setinvert 10 10 .scale .translate mss dcs mns .initdc}.cvx .def
(insertcorners)
(puts in corners)
{.countsa .homesa {.nextsa 0 0 .insertsa .prevsa .cornersa checkduplicate}.cvx .rept}/xdef
(checkduplicate) {.thesa 0 0 areclose .thesa theprevsa areclose .thesa thenextsa areclose .or .or {.deletesa .prevsa}/if .nextsa}.cvx .def
(areclose) {Complex.Sub Complex.Abs 0.1 .lt}.cvx .def
(theprevsa) {.prevsa .thesa .nextsa}.cvx .def
(thenextsa) {.nextsa .thesa .prevsa}.cvx .def
(sharpencorners)
{.countsa .homesa {.nextsa IsCorner {.cornersa}/if}.cvx .rept}.cvx .def
(k?) (counts the knots)
{ 0 (8 {.pop}.cvx .rept 1 .add).cvx .foralllinks =}/xdef
(printpoint) {.exch cvtempstring .print ( ).print cvtempstring .print ( ).print}.cvx .def
(newcontour) {(initmoveto) {logpoint (.movetonext) .noter (initmoveto) {.pop .pop}.cvx .def}.cvx .def}.cvx .def
(HandFitContour) {.dup (curContour) .exch .store
 .setsa 3 0 .scalesa edit}.cvx .def
(gp) {.touch 2 .copy .exch cvtempstring .print ( ).print cvtempstring .print ( ).print}.cvx .def
(sk) {gp .moveto (.moveto) = {gp gp gp .curveto (.curveto) = .getpos 0 .drawpath .moveto}.cvx .loop}.cvx .def
(.nodesa) (.jointsa).cvx .def
(.cornernode) (.forcejoint).cvx .def
(.tansa) (.tanin).cvx .def
(.cornersa) (0 0 .tanIn 0 0 .tanOut 2 .jointsa).cvx .def
(.thetan) (.thetanin).cvx .def
(resetforced) {.countsa {.false .forcejoint .nextsa}.cvx .rept}.cvx .def
(resettans) {.countsa {0 0 .tanIn 0 0 .tanOut .nextsa}.cvx .rept}.cvx .def