diff options
Diffstat (limited to 'metapost/context/base/mpiv/mp-node.mpiv')
-rw-r--r-- | metapost/context/base/mpiv/mp-node.mpiv | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/metapost/context/base/mpiv/mp-node.mpiv b/metapost/context/base/mpiv/mp-node.mpiv new file mode 100644 index 000000000..fdd308ad1 --- /dev/null +++ b/metapost/context/base/mpiv/mp-node.mpiv @@ -0,0 +1,182 @@ +%D \module +%D [ file=mp-node.mpiv, +%D version=1998.02.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=Node Based Graphics, +%D author=Alan Braslau, +%D date=\currentdate, +%D copyright={Alan Braslau & \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Ths crossing macros were written as part of this module but as they +%D can be of use elsewhere they are defined in mp-tool. + +if known context_node : endinput ; fi ; + +boolean context_node ; context_node := true ; + +% returns a pair suffix if the path is unknown + +vardef makenode@#(suffix p)(text t) = + save i, b ; numeric i ; string b ; + for a = t : + if unknown i : % first argument is the index + i = a ; + if isarray p : + % + % note that one needs to declare "path p[] ; picture p[]pic[] ;" + % before calling node() if one is to use a pseudo-array for p + % because "picture p1.pic[] ;" is not a valid syntax! + % + % The following works, but is a bit awkward... + % + b := prefix p ; + if not picture p.pic[i] : scantokens("picture " & b & "[]pic[] ;") ; fi + if not pair p.pos[i] : scantokens("pair " & b & "[]pos[] ;") ; fi + else : + if not picture p.pic[i] : picture p.pic[] ; fi + if not pair p.pos[i] : pair p.pos[] ; fi + fi + else : + if known p.pic[i] : + addto p.pic[i] also + else : + p.pic[i] := + fi + if picture a : a + elseif string a : textext@#(a) + elseif numeric a : textext@#(decimal a) + elseif ((boolean a) and a) : image(draw origin) + else : nullpicture + fi ; + fi + endfor + p.pos[i] if known p : := point i of p ; fi +enddef ; + +% returns a picture + +vardef node@#(suffix p)(text t) = + if pair makenode@#(p)(t) : + % nop: gobble the function return. + fi + for a = t : + if (unknown p) and (known p.pos[a]) : + makenodepath(p) ; + fi + if known p.pic[a] : + p.pic[a] if known p : shifted point a of p fi + else : + nullpicture + fi + exitif true ; + endfor +enddef ; + +% returns a path + +vardef fromto@#(expr d)(suffix p)(expr f)(suffix q)(text s) = + save r, t, l ; + path r[] ; numeric t ; picture l ; + for a = s : + if unknown t : + t = a ; + if (unknown p) and (known p.pos[f]) : + makenodepath(p) ; + fi + if (unknown q) and (known q.pos[t]) : + makenodepath(q) ; + fi + r0 = if ((not numeric d) and + (point f of p = point f of q) and + (point t of p = point t of q)) : + subpath (f,t) of p + else : + point f of p -- point t of q + fi ; + save deviation ; numeric deviation ; + deviation := if numeric d: d else: 0 fi ; + r1 = if deviation=0 : r0 + else : + point 0 of r0 .. + unitvector direction .5length r0 of r0 rotated 90 + scaled deviation * arclength r0 + shifted point .5length r0 of r0 .. + point length r0 of r0 + fi ; + else : + if known l : + addto l also + else : + l := + fi + if picture a : a + elseif string a : textext@#(a) + elseif numeric a : textext@#(decimal a) + elseif ((boolean a) and a) : image(draw origin withpen currentpen scaled 4) + else : nullpicture + fi ; + fi + endfor + r2 = r1 + if known p.pic[f if cycle p: mod length p fi] : + cutbefore boundingbox (p.pic[f if cycle p: mod length p fi] shifted point f of p) + fi + if known q.pic[t if cycle q: mod length q fi] : + cutafter boundingbox (q.pic[t if cycle q: mod length q fi] shifted point t of q) + fi + ; + if known l : + l := l shifted point .5length r2 of r2 ; + draw l ; + (r2 if str @# = "" : crossingunder l fi) + else : + r2 + fi +enddef ; + +% returns pair: bounding point of the node picture + +vardef nodeboundingpoint@#(suffix p)(expr i) = + if known p.pic[i] : + boundingpoint@#(p.pic[i]) + else : + origin + fi +enddef ; + +% returns pair: scaled laboff direction + +vardef relative@#(expr s) = + (mfun_laboff@# scaled s) +enddef ; + +% returns pair: vector between nodes (+ optional scale) + +vardef betweennodes@#(suffix p)(expr f)(suffix q)(text s) = + save t ; numeric t ; + for a = s : + if unknown t : + t = a ; + nodeboundingpoint@#(q,t) + nodeboundingpoint@#(p,f) + else : + + relative@#(a) + fi + endfor +enddef ; + +% build a path from the node positions. +% Must be continuous in index starting at 0. + +vardef makenodepath(suffix p) = + if unknown p : + save i ; i = -1 ; + p = forever : exitif unknown p.pos[incr i] ; + p.pos[i] -- + endfor cycle ; + fi +enddef ; + |