summaryrefslogtreecommitdiff
path: root/metapost/context/base/mpiv/mp-node.mpiv
diff options
context:
space:
mode:
Diffstat (limited to 'metapost/context/base/mpiv/mp-node.mpiv')
-rw-r--r--metapost/context/base/mpiv/mp-node.mpiv182
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 ;
+