diff options
Diffstat (limited to 'Master/texmf-dist/metapost/context/base/mpxl/mp-node.mpxl')
-rw-r--r-- | Master/texmf-dist/metapost/context/base/mpxl/mp-node.mpxl | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/Master/texmf-dist/metapost/context/base/mpxl/mp-node.mpxl b/Master/texmf-dist/metapost/context/base/mpxl/mp-node.mpxl new file mode 100644 index 00000000000..7d6b9dd055b --- /dev/null +++ b/Master/texmf-dist/metapost/context/base/mpxl/mp-node.mpxl @@ -0,0 +1,275 @@ +%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 The 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 metafun_loaded_node : endinput ; fi ; + +newinternal boolean metafun_loaded_node ; metafun_loaded_node := true ; immutable metafun_loaded_node ; + +% Build a path from the node positions. +% Must be integer and continuous in index starting at 0. + +vardef makenodepath(suffix p) = + if unknown p : + if not path p : + d := dimension p ; + if d>0 : + scantokens("path " & prefix p & for i=1 upto d : "[]" & endfor " ;") ; + else : + path p ; + fi + fi + save i ; i = -1 ; + p = forever : exitif unknown p.pos[incr i] ; + p.pos[i] -- + endfor cycle ; + fi +enddef ; + +% can take a list: + +def clearpath text t = + save t ; path t ; +enddef ; + +def clearnodepath = clearpath nodepath enddef ; + +clearnodepath ; + +% the trailing "," below handles when number of t<3 + +vardef makenode@#(text t) = + for a = t : + if (path a) or (unknown a) : + mfun_makenode@#(t,) + elseif (string a) and (length(a) = 0) : + mfun_makenode@#(t,) + else : + mfun_makenode@#(nodepath, t,) + fi + exitif true ; + endfor +enddef ; + +vardef node@#(text t) = + for a = t : + if (path a) or (unknown a) : + mfun_node@#(t,) + elseif (string a) and (length(a) = 0) : + mfun_node@#(t,) + else : + mfun_node@#(nodepath, t,) + fi + exitif true ; + endfor +enddef ; + +vardef nodeboundingpoint@#(text t) = + for a = t : + if (path a) or (unknown a) : + mfun_nodeboundingpoint@#(t) + elseif (string a) and (length(a) = 0) : + mfun_nodeboundingpoint@#(t) + else : + mfun_nodeboundingpoint@#(nodepath,a) + fi + exitif true ; + endfor +enddef ; + +vardef fromto@#(expr d, f)(text t) = + fromtopaths@#(d,nodepath,f,nodepath,t) +enddef ; + +% returns a pair suffix if the path is unknown + +vardef mfun_makenode@#(suffix p)(expr i)(text t) = + save d, b ; string b ; + d = dimension p ; + if d > 0 : + b := prefix p ; + if not picture p.pic[i] : scantokens("picture " & b & + for j=1 upto d : "[]" & endfor + "pic[] ;") ; fi + if not pair p.pos[i] : scantokens("pair " & b & + for j=1 upto d : "[]" & endfor + "pos[] ;") ; fi + else : + if not picture p.pic[i] : picture p.pic[] ; fi + if not pair p.pos[i] : pair p.pos[] ; fi + fi + for a = t : + if known p.pic[i] : + addto p.pic[i] also + else : + p.pic[i] = + fi + if picture a : a + elseif string a : if (length(a) > 0) : textext@#(a) else : nullpicture fi + elseif numeric a : textext@#(decimal a) + elseif ((boolean a) and a) : image(draw origin withpen currentpen scaled 4) + else : nullpicture + fi ; + endfor + p.pos[i] if known p : := point i of p ; fi +enddef ; + +% returns a picture + +vardef mfun_node@#(suffix p)(expr i)(text t) = + if pair mfun_makenode@#(p,i,t) : + % nop: enclose in "if ... fi" to gobble the function return. + fi + if (unknown p) and (known p.pos[i]) : + makenodepath(p) ; + fi + if known p.pic[i] : + p.pic[i] if known p : shifted point i of p fi + else : + nullpicture + fi +enddef ; + +newinternal node_loopback_yscale ; node_loopback_yscale := 1 ; + +% returns a path + +vardef fromtopaths@#(expr d)(suffix p)(expr f)(suffix q)(text s) = + save r, t, l ; + path r[] ; 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 ; + deviation := if numeric d: d else: 0 fi ; + r1 = if (point 0 of r0) = (point length r0 of r0) : + (fullcircle yscaled node_loopback_yscale rotated 180 + if mfun_laboff@# <> origin : + rotated angle mfun_laboff@# + shifted .5mfun_laboff@# + fi) + scaled deviation + shifted point 0 of r0 + elseif 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 : if (length(a) > 0) : textext@#(a) else : nullpicture fi + 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 mfun_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 ; + for a = s : + if unknown t : + t = a ; + mfun_nodeboundingpoint@#(q,t) + mfun_nodeboundingpoint@#(p,f) + else : + + relative@#(a) + fi + endfor +enddef ; + +% helpers that save passing tokens + +def mfun_node_init(expr dx, dy, da) = + save nodelattice ; pair nodelattice[] ; + nodelattice0 = (dx,0) ; + nodelattice1 = dy * dir(da) ; + clearnodepath ; + save nodecount ; nodecount = -1; +enddef ; + +def mfun_node_make(expr x, y, s) = + nodecount := nodecount + 1 ; + makenode(nodecount,s) = x * nodelattice0 + y * nodelattice1 ; +enddef ; + +def mfun_node_flush = + for i=0 upto nodecount: + draw node(i) ; + endfor +enddef ; + +vardef mfun_nodes_fromto@#(expr d, f)(text t) = + fromtopaths@#(d,nodepath,f,nodepath,t) +enddef ; + +permanent makenodepath, clearpath, clearnodepath, makenode, node, nodeboundingpoint, fromto, fromtopaths, relative, betweennodes ; +permanent node_loopback_yscale ; + |