texlive[66174] Master/texmf-dist/metapost/context/base: ConTeXt LMTX:

commits+siepo at tug.org commits+siepo at tug.org
Sun Feb 26 15:42:15 CET 2023


Revision: 66174
          http://tug.org/svn/texlive?view=revision&revision=66174
Author:   siepo
Date:     2023-02-26 15:42:15 +0100 (Sun, 26 Feb 2023)
Log Message:
-----------
ConTeXt LMTX: metapost

Modified Paths:
--------------
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-back.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-base.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grap.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grph.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-mlib.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-page.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tres.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpxl/metafun.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/minifun.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-abck.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-apos.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-base.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-cont.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-grph.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-lmtx.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-luas.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-math.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-mlib.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-page.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-text.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-tool.mpxl

Added Paths:
-----------
    trunk/Master/texmf-dist/metapost/context/base/common/boxes.mp
    trunk/Master/texmf-dist/metapost/context/base/common/hatching.mp
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-xbox.mpiv
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-asnc.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-xbox.mpxl

Removed Paths:
-------------
    trunk/Master/texmf-dist/metapost/context/base/mpii/
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-idea.mpiv

Added: trunk/Master/texmf-dist/metapost/context/base/common/boxes.mp
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/common/boxes.mp	                        (rev 0)
+++ trunk/Master/texmf-dist/metapost/context/base/common/boxes.mp	2023-02-26 14:42:15 UTC (rev 66174)
@@ -0,0 +1 @@
+scantokens("input mp-xbox.mp" & (if metapostversion > 2 : "xl" else : "iv" fi)) ;


Property changes on: trunk/Master/texmf-dist/metapost/context/base/common/boxes.mp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/metapost/context/base/common/hatching.mp
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/common/hatching.mp	                        (rev 0)
+++ trunk/Master/texmf-dist/metapost/context/base/common/hatching.mp	2023-02-26 14:42:15 UTC (rev 66174)
@@ -0,0 +1,10 @@
+% This is placeholder for Bogluslaw Jackowski's hatching.mp file which can be found in
+% the public domain and dates from 2000. It provides:
+%
+% draw hatched (fullcircle scaled 10cm) (45, 4, 1) withcolor "red" ;
+%
+% interim hatch_match := 1;
+%
+% This macro is not in mp-tool so this is a placeholder. The hatching macro doesn't fit
+% into metafun because it assume withcolor to behave in a certain way. Also, we use more
+% efficient path constructor.


Property changes on: trunk/Master/texmf-dist/metapost/context/base/common/hatching.mp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-back.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-back.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-back.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -33,6 +33,23 @@
     endgroup ;
 enddef ;
 
+% \starttext
+%
+% \startMPpage
+%     input "mp-back"
+%
+%     some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white, .6white, .7white, .6white) currentpicture := currentpicture shifted (0,-3cm) ;
+%     some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white, .6white,   white,   white) currentpicture := currentpicture shifted (0,-3cm) ;
+%     some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white,  white,    white,   white) currentpicture := currentpicture shifted (0,-3cm) ;
+%     some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white,  white,    white,   white) currentpicture := currentpicture shifted (0,-3cm) ;
+%     some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white,  white,    white,   white) currentpicture := currentpicture shifted (0,-3cm) ;
+%     some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white,  white,    white,   white) currentpicture := currentpicture shifted (0,-3cm) ;
+%     some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white,  white,    white,   white) currentpicture := currentpicture shifted (0,-3cm) ;
+%     some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm, .5white, .8white, .7white,  white,    white,   white)
+% \stopMPpage
+
+% \stoptext
+
 def some_double_back (expr back_type        ,
                            back_width       ,
                            back_height      ,
@@ -163,49 +180,3 @@
 
     endgroup;
 enddef ;
-
-% endinput ;
-%
-% beginfig (1) ;
-%
-% some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, .6white, .7white, .6white)
-%
-% currentpicture := currentpicture shifted (0,-3cm) ;
-%
-% some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, .6white, white, white)
-%
-% currentpicture := currentpicture shifted (0,-3cm) ;
-%
-% some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, white, white, white)
-%
-% currentpicture := currentpicture shifted (0,-3cm) ;
-%
-% some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, white, white, white)
-%
-% currentpicture := currentpicture shifted (0,-3cm) ;
-%
-% some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, white, white, white)
-%
-% currentpicture := currentpicture shifted (0,-3cm) ;
-%
-% some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, white, white, white)
-%
-% currentpicture := currentpicture shifted (0,-3cm) ;
-%
-% some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, white, white, white)
-%
-% currentpicture := currentpicture shifted (0,-3cm) ;
-%
-% some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm,
-%            .5white, .8white, .7white, white, white, white)
-%
-% endfig ;
-%
-% end .

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-base.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-base.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-base.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -85,7 +85,6 @@
     tracingchoices   := 1 ;
     tracinglostchars := 1 ;
     tracingstats     := 1 ;
-    tracingoutput    := 1 ;
     tracingmacros    := 1 ;
     tracingrestores  := 1 ;
 enddef ;
@@ -105,7 +104,6 @@
     tracingchoices   := 0 ;
     tracinglostchars := 0 ;
     tracingstats     := 0 ;
-    tracingoutput    := 0 ;
     tracingmacros    := 0 ;
     tracingrestores  := 0 ;
 enddef ;
@@ -194,26 +192,32 @@
 
 background := white ; % obsolete
 
-let graypart  = greypart  ;
+let graypart  = greypart ;
 let greycolor = numeric ;
 let graycolor = numeric ;
 
 % color part (will be overloaded)
 
+newinternal nocolormodel   ; nocolormodel   := 1 ;
+newinternal greycolormodel ; greycolormodel := 3 ;
+newinternal graycolormodel ; graycolormodel := 3 ;
+newinternal rgbcolormodel  ; rgbcolormodel  := 5 ;
+newinternal cmykcolormodel ; cmykcolormodel := 7 ;
+
 def colorpart primary t =
-    if colormodel t = 7:
+    if colormodel t = cmykcolormodel:
         (cyanpart t, magentapart t, yellowpart t, blackpart t)
-    elseif colormodel t = 5 :
+    elseif colormodel t = rgbcolormodel :
         (redpart t, greenpart t, bluepart t)
-    elseif colormodel t = 3 :
+    elseif colormodel t = graycolormodel :
         (greypart t)
-    elseif colormodel t = 1 :
+    elseif colormodel t = nocolormodel :
         false
-    elseif defaultcolormodel = 7 :
+    elseif defaultcolormodel = cmykcolormodel :
         (0,0,0,1)
-    elseif defaultcolormodel = 5 :
+    elseif defaultcolormodel = rgbcolormodel :
         black
-    elseif defaultcolormodel = 3 :
+    elseif defaultcolormodel = graycolormodel :
         0
     else :
         false
@@ -924,8 +928,13 @@
 extra_beginfig := "" ;
 extra_endfig   := "" ;
 
-def beginfig(expr c) =
+boolean makingfigure ; makingfigure := false ;
+numeric stacking ; stacking := 0 ;
+
+def beginfig(expr c) = % redefined in mp-grph !
     begingroup
+    save makingfigure ; boolean makingfigure ;
+    save stacking ; numeric stacking;
     charcode := c ;
     clearxy ;
     clearit ;
@@ -932,6 +941,8 @@
     clearpen ;
     pickup defaultpen ;
     drawoptions() ;
+    stacking := 0 ;
+    makingfigure := true;
     scantokens extra_beginfig ;
 enddef ;
 

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grap.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grap.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grap.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -36,7 +36,7 @@
 % Macros for drawing graphs
 
 % begingraph(width,height)       begin a new graph
-% setcoords(xtype,ytype)         sets up a new coordinate system (log,-linear..)
+% setcoords(xtype,ytype)         sets up a new coordinate system (logarithmic,-linear..)
 % setrange(lo,hi)                set coord ranges (numeric and string args OK)
 % gdraw <file or path> [with...] draw a line in current coord system
 % gfill <file or path> [with...] fill a region using current coord system
@@ -221,7 +221,7 @@
 %   an offset to graph_modified_lower and graph_modified_higher to ease computing exponents
 % Some additional variables function as constants.  Most can be modified by the
 % user to alter the behavior of these macros.
-% Not very modifiable :  log, linear,
+% Not very modifiable :  logarithmic, linear,
 %                        graph_frame_pair_a, graph_frame_pair_b, graph_margin_pair
 % Modifiable :           graph_template.suffix,
 %                        graph_log_marks[], graph_lin_marks, graph_exp_marks,
@@ -229,8 +229,8 @@
 %                        graph_log_minimum, Autoform
 
 
-newinternal log, linear ;        % coordinate system codes
-log :=1 ; linear :=2;
+newinternal logarithmic, linear ;        % coordinate system codes
+logarithmic :=1 ; linear :=2;
 
 % note that mp-tool.mpiv defines log as log10.
 
@@ -240,10 +240,10 @@
 % to setcoords.
 % `Internal graph coordinates' are used for graph_current_graph, graph_current_bb, Z_.low, Z_.high.
 % Their meaning depends on the appropriate component of Z_.graph_coordinate_type :
-%     log means internal graph coords =  mlog(user graph coords)
-%    -log means internal graph coords = -mlog(user graph coords)
-%  linear means internal graph coords =      (user graph coords)
-% -linear means internal graph coords =     -(user graph coords)
+%  logarithmic means internal graph coords =  mlog(user graph coords)
+% -logarithmic means internal graph coords = -mlog(user graph coords)
+%  linear      means internal graph coords =      (user graph coords)
+% -linear      means internal graph coords =     -(user graph coords)
 
 
 vardef graph_set_default_bounds =         % Set default Z_.low, Z_.high
@@ -279,13 +279,13 @@
 %def graph_with_pen_and_color(expr q) =
 %  withpen penpart q
 %  withcolor
-%  if colormodel q=1 :
+%  if colormodel q=nocolormodel :
 %    false
-%  elseif colormodel q=3 :
+%  elseif colormodel q=graycolormodel :
 %    (greypart q)
-%  elseif colormodel q=5 :
+%  elseif colormodel q=rgbcolormodel :
 %    (redpart q, greenpart q, bluepart q)
-%  elseif colormodel q=7 :
+%  elseif colormodel q=cmykcolormodel :
 %    (cyanpart q, magentapart q, yellowpart q, blackpart q)
 %  fi
 %  withprescript  prescriptpart q
@@ -396,23 +396,23 @@
      @#low  = if unknown l :
                 whatever
               else :
-                if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l
+                if abs @#graph_coordinate_type=logarithmic : graph_mlog fi if string l : scantokens fi l
               fi ;
      @#high = if unknown h :
                 whatever
               else :
-                if abs @#graph_coordinate_type=log : graph_mlog fi if string h : scantokens fi h
+                if abs @#graph_coordinate_type=logarithmic : graph_mlog fi if string h : scantokens fi h
               fi ;
   else :
     -@#high = if unknown l :
                 whatever
               else :
-                if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l
+                if abs @#graph_coordinate_type=logarithmic : graph_mlog fi if string l : scantokens fi l
               fi ;
     -@#low  = if unknown h :
                 whatever
               else :
-                if abs @#graph_coordinate_type=log : graph_mlog fi if string h : scantokens fi h
+                if abs @#graph_coordinate_type=logarithmic : graph_mlog fi if string h : scantokens fi h
               fi ;
   fi
 enddef ;
@@ -451,8 +451,8 @@
   if known p :
     graph_scan_path(p,
       (abs X_.graph_coordinate_type<>linear) or (abs Y_.graph_coordinate_type<>linear),
-      if abs X_.graph_coordinate_type=log : graph_mlog fi,
-      if abs Y_.graph_coordinate_type=log : graph_mlog fi)
+      if abs X_.graph_coordinate_type=logarithmic : graph_mlog fi,
+      if abs Y_.graph_coordinate_type=logarithmic : graph_mlog fi)
       transformed  (identity
         if X_.graph_coordinate_type<0 : xscaled -1 fi
         if Y_.graph_coordinate_type<0 : yscaled -1 fi)
@@ -928,7 +928,7 @@
 Ten_to4 = 10000 ;
 
 % Determine the X_ or Y_ bounds on the range to be covered by automatic grid
-% marks.  Suffix @# is X_ or Y_.  The result is log or linear to specify the
+% marks.  Suffix @# is X_ or Y_.  The result is logarithmic or linear to specify the
 % type of grid spacing to use.  Bounds are returned in variables local to
 % begingraph..endgraph : pairs graph_modified_lower and graph_modified_higher
 %  are upper and lower bounds in
@@ -940,10 +940,10 @@
   save l, h ;
   graph_set_default_bounds ;
   if @#graph_coordinate_type>0 : (l,h) else : -(h,l) fi = (@#low, @#high) ;
-  if abs @#graph_coordinate_type=log :
+  if abs @#graph_coordinate_type=logarithmic :
     graph_modified_lower  := graph_Meform(l)+graph_modified_bias ;
     graph_modified_higher := graph_Meform(h)+graph_modified_bias ;
-    if h-l >= graph_log_minimum : log else : linear fi
+    if h-l >= graph_log_minimum : logarithmic else : linear fi
   else :
     graph_modified_lower  := graph_Feform(l)+graph_modified_bias ;
     graph_modified_higher := graph_Feform(h)+graph_modified_bias ;
@@ -1072,7 +1072,7 @@
 
 def auto suffix $ =
   hide(def graph_comma= hide(def graph_comma=,enddef) enddef)
-  if graph_bounds.graph_suffix($)=log :
+  if graph_bounds.graph_suffix($)=logarithmic :
     if graph_select_exponent_mark.graph_exponent :
       graph_generate_exponents(graph_exponent,
         graph_comma graph_factor_and_exponent_to_string(1,e))

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grph.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grph.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-grph.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -49,8 +49,10 @@
     interim linecap := linecap ;
     interim linejoin := linejoin ;
     interim miterlimit := miterlimit ;
-    save _background_ ; color _background_ ; _background_ :=  background  ;
-    save  background  ; color  background  ;  background  := _background_ ;
+    save stacking ; numeric stacking ; stacking := 0 ;
+    save makingfigure ; boolean makingfigure ; makingfigure := true ;
+    save _background_ ; color _background_ ; _background_ := background  ;
+    save  background ; color background ;  background := _background_ ;
     drawoptions () ;
 enddef ;
 

Deleted: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-idea.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-idea.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-idea.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -1,44 +0,0 @@
-% redpart (1,1,0,0) crashes
-
-% let normalredpart     = redpart ;
-% let normalgreenpart   = greenpart ;
-% let normalbluepart    = bluepart ;
-% let normalcyanpart    = cyanpart ;
-% let normalmagentapart = magentapart ;
-% let normalyellowpart  = yellowpart ;
-% let normalblackpart   = blackpart ;
-
-% vardef redpart     expr p = if cmykcolor p : 1 - normalcyanpart    p elseif rgbcolor p :     normalredpart   p else : p fi enddef ;
-% vardef greenpart   expr p = if cmykcolor p : 1 - normalmagentapart p elseif rgbcolor p :     normalgreenpart p else : p fi enddef ;
-% vardef bluepart    expr p = if cmykcolor p : 1 - normalyellowpart  p elseif rgbcolor p :     normalbluepart  p else : p fi enddef ;
-% vardef cyanpart    expr p = if cmykcolor p :     normalcyanpart    p elseif rgbcolor p : 1 - normalredpart   p else : p fi enddef ;
-% vardef magentapart expr p = if cmykcolor p :     normalmagentapart p elseif rgbcolor p : 1 - normalgreenpart p else : p fi enddef ;
-% vardef yellowpart  expr p = if cmykcolor p :     normalyellowpart  p elseif rgbcolor p : 1 - normalbluepart  p else : p fi enddef ;
-% vardef blackpart   expr p = if cmykcolor p :     normalblackpart   p elseif rgbcolor p :                     0 else : p fi enddef ;
-
-vardef rcomponent expr p = if rgbcolor  p : redpart     p elseif cmykcolor p : 1 - cyanpart    p else : p fi enddef ;
-vardef gcomponent expr p = if rgbcolor  p : greenpart   p elseif cmykcolor p : 1 - magentapart p else : p fi enddef ;
-vardef bcomponent expr p = if rgbcolor  p : bluepart    p elseif cmykcolor p : 1 - yellowpart  p else : p fi enddef ;
-vardef ccomponent expr p = if cmykcolor p : cyanpart    p elseif rgbcolor  p : 1 - redpart     p else : p fi enddef ;
-vardef mcomponent expr p = if cmykcolor p : magentapart p elseif rgbcolor  p : 1 - greenpart   p else : p fi enddef ;
-vardef ycomponent expr p = if cmykcolor p : yellowpart  p elseif rgbcolor  p : 1 - bluepart    p else : p fi enddef ;
-vardef bcomponent expr p = if cmykcolor p : blackpart   p elseif rgbcolor  p :                 0 else : p fi enddef ;
-
-vardef somecolor = (1,1,0,0) enddef ;
-
-fill OverlayBox withcolor (rcomponent somecolor,gcomponent somecolor,bcomponent somecolor) ;
-fill OverlayBox withcolor (ccomponent somecolor,mcomponent somecolor,ycomponent somecolor,bcomponent somecolor) ;
-
-% def newcolor     text v = forsuffixes i=v : save i ; color     i ; endfor ; enddef ;
-% def newnumeric   text v = forsuffixes i=v : save i ; numeric   i ; endfor ; enddef ;
-% def newboolean   text v = forsuffixes i=v : save i ; boolean   i ; endfor ; enddef ;
-% def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; enddef ;
-% def newpath      text v = forsuffixes i=v : save i ; path      i ; endfor ; enddef ;
-% def newpicture   text v = forsuffixes i=v : save i ; picture   i ; endfor ; enddef ;
-% def newstring    text v = forsuffixes i=v : save i ; string    i ; endfor ; enddef ;
-
-% width := 10 ;
-% beginfig(1) ;
-%   newpath width, height ; width := origin -- cycle ;
-% endfig ;
-% width := 10 ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-mlib.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-mlib.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-mlib.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -310,7 +310,7 @@
 pair mfun_laboff.lrt    ; mfun_laboff.lrt    := (.7,-.7) ;
 
 pair mfun_laboff.d      ; mfun_laboff.d      := mfun_laboff     ;
-pair mfun_laboff.dflt   ; mfun_laboff.dflt   := mfun_laboff.lft ;
+pair mfun_laboff.dlft   ; mfun_laboff.dlft   := mfun_laboff.lft ;
 pair mfun_laboff.drt    ; mfun_laboff.drt    := mfun_laboff.rt  ;
 pair mfun_laboff.origin ; mfun_laboff.origin := mfun_laboff     ;
 pair mfun_laboff.raw    ; mfun_laboff.raw    := mfun_laboff     ;
@@ -339,7 +339,7 @@
 mfun_labxf.lrt      := mfun_labxf.r_b := mfun_labxf.b_r := 0   ;
 
 mfun_labxf.d        := mfun_labxf     ;
-mfun_labxf.dflt     := mfun_labxf.lft ;
+mfun_labxf.dlft     := mfun_labxf.lft ;
 mfun_labxf.drt      := mfun_labxf.rt  ;
 mfun_labxf.origin   := 0              ;
 mfun_labxf.raw      := 0              ;
@@ -355,7 +355,7 @@
 mfun_labyf.lrt      := mfun_labyf.r_b := mfun_labyf.b_r := 1   ;
 
 mfun_labyf.d        := mfun_labyf     ;
-mfun_labyf.dflt     := mfun_labyf.lft ;
+mfun_labyf.dlft     := mfun_labyf.lft ;
 mfun_labyf.drt      := mfun_labyf.rt  ;
 mfun_labyf.origin   := 0              ;
 mfun_labyf.raw      := 0              ;
@@ -370,7 +370,7 @@
 mfun_labtype.llft   := mfun_labtype.l_b :=  mfun_labtype.b_l :=  7 ;
 mfun_labtype.lrt    := mfun_labtype.r_b :=  mfun_labtype.b_r :=  8 ;
 mfun_labtype.d                                               := 10 ;
-mfun_labtype.dflt                                            := 11 ;
+mfun_labtype.dlft                                            := 11 ;
 mfun_labtype.drt                                             := 12 ;
 mfun_labtype.origin                                          :=  0 ;
 mfun_labtype.raw                                             :=  0 ;
@@ -1334,11 +1334,11 @@
 enddef ;
 
 def withproperties expr p =
-    if colormodel p = 3 :
+    if colormodel p = graycolormodel :
         withcolor greypart p
-    elseif colormodel p = 5 :
+    elseif colormodel p = rgbcolor :
         withcolor (redpart p,greenpart p,bluepart p)
-    elseif colormodel p = 7 :
+    elseif colormodel p = cmykcolormodel :
         withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p)
     fi
     withpen penpart p

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-page.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-page.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-page.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -504,6 +504,10 @@
     (unitsquare xyscaled (OverlayWidth,OverlayHeight))
 enddef ;
 
+def BoundToOverlayBox =
+    setbounds currentpicture to OverlayBox;
+enddef ;
+
 % handy
 
 def innerenlarged =

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -138,12 +138,6 @@
 
 %D Colors:
 
-newinternal nocolormodel   ; nocolormodel   := 1 ;
-newinternal greycolormodel ; greycolormodel := 3 ;
-newinternal graycolormodel ; graycolormodel := 3 ;
-newinternal rgbcolormodel  ; rgbcolormodel  := 5 ;
-newinternal cmykcolormodel ; cmykcolormodel := 7 ;
-
 let grayscale = graycolor ;
 let greyscale = greycolor ;
 
@@ -554,7 +548,7 @@
 enddef ;
 
 vardef mfun_tool_striped_number(expr option, p, s_n, s_slot) text extra =
-    image (
+%     image (
         begingroup ;
         save pattern, shape, bounds, penwidth, used_n, used_slot ;
         picture pattern, shape ; path bounds ; numeric used_s, used_slot ;
@@ -591,7 +585,7 @@
             addto currentpicture also shape ;
         fi ;
         endgroup ;
-    )
+%     )
 enddef ;
 
 def mfun_tool_striped_angle_action text extra =
@@ -602,7 +596,7 @@
 enddef ;
 
 vardef mfun_tool_striped_angle(expr option, p, s_angle, s_gap) text extra =
-    image (
+%     image (
         begingroup ;
         save pattern, shape, mask, maximum, minimum, centrum, used_angle, used_gap ;
         picture pattern, shape, mask ; numeric maximum, minimum ; pair centrum ; numeric used_angle, used_gap ;
@@ -643,7 +637,7 @@
         fi ;
         currentpicture := currentpicture shifted centrum ;
         endgroup ;
-    )
+%     )
 enddef;
 
 newinternal striped_normal_inner  ; striped_normal_inner  := 1 ;
@@ -652,11 +646,13 @@
 newinternal striped_reverse_outer ; striped_reverse_outer := 4 ;
 
 secondarydef p anglestriped s =
-    mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)
+  % mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)
+    image(mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)) % for 'withcolor'
 enddef ;
 
 secondarydef p numberstriped s =
-    mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)
+  % mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)
+    image(mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)) % for 'withcolor'
 enddef ;
 
 % for old times sake:
@@ -2474,6 +2470,23 @@
     endfor cycle)
 enddef ;
 
+% Mikael Sundqvist came up with this one. We made it robust for points being too close
+% for smoothing.
+
+primarydef p smoothcornered c =
+    ( begingroup ;
+        save cc ;
+        if not cycle p: (point 0 of p) -- fi
+        for i=1 upto length(p) :
+            hide (cc := min(c,arclength (subpath(i-1,i) of p)/2);)
+            (point i-1 of p) shifted (cc*(unitvector(point i   of p - point i-1 of p))) --
+            (point i   of p) shifted (cc*(unitvector(point i-1 of p - point i   of p))) ..
+            controls point i of p ..
+        endfor
+        if cycle p : cycle else : point 1 along p fi
+    endgroup )
+enddef ;
+
 % cmyk color support
 
 % vardef cmyk(expr c,m,y,k) = % elsewhere
@@ -3689,3 +3702,67 @@
             t
         endgroup
 enddef ;
+
+% By Bogluslaw Jackowski (public domain):
+%
+% draw hatched (fullcircle scaled 10cm) (45, 4, 1) withcolor "red" ;
+
+newinternal hatch_match; hatch_match := 1;
+
+vardef hatched(expr o) primary c =
+    save a_, b_, d_, l_, i_, r_, za_, zb_, zc_, zd_;
+    path b_; picture r_; pair za_, zb_, zc_, zd_;
+    r_ := image (
+        a_ := redpart(c) mod 180 ;
+        l_ := greenpart(c) ;
+        d_ := -bluepart(c) ;
+        b_ := o rotated -a_ ;
+        b_ :=
+            if a_ >= 90 :
+                (lrcorner b_ -- llcorner b_ -- ulcorner b_ -- urcorner b_ -- cycle)
+            else :
+                (llcorner b_ -- lrcorner b_ -- urcorner b_ -- ulcorner b_ -- cycle)
+            fi
+            rotated a_ ;
+        za_ := point 0 of b_ ;
+        zb_ := point 1 of b_ ;
+        zc_ := point 2 of b_ ;
+        zd_ := point 3 of b_ ;
+        if hatch_match > 0 :
+            n_ := round(length(zd_-za_) / l_) ;
+            if n_ < 2:
+                n_ := 2 ;
+            fi ;
+            l_ := length(zd_-za_) / n_ ;
+        else :
+            n_ := length(zd_-za_) / l_ ;
+        fi
+        save currentpen; pen currentpen ; pickup pencircle scaled d_;
+        % we use a single path instead:
+        for i_ := if hatch_match > 0 : 1 else : 0 fi upto ceiling n_ - 1 :
+            nodraw (i_/n_)[zd_,za_] -- (i_/n_)[zc_,zb_] ;
+        endfor
+        dodraw origin ;
+    ) ;
+    clip r_ to o;
+    r_
+enddef;
+
+% By Mikael Sundqvist, with a little evolution:
+
+numeric mfun_dash_on, mfun_dash_off ;
+
+primarydef p withdashes len =
+    hide (
+        save l, t, n, m, don, doff; pair t ;
+        l := arclength p ;
+        t := paired (len) ;
+        m := xpart t + ypart t ;
+        n := (l if not cycle p : - xpart t fi) div m ;
+        (n if not cycle p : + 1 fi) * don + n * doff = l ;
+        don*(ypart t) = doff*(xpart t) ;
+        mfun_dash_on := don ;
+        mfun_dash_off := doff ;
+    )
+    p dashed dashpattern (on mfun_dash_on off mfun_dash_off)
+enddef ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tres.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tres.mpiv	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tres.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -106,9 +106,7 @@
      fi)
 enddef ;
 
-%D This overloads the plain macro \type {abs} (being \type {length}):
-
-vardef abs primary p =
+vardef Abs primary p =
     if triplet p :
         sqrt((Xpart p)**2+(Ypart p)**2+(Zpart p)**2)
     else :
@@ -116,6 +114,10 @@
     fi
 enddef ;
 
+vardef Unitvector primary z =
+    z/Abs z
+enddef ;
+
 primarydef p dotproduct q =
     ((Xpart p)*(Xpart q) + (Ypart p)*(Ypart q) + (Zpart p)*(Zpart q))
 enddef ;

Added: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-xbox.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-xbox.mpiv	                        (rev 0)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-xbox.mpiv	2023-02-26 14:42:15 UTC (rev 66174)
@@ -0,0 +1,329 @@
+% This file is a variant of "macros for boxes"::
+%
+% author    : Taco Hoekwater
+% version   : $Id: boxes.mp,v 1.5 2005/02/25 11:28:56 taco Exp $
+% copyright : Public domain
+% patched   : Hans Hagen
+%
+% author    : Karl Berry
+% version   : $Id: rboxes.mp,v 1.2 2004/09/19 21:47:11 karl Exp $
+% copyright : Public domain
+% patched   : Hans Hagen
+%
+% The code is the same but I've added a boxes_ namespace for some so that we don't
+% clash with metafun.
+
+if known metafun_loaded_xbox : endinput ; fi ;
+
+boolean metafun_loaded_xbox ; metafun_loaded_xbox := true ;
+
+% Find the length of the prefix of string s for which cond is true for each character
+% c of the prefix. Loading and initialization is now under metafun control. Only the
+% mpxl variant will be adapted. When needed this file will be adapted.
+
+vardef boxes_str_prefix (expr s) (text cond) =
+    save i_, c; string c; i_ = 0;
+    forever:
+        c := substring (i_, i_ + 1) of s;
+        exitunless cond;
+        exitif incr i_ = length s;
+    endfor
+    i_
+enddef;
+
+% Take a string returned by the str operator and return the same string with explicit
+% numeric subscripts replaced by generic subscript symbols [] (fixed by Eddie Kohler).
+
+vardef generisize (expr ss) =
+    save r, s, l; string r, s;
+    r = ""; % result so far
+    s = ss; % left to process
+    forever:
+        exitif s = "";
+        l := boxes_str_prefix(s, (c<>"[") and ((c<"0") or (c>"9")));
+        r := r & substring (0,l) of s;
+        s := substring (l, infinity) of s;
+        if s <> "" :
+            if (s >= "[") and (length s > 1) :
+                if (substring (1,2) of s) = "[" :
+                    l := 2;
+                    r := r & "[[";
+                else :
+                    l := 1 + boxes_str_prefix(s, c <> "]");
+                    r := r & "[]";
+                fi
+            else :
+                r := r & "[]";
+                l := boxes_str_prefix(s, (c = ".") or ("0" <= c) and (c <= "9"));
+            fi
+            s := substring(l, infinity) of s;
+        fi
+    endfor
+    r
+enddef;
+
+% Make sure the string boxes_n_gen is generisize(_n_):
+
+string boxes_n, boxes_n_cur, boxes_n_gen; boxes_n_cur := "]"; % this won't match _n_
+
+vardef boxes_set_n_gen =
+    if boxes_n <> boxes_n_cur:
+        boxes_n_cur := boxes_n;
+        boxes_n_gen := generisize(boxes_n);
+    fi
+enddef;
+
+% Given a type t and list of variable names vars, make sure that they are of type t
+% and redeclare them as necessary.  In the vars list _n represents scantokens boxes_n,
+% a suffix that might contain numeric subscripts. This suffix needs to be replaced
+% by scantokens boxes_n_gen in order to get a variable that can be declared to be of
+% type t.
+
+vardef boxes_declare(text t) text vars =
+    boxes_set_n_gen;
+    forsuffixes v_ = vars :
+        if forsuffixes _n = scantokens boxes_n : not t v_ endfor :
+            def boxes_gdmac text _n = t v_ enddef;
+            expandafter boxes_gdmac scantokens boxes_n_gen;
+        fi
+    endfor
+enddef;
+
+% Here is another version that redeclares the vars even if they are already of the
+% right type.
+
+vardef boxes_redeclare(text t) text vars =
+    boxes_set_n_gen;
+    def boxes_gdmac text _n = t vars enddef;
+    expandafter boxes_gdmac scantokens boxes_n_gen;
+enddef;
+
+% pp should be a string giving the name of a macro that finds the boundary path and
+% sp should be a string that names a macro for fixing the size and shape. The suffix
+% $ is the name of the box. The text t gives the box contents: either empty, a
+% picture, or a string to typeset.
+
+def boxes_begin (expr pp, sp) (suffix $) (text t) =
+    boxes_n := str $;
+    boxes_declare (pair) _n.off, _n.c;
+    boxes_declare (string) boxes_pproc._n, boxes_sproc._n;
+    boxes_declare (picture) boxes_pic._n;
+    boxes_pproc$ := pp;
+    boxes_sproc$ := sp;
+    boxes_pic$ := nullpicture;
+    for _p_ = t :
+      % boxes_pic$ := if picture _p_: _p_ else: _p_ infont defaultfont scaled defaultscale fi;
+        boxes_pic$ := if picture _p_: _p_ else: textext(_p_) fi;
+    endfor
+    $c = $off + .5[llcorner boxes_pic$, urcorner boxes_pic$]
+enddef;
+
+% The suffix cl names a vardef macro that clears box-related variables. The suffix $
+% is the name of the box being ended.
+
+def boxes_end(suffix cl, $) =
+    if known boxes_pic.boxes_prevbox:
+        boxes_dojoin(boxes_prevbox,$);
+    fi
+    def boxes_prevbox = $ enddef;
+    expandafter def expandafter boxes_clear_all expandafter =
+        boxes_clear_all cl($);
+    enddef
+enddef;
+
+% Text t gives equations for joining box a to box b.
+
+def boxes_boxjoin(text t) =
+    def boxes_prevbox = _ enddef;
+    def boxes_dojoin(suffix a,b) = t enddef;
+enddef ;
+
+def boxes_clear_all = enddef;
+
+% Given a list of box names, give whatever default values are necessary
+% in order to fix the size and shape of each box.
+
+vardef boxes_fixsize(text t) =
+    forsuffixes $ = t : scantokens boxes_sproc$($); endfor
+enddef;
+
+% Given a list of box names, give default values for any unknown positioning offsets.
+
+vardef boxes_fixpos(text t) =
+    forsuffixes $=t:
+        if unknown xpart $.off : xpart $.off = 0; fi
+        if unknown ypart $.off : ypart $.off = 0; fi
+    endfor
+enddef;
+
+% Return the boundary path for the given box
+
+vardef bpath suffix $ =
+    boxes_fixsize($);
+    boxes_fixpos($);
+    scantokens boxes_pproc$($)
+enddef;
+
+% Return the contents of the given box. First define a private version that the user can't
+% accidently clobber.
+
+vardef boxes_pic_mac suffix $ =
+    boxes_fixsize($);
+    boxes_fixpos($);
+    boxes_pic$ shifted $off
+enddef;
+
+vardef pic suffix $ = boxes_pic_mac $ enddef;
+
+% Draw each box:
+
+def drawboxed(text t) =
+    boxes_fixsize(t);
+    boxes_fixpos(t);
+    forsuffixes s = t: draw boxes_pic_mac.s; draw bpath.s; endfor
+enddef;
+
+% Draw contents of each box:
+
+def drawunboxed(text t) =
+    boxes_fixsize(t);
+    boxes_fixpos(t);
+    forsuffixes s = t :
+        draw boxes_pic_mac.s;
+    endfor
+enddef;
+
+% Draw boundary path for each box:
+
+def drawboxes(text t) =
+    forsuffixes s = t :
+        draw bpath.s;
+    endfor
+enddef;
+
+% Rectangular boxes
+
+newinternal defaultdx, defaultdy; defaultdx := defaultdy := 3bp;
+
+vardef boxit@#(text tt) =
+    boxes_begin("boxes_path","boxes_size",@#,tt);
+    boxes_declare (pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w;
+    0 = xpart(@#nw - @#sw) = ypart(@#se - @#sw);
+    0 = xpart(@#ne - @#se) = ypart(@#ne - @#nw);
+    @#w = .5[@#nw,@#sw];
+    @#s = .5[@#sw,@#se];
+    @#e = .5[@#ne,@#se];
+    @#n = .5[@#ne,@#nw];
+    @#ne - @#c = @#c - @#sw = (@#dx,@#dy) + .5*(urcorner boxes_pic@# - llcorner boxes_pic@#);
+    boxes_end(boxes_clear,@#);
+enddef;
+
+def boxes_path(suffix $) =
+    $.sw -- $.se -- $.ne -- $.nw -- cycle
+enddef;
+
+def boxes_size(suffix $) =
+    if unknown $.dx : $.dx = defaultdx; fi
+    if unknown $.dy : $.dy = defaultdy; fi
+enddef;
+
+vardef boxes_clear(suffix $) =
+    boxes_n := str $;
+    boxes_redeclare(numeric) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w, _n.c, _n.off, _n.dx, _n.dy;
+enddef;
+
+% Circular and oval boxes
+
+newinternal circmargin; circmargin := 2bp;  % default clearance for picture corner
+
+vardef circleit@#(text tt) =
+    boxes_begin("boxes_the_circle","boxes_size_circle",@#,tt);
+    boxes_generic_declare(pair) _n.n, _n.s, _n.e, _n.w;
+    @#e - @#c = @#c - @#w = (@#dx,0) + .5*(lrcorner boxes_pic@# - llcorner boxes_pic@#);
+    @#n - @#c = @#c - @#s = (0,@#dy) + .5*(ulcorner boxes_pic@# - llcorner boxes_pic@#);
+    boxes_end(boxes_clear_circle,@#);
+enddef;
+
+def boxes_the_circle (suffix $) =
+    $.e{up} ... $.n{left} ... $.w{down} ... $.s{right} ... cycle
+enddef;
+
+vardef boxes_clear_circle (suffix $) =
+    boxes_n := str $;
+    boxes_redeclare(numeric) _n.n, _n.s, _n.e, _n.w, _n.c, _n.off, _n.dx, _n.dy;
+enddef;
+
+vardef boxes_size_circle (suffix $) =
+    save a_, b_;
+    (a_,b_) = .5*(urcorner boxes_pic$ - llcorner boxes_pic$);
+    if unknown $dx :
+        if unknown $dy :
+            if unknown($dy-$dx) :
+                a_ + $dx = b_ + $dy;
+            fi
+            if a_ + $dx = b_ + $dy :
+                a_ + $dx = a_ ++ b_ + circmargin;
+            else :
+                $dx = boxes_select(max(a_,b_ + $dx - $dy), (a_ + d_,0){up} ... (0,b_ + d_ + $dy - $dx){left});
+            fi
+        else :
+            $dx = boxes_select(a_, (a_ + d_,0){up}...(0,b_ + $dy){left});
+        fi
+    elseif unknown $dy :
+        $dy = boxes_select(b_, (a_ + $dx,0){up}...(0,b_ + d_){left});
+    fi
+enddef;
+
+vardef boxes_select(expr dhi)(text tt) =
+    save f_, p_; path p_;
+    p_ = origin .. (a_,b_) + circmargin * unitvector(a_,b_);
+    vardef f_ (expr d_) =
+        xpart((tt) intersectiontimes p_) >= 0
+    enddef;
+    solve f_(0, dhi + 1.5circmargin)
+enddef;
+
+def boxes_init_all =
+    boxes_boxjoin();
+    save boxes_pic, boxes_sproc, boxes_pproc;
+    def boxes_clear_all = enddef;
+enddef ;
+
+def boxjoin(text t) =
+    def boxes_prevbox = _ enddef;
+    def boxes_dojoin(suffix a,b) = t enddef;
+enddef;
+
+extra_beginfig := extra_beginfig & "boxes_init_all;";
+extra_endfig   := "boxes_clear_all;" & extra_endfig;
+
+if makingfigure :
+    boxes_init_all;
+fi ;
+
+% Rectangular boxes with rounded corners
+
+newinternal rbox_radius ; rbox_radius := 8bp ;
+
+vardef rboxit@#(text tt) =
+    boxes_begin("boxes_the_rounded","boxes_size",@#,tt) ;
+    boxes_generic_declare (pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w ;
+    0 = xpart(@#nw - @#sw) = ypart(@#se - @#sw) ;
+    0 = xpart(@#ne - @#se) = ypart(@#ne - @#nw) ;
+    @#w = .5[@#nw,@#sw] ;
+    @#s = .5[@#sw,@#se] ;
+    @#e = .5[@#ne,@#se] ;
+    @#n = .5[@#ne,@#nw] ;
+    @#ne - @#c = @#c - @#sw = (@#dx,@#dy) + .5*(urcorner boxes_pic@# - llcorner boxes_pic@#) ;
+    boxes_end(boxes_clear,@#) ;
+enddef;
+
+def boxes_the_rounded(suffix $) =
+    save _r ; _r = min(rbox_radius, .5*ypart($.n-$.s), .5*xpart($.e-$.w));
+    $.sw + (_r,0) {right} .. {right} $.se - (_r,0) ..
+    $.se + (0,_r)    {up} .. {up}    $.ne - (0,_r) ..
+    $.ne - (_r,0)  {left} .. {left}  $.nw + (_r,0) ..
+    $.nw - (0,_r)  {down} .. {down}  $.sw + (0,_r) ..
+    cycle
+enddef;
+

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/metafun.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/metafun.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/metafun.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -46,6 +46,7 @@
 input "mp-node.mpxl" ;
 input "mp-apos.mpxl" ;
 input "mp-abck.mpxl" ;
+input "mp-asnc.mpxl" ;
 input "mp-blob.mpxl" ;
 input "mp-lmtx.mpxl" ;
 input "mp-text.mpxl" ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/minifun.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/minifun.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/minifun.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -24,10 +24,10 @@
 
 newinternal boolean contextlmtxmode ; contextlmtxmode := true ; immutable contextlmtxmode ;
 
-input "mp-base.mpiv" ;
+input "mp-base.mpxl" ;
 input "mp-tool.mpxl" ;
+input "mp-luas.mpxl" ;
 input "mp-mlib.mpxl" ;
-input "mp-luas.mpxl" ;
 input "mp-math.mpxl" ;
 input "mp-cont.mpxl" ;
 input "mp-page.mpxl" ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-abck.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-abck.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-abck.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -31,27 +31,67 @@
 nofmultipars     := 0 ;
 par_strut_height := 0 ;
 par_strut_depth  := 0 ;
-par_line_height  := 0 ;
+% par_line_height  := 0 ;
 
-def boxgridoptions = withcolor .8red   enddef ;
-def boxlineoptions = withcolor .8blue  enddef ;
-def boxfilloptions = withcolor .8white enddef ;
+pair    boxgriddirection ; boxgriddirection := up ;   % to be interfaced
+numeric boxgriddistance  ; boxgriddistance  := .5cm ; % to be interfaced
 
-numeric boxgridtype      ; boxgridtype      := 0 ;
-numeric boxlinetype      ; boxlinetype      := 1 ;
-numeric boxfilltype      ; boxfilltype      := 1 ;
-numeric boxdashtype      ; boxdashtype      := 0 ;
-pair    boxgriddirection ; boxgriddirection := up ;
-numeric boxgridwidth     ; boxgridwidth     := 1pt ;
-numeric boxlinewidth     ; boxlinewidth     := 1pt ;
-numeric boxlineradius    ; boxlineradius    := 0 ;
-numeric boxlineoffset    ; boxlineoffset    := 0 ;
-numeric boxfilloffset    ; boxfilloffset    := 0 ;
-numeric boxgriddistance  ; boxgriddistance  := .5cm ;
-numeric boxgridshift     ; boxgridshift     := 0 ;
+def boxgridtype     = (runscript mfid_mpvarn "gridtype") enddef ;
+def boxgridwidth    = (runscript mfid_mpvard "gridwidth") enddef ;
+def boxgridshift    = (runscript mfid_mpvard "gridshift") enddef ;
+def boxgridcolor    = (runscript mfid_mpvars "gridcolor") enddef ;
 
-permanent multipars, multiregs, multibox, multikind, multilocs, nofmultipars ;
+def boxlinetype     = (runscript mfid_mpvarn "linetype") enddef ;
+def boxlinewidth    = (runscript mfid_mpvard "linewidth") enddef ;
+def boxlineradius   = (runscript mfid_mpvard "lineradius") enddef ;
+def boxlineoffset   = (runscript mfid_mpvard "lineoffset") enddef ;
+def boxlinecolor    = (runscript mfid_mpvars "linecolor") enddef ;
 
+def boxfilltype     = (runscript mfid_mpvarn "filltype") enddef ;
+def boxfilloffset   = (runscript mfid_mpvard "filloffset") enddef ;
+def boxfillcolor    = (runscript mfid_mpvars "fillcolor") enddef ;
+
+def boxdashtype     = (runscript mfid_mpvarn "dashtype") enddef ;
+
+def boxalternative  = (runscript mfid_mpvarn "alternative") enddef;
+def boxdistance     = (runscript mfid_mpvard "distance") enddef;
+def boxlocation     = (runscript mfid_mpvarn "location") enddef ;
+def boxtopoffset    = (runscript mfid_mpvard "topoffset") enddef;
+def boxbottomoffset = (runscript mfid_mpvard "bottomoffset") enddef;
+
+vardef boxatright  =
+    save b ; b := boxlocation ;
+    if b = 1 :
+        false
+    elseif b = 2 :
+        true
+    elseif OnRightPage :
+        if b = 4 : % outer
+            true
+        else : % inner
+            false
+        fi
+    else :
+        if b = 4 : % inner
+            false
+        else : % inner
+            true
+        fi
+    fi
+enddef ;
+
+def boxgridoptions  = withcolor boxgridcolor enddef ;
+def boxlineoptions  = withcolor boxlinecolor enddef ;
+def boxfilloptions  = withcolor boxfillcolor enddef ;
+
+mutable
+    multipars, multiregs, multibox, multikind, multilocs, nofmultipars,
+    boxgridtype, boxgridwidth, boxgridshift, boxgridcolor,
+    boxlinetype, boxlinewidth, boxlineradius, boxlineoffset, boxlinecolor,
+    boxfilltype, boxfilloffset, boxfillcolor, boxdashtype,
+    boxalternative, boxdistance, boxtopoffset, boxbottomoffset,
+    boxgridoptions, boxlineoptions, boxfilloptions ;
+
 vardef abck_draw_path(expr p) =
     if (length p > 2) and (bbwidth(p) > 1) and (bbheight(p) > 1) :
         save pp ; path pp ;
@@ -205,6 +245,8 @@
 path    pxy[] ;
 numeric hxy[], wxy[], dxy[], nxy[] ;
 
+mutable lxy, rxy, cxy, llxy, lrxy, ulxy, urxy, pxy, hxy, wxy, dxy, nxy ;
+
 def box_found (expr n,x,y,w,h,d) =
     not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0))
 enddef ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-apos.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-apos.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-apos.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -11,6 +11,8 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
+%D Massimiliano Farinella added jiggles (zigzags) to the sidebars.
+
 if known metafun_loaded_apos : endinput ; fi ;
 
 newinternal boolean metafun_loaded_apos ; metafun_loaded_apos := true ; immutable metafun_loaded_apos ;
@@ -68,38 +70,102 @@
 
 % anch-bar:
 
-def anch_sidebars_draw (expr firstpage, lastpage, yfirst, ylast, height, depth,
-        x, y, w, h, alternative, distance, linewidth, linecolor, topoffset, bottomoffset) =
+% When Massimiliano Farinella (aka mf) added the patterns with jiggles the interface got
+% upgraded to lmtx too. So this one is different from the mkiv version! Messed up a little
+% by me to fit in the rest.
+
+vardef anch_sidebars_pattern(expr a, b, pattern, patternlength, patternheight, linewidth) =
+    image (
+        save p, q, s ; pair p, s ; path q ;
+        s := ( (b - a) / arclength (a -- b) ) * patternlength ;
+        q := pattern xscaled patternlength yscaled patternheight rotated (angle(s)) ;
+        p := a ;
+        forever :
+            draw
+                q shifted p
+                withpen pencircle scaled linewidth ;
+            p := p + s ;
+            exitif arclength (a -- p) > arclength (a -- b) ;
+        endfor ;
+        clip currentpicture to
+            (xpart llcorner currentpicture, ypart b) --
+            (xpart lrcorner currentpicture, ypart b) --
+            (xpart urcorner currentpicture, ypart a) --
+            (xpart ulcorner currentpicture, ypart a) -- cycle ;
+    )
+enddef ;
+
+% (performance wise) we can fetch distance and alternative once
+
+def anch_sidebars_draw(expr b_self, e_self, t_anchor) = % even these three can become variables
     % beware, we anchor at (x,y)
     begingroup ;
-    if alternative = 1 :
-        interim linecap := rounded ;
-    else :
-        interim linecap := butt ;
-    fi ;
-    save a, b ; pair a, b ;
-    if firstpage = lastpage :
-        a := (-distance,yfirst+height-y) ;
-        b := (-distance,ylast-depth-y) ;
-    elseif RealPageNumber = firstpage :
-        a := (-distance,yfirst+height-y) ;
-        b := (-distance,0) ;
-    elseif RealPageNumber = lastpage :
-        a := (-distance,h) ;
-        b := (-distance,ylast-depth-y) ;
-    else :
-        a := (-distance,h) ;
-        b := (-distance,0) ;
-    fi ;
-    a := (xpart a, min(ypart a + topoffset,   h)) ;
-    b := (xpart b, max(ypart b - bottomoffset,0)) ;
-    draw
-        a -- b
-        if alternative = 1 :
-            dashed (withdots scaled (linewidth/2))
-        fi
-        withpen pencircle scaled linewidth
-        withcolor linecolor ;
+        interim linecap := if boxalternative = 1 : rounded else : butt fi ;
+        save a, b, lw, by ; pair a, b ; numeric lw, by ;
+        by := getposy(getposregion(b_self)) - getposy(t_anchor) ; % for mf to do: all of them
+        if getpospage(b_self) = getpospage(e_self) :
+            a := (-boxdistance,getposy(b_self) + getposheight(b_self) - getposy(t_anchor)) ;
+            b := (-boxdistance,getposy(e_self) - getposdepth (e_self) - getposy(t_anchor)) ;
+        elseif RealPageNumber = getpospage(b_self) :
+            a := (-boxdistance,getposy(b_self) + getposheight(b_self) - getposy(t_anchor)) ;
+            b := (-boxdistance,by) ;
+        elseif RealPageNumber = getpospage(e_self) :
+            a := (-boxdistance,getposheight(t_anchor)) ;
+            b := (-boxdistance,getposy(e_self) - getposdepth (e_self) - getposy(t_anchor)) ;
+        else :
+            a := (-boxdistance,getposheight(t_anchor)) ;
+            b := (-boxdistance,0) ;
+        fi ;
+        if a == b :
+            message("side bar pattern ignored: a == b") ;
+        else :
+            a := (xpart a, min(ypart a + boxtopoffset,getposheight(t_anchor))) ;
+            b := (xpart b, max(ypart b - boxbottomoffset,0)) ;
+            if boxatright :
+                a := (xpart a + HSize + 2 * boxdistance,ypart a) ;
+                b := (xpart b + HSize + 2 * boxdistance,ypart b) ;
+            fi ;
+            lw := boxlinewidth ;
+            draw
+                if boxalternative = 2 :
+                    anch_sidebars_pattern(a, b,
+                        ((0,0)--(0.25,-0.5)--(0.75,0.5)--(1,0)) scaled lw,
+                        2lw, 2lw, lw
+                    )
+                elseif boxalternative = 3 :
+                    anch_sidebars_pattern(a, b,
+                        ((0,0)--(0.25,-0.5)--(0.75,0.5)--(1,0)) scaled lw,
+                        4lw, 1.5lw, lw
+                    )
+                elseif boxalternative = 4 :
+                    anch_sidebars_pattern(a, b,
+                        (((0,0) .. controls (0,0.5) and (0.5,0.5) .. (0.5,0)) -- ((0.5,0) .. controls (0.5,-0.5) and (1,-0.5) .. (1,0))) scaled lw,
+                        6lw, 4lw, lw
+                    )
+                elseif boxalternative = 5 :
+                    anch_sidebars_pattern(a, b,
+                        ((0,0) .. controls (0,1) and (1,1) .. (1,0)) scaled lw,
+                        4lw, 2lw, lw
+                    )
+                elseif boxalternative = 6 :
+                    anch_sidebars_pattern(a, b,
+                        ((0,0.5) .. (1,-0.5)) scaled lw,
+                        4lw, 2lw, lw
+                    )
+                elseif boxalternative = 7 :
+                    anch_sidebars_pattern(a, b,
+                        ((0,-0.5) .. (1,0.5)) scaled lw,
+                        22lw, 5lw, lw
+                    )
+                else :
+                    (a -- b)
+                        if boxalternative = 1 :
+                            dashed (withdots scaled (lw/2))
+                        fi
+                        withpen pencircle scaled lw
+                fi
+                withcolor boxlinecolor ;
+        fi ;
     endgroup ;
 enddef ;
 
@@ -110,3 +176,139 @@
 
 def getposboxes (expr tags, anchor) = runscript mfid_getposboxes  tags anchor ; enddef ;
 def getmultipars(expr tags, anchor) = runscript mfid_getmultipars tags anchor ; enddef ;
+
+newscriptindex mfid_getpospage      ; mfid_getpospage      := scriptindex "getpospage"      ; vardef getpospage     (expr n) = runscript mfid_getpospage      n enddef ;
+newscriptindex mfid_getposparagraph ; mfid_getposparagraph := scriptindex "getposparagraph" ; vardef getposparagraph(expr n) = runscript mfid_getposparagraph n enddef ;
+newscriptindex mfid_getposcolumn    ; mfid_getposcolumn    := scriptindex "getposcolumn"    ; vardef getposcolumn   (expr n) = runscript mfid_getposcolumn    n enddef ;
+newscriptindex mfid_getposregion    ; mfid_getposregion    := scriptindex "getposregion"    ; vardef getposregion   (expr n) = runscript mfid_getposregion    n enddef ;
+
+newscriptindex mfid_getposx ; mfid_getposx := scriptindex "getposx" ; vardef getposx(expr n) = runscript mfid_getposx n enddef ;
+newscriptindex mfid_getposy ; mfid_getposy := scriptindex "getposy" ; vardef getposy(expr n) = runscript mfid_getposy n enddef ;
+
+newscriptindex mfid_getposwidth  ; mfid_getposwidth  := scriptindex "getposwidth"  ; vardef getposwidth (expr n) = runscript mfid_getposwidth  n enddef ;
+newscriptindex mfid_getposheight ; mfid_getposheight := scriptindex "getposheight" ; vardef getposheight(expr n) = runscript mfid_getposheight n enddef ;
+newscriptindex mfid_getposdepth  ; mfid_getposdepth  := scriptindex "getposdepth"  ; vardef getposdepth (expr n) = runscript mfid_getposdepth  n enddef ;
+
+newscriptindex mfid_getposleftskip   ; mfid_getposleftskip   := scriptindex "getposleftskip"   ; vardef getposleftskip  (expr n) = runscript mfid_getposleftskip   n enddef ;
+newscriptindex mfid_getposrightskip  ; mfid_getposrightskip  := scriptindex "getposrightskip"  ; vardef getposrightskip (expr n) = runscript mfid_getposrightskip  n enddef ;
+newscriptindex mfid_getposhsize      ; mfid_getposhsize      := scriptindex "getposhsize"      ; vardef getposhsize     (expr n) = runscript mfid_getposhsize      n enddef ;
+newscriptindex mfid_getposparindent  ; mfid_getposparindent  := scriptindex "getposparindent"  ; vardef getposparindent (expr n) = runscript mfid_getposparindent  n enddef ;
+newscriptindex mfid_getposhangindent ; mfid_getposhangindent := scriptindex "getposhangindent" ; vardef getposhangindent(expr n) = runscript mfid_getposhangindent n enddef ;
+newscriptindex mfid_getposhangafter  ; mfid_getposhangafter  := scriptindex "getposhangafter"  ; vardef getposhangafter (expr n) = runscript mfid_getposhangafter  n enddef ;
+
+newscriptindex mfid_getposxy         ; mfid_getposxy         := scriptindex "getposxy"         ; vardef getposxy        (expr n) = runscript mfid_getposxy         n enddef ;
+newscriptindex mfid_getposupperleft  ; mfid_getposupperleft  := scriptindex "getposupperleft"  ; vardef getposupperleft (expr n) = runscript mfid_getposupperleft  n enddef ;
+newscriptindex mfid_getposlowerleft  ; mfid_getposlowerleft  := scriptindex "getposlowerleft"  ; vardef getposlowerleft (expr n) = runscript mfid_getposlowerleft  n enddef ;
+newscriptindex mfid_getposupperright ; mfid_getposupperright := scriptindex "getposupperright" ; vardef getposupperright(expr n) = runscript mfid_getposupperright n enddef ;
+newscriptindex mfid_getposlowerright ; mfid_getposlowerright := scriptindex "getposlowerright" ; vardef getposlowerright(expr n) = runscript mfid_getposlowerright n enddef ;
+
+newscriptindex mfid_getposllx ; mfid_getposllx := scriptindex "getposllx" ; vardef getposllx(expr n) = runscript mfid_getposllx n enddef ;
+newscriptindex mfid_getposlly ; mfid_getposlly := scriptindex "getposlly" ; vardef getposlly(expr n) = runscript mfid_getposlly n enddef ;
+newscriptindex mfid_getposurx ; mfid_getposurx := scriptindex "getposurx" ; vardef getposurx(expr n) = runscript mfid_getposurx n enddef ;
+newscriptindex mfid_getposury ; mfid_getposury := scriptindex "getposury" ; vardef getposury(expr n) = runscript mfid_getposury n enddef ;
+
+permanent
+    getposboxes, getmultipars,
+    getpospage, getposparagraph, getposcolumn, getposregion,
+    getposx, getposy, getposwidth, getposheight, getposdepth,
+    getposleftskip, getposrightskip, getposhsize, getposparindent, getposhangindent, getposhangafter,
+    getposxy, getposupperleft, getposlowerleft, getposupperright, getposlowerright,
+    getposllx, getposlly, getposurx, getposury ;
+
+def anch_box_arrows_draw =
+    begingroup ;
+        save f, t, p, alternative, delta, dashtype, edge, arrow, ff, tt, spanpages, spanfirst, spanlast, skip ;
+        pair f, t, ff, tt ; path p ; string alternative, arrow ; boolean spanpages, spanfirst, spanlast, skip ;
+        dashtype := mpvarn("dashtype") ;
+        delta := mpvard("distance");
+        alternative := mpvars("alternative") ;
+        arrow := mpvars("arrow") ;
+        spanpages := false ;
+        spanfirst := true ;
+        spanlast := true ;
+        skip := false ;
+        if positionx(mpvars("rightedge")) > 0 :
+            if alternative = "left" :
+                edge := positionx(mpvars("leftedge"));
+                f := (edge,positiony(mpvars("from"))) ;
+                t := (edge,positiony(mpvars("to"  ))) ;
+                p := (f  -- (f xshifted - delta) -- (t xshifted - delta) --  t) ;
+                draw thetextext.lft(mpvars("text"), (point .5 along p) xshifted -ExHeight) ;
+            elseif alternative = "right" :
+                edge := positionx(mpvars("rightedge"));
+                f := (edge,positiony(mpvars("from"))) ;
+                t := (edge,positiony(mpvars("to"  ))) ;
+                p := (f  -- (f xshifted delta) -- (t xshifted delta) --  t) ;
+                draw thetextext.rt(mpvars("text"), (point .5 along p) xshifted ExHeight) ;
+            elseif alternative = "middle" :
+                p := f  --  t ;
+                draw thetextext.rt(mpvars("text"), (point .5 along p) xshifted ExHeight) ;
+            fi ;
+        else :
+            f := positionxy(mpvars("from")) ;
+            t := positionxy(mpvars("to")) ;
+            spanpages := getpospage(mpvars("to")) > getpospage(mpvars("from")) ;
+            if spanpages :
+                if getpospage(mpvars("from")) = RealPageNumber :
+                    t := (getposwidth(getposregion(mpvars("from"))),ypart f) ;
+                    spanlast := false ;
+                elseif getpospage(mpvars("to")) = RealPageNumber :
+                    f := (getposx(getposregion(mpvars("to"))),ypart t) ;
+                    spanfirst := false ;
+                fi ;
+            fi
+% drawdot f withpen pencircle scaled 2pt;
+% drawdot t withpen pencircle scaled 2pt;
+            %
+            skip := (not spanpages) and ((mpvars("span")) = "yes") ;
+            if skip :
+                % we skip the second just in case
+            elseif alternative = "" :
+                message("invalid alternative in draw box arrow");
+                skip := true;
+            elseif alternative = "bottom" :
+                ff := (xpart f, min(ypart f, ypart t)) ;
+                tt := (xpart t, ypart ff) ;
+                p := (if spanfirst: f -- fi (ff yshifted -delta) -- (tt yshifted -delta) if spanlast : --  t fi) ;
+                draw thetextext.bot(mpvars("text"), (point .5 along p) yshifted -.25ExHeight) ;
+            elseif alternative = "top" :
+                ff := (xpart f, max(ypart f, ypart t)) ;
+                tt := (xpart t, ypart ff) ;
+                p := (if spanfirst: f -- fi (ff yshifted delta) -- (tt yshifted delta) if spanlast : --  t fi) ;
+                draw thetextext.top(mpvars("text"), (point .5 along p) yshifted .25ExHeight) ;
+            elseif alternative = "left" :
+                ff := (min(xpart f, xpart t), ypart f) ;
+                tt := (xpart ff, ypart t) ;
+                p := (f  -- (ff xshifted - delta) -- (tt xshifted - delta) --  t) ;
+                draw thetextext.lft(mpvars("text"), (point .5 along p) xshifted -ExHeight) ;
+            elseif alternative = "right" :
+                ff := (max(xpart f, xpart t), ypart f) ;
+                tt := (xpart ff, ypart t) ;
+                p := (f  -- (ff xshifted delta) -- (tt xshifted delta) --  t) ;
+                draw thetextext.rt(mpvars("text"), (point .5 along p) xshifted ExHeight) ;
+            elseif alternative = "middle" :
+                p := f  --  t ;
+                draw thetextext.rt(mpvars("text"), (point .5 along p) xshifted ExHeight) ;
+            fi ;
+        fi ;
+        if not skip :
+            % 1 = dashed, 2 = dashed with background
+            if arrow ="no" :
+                draw
+            elseif arrow == "reverse" :
+                drawarrow reverse
+            elseif arrow == "both" :
+                drawdblarrow
+            else :
+                drawarrow
+            fi
+                p
+                if dashtype == 1 :
+                    withdashes .5ExHeight
+                fi
+                withpen pencircle scaled mpvard("rulethickness")
+                withcolor mpvars("linecolor") ;
+            positioninregion ;
+        fi ;
+    endgroup ;
+enddef ;

Added: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-asnc.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-asnc.mpxl	                        (rev 0)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-asnc.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -0,0 +1,133 @@
+%D \module
+%D   [       file=mp-asnc.mpiv,
+%D        version=2012.02.19, % was mp-core: 1999.08.01, anchoring
+%D          title=\CONTEXT\ \METAPOST\ graphics,
+%D       subtitle=anchored background macros,
+%D         author=Hans Hagen,
+%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 mreadme.pdf for
+%C details.
+
+%D See anch-snc.mkxl for historic comments.
+
+if known context_asnc : endinput ; fi ;
+
+boolean context_asnc ; context_asnc := true ;
+
+newscriptindex mfid_asnc_collect   ; mfid_asnc_collect   := scriptindex "asnc_collect"  ; def asnc_collect (expr category,realpage,region) = runscript mfid_asnc_collect (category) (realpage) (region)  enddef ;
+
+newscriptindex mfid_asnc_extend    ; mfid_asnc_extend    := scriptindex "asnc_extend"   ; def asnc_extend    = runscript mfid_asnc_extend    enddef ;
+newscriptindex mfid_asnc_prune     ; mfid_asnc_prune     := scriptindex "asnc_prune"    ; def asnc_prune     = runscript mfid_asnc_prune     enddef ;
+newscriptindex mfid_asnc_collapse  ; mfid_asnc_collapse  := scriptindex "asnc_collapse" ; def asnc_collapse  = runscript mfid_asnc_collapse  enddef ;
+newscriptindex mfid_asnc_getsize   ; mfid_asnc_getsize   := scriptindex "asnc_getsize"  ; def asnc_getsize   = runscript mfid_asnc_getsize   enddef ;
+newscriptindex mfid_asnc_getx      ; mfid_asnc_getx      := scriptindex "asnc_getx"     ; def asnc_getx      = runscript mfid_asnc_getx      enddef ;
+newscriptindex mfid_asnc_gety      ; mfid_asnc_gety      := scriptindex "asnc_gety"     ; def asnc_gety      = runscript mfid_asnc_gety      enddef ;
+newscriptindex mfid_asnc_getw      ; mfid_asnc_getw      := scriptindex "asnc_getw"     ; def asnc_getw      = runscript mfid_asnc_getw      enddef ;
+newscriptindex mfid_asnc_geth      ; mfid_asnc_geth      := scriptindex "asnc_geth"     ; def asnc_geth      = runscript mfid_asnc_geth      enddef ;
+newscriptindex mfid_asnc_getd      ; mfid_asnc_getd      := scriptindex "asnc_getd"     ; def asnc_getd      = runscript mfid_asnc_getd      enddef ;
+
+newscriptindex mfid_asnc_gettop    ; mfid_asnc_gettop    := scriptindex "asnc_gettop"   ; def asnc_gettop   (expr n) = (runscript mfid_asnc_gettop    n) enddef ;
+newscriptindex mfid_asnc_getbottom ; mfid_asnc_getbottom := scriptindex "asnc_getbottom"; def asnc_getbottom(expr n) = (runscript mfid_asnc_getbottom n) enddef ;
+newscriptindex mfid_asnc_getkind   ; mfid_asnc_getkind   := scriptindex "asnc_getkind"  ; def asnc_getkind  (expr n) = (runscript mfid_asnc_getkind   n) enddef ;
+newscriptindex mfid_asnc_gettask   ; mfid_asnc_gettask   := scriptindex "asnc_gettask"  ; def asnc_gettask  (expr n) = (runscript mfid_asnc_gettask   n) enddef ;
+
+presetparameters "synchronizer" [
+    color    = "darkgray", % default color
+    colors   = {
+        "darkred"
+        "darkgreen"
+        "darkblue",
+        "darkyellow",
+        "darkmagenta",
+        "darkcyan",
+        "darkgray"
+    },
+    index    = 1,
+    hoffset  = 0,
+    voffset  = 0,
+    region   = "",
+    width    = 1cm,
+    extend   = false,
+    prune    = true,
+    collapse = true,
+    draw     = true,
+    fill     = true,
+    page     = "auto", % yes | clip | auto | no
+] ;
+
+def lmt_synchronizer = applyparameters "synchronizer" "lmt_do_synchronizer" enddef ;
+
+% boxdx boxdy ...
+
+vardef lmt_do_synchronizer =
+    pushparameters "synchronizer" ;
+        begingroup ;
+        save index, dx, dy, width, count, page, region, paths, tasks, kinds ;
+        path paths[] ; numeric tasks[] ; numeric kinds[] ;
+        %
+        numeric index  ; index  := getparameter "index" ;
+        numeric dx     ; dx     := getparameter "hoffset" ;
+        numeric dy     ; dy     := getparameter "voffset" ;
+        numeric width  ; width  := getparameter "width" ;
+        numeric count  ; count  := 0 ;
+        string page    ; page   := getparameter "page" ;
+        string region  ; region := getparameter "region" ;
+        %
+        count := asnc_collect(index,RealPageNumber,region) ;
+        if getparameter "extend" :
+            count := asnc_extend ; % to top of text area
+        fi ;
+        if getparameter "prune" :
+            count := asnc_prune ; % clip top / bottom
+        fi ;
+        if getparameter "collapse" :
+            count := asnc_collapse ;
+        fi ;
+        if count > 0 :
+            save k, t, b, l, r, y ;
+            numeric l ; l := dx ;
+            numeric r ; r := dx + width ;
+            numeric y ; y := asnc_gety + dy ;
+            for i=1 upto count :
+                k := asnc_getkind(i) ;
+                t := asnc_gettop(i) - y ;
+                b := asnc_getbottom(i) - y ;
+                paths[i] = ((l,t) -- (r,t) -- (r,b) -- (l,b) -- cycle) ;
+                tasks[i] = asnc_gettask(i) ;
+                kinds[i] = k ;
+            endfor ;
+            if page = "auto" :
+                page := if region == "" : "clip" else : "no" fi ;
+            fi ;
+            if (page = "clip") or (page = "yes") :
+                StartPage ;
+            fi ;
+            if getparameter "fill" :
+                for i=1 upto count :
+                    fill paths[i]
+                        withcolor getparameterdefault "colors" i (getparameter "color") ;
+                    ;
+                endfor ;
+            fi ;
+            if getparameter "draw" :
+                for i=1 upto count :
+                    draw paths[i]
+                        withcolor getparameterdefault "colors" i (getparameter "color") ;
+                    ;
+                endfor ;
+            fi ;
+            if page = "clip" :
+                clip currentpicture to Page ;
+                setbounds currentpicture to Page ;
+            fi ;
+            if (page = "clip") or (page = "yes") :
+                StopPage ;
+            fi ;
+        fi ;
+        endgroup ;
+    popparameters ;
+enddef ;
+

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-base.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-base.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-base.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -61,45 +61,43 @@
 
 % These need to be adapted to a library approach:
 
-warningcheck     := 1 ;
+warningcheck := 1 ;
 
 def interact = % sets up to make "show" commands stop
     hide (
-        showstopping  := 1 ;
-        tracingonline := 1 ;
+        interim showstopping  := 1 ;
+        interim tracingonline := 1 ;
     )
 enddef ;
 
 def loggingall = % puts tracing info into the log
-    tracingcommands  := 3 ;
-    tracingtitles    := 1 ;
-    tracingequations := 1 ;
-    tracingcapsules  := 1 ;
-    tracingspecs     := 2 ;
-    tracingchoices   := 1 ;
-    tracingstats     := 1 ;
-    tracingoutput    := 1 ;
-    tracingmacros    := 1 ;
-    tracingrestores  := 1 ;
+    interim tracingtitles    := 1 ;
+    interim tracingequations := 1 ;
+    interim tracingcapsules  := 1 ;
+    interim tracingspecs     := 2 ;
+    interim tracingchoices   := 1 ;
+    interim tracingstats     := 1 ;
+    interim tracingmacros    := 1 ;
+    interim tracingcommands  := 3 ;
+    interim tracingrestores  := 1 ;
 enddef ;
 
 def tracingall = % turns on every form of tracing
-    tracingonline := 1 ;
-    showstopping  := 1 ;
+    interim tracingonline := 1 ;
+    interim showstopping  := 1 ;
     loggingall ;
 enddef ;
 
 def tracingnone = % turns off every form of tracing
-    tracingcommands  := 0 ;
-    tracingtitles    := 0 ;
-    tracingequations := 0 ;
-    tracingcapsules  := 0 ;
-    tracingspecs     := 0 ;
-    tracingchoices   := 0 ;
-    tracingstats     := 0 ;
-    tracingoutput    := 0 ;
-    tracingmacros    := 0 ;
-    tracingrestores  := 0 ;
+    interim tracingrestores  := 0 ;
+    interim tracingcommands  := 0 ;
+    interim tracingtitles    := 0 ;
+    interim tracingequations := 0 ;
+    interim tracingcapsules  := 0 ;
+    interim tracingspecs     := 0 ;
+    interim tracingchoices   := 0 ;
+    interim tracingstats     := 0 ;
+    interim tracingmacros    := 0 ;
 enddef ;
 
 permanent interact, loggingall, tracingall, tracingnone ;
@@ -208,20 +206,26 @@
 
 % color part (will be overloaded)
 
+newinternal nocolormodel   ; nocolormodel   := 0 ;
+newinternal greycolormodel ; greycolormodel := 1 ;
+newinternal graycolormodel ; graycolormodel := 1 ;
+newinternal rgbcolormodel  ; rgbcolormodel  := 2 ;
+newinternal cmykcolormodel ; cmykcolormodel := 3 ;
+
 def colorpart primary t =
-    if colormodel t = 7:
+    if colormodel t = cmykcolormodel:
         (cyanpart t, magentapart t, yellowpart t, blackpart t)
-    elseif colormodel t = 5 :
+    elseif colormodel t = rgbcolormodel :
         (redpart t, greenpart t, bluepart t)
-    elseif colormodel t = 3 :
+    elseif colormodel t = graycolormodel :
         (greypart t)
-    elseif colormodel t = 1 :
+    elseif colormodel t = nocolormodel :
         false
-    elseif defaultcolormodel = 7 :
+    elseif defaultcolormodel = cmykcolormodel :
         (0,0,0,1)
-    elseif defaultcolormodel = 5 :
+    elseif defaultcolormodel = rgbcolormodel :
         black
-    elseif defaultcolormodel = 3 :
+    elseif defaultcolormodel = graycolormodel :
         0
     else :
         false
@@ -284,7 +288,8 @@
             round(point i of u) ..
             controls round(postcontrol i of u) and round(precontrol i+1 of u) ..
         endfor
-        if cycle u : cycle else : point infinity of u fi
+%         if cycle u : cycle else : point infinity of u fi
+        if cycle u : cycle else : nocycle fi
     else :
         u
     fi
@@ -431,9 +436,9 @@
 path        temp_path_a, temp_path_b ;
 pair        temp_pair_dz, temp_pair_z[] ;
 
-vardef direction expr t of p =
-    postcontrol t of p - precontrol t of p
-enddef ;
+% vardef direction expr t of p =
+%     postcontrol t of p - precontrol t of p
+% enddef ;
 
 vardef directionpoint expr z of p =
     temp_internal_a := directiontime z of p ;
@@ -475,7 +480,8 @@
     endgroup
 enddef ;
 
-permanent direction, directionpoint, intersectionpoint, softjoin ;
+% permanent direction, directionpoint, intersectionpoint, softjoin ;
+permanent directionpoint, intersectionpoint, softjoin ;
 
 newinternal join_radius ;
 path cuttings ; % what got cut off
@@ -495,7 +501,7 @@
 enddef ;
 
 tertiarydef a cutafter b =
-    reverse (reverse a  cutbefore  b)
+    reverse (reverse a cutbefore  b) % inefficient, a and b are copied
     hide(cuttings := reverse cuttings)
 enddef ;
 
@@ -635,12 +641,13 @@
 
 mm :=  2.83464 ;
 pt :=  0.99626 ;
-dd :=  1.06601 ;
+dd :=  1.06601 ; % 1.0660068107174
 bp :=  1 ;
 cm := 28.34645 ;
 pc := 11.95517 ;
 cc := 12.79213 ;
 in := 72 ;
+dk :=  6.41577 ; % 6.4157650704225 ;
 
 immutable mm, pt, bp, cm, in ; % we don't protect (yet): dd, pc cc (used as locals)
 
@@ -803,7 +810,8 @@
 enddef ;
 
 vardef savepen =
-    temp_pen_stack[incr temp_pen_count] = currentpen ;
+    temp_pen_count := temp_pen_count + 1 ;
+    temp_pen_stack[temp_pen_count] = currentpen ;
     temp_pen_l[temp_pen_count] = pen_lft ;
     temp_pen_r[temp_pen_count] = pen_rt ;
     temp_pen_t[temp_pen_count] = pen_top ;
@@ -989,7 +997,9 @@
 extra_beginfig := "" ;
 extra_endfig   := "" ;
 
-def beginfig(expr c) =
+newinternal boolean makingfigure ; makingfigure := false ;
+
+def beginfig(expr c) = % redefined in mp-grph !
     begingroup
     charcode := c ;
     clearxy ;
@@ -997,6 +1007,8 @@
     clearpen ;
     pickup defaultpen ;
     drawoptions() ;
+    interim stacking := 0 ;
+    interim makingfigure := true;
     scantokens extra_beginfig ;
 enddef ;
 

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-cont.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-cont.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-cont.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -29,47 +29,49 @@
 
 extra_beginfig := extra_beginfig & "mfun_swapped := false ;" ;
 
-newscriptindex mfid_PaperHeight          ; mfid_PaperHeight          := scriptindex "PaperHeight"          ; vardef PaperHeight          = runscript mfid_PaperHeight          enddef ;
-newscriptindex mfid_PaperWidth           ; mfid_PaperWidth           := scriptindex "PaperWidth"           ; vardef PaperWidth           = runscript mfid_PaperWidth           enddef ;
-newscriptindex mfid_PrintPaperHeight     ; mfid_PrintPaperHeight     := scriptindex "PrintPaperHeight"     ; vardef PrintPaperHeight     = runscript mfid_PrintPaperHeight     enddef ;
-newscriptindex mfid_PrintPaperWidth      ; mfid_PrintPaperWidth      := scriptindex "PrintPaperWidth"      ; vardef PrintPaperWidth      = runscript mfid_PrintPaperWidth      enddef ;
-newscriptindex mfid_TopSpace             ; mfid_TopSpace             := scriptindex "TopSpace"             ; vardef TopSpace             = runscript mfid_TopSpace             enddef ;
-newscriptindex mfid_BottomSpace          ; mfid_BottomSpace          := scriptindex "BottomSpace"          ; vardef BottomSpace          = runscript mfid_BottomSpace          enddef ;
-newscriptindex mfid_BackSpace            ; mfid_BackSpace            := scriptindex "BackSpace"            ; vardef BackSpace            = runscript mfid_BackSpace            enddef ;
-newscriptindex mfid_CutSpace             ; mfid_CutSpace             := scriptindex "CutSpace"             ; vardef CutSpace             = runscript mfid_CutSpace             enddef ;
-newscriptindex mfid_MakeupHeight         ; mfid_MakeupHeight         := scriptindex "MakeupHeight"         ; vardef MakeupHeight         = runscript mfid_MakeupHeight         enddef ;
-newscriptindex mfid_MakeupWidth          ; mfid_MakeupWidth          := scriptindex "MakeupWidth"          ; vardef MakeupWidth          = runscript mfid_MakeupWidth          enddef ;
-newscriptindex mfid_TopHeight            ; mfid_TopHeight            := scriptindex "TopHeight"            ; vardef TopHeight            = runscript mfid_TopHeight            enddef ;
-newscriptindex mfid_TopDistance          ; mfid_TopDistance          := scriptindex "TopDistance"          ; vardef TopDistance          = runscript mfid_TopDistance          enddef ;
-newscriptindex mfid_HeaderHeight         ; mfid_HeaderHeight         := scriptindex "HeaderHeight"         ; vardef HeaderHeight         = runscript mfid_HeaderHeight         enddef ;
-newscriptindex mfid_HeaderDistance       ; mfid_HeaderDistance       := scriptindex "HeaderDistance"       ; vardef HeaderDistance       = runscript mfid_HeaderDistance       enddef ;
-newscriptindex mfid_TextHeight           ; mfid_TextHeight           := scriptindex "TextHeight"           ; vardef TextHeight           = runscript mfid_TextHeight           enddef ;
-newscriptindex mfid_FooterDistance       ; mfid_FooterDistance       := scriptindex "FooterDistance"       ; vardef FooterDistance       = runscript mfid_FooterDistance       enddef ;
-newscriptindex mfid_FooterHeight         ; mfid_FooterHeight         := scriptindex "FooterHeight"         ; vardef FooterHeight         = runscript mfid_FooterHeight         enddef ;
-newscriptindex mfid_BottomDistance       ; mfid_BottomDistance       := scriptindex "BottomDistance"       ; vardef BottomDistance       = runscript mfid_BottomDistance       enddef ;
-newscriptindex mfid_BottomHeight         ; mfid_BottomHeight         := scriptindex "BottomHeight"         ; vardef BottomHeight         = runscript mfid_BottomHeight         enddef ;
-newscriptindex mfid_LeftEdgeWidth        ; mfid_LeftEdgeWidth        := scriptindex "LeftEdgeWidth"        ; vardef LeftEdgeWidth        = runscript mfid_LeftEdgeWidth        enddef ;
-newscriptindex mfid_LeftEdgeDistance     ; mfid_LeftEdgeDistance     := scriptindex "LeftEdgeDistance"     ; vardef LeftEdgeDistance     = runscript mfid_LeftEdgeDistance     enddef ;
-newscriptindex mfid_LeftMarginWidth      ; mfid_LeftMarginWidth      := scriptindex "LeftMarginWidth"      ; vardef LeftMarginWidth      = runscript mfid_LeftMarginWidth      enddef ;
-newscriptindex mfid_LeftMarginDistance   ; mfid_LeftMarginDistance   := scriptindex "LeftMarginDistance"   ; vardef LeftMarginDistance   = runscript mfid_LeftMarginDistance   enddef ;
-newscriptindex mfid_TextWidth            ; mfid_TextWidth            := scriptindex "TextWidth"            ; vardef TextWidth            = runscript mfid_TextWidth            enddef ;
-newscriptindex mfid_RightMarginDistance  ; mfid_RightMarginDistance  := scriptindex "RightMarginDistance"  ; vardef RightMarginDistance  = runscript mfid_RightMarginDistance  enddef ;
-newscriptindex mfid_RightMarginWidth     ; mfid_RightMarginWidth     := scriptindex "RightMarginWidth"     ; vardef RightMarginWidth     = runscript mfid_RightMarginWidth     enddef ;
-newscriptindex mfid_RightEdgeDistance    ; mfid_RightEdgeDistance    := scriptindex "RightEdgeDistance"    ; vardef RightEdgeDistance    = runscript mfid_RightEdgeDistance    enddef ;
-newscriptindex mfid_RightEdgeWidth       ; mfid_RightEdgeWidth       := scriptindex "RightEdgeWidth"       ; vardef RightEdgeWidth       = runscript mfid_RightEdgeWidth       enddef ;
-newscriptindex mfid_InnerMarginDistance  ; mfid_InnerMarginDistance  := scriptindex "InnerMarginDistance"  ; vardef InnerMarginDistance  = runscript mfid_InnerMarginDistance  enddef ;
-newscriptindex mfid_InnerMarginWidth     ; mfid_InnerMarginWidth     := scriptindex "InnerMarginWidth"     ; vardef InnerMarginWidth     = runscript mfid_InnerMarginWidth     enddef ;
-newscriptindex mfid_OuterMarginDistance  ; mfid_OuterMarginDistance  := scriptindex "OuterMarginDistance"  ; vardef OuterMarginDistance  = runscript mfid_OuterMarginDistance  enddef ;
-newscriptindex mfid_OuterMarginWidth     ; mfid_OuterMarginWidth     := scriptindex "OuterMarginWidth"     ; vardef OuterMarginWidth     = runscript mfid_OuterMarginWidth     enddef ;
-newscriptindex mfid_InnerEdgeDistance    ; mfid_InnerEdgeDistance    := scriptindex "InnerEdgeDistance"    ; vardef InnerEdgeDistance    = runscript mfid_InnerEdgeDistance    enddef ;
-newscriptindex mfid_InnerEdgeWidth       ; mfid_InnerEdgeWidth       := scriptindex "InnerEdgeWidth"       ; vardef InnerEdgeWidth       = runscript mfid_InnerEdgeWidth       enddef ;
-newscriptindex mfid_OuterEdgeDistance    ; mfid_OuterEdgeDistance    := scriptindex "OuterEdgeDistance"    ; vardef OuterEdgeDistance    = runscript mfid_OuterEdgeDistance    enddef ;
-newscriptindex mfid_OuterEdgeWidth       ; mfid_OuterEdgeWidth       := scriptindex "OuterEdgeWidth"       ; vardef OuterEdgeWidth       = runscript mfid_OuterEdgeWidth       enddef ;
-newscriptindex mfid_PageOffset           ; mfid_PageOffset           := scriptindex "PageOffset"           ; vardef PageOffset           = runscript mfid_PageOffset           enddef ;
-newscriptindex mfid_PageDepth            ; mfid_PageDepth            := scriptindex "PageDepth"            ; vardef PageDepth            = runscript mfid_PageDepth            enddef ;
-newscriptindex mfid_LayoutColumns        ; mfid_LayoutColumns        := scriptindex "LayoutColumns"        ; vardef LayoutColumns        = runscript mfid_LayoutColumns        enddef ;
-newscriptindex mfid_LayoutColumnDistance ; mfid_LayoutColumnDistance := scriptindex "LayoutColumnDistance" ; vardef LayoutColumnDistance = runscript mfid_LayoutColumnDistance enddef ;
-newscriptindex mfid_LayoutColumnWidth    ; mfid_LayoutColumnWidth    := scriptindex "LayoutColumnWidth"    ; vardef LayoutColumnWidth    = runscript mfid_LayoutColumnWidth    enddef ;
+newscriptindex mfid_PaperHeight           ; mfid_PaperHeight           := scriptindex "PaperHeight"           ; vardef PaperHeight           = runscript mfid_PaperHeight           enddef ;
+newscriptindex mfid_PaperWidth            ; mfid_PaperWidth            := scriptindex "PaperWidth"            ; vardef PaperWidth            = runscript mfid_PaperWidth            enddef ;
+newscriptindex mfid_PrintPaperHeight      ; mfid_PrintPaperHeight      := scriptindex "PrintPaperHeight"      ; vardef PrintPaperHeight      = runscript mfid_PrintPaperHeight      enddef ;
+newscriptindex mfid_PrintPaperWidth       ; mfid_PrintPaperWidth       := scriptindex "PrintPaperWidth"       ; vardef PrintPaperWidth       = runscript mfid_PrintPaperWidth       enddef ;
+newscriptindex mfid_TopSpace              ; mfid_TopSpace              := scriptindex "TopSpace"              ; vardef TopSpace              = runscript mfid_TopSpace              enddef ;
+newscriptindex mfid_BottomSpace           ; mfid_BottomSpace           := scriptindex "BottomSpace"           ; vardef BottomSpace           = runscript mfid_BottomSpace           enddef ;
+newscriptindex mfid_BackSpace             ; mfid_BackSpace             := scriptindex "BackSpace"             ; vardef BackSpace             = runscript mfid_BackSpace             enddef ;
+newscriptindex mfid_CutSpace              ; mfid_CutSpace              := scriptindex "CutSpace"              ; vardef CutSpace              = runscript mfid_CutSpace              enddef ;
+newscriptindex mfid_MakeupHeight          ; mfid_MakeupHeight          := scriptindex "MakeupHeight"          ; vardef MakeupHeight          = runscript mfid_MakeupHeight          enddef ;
+newscriptindex mfid_MakeupWidth           ; mfid_MakeupWidth           := scriptindex "MakeupWidth"           ; vardef MakeupWidth           = runscript mfid_MakeupWidth           enddef ;
+newscriptindex mfid_TopHeight             ; mfid_TopHeight             := scriptindex "TopHeight"             ; vardef TopHeight             = runscript mfid_TopHeight             enddef ;
+newscriptindex mfid_TopDistance           ; mfid_TopDistance           := scriptindex "TopDistance"           ; vardef TopDistance           = runscript mfid_TopDistance           enddef ;
+newscriptindex mfid_HeaderHeight          ; mfid_HeaderHeight          := scriptindex "HeaderHeight"          ; vardef HeaderHeight          = runscript mfid_HeaderHeight          enddef ;
+newscriptindex mfid_HeaderDistance        ; mfid_HeaderDistance        := scriptindex "HeaderDistance"        ; vardef HeaderDistance        = runscript mfid_HeaderDistance        enddef ;
+newscriptindex mfid_TextHeight            ; mfid_TextHeight            := scriptindex "TextHeight"            ; vardef TextHeight            = runscript mfid_TextHeight            enddef ;
+newscriptindex mfid_FooterDistance        ; mfid_FooterDistance        := scriptindex "FooterDistance"        ; vardef FooterDistance        = runscript mfid_FooterDistance        enddef ;
+newscriptindex mfid_FooterHeight          ; mfid_FooterHeight          := scriptindex "FooterHeight"          ; vardef FooterHeight          = runscript mfid_FooterHeight          enddef ;
+newscriptindex mfid_BottomDistance        ; mfid_BottomDistance        := scriptindex "BottomDistance"        ; vardef BottomDistance        = runscript mfid_BottomDistance        enddef ;
+newscriptindex mfid_BottomHeight          ; mfid_BottomHeight          := scriptindex "BottomHeight"          ; vardef BottomHeight          = runscript mfid_BottomHeight          enddef ;
+newscriptindex mfid_LeftEdgeWidth         ; mfid_LeftEdgeWidth         := scriptindex "LeftEdgeWidth"         ; vardef LeftEdgeWidth         = runscript mfid_LeftEdgeWidth         enddef ;
+newscriptindex mfid_LeftEdgeDistance      ; mfid_LeftEdgeDistance      := scriptindex "LeftEdgeDistance"      ; vardef LeftEdgeDistance      = runscript mfid_LeftEdgeDistance      enddef ;
+newscriptindex mfid_LeftMarginWidth       ; mfid_LeftMarginWidth       := scriptindex "LeftMarginWidth"       ; vardef LeftMarginWidth       = runscript mfid_LeftMarginWidth       enddef ;
+newscriptindex mfid_LeftMarginDistance    ; mfid_LeftMarginDistance    := scriptindex "LeftMarginDistance"    ; vardef LeftMarginDistance    = runscript mfid_LeftMarginDistance    enddef ;
+newscriptindex mfid_TextWidth             ; mfid_TextWidth             := scriptindex "TextWidth"             ; vardef TextWidth             = runscript mfid_TextWidth             enddef ;
+newscriptindex mfid_RightMarginDistance   ; mfid_RightMarginDistance   := scriptindex "RightMarginDistance"   ; vardef RightMarginDistance   = runscript mfid_RightMarginDistance   enddef ;
+newscriptindex mfid_RightMarginWidth      ; mfid_RightMarginWidth      := scriptindex "RightMarginWidth"      ; vardef RightMarginWidth      = runscript mfid_RightMarginWidth      enddef ;
+newscriptindex mfid_RightEdgeDistance     ; mfid_RightEdgeDistance     := scriptindex "RightEdgeDistance"     ; vardef RightEdgeDistance     = runscript mfid_RightEdgeDistance     enddef ;
+newscriptindex mfid_RightEdgeWidth        ; mfid_RightEdgeWidth        := scriptindex "RightEdgeWidth"        ; vardef RightEdgeWidth        = runscript mfid_RightEdgeWidth        enddef ;
+newscriptindex mfid_InnerMarginDistance   ; mfid_InnerMarginDistance   := scriptindex "InnerMarginDistance"   ; vardef InnerMarginDistance   = runscript mfid_InnerMarginDistance   enddef ;
+newscriptindex mfid_InnerMarginWidth      ; mfid_InnerMarginWidth      := scriptindex "InnerMarginWidth"      ; vardef InnerMarginWidth      = runscript mfid_InnerMarginWidth      enddef ;
+newscriptindex mfid_OuterMarginDistance   ; mfid_OuterMarginDistance   := scriptindex "OuterMarginDistance"   ; vardef OuterMarginDistance   = runscript mfid_OuterMarginDistance   enddef ;
+newscriptindex mfid_OuterMarginWidth      ; mfid_OuterMarginWidth      := scriptindex "OuterMarginWidth"      ; vardef OuterMarginWidth      = runscript mfid_OuterMarginWidth      enddef ;
+newscriptindex mfid_InnerEdgeDistance     ; mfid_InnerEdgeDistance     := scriptindex "InnerEdgeDistance"     ; vardef InnerEdgeDistance     = runscript mfid_InnerEdgeDistance     enddef ;
+newscriptindex mfid_InnerEdgeWidth        ; mfid_InnerEdgeWidth        := scriptindex "InnerEdgeWidth"        ; vardef InnerEdgeWidth        = runscript mfid_InnerEdgeWidth        enddef ;
+newscriptindex mfid_OuterEdgeDistance     ; mfid_OuterEdgeDistance     := scriptindex "OuterEdgeDistance"     ; vardef OuterEdgeDistance     = runscript mfid_OuterEdgeDistance     enddef ;
+newscriptindex mfid_OuterEdgeWidth        ; mfid_OuterEdgeWidth        := scriptindex "OuterEdgeWidth"        ; vardef OuterEdgeWidth        = runscript mfid_OuterEdgeWidth        enddef ;
+newscriptindex mfid_PageOffset            ; mfid_PageOffset            := scriptindex "PageOffset"            ; vardef PageOffset            = runscript mfid_PageOffset            enddef ;
+newscriptindex mfid_PageDepth             ; mfid_PageDepth             := scriptindex "PageDepth"             ; vardef PageDepth             = runscript mfid_PageDepth             enddef ;
+newscriptindex mfid_LayoutColumns         ; mfid_LayoutColumns         := scriptindex "LayoutColumns"         ; vardef LayoutColumns         = runscript mfid_LayoutColumns         enddef ;
+newscriptindex mfid_LayoutColumnDistance  ; mfid_LayoutColumnDistance  := scriptindex "LayoutColumnDistance"  ; vardef LayoutColumnDistance  = runscript mfid_LayoutColumnDistance  enddef ;
+newscriptindex mfid_LayoutColumnWidth     ; mfid_LayoutColumnWidth     := scriptindex "LayoutColumnWidth"     ; vardef LayoutColumnWidth     = runscript mfid_LayoutColumnWidth     enddef ;
+newscriptindex mfid_LastChangedLayoutPage ; mfid_LastChangedLayoutPage := scriptindex "LastChangedLayoutPage" ; vardef LastChangedLayoutPage = runscript mfid_LastChangedLayoutPage enddef ;
+newscriptindex mfid_SwapMarginDimensions  ; mfid_SwapMarginDimensions  := scriptindex "SwapMarginDimensions"  ; vardef SwapMarginDimensions  = runscript mfid_SwapMarginDimensions  enddef ;
 
 immutable % permanent
     PaperHeight, PaperWidth, PrintPaperHeight, PrintPaperWidth, TopSpace,
@@ -80,7 +82,8 @@
     RightMarginWidth, RightEdgeDistance, RightEdgeWidth, InnerMarginDistance,
     InnerMarginWidth, OuterMarginDistance, OuterMarginWidth, InnerEdgeDistance,
     InnerEdgeWidth, OuterEdgeDistance, OuterEdgeWidth, PageOffset, PageDepth,
-    LayoutColumns, LayoutColumnDistance, LayoutColumnWidth ;
+    LayoutColumns, LayoutColumnDistance, LayoutColumnWidth,
+    LastChangedLayoutPage, SwapMarginDimensions ;
 
 newscriptindex mfid_OnRightPage      ; mfid_OnRightPage      := scriptindex "OnRightPage"      ; vardef OnRightPage      = runscript mfid_OnRightPage      enddef ;
 newscriptindex mfid_OnOddPage        ; mfid_OnOddPage        := scriptindex "OnOddPage"        ; vardef OnOddPage        = runscript mfid_OnOddPage        enddef ;
@@ -134,9 +137,9 @@
 immutable % permanent
     PageFraction, SpineWidth, PaperBleed ;
 
-%              mfid_CurrentLayout    ; mfid_CurrentLayout    := scriptindex "CurrentLayout"    ; vardef CurrentLayout    = runscript mfid_CurrentLayout        enddef ;
-%              mfid_OverlayLineColor ; mfid_OverlayLineColor := scriptindex "OverlayLineColor  ; vardef OverlayLineColor = runscript mfid_OverlayLineColor     enddef ;
-%              mfid_OverlayColor     ; mfid_OverlayColor     := scriptindex "OverlayColor      ; vardef OverlayColor     = runscript mfid_OverlayColor         enddef ;
+newscriptindex mfid_CurrentLayout    ; mfid_CurrentLayout    := scriptindex "CurrentLayout"    ; vardef CurrentLayout    = runscript mfid_CurrentLayout        enddef ;
+newscriptindex mfid_OverlayLineColor ; mfid_OverlayLineColor := scriptindex "OverlayLineColor" ; vardef OverlayLineColor = runscript mfid_OverlayLineColor     enddef ;
+newscriptindex mfid_OverlayColor     ; mfid_OverlayColor     := scriptindex "OverlayColor"     ; vardef OverlayColor     = runscript mfid_OverlayColor         enddef ;
 newscriptindex mfid_OverlayWidth     ; mfid_OverlayWidth     := scriptindex "OverlayWidth"     ; vardef OverlayWidth     = runscript mfid_OverlayWidth         enddef ;
 newscriptindex mfid_OverlayHeight    ; mfid_OverlayHeight    := scriptindex "OverlayHeight"    ; vardef OverlayHeight    = runscript mfid_OverlayHeight        enddef ;
 newscriptindex mfid_OverlayDepth     ; mfid_OverlayDepth     := scriptindex "OverlayDepth"     ; vardef OverlayDepth     = runscript mfid_OverlayDepth         enddef ;
@@ -145,7 +148,7 @@
 newscriptindex mfid_OverlayRegion    ; mfid_OverlayRegion    := scriptindex "OverlayRegion"    ; vardef OverlayRegion    = runscript mfid_OverlayRegion        enddef ;
 
 immutable % permanent
-  %  CurrentLayout, OverlayLineColor, OverlayColor,
+    CurrentLayout, OverlayLineColor, OverlayColor,
     OverlayWidth, OverlayHeight, OverlayDepth, OverlayLineWidth, OverlayOffset, OverlayRegion ;
 
 newscriptindex mfid_defaultcolormodel    ; mfid_defaultcolormodel    := scriptindex "defaultcolormodel"    ; vardef defaultcolormodel = runscript mfid_defaultcolormodel enddef ;
@@ -153,18 +156,18 @@
 immutable % permanent
     defaultcolormodel ;
 
-vardef LeftMarginWidth     = if mfun_swapped and not OnRightPage : runscript mfid_RightMarginWidth    else : runscript mfid_LeftMarginWidth     fi enddef ;
-vardef RightMarginWidth    = if mfun_swapped and not OnRightPage : runscript mfid_LeftMarginWidth     else : runscript mfid_RightMarginWidth    fi enddef ;
-vardef LeftMarginDistance  = if mfun_swapped and not OnRightPage : runscript mfid_RightMarginDistance else : runscript mfid_LeftMarginDistance  fi enddef ;
-vardef RightMarginDistance = if mfun_swapped and not OnRightPage : runscript mfid_LeftMarginDistance  else : runscript mfid_RightMarginDistance fi enddef ;
+vardef LeftMarginWidth     = runscript mfid_LeftMarginWidth     enddef ;
+vardef RightMarginWidth    = runscript mfid_RightMarginWidth    enddef ;
+vardef LeftMarginDistance  = runscript mfid_LeftMarginDistance  enddef ;
+vardef RightMarginDistance = runscript mfid_RightMarginDistance enddef ;
 
-vardef LeftEdgeWidth       = if mfun_swapped and not OnRightPage : runscript mfid_RightEdgeWidth      else : runscript mfid_LeftEdgeWidth       fi enddef ;
-vardef RightEdgeWidth      = if mfun_swapped and not OnRightPage : runscript mfid_LeftEdgeWidth       else : runscript mfid_RightEdgeWidth      fi enddef ;
-vardef LeftEdgeDistance    = if mfun_swapped and not OnRightPage : runscript mfid_RightEdgeDistance   else : runscript mfid_LeftEdgeDistance    fi enddef ;
-vardef RightEdgeDistance   = if mfun_swapped and not OnRightPage : runscript mfid_LeftEdgeDistance    else : runscript mfid_RightEdgeDistance   fi enddef ;
+vardef LeftEdgeWidth       = runscript mfid_LeftEdgeWidth       enddef ;
+vardef RightEdgeWidth      = runscript mfid_RightEdgeWidth      enddef ;
+vardef LeftEdgeDistance    = runscript mfid_LeftEdgeDistance    enddef ;
+vardef RightEdgeDistance   = runscript mfid_RightEdgeDistance   enddef ;
 
-vardef BackSpace           = if mfun_swapped and not OnRightPage : PaperWidth - MakeupWidth - fi runscript mfid_BackSpace enddef ;
-vardef CutSpace            = if mfun_swapped and not OnRightPage : PaperWidth - MakeupWidth - fi runscript mfid_CutSpace  enddef ;
+vardef BackSpace           = runscript mfid_BackSpace           enddef ;
+vardef CutSpace            = runscript mfid_CutSpace            enddef ;
 
 % better use:
 
@@ -196,3 +199,69 @@
     InnerMarginDistance, OuterEdgeWidth, InnerEdgeWidth, OuterEdgeDistance,
     InnerEdgeDistance, OuterSpaceWidth, InnerSpaceWidth, OuterMargin, InnerMargin,
     OuterEdge, InnerEdge ;
+
+% see node-rul.*
+
+% for the moment we put these here:
+
+% string  RuleDirection ; RuleDirection := "" ;
+% string  RuleOption    ; RuleOption    := "" ;
+% numeric RuleWidth     ; RuleWidth     := 0 ;
+% numeric RuleHeight    ; RuleHeight    := 0 ;
+% numeric RuleDepth     ; RuleDepth     := 0 ;
+% numeric RuleH         ; RuleH         := 0 ;
+% numeric RuleV         ; RuleV         := 0 ;
+% numeric RuleThickness ; RuleThickness := 0 ;
+% numeric RuleFactor    ; RuleFactor    := 0 ;
+% numeric RuleOffset    ; RuleOffset    := 0 ;
+%                     def RuleColor      = (.5white) enddef ; % yet undecided, might become a string
+
+newscriptindex mfid_RuleWidth     ; mfid_RuleWidth     := scriptindex "RuleWidth"     ; vardef RuleWidth     = runscript mfid_RuleWidth     enddef ;
+newscriptindex mfid_RuleHeight    ; mfid_RuleHeight    := scriptindex "RuleHeight"    ; vardef RuleHeight    = runscript mfid_RuleHeight    enddef ;
+newscriptindex mfid_RuleDepth     ; mfid_RuleDepth     := scriptindex "RuleDepth"     ; vardef RuleDepth     = runscript mfid_RuleDepth     enddef ;
+newscriptindex mfid_RuleH         ; mfid_RuleH         := scriptindex "RuleH"         ; vardef RuleH         = runscript mfid_RuleH         enddef ;
+newscriptindex mfid_RuleV         ; mfid_RuleV         := scriptindex "RuleV"         ; vardef RuleV         = runscript mfid_RuleV         enddef ;
+newscriptindex mfid_RuleThickness ; mfid_RuleThickness := scriptindex "RuleThickness" ; vardef RuleThickness = runscript mfid_RuleThickness enddef ;
+newscriptindex mfid_RuleOffset    ; mfid_RuleOffset    := scriptindex "RuleOffset"    ; vardef RuleOffset    = runscript mfid_RuleOffset    enddef ;
+newscriptindex mfid_RuleDirection ; mfid_RuleDirection := scriptindex "RuleDirection" ; vardef RuleDirection = runscript mfid_RuleDirection enddef ;
+newscriptindex mfid_RuleFactor    ; mfid_RuleFactor    := scriptindex "RuleFactor"    ; vardef RuleFactor    = runscript mfid_RuleFactor    enddef ;
+newscriptindex mfid_RuleOption    ; mfid_RuleOption    := scriptindex "RuleOption"    ; vardef RuleOption    = runscript mfid_RuleOption    enddef ;
+newscriptindex mfid_RuleColor     ; mfid_RuleColor     := scriptindex "RuleColor"     ;    def RuleColor     = runscript (mfid_RuleColor)   enddef ;
+
+immutable % permanent
+    RuleWidth, RuleHeight, RuleDepth, RuleH, RuleV, RuleThickness, RuleOffset,
+    RuleDirection, RuleFactor, RuleOption, RuleColor ;
+
+def FakeWord(expr RuleWidth, RuleHeight, RuleDepth, RuleThickness) (text RuleColor) =
+    fill unitsquare
+        xscaled RuleWidth
+        yscaled (RuleDepth-RuleThickness/2)
+        withcolor RuleColor ;
+    fill unitsquare
+        xscaled RuleWidth
+        yscaled (RuleHeight-RuleDepth-RuleThickness/2)
+        shifted (0,RuleDepth+RuleThickness)
+        withcolor RuleColor ;
+enddef ;
+
+def FakeRule(expr RuleWidth, RuleHeight, RuleDepth, RuleThickness) (text RuleColor) =
+    fill unitsquare
+        xscaled RuleWidth
+        yscaled RuleHeight
+        withcolor RuleColor ;
+enddef ;
+
+permanent
+    FakeWord, FakeRule ;
+
+% see typo-ada.*
+
+newscriptindex mfid_AdaptiveWidth     ; mfid_AdaptiveWidth     := scriptindex "AdaptiveWidth"     ; vardef AdaptiveWidth     = runscript mfid_AdaptiveWidth     enddef ;
+newscriptindex mfid_AdaptiveHeight    ; mfid_AdaptiveHeight    := scriptindex "AdaptiveHeight"    ; vardef AdaptiveHeight    = runscript mfid_AdaptiveHeight    enddef ;
+newscriptindex mfid_AdaptiveDepth     ; mfid_AdaptiveDepth     := scriptindex "AdaptiveDepth"     ; vardef AdaptiveDepth     = runscript mfid_AdaptiveDepth     enddef ;
+newscriptindex mfid_AdaptiveTotal     ; mfid_AdaptiveTotal     := scriptindex "AdaptiveDepth"     ; vardef AdaptiveTotal     = runscript mfid_AdaptiveTotal     enddef ;
+newscriptindex mfid_AdaptiveThickness ; mfid_AdaptiveThickness := scriptindex "AdaptiveThickness" ; vardef AdaptiveThickness = runscript mfid_AdaptiveThickness enddef ;
+newscriptindex mfid_AdaptiveColor     ; mfid_AdaptiveColor     := scriptindex "AdaptiveColor"     ; vardef AdaptiveColor     = runscript mfid_AdaptiveColor     enddef ;
+
+immutable % permanent
+    AdaptiveWidth, AdaptiveHeight, AdaptiveDepth, AdaptiveThickness, AdaptiveColor ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-grph.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-grph.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-grph.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -47,10 +47,10 @@
     interim linecap := linecap ;
     interim linejoin := linejoin ;
     interim miterlimit := miterlimit ;
-    % not really needed:
+    interim stacking := 0 ;
+    interim makingfigure := true;
     save temp_b ; color temp_b ; temp_b := background ;
     save background ; color background ; background := temp_b ;
-    %
     drawoptions () ;
 enddef ;
 

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-lmtx.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-lmtx.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-lmtx.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -1,5 +1,5 @@
 %D \module
-%D   [       file=mp-luas.lmtx,
+%D   [       file=mp-lmtx.lmtx,
 %D        version=2019.06.23,
 %D          title=\CONTEXT\ \METAPOST\ graphics,
 %D       subtitle=\LUA,
@@ -237,7 +237,9 @@
                                             if d < left : rotated 180 shifted (0,-5) else : shifted (0,5) fi
                                             ysized ts
                                             shifted a
-                                            rotatedaround(a,angle(d)) ;
+                                            if d <> origin :
+                                                rotatedaround(a,angle(d))
+                                            fi ;
                                     endfor ;
                                 fi ;
                             popparameters ;
@@ -282,6 +284,8 @@
             kind := "r" ;
         elseif kind = "fillup" :
             kind := "u" ;
+        elseif kind = "path" :
+            kind := "p" ;
         fi ;
         currentoutlinetext := currentoutlinetext + 1 ;
         lua.mp.mf_outline_text(
@@ -363,7 +367,7 @@
         interim tracingfollowtext := if getparameter "trace" : 1 else : 0 fi ;
         draw followtext (
             if (getparameter "reverse") : reverse fi (getparameter "path"),
-                getparameter "text"
+            (getparameter "text")
         ) ;
         popparameters ;
     )
@@ -599,6 +603,8 @@
     xarrow      = "",
     yarrow      = "",
     reverse     = false,
+  % function    : metatable is parent
+    axis        = "both",
 ] ;
 
 def lmt_function = applyparameters "function" "lmt_do_function" enddef ;
@@ -610,8 +616,7 @@
         q := (xmin,0) -- p -- (xmax,0) -- cycle ;
         fill q withcolor fcolor ;
     else :
-        draw p withpen currentpen scaled dsize withcolor dcolor
-            ;
+        draw p withpen currentpen scaled dsize withcolor dcolor ;
     fi ;
     if psize > 0 :
         if psymbol = "dot" :
@@ -638,9 +643,9 @@
         pickup pencircle xyscaled(lw/sx,lw/sy) ;
         draw image (
             save xmin, xmax, xstep, xsmall, xlarge, ymin, ymax, ystep, ysmall, ylarge, p ;
-            save code, option, txl, txs, tyl, tys, swap ;
-            string code, option ;
-            path txl, txs, tyl, tys ; boolean swap ;
+            save code, option, txl, txs, tyl, tys, swap, axis ;
+            string code, option, shape, axis ;
+            path txl, txs, tyl, tys ; boolean swap, close ;
             picture p ;
 
             xmin    := getparameter "xmin" ;
@@ -655,36 +660,38 @@
             ylarge  := getparameter "ylarge" ;
             code    := getparameter "code" ;
             swap    := getparameter "reverse" ;
-
+            shape   := getparameter "shape" ;
+            close   := getparameter "close" ;
+            axis    := getparameter "axis" ;
             p := image (
-
                 if (getparametercount "functions") > 0 :
                     for s = 1 upto getparametercount "functions" :
-                        pushparameters "functions" s ;
+                        % todo: pushparameters with a metatable, here parent
+                        pushparameters "functions" [s] ;
                         lmt_do_function_p (
-                            getparameterdefault "xmin",
-                            getparameterdefault "xmax",
-                            getparameterdefault "xstep",
-                            getparameterdefault "code",
-                            getparameterdefault "shape",
-                            getparameterdefault "close",
-                            getparameterdefault "fillcolor",
-                            getparameterdefault "drawsize",
-                            getparameterdefault "drawcolor",
-                            getparameterdefault "pointsymbol",
-                            getparameterdefault "pointsize",
-                            getparameterdefault "pointcolor"
+                            (getparameterdefault "xmin"        xmin),
+                            (getparameterdefault "xmax"        xmax),
+                            (getparameterdefault "xstep"       xstep),
+                            (getparameterdefault "code"        code),
+                            (getparameterdefault "shape"       shape),
+                            (getparameterdefault "close"       close),
+                            (getparameterdefault "fillcolor"   (getparameter "fillcolor")),
+                            (getparameterdefault "drawsize"    (getparameter "drawsize")),
+                            (getparameterdefault "drawcolor"   (getparameter "drawcolor")),
+                            (getparameterdefault "pointsymbol" (getparameter "pointsymbol")),
+                            (getparameterdefault "pointsize"   (getparameter "pointsize")),
+                            (getparameterdefault "pointcolor"  (getparameter "pointcolor"))
                         ) ;
                         popparameters ;
                     endfor ;
                 elseif code <> "" :
                     lmt_do_function_p (
-                        getparameter "xmin",
-                        getparameter "xmax",
-                        getparameter "xstep",
-                        getparameter "code",
-                        getparameter "shape",
-                        getparameter "close",
+                        xmin,
+                        xmax,
+                        xstep,
+                        code,
+                        shape,
+                        close,
                         getparameter "fillcolor",
                         getparameter "drawsize",
                         getparameter "drawcolor",
@@ -697,6 +704,12 @@
 
             if not swap : draw p fi ;
 
+if (axis = "") or (axis = "no") :
+    % nothing
+else :
+
+    % todo: x y both
+
             option := getparameter "xticks" ;
             if option = "top" :
                 txs := (0,0) -- (0,tl) ;
@@ -884,6 +897,8 @@
                     shifted (xmin-tl,0)
                     shifted center leftboundary currentpicture ;
             fi ;
+
+fi ;
         )
 
         xyscaled(sx,sy) ;
@@ -1001,6 +1016,9 @@
     originsize      = 1mm,
     trace           = false,
     showlabels      = true,
+    showlegend      = true,
+    showvalues      = false,
+    showaxis        = false,
     center          = false,
 
     samples         = { },
@@ -1009,6 +1027,7 @@
     percentage      = false,
     maximum         = 0,
     distance        = 1mm,
+    threshold       = eps,
 
   % labels          = { },
     labelstyle      = "",
@@ -1019,6 +1038,16 @@
     labelfraction   = 0.8,
     labelcolor      = "",
 
+    axisstyle       = "",
+    axiscolor       = "",
+    axisformat      = "",
+    axislinewidth   = mm/5,
+    axislinecolor   = "",
+
+    valuestyle      = "",
+    valuecolor      = "",
+    valueformat     = "",
+
     backgroundcolor = "",
     drawcolor       = "white",
     fillcolors      = { % use color palet
@@ -1026,9 +1055,11 @@
         "darkyellow", "darkmagenta", "darkcyan",
         "darkgray"
     },
+    linecolors      = { },
     colormode       = "global",
 
     linewidth       = .25mm,
+  % linegap         = 0,
 
     legendcolor     = "",
     legendstyle     = "",
@@ -1036,11 +1067,13 @@
 ] ;
 
 presetparameters "chart:circle" "chart" [
-    height      = 5cm,
-    width       = 5mm,
-    labelanchor = "",
-    labeloffset = 0,
-    labelstrut  = "no",
+    height       = 5cm,
+    width        = 5mm,
+    innerradius  = 0,
+    initialangle = 0, % -90 == top
+    labelanchor  = "",
+    labeloffset  = 0,
+    labelstrut   = "no",
 ] ;
 
 presetparameters "chart:histogram" "chart" [
@@ -1065,24 +1098,59 @@
 
 def lmt_do_chart_start (expr what) =
     pushparameters what ;
-    save width, height, distance, linewidth, labelgap, labelfraction, value, nofsamples, nofsamplesets ;
-    save fillcolor, drawcolor, labelcolor, labelstyle, labelformat, labelstrut, labelanchor, colormode ;
-    string fillcolor, drawcolor, labelcolor, labelstyle, labelformat, labelstrut, labelanchor, colormode ;
-    height := getparameter "height" ;
-    width := getparameter "width" ;
-    distance := getparameter "distance" ;
-    linewidth := getparameter "linewidth" ;
-    drawcolor := getparameter "drawcolor" ;
-    colormode :=  getparameter "colormode" ;
-    labelcolor := getparameter "labelcolor" ;
-    labelgap := getparameter "labeloffset" ;
-    labelstyle := getparameter "labelstyle" ;
-    labelformat := getparameter "labelformat" ;
-    labelstrut := getparameter "labelstrut" ;
-    labelanchor := getparameter "labelanchor" ;
+    save width, height, depth, distance,
+        threshold,
+        linewidth, linegap,
+        value, nofsamples, nofsamplesets,
+        fillcolor, linecolor, drawcolor,
+        labelcolor, labelstyle, labelformat, labelgap, labelfraction, labelstrut, labelanchor,
+        axiscolor, axisstyle, axisformat, axisgap, axislinewidth, axislinecolor,
+        valuecolor, valuestyle, valueformat, valuegap,
+        colormode ;
+    string fillcolor, linecolor, drawcolor,
+        labelcolor, labelstyle, labelformat, labelstrut, labelanchor,
+        axiscolor, axisstyle, axisformat, axislinecolor,
+        valuecolor, valuestyle, valueformat,
+        colormode ;
+    if hasparameter "sampleset" :
+        setluaparameter what "samples" (getparameter "sampleset") ;
+    fi ;
+
+    threshold     := getparameter "threshold" ;
+    colormode     := getparameter "colormode" ;
+
+    linewidth     := getparameter "linewidth" ;
+    linegap       := getparameterdefault "linegap" linewidth ;
+
+    height        := getparameter "height" ;
+    depth         := max(getparameter "originsize", (getparameter "innerradius"), 8*linewidth) ;
+    width         := getparameter "width" ;
+    distance      := getparameter "distance" ;
+
+    drawcolor     := getparameter "drawcolor" ;
+
+    labelcolor    := getparameter "labelcolor" ;
+    labelstyle    := getparameter "labelstyle" ;
+    labelformat   := getparameter "labelformat" ;
+    labelgap      := getparameter "labeloffset" ;
+    labelstrut    := getparameter "labelstrut" ;
+    labelanchor   := getparameter "labelanchor" ;
     labelfraction := getparameter "labelfraction" ;
+
+    axiscolor     := getparameter "axiscolor" ;
+    axisstyle     := getparameter "axisstyle" ;
+    axisformat    := getparameter "axisformat" ;
+    axisgap       := getparameter "axisoffset" ;
+    axislinewidth := getparameter "axislinewidth" ;
+    axislinecolor := getparameter "axislinecolor" ;
+
+    valuecolor    := getparameter "valuecolor" ;
+    valuestyle    := getparameter "valuestyle" ;
+    valueformat   := getparameter "valueformat" ;
+    valuegap      := getparameter "valueoffset" ;
+
     nofsamplesets := getparametercount "samples" ;
-    nofsamples := getmaxparametercount "samples" ;
+    nofsamples    := getmaxparametercount "samples" ;
 enddef ;
 
 def lmt_do_chart_stop =
@@ -1119,84 +1187,137 @@
 enddef ;
 
 def lmt_do_chart_legend =
-    n := getparametercount "legend" ;
-    if n > 0 :
-        save dx, dy, p, l, w, o, d, ddy ; picture l ;
-        dx := xpart urcorner currentpicture + EmWidth ;
-        dy := ypart urcorner currentpicture ;
-        labelcolor := getparameter "legendcolor" ;
-        labelstyle := getparameter "legendstyle" ;
-        w := 2EmWidth ;
-        o := .25EmWidth ;
-        d := ExHeight ;
-        ddy := .8LineHeight ;
-        for i=1 upto n :
-            dy := dy - ddy ;
-            l := lmt_text [
-                text       = getparameter "legend" i,
-                anchor     = "rt"
-                style      = labelstyle,
-                color      = labelcolor,
-                background = "",
-            ] ;
-            fill leftboundary l rightenlarged w
-                shifted (dx,dy+d)
-                withcolor getparameter "fillcolors" i ;
-            draw l
-                shifted (dx+w+o,dy+d) ;
-        endfor ;
+    if getparameter "showlegend" :
+        n := getparametercount "legend" ;
+        if n > 0 :
+            save dx, dy, p, l, w, o, d, ddy ; picture l ;
+            dx := xpart urcorner currentpicture + EmWidth ;
+            dy := ypart urcorner currentpicture ;
+            labelcolor := getparameter "legendcolor" ;
+            labelstyle := getparameter "legendstyle" ;
+            w := 2EmWidth ;
+            o := .25EmWidth ;
+            d := ExHeight ;
+            ddy := .8LineHeight ;
+            for i=1 upto n :
+                dy := dy - ddy ;
+                l := lmt_text [
+                    text       = getparameter "legend" i,
+                    anchor     = "rt"
+                    style      = labelstyle,
+                    color      = labelcolor,
+                    background = "",
+                ] ;
+                fill leftboundary l rightenlarged w
+                    shifted (dx,dy+d)
+                    withcolor getparameter "fillcolors" i ;
+                draw l
+                    shifted (dx+w+o,dy+d) ;
+            endfor ;
+        fi ;
     fi ;
 enddef ;
 
+% draw lmt_chart_circle [
+%     height       = 4cm,
+%     innerradius  = 2.0cm,
+%     samples      = { { 10, 20, 30, 40, 50 } },
+%     percentage   = false,
+%     initialangle = 90,
+%     linewidth    = .125mm,
+%     originsize   = 0,
+%     showlabels   = false,
+%     drawcolor    = "white",
+%     fillcolors   = { "red",     "green",  "blue",     "",       "cyan" },
+%     linecolors   = { "magenta", "orange", "darkgray", "orange", "darkgray" }
+%     linecolors   = { "",        "orange", "",         "orange", "" }
+% ] ;
+
 vardef lmt_do_chart_circle =
     image (
         lmt_do_chart_start("chart:circle") ;
         if (nofsamplesets > 0) and (nofsamples > 0) :
             nofsamplesets := 1 ;
-            save p, r, s, first, last, total, factor, n, percentage ;
-            path p, r, s[] ; boolean percentage ;
+            save p, q, r, s, t, pl, ql, first, last, total, factor, n, percentage, initial, clockwise ;
+            path p, q, r, s[], t[] ; boolean percentage, clockwise ;
+            save value, v;
+            clockwise := true ;
             percentage := getparameter "percentage" ;
+            initial := if not clockwise : - fi getparameter "initialangle" ; % watch sign
             total := 0 ;
             for i = 1 upto nofsamples :
-                total := total + getparameter "samples" (1) i ; % () is needed else 1i
+                value := getparameter "samples" (1) i ;
+                if value > threshold :
+                    total := total + value ;
+                fi ;
             endfor ;
-            factor := 100/total ;
-            first := 0 ;
-            p := fullcircle ysized (height) ;
-            r := origin -- (2*height,0) ;
-            for i = 1 upto nofsamples :
-                fillcolor := getparameter "fillcolors" i ;
-                value := (getparameter "samples" (1) i) * factor ;
-                last := first + (360 / 100) * value ;
-                s[i] := ((p cutbefore (r rotated first)) cutafter (r rotated last)) ;
-                fill origin -- s[i] -- cycle withcolor fillcolor ;
-                first := last ;
-            endfor ;
-            if linewidth > 0 :
-                if drawcolor = "" :
-                    drawcolor := backgroundcolor ;
+            if total = 0 :
+                message("zero total in circular chart");
+            else :
+                factor := 100/total ;
+                first := initial ;
+                if clockwise :
+                    p := (reverse fullcircle rotated first) ysized (height) ;
+                    q := (reverse fullcircle rotated first) ysized (depth) ;
+                else :
+                    p := fullcircle ysized (height) ;
+                    q := fullcircle ysized (depth) ;
                 fi ;
+                r := origin -- (2*height,0) ;
+                pl := ((linewidth + linegap) / (arclength p)) * 360;
+                ql := ((linewidth + linegap) / (arclength q)) * 360;
+                v := 0 ;
                 for i = 1 upto nofsamples :
-                    interim linecap := butt ;
-                    draw origin -- (point 0            of s[i]) withpen pencircle scaled linewidth withcolor drawcolor ;
-                    draw origin -- (point length(s[i]) of s[i]) withpen pencircle scaled linewidth withcolor drawcolor ;
-                endfor ;
-            fi ;
-            if getparameter "showlabels" :
-                first := 0 ;
-                for i = 1 upto nofsamples :
                     value := getparameter "samples" (1) i ;
-                    last := first + (360/100) * value * factor ;
-                    draw lmt_do_chart_text (s,i,value)
-                        shifted ((labelfraction*(height/2),0) rotated ((first+last)/2)) ;
-                    first := last ;
+                    if value > threshold :
+                        v := v + 1 ;
+                        fillcolor := getparameter "fillcolors" i ;
+                        linecolor := getparameterdefault "linecolors" i "" ;
+                        if linecolor = "" :
+                            linecolor := fillcolor ;
+                        fi ;
+                        value := value * factor ;
+                        last := first if clockwise : - else : + fi (360/100) * value ;
+                        s[v] :=         ((p cutbefore (r rotated first)) cutafter (r rotated (last + pl))) ;
+                        t[v] := reverse ((q cutbefore (r rotated first)) cutafter (r rotated (last + ql))) ;
+                        path piece ; piece := s[v] -- t[v] -- cycle ;
+                        if fillcolor <> "" :
+                            fill piece
+                                withpen pencircle scaled linewidth
+                                withcolor fillcolor
+                            ;
+                        fi ;
+                        if linecolor <> "" :
+                            if linewidth > 0 :
+                                interim linecap := butt ;
+                                draw piece
+                                    withpen pencircle scaled linewidth
+                                    withcolor if linecolor <> "" : linecolor else drawcolor : fi
+                                ;
+                            fi ;
+                        fi ;
+                        first := last ;
+                    fi ;
                 endfor ;
+                if linewidth > 0 :
+                    clip currentpicture to p enlarged linewidth ;
+                fi ;
+                if getparameter "showlabels" :
+                    first := initial ;
+                    v := 0 ;
+                    for i = 1 upto nofsamples :
+                        value := getparameter "samples" (1) i ;
+                        if value > threshold :
+                            v := v + 1 ;
+                            last := first if clockwise : - else : + fi (360/100) * value * factor ;
+                            draw lmt_do_chart_text (s,i,value)
+                                shifted ((labelfraction*(height/2),0) rotated ((first+last)/2)) ;
+                            first := last ;
+                        fi
+                    endfor ;
+                fi ;
+                lmt_do_chart_legend ;
             fi ;
-            lmt_do_chart_legend ;
-            n := getparameter "originsize" ;
-            if n > 0 :
-                fill fullcircle scaled n withcolor "white"  ;
-            fi ;
         fi ;
         lmt_do_chart_stop ;
     )
@@ -1242,14 +1363,14 @@
                 endfor ;
             endfor ;
             setbounds currentpicture to unitsquare xyscaled (maxwidth,height) ;
-            for s = 1 upto nofsamplesets :
-                if getparameter "showlabels" :
+            if getparameter "showlabels" :
+                for s = 1 upto nofsamplesets :
                     for i = 1 upto nofsamples :
                         draw lmt_do_chart_text (s,i,getparameter "samples" s i)
                             shifted (nofsamplesets*((i-1)*width)+width/2+(s-1)*width+(i-1)*distance,0) ;
                     endfor ;
-                fi ;
-            endfor ;
+                endfor ;
+            fi ;
             lmt_do_chart_legend ;
         fi ;
         lmt_do_chart_stop ;
@@ -2108,7 +2229,7 @@
         w := getparameter "width" ;
         h := getparameter "height" ;
         o := getparameter "offset" ;
-        lua.mp.lmt_svg_include() ;
+        lua.mp.lmt_svg_include() ; % textext runs twice .. maybe force once here
         if getparameter "origin" :
             currentpicture := currentpicture shifted -llcorner currentpicture ;
         fi ;
@@ -2264,8 +2385,10 @@
 
 % Again an experiment (todo: the faster method):
 
-newscriptindex mfid_remaptext ; mfid_remaptext := scriptindex "remaptext" ; def lmt_remaptext = runscript mfid_remaptext enddef ;
+% watch the ; that we scan!
 
+newscriptindex mfid_remaptext ; mfid_remaptext := scriptindex "remaptext" ; def lmt_remaptext = runscript mfid_remaptext ; enddef ;
+
 triplet mfun_tt_s ;
 
 vardef rawmaptext(expr s) =
@@ -2339,13 +2462,13 @@
 
 % nice hack
 
-newscriptindex mfid_scrutenized ; mfid_scrutenized := scriptindex "scrutenized" ;
+newscriptindex mfid_scrutinized ; mfid_scrutinized := scriptindex "scrutinized" ;
 
-primarydef p scrutenized n =
-    runscript mfid_scrutenized p n
+primarydef p scrutinized n =
+    runscript mfid_scrutinized p n
 enddef ;
 
-permanent scrutenized ;
+permanent scrutinized ;
 
 % for now here
 
@@ -2359,12 +2482,20 @@
 %
 % permanent mpv_numeric, mpv_dimension, mpv_string ;
 
-newscriptindex mfid_mpvar ; mfid_mpvar := scriptindex "mpvar" ;
+% newscriptindex mfid_mpvar ; mfid_mpvar := scriptindex "mpvar" ;
+%
+% def mpvar = runscript mfid_mpvar enddef ;
 
-def mpvar = runscript mfid_mpvar enddef ;
+% d(imension) n(umber) s(tring) b(oolean) <heuristic>
 
-permanent mpvar ;
+newscriptindex mfid_mpvard ; mfid_mpvard := scriptindex "mpvard" ; def mpvard = runscript mfid_mpvard enddef ; % dimension
+newscriptindex mfid_mpvarn ; mfid_mpvarn := scriptindex "mpvarn" ; def mpvarn = runscript mfid_mpvarn enddef ; % numeric
+newscriptindex mfid_mpvars ; mfid_mpvars := scriptindex "mpvars" ; def mpvars = runscript mfid_mpvars enddef ; % string
+newscriptindex mfid_mpvarb ; mfid_mpvarb := scriptindex "mpvarb" ; def mpvarb = runscript mfid_mpvarb enddef ; % string
+newscriptindex mfid_mpvar  ; mfid_mpvar  := scriptindex "mpvar"  ; def mpvar  = runscript mfid_mpvar  enddef ; % automatic
 
+permanent mpvard, mpvarn, mpvars, mpvarb, mpvar ;
+
 % for old times sake (metafun manual)
 
 vardef textual primary p = false enddef ;
@@ -2401,3 +2532,200 @@
         popparameters ;
     )
 enddef ;
+
+% For now we collect all lmt namespace extensions here, so also this one:
+
+presetparameters "matrix" [
+  % cell    = (1, 1),
+  % from    = (1, 1),
+  % to      = (1, 1),
+  % shape   = { "circle", "square" },
+    connect = { "center", "center" },
+  % text    = "",
+] ;
+
+def lmt_matrix = applyparameters "matrix" "lmt_do_matrix" enddef ;
+
+vardef mfun_lmt_matrix_cell (expr p) =
+  % anchorbox ("matrix", xpart p, ypart p) ("matrix", xpart p + 1, ypart p)
+    matrixcell (xpart p, ypart p)
+enddef ;
+
+% todo: lft rt etc but then we need to push/pop the linewidth too
+
+def mfun_lmt_matrix_connect (expr h, p, r, l, u, d, gap) =
+    if     h == "right"  : center rightboundary   (p enlarged gap) { r }
+    elseif h == "left"   : center leftboundary    (p enlarged gap) { l }
+    elseif h == "top"    : center topboundary     (p enlarged gap) { u }
+    elseif h == "bottom" : center bottomboundary  (p enlarged gap) { d }
+    else                 : center                 (p enlarged gap)
+    fi
+enddef ;
+
+def mfun_lmt_matrix_source (expr p, h, gap) =
+    mfun_lmt_matrix_connect(h, p, right, left, up, down, gap)
+enddef ;
+
+def mfun_lmt_matrix_target (expr p, h, gap) =
+    mfun_lmt_matrix_connect(h, p, left, right, down, up, gap)
+enddef ;
+
+vardef mfun_lmt_matrix_enhance (expr p, h) =
+    if h = "circle" :
+        fullcircle xysized (bbwidth p, bbheight p) shifted center p
+    elseif h = "round" :
+        (p smoothed getparameterdefault "radius" ExHeight) xysized (bbwidth p, bbheight p)
+    elseif h = "path" :
+        (getparameterpath "path") shifted center p
+    elseif h = "scaledpath" :
+        (getparameterpath "path") xysized (bbwidth p, bbheight p) shifted center p
+    else :
+        p
+    fi
+enddef ;
+
+vardef lmt_do_matrix =
+    image (
+        pushparameters "matrix" ;
+        draw image (
+            save a, b, c, o, g ; path a, b, c ; numeric o, g ;
+            if (hasparameter "arrowoffset") :
+                g := getparameter "arrowoffset" ;
+            elseif (hasparameter "linewidth") :
+                g := getparameter "linewidth" ;
+            else :
+                g := 0;
+            fi ;
+            if (hasparameter "from") and (hasparameter "to") :
+                a := mfun_lmt_matrix_cell(getparameter "from") ;
+                b := mfun_lmt_matrix_cell(getparameter "to") ;
+                if hasparameter "offset" :
+                    o := getparameter "offset" ;
+                    a := a enlarged o ;
+                    b := b enlarged o ;
+                fi ;
+                if hasparameter "shapes" :
+                    a := mfun_lmt_matrix_enhance(a, getparameter "shapes" 1) ;
+                    b := mfun_lmt_matrix_enhance(b, getparameter "shapes" 2) ;
+                fi ;
+                draw a
+                    if (hasparameter "colors") :
+                        withcolor (getparameter "colors" 1)
+                    elseif (hasparameter "color") :
+                        withcolor (getparameter "color")
+                    fi
+                ;
+                draw b
+                    if (hasparameter "colors") :
+                        withcolor (getparameter "colors" 2)
+                    elseif (hasparameter "color") :
+                        withcolor (getparameter "color")
+                    fi
+                ;
+                c :=
+                    mfun_lmt_matrix_source(a, getparameter "connect" 1, g) ..
+                    mfun_lmt_matrix_target(b, getparameter "connect" 2, g) ;
+                drawarrow c
+                    if (hasparameter "arrowcolor") :
+                        withcolor (getparameter "arrowcolor")
+                    elseif (hasparameter "color") :
+                        withcolor (getparameter "color")
+                    fi
+                ;
+                if hasparameter "label" :
+                    pushparameters "label" ;
+                    draw lmt_text [
+                        text     = getparameter "text",
+                        position = point (getparameterdefault "fraction" 1/2) of c,
+                        offset   = if hasparameter "offset" : getparameter "offset" fi,
+                        color    = if hasparameter "color"  : getparameter "color"  fi,
+                        anchor   = if hasparameter "anchor" : getparameter "anchor" fi,
+                      % strut style format background backgroundcolor
+                    ] ;
+                    popparameters ;
+                fi ;
+            elseif (hasparameter "cell") :
+                a := mfun_lmt_matrix_cell(getparameter "cell") ;
+                if hasparameter "offset" :
+                    o := getparameter "offset" ;
+                    a := a enlarged o ;
+                fi ;
+                if hasparameter "shape" :
+                    a := mfun_lmt_matrix_enhance(a, getparameter "shape") ;
+                fi ;
+                draw a
+                    if (hasparameter "color") :
+                        withcolor (getparameter "color")
+                    fi
+                ;
+            fi;
+        )
+        if (hasparameter "linewidth") :
+            withpen pencircle scaled (getparameter "linewidth")
+        fi
+        popparameters
+    )
+enddef ;
+
+% This might move to its own module if we add more:
+
+presetparameters "glyphshape" [
+  % id        = "",
+  % character = "",
+    shape       = true,
+    boundingbox = false,
+    baseline    = false,
+    usedline    = true,
+    usedbox     = true,
+] ;
+
+def lmt_glyphshape = applyparameters "glyphshape" "lmt_do_glyphshape" enddef ;
+
+vardef glyphshape_start(expr id, character) =
+    lua.mp.lmt_glyphshape_start(id, character) ;
+enddef ;
+
+vardef glyphshape_stop         = lua.mp.lmt_glyphshape_stop() ;      enddef ;
+vardef glyphshape_n            = lua.mp.lmt_glyphshape_n()           enddef ;
+vardef glyphshape_path(expr i) = lua.mp.lmt_glyphshape_path(i)       enddef ;
+vardef glyphshape_boundingbox  = lua.mp.lmt_glyphshape_boundingbox() enddef ;
+vardef glyphshape_baseline     = lua.mp.lmt_glyphshape_baseline()    enddef ;
+vardef glyphshape_usedbox      = lua.mp.lmt_glyphshape_usedbox()     enddef ;
+vardef glyphshape_usedline     = lua.mp.lmt_glyphshape_usedline()    enddef ;
+vardef glyphshape_width        = lua.mp.lmt_glyphshape_width()       enddef ;
+vardef glyphshape_height       = lua.mp.lmt_glyphshape_height()      enddef ;
+vardef glyphshape_depth        = lua.mp.lmt_glyphshape_depth()       enddef ;
+vardef glyphshape_italic       = lua.mp.lmt_glyphshape_italic()      enddef ;
+vardef glyphshape_accent       = lua.mp.lmt_glyphshape_accent()      enddef ;
+
+vardef lmt_do_glyphshape =
+    image (
+        pushparameters "glyphshape" ;
+            lua.mp.lmt_glyphshape_start(getparameter "id", getparameter "character") ;
+            if getparameter "shape" :
+                draw for i=1 upto lua.mp.lmt_glyphshape_n() :
+                    lua.mp.lmt_glyphshape_path(i) &&
+                endfor cycle ;
+            fi ;
+            if getparameter "boundingbox" :
+                draw
+                    lua.mp.lmt_glyphshape_boundingbox()
+                    withcolor red
+                ;
+            fi ;
+            if getparameter "usedline" :
+                draw
+                    lua.mp.lmt_glyphshape_usedline()
+                    withcolor green
+                ;
+            fi ;
+            if getparameter "usedbox" :
+                draw
+                    lua.mp.lmt_glyphshape_usedbox()
+                    withcolor blue
+                ;
+            fi ;
+            lua.mp.lmt_glyphshape_stop() ;
+        popparameters ;
+    )
+enddef ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-luas.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-luas.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-luas.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -112,8 +112,12 @@
     mlib_luas_lualist("MP." & str @#,t)
 enddef ;
 
-def message expr t =
-    lua.mp.report(tostring(t)) ;
+% todo: runner
+
+newscriptindex mfun_message ; mfun_message := scriptindex("message") ;
+
+def message text t =
+    runscript mfun_message tostring(t) ; % todo: scananything
 enddef ;
 
 permanent newscriptindex, scriptindex, luacall, lua, lualist, mp, MP  ;
@@ -134,19 +138,31 @@
 
 % Modes:
 
-vardef texmode   (expr s) = lua.mp("mode",      s) enddef ;
-vardef systemmode(expr s) = lua.mp("systemmode",s) enddef ;
+newscriptindex mfid_mode       ; mfid_mode       := scriptindex "mode" ;
+newscriptindex mfid_systemmode ; mfid_systemmode := scriptindex "systemmode" ;
 
+vardef texmode    (expr s) = runscript mfid_mode       s enddef ;
+vardef systemmode (expr s) = runscript mfid_systemmode s enddef ;
+
+% let processingmode = systemmode ;
+
 permanent texmode, systemmode ;
 
 % A few helpers
 
-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 ;
+newscriptindex mfid_isarray   ; mfid_isarray   := scriptindex "isarray"   ;
+newscriptindex mfid_prefix    ; mfid_prefix    := scriptindex "prefix"    ;
+newscriptindex mfid_dimension ; mfid_dimension := scriptindex "dimension" ;
+newscriptindex mfid_isobject  ; mfid_isobject  := scriptindex "isobject"  ;
 
-permanent isarray, prefix, dimension ;
+vardef isarray   suffix a = runscript mfid_isarray  (str a) enddef ;
+vardef prefix    suffix a = runscript mfid_prefix   (str a) enddef ;
+vardef dimension suffix a = runscript mfid_dimension(str a) enddef ;
 
+vardef isobject  expr p = if picture p : runscript mfid_isobject prescriptpart p else : false fi enddef ;
+
+permanent isarray, prefix, dimension, isobject ;
+
 % More access
 
 newscriptindex mfid_getmacro ; mfid_getmacro := scriptindex "getmacro" ; def getmacro = runscript mfid_getmacro enddef ;
@@ -171,16 +187,39 @@
     setmacro, setdimen, setcount, settoks,
     setglobalmacro, setglobaldimen, setglobalcount, setglobaltoks ;
 
-vardef positionpath  (expr name) = lua.mp.positionpath  (name) enddef ;
-vardef positioncurve (expr name) = lua.mp.positioncurve (name) enddef ;
-vardef positionxy    (expr name) = lua.mp.positionxy    (name) enddef ;
-vardef positionpxy   (expr name) = lua.mp.positionpxy   (name) enddef ;
-vardef positionwhd   (expr name) = lua.mp.positionwhd   (name) enddef ;
-vardef positionpage  (expr name) = lua.mp.positionpage  (name) enddef ;
-vardef positionregion(expr name) = lua.mp.positionregion(name) enddef ;
-vardef positionbox   (expr name) = lua.mp.positionbox   (name) enddef ;
-vardef positionanchor            = lua.mp.positionanchor()     enddef ;
+newscriptindex mfid_positionpath        ; mfid_positionpath        := scriptindex("positionpath") ;
+newscriptindex mfid_positioncurve       ; mfid_positioncurve       := scriptindex("positioncurve") ;
+newscriptindex mfid_positionxy          ; mfid_positionxy          := scriptindex("positionxy") ;
+newscriptindex mfid_positionx           ; mfid_positionx           := scriptindex("positionx") ;
+newscriptindex mfid_positiony           ; mfid_positiony           := scriptindex("positiony") ;
+newscriptindex mfid_positionposition    ; mfid_positionparagraph   := scriptindex("positionparagraph") ;
+newscriptindex mfid_positionwhd         ; mfid_positionwhd         := scriptindex("positionwhd") ;
+newscriptindex mfid_positionpage        ; mfid_positionpage        := scriptindex("positionpage") ;
+newscriptindex mfid_positioncolumn      ; mfid_positioncolumn      := scriptindex("positioncolumn") ;
+newscriptindex mfid_positionregion      ; mfid_positionregion      := scriptindex("positionregion") ;
+newscriptindex mfid_positionbox         ; mfid_positionbox         := scriptindex("positionbox") ;
+newscriptindex mfid_positionanchor      ; mfid_positionanchor      := scriptindex("positionanchor") ;
+newscriptindex mfid_positioncolumnfromx ; mfid_positioncolumnfromx := scriptindex("positioncolumnfromx") ;
+newscriptindex mfid_positioncolumnbox   ; mfid_positioncolumnbox   := scriptindex("positioncolumnbox") ;
+newscriptindex mfid_overlaycolumnbox    ; mfid_overlaycolumnbox    := scriptindex("overlaycolumnbox") ;
 
+vardef positionpath     (expr name)   = runscript mfid_positionpath     (name)   enddef ;
+vardef positioncurve    (expr name)   = runscript mfid_positioncurve    (name)   enddef ;
+vardef positionxy       (expr name)   = runscript mfid_positionxy       (name)   enddef ;
+vardef positionx        (expr name)   = runscript mfid_positionx        (name)   enddef ;
+vardef positiony        (expr name)   = runscript mfid_positiony        (name)   enddef ;
+vardef positionwhd      (expr name)   = runscript mfid_positionwhd      (name)   enddef ;
+vardef positionpage     (expr name)   = runscript mfid_positionpage     (name)   enddef ;
+vardef positioncolumn   (expr name)   = runscript mfid_positioncolumn   (name)   enddef ;
+vardef positionparagraph(expr name)   = runscript mfid_positionparagraph(name)   enddef ;
+vardef positionpar      (expr name)   = runscript mfid_positionparagraph(name)   enddef ;
+vardef positionregion   (expr name)   = runscript mfid_positionregion   (name)   enddef ;
+vardef positionbox      (expr name)   = runscript mfid_positionbox      (name)   enddef ;
+vardef positionanchor                 = runscript mfid_positionanchor            enddef ;
+vardef positioncolumnatx(expr name)   = runscript mfid_positioncolumnatx(name)   enddef ;
+vardef positioncolumnbox(expr column) = runscript mfid_positioncolumnbox(column) enddef ;
+vardef overlaycolumnbox (expr column) = runscript mfid_overlaycolumnbox (column) enddef ;
+
 vardef positioninregion =
     currentpicture := currentpicture shifted - positionxy(positionanchor) ;
 enddef ;
@@ -189,8 +228,10 @@
     currentpicture := currentpicture shifted - positionxy(name) ;
 enddef ;
 
-permanent positionpath, positioncurve, positionxy, positionpxy, positionwhd, positionpage,
-    positionregion, positionbox, positionanchor, positioninregion, positionatanchor ;
+permanent positionpath, positioncurve, positionxy, positionwhd,
+    positionpage, positionregion, positioncolumn, positionparagraph,
+    positionbox, positionanchor, positioninregion, positionatanchor,
+    positioncolumnatx, positioncolumnbox, overlaycolumnbox ;
 
 let wdpart = redpart ;
 let htpart = greenpart ;
@@ -198,9 +239,17 @@
 
 permanent wdpart, htpart, dppart;
 
-vardef texvar(expr name) = lua.mp.texvar(name) enddef ;
-vardef texstr(expr name) = lua.mp.texstr(name) enddef ;
+newscriptindex mfid_sortedpath ; mfid_sortedpath := scriptindex "sortedpath" ;
+newscriptindex mfid_uniquepath ; mfid_uniquepath := scriptindex "uniquepath" ;
 
+def sortedpath = runscript mfid_sortedpath enddef ;
+def uniquepath = runscript mfid_uniquepath enddef ;
+
+permanent sortpath, uniquepath ;
+
+newscriptindex mfid_texvar ; mfid_texvar := scriptindex "texvar" ; vardef texvar(expr s) = runscript mfid_texvar s enddef ;
+newscriptindex mfid_texstr ; mfid_texstr := scriptindex "texstr" ; vardef texstr(expr s) = runscript mfid_texstr s enddef ;
+
 newscriptindex mfid_path_lengthof ; mfid_path_lengthof := scriptindex "pathlengthof" ;
 newscriptindex mfid_path_pointof  ; mfid_path_pointof  := scriptindex "pathpointof" ;
 newscriptindex mfid_path_leftof   ; mfid_path_leftof   := scriptindex "pathleftof" ;
@@ -233,8 +282,8 @@
 % def utflen = runscript mfid_utflen enddef ;
 % def utfsub = runscript mfid_utfsub enddef ;
 
-vardef utfnum expr s  = runscript mfid_utfnum s enddef ; % str
-vardef utflen expr s  = runscript mfid_utflen s enddef ; % str
+vardef utfnum(expr s) = runscript mfid_utfnum s enddef ; % str
+vardef utflen(expr s) = runscript mfid_utflen s enddef ; % str
 vardef utfsub(text t) = runscript mfid_utfsub t enddef ; % str, first, (optional) last
 
 permanent utfnum, utflen, utfsub ;
@@ -252,8 +301,10 @@
 newscriptindex mfid_getparametertext     ; mfid_getparametertext     := scriptindex "getparametertext" ;
 %              mfid_getparameteroption   ; mfid_getparameteroption   := scriptindex "getparameteroption" ;
 newscriptindex mfid_applyparameters      ; mfid_applyparameters      := scriptindex "applyparameters" ;
+newscriptindex mfid_mergeparameters      ; mfid_mergeparameters      := scriptindex "mergeparameters" ;
 newscriptindex mfid_pushparameters       ; mfid_pushparameters       := scriptindex "pushparameters" ;
 newscriptindex mfid_popparameters        ; mfid_popparameters        := scriptindex "popparameters" ;
+newscriptindex mfid_setluaparameter      ; mfid_setluaparameter      := scriptindex "setluaparameter" ;
 
 def getparameters        = runscript mfid_getparameters        enddef ;
 def presetparameters     = runscript mfid_presetparameters     enddef ;
@@ -268,13 +319,32 @@
 def getparametertext     = runscript mfid_getparametertext     enddef ;
 %   getparameteroption   = runscript mfid_getparameteroption   enddef ;
 def applyparameters      = runscript mfid_applyparameters      enddef ;
+def mergeparameters      = runscript mfid_mergeparameters      enddef ;
 def pushparameters       = runscript mfid_pushparameters       enddef ;
 def popparameters        = runscript mfid_popparameters        enddef ;
+def setluaparameter      = runscript mfid_setluaparameter      enddef ;
 
 permanent getparameters, presetparameters, hasparameter, hasoption, getparameter, getparameterdefault,
     getparametercount, getmaxparametercount, getparameterpath, getparameterpen, getparametertext, % getparameteroption,
-    applyparameters, pushparameters, popparameters ;
+    applyparameters, mergeparameters, pushparameters, popparameters, setluaparameter ;
 
+newscriptindex mfun_newrecord ; mfun_newrecord := scriptindex "newrecord" ;
+newscriptindex mfun_setrecord ; mfun_setrecord := scriptindex "setrecord" ;
+newscriptindex mfun_getrecord ; mfun_getrecord := scriptindex "getrecord" ;
+newscriptindex mfun_cntrecord ; mfun_cntrecord := scriptindex "cntrecord" ;
+
+% let record = runscript ; % We need to use "let" because we don't expand!
+
+def record    = newinternal numeric runscript enddef ;
+
+def newrecord = runscript mfun_newrecord ; enddef ; % semicolon prevents lookahead
+def setrecord = runscript mfun_setrecord ; enddef ;
+def getrecord = runscript mfun_getrecord   enddef ;
+def cntrecord = runscript mfun_cntrecord   enddef ;
+
+permanent
+    record, newrecord, setrecord, getrecord, cntrecord ;
+
 % No vardef's because we need to scan for an assignment too and we'll see
 % an endgroup otherwise.
 
@@ -310,7 +380,7 @@
 
 newscriptindex mfid_textextanchor ; mfid_textextanchor := scriptindex("textextanchor") ;
 
-def textextanchor = runscript mfid_textextanchor enddef ;
+% def textextanchor = runscript mfid_textextanchor enddef ;
 
 vardef textextanchor(expr p) =
     runscript mfid_textextanchor (prescriptpart p)
@@ -317,3 +387,52 @@
 enddef ;
 
 permanent textextanchor ;
+
+newscriptindex mfid_anchorxy   ; mfid_anchorxy   := scriptindex "anchorxy"   ;
+newscriptindex mfid_anchorx    ; mfid_anchorx    := scriptindex "anchorx"    ;
+newscriptindex mfid_anchory    ; mfid_anchory    := scriptindex "anchory"    ;
+newscriptindex mfid_anchorht   ; mfid_anchorht   := scriptindex "anchorht"   ;
+newscriptindex mfid_anchordp   ; mfid_anchordp   := scriptindex "anchordp"   ;
+newscriptindex mfid_anchorul   ; mfid_anchorul   := scriptindex "anchorul"   ;
+newscriptindex mfid_anchorll   ; mfid_anchorll   := scriptindex "anchorll"   ;
+newscriptindex mfid_anchorlr   ; mfid_anchorlr   := scriptindex "anchorlr"   ;
+newscriptindex mfid_anchorur   ; mfid_anchorur   := scriptindex "anchorur"   ;
+newscriptindex mfid_anchorbox  ; mfid_anchorbox  := scriptindex "anchorbox"  ;
+newscriptindex mfid_anchorspan ; mfid_anchorspan := scriptindex "anchorspan" ;
+
+def anchorxy (expr name, x, y) = runscript mfid_anchorxy  name x y enddef ;
+def anchorx  (expr name, x, y) = runscript mfid_anchorx   name x y enddef ;
+def anchory  (expr name, x, y) = runscript mfid_anchory   name x y enddef ;
+def anchorht (expr name, x, y) = runscript mfid_anchorht  name x y enddef ;
+def anchordp (expr name, x, y) = runscript mfid_anchordp  name x y enddef ;
+def anchorul (expr name, x, y) = runscript mfid_anchorul  name x y enddef ;
+def anchorll (expr name, x, y) = runscript mfid_anchorll  name x y enddef ;
+def anchorlr (expr name, x, y) = runscript mfid_anchorlr  name x y enddef ;
+def anchorur (expr name, x, y) = runscript mfid_anchorur  name x y enddef ;
+
+% todo: matrix =
+
+string mfun_local_anchor_tag ; mfun_local_anchor_tag := "matrix" ; % todo: push pop
+
+
+vardef localanchorbox (expr lname, fx, fy, rname, tx, ty) = (runscript mfid_anchorbox  lname fx fy rname tx ty) enddef ;
+vardef localanchorspan(expr lname, fx, fy, rname, tx, ty) = (runscript mfid_anchorspan lname fx fy rname tx ty) enddef ;
+vardef localanchorcell(expr  name,  x,  y               ) = (runscript mfid_anchorspan  name  x  y  name  x  y) enddef ;
+
+vardef anchorbox (expr fx, fy, tx, ty) = (runscript mfid_anchorbox  mfun_local_anchor_tag fx fy mfun_local_anchor_tag tx ty) enddef ;
+vardef anchorspan(expr fx, fy, tx, ty) = (runscript mfid_anchorspan mfun_local_anchor_tag fx fy mfun_local_anchor_tag tx ty) enddef ;
+vardef anchorcell(expr  x,  y        ) = (runscript mfid_anchorspan mfun_local_anchor_tag  x  y mfun_local_anchor_tag  x  y) enddef ;
+
+vardef matrixbox (expr fx, fy, tx, ty) = (runscript mfid_anchorbox  mfun_local_anchor_tag fx fy mfun_local_anchor_tag (tx+1) ty) enddef ;
+vardef matrixspan(expr fx, fy, tx, ty) = (runscript mfid_anchorspan mfun_local_anchor_tag fx fy mfun_local_anchor_tag (tx+1) ty) enddef ;
+vardef matrixcell(expr  x,  y        ) = (runscript mfid_anchorbox  mfun_local_anchor_tag  x  y mfun_local_anchor_tag ( x+1)  y) enddef ;
+
+permanent
+    anchorxy, anchorx, anchory,
+    anchorht, anchordp,
+    anchorul, anchorll, anchorlr, anchorur, anchorbox,
+    anchorspan ;
+
+permanent
+    matrixbox, matrixspan, matrixcell
+

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-math.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-math.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-math.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -157,8 +157,19 @@
   % vardef tand primary x = sind(x)/cosd(x)  enddef ;
   % vardef cotd primary x = cosd(x)/sind(x)  enddef ;
 
-    permanent sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, asinh, acosh, atanh, invsin, invcos, invtan, asind, acosd, atand ;
+else : % decimal
 
+    vardef sin    primary x = sind(x*radian)   enddef ;
+    vardef cos    primary x = cosd(x*radian)   enddef ;
+    vardef tan    primary x = sin(x)/cos(x)    enddef ;
+    vardef asin   primary x = angle((1+-+x,x)) enddef ;
+    vardef acos   primary x = angle((x,1+-+x)) enddef ;
+    vardef atan   primary x = angle(1,x)       enddef ;
+
+    vardef invsin primary x = (asin(x))/radian enddef ;
+    vardef invcos primary x = (acos(x))/radian enddef ;
+    vardef invtan primary x = (atan(x))/radian enddef ;
+
 fi ;
 
 permanent
@@ -177,7 +188,10 @@
 
     % sqrt, sind, cosd, % these are primitives
 
-    sqr, log, ln, exp, inv, sin, cos, tan, asin, acos, atan, invsin, invcos, invtan,
-    tand, asind, acosd, atand, tand, cotd
+    sqr, log, ln, exp, inv,
+    sin, cos, tan, asin, acos, atan, invsin, invcos, invtan,
+    tand, cotd,
+    sinh, cosh, tanh, asinh, acosh,
+    atanh, asind, acosd, atand
 ;
 

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-mlib.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-mlib.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-mlib.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -17,19 +17,6 @@
 
 % numeric LUATEXFUNCTIONALITY ; LUATEXFUNCTIONALITY := runscript("mp.print(LUATEXFUNCTIONALITY or (status and status.development_id) or 6346)") ;
 
-%D Objects:
-
-vardef isobject expr p =
-    if picture p :
-      % lua.mp.isobject(prescriptpart p)
-        runscript("mp.isobject(" & prescriptpart p & ")")
-    else :
-        false
-    fi
-enddef ;
-
-permanent isobject ;
-
 %D Color and transparency
 %D
 %D Separable:
@@ -123,36 +110,15 @@
     withprescript "tr_transparency=" & decimal t
 enddef ;
 
-% no, not compatible ... maybe only mpiv .. maybe withopacity
+% for svg:
 
-% let opacity = pair ;
-
-% def withtransparency expr t =
-%     withprescript "tr_alternative="  & decimal transparency_alternative_to_number(xpart t)
-%     withprescript "tr_transparency=" & decimal ypart t
-% enddef ;
-%
-% withtransparency (1,.5)
-% withtransparency ("normal",.5)
-%
-% withopacity      (1,.5)
-% withopacity      (normaltransparency,.5)
-% withopacity      .5
-
-def withopacity expr t =
-    if pair t :
-        withprescript "tr_alternative="  & decimal transparency_alternative_to_number(xpart t)
-        withprescript "tr_transparency=" & decimal ypart t
-    else :
-        mfun_with_opacity (transparency_alternative_to_number(t))
+def withopacity expr o =
+    if o <> 1 :
+        withprescript "tr_alternative="  & decimal normaltransparent
+        withprescript "tr_transparency=" & decimal o
     fi
 enddef ;
 
-def mfun_with_opacity (expr a) expr t =
-    withprescript "tr_alternative="  & decimal a
-    withprescript "tr_transparency=" & decimal t
-enddef ;
-
 % Provided for downward compability:
 
 def cmyk(expr c, m, y, k) =
@@ -167,12 +133,11 @@
 
 permanent textextoffset ;
 
-%%%%%%% mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ; % we can consider using colors (less hash space)
-color   mfun_tt_b ;
-numeric mfun_tt_n ; mfun_tt_n := 0 ;
-picture mfun_tt_p ; mfun_tt_p := nullpicture ;
-picture mfun_tt_o ; mfun_tt_o := nullpicture ;
-picture mfun_tt_c ; mfun_tt_c := nullpicture ;
+rgbcolor mfun_tt_r ;
+numeric  mfun_tt_n ; mfun_tt_n := 0 ;
+picture  mfun_tt_p ; mfun_tt_p := nullpicture ;
+picture  mfun_tt_o ; mfun_tt_o := nullpicture ;
+picture  mfun_tt_c ; mfun_tt_c := nullpicture ;
 
 if unknown mfun_trial_run :
     boolean mfun_trial_run ;
@@ -234,8 +199,9 @@
 
 permanent catcoderegime ;
 
-newscriptindex mfid_sometextext ; mfid_sometextext := scriptindex "sometextext" ;
-newscriptindex mfid_madetextext ; mfid_madetextext := scriptindex "madetextext" ;
+newscriptindex mfid_sometextext   ; mfid_sometextext   := scriptindex "sometextext" ;
+newscriptindex mfid_madetextext   ; mfid_madetextext   := scriptindex "madetextext" ;
+newscriptindex mfid_boxdimensions ; mfid_boxdimensions := scriptindex "boxdimensions" ;
 
 vardef rawtextext(expr s) =
     if s = "" :
@@ -275,6 +241,10 @@
     mfun_tt_c
 enddef ;
 
+% \setbox\scratchbox\hbox{!!!!!!!!!!!!!}
+% \putboxincache{one}{a}\scratchbox
+% \startMPcode draw rawtexbox("one","a") ; \stopMPcode
+
 vardef validtexbox(expr category, name) =
     if category == "" :
         false
@@ -290,11 +260,12 @@
 vardef rawtexbox(expr category, name) =
     mfun_tt_c := nullpicture ;
     if validtexbox(category,name) :
-        mfun_tt_b := lua.mp.mf_tb_dimensions(category, name) ;
+      % mfun_tt_r := lua.mp.mf_tb_dimensions(category, name) ;
+        mfun_tt_r := runscript mfid_boxdimensions category name ;
         addto mfun_tt_c doublepath unitsquare
-            xscaled wdpart mfun_tt_b
-            yscaled (htpart mfun_tt_b + dppart mfun_tt_b)
-            shifted (0,- dppart mfun_tt_b)
+            xscaled wdpart mfun_tt_r
+            yscaled (htpart mfun_tt_r + dppart mfun_tt_r)
+            shifted (0,- dppart mfun_tt_r)
             withprescript "mf_object=box"
             withprescript "bx_category=" & if numeric category : decimal fi category
             withprescript "bx_name=" & if numeric name : decimal fi name ;
@@ -332,7 +303,7 @@
 pair mfun_laboff.lrt    ; mfun_laboff.lrt    := (.7,-.7) ;
 
 pair mfun_laboff.d      ; mfun_laboff.d      := mfun_laboff     ;
-pair mfun_laboff.dflt   ; mfun_laboff.dflt   := mfun_laboff.lft ;
+pair mfun_laboff.dlft   ; mfun_laboff.dlft   := mfun_laboff.lft ;
 pair mfun_laboff.drt    ; mfun_laboff.drt    := mfun_laboff.rt  ;
 pair mfun_laboff.origin ; mfun_laboff.origin := mfun_laboff     ;
 pair mfun_laboff.raw    ; mfun_laboff.raw    := mfun_laboff     ;
@@ -361,7 +332,7 @@
 mfun_labxf.lrt      := mfun_labxf.r_b := mfun_labxf.b_r := 0   ;
 
 mfun_labxf.d        := mfun_labxf     ;
-mfun_labxf.dflt     := mfun_labxf.lft ;
+mfun_labxf.dlft     := mfun_labxf.lft ;
 mfun_labxf.drt      := mfun_labxf.rt  ;
 mfun_labxf.origin   := 0              ;
 mfun_labxf.raw      := 0              ;
@@ -377,7 +348,7 @@
 mfun_labyf.lrt      := mfun_labyf.r_b := mfun_labyf.b_r := 1   ;
 
 mfun_labyf.d        := mfun_labyf     ;
-mfun_labyf.dflt     := mfun_labyf.lft ;
+mfun_labyf.dlft     := mfun_labyf.lft ;
 mfun_labyf.drt      := mfun_labyf.rt  ;
 mfun_labyf.origin   := 0              ;
 mfun_labyf.raw      := 0              ;
@@ -392,7 +363,7 @@
 mfun_labtype.llft   := mfun_labtype.l_b :=  mfun_labtype.b_l :=  7 ;
 mfun_labtype.lrt    := mfun_labtype.r_b :=  mfun_labtype.b_r :=  8 ;
 mfun_labtype.d                                               := 10 ;
-mfun_labtype.dflt                                            := 11 ;
+mfun_labtype.dlft                                            := 11 ;
 mfun_labtype.drt                                             := 12 ;
 mfun_labtype.origin                                          :=  0 ;
 mfun_labtype.raw                                             :=  0 ;
@@ -696,20 +667,27 @@
 numeric mfun_shade_nx, mfun_shade_ny ;
 numeric mfun_shade_dx, mfun_shade_dy ;
 numeric mfun_shade_tx, mfun_shade_ty ;
+pair    mfun_shade_center ;
+path    mfun_shade_bbox ;
 
+numeric mfun_shade_height, mfun_shade_width;
 % first
 
 def mfun_with_shade_method_analyze(expr p) =
-    mfun_shade_path := p ;
-    mfun_shade_step := 1 ;
-    mfun_shade_fx   := xpart point 0 of p ;
-    mfun_shade_fy   := ypart point 0 of p ;
-    mfun_shade_lx   := mfun_shade_fx ;
-    mfun_shade_ly   := mfun_shade_fy ;
-    mfun_shade_nx   := 0 ;
-    mfun_shade_ny   := 0 ;
-    mfun_shade_dx   := abs(mfun_shade_fx - mfun_shade_lx) ;
-    mfun_shade_dy   := abs(mfun_shade_fy - mfun_shade_ly) ;
+    mfun_shade_path   := p ;
+    mfun_shade_center := center p;
+    mfun_shade_bbox   := boundingbox p;
+    mfun_shade_width  := bbwidth p;
+    mfun_shade_height := bbheight p;
+    mfun_shade_step   := 1 ;
+    mfun_shade_fx     := xpart point 0 of p ;
+    mfun_shade_fy     := ypart point 0 of p ;
+    mfun_shade_lx     := mfun_shade_fx ;
+    mfun_shade_ly     := mfun_shade_fy ;
+    mfun_shade_nx     := 0 ;
+    mfun_shade_ny     := 0 ;
+    mfun_shade_dx     := abs(mfun_shade_fx - mfun_shade_lx) ;
+    mfun_shade_dy     := abs(mfun_shade_fy - mfun_shade_ly) ;
     for i=1 upto length(p) :
         mfun_shade_tx := abs(mfun_shade_fx - xpart point i of p) ;
         mfun_shade_ty := abs(mfun_shade_fy - ypart point i of p) ;
@@ -726,6 +704,33 @@
     endfor ;
 enddef ;
 
+% todo: native bbox
+
+vardef mfun_shade_center_fraction_do expr a =
+    ddecimal (
+        (xpart llcorner mfun_shade_bbox) + (xpart a) * mfun_shade_width,
+        (ypart llcorner mfun_shade_bbox) + (ypart a) * mfun_shade_height
+    )
+enddef ;
+
+def withshadecenterfraction expr a =
+    withprescript "sh_center_a=" & mfun_shade_center_fraction_do a
+    withprescript "sh_center_b=" & mfun_shade_center_fraction_do a
+enddef ;
+
+def withshadecenteronefraction expr a =
+    withprescript "sh_center_a=" & mfun_shade_center_fraction_do a
+enddef ;
+
+def withshadecentertwofraction expr a =
+    withprescript "sh_center_b=" & mfun_shade_center_fraction_do a
+enddef ;
+
+def withshaderadiusfraction expr a =
+    withprescript "sh_radius_a=0"
+    withprescript "sh_radius_b=" & decimal (a * sqrt(mfun_shade_width*mfun_shade_width+mfun_shade_height*mfun_shade_height)/2)
+enddef ;
+
 vardef mfun_max_radius(expr p) =
     max (
         (xpart center   p - xpart llcorner p) ++ (ypart center   p - ypart llcorner p),
@@ -780,6 +785,14 @@
     withprescript "sh_center_b=" & ddecimal a
 enddef ;
 
+def withshadecenterone expr a =
+    withprescript "sh_center_a=" & ddecimal a
+enddef ;
+
+def withshadecentertwo expr a =
+    withprescript "sh_center_b=" & ddecimal a
+enddef ;
+
 def withshadevector expr a =
     withprescript "sh_center_a=" & ddecimal (point xpart a of mfun_shade_path)
     withprescript "sh_center_b=" & ddecimal (point ypart a of mfun_shade_path)
@@ -828,6 +841,12 @@
     fi
 enddef ;
 
+% def withshadeopacity expr a =
+%     if mfun_shade_step > 0 :
+%         withprescript "sh_opacity_" & decimal mfun_shade_step & "=" & decimal a
+%     fi
+% enddef ;
+
 def withshadecolors (expr a, b) =
     if mfun_shade_step > 0 :
         withprescript "sh_color=into"
@@ -1099,6 +1118,11 @@
     rawtextext("\externalfigure[" & filename & "]")
 enddef ;
 
+vardef svgembeddedfigure primary index =
+%     mfun_onetime_textext := true ;
+    rawtextext("\svgembeddedfigure{" & decimal index & "}")
+enddef ;
+
 permanent withmask, externalfigure, figure ;
 
 % Positions
@@ -1347,13 +1371,25 @@
 
 % New
 
-def bitmapimage(expr xresolution, yresolution, data) =
-    image (
-        addto currentpicture doublepath unitsquare
-            withprescript  "bm_xresolution=" & decimal xresolution
-            withprescript  "bm_yresolution=" & decimal yresolution
-            withpostscript data ;
-    )
+% def bitmapimage(expr xresolution, yresolution, data) =
+%     image (
+%         addto currentpicture doublepath unitsquare
+%             withprescript  "bm_xresolution=" & decimal xresolution
+%             withprescript  "bm_yresolution=" & decimal yresolution
+%             withpostscript data ;
+%     )
+% enddef ;
+
+vardef bitmapimage(expr xresolution, yresolution, data) =
+    save p ; picture p ; p := nullpicture ;
+    addto p doublepath unitsquare
+%         xscaled xresolution
+%         yscaled yresolution
+        withprescript  "bm_xresolution=" & decimal xresolution
+        withprescript  "bm_yresolution=" & decimal yresolution
+        withpostscript data
+    ;
+    p
 enddef ;
 
 permanent bitmapimage ;
@@ -1370,11 +1406,11 @@
 enddef ;
 
 def withproperties expr p =
-    if colormodel p = 3 :
+    if colormodel p = graycolormodel :
         withcolor greypart p
-    elseif colormodel p = 5 :
+    elseif colormodel p = rgbcolormodel :
         withcolor (redpart p,greenpart p,bluepart p)
-    elseif colormodel p = 7 :
+    elseif colormodel p = cmykcolormodel :
         withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p)
     fi
     withpen penpart p
@@ -1381,6 +1417,9 @@
     if length (dashpart p) > 0 :
         dashed dashpart p
     fi
+    if stackingpart p <> 0 :
+        withstacking stackingpart p
+    fi
     withprescript prescriptpart p
     withpostscript postscriptpart p
 enddef ;
@@ -1398,10 +1437,12 @@
     temp_q:= nullpicture ;
     addto temp_q contour temp_r
         withprescript "gr_state=start"
-        withprescript "gr_type=" & s ;
+        withprescript "gr_type=" & s
+    ;
     addto temp_q also temp_p ;
     addto temp_q contour temp_r
-        withprescript "gr_state=stop" ;
+        withprescript "gr_state=stop"
+    ;
     temp_q
     endgroup
 enddef ;
@@ -1408,6 +1449,63 @@
 
 permanent asgroup ;
 
+% Even more experimental:
+
+pair    mfun_pattern_s ; mfun_pattern_s := origin ; % auto scale to fraction of shape (svg)
+boolean mfun_pattern_f ; mfun_pattern_f := false  ; % anchor or not (normally we do that)
+
+def withpatternscale primary s = hide (mfun_pattern_s := paired s ;) enddef ;
+def withpatternfloat primary s = hide (mfun_pattern_f := s ;) enddef ;
+
+primarydef t withpattern p =
+    begingroup
+    %
+    save temp_q, temp_r ;
+    picture temp_q ; path temp_r ;
+    % the combination
+    temp_q:= nullpicture ;
+    % the pattern
+    temp_r := boundingbox p ;
+    if mfun_pattern_s <> origin :
+        sx := (xpart mfun_pattern_s) * bbwidth (t) ;
+        sy := (ypart mfun_pattern_s) * bbheight(t) ;
+        temp_r := temp_r xysized (sx,sy) ;
+        addto temp_q contour temp_r
+            withprescript "pt_state=start"
+            withprescript "pt_action=set"
+            withprescript "pt_float=" & tostring(mfun_pattern_f)
+        ;
+        addto temp_q also (p xysized (sx,sy));
+    else :
+        addto temp_q contour temp_r
+            withprescript "pt_state=start"
+            withprescript "pt_action=set"
+            withprescript "pt_float=" & tostring(mfun_pattern_f)
+        ;
+        addto temp_q also p ;
+    fi ;
+    addto temp_q contour temp_r
+        withprescript "pt_state=stop"
+        withprescript "pt_action=set" ;
+    % the path
+    temp_r := boundingbox t ;
+    addto temp_q contour temp_r
+        withprescript "pt_state=start"
+        withprescript "pt_action=get"
+    ;
+    addto temp_q contour temp_r
+        withprescript "pt_state=stop"
+        withprescript "pt_action=get" ;
+    % make sure we fill only t
+    clip temp_q to t ;
+    % reset
+    mfun_pattern_s := origin ;
+    mfun_pattern_f := false ;
+    % the path
+    temp_q
+    endgroup
+enddef ;
+
 % Also experimental ... needs to be made better ... so it can change!
 
 string mfun_auto_align[] ;
@@ -1577,104 +1675,22 @@
 % but running lua is fast enough so we can gain on string construction in metapost
 % which is also not that efficient.
 
-vardef mfun_key_to_lua(expr k) =
-    if numeric k : decimal k else : "'" & k & "'" fi
-enddef ;
+newscriptindex mfid_passvariable ; mfid_passvariable := scriptindex("passvariable") ;
+newscriptindex mfid_pushvariable ; mfid_pushvariable := scriptindex("pushvariable") ;
+newscriptindex mfid_popvariable  ; mfid_popvariable  := scriptindex("popvariable") ;
 
-vardef mfun_point_to_lua(expr k,p,i) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
-        decimal xpart (point       i of p) & "," &
-        decimal ypart (point       i of p) & "," &
-        decimal xpart (precontrol  i of p) & "," &
-        decimal ypart (precontrol  i of p) & "," &
-        decimal xpart (postcontrol i of p) & "," &
-        decimal ypart (postcontrol i of p)
-    & "})" ) ;
-enddef ;
+def passvariable        (expr key, value) = runscript mfid_passvariable key value ; enddef ;
+def startpassingvariable(expr key)        = runscript mfid_pushvariable key ; enddef ;
+def stoppassingvariable                   = runscript mfid_popvariable ; enddef ;
 
-vardef mfun_transform_to_lua(expr k,t) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
-        decimal xxpart t & "," &   % rx
-        decimal xypart t & "," &   % sx
-        decimal yxpart t & "," &   % sy
-        decimal yypart t & "," &   % ry
-        decimal xpart  t & "," &   % tx
-        decimal ypart  t           % ty
-    & "})" ) ;
-enddef ;
-
-vardef mfun_numeric_to_lua(expr k,n) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & "," & decimal n & ")" ) ;
-enddef ;
-
-vardef mfun_pair_to_lua(expr k,p) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
-        decimal xpart p & "," &
-        decimal ypart p
-    & "})" ) ;
-enddef ;
-
-vardef mfun_rgbcolor_to_lua(expr k,c) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
-        decimal redpart   c & "," &
-        decimal greenpart c & "," &
-        decimal bluepart  c
-    & "})" ) ;
-enddef ;
-
-vardef mfun_cmykcolor_to_lua(expr k,c) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
-        decimal cyanpart    c & "," &
-        decimal magentapart c & "," &
-        decimal yellowpart  c & "," &
-        decimal blackpart   c
-    & "})" ) ;
-enddef ;
-
-vardef mfun_path_to_lua(expr k,p) =
-    runscript("metapost.pushvariable(" & mfun_key_to_lua(k) & ")") ;
-    for i=0 upto length(p) :
-        mfun_point_to_lua(i+1,p,i) ;
-    endfor ;
-    runscript("metapost.popvariable()") ;
-enddef ;
-
-vardef mfun_boolean_to_lua(expr k,b) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & if b : ",true)" else : ",false)" fi ) ;
-enddef ;
-
-vardef mfun_string_to_lua(expr k,s) =
-    runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",[==[" & s & "]==])" ) ;
-enddef ;
-
-def passvariable(expr key, value) =
-    if     numeric   value : mfun_numeric_to_lua  (key,value) ;
-    elseif pair      value : mfun_pair_to_lua     (key,value) ;
-    elseif string    value : mfun_string_to_lua   (key,value) ;
-    elseif boolean   value : mfun_boolean_to_lua  (key,value) ;
-    elseif path      value : mfun_path_to_lua     (key,value) ;
-    elseif rgbcolor  value : mfun_rgbcolor_to_lua (key,value) ;
-    elseif cmykcolor value : mfun_cmykcolor_to_lua(key,value) ;
-    elseif transform value : mfun_transform_to_lua(key,value) ;
-    fi ;
-enddef ;
-
 def passarrayvariable(expr key)(suffix values)(expr first, last, stp) =
-    runscript("metapost.pushvariable(" & mfun_key_to_lua(key) & ")") ;
+    startpassingvariable(key) ;
     for i=first step stp until last :
         passvariable(i, values[i]) ;
     endfor
-    runscript("metapost.popvariable()") ;
+    stoppassingvariable ;
 enddef ;
 
-def startpassingvariable(expr k) =
-    runscript("metapost.pushvariable(" & mfun_key_to_lua(k) & ")") ;
-enddef ;
-
-def stoppassingvariable =
-    runscript("metapost.popvariable()") ;
-enddef ;
-
 permanent passvariable, passarrayvariable, startpassingvariable, stoppassingvariable ;
 
 % moved here from mp-grap.mpiv
@@ -1750,20 +1766,20 @@
 % def strfmt = format    enddef ; % old
 % def varfmt = formatted enddef ; % old
 
-
 % def fmttext = lua.mp.formatted enddef ;
 
 % new
 
-def fillup   text t = draw t withpostscript "both"    enddef ; % we use draw because we need the proper boundingbox
-def eofillup text t = draw t withpostscript "eoboth"  enddef ; % we use draw because we need the proper boundingbox
-def eofill   text t = fill t withpostscript "evenodd" enddef ;
-def nofill   text t = fill t withpostscript "collect" enddef ;
-def nodraw   text t = draw t withpostscript "collect" enddef ;
-def dodraw   text t = draw t withpostscript "flush"   enddef ;
-%   eodraw   text t = draw t withpostscript "evenodd" enddef ;
-def dofill   text t = fill t withpostscript "flush"   enddef ;
-def eoclip   text t = clip t withpostscript "evenodd" enddef ;
+def fillup   text t = draw t withpostscript "both"     enddef ; % we use draw because we need the proper boundingbox
+def eofillup text t = draw t withpostscript "eoboth"   enddef ; % we use draw because we need the proper boundingbox
+def eofill   text t = fill t withpostscript "evenodd"  enddef ;
+def nofill   text t = fill t withpostscript "collect"  enddef ;
+def nodraw   text t = draw t withpostscript "collect"  enddef ;
+def dodraw   text t = draw t withpostscript "flush"    enddef ;
+%   eodraw   text t = draw t withpostscript "evenodd"  enddef ;
+def dofill   text t = fill t withpostscript "flush"    enddef ;
+def eoclip   text t = clip t withpostscript "evenodd"  enddef ;
+def enfill   text t = fill t withpostscript "envelope" enddef ;
 
 permanent fillup, eofillup, eofill, nofill, nodraw, dodraw, dofill, eoclip ;
 
@@ -1796,14 +1812,29 @@
 
 permanent comment, report ;
 
-% This overloads a dummy:
+% This nechanism is not really promoted and more an experiment. It scales better than
+% \METAPOST\ own hash.
 
 % todo: use mfid_* cum suis
 
+newscriptindex mfid_hash_new     ; mfid_hash_new     := scriptindex("lmt_hash_new") ;
+newscriptindex mfid_hash_dispose ; mfid_hash_dispose := scriptindex("lmt_hash_dispose") ;
+newscriptindex mfid_hash_in      ; mfid_hash_in      := scriptindex("lmt_hash_in") ;
+newscriptindex mfid_hash_from    ; mfid_hash_from    := scriptindex("lmt_hash_from") ;
+newscriptindex mfid_hash_to      ; mfid_hash_to      := scriptindex("lmt_hash_to") ;
+
+def newhash                          = runscript mfid_hash_new                 enddef ; % optional, returns index
+def disposehash (expr n)             = runscript mfid_hash_dispose n           enddef ;
+def inhash      (expr n, key)        = runscript mfid_hash_in      n key       enddef ;
+def fromhash    (expr n, key)        = runscript mfid_hash_from    n key       enddef ;
+def tohash      (expr n, key, value) = runscript mfid_hash_to      n key value enddef ;
+
+string mfun_u_l_h ; mfun_u_l_h := "mfun_u_l_h" ;
+
 vardef uniquelist(suffix list) =
     % this can be optimized by passing all values at once and returning
     % a result but for now this is ok .. we need an undef foo
-    save i, j, h ;
+    save i, j ;
     if known lis[0] :
         i := 0 ;
         j := -1 ;
@@ -1811,20 +1842,34 @@
         i := 1 ;
         j := 0 ;
     fi ;
-    h := lua.mp.newhash() ;
+  % mfun_u_l_h := runscript mfid_hash_new ; % here mfun_u_l_h has to be a numeric
     forever :
         exitif unknown list[i] ;
-        if not lua.mp.inhash(h,list[i]) :
+        if not (runscript mfid_hash_in (mfun_u_l_h) list[i]) :
             j := j + 1 ;
             list[j] := list[i] ;
-            lua.mp.tohash(h,list[i]) ;
+            runscript mfid_hash_to (mfun_u_l_h) (j) list[i] ;
         fi ;
         i := i + 1 ;
     endfor ;
-    for n = j+1 step 1 until i-1 :
+    for n = j + 1 step 1 until i - 1 :
         dispose(list[n])
     endfor ;
-    lua.mp.disposehash(h) ;
+    runscript mfid_hash_dispose mfun_u_l_h ;
 enddef ;
 
 permanent uniquelist ;
+
+% This influences the decision for a curve or path segment; 1/4096 is the default but
+% 10/2048 works quite well.
+
+def withtolerance expr n =
+    withprescript ("tolerance=" & decimal n)
+enddef ;
+
+% fun stuff: randomseed := repeatablerandom("default") ;
+
+newscriptindex mfid_repeatablerandom ; mfid_repeatablerandom := scriptindex("repeatablerandom") ;
+
+def repeatablerandom = runscript mfid_repeatablerandom enddef ;
+

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-page.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-page.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-page.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -52,83 +52,109 @@
 
 % We could go for just setting them (:=):
 
-path    mfun_page_area[][] ;
-pair    mfun_page_location[][] ;
-path    mfun_page_field[][] ;
-numeric mfun_page_vsize[] ;
-numeric mfun_page_hsize[] ;
-numeric mfun_page_vstep[] ;
-numeric mfun_page_hstep[] ;
+path    mfun_page_area    [][][] ;
+pair    mfun_page_location[][][] ;
+path    mfun_page_field   [][][] ;
+numeric mfun_page_vsize   [][] ;
+numeric mfun_page_hsize   [][] ;
+numeric mfun_page_vstep   [][] ;
+numeric mfun_page_hstep   [][] ;
 
-newinternal mfun_page_done ; mfun_page_done := 0 ;
+numeric mfun_page_odd ; mfun_page_odd := 1 ;
 
 def mfun_page_check_vsize =
-    mfun_page_vsize[Top]             := TopHeight ;
-    mfun_page_vsize[TopSeparator]    := TopDistance ;
-    mfun_page_vsize[Header]          := HeaderHeight ;
-    mfun_page_vsize[HeaderSeparator] := HeaderDistance ;
-    mfun_page_vsize[Text]            := TextHeight ;
-    mfun_page_vsize[FooterSeparator] := FooterDistance ;
-    mfun_page_vsize[Footer]          := FooterHeight ;
-    mfun_page_vsize[BottomSeparator] := BottomDistance ;
-    mfun_page_vsize[Bottom]          := BottomHeight ;
+    mfun_page_vsize[mfun_page_odd][Top]             := TopHeight ;
+    mfun_page_vsize[mfun_page_odd][TopSeparator]    := TopDistance ;
+    mfun_page_vsize[mfun_page_odd][Header]          := HeaderHeight ;
+    mfun_page_vsize[mfun_page_odd][HeaderSeparator] := HeaderDistance ;
+    mfun_page_vsize[mfun_page_odd][Text]            := TextHeight ;
+    mfun_page_vsize[mfun_page_odd][FooterSeparator] := FooterDistance ;
+    mfun_page_vsize[mfun_page_odd][Footer]          := FooterHeight ;
+    mfun_page_vsize[mfun_page_odd][BottomSeparator] := BottomDistance ;
+    mfun_page_vsize[mfun_page_odd][Bottom]          := BottomHeight ;
 enddef ;
 
 def mfun_page_check_hsize =
-    mfun_page_hsize[LeftEdge]             := LeftEdgeWidth ;
-    mfun_page_hsize[LeftEdgeSeparator]    := LeftEdgeDistance ;
-    mfun_page_hsize[LeftMargin]           := LeftMarginWidth ;
-    mfun_page_hsize[LeftMarginSeparator]  := LeftMarginDistance ;
-    mfun_page_hsize[Text]                 := MakeupWidth ;
-    mfun_page_hsize[RightMarginSeparator] := RightMarginDistance ;
-    mfun_page_hsize[RightMargin]          := RightMarginWidth ;
-    mfun_page_hsize[RightEdgeSeparator]   := RightEdgeDistance ;
-    mfun_page_hsize[RightEdge]            := RightEdgeWidth ;
+    mfun_page_hsize[mfun_page_odd][LeftEdge]             := LeftEdgeWidth ;
+    mfun_page_hsize[mfun_page_odd][LeftEdgeSeparator]    := LeftEdgeDistance ;
+    mfun_page_hsize[mfun_page_odd][LeftMargin]           := LeftMarginWidth ;
+    mfun_page_hsize[mfun_page_odd][LeftMarginSeparator]  := LeftMarginDistance ;
+    mfun_page_hsize[mfun_page_odd][Text]                 := MakeupWidth ;
+    mfun_page_hsize[mfun_page_odd][RightMarginSeparator] := RightMarginDistance ;
+    mfun_page_hsize[mfun_page_odd][RightMargin]          := RightMarginWidth ;
+    mfun_page_hsize[mfun_page_odd][RightEdgeSeparator]   := RightEdgeDistance ;
+    mfun_page_hsize[mfun_page_odd][RightEdge]            := RightEdgeWidth ;
 enddef ;
 
 def mfun_page_check_vstep =
-    mfun_page_vstep[TopSeparator]    := PaperHeight-TopSpace ;
-    mfun_page_vstep[Top]             := mfun_page_vstep[TopSeparator]   +mfun_page_vsize[TopSeparator] ;
-    mfun_page_vstep[Header]          := mfun_page_vstep[TopSeparator]   -mfun_page_vsize[Header] ;
-    mfun_page_vstep[HeaderSeparator] := mfun_page_vstep[Header]         -mfun_page_vsize[HeaderSeparator] ;
-    mfun_page_vstep[Text]            := mfun_page_vstep[HeaderSeparator]-mfun_page_vsize[Text] ;
-    mfun_page_vstep[FooterSeparator] := mfun_page_vstep[Text]           -mfun_page_vsize[FooterSeparator] ;
-    mfun_page_vstep[Footer]          := mfun_page_vstep[FooterSeparator]-mfun_page_vsize[Footer] ;
-    mfun_page_vstep[BottomSeparator] := mfun_page_vstep[Footer]         -mfun_page_vsize[BottomSeparator] ;
-    mfun_page_vstep[Bottom]          := mfun_page_vstep[BottomSeparator]-mfun_page_vsize[Bottom] ;
+    mfun_page_vstep[mfun_page_odd][TopSeparator]    := PaperHeight-TopSpace ;
+    mfun_page_vstep[mfun_page_odd][Top]             := mfun_page_vstep[mfun_page_odd][TopSeparator]   +mfun_page_vsize[mfun_page_odd][TopSeparator] ;
+    mfun_page_vstep[mfun_page_odd][Header]          := mfun_page_vstep[mfun_page_odd][TopSeparator]   -mfun_page_vsize[mfun_page_odd][Header] ;
+    mfun_page_vstep[mfun_page_odd][HeaderSeparator] := mfun_page_vstep[mfun_page_odd][Header]         -mfun_page_vsize[mfun_page_odd][HeaderSeparator] ;
+    mfun_page_vstep[mfun_page_odd][Text]            := mfun_page_vstep[mfun_page_odd][HeaderSeparator]-mfun_page_vsize[mfun_page_odd][Text] ;
+    mfun_page_vstep[mfun_page_odd][FooterSeparator] := mfun_page_vstep[mfun_page_odd][Text]           -mfun_page_vsize[mfun_page_odd][FooterSeparator] ;
+    mfun_page_vstep[mfun_page_odd][Footer]          := mfun_page_vstep[mfun_page_odd][FooterSeparator]-mfun_page_vsize[mfun_page_odd][Footer] ;
+    mfun_page_vstep[mfun_page_odd][BottomSeparator] := mfun_page_vstep[mfun_page_odd][Footer]         -mfun_page_vsize[mfun_page_odd][BottomSeparator] ;
+    mfun_page_vstep[mfun_page_odd][Bottom]          := mfun_page_vstep[mfun_page_odd][BottomSeparator]-mfun_page_vsize[mfun_page_odd][Bottom] ;
 enddef ;
 
 def mfun_page_check_hstep =
-    mfun_page_hstep[Text]                 := BackSpace ;
-    mfun_page_hstep[LeftMarginSeparator]  := mfun_page_hstep[Text]                -mfun_page_hsize[LeftMarginSeparator] ;
-    mfun_page_hstep[RightMarginSeparator] := mfun_page_hstep[Text]                +mfun_page_hsize[Text] ;
-    mfun_page_hstep[LeftMargin]           := mfun_page_hstep[LeftMarginSeparator] -mfun_page_hsize[LeftMargin] ;
-    mfun_page_hstep[RightMargin]          := mfun_page_hstep[RightMarginSeparator]+mfun_page_hsize[RightMarginSeparator] ;
-    mfun_page_hstep[LeftEdgeSeparator]    := mfun_page_hstep[LeftMargin]          -mfun_page_hsize[LeftEdgeSeparator] ;
-    mfun_page_hstep[LeftEdge]             := mfun_page_hstep[LeftEdgeSeparator]   -mfun_page_hsize[LeftEdge] ;
-    mfun_page_hstep[RightEdgeSeparator]   := mfun_page_hstep[RightMargin]         +mfun_page_hsize[RightMargin] ;
-    mfun_page_hstep[RightEdge]            := mfun_page_hstep[RightEdgeSeparator]  +mfun_page_hsize[RightEdgeSeparator] ;
+    mfun_page_hstep[mfun_page_odd][Text]                 := BackSpace ;
+    mfun_page_hstep[mfun_page_odd][LeftMarginSeparator]  := mfun_page_hstep[mfun_page_odd][Text]                -mfun_page_hsize[mfun_page_odd][LeftMarginSeparator] ;
+    mfun_page_hstep[mfun_page_odd][RightMarginSeparator] := mfun_page_hstep[mfun_page_odd][Text]                +mfun_page_hsize[mfun_page_odd][Text] ;
+    mfun_page_hstep[mfun_page_odd][LeftMargin]           := mfun_page_hstep[mfun_page_odd][LeftMarginSeparator] -mfun_page_hsize[mfun_page_odd][LeftMargin] ;
+    mfun_page_hstep[mfun_page_odd][RightMargin]          := mfun_page_hstep[mfun_page_odd][RightMarginSeparator]+mfun_page_hsize[mfun_page_odd][RightMarginSeparator] ;
+    mfun_page_hstep[mfun_page_odd][LeftEdgeSeparator]    := mfun_page_hstep[mfun_page_odd][LeftMargin]          -mfun_page_hsize[mfun_page_odd][LeftEdgeSeparator] ;
+    mfun_page_hstep[mfun_page_odd][LeftEdge]             := mfun_page_hstep[mfun_page_odd][LeftEdgeSeparator]   -mfun_page_hsize[mfun_page_odd][LeftEdge] ;
+    mfun_page_hstep[mfun_page_odd][RightEdgeSeparator]   := mfun_page_hstep[mfun_page_odd][RightMargin]         +mfun_page_hsize[mfun_page_odd][RightMargin] ;
+    mfun_page_hstep[mfun_page_odd][RightEdge]            := mfun_page_hstep[mfun_page_odd][RightEdgeSeparator]  +mfun_page_hsize[mfun_page_odd][RightEdgeSeparator] ;
 enddef ;
 
+numeric mfun_last_changed_page ; mfun_last_changed_page := -1 ;
+boolean mfun_page_done_odd     ; mfun_page_done_odd     := false ;
+boolean mfun_page_done_even    ; mfun_page_done_even    := false ;
+
+def mfun_check_page_dimensions_indeed =
+    mfun_page_check_vsize ;
+    mfun_page_check_hsize ;
+    mfun_page_check_vstep ;
+    mfun_page_check_hstep ;
+enddef ;
+
 def mfun_check_page_dimensions =
-    if mfun_page_done <> RealPageNumber :
-        if LayoutHasChanged :
-            mfun_page_check_vsize ;
-            mfun_page_check_hsize ;
-            mfun_page_check_vstep ;
-            mfun_page_check_hstep ;
+    begingroup ;
+    save n ; n := LastChangedLayoutPage ;
+    SwapMarginDimensions ; % always
+    if mfun_last_changed_page <> n :
+        report("page", "layout changed") ;
+        mfun_page_done_odd := false ;
+        mfun_page_done_even := false ;
+        mfun_last_changed_page := n ;
+    fi ;
+    if odd RealPageNumber :
+        mfun_page_odd := 1 ;
+        if not mfun_page_done_odd :
+            report("page", "checking odd") ;
+            mfun_check_page_dimensions_indeed ;
+            mfun_page_done_odd := true ;
         fi ;
-        mfun_page_done := RealPageNumber ;
+    else :
+        mfun_page_odd := 2 ;
+        if not mfun_page_done_even :
+            report("page", "checking even") ;
+            mfun_check_page_dimensions_indeed ;
+            mfun_page_done_even := true ;
+        fi ;
     fi ;
+    endgroup ;
 enddef;
 
-
 def mfun_check_page_area =
     mfun_check_page_dimensions ;
     for VerPos=Top step 10 until Bottom:
         for HorPos=LeftEdge step 1 until RightEdge:
-            mfun_page_area[HorPos][VerPos] := unitsquare xscaled mfun_page_hsize[HorPos] yscaled mfun_page_vsize[VerPos] ;
-            mfun_page_area[VerPos][HorPos] := mfun_page_area[HorPos][VerPos] ;
+            mfun_page_area[mfun_page_odd][HorPos][VerPos] := unitsquare xscaled mfun_page_hsize[mfun_page_odd][HorPos] yscaled mfun_page_vsize[where][VerPos] ;
+            mfun_page_area[mfun_page_odd][VerPos][HorPos] := mfun_page_area[mfun_page_odd][HorPos][VerPos] ;
         endfor ;
     endfor ;
 enddef ;
@@ -137,8 +163,8 @@
     mfun_check_page_dimensions ;
     for VerPos=Top step 10 until Bottom:
         for HorPos=LeftEdge step 1 until RightEdge:
-            mfun_page_location[HorPos][VerPos] := (mfun_page_hstep[HorPos],mfun_page_vstep[VerPos]) ;
-            mfun_page_location[VerPos][HorPos] := mfun_page_location[HorPos][VerPos] ;
+            mfun_page_location[mfun_page_odd][HorPos][VerPos] := (mfun_page_hstep[mfun_page_odd][HorPos],mfun_page_vstep[mfun_page_odd][VerPos]) ;
+            mfun_page_location[mfun_page_odd][VerPos][HorPos] := mfun_page_location[mfun_page_odd][HorPos][VerPos] ;
         endfor ;
     endfor ;
 enddef ;
@@ -147,19 +173,19 @@
     mfun_check_page_dimensions ;
     for VerPos=Top step 10 until Bottom:
         for HorPos=LeftEdge step 1 until RightEdge:
-            mfun_page_field[HorPos][VerPos] := unitsquare xscaled mfun_page_hsize[HorPos] yscaled mfun_page_vsize[VerPos] shifted (mfun_page_hstep[HorPos],mfun_page_vstep[VerPos]) ;
-            mfun_page_field[VerPos][HorPos] := mfun_page_field[HorPos][VerPos] ;
+            mfun_page_field[mfun_page_odd][HorPos][VerPos] := unitsquare xscaled mfun_page_hsize[mfun_page_odd][HorPos] yscaled mfun_page_vsize[mfun_page_odd][VerPos] shifted (mfun_page_hstep[mfun_page_odd][HorPos],mfun_page_vstep[mfun_page_odd][VerPos]) ;
+            mfun_page_field[mfun_page_odd][VerPos][HorPos] := mfun_page_field[mfun_page_odd][HorPos][VerPos] ;
         endfor ;
     endfor ;
 enddef ;
 
-def Area     = hide(mfun_check_page_area       ;) mfun_page_area     enddef ;
-def Location = hide(mfun_check_page_location   ;) mfun_page_location enddef ;
-def Field    = hide(mfun_check_page_field      ;) mfun_page_field    enddef ;
-def Vsize    = hide(mfun_check_page_dimensions ;) mfun_page_vsize    enddef ;
-def Hsize    = hide(mfun_check_page_dimensions ;) mfun_page_hsize    enddef ;
-def Vstep    = hide(mfun_check_page_dimensions ;) mfun_page_vstep    enddef ;
-def Hstep    = hide(mfun_check_page_dimensions ;) mfun_page_hstep    enddef ;
+def Area     = hide(mfun_check_page_area       ;) mfun_page_area    [mfun_page_odd] enddef ;
+def Location = hide(mfun_check_page_location   ;) mfun_page_location[mfun_page_odd] enddef ;
+def Field    = hide(mfun_check_page_field      ;) mfun_page_field   [mfun_page_odd] enddef ;
+def Vsize    = hide(mfun_check_page_dimensions ;) mfun_page_vsize   [mfun_page_odd] enddef ;
+def Hsize    = hide(mfun_check_page_dimensions ;) mfun_page_hsize   [mfun_page_odd] enddef ;
+def Vstep    = hide(mfun_check_page_dimensions ;) mfun_page_vstep   [mfun_page_odd] enddef ;
+def Hstep    = hide(mfun_check_page_dimensions ;) mfun_page_hstep   [mfun_page_odd] enddef ;
 
 immutable % permanent
     Area, Location, Field, Vsize, Hsize, Vstep, Hstep ;
@@ -222,9 +248,16 @@
     (unitsquare xyscaled (OverlayWidth,OverlayHeight))
 enddef ;
 
+def BoundToOverlayBox =
+    setbounds currentpicture to OverlayBox;
+enddef ;
+
 immutable % permanent
     OverlayBox ;
 
+permanent
+    BoundToOverlayBox ;
+
 % handy
 
 def innerenlarged =
@@ -254,43 +287,3 @@
 %         cycle
 %     )
 % enddef ;
-
-% for the moment we put these here:
-
-string  RuleDirection ; RuleDirection := "" ;
-string  RuleOption    ; RuleOption    := "" ;
-numeric RuleWidth     ; RuleWidth     := 0 ;
-numeric RuleHeight    ; RuleHeight    := 0 ;
-numeric RuleDepth     ; RuleDepth     := 0 ;
-numeric RuleH         ; RuleH         := 0 ;
-numeric RuleV         ; RuleV         := 0 ;
-numeric RuleThickness ; RuleThickness := 0 ;
-numeric RuleFactor    ; RuleFactor    := 0 ;
-numeric RuleOffset    ; RuleOffset    := 0 ;
-                    def RuleColor      = (.5white) enddef ; % yet undecided, might become a string
-
-def FakeWord(expr RuleWidth, RuleHeight, RuleDepth, RuleThickness) (text RuleColor) =
-    fill unitsquare
-        xscaled RuleWidth
-        yscaled (RuleDepth-RuleThickness/2)
-        withcolor RuleColor ;
-    fill unitsquare
-        xscaled RuleWidth
-        yscaled (RuleHeight-RuleDepth-RuleThickness/2)
-        shifted (0,RuleDepth+RuleThickness)
-        withcolor RuleColor ;
-enddef ;
-
-def FakeRule(expr RuleWidth, RuleHeight, RuleDepth, RuleThickness) (text RuleColor) =
-    fill unitsquare
-        xscaled RuleWidth
-        yscaled RuleHeight
-        withcolor RuleColor ;
-enddef ;
-
-mutable
-    RuleDirection, RuleOption, RuleWidth, RuleHeight, RuleDepth, RuleH, RuleV, RuleThickness,
-    RuleFactor, RuleOffset, RuleColor;
-
-permanent
-    FakeWord, FakeRule ;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-text.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-text.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-text.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -18,7 +18,8 @@
 newinternal boolean metafun_loaded_text ; metafun_loaded_text := true ; immutable metafun_loaded_text ;
 
 % This is still mostly the same as the one discussed in the good old \METAFUN\
-% example code but modernized abit to suit \LMTX.
+% example code but modernized abit to suit \LMTX. We can actually use \hsplit
+% now!
 
 newscriptindex mfid_setparshapeproperty ; mfid_setparshapeproperty := scriptindex "setparshapeproperty" ;
 
@@ -123,9 +124,9 @@
         save a, b; pair a, b ;
         a := pat intersection_point (lin shifted (0,strutheight)) ;
         if intersection_found :
-        a := a shifted (0,-strutheight) ;
+            a := a shifted (0,-strutheight) ;
         else :
-        a := pat intersection_point lin ;
+            a := pat intersection_point lin ;
         fi ;
         b := pat intersection_point (lin shifted (0,-strutdepth)) ;
         if intersection_found :

Modified: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-tool.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-tool.mpxl	2023-02-26 14:38:27 UTC (rev 66173)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-tool.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -32,7 +32,7 @@
 
 % newinternal metapostversion ; metapostversion := scantokens(mpversion) ;
 
-newinternal metapostversion ; metapostversion := 2.0 ; permanent metapostversion ;
+newinternal metapostversion ; metapostversion := 3.0 ; permanent metapostversion ;
 
 %D We always want \EPS\ conforming output, so we say:
 
@@ -142,12 +142,6 @@
 
 %D Colors:
 
-newinternal nocolormodel   ; nocolormodel   := 1 ;
-newinternal greycolormodel ; greycolormodel := 3 ;
-newinternal graycolormodel ; graycolormodel := 3 ;
-newinternal rgbcolormodel  ; rgbcolormodel  := 5 ;
-newinternal cmykcolormodel ; cmykcolormodel := 7 ;
-
 let grayscale = graycolor ;
 let greyscale = greycolor ;
 
@@ -262,7 +256,7 @@
 enddef ;
 
 def finishsavingdata =
-    lua.mp.mf_finish_saving_data() ;
+  % lua.mp.mf_finish_saving_data() ;
 enddef ;
 
 %D Instead of a keystroke eating save and allocation sequence, you can use the \quote
@@ -332,26 +326,53 @@
 % let push_boundingbox = pushboundingbox ; % downward compatible
 % let pop_boundingbox  = popboundingbox  ; % downward compatible
 
-vardef boundingbox primary p =
-    if (path p) or (picture p) :
-        llcorner p -- lrcorner p -- urcorner p -- ulcorner p
-    else :
-        origin
-    fi -- cycle
-enddef;
+% vardef boundingbox primary p =
+%     if (path p) or (picture p) :
+%         llcorner p -- lrcorner p -- urcorner p -- ulcorner p
+%     else :
+%         origin
+%     fi -- cycle
+% enddef;
 
+% vardef boundingbox primary p =
+%     if (path p) or (picture p) :
+%         save a, b ; pair a, b ; a := llcorner p ; b:= urcorner p ;
+%         a -- (xpart b, ypart a) -- b -- (xpart a, ypart b)
+%     else :
+%         origin
+%     fi -- cycle
+% enddef;
+
+% vardef innerboundingbox primary p =
+%     top  rt llcorner p --
+%     top lft lrcorner p --
+%     bot lft urcorner p --
+%     bot  rt ulcorner p -- cycle
+% enddef;
+
+% vardef outerboundingbox primary p =
+%     bot lft llcorner p --
+%     bot  rt lrcorner p --
+%     top  rt urcorner p --
+%     top lft ulcorner p -- cycle
+% enddef;
+
+let boundingbox = corners ;
+
 vardef innerboundingbox primary p =
-    top  rt llcorner p --
-    top lft lrcorner p --
-    bot lft urcorner p --
-    bot  rt ulcorner p -- cycle
+    save b ; path b ; b := corners p ;
+    top  rt point 0 of b --
+    top lft point 1 of b --
+    bot lft point 2 of b --
+    bot  rt point 3 of b -- cycle
 enddef;
 
 vardef outerboundingbox primary p =
-    bot lft llcorner p --
-    bot  rt lrcorner p --
-    top  rt urcorner p --
-    top lft ulcorner p -- cycle
+    save b ; path b ; b := corners p ;
+    bot lft point 0 of b --
+    bot  rt point 1 of b --
+    top  rt point 2 of b --
+    top lft point 3 of b -- cycle
 enddef;
 
 % def inner_boundingbox = innerboundingbox enddef ;
@@ -375,11 +396,12 @@
 
 vardef boundingradius primary p =
     if picture p :
+        pair c ; c := -center p;
         max(
-            abs((llcorner p) shifted -center p),
-            abs((lrcorner p) shifted -center p),
-            abs((urcorner p) shifted -center p),
-            abs((ulcorner p) shifted -center p)
+            abs((llcorner p) shifted c),
+            abs((lrcorner p) shifted c),
+            abs((urcorner p) shifted c),
+            abs((ulcorner p) shifted c)
         )
     elseif pen p :
         boundingradius image(draw makepath p ;)
@@ -551,21 +573,30 @@
 enddef ;
 
 def mfun_tool_striped_set_options(expr option) =
-    save isinner, swapped ;
-    boolean isinner, swapped ;
-    if option = 1 :
+    save isinner, swapped, isdrawn ;
+    boolean isinner, swapped, isdrawn ;
+    if option = 0 :
+        isdrawn := true;
+        isinner := true ;
+        swapped := false ;
+    elseif option = 1 :
+        isdrawn := false ;
         isinner := false ;
         swapped := false ;
     elseif option = 2 :
+        isdrawn := false ;
         isinner := true ;
         swapped := false ;
     elseif option = 3 :
+        isdrawn := false ;
         isinner := false ;
         swapped := true ;
     elseif option = 4 :
+        isdrawn := false ;
         isinner := true ;
         swapped := true ;
     else :
+        isdrawn := false ;
         isinner := false ;
         swapped := false ;
     fi ;
@@ -572,7 +603,7 @@
 enddef ;
 
 vardef mfun_tool_striped_number(expr option, p, asked_n, asked_slot) text extra =
-    image (
+%     image (
         begingroup ;
         save pattern, shape, bounds, penwidth, used_n, used_slot ;
         picture pattern, shape ; path bounds ; numeric used_s, used_slot ;
@@ -601,7 +632,9 @@
                 endfor ;
             fi ;
         ) ;
-        if swapped :
+        if isdrawn :
+            addto currentpicture also pattern ;
+        elseif swapped :
             addto currentpicture also shape ;
             addto currentpicture also pattern ;
         else :
@@ -609,18 +642,26 @@
             addto currentpicture also shape ;
         fi ;
         endgroup ;
-    )
+%     )
 enddef ;
 
+% def mfun_tool_striped_angle_action text extra =
+%     for i = minimum -.5used_gap step used_gap until maximum :
+%         draw (minimum,i) -- (maximum,i) extra ;
+%     endfor ;
+%     currentpicture := currentpicture rotated used_angle ;
+% enddef ;
+
 def mfun_tool_striped_angle_action text extra =
     for i = minimum -.5used_gap step used_gap until maximum :
-        draw (minimum,i) -- (maximum,i) extra ;
+        nodraw (minimum,i) -- (maximum,i) extra ;
     endfor ;
+    dodraw origin ;
     currentpicture := currentpicture rotated used_angle ;
 enddef ;
 
 vardef mfun_tool_striped_angle(expr option, p, asked_angle, asked_gap) text extra =
-    image (
+%     image (
         begingroup ;
         save pattern, shape, mask, maximum, minimum, centrum, used_angle, used_gap ;
         picture pattern, shape, mask ; numeric maximum, minimum ; pair centrum ; numeric used_angle, used_gap ;
@@ -628,17 +669,22 @@
         used_angle := if asked_angle = 0 : stripe_angle else : asked_angle fi ;
         used_gap := if asked_gap = 0 : stripe_gap else : asked_gap fi ;
         shape := image(draw p) ;
-        centrum := center shape ;
+      % centrum := center shape ;
+        centrum := llcorner shape ;
         shape := shape shifted - centrum ;
         mask := shape rotated used_angle ;
         maximum := max (xpart llcorner mask, xpart urcorner mask, ypart llcorner mask, ypart urcorner mask) ;
         minimum := min (xpart llcorner mask, xpart urcorner mask, ypart llcorner mask, ypart urcorner mask) ;
+        % a hack:
+maximum := maximum + max(xpart urcorner shape, ypart urcorner shape);
+minimum := minimum - max(xpart urcorner shape, ypart urcorner shape);
+        %
         pattern := image (
             if isinner :
                 mfun_tool_striped_angle_action extra ;
                 for s within shape :
                     if stroked s or filled s :
-                        clip currentpicture to pathpart s ;
+                       clip currentpicture to pathpart s ;
                     fi
                 endfor ;
             else :
@@ -652,7 +698,9 @@
                 endfor ;
             fi ;
         ) ;
-        if swapped :
+        if isdrawn :
+            addto currentpicture also pattern ;
+        elseif swapped :
             addto currentpicture also shape ;
             addto currentpicture also pattern ;
         else :
@@ -661,7 +709,7 @@
         fi ;
         currentpicture := currentpicture shifted centrum ;
         endgroup ;
-    )
+%     )
 enddef;
 
 newinternal striped_normal_inner  ; striped_normal_inner  := 1 ;
@@ -670,11 +718,13 @@
 newinternal striped_reverse_outer ; striped_reverse_outer := 4 ;
 
 secondarydef p anglestriped s =
-    mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)
+  % mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)
+    image(mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)) % for 'withcolor'
 enddef ;
 
 secondarydef p numberstriped s =
-    mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)
+  % mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)
+    image(mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)) % for 'withcolor'
 enddef ;
 
 % for old times sake:
@@ -695,22 +745,91 @@
     draw image(asked_draw asked_path asked_text) anglestriped(3,0,0) asked_spec ;
 enddef ;
 
+%D A more efficient variant by Mikael:
+
+% path p ; p := fullcircle scaled 3cm && (unitsquare scaled 2cm shifted (4cm,4cm)) && cycle ;
+% draw hatch(p,30,0.2cm) ; draw p ;
+
+vardef hatch(expr p, a, d) =
+    save thestripe, diag, b ; picture thestripe ; numeric diag ; path b ;
+    b := boundingbox p;
+    diag := 0.55 * ( abs((urcorner b) - (llcorner b)) ) ;
+    thestripe := image (
+        draw (-diag,0) -- (diag, 0) &&
+        for i = d step d until diag:
+            (-diag, i) -- (diag, i) &&
+            (-diag,-i) -- (diag,-i) &&
+        endfor nocycle
+        withpen currentpen ;
+    ) ;
+    thestripe := thestripe shifted center b ;
+    thestripe := thestripe rotatedaround(center b, a) ;
+    clip thestripe to p ;
+    thestripe
+enddef ;
+
 %D A few normalizing macros:
 
+% primarydef p xsized w =
+%     (p if (bbwidth (p) > 0) and (w > 0) : scaled (w/bbwidth (p)) fi)
+% enddef ;
+% primarydef p xsized w =
+%     begingroup
+%     save b, l ; path b;
+%     b := corners p ;
+%     l := xpart point 1 of b - xpart point 0 of b ;
+%     (p if (l > 0) and (w > 0) : scaled (w/l) fi)
+%     endgroup
+% enddef ;
 primarydef p xsized w =
-    (p if (bbwidth (p) > 0) and (w > 0) : scaled (w/bbwidth (p)) fi)
+    begingroup
+    save r, l ; pair r;
+    r := xrange p ;
+    l := ypart r - xpart r ;
+    (p if (l > 0) and (w > 0) : scaled (w/l) fi)
+    endgroup
 enddef ;
 
+% primarydef p ysized h =
+%     (p if (bbheight(p) > 0) and (h > 0) : scaled (h/bbheight(p)) fi)
+% enddef ;
+% primarydef p ysized h =
+%     begingroup
+%     save b, l ; path b;
+%     b := corners p ;
+%     l := ypart point 2 of b - ypart point 1 of b ;
+%     (p if (l > 0) and (h > 0) : scaled (h/l) fi)
+%     endgroup
+% enddef ;
 primarydef p ysized h =
-    (p if (bbheight(p) > 0) and (h > 0) : scaled (h/bbheight(p)) fi)
+    begingroup
+    save r, l ; pair r ;
+    r := yrange p ;
+    l := ypart r - xpart r ;
+    (p if (l > 0) and (h > 0) : scaled (h/l) fi)
+    endgroup
 enddef ;
 
-primarydef p xysized s =
+% primarydef p xysized s = % a one step transform might be faster
+%     begingroup
+%     save wh, w, h ; pair wh ; numeric w, h ;
+%     wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ;
+%     p
+%         if (w > 0) and (h > 0) :
+%             if xpart wh > 0 : xscaled (xpart wh/w) fi
+%             if ypart wh > 0 : yscaled (ypart wh/h) fi
+%         fi
+%     endgroup
+% enddef ;
+primarydef p xysized s = % a one step transform might be faster
     begingroup
-    save wh, w, h ; pair wh ; numeric w, h ;
-    wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ;
+    save wh, w, h, b ; pair wh ; path b;
+    b := corners p ;
+    w := xpart point 1 of b - xpart point 0 of b ;
+    h := ypart point 2 of b - ypart point 1 of b ;
+    wh := paired (s) ;
     p
-        if (w>0) and (h>0) :
+        if (w > 0) and (h > 0) :
             if xpart wh > 0 : xscaled (xpart wh/w) fi
             if ypart wh > 0 : yscaled (ypart wh/h) fi
         fi
@@ -717,10 +836,130 @@
     endgroup
 enddef ;
 
+% to be tested
+%
+% primarydef p xysized s =
+%     begingroup
+%     save wh, w, h ; pair wh ; numeric w, h ;
+%     wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ;
+%     if (w > 0) and (h > 0) :
+%         transform t ; t := identity if xpart wh > 0 : xscaled (xpart wh/w) fi if ypart wh > 0 : yscaled (ypart wh/h)
+%     fi ;
+%     p if (w > 0) and (h > 0) : transformed t fi
+%     endgroup
+% enddef ;
+
 let sized = xysized ;
 
 permanent xsized, ysized, xysized, sized ;
 
+% primarydef p xynormalized s =
+%     begingroup
+%     save w, h ; numeric w, h ;
+%     w := bbwidth(p) ;
+%     h := bbheight(p) ;
+%     if (w > 0) and (h > 0) :
+%         save t, wh ; transform t ; pair wh ;
+%         wh := paired (s) ;
+%         t := identity
+%             shifted - llcorner p
+%             if xpart wh > 0 : xscaled (xpart wh/w) fi
+%             if ypart wh > 0 : yscaled (ypart wh/h) fi
+%         ;
+%         p transformed t
+%     else :
+%         p
+%     fi
+%     endgroup
+% enddef ;
+primarydef p xynormalized s =
+    begingroup save w, h, b ; path b;
+    b := corners p ;
+    w := xpart point 1 of b - xpart point 0 of b ;
+    h := ypart point 2 of b - ypart point 1 of b ;
+    if (w > 0) and (h > 0) :
+        save t, wh ; transform t ; pair wh ;
+        wh := paired (s) ;
+        t := identity
+            shifted - llcorner p
+            if xpart wh > 0 : xscaled (xpart wh/w) fi
+            if ypart wh > 0 : yscaled (ypart wh/h) fi
+        ;
+        p transformed t
+    else :
+        p
+    fi
+    endgroup
+enddef ;
+
+% primarydef p xnormalized s =
+%     begingroup
+%     save w ; numeric w ;
+%     w := bbwidth(p) ;
+%     if (w > 0) :
+%         save t ; transform t ;
+%         t := identity
+%             shifted - llcorner p
+%             if s > 0 : xscaled (s/w) fi
+%         ;
+%         p transformed t
+%     else :
+%         p
+%     fi
+%     endgroup
+% enddef ;
+primarydef p xnormalized s =
+    begingroup save h, r ; pair r ;
+    r := xrange p ;
+    w := ypart r - xpart r ;
+    if (w > 0) :
+        save t ; transform t ;
+        t := identity
+            shifted - llcorner p
+            if s > 0 : xscaled (s/w) fi
+        ;
+        p transformed t
+    else :
+        p
+    fi
+    endgroup
+enddef ;
+
+% primarydef p ynormalized s =
+%     begingroup
+%     save h ; numeric h ;
+%     h := bbheight(p) ;
+%     if (h > 0) :
+%         save t ; transform t ;
+%         t := identity
+%             shifted - llcorner p
+%             if s > 0 : yscaled (s/h) fi
+%         ;
+%         p transformed t
+%     else :
+%         p
+%     fi
+%     endgroup
+% enddef ;
+primarydef p ynormalized s =
+    begingroup save h, r ; pair r ;
+    r := yrange p ;
+    h := ypart r - xpart r ;
+    if (h > 0) :
+        save t ; transform t ;
+        t := identity
+            shifted - llcorner p
+            if s > 0 : yscaled (s/h) fi
+        ;
+        p transformed t
+    else :
+        p
+    fi
+    endgroup
+enddef ;
+
+permanent xnormalized, ynormalized, xynormalized ;
+
 % def xscale_currentpicture(expr w) = % obsolete
 %     currentpicture := currentpicture xsized w ;
 % enddef;
@@ -757,10 +996,10 @@
 
 path tcircle, bcircle, lcircle, rcircle ;
 
-tcircle = origin -- (+.5,0) & (+.5,0) {up}    .. (0,+.5) .. {down}  (-.5,0) -- cycle ;
-bcircle = origin -- (-.5,0) & (-.5,0) {down}  .. (0,-.5) .. {up}    (+.5,0) -- cycle ;
-lcircle = origin -- (0,+.5) & (0,+.5) {left}  .. (-.5,0) .. {right} (0,-.5) -- cycle ;
-rcircle = origin -- (0,-.5) & (0,-.5) {right} .. (+.5,0) .. {left}  (0,+.5) -- cycle ;
+tcircle := origin -- (+.5,0) & (+.5,0) {up}    .. (0,+.5) .. {down}  (-.5,0) -- cycle ;
+bcircle := origin -- (-.5,0) & (-.5,0) {down}  .. (0,-.5) .. {up}    (+.5,0) -- cycle ;
+lcircle := origin -- (0,+.5) & (0,+.5) {left}  .. (-.5,0) .. {right} (0,-.5) -- cycle ;
+rcircle := origin -- (0,-.5) & (0,-.5) {right} .. (+.5,0) .. {left}  (0,+.5) -- cycle ;
 
 path urtriangle, ultriangle, lltriangle, lrtriangle ; % watch out: it's contrary to what you expect and starts in the origin
 
@@ -783,6 +1022,17 @@
 unitdiamond := (.5,0) -- (1,.5) -- (.5,1) -- (0,.5) -- cycle ;
 fulldiamond := unitdiamond shifted - center unitdiamond ;
 
+path unitoctagon, fulloctagon ;
+
+unitoctagon := for i within (unitcircle rotated 45/2) : pathpoint -- endfor cycle ;
+fulloctagon := unitoctagon shifted - center unitoctagon ;
+
+path unithexagon, fullhexagon ;
+
+%%%%hexagon := for i = 0 upto 5 : .5dir (60i) -- endfor cycle ;
+fullhexagon := for i = 0 step 60 until 360 : .5 dir(i) -- endfor cycle ;
+unithexagon := fullhexagon shifted (.5,.5) ;
+
 permanent
     fullsquare, unitcircle,
     urcircle, ulcircle, llcircle, lrcircle,
@@ -789,7 +1039,7 @@
     tcircle, bcircle, lcircle, rcircle,
     urtriangle, ultriangle, lltriangle, lrtriangle,
     triangle, uptriangle, downtriangle, lefttriangle, righttriangle,
-    unitdiamond, fulldiamond ;
+    unitdiamond, fulldiamond, unitoctagon, fulloctagon, unithexagon, fullhexagon ;
 
 %D More robust:
 
@@ -852,12 +1102,11 @@
 
 %D usage: \type{innerpath peepholed outerpath}.
 %D
-%D beginfig(1);
-%D   def fullsquare = (unitsquare shifted -center unitsquare) enddef ;
+%D \startMPcode
 %D   fill (fullsquare scaled 200) withcolor red ;
 %D   path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ;
 %D   fill p peepholed bbox p ;
-%D endfig;
+%D \stopMPcode
 
 secondarydef p peepholed q =
     begingroup
@@ -1100,11 +1349,24 @@
     fi
 ) enddef ;
 
+% vardef laddered primary p = % was expr
+%     point 0 of p
+%     for i=1 upto length(p) :
+%         -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p)
+%     endfor
+% enddef ;
+
 vardef laddered primary p = % was expr
-    point 0 of p
-    for i=1 upto length(p) :
-        -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p)
+    save a; pair a ; a := point 0 of p ; a --
+    for i within p :
+        if i > 0 : (xpart pathpoint, ypart a) -- pathpoint -- fi
+        hide(a := pathpoint)
     endfor
+    if cycle p :
+        (xpart point 0 of p, ypart a) -- point 0 of p -- cycle
+    else :
+        nocycle
+    fi
 enddef ;
 
 permanent crossed, laddered ;
@@ -1150,19 +1412,56 @@
     endgroup
 enddef ;
 
+% vardef mfun_randomized_path(expr p,s) =
+%     for i=0 upto length(p)-1 :
+%          (point       i    of p) .. controls
+%         ((postcontrol i    of p) randomshifted s) and
+%         ((precontrol (i+1) of p) randomshifted s) ..
+%     endfor
+%     if cycle p :
+%         cycle
+%     else :
+%         (point length(p) of p)
+%     fi
+% enddef;
+%
+% Here is a Mikael Sundqvist improved version. This time we also use
+% some new functionality.
+
 vardef mfun_randomized_path(expr p,s) =
-    for i=0 upto length(p)-1 :
-         (point       i    of p) .. controls
-        ((postcontrol i    of p) randomshifted s) and
-        ((precontrol (i+1) of p) randomshifted s) ..
-    endfor
-    if cycle p :
-        cycle
-    else :
-        (point length(p) of p)
-    fi
-enddef;
+    save r, oldr, newr, firstr, l ; pair r, oldr, newr, firstr ;
+    r := paired(s) ;
+    l := length(p) ;
+    newr := (-1/2+uniformdeviate(1),-1/2+uniformdeviate(1)) xyscaled r ;
+    firstr := newr ;
+    for i within p :
+        hide (
+            oldr := newr ;
+            newr := (-1/2+uniformdeviate(1),-1/2+uniformdeviate(1)) xyscaled r ;
+        )
+        pathpoint ..
+        controls  (pathpostcontrol shifted oldr )
+        and      ((deltaprecontrol 1) shifted if (i <> l - 1) : - newr else : - firstr fi) ..
+    endfor if cycle p : cycle else : nocycle fi
+enddef ;
 
+
+vardef mfun_randomrotated_path(expr p, s) =
+    save r, oldr, newr, firstr, l ;
+    l := length(p) ;
+    newr := (-1/2+uniformdeviate(1))*s ;
+    firstr := newr ;
+    for i within p :
+        hide (
+            oldr := newr ;
+            newr := (-1/2+uniformdeviate(1)) * s ;
+        )
+        pathpoint ..
+        controls  (pathpostcontrol rotatedaround(pathpoint, oldr) )
+        and      ((deltaprecontrol 1) rotatedaround(deltapoint 1, if (i <> l - 1) : newr else : firstr fi)) ..
+    endfor if cycle p : cycle else : nocycle fi
+enddef ;
+
 vardef mfun_randomized_picture(expr p,s)(text rnd) =
     save currentpicture ;
     picture currentpicture ;
@@ -1200,6 +1499,16 @@
     fi
 ) enddef ;
 
+primarydef p randomrotatedcontrols s = (
+    if path p :
+        mfun_randomrotated_path(p,s)
+    elseif picture p :
+        mfun_randomized_picture(p,s)(randomrotatedcontrols)
+    else :
+        p randomized s
+    fi
+) enddef ;
+
 primarydef p randomized s = (
     if path p :
         for i=0 upto length(p)-1 :
@@ -1253,7 +1562,8 @@
     fi
 ) enddef ;
 
-permanent superellipsed, squeezed, randomshifted, randomized, randomizedcontrols ;
+permanent superellipsed, squeezed, randomshifted, randomized,
+    randomizedcontrols, randomrotatedcontrols ;
 
 %D Not perfect (alternative for interpath)
 
@@ -1502,22 +1812,33 @@
 def drawpointlabels   expr c = path temp_c ; temp_c := c ; mfun_draw_pointlabels   enddef ;
 
 def mfun_draw_points text t =
-    for i=0 upto length(temp_c) if cycle temp_c : -1 fi :
-        normaldraw point i of temp_c mfun_opt_pnt t ;
+%     for i=0 upto length(temp_c) if cycle temp_c : -1 fi :
+%         normaldraw point i of temp_c mfun_opt_pnt t ;
+%     endfor ;
+    for i within temp_c :
+        normaldraw pathpoint mfun_opt_pnt t ;
     endfor ;
 enddef;
 
 def mfun_draw_controlpoints text t =
-    for i=0 upto length(temp_c) :
-        normaldraw precontrol  i of temp_c mfun_opt_ctr t ;
-        normaldraw postcontrol i of temp_c mfun_opt_ctr t ;
+%     for i=0 upto length(temp_c) :
+%         normaldraw precontrol  i of temp_c mfun_opt_ctr t ;
+%         normaldraw postcontrol i of temp_c mfun_opt_ctr t ;
+%     endfor ;
+    for i within temp_c :
+        normaldraw pathprecontrol  t mfun_opt_ctr t ;
+        normaldraw pathpostcontrol t mfun_opt_ctr t ;
     endfor ;
 enddef;
 
 def mfun_draw_controllines text t =
-    for i=0 upto length(temp_c) :
-        normaldraw point i of temp_c -- precontrol  i of temp_c mfun_opt_lin t ;
-        normaldraw point i of temp_c -- postcontrol i of temp_c mfun_opt_lin t ;
+%     for i=0 upto length(temp_c) :
+%         normaldraw point i of temp_c -- precontrol  i of temp_c mfun_opt_lin t ;
+%         normaldraw point i of temp_c -- postcontrol i of temp_c mfun_opt_lin t ;
+%     endfor ;
+    for i within temp_c :
+        normaldraw pathpoint -- pathprecontrol  t mfun_opt_lin t ;
+        normaldraw pathpoint -- pathpostcontrol t mfun_opt_lin t ;
     endfor ;
 enddef;
 
@@ -1526,6 +1847,7 @@
 string  pointlabelfont  ; pointlabelfont  := "" ;
 
 def mfun_draw_pointlabels text asked_options =
+    % todo: for i within temp_c : pathdirection
     for i=0 upto length(temp_c) if cycle temp_c : -1 fi :
         pair temp_u ; temp_u := unitvector(direction i of temp_c) rotated if swappointlabels : - fi 90 ;
         pair temp_p ; temp_p := (point i of temp_c) ;
@@ -2575,8 +2897,25 @@
     endfor cycle)
 enddef ;
 
-permanent smoothed, cornered ;
+% Mikael Sundqvist came up with this one. We made it robust for points being too close
+% for smoothing.
 
+primarydef p smoothcornered c =
+    ( begingroup ;
+        save cc ;
+        if not cycle p: (point 0 of p) -- fi
+        for i=1 upto length(p) :
+            hide (cc := min(c,arclength (subpath(i-1,i) of p)/2);)
+            (point i-1 of p) shifted (cc*(unitvector(point i   of p - point i-1 of p))) --
+            (point i   of p) shifted (cc*(unitvector(point i-1 of p - point i   of p))) ..
+            controls point i of p ..
+        endfor
+        if cycle p : cycle else : point 1 along p fi
+    endgroup )
+enddef ;
+
+permanent smoothed, cornered, smoothcornered ;
+
 % cmyk color support
 
 % vardef cmyk(expr c,m,y,k) = % elsewhere
@@ -2596,12 +2935,31 @@
 %         0
 %     fi
 % enddef ;
-
+% vardef bbwidth primary p =
+%     if unknown p :
+%         0
+%     elseif path p or picture p :
+%         xpart (lrcorner p - llcorner p)
+%     else :
+%         0
+%     fi
+% enddef ;
+% vardef bbwidth primary p =
+%     if unknown p :
+%         0
+%     elseif path p or picture p :
+%         save b ; path b; b := corners p ;
+%         xpart point 0 of b - xpart point 1 of b
+%     else :
+%         0
+%     fi
+% enddef ;
 vardef bbwidth primary p =
     if unknown p :
         0
     elseif path p or picture p :
-        xpart (lrcorner p - llcorner p)
+        save r ; pair r ; r := xrange p ;
+        ypart r - xpart r
     else :
         0
     fi
@@ -2618,12 +2976,31 @@
 %         0
 %     fi
 % enddef ;
-
+% vardef bbheight primary p =
+%     if unknown p :
+%         0
+%     elseif path p or picture p :
+%         ypart (urcorner p - lrcorner p)
+%     else :
+%         0
+%     fi
+% enddef ;
+% vardef bbheight primary p =
+%     if unknown p :
+%         0
+%     elseif path p or picture p :
+%         save b ; path b; b := corners p ;
+%         ypart point 2 of b - ypart point 1 of b
+%     else :
+%         0
+%     fi
+% enddef ;
 vardef bbheight primary p =
     if unknown p :
         0
     elseif path p or picture p :
-        ypart (urcorner p - lrcorner p)
+        save r ; pair r ; r := yrange p ;
+        ypart r - xpart r
     else :
         0
     fi
@@ -2782,16 +3159,20 @@
 
 % an improved plain mp macro
 
+% vardef center primary p =
+%     if pair p :
+%         p
+%     else :
+%         .5[llcorner p, urcorner p]
+%     fi
+% enddef;
+%
+% permanent center ;
+
 vardef center primary p =
-    if pair p :
-        p
-    else :
-        .5[llcorner p, urcorner p]
-    fi
-enddef;
+    centerof p
+enddef ;
 
-permanent center ;
-
 % new, yet undocumented
 
 vardef rangepath (expr p, d, a) =
@@ -3006,12 +3387,28 @@
 
 %D New too:
 
+% primarydef p xstretched w = (
+%     p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi
+% ) enddef ;
+%
+% primarydef p ystretched h = (
+%     p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi
+% ) enddef ;
+
 primarydef p xstretched w = (
-    p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi
+    begingroup save l, r ; pair r;
+    r := xrange p ;
+    l := ypart r - xpart r ;
+    p if (l > 0) and (w > 0) : xscaled (w/l) fi
+    endgroup
 ) enddef ;
 
 primarydef p ystretched h = (
-    p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi
+    begingroup save l, r ; pair r;
+    r := yrange p ;
+    l := ypart r - xpart r ;
+    p if (l > 0) and (h > 0) : yscaled (h/l) fi
+    endgroup
 ) enddef ;
 
 permanent xstretched, ystretched ;
@@ -3651,7 +4048,7 @@
     not (p insideof q)
 enddef ;
 
-permanent crossingdebug, crossingscale, crossingnumberm, infotext, crossingunder, insideof, outsideof ;
+permanent crossingdebug, crossingscale, crossingnumbermax, infotext, crossingunder, insideof, outsideof ;
 
 %D Also handy:
 
@@ -3792,8 +4189,24 @@
     t
 enddef ;
 
-permanent totransform, bymatrix ;
+% vardef bytopdownmatrix(expr rx, sx, sy, ry, tx, ty) =
+%     save t ; transform t ;
+%     xxpart t =  rx ; yypart t =  ry ;
+%     xypart t = -sy ; yxpart t = -sx ;
+%     xpart  t =  tx ; ypart  t =  ty ;
+%     t
+% enddef ;
 
+vardef closedcurve primary p =
+    p if (path p and not cycle p) or (pair p) : .. cycle fi
+enddef ;
+
+vardef closedlines primary p =
+    p if (path p and not cycle p) or (pair p) : -- cycle fi
+enddef ;
+
+permanent totransform, bymatrix, closedcurve, closedlines ;
+
 let xslanted = slanted ;
 
 def yslanted primary s =
@@ -3829,3 +4242,212 @@
 enddef ;
 
 permanent processpath ;
+
+% By Bogluslaw Jackowski (public domain):
+%
+% draw hatched (fullcircle scaled 10cm) (45, 4, 1) withcolor "red" ;
+
+newinternal hatch_match; hatch_match := 1;
+
+vardef hatched(expr o) primary c =
+    save a_, b_, d_, l_, i_, r_, za_, zb_, zc_, zd_;
+    path b_; picture r_; pair za_, zb_, zc_, zd_;
+    r_ := image (
+        a_ := redpart(c) mod 180 ;
+        l_ := greenpart(c) ;
+        d_ := -bluepart(c) ;
+        b_ := o rotated -a_ ;
+        b_ :=
+            if a_ >= 90 :
+                (lrcorner b_ -- llcorner b_ -- ulcorner b_ -- urcorner b_ -- cycle)
+            else :
+                (llcorner b_ -- lrcorner b_ -- urcorner b_ -- ulcorner b_ -- cycle)
+            fi
+            rotated a_ ;
+        za_ := point 0 of b_ ;
+        zb_ := point 1 of b_ ;
+        zc_ := point 2 of b_ ;
+        zd_ := point 3 of b_ ;
+        if hatch_match > 0 :
+            n_ := round(length(zd_-za_) / l_) ;
+            if n_ < 2:
+                n_ := 2 ;
+            fi ;
+            l_ := length(zd_-za_) / n_ ;
+        else :
+            n_ := length(zd_-za_) / l_ ;
+        fi
+        save currentpen; pen currentpen ; pickup pencircle scaled d_;
+        % we use a single path instead:
+        for i_ := if hatch_match > 0 : 1 else : 0 fi upto ceiling n_ - 1 :
+            nodraw (i_/n_)[zd_,za_] -- (i_/n_)[zc_,zb_] ;
+        endfor
+        dodraw origin ;
+    ) ;
+    clip r_ to o;
+    r_
+enddef;
+
+permanent hatched ;
+
+% By Mikael Sundqvist, with a little evolution:
+
+numeric mfun_dash_on, mfun_dash_off ;
+
+% primarydef p withdashes len =
+%     hide (
+%         save l, t, n, m ; pair t ;
+%         l := arclength p ;
+%         t := paired(len) ;
+%         m := xpart t + ypart t ;
+%         n := l / (l div m) / m ;
+%         mfun_dash_on  := n * xpart t ;
+%         mfun_dash_off := n * ypart t ;
+%     )
+%     p dashed dashpattern (on mfun_dash_on off mfun_dash_off)
+% enddef ;
+
+primarydef p withdashes len =
+    hide (
+        save l, t, n, m, don, doff; pair t ;
+        l := arclength p ;
+        t := paired (len) ;
+        m := xpart t + ypart t ;
+        n := (l if not cycle p : - xpart t fi) div m ;
+        (n if not cycle p : + 1 fi) * don + n * doff = l ;
+        don*(ypart t) = doff*(xpart t) ;
+        mfun_dash_on := don ;
+        mfun_dash_off := doff ;
+    )
+    p dashed dashpattern (on mfun_dash_on off mfun_dash_off)
+enddef ;
+
+permanent withdashes ;
+
+%D For Mikael:
+
+path mfun_b ;
+pair mfun_k ;
+
+path mfun_nullpath ;
+
+tertiarydef p sortedintersectiontimes q =
+    sortedpath (p intersectiontimeslist q)
+enddef ;
+
+tertiarydef p intersectionpath q =
+    begingroup ;
+    save mfun_b ; path mfun_b ; mfun_b := sortedpath (p intersectiontimeslist q) ;
+    save mfun_k ; pair mfun_k ; mfun_k := point 0 of mfun_b;
+    if mfun_k <> (-1,-1) :
+        .5[point xpart mfun_k of p, point ypart mfun_k of q]
+        for i = 1 upto length(mfun_b) :
+            hide(mfun_k := point i of mfun_b;)
+            -- .5[point xpart mfun_k of p, point ypart mfun_k of q]
+        endfor
+    else :
+        mfun_nullpath
+    fi
+    endgroup
+enddef ;
+
+tertiarydef p firstintersectionpath q =
+    begingroup ;
+    save mfun_b ; path mfun_b ; mfun_b := sortedpath (p intersectiontimeslist q) ;
+    if (point 0 of mfun_b) <> (-1,-1) :
+        point xpart (point 0 of mfun_b) of p
+        for i = 1 upto length(mfun_b) :
+            -- point xpart (point i of mfun_b) of p
+        endfor
+    else :
+        mfun_nullpath
+    fi
+    endgroup
+enddef ;
+
+tertiarydef p secondintersectionpath q =
+    q firstintersectionpath p
+enddef;
+
+vardef intersectionsfound expr p =
+    (point 0 of p) <> (-1,-1)
+enddef ;
+
+%D As part of our intersection journey MS came up with:
+
+tertiarydef p cutbeforefirst q =
+    begingroup ;
+    save mfun_b, mfun_p ; path mfun_b, mfun_p ; mfun_b := sortedpath (p intersectiontimeslist q) ;
+    if (point 0 of mfun_b) <> (-1,-1) :
+        mfun_p := subpath(xpart point 0 of mfun_b, length p) of p;
+    else :
+        mfun_p := p ;
+    fi ;
+    mfun_p
+    endgroup
+enddef ;
+
+tertiarydef p cutafterfirst q =
+    begingroup ;
+    save mfun_b, mfun_p ; path mfun_b, mfun_p ; mfun_b := sortedpath (p intersectiontimeslist q) ;
+    if (point 0 of mfun_b) <> (-1,-1) :
+        mfun_p := subpath(0, xpart point 0 of mfun_b) of p;
+    else :
+        mfun_p := p ;
+    fi ;
+    mfun_p
+    endgroup
+enddef ;
+
+
+tertiarydef p cutbeforelast q =
+    begingroup ;
+    save mfun_b, mfun_p ; path mfun_b, mfun_p ; mfun_b := sortedpath (p intersectiontimeslist q) ;
+    if (point 0 of mfun_b) <> (-1,-1) :
+        mfun_p := subpath(xpart point (length mfun_b) of mfun_b, length p) of p;
+    else :
+        mfun_p := p ;
+    fi ;
+    mfun_p
+    endgroup
+enddef ;
+
+tertiarydef p cutafterlast q =
+    begingroup ;
+    save mfun_b, mfun_p ; path mfun_b, mfun_p ; mfun_b := sortedpath (p intersectiontimeslist q) ;
+    if (point 0 of mfun_b) <> (-1,-1) :
+        mfun_p := subpath(0, xpart point (length mfun_b) of mfun_b) of p;
+    else :
+        mfun_p := p ;
+    fi ;
+    mfun_p
+    endgroup
+enddef ;
+
+% I don't want to define this path every time I make a demo:
+
+vardef starring(expr e) =
+    save a, b, c, d ;
+    pair a, b, c, d ;
+    a := (-1,-1) ; b := ( 1,-1) ;
+    c := ( 1, 1) ; d := (-1, 1) ;
+    a -- (.5[a,b] shifted (0,-e)) --
+    b -- (.5[b,c] shifted (e, 0)) --
+    c -- (.5[c,d] shifted (0, e)) --
+    d -- (.5[d,a] shifted (-e,0)) -- cycle
+enddef ;
+
+vardef dashing (expr pth, shp, stp) =
+    for i within arcpointlist stp of pth :
+        shp
+            rotated angle(pathdirection)
+            shifted pathpoint
+        &&
+    endfor nocycle
+enddef ;
+
+% like center, mod and div this is a candidate for a primitive
+
+% vardef centerofmass primary p =
+%     (origin for i within p : + pathpoint endfor) / length(p)
+% enddef ;

Added: trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-xbox.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-xbox.mpxl	                        (rev 0)
+++ trunk/Master/texmf-dist/metapost/context/base/mpxl/mp-xbox.mpxl	2023-02-26 14:42:15 UTC (rev 66174)
@@ -0,0 +1,332 @@
+% This file is a variant of "macros for boxes"::
+%
+% author    : Taco Hoekwater
+% version   : $Id: boxes.mp,v 1.5 2005/02/25 11:28:56 taco Exp $
+% copyright : Public domain
+% patched   : Hans Hagen
+%
+% author    : Karl Berry
+% version   : $Id: rboxes.mp,v 1.2 2004/09/19 21:47:11 karl Exp $
+% copyright : Public domain
+% patched   : Hans Hagen
+%
+% The code is the same but I've added a boxes_ namespace for some so that we don't
+% clash with metafun.
+
+% The code is the same but I've added s boxes_ namespace for soem so that we don't
+% clash with metafun. Loading and initialization is now under metafun control.
+
+if known metafun_loaded_xbox : endinput ; fi ;
+
+newinternal boolean metafun_loaded_xbox ; metafun_loaded_xbox := true ; immutable metafun_loaded_xbox ;
+
+% Find the length of the prefix of string s for which cond is true for each character
+% c of the prefix. Loading and initialization is now under metafun control. Only the
+% mpxl variant will be adapted. When needed this file will be adapted.
+
+vardef boxes_str_prefix (expr s) (text cond) =
+    save i_, c; string c; i_ = 0;
+    forever:
+        c := substring (i_, i_ + 1) of s;
+        exitunless cond;
+        exitif incr i_ = length s;
+    endfor
+    i_
+enddef;
+
+% Take a string returned by the str operator and return the same string with explicit
+% numeric subscripts replaced by generic subscript symbols [] (fixed by Eddie Kohler).
+
+vardef generisize (expr ss) =
+    save r, s, l; string r, s;
+    r = ""; % result so far
+    s = ss; % left to process
+    forever:
+        exitif s = "";
+        l := boxes_str_prefix(s, (c<>"[") and ((c<"0") or (c>"9")));
+        r := r & substring (0,l) of s;
+        s := substring (l, infinity) of s;
+        if s <> "" :
+            if (s >= "[") and (length s > 1) :
+                if (substring (1,2) of s) = "[" :
+                    l := 2;
+                    r := r & "[[";
+                else :
+                    l := 1 + boxes_str_prefix(s, c <> "]");
+                    r := r & "[]";
+                fi
+            else :
+                r := r & "[]";
+                l := boxes_str_prefix(s, (c = ".") or ("0" <= c) and (c <= "9"));
+            fi
+            s := substring(l, infinity) of s;
+        fi
+    endfor
+    r
+enddef;
+
+% Make sure the string boxes_n_gen is generisize(_n_):
+
+string boxes_n, boxes_n_cur, boxes_n_gen; boxes_n_cur := "]"; % this won't match _n_
+
+vardef boxes_set_n_gen =
+    if boxes_n <> boxes_n_cur:
+        boxes_n_cur := boxes_n;
+        boxes_n_gen := generisize(boxes_n);
+    fi
+enddef;
+
+% Given a type t and list of variable names vars, make sure that they are of type t
+% and redeclare them as necessary.  In the vars list _n represents scantokens boxes_n,
+% a suffix that might contain numeric subscripts. This suffix needs to be replaced
+% by scantokens boxes_n_gen in order to get a variable that can be declared to be of
+% type t.
+
+vardef boxes_declare(text t) text vars =
+    boxes_set_n_gen;
+    forsuffixes v_ = vars :
+        if forsuffixes _n = scantokens boxes_n : not t v_ endfor :
+            def boxes_gdmac text _n = t v_ enddef;
+            expandafter boxes_gdmac scantokens boxes_n_gen;
+        fi
+    endfor
+enddef;
+
+% Here is another version that redeclares the vars even if they are already of the
+% right type.
+
+vardef boxes_redeclare(text t) text vars =
+    boxes_set_n_gen;
+    def boxes_gdmac text _n = t vars enddef;
+    expandafter boxes_gdmac scantokens boxes_n_gen;
+enddef;
+
+% pp should be a string giving the name of a macro that finds the boundary path and
+% sp should be a string that names a macro for fixing the size and shape. The suffix
+% $ is the name of the box. The text t gives the box contents: either empty, a
+% picture, or a string to typeset.
+
+def boxes_begin (expr pp, sp) (suffix $) (text t) =
+    boxes_n := str $;
+    boxes_declare (pair) _n.off, _n.c;
+    boxes_declare (string) boxes_pproc._n, boxes_sproc._n;
+    boxes_declare (picture) boxes_pic._n;
+    boxes_pproc$ := pp;
+    boxes_sproc$ := sp;
+    boxes_pic$ := nullpicture;
+    for _p_ = t :
+      % boxes_pic$ := if picture _p_: _p_ else: _p_ infont defaultfont scaled defaultscale fi;
+        boxes_pic$ := if picture _p_: _p_ else: textext(_p_) fi;
+    endfor
+    $c = $off + .5[llcorner boxes_pic$, urcorner boxes_pic$]
+enddef;
+
+% The suffix cl names a vardef macro that clears box-related variables. The suffix $
+% is the name of the box being ended.
+
+def boxes_end(suffix cl, $) =
+    if known boxes_pic.boxes_prevbox:
+        boxes_dojoin(boxes_prevbox,$);
+    fi
+    def boxes_prevbox = $ enddef;
+    expandafter def expandafter boxes_clear_all expandafter =
+        boxes_clear_all cl($);
+    enddef
+enddef;
+
+% Text t gives equations for joining box a to box b.
+
+def boxes_boxjoin(text t) =
+    def boxes_prevbox = _ enddef;
+    def boxes_dojoin(suffix a,b) = t enddef;
+enddef ;
+
+def boxes_clear_all = enddef;
+
+% Given a list of box names, give whatever default values are necessary
+% in order to fix the size and shape of each box.
+
+vardef boxes_fixsize(text t) =
+    forsuffixes $ = t : scantokens boxes_sproc$($); endfor
+enddef;
+
+% Given a list of box names, give default values for any unknown positioning offsets.
+
+vardef boxes_fixpos(text t) =
+    forsuffixes $=t:
+        if unknown xpart $.off : xpart $.off = 0; fi
+        if unknown ypart $.off : ypart $.off = 0; fi
+    endfor
+enddef;
+
+% Return the boundary path for the given box
+
+vardef bpath suffix $ =
+    boxes_fixsize($);
+    boxes_fixpos($);
+    scantokens boxes_pproc$($)
+enddef;
+
+% Return the contents of the given box. First define a private version that the user can't
+% accidently clobber.
+
+vardef boxes_pic_mac suffix $ =
+    boxes_fixsize($);
+    boxes_fixpos($);
+    boxes_pic$ shifted $off
+enddef;
+
+vardef pic suffix $ = boxes_pic_mac $ enddef;
+
+% Draw each box:
+
+def drawboxed(text t) =
+    boxes_fixsize(t);
+    boxes_fixpos(t);
+    forsuffixes s = t: draw boxes_pic_mac.s; draw bpath.s; endfor
+enddef;
+
+% Draw contents of each box:
+
+def drawunboxed(text t) =
+    boxes_fixsize(t);
+    boxes_fixpos(t);
+    forsuffixes s = t :
+        draw boxes_pic_mac.s;
+    endfor
+enddef;
+
+% Draw boundary path for each box:
+
+def drawboxes(text t) =
+    forsuffixes s = t :
+        draw bpath.s;
+    endfor
+enddef;
+
+% Rectangular boxes
+
+newinternal defaultdx, defaultdy; defaultdx := defaultdy := 3bp;
+
+vardef boxit@#(text tt) =
+    boxes_begin("boxes_path","boxes_size",@#,tt);
+    boxes_declare (pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w;
+    0 = xpart(@#nw - @#sw) = ypart(@#se - @#sw);
+    0 = xpart(@#ne - @#se) = ypart(@#ne - @#nw);
+    @#w = .5[@#nw,@#sw];
+    @#s = .5[@#sw,@#se];
+    @#e = .5[@#ne,@#se];
+    @#n = .5[@#ne,@#nw];
+    @#ne - @#c = @#c - @#sw = (@#dx,@#dy) + .5*(urcorner boxes_pic@# - llcorner boxes_pic@#);
+    boxes_end(boxes_clear,@#);
+enddef;
+
+def boxes_path(suffix $) =
+    $.sw -- $.se -- $.ne -- $.nw -- cycle
+enddef;
+
+def boxes_size(suffix $) =
+    if unknown $.dx : $.dx = defaultdx; fi
+    if unknown $.dy : $.dy = defaultdy; fi
+enddef;
+
+vardef boxes_clear(suffix $) =
+    boxes_n := str $;
+    boxes_redeclare(numeric) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w, _n.c, _n.off, _n.dx, _n.dy;
+enddef;
+
+% Circular and oval boxes
+
+newinternal circmargin; circmargin := 2bp;  % default clearance for picture corner
+
+vardef circleit@#(text tt) =
+    boxes_begin("boxes_the_circle","boxes_size_circle",@#,tt);
+    boxes_declare(pair) _n.n, _n.s, _n.e, _n.w;
+    @#e - @#c = @#c - @#w = (@#dx,0) + .5*(lrcorner boxes_pic@# - llcorner boxes_pic@#);
+    @#n - @#c = @#c - @#s = (0,@#dy) + .5*(ulcorner boxes_pic@# - llcorner boxes_pic@#);
+    boxes_end(boxes_clear_circle,@#);
+enddef;
+
+def boxes_the_circle (suffix $) =
+    $.e{up} ... $.n{left} ... $.w{down} ... $.s{right} ... cycle
+enddef;
+
+vardef boxes_clear_circle (suffix $) =
+    boxes_n := str $;
+    boxes_redeclare(numeric) _n.n, _n.s, _n.e, _n.w, _n.c, _n.off, _n.dx, _n.dy;
+enddef;
+
+vardef boxes_size_circle (suffix $) =
+    save a_, b_;
+    (a_,b_) = .5*(urcorner boxes_pic$ - llcorner boxes_pic$);
+    if unknown $dx :
+        if unknown $dy :
+            if unknown($dy-$dx) :
+                a_ + $dx = b_ + $dy;
+            fi
+            if a_ + $dx = b_ + $dy :
+                a_ + $dx = a_ ++ b_ + circmargin;
+            else :
+                $dx = boxes_select(max(a_,b_ + $dx - $dy), (a_ + d_,0){up} ... (0,b_ + d_ + $dy - $dx){left});
+            fi
+        else :
+            $dx = boxes_select(a_, (a_ + d_,0){up}...(0,b_ + $dy){left});
+        fi
+    elseif unknown $dy :
+        $dy = boxes_select(b_, (a_ + $dx,0){up}...(0,b_ + d_){left});
+    fi
+enddef;
+
+vardef boxes_select(expr dhi)(text tt) =
+    save f_, p_; path p_;
+    p_ = origin .. (a_,b_) + circmargin * unitvector(a_,b_);
+    vardef f_ (expr d_) =
+        xpart((tt) intersectiontimes p_) >= 0
+    enddef;
+    solve f_(0, dhi + 1.5circmargin)
+enddef;
+
+def boxes_init_all =
+    boxes_boxjoin();
+    save boxes_pic, boxes_sproc, boxes_pproc;
+    def boxes_clear_all = enddef;
+enddef ;
+
+def boxjoin(text t) =
+    def boxes_prevbox = _ enddef;
+    def boxes_dojoin(suffix a,b) = t enddef;
+enddef;
+
+extra_beginfig := extra_beginfig & "boxes_init_all;";
+extra_endfig   := "boxes_clear_all;" & extra_endfig;
+
+if makingfigure :
+    boxes_init_all;
+fi ;
+
+% Rectangular boxes with rounded corners
+
+newinternal rbox_radius ; rbox_radius := 8bp ;
+
+vardef rboxit@#(text tt) =
+    boxes_begin("boxes_the_rounded","boxes_size",@#,tt) ;
+    boxes_declare (pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w ;
+    0 = xpart(@#nw - @#sw) = ypart(@#se - @#sw) ;
+    0 = xpart(@#ne - @#se) = ypart(@#ne - @#nw) ;
+    @#w = .5[@#nw,@#sw] ;
+    @#s = .5[@#sw,@#se] ;
+    @#e = .5[@#ne,@#se] ;
+    @#n = .5[@#ne,@#nw] ;
+    @#ne - @#c = @#c - @#sw = (@#dx,@#dy) + .5*(urcorner boxes_pic@# - llcorner boxes_pic@#) ;
+    boxes_end(boxes_clear,@#) ;
+enddef;
+
+def boxes_the_rounded(suffix $) =
+    save _r ; _r = min(rbox_radius, .5*ypart($.n-$.s), .5*xpart($.e-$.w));
+    $.sw + (_r,0) {right} .. {right} $.se - (_r,0) ..
+    $.se + (0,_r)    {up} .. {up}    $.ne - (0,_r) ..
+    $.ne - (_r,0)  {left} .. {left}  $.nw + (_r,0) ..
+    $.nw - (0,_r)  {down} .. {down}  $.sw + (0,_r) ..
+    cycle
+enddef;
+



More information about the tex-live-commits mailing list.