(Fit.JaM) = (April 7, 1983 3:36 pm) = (user) .dup .where {.pop .pop}{256 .dict .def}.ifelse .cvx .exec user .begin (/run){(Running ).print .dup .print .run (.)=}.cvx .def (/loadbcd){(Loading ).print .dup .print .loadbcd (.)=}.cvx .def (init) ( (JaMImager.jam)/run (Fit.bcd)/loadbcd (FitJaM) .callinit FitJaM.InitAll ).cvx .def (startup) (gets things started) {((/ivy/plass/hacks/cmr30.ac) FitFont 0 128 FitACRange (will fit a whole font and append the results to curve.log)) = }/xdef (ds) (draws the samples) (.drawsa)/xdef (dss) (draws all contours) {.countcon {ds .nextcon}.cvx .rept}/xdef (ms) (marks the samples) (1 .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 (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 (getAIS) (Loads an AIS file for stroke tracing: takes a file name) (.dup .setupais .drawmyais .ctraceopen)/xdef (da) (draws the current sampled image) (.drawmyais)/xdef (trace) (Trace a stroke in sampled image: first touch tells start, second indicates initial direction) (.resetsa .touch .touch 3 230 1000 .ctrace)/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 (cusps) (cusp edit: red sets a cusp, yellow sets a tangent, blue removes a cusp) (resetmouse (cusp edit: red sets a cusp, yellow sets a tangent, blue removes a cusp ) .print (.redup) (.selectsa .true .cuspsa mn).cvx .def (.yellowup) (.selectsa .true .cuspnode mn).cvx .def (.blueup) (.selectsa .false .cuspsa 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 (corners) (touch the corners) {resetmouse e ms (.reddown) {.selectsa .cornersa .true .nodesa e ms}.cvx .def (.bluedown) {.homesa .nextsa .deletesa .selectsa .makefirstsa .homesa .nextsa .thesa .addsa .homesa .nextsa .true .nodesa .homesa .prevsa .true .nodesa}.cvx .def }/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 cvtempstring .print ( knots) =}/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