summaryrefslogtreecommitdiff
path: root/metapost
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-03-15 16:04:31 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-03-15 16:04:31 +0100
commita4e07f30e880ab27c2918f81f136e257475b7729 (patch)
tree02db002d3001a49777a049f9a98fdc872a5e1ad1 /metapost
parentcbc37c39432e0ebe38e0922fc6d14c2955ab3ba2 (diff)
downloadcontext-a4e07f30e880ab27c2918f81f136e257475b7729.tar.gz
2018-03-15 15:36:00
Diffstat (limited to 'metapost')
-rw-r--r--metapost/context/base/mpii/mp-tool.mpii1
-rw-r--r--metapost/context/base/mpiv/metafun.mpiv1
-rw-r--r--metapost/context/base/mpiv/mp-char.mpiv24
-rw-r--r--metapost/context/base/mpiv/mp-crop.mpiv22
-rw-r--r--metapost/context/base/mpiv/mp-grap.mpiv5
-rw-r--r--metapost/context/base/mpiv/mp-grph.mpiv5
-rw-r--r--metapost/context/base/mpiv/mp-luas.mpiv24
-rw-r--r--metapost/context/base/mpiv/mp-mlib.mpiv42
-rw-r--r--metapost/context/base/mpiv/mp-node.mpiv220
-rw-r--r--metapost/context/base/mpiv/mp-page.mpiv6
-rw-r--r--metapost/context/base/mpiv/mp-text.mpiv14
-rw-r--r--metapost/context/base/mpiv/mp-tool.mpiv161
-rw-r--r--metapost/context/base/mpiv/mp-tres.mpiv186
13 files changed, 535 insertions, 176 deletions
diff --git a/metapost/context/base/mpii/mp-tool.mpii b/metapost/context/base/mpii/mp-tool.mpii
index a3300f5bb..562139fed 100644
--- a/metapost/context/base/mpii/mp-tool.mpii
+++ b/metapost/context/base/mpii/mp-tool.mpii
@@ -2816,3 +2816,4 @@ enddef;
extra_endfig := extra_endfig & "mfun_apply_max_dimensions ;" ;
let dump = relax ;
+
diff --git a/metapost/context/base/mpiv/metafun.mpiv b/metapost/context/base/mpiv/metafun.mpiv
index ab3fa8638..818fd7c56 100644
--- a/metapost/context/base/mpiv/metafun.mpiv
+++ b/metapost/context/base/mpiv/metafun.mpiv
@@ -35,6 +35,7 @@ input "mp-func.mpiv" ; % under construction
% "mp-char.mpiv" ; % loaded on demand
% "mp-step.mpiv" ; % loaded on demand
% "mp-chem.mpiv" ; % loaded on demand
+input "mp-node.mpiv" ; % relatively small so preloaded
input "mp-apos.mpiv" ;
input "mp-abck.mpiv" ;
diff --git a/metapost/context/base/mpiv/mp-char.mpiv b/metapost/context/base/mpiv/mp-char.mpiv
index e878c2d16..54e9d6e88 100644
--- a/metapost/context/base/mpiv/mp-char.mpiv
+++ b/metapost/context/base/mpiv/mp-char.mpiv
@@ -31,14 +31,14 @@ numeric flow_shape_width ; flow_shape_width := 45pt ;
numeric flow_grid_height ; flow_grid_height := 40pt ;
numeric flow_shape_height ; flow_shape_height := 30pt ;
numeric flow_chart_offset ; flow_chart_offset := 2pt ;
-color flow_chart_background_color ; flow_chart_background_color := white ;
+string flow_chart_background_color ; flow_chart_background_color := "white" ;
boolean flow_show_mid_points ; flow_show_mid_points := false ;
boolean flow_show_con_points ; flow_show_con_points := false ;
boolean flow_show_all_points ; flow_show_all_points := false ;
numeric flow_shape_line_width ; flow_shape_line_width := 2pt ;
-color flow_shape_line_color ; flow_shape_line_color := .5white ;
-color flow_shape_fill_color ; flow_shape_fill_color := .9white ;
-color flow_connection_line_color ; flow_connection_line_color := .2white ;
+string flow_shape_line_color ; flow_shape_line_color := "gray-5" ;
+string flow_shape_fill_color ; flow_shape_fill_color := "gray-9";
+string flow_connection_line_color ; flow_connection_line_color := "gray-2" ;
numeric flow_connection_line_width ; flow_connection_line_width := flow_shape_line_width ;
@@ -102,14 +102,14 @@ def flow_new_chart =
flow_grid_height := 40pt ;
flow_shape_height := 30pt ;
flow_chart_offset := 2pt ;
- flow_chart_background_color := white ;
+ flow_chart_background_color := "white" ;
flow_show_mid_points := false ;
flow_show_con_points := false ;
flow_show_all_points := false ;
flow_shape_line_width := 2pt ;
- flow_shape_line_color := .5white ;
- flow_shape_fill_color := .9white ;
- flow_connection_line_color := .2white ;
+ flow_shape_line_color := "gray-5" ;
+ flow_shape_fill_color := "gray-9" ;
+ flow_connection_line_color := "gray-2" ;
flow_connection_line_width := flow_shape_line_width ;
flow_connection_smooth_size := 5pt ;
flow_connection_arrow_size := 4pt ;
@@ -140,8 +140,8 @@ def flow_new_chart =
path flow_xypath [][] ;
numeric flow_xysx [][] ;
numeric flow_xysy [][] ;
- color flow_xyfill [][] ;
- color flow_xydraw [][] ;
+ string flow_xyfill [][] ;
+ string flow_xydraw [][] ;
numeric flow_xyline [][] ;
boolean flow_xypeep [][] ;
picture flow_xytext [][] ;
@@ -150,7 +150,7 @@ def flow_new_chart =
picture flow_xycomment [][] ;
path flow_cpaths [] ;
numeric flow_cline [] ;
- color flow_ccolor [] ;
+ string flow_ccolor [] ;
boolean flow_carrow [] ;
boolean flow_cdash [] ;
boolean flow_ccross [] ;
@@ -1112,7 +1112,7 @@ def flow_begin_sub_chart =
begingroup ;
save flow_shape_line_width, flow_connection_line_width ;
save flow_shape_line_color, flow_shape_fill_color, flow_connection_line_color ;
- color flow_shape_line_color, flow_shape_fill_color, flow_connection_line_color ;
+ string flow_shape_line_color, flow_shape_fill_color, flow_connection_line_color ;
save flow_smooth, flow_arrowtip, flow_dashline, flow_peepshape ;
boolean flow_smooth, flow_arrowtip, flow_dashline, flow_peepshape ;
enddef ;
diff --git a/metapost/context/base/mpiv/mp-crop.mpiv b/metapost/context/base/mpiv/mp-crop.mpiv
index 00bcdcb44..e06cf8def 100644
--- a/metapost/context/base/mpiv/mp-crop.mpiv
+++ b/metapost/context/base/mpiv/mp-crop.mpiv
@@ -15,7 +15,7 @@ if known context_crop : endinput ; fi ;
boolean context_crop ; context_crop := true ;
-vardef crop_marks_lines (expr box, len, offset, nx, ny) =
+vardef crop_marks_lines (expr box, len, offset, nx, ny, boxtoo) =
save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ;
p := image (
x := if nx = 0 : 1 else : nx - 1 fi ;
@@ -30,12 +30,20 @@ vardef crop_marks_lines (expr box, len, offset, nx, ny) =
draw ((llcorner box) -- (llcorner box) shifted (0,-len)) shifted (i*w,-offset) ;
draw ((ulcorner box) -- (ulcorner box) shifted (0, len)) shifted (i*w, offset) ;
endfor ;
+ if boxtoo :
+ for i=0 upto x-1 :
+ for j=0 upto y-1 :
+ draw box enlarged 1/8 shifted (i*w,j*h) dashed evenly withpen pencircle scaled 1/4 ;
+ endfor ;
+ endfor ;
+ fi ;
) ;
setbounds p to box ;
p
enddef ;
vardef crop_marks_cmyk =
+ pickup pencircle scaled 1/2 ;
save p ; picture p ; p := image (
fill ulcircle scaled 12.5 withcolor (1,0,0,0) ;
fill urcircle scaled 12.5 withcolor (0,1,0,0) ;
@@ -125,6 +133,8 @@ enddef ;
def page_marks_add_color(expr width, height, length, offset) = % todo: namespace
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
+
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
@@ -159,6 +169,8 @@ enddef ;
def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
+
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
@@ -169,12 +181,14 @@ def page_marks_add_marking(expr width, height, length, offset) = % todo: namespa
enddef ;
-def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace
+def page_marks_add_lines(expr width, height, length, offset, nx, ny, boxtoo) = % todo: namespace
+
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
- draw crop_marks_lines(page,length,offset,nx,ny) ;
+ draw crop_marks_lines(page,length,offset,nx,ny,boxtoo) ;
setbounds currentpicture to page ;
@@ -182,6 +196,8 @@ enddef ;
def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
+
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
diff --git a/metapost/context/base/mpiv/mp-grap.mpiv b/metapost/context/base/mpiv/mp-grap.mpiv
index 3a1d7742a..e799f629c 100644
--- a/metapost/context/base/mpiv/mp-grap.mpiv
+++ b/metapost/context/base/mpiv/mp-grap.mpiv
@@ -199,7 +199,8 @@ def begingraph(expr w, h) =
graph_number_of_arrowheads = 0 ;
if known graph_background : % new feature!
- fill origin--(w,0)--(w,h)--(0,h)--cycle withcolor graph_background ;
+ addto graph_finished_graph contour
+ origin--(w,0)--(w,h)--(0,h)--cycle withcolor graph_background ;
fi
enddef ;
@@ -863,7 +864,7 @@ vardef graph_gridline_picture@#(suffix $)(expr c, f, u)(text w) =
if c : graph_xyscale fi
shifted (((.5 + mfun_laboff@# dotprod (.5,.5)) * mfun_laboff@#) graph_xyscale) ;
image(draw p w ;
- label@#(if string f : format(f,u) else : f fi, point 0 of p))
+ label@#(if string f : format(f,u) else : f fi, point 0 of p) w)
fi
enddef ;
diff --git a/metapost/context/base/mpiv/mp-grph.mpiv b/metapost/context/base/mpiv/mp-grph.mpiv
index 5938b9f02..04d4920f6 100644
--- a/metapost/context/base/mpiv/mp-grph.mpiv
+++ b/metapost/context/base/mpiv/mp-grph.mpiv
@@ -65,7 +65,6 @@ enddef ;
numeric currentgraphictext ; currentgraphictext := 0 ;
-def data_mpo_file = job_name & "-mpgraph.mpo" enddef ;
def data_mpy_file = job_name & "-mpgraph.mpy" enddef ;
def begingraphictextfig (expr n) =
@@ -82,10 +81,10 @@ def endgraphictextfig =
enddef ;
def loadfigure primary filename =
- doloadfigure (filename)
+ mfun_load_figure(filename)
enddef ;
-def doloadfigure (expr filename) text figureattributes =
+def mfun_load_figure (expr filename) text figureattributes =
begingroup ;
save figurenumber, figurepicture, number, fixedplace ;
numeric figurenumber ; figurenumber := 0 ;
diff --git a/metapost/context/base/mpiv/mp-luas.mpiv b/metapost/context/base/mpiv/mp-luas.mpiv
index 76d28f7f9..d35701ec6 100644
--- a/metapost/context/base/mpiv/mp-luas.mpiv
+++ b/metapost/context/base/mpiv/mp-luas.mpiv
@@ -49,6 +49,9 @@ boolean context_luas ; context_luas := true ;
%
% Fourth variant:
+string mfun_lua_bs ; mfun_lua_bs := "[[" ;
+string mfun_lua_es ; mfun_lua_es := "]]" ;
+
vardef mlib_luas_luacall(text t) =
runscript("" for s = t :
if string s :
@@ -72,7 +75,8 @@ vardef mlib_luas_lualist(expr c)(text t) =
hide(b := true)
fi
if string s :
- & ditto & s & ditto
+ % & ditto & s & ditto
+ & mfun_lua_bs & s & mfun_lua_es
elseif numeric s :
& decimal s
elseif boolean s :
@@ -106,21 +110,11 @@ def message expr t =
if t <> "" : lua.mp.report(t) fi ;
enddef ;
-% a few helpers
-
-% A few helpers:
-
-vardef isarray suffix a =
- lua.mp.isarray(str a)
-enddef ;
+% A few helpers
-vardef prefix suffix a =
- lua.mp.prefix(str a)
-enddef ;
-
-vardef dimensions suffix a =
- lua.mp.dimensions(str a)
-enddef ;
+vardef isarray suffix a = lua.mp.isarray (str a) enddef ;
+vardef prefix suffix a = lua.mp.prefix (str a) enddef ;
+vardef dimension suffix a = lua.mp.dimension(str a) enddef ;
% More access
diff --git a/metapost/context/base/mpiv/mp-mlib.mpiv b/metapost/context/base/mpiv/mp-mlib.mpiv
index 0638ee3e1..115fe63ae 100644
--- a/metapost/context/base/mpiv/mp-mlib.mpiv
+++ b/metapost/context/base/mpiv/mp-mlib.mpiv
@@ -1245,33 +1245,21 @@ vardef properties(text t) =
image(draw unitcircle t)
enddef ;
-% if metapostversion < 1.770 :
-%
-% def withproperties expr p =
-% if colormodel p = 3 :
-% withcolor greypart p
-% elseif colormodel p = 5 :
-% withcolor (redpart p,greenpart p,bluepart p)
-% elseif colormodel p = 7 :
-% withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p)
-% fi
-% enddef ;
-%
-% else :
-
- def withproperties expr p =
- if colormodel p = 3 :
- withcolor greypart p
- elseif colormodel p = 5 :
- withcolor (redpart p,greenpart p,bluepart p)
- elseif colormodel p = 7 :
- withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p)
- fi
- withprescript prescriptpart p
- withpostscript postscriptpart p
- enddef ;
-
-% fi ;
+def withproperties expr p =
+ if colormodel p = 3 :
+ withcolor greypart p
+ elseif colormodel p = 5 :
+ withcolor (redpart p,greenpart p,bluepart p)
+ elseif colormodel p = 7 :
+ withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p)
+ fi
+ withpen penpart p
+ % if dashpart p <> nullpicture : % fails
+ dashed dashpart p
+ % fi
+ withprescript prescriptpart p
+ withpostscript postscriptpart p
+enddef ;
% Experimental:
diff --git a/metapost/context/base/mpiv/mp-node.mpiv b/metapost/context/base/mpiv/mp-node.mpiv
index fdd308ad1..79391220b 100644
--- a/metapost/context/base/mpiv/mp-node.mpiv
+++ b/metapost/context/base/mpiv/mp-node.mpiv
@@ -11,76 +11,137 @@
%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 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 context_node : endinput ; fi ;
boolean context_node ; context_node := true ;
-% returns a pair suffix if the path is unknown
+% Build a path from the node positions.
+% Must be integer and continuous in index starting at 0.
-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
+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 :
- if not picture p.pic[i] : picture p.pic[] ; fi
- if not pair p.pos[i] : pair p.pos[] ; fi
+ 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,)
else :
- if known p.pic[i] :
- addto p.pic[i] also
- else :
- p.pic[i] :=
- fi
+ 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,)
+ 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)
+ 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 : textext@#(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)
+ elseif ((boolean a) and a) : image(draw origin withpen currentpen scaled 4)
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.
+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
- 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 ;
+newinternal node_loopback_yscale ; node_loopback_yscale := 1 ;
+
% returns a path
-vardef fromto@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
+vardef fromtopaths@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
save r, t, l ;
- path r[] ; numeric t ; picture l ;
+ path r[] ; picture l ;
for a = s :
if unknown t :
t = a ;
@@ -97,15 +158,24 @@ vardef fromto@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
else :
point f of p -- point t of q
fi ;
- save deviation ; numeric deviation ;
+ save 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
+ 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 :
@@ -113,12 +183,12 @@ vardef fromto@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
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 ;
+ 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
@@ -140,7 +210,7 @@ enddef ;
% returns pair: bounding point of the node picture
-vardef nodeboundingpoint@#(suffix p)(expr i) =
+vardef mfun_nodeboundingpoint@#(suffix p)(expr i) =
if known p.pic[i] :
boundingpoint@#(p.pic[i])
else :
@@ -157,7 +227,7 @@ enddef ;
% returns pair: vector between nodes (+ optional scale)
vardef betweennodes@#(suffix p)(expr f)(suffix q)(text s) =
- save t ; numeric t ;
+ save t ;
for a = s :
if unknown t :
t = a ;
@@ -168,15 +238,27 @@ vardef betweennodes@#(suffix p)(expr f)(suffix q)(text s) =
endfor
enddef ;
-% build a path from the node positions.
-% Must be continuous in index starting at 0.
+% helpers that save passing tokens
-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
+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 ;
diff --git a/metapost/context/base/mpiv/mp-page.mpiv b/metapost/context/base/mpiv/mp-page.mpiv
index f32990677..6e93bdaae 100644
--- a/metapost/context/base/mpiv/mp-page.mpiv
+++ b/metapost/context/base/mpiv/mp-page.mpiv
@@ -235,9 +235,13 @@ vardef OnOddPage = lua.mp.OnOddPage () enddef ;
vardef InPageBody = lua.mp.InPageBody () enddef ;
vardef RealPageNumber = lua.mp.RealPageNumber () enddef ;
+vardef LastPageNumber = lua.mp.LastPageNumber () enddef ; % duplicates
+
vardef PageNumber = lua.mp.PageNumber () enddef ;
vardef NOfPages = lua.mp.NOfPages () enddef ;
-vardef LastPageNumber = lua.mp.LastPageNumber () enddef ; % duplicates
+
+vardef SubPageNumber = lua.mp.SubPageNumber () enddef ;
+vardef NOfSubPages = lua.mp.NOfSubPages () enddef ;
vardef CurrentColumn = lua.mp.CurrentColumn () enddef ;
vardef NOfColumns = lua.mp.NOfColumns () enddef ;
diff --git a/metapost/context/base/mpiv/mp-text.mpiv b/metapost/context/base/mpiv/mp-text.mpiv
index b68e8412a..043d09d80 100644
--- a/metapost/context/base/mpiv/mp-text.mpiv
+++ b/metapost/context/base/mpiv/mp-text.mpiv
@@ -59,10 +59,10 @@ def build_parshape (expr p, offset_or_path, dx, dy, baselineskip, strutheight, s
startsavingdata ;
- savedata "\global\parvoffset " & decimal voffset&"bp " ;
- savedata "\global\parhoffset " & decimal hoffset&"bp " ;
- savedata "\global\parwidth " & decimal hsize&"bp " ;
- savedata "\global\parheight " & decimal vsize&"bp " ;
+ savedata "\global\parvoffset " & decimal voffset & "bp " ;
+ savedata "\global\parhoffset " & decimal hoffset & "bp " ;
+ savedata "\global\parwidth " & decimal hsize & "bp " ;
+ savedata "\global\parheight " & decimal vsize & "bp " ;
if not path offset_or_path :
q := q xscaled ((hsize-2hoffset)/hsize) yscaled ((vsize-2voffset)/vsize) ;
@@ -144,13 +144,13 @@ def build_parshape (expr p, offset_or_path, dx, dy, baselineskip, strutheight, s
if (i=strutheight) and (width[n]<baselineskip) :
n := n - 1 ;
- savedata "\global\chardef\parfirst=1 " ;
+ savedata "\global\parfirst\plusone " ;
fi ;
endfor ;
- savedata "\global\parlines " & decimal n ;
- savedata "\global\partoks{ " ;
+ savedata "\global\parlines " & decimal n ;
+ savedata "\global\partoks{ " ;
for i=1 upto n:
savedata decimal indent[i]&"bp " & decimal width[i]&"bp " ;
endfor ;
diff --git a/metapost/context/base/mpiv/mp-tool.mpiv b/metapost/context/base/mpiv/mp-tool.mpiv
index cd04b8dcb..36d6f1743 100644
--- a/metapost/context/base/mpiv/mp-tool.mpiv
+++ b/metapost/context/base/mpiv/mp-tool.mpiv
@@ -234,50 +234,27 @@ def job_name =
jobname
enddef ;
-def data_mpd_file =
- job_name & "-mp.mpd"
-enddef ;
-
%D Because \METAPOST\ has a hard coded limit of 4~datafiles,
%D we need some trickery when we have multiple files. This will
%D be redone (via \LUA).
-if unknown collapse_data :
- boolean collapse_data ;
- collapse_data := false ;
-fi ;
-
boolean savingdata ; savingdata := false ;
boolean savingdatadone ; savingdatadone := false ;
def savedata expr txt =
- write if collapse_data :
- txt
- else :
- if savingdata : txt else : "\MPdata{" & decimal charcode & "}{" & txt & "}" fi & "%"
- fi to data_mpd_file ;
+ lua.mp.save_data(txt);
enddef ;
def startsavingdata =
- savingdata := true ;
- savingdatadone := true ;
- if collapse_data :
- write "\MPdata{" & decimal charcode & "}{%" to data_mpd_file ;
- fi ;
+ lua.mp.start_saving_data();
enddef ;
def stopsavingdata =
- if collapse_data :
- write "}%" to data_mpd_file ;
- fi ;
- savingdata := false ;
+ lua.mp.stop_saving_data() ;
enddef ;
def finishsavingdata =
- if savingdatadone :
- write EOF to data_mpd_file ;
- savingdatadone := false ;
- fi ;
+ lua.mp.finish_saving_data() ;
enddef ;
%D Instead of a keystroke eating save and allocation
@@ -1204,8 +1181,53 @@ enddef ;
%D Interesting too:
+% primarydef p paralleled d = (
+% p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p)
+% ) enddef ;
+%
+% primarydef p paralleled d = (
+% p shifted ((d*unitvector(direction 0 of p) - point 0 of p) rotated 90)
+% ) enddef ;
+%
+% Alan came up with an improved version and stepwise we ended up with (or
+% might up with a variant of):
+
+vardef perpendicular expr t of p =
+ unitvector((direction t of p) rotated 90)
+enddef ;
+
+def istextext(expr p) =
+ (picture p and ((substring(0,3) of prescriptpart p) = "tx_"))
+enddef ;
+
primarydef p paralleled d = (
- p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p)
+ if path p :
+ begingroup ;
+ save dp ; pair dp ;
+ for i=0 upto length p if cycle p : -1 fi :
+ hide(dp := d * perpendicular i of p)
+ if i > 0 : .. fi
+ (point i of p + dp)
+ if i < length p :
+ .. controls (postcontrol i of p + dp) and
+ (precontrol (i+1) of p + dp)
+ fi
+ endfor
+ if cycle p : .. cycle fi
+ endgroup
+ elseif picture p :
+ image(
+ for i within p :
+ draw (pathpart i)
+ if not istextext(i) : % dirty trick
+ paralleled d
+ fi
+ mfun_decoration_i i ;
+ endfor ;
+ )
+ elseif pair p :
+ p
+ fi
) enddef ;
vardef punked primary p =
@@ -1291,6 +1313,7 @@ enddef ;
newinternal ahvariant ; ahvariant := 0 ;
newinternal ahdimple ; ahdimple := 1/5 ;
+newinternal ahscale ; ahscale := 3/4 ;
vardef arrowhead expr p =
save q, e, r ;
@@ -1333,7 +1356,8 @@ def resetarrows =
ahangle := 45 ;
ahvariant := 0 ;
ahdimple := 1/5 ;
- )
+ ahscale := 3/4 ;
+)
enddef ;
%D Points.
@@ -1690,7 +1714,9 @@ def mfun_with_arrow_picture (text t) =
mfun_arrow_count := 0 ;
mfun_arrow_snippets := stroked_paths(mfun_arrow_picture) ;
for i within mfun_arrow_picture :
- if stroked i :
+ if istextext(i) :
+ draw i
+ else :
mfun_arrow_count := mfun_arrow_count + 1 ;
mfun_arrow_path := pathpart i ;
t
@@ -1719,13 +1745,12 @@ def mfun_draw_arrow_picture_double text t =
fi
mfun_with_arrow_picture (
draw
- if mfun_arrow_count = 1 :
- arrowpath reverse
- fi
- if mfun_arrow_count = mfun_arrow_snippets :
- arrowpath
- fi
- mfun_arrow_path mfun_decoration_i i t ;
+ if mfun_arrow_count = 1 :
+ arrowpath reverse
+ elseif mfun_arrow_count = mfun_arrow_snippets :
+ arrowpath
+ fi
+ mfun_arrow_path mfun_decoration_i i t ;
if mfun_arrow_count = 1 :
fillup arrowhead reverse mfun_arrow_path mfun_decoration_i i t ;
fi
@@ -1736,6 +1761,65 @@ def mfun_draw_arrow_picture_double text t =
endgroup ;
enddef ;
+%D Some more arrow magic, by Alan:
+
+def drawdoublearrows expr p =
+ begingroup ;
+ save mfun_arrow_path ;
+ path mfun_arrow_path ;
+ save mfun_arrow_path_parallel ;
+ path mfun_arrow_path_parallel ;
+ if path p :
+ mfun_arrow_path := p ;
+ expandafter mfun_draw_arrow_paths
+ elseif picture p :
+ save mfun_arrow_picture ;
+ picture mfun_arrow_picture ;
+ mfun_arrow_picture := p ;
+ expandafter mfun_draw_arrow_pictures
+ else :
+ expandafter mfun_draw_arrow_nothing
+ fi
+enddef ;
+
+def mfun_draw_arrow_paths text t =
+ if autoarrows :
+ set_ahlength(t) ;
+ fi
+ save d ; d := ahscale*ahlength*sind(ahangle/2) ;
+ mfun_arrow_path_parallel := mfun_arrow_path paralleled d ;
+ draw arrowpath mfun_arrow_path_parallel t ;
+ fillup arrowhead mfun_arrow_path_parallel t ;
+ mfun_arrow_path_parallel := (reverse mfun_arrow_path) paralleled d ;
+ draw arrowpath mfun_arrow_path_parallel t ;
+ fillup arrowhead mfun_arrow_path_parallel t ;
+ endgroup ;
+enddef ;
+
+def mfun_draw_arrow_pictures text t =
+ if autoarrows :
+ set_ahlength(t) ;
+ fi
+ save d ; d := ahscale*ahlength*sind(ahangle/2) ;
+ mfun_with_arrow_picture(
+ if mfun_arrow_count = 1 :
+ draw (mfun_arrow_path paralleled d) mfun_decoration_i i t ;
+ mfun_arrow_path_parallel := (reverse mfun_arrow_path) paralleled d ;
+ draw arrowpath mfun_arrow_path_parallel mfun_decoration_i i t ;
+ fillup arrowhead mfun_arrow_path_parallel mfun_decoration_i i t ;
+ elseif mfun_arrow_count = mfun_arrow_snippets :
+ draw ((reverse mfun_arrow_path) paralleled d) mfun_decoration_i i t ;
+ mfun_arrow_path_parallel := mfun_arrow_path paralleled d ;
+ draw arrowpath mfun_arrow_path_parallel mfun_decoration_i i t ;
+ fillup arrowhead mfun_arrow_path_parallel mfun_decoration_i i t ;
+ else :
+ draw ( mfun_arrow_path paralleled d) mfun_decoration_i i t ;
+ draw ((reverse mfun_arrow_path) paralleled d) mfun_decoration_i i t ;
+ fi
+ )
+ endgroup ;
+enddef ;
+
%D Handy too ......
vardef pointarrow (expr pat, loc, len, off) =
@@ -3222,6 +3306,9 @@ def loadmodule expr name = % no vardef
fi ;
enddef ;
+def loadfile (expr filename) = scantokens("input " & filename) enddef ;
+def loadimage (expr filename) = image(scantokens("input " & filename);) enddef ;
+
%D Handy for backgrounds:
def drawpathwithpoints expr p =
diff --git a/metapost/context/base/mpiv/mp-tres.mpiv b/metapost/context/base/mpiv/mp-tres.mpiv
new file mode 100644
index 000000000..335670a98
--- /dev/null
+++ b/metapost/context/base/mpiv/mp-tres.mpiv
@@ -0,0 +1,186 @@
+%D \module
+%D [ file=mp-tres.mpiv,
+%D version=2017.11.08,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=Pseudo 3D,
+%D author=Alan Braslau,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+%D This module provides simple 3D->2D projections. The code is an adaption of code
+%D by Urs Oswald, Dr.sc.math.\ ETH as presented in:
+%D
+%D \starttyping
+%D http://www.ursoswald.ch/metapost/tutorial.html.
+%D \stoptyping
+%D
+%D We need a bit more so it got extended.
+
+if known context_three : endinput ; fi ;
+
+boolean context_three ; context_three := true ;
+
+pair mfun_three_xy ; % this avoids the costly save and allocate
+pair mfun_three_yz ;
+pair mfun_three_zx ;
+
+transform Txy ;
+
+def setTxy(expr ori, ang) =
+ begingroup
+ save P, t ;
+ pair P[] ;
+ transform t ;
+
+ P0 = ori ; % origin in MetaPost coordinates (bp)
+ P1 = (left rotated ang) scaled (cosd ang) ; % x axis (in mathematical coordinates)
+
+ % A sort of "cavalier projection".
+
+ % t: maps mathematical 2D coordinates onto MetaPost coordinates.
+
+ t := identity shifted P0 ; % Note: no shift when P0 = origin!
+
+ % Txy: maps the x-y plane of 3D space onto MetaPost coordinates,
+ % z is the vertical (MetaPost y).
+
+ % Txy:=identity
+ % reflectedabout((0,0), (1,1))
+ % yscaled ypart P1
+ % slanted (xpart P1/ypart P1)
+ % transformed t ;
+
+ % Alternatively, defined via Pxy:
+
+ % Pxy is the projection of the 3D plane z=0 onto the mathematical 2D coordinates.
+ % Pxy is determined by 3 e q u a t i o n s describing
+ % how (1,0), (0,1), and (0,0) are mapped
+
+ save Pxy ;
+ transform Pxy ;
+ P1 = (1,0) transformed Pxy ; % Pxy: (1,0) --> P1
+ (1,0) = (0,1) transformed Pxy ; % (0,1) --> (1,0)
+ (0,0) = (0,0) transformed Pxy ; % (0,0) --> (0,0)
+
+ % mathematical 2D coordinates --> MetaPost coordinates
+
+ Txy := Pxy transformed t ;
+ endgroup
+enddef ;
+
+setTxy(origin,60) ;
+
+%D We already define triplet (as rgbcolor synonym) in in \type {mp-tool.mpiv}:
+
+let Xpart = redpart ;
+let Ypart = greenpart ;
+let Zpart = bluepart ;
+
+primarydef p Xscaled q =
+ (q*Xpart p, Ypart p, Zpart p)
+enddef ;
+
+primarydef p Yscaled q =
+ (Xpart p, q*Ypart p, Zpart p)
+enddef ;
+
+primarydef p Zscaled q =
+ (Xpart p, Ypart p, q*Zpart p)
+enddef ;
+
+primarydef p XYZscaled q =
+ (q*Xpart p,q*Ypart p,q*Zpart p)
+enddef ;
+
+vardef projection expr t =
+ if triplet t :
+ (Xpart t, Ypart t) transformed Txy shifted (0,Zpart t)
+ elseif pair t :
+ t transformed Txy
+ else :
+ origin transformed Txy
+ fi
+enddef ;
+
+%D This overloads the plain macro \type {abs} (being \type {length}):
+
+vardef abs primary p =
+ if triplet p :
+ sqrt((Xpart p)**2+(Ypart p)**2+(Zpart p)**2)
+ else :
+ length p
+ fi
+enddef ;
+
+primarydef p dotproduct q =
+ ((Xpart p)*(Xpart q) + (Ypart p)*(Ypart q) + (Zpart p)*(Zpart q))
+enddef ;
+
+primarydef p crossproduct q =
+ (
+ (Ypart p)*(Zpart q) - (Zpart p)*(Ypart q),
+ (Zpart p)*(Xpart q) - (Xpart p)*(Zpart q),
+ (Xpart p)*(Ypart q) - (Ypart p)*(Xpart q)
+ )
+enddef ;
+
+primarydef p rotatedaboutX q =
+ hide (
+ mfun_three_yz := (Ypart p, Zpart p) ;
+ mfun_three_yz := mfun_three_yz rotated q ;
+ )
+ (Xpart p, xpart mfun_three_yz, ypart mfun_three_yz)
+enddef ;
+
+primarydef p rotatedaboutY q =
+ hide(
+ mfun_three_zx := (Zpart p, Xpart p) ;
+ mfun_three_zx := mfun_three_zx rotated q ;
+ )
+ (ypart mfun_three_zx, Ypart p, xpart mfun_three_zx)
+enddef ;
+
+primarydef p rotatedaboutZ q =
+ hide (
+ mfun_three_xy := (Xpart p, Ypart p) ;
+ mfun_three_xy := mfun_three_xy rotated q ;
+ )
+ (xpart mfun_three_xy, ypart mfun_three_xy, Zpart p)
+enddef ;
+
+%D We can use a rotation about an arbitrary direction t ... (easy)
+
+% primarydef p rotatedabout(expr t, a) =
+% enddef ;
+
+vardef draw_vector@# (expr v, s) text t =
+ if triplet v :
+ drawarrow projection(Origin) -- projection(v) t ;
+ if string s :
+ label@#(s, projection(v)) t ;
+ fi
+ fi
+enddef ;
+
+%D Some constants...
+
+triplet Origin, Xunitvector, Yunitvector, Zunitvector ;
+
+Origin := (0,0,0) ;
+Xunitvector := (1,0,0) ;
+Yunitvector := (0,1,0) ;
+Zunitvector := (0,0,1) ;
+
+%D We could do but don't:
+
+% let normalxpart = xpart ;
+% let normalypart = ypart ;
+
+% vardef xpart expr p = if triplet p : redpart else : normalxpart fi p enddef ;
+% vardef ypart expr p = if triplet p : greenpart else : normalypart fi p enddef ;
+% vardef zpart expr p = bluepart p enddef ;
+