% utils.jam
(utils.jam) =
(inch) {72.0 .mul} .cvx .def
(center) {
(xxxtext) .exch .def
{
-0.5 1 .scale2t .true .setnoimage xxxtext .show
-2 1 .scale2t .false .setnoimage xxxtext .show
} .cvx .dosaveall
} .cvx .def
(dropCenter) {
(xxxcolor) .exch .cvx .def
(xxxtext) .exch .def
{ black xxxtext center } .cvx .dosaveall
{ 1 1 .setxyrel xxxcolor xxxtext center } .cvx .dosaveall
} .cvx .def
(whitedropCenter) {
(xxxcolor) .exch .cvx .def
(xxxtext) .exch .def
{ white xxxtext center } .cvx .dosaveall
{ 2 2 .setxyrel xxxcolor xxxtext center } .cvx .dosaveall
} .cvx .def
(drop) {
(xxxcolor) .exch .cvx .def
(xxxtext) .exch .def
{
black xxxtext .show
-1 1 .scale2t .true .setnoimage xxxtext .show
xxxcolor -1 1 .scale2t 1 1 .setxyrel .false .setnoimage xxxtext .show
} .cvx .dosaveall
} .cvx .def
(whitedrop) {
(xxxcolor) .exch .cvx .def
(xxxtext) .exch .def
{
white xxxtext .show
-1 1 .scale2t .true .setnoimage xxxtext .show
xxxcolor -1 1 .scale2t 2 2 .setxyrel .false .setnoimage xxxtext .show
} .cvx .dosaveall
} .cvx .def
% 2 unit arrow head pointing up
(arrow-1) [ 0 0 .moveto -2 -2 .lineto 0 4 .lineto 2 -2 .lineto 0 0 .lineto ] .def
(arrow-2) [ 0 0 .moveto -2 0 .lineto 0 4 .lineto 2 0 .lineto 0 0 .lineto ] .def
% <w> <h> <radius> roundCornerBox
(roundCornerBox) {
(xxxr) .exch .def
(xxxh) .exch .def
(xxxw) .exch .def
xxxw xxxr .sub 0 .moveto
xxxr 0 .lineto
0 0 0 xxxr 0.414214 .conicto
0 xxxh xxxr .sub .lineto
0 xxxh xxxr xxxh 0.414214 .conicto
xxxw xxxr .sub xxxh .lineto
xxxw xxxh xxxw xxxh xxxr .sub 0.414214 .conicto
xxxw xxxr .lineto
xxxw 0 xxxw xxxr .sub 0 0.414214 .conicto
} .cvx .def
% <text> boxedRope returns <path> <text> <offsetx> <offsety>
(boxedRope) {
(xxxtext) .exch .def
xxxtext .textbox
(xxxas) .exch .def
(xxxright) .exch .def
(xxxdes) .exch .def
(xxxle) .exch .def
(xxxmargin) xxxdes xxxas .add 3 .div .def
xxxright xxxmargin .add xxxdes xxxas .add xxxmargin .add xxxmargin 2 .div roundCornerBox
xxxtext
% 0 xxxle xxxmargin .add .sub
% 0 xxxdes xxxmargin .add .sub
xxxmargin 2 .div
xxxdes xxxmargin 2 .div .add
} .cvx .def
% (x) {t 5 .scalet black 10 CLSSM (ABCDEFGHIJKLMNOPQRSTUVWXYZ) boxedRope .setxy .show .maskstroke} .cvx .def
(circle) [ % 1 unit radius circle centered on 0 0
-1 0 .moveto 1 0 -1 0 .arcto
] .def
(arrow-3) [ 0 0 .moveto -6 2 .lineto -4 0 .lineto -6 -2 .lineto 0 0 .lineto ] .def
(arrow) { % <x1> <y1> <x2> <y2> <thickness> arrow
(xxxthickness) .exch .def
(xxxy2) .exch .def
(xxxx2) .exch .def
(xxxy1) .exch .def
(xxxx1) .exch .def
(xxxr) xxxy2 xxxy1 .sub xxxx2 xxxx1 .sub .atan .def
(xxxl) xxxx2 xxxx1 .sub .dup .mul xxxy2 xxxy1 .sub .dup .mul .add .sqrt .def
{ xxxx1 xxxy1 .translatet xxxr .rotatet 0 0 .moveto xxxl xxxthickness 3 .mul .sub 0 .lineto xxxthickness .setstrokewidth .maskstroke } .cvx .dosave
{ xxxx2 xxxy2 .translatet xxxthickness .scalet xxxr .rotatet arrow-3 .arraymaskfill} .cvx .dosave
} .cvx .def
(arrowr) { % <x1> <y1> <w> <h> <thickness> arrowr
(xxxthickness) .exch .def
(xxxh) .exch .def
(xxxw) .exch .def
(xxxy1) .exch .def
(xxxx1) .exch .def
xxxx1 xxxy1 xxxx1 xxxw .add xxxy1 xxxh .add xxxthickness arrow
} .cvx .def