From a4e07f30e880ab27c2918f81f136e257475b7729 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 15 Mar 2018 16:04:31 +0100 Subject: 2018-03-15 15:36:00 --- metapost/context/base/mpii/mp-tool.mpii | 1 + metapost/context/base/mpiv/metafun.mpiv | 1 + metapost/context/base/mpiv/mp-char.mpiv | 24 ++-- metapost/context/base/mpiv/mp-crop.mpiv | 22 +++- metapost/context/base/mpiv/mp-grap.mpiv | 5 +- metapost/context/base/mpiv/mp-grph.mpiv | 5 +- metapost/context/base/mpiv/mp-luas.mpiv | 24 ++-- metapost/context/base/mpiv/mp-mlib.mpiv | 42 +++--- metapost/context/base/mpiv/mp-node.mpiv | 220 ++++++++++++++++++++++---------- metapost/context/base/mpiv/mp-page.mpiv | 6 +- metapost/context/base/mpiv/mp-text.mpiv | 14 +- metapost/context/base/mpiv/mp-tool.mpiv | 161 +++++++++++++++++------ metapost/context/base/mpiv/mp-tres.mpiv | 186 +++++++++++++++++++++++++++ 13 files changed, 535 insertions(+), 176 deletions(-) create mode 100644 metapost/context/base/mpiv/mp-tres.mpiv (limited to 'metapost') 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] 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 ; + -- cgit v1.2.3