summaryrefslogtreecommitdiff
path: root/metapost/context/base
diff options
context:
space:
mode:
Diffstat (limited to 'metapost/context/base')
-rw-r--r--metapost/context/base/metafun.mpiv5
-rw-r--r--metapost/context/base/mp-bare.mpiv93
-rw-r--r--metapost/context/base/mp-base.mpii19
-rw-r--r--metapost/context/base/mp-base.mpiv95
-rw-r--r--metapost/context/base/mp-chem.mpiv115
-rw-r--r--metapost/context/base/mp-form.mpiv2
-rw-r--r--metapost/context/base/mp-func.mpiv33
-rw-r--r--metapost/context/base/mp-grap.mpiv336
-rw-r--r--metapost/context/base/mp-luas.mpiv99
-rw-r--r--metapost/context/base/mp-mlib.mpiv571
-rw-r--r--metapost/context/base/mp-page.mpiv522
-rw-r--r--metapost/context/base/mp-tool.mpii2683
-rw-r--r--metapost/context/base/mp-tool.mpiv218
13 files changed, 2934 insertions, 1857 deletions
diff --git a/metapost/context/base/metafun.mpiv b/metapost/context/base/metafun.mpiv
index a113675e6..b1d4f32e7 100644
--- a/metapost/context/base/metafun.mpiv
+++ b/metapost/context/base/metafun.mpiv
@@ -15,10 +15,14 @@
%D prevent dependency problems and in the end even may use a patched version,
%D we prefer to use a copy.
+prologues := 0 ;
+mpprocset := 1 ;
+
input "mp-base.mpiv" ;
input "mp-tool.mpiv" ;
input "mp-mlib.mpiv" ;
% "mp-core.mpiv" ; % todo: namespace and cleanup
+input "mp-luas.mpiv" ; % experimental
input "mp-page.mpiv" ; % todo: namespace and cleanup
input "mp-butt.mpiv" ; % todo: namespace and cleanup
input "mp-shap.mpiv" ; % will be improved
@@ -46,6 +50,7 @@ let normalend = end ;
if known mplib :
def end = ; message "" ; message metafunversion ; message "" ; endinput ; enddef ;
+ def bye = ; message "" ; message metafunversion ; message "" ; endinput ; enddef ;
else :
def end = ; message "" ; message metafunversion ; message "" ; normalend ; enddef ;
fi ;
diff --git a/metapost/context/base/mp-bare.mpiv b/metapost/context/base/mp-bare.mpiv
new file mode 100644
index 000000000..c6194b1ee
--- /dev/null
+++ b/metapost/context/base/mp-bare.mpiv
@@ -0,0 +1,93 @@
+%D \module
+%D [ file=mp-bare.mpiv,
+%D version=2014.10.31,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=plain plugins,
+%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 licen-en.pdf for
+%C details.
+
+if known context_bare : endinput ; fi ;
+boolean context_bare ; context_bare := true ;
+
+numeric mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ;
+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 ;
+ mfun_trial_run := false ;
+fi ;
+
+if unknown mfun_first_run :
+ boolean mfun_first_run ;
+ mfun_first_run := true ;
+fi ;
+
+def mfun_reset_tex_texts =
+ mfun_tt_n := 0 ;
+ mfun_tt_p := nullpicture ;
+ mfun_tt_o := nullpicture ; % redundant
+ mfun_tt_c := nullpicture ; % redundant
+enddef ;
+
+def mfun_flush_tex_texts =
+ addto currentpicture also mfun_tt_p
+enddef ;
+
+extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ;
+extra_endfig := "mfun_flush_tex_texts ; mfun_reset_tex_texts ; " & extra_endfig ;
+
+vardef colordecimals primary c =
+ if cmykcolor c :
+ decimal cyanpart c & ":" & decimal magentapart c & ":" & decimal yellowpart c & ":" & decimal blackpart c
+ elseif rgbcolor c :
+ decimal redpart c & ":" & decimal greenpart c & ":" & decimal bluepart c
+ else :
+ decimal c
+ fi
+enddef ;
+
+vardef rawtextext(expr str) = % todo: avoid currentpicture
+ if str = "" :
+ nullpicture
+ else :
+ mfun_tt_n := mfun_tt_n + 1 ;
+ mfun_tt_c := nullpicture ;
+ if mfun_trial_run :
+ mfun_tt_o := nullpicture ;
+ addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
+ addto mfun_tt_c doublepath unitsquare
+ withprescript "tx_number=" & decimal mfun_tt_n
+ withprescript "tx_stage=trial"
+ withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
+ withpostscript str ;
+ addto mfun_tt_p also mfun_tt_c ;
+ elseif known mfun_tt_d[mfun_tt_n] :
+ addto mfun_tt_c doublepath unitsquare
+ xscaled mfun_tt_w[mfun_tt_n]
+ yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n])
+ shifted (0,-mfun_tt_d[mfun_tt_n])
+ withprescript "tx_number=" & decimal mfun_tt_n
+ withprescript "tx_stage=final" ;
+ else :
+ addto mfun_tt_c doublepath unitsquare ; % unitpicture
+ fi ;
+ mfun_tt_c
+ fi
+enddef ;
+
+primarydef str infont name = % nasty hack
+ if name = "" :
+ rawtextext(str)
+ else :
+ rawtextext("\definedfont[" & name & "]" & str)
+ fi
+enddef ;
+
diff --git a/metapost/context/base/mp-base.mpii b/metapost/context/base/mp-base.mpii
index 0f8104447..7af4bc436 100644
--- a/metapost/context/base/mp-base.mpii
+++ b/metapost/context/base/mp-base.mpii
@@ -110,12 +110,15 @@ transform identity;
for z=origin,right,up: z transformed identity = z; endfor
% color constants
-color black, white, red, green, blue, background;
+color black, white, red, green, blue, cyan, magenta, yellow, background;
black = (0,0,0);
white = (1,1,1);
red = (1,0,0);
green = (0,1,0);
blue = (0,0,1);
+cyan = (0,1,1);
+magenta = (1,0,1);
+yellow = (1,1,0);
background = white; % The user can reset this
% color part selection for within
@@ -360,9 +363,17 @@ enddef;
def filldraw expr c =
addto currentpicture contour c withpen currentpen
_op_ enddef;
-def drawdot expr z =
- addto currentpicture contour makepath currentpen shifted z
- _op_ enddef;
+% def drawdot expr z =
+% addto currentpicture contour makepath currentpen shifted z
+% _op_ enddef;
+
+def drawdot expr p =
+ if pair p :
+ addto currentpicture doublepath p withpen currentpen _op_
+ else :
+ errmessage("drawdot only accepts a pair expression")
+ fi
+enddef ;
def unfill expr c = fill c withcolor background enddef;
def undraw expr p = draw p withcolor background enddef;
diff --git a/metapost/context/base/mp-base.mpiv b/metapost/context/base/mp-base.mpiv
index 2887cc462..28eb57fb8 100644
--- a/metapost/context/base/mp-base.mpiv
+++ b/metapost/context/base/mp-base.mpiv
@@ -195,7 +195,8 @@ yellow := (1,1,0) ;
background := white ; % obsolete
let graypart = greypart ;
-let graycolor = greycolor ;
+let greycolor = numeric ;
+let graycolor = numeric ;
% color part (will be overloaded)
@@ -323,7 +324,7 @@ primarydef w dotprod z =
enddef ;
primarydef x**y =
- if y=2 :
+ if y = 2 :
x*x
else :
takepower y of x
@@ -348,11 +349,46 @@ def takepower expr y of x =
endfor
fi
else :
- hide(errmessage "Undefined power: " & decimal x&"**"&decimal y)
+ hide(errmessage "Undefined power: " & decimal x & "**" & decimal y)
fi
fi
enddef ;
+% for big number systems:
+%
+% primarydef x**y =
+% if y = 1 :
+% x
+% elseif y = 2 :
+% x*x
+% elseif y = 3 :
+% x*x*x
+% else :
+% takepower y of x
+% fi
+% enddef ;
+%
+% vardef takepower expr y of x =
+% if (x=0) and (y>0) :
+% 0
+% else :
+% 1
+% if y = floor y :
+% if y >= 0 :
+% for n=1 upto y :
+% *x
+% endfor
+% else :
+% for n=-1 downto y :
+% /x
+% endfor
+% fi
+% else :
+% hide(errmessage "Undefined power: " & decimal x & "**" & decimal y)
+% fi
+% fi
+% enddef ;
+
vardef direction expr t of p =
postcontrol t of p - precontrol t of p
enddef ;
@@ -594,8 +630,36 @@ def filldraw expr c =
addto currentpicture contour c withpen currentpen _op_
enddef ;
-def drawdot expr z =
- addto currentpicture contour makepath currentpen shifted z _op_
+% def drawdot expr z =
+% addto currentpicture contour makepath currentpen shifted z _op_
+% enddef ;
+%
+% testcase DEK:
+%
+% for j=1 upto 9 :
+% pickup pencircle xscaled .4 yscaled .2 ;
+% drawdot (10j,0) withpen pencircle xscaled .5j yscaled .25j rotated 45 ;
+% pickup pencircle xscaled .5j yscaled .25j rotated 45 ;
+% drawdot (10j,10);
+% endfor ;
+%
+% or:
+%
+%\startMPpage
+%
+% def drawdot expr z =
+% addto currentpicture contour (makepath currentpen shifted z) _op_
+% enddef;
+%
+% drawdot origin shifted (0,-3cm) withpen pencircle scaled 2cm ;
+% pickup pencircle scaled 2cm ; drawdot origin withcolor red ;
+
+def drawdot expr p =
+ if pair p :
+ addto currentpicture doublepath p withpen currentpen _op_
+ else :
+ errmessage("drawdot only accepts a pair expression")
+ fi
enddef ;
def unfill expr c = fill c withcolor background enddef ;
@@ -651,10 +715,10 @@ enddef ;
def pen_pickup_ primary q =
currentpen := q ;
- pen_lft :=xpart penoffset down of currentpen ;
- pen_rt :=xpart penoffset up of currentpen ;
- pen_top :=ypart penoffset left of currentpen ;
- pen_bot :=ypart penoffset right of currentpen ;
+ pen_lft := xpart penoffset down of currentpen ;
+ pen_rt := xpart penoffset up of currentpen ;
+ pen_top := ypart penoffset left of currentpen ;
+ pen_bot := ypart penoffset right of currentpen ;
path currentpen_path ;
enddef ;
@@ -670,7 +734,8 @@ vardef savepen =
pen_count_
enddef ;
-def clearpen = currentpen:=nullpen;
+def clearpen =
+ currentpen := nullpen;
pen_lft := pen_rt := pen_top := pen_bot := 0 ;
path currentpen_path ;
enddef ;
@@ -801,7 +866,7 @@ vardef labels@#(text t) =
endfor
enddef ;
-% til lhere
+% till lhere
vardef dotlabels@#(text t) =
forsuffixes $=t:
@@ -817,17 +882,19 @@ vardef penlabels@#(text t) =
endfor
enddef ;
+% range 4 thru 10
+
def range expr x =
- numtok[x]
+ _numtok_[x]
enddef ;
-def numtok suffix x =
+def _numtok_ suffix x =
x
enddef ;
tertiarydef m thru n =
m for x=m+1 step 1 until n :
- , numtok[x]
+ , _numtok_[x]
endfor
enddef ;
diff --git a/metapost/context/base/mp-chem.mpiv b/metapost/context/base/mp-chem.mpiv
index 2addb0a73..b861d3f12 100644
--- a/metapost/context/base/mp-chem.mpiv
+++ b/metapost/context/base/mp-chem.mpiv
@@ -11,7 +11,8 @@
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
%C details.
-%D This module is incomplete and experimental.
+%D This module is incomplete and experimental. Okay, it's not that bad but we do need
+%D some disclaimer.
% either consistent setting or not
@@ -24,7 +25,7 @@ numeric
chem_text_min, chem_text_max,
chem_rotation, chem_adjacent, chem_stack_n,
chem_substituent, chem_substituent.lft, chem_substituent.rt,
- chem_setting_offset, chem_text_offset, chem_picture_offset,
+ chem_setting_offset, chem_text_offset,
chem_center_offset, chem_dbl_offset,
chem_bb_angle, chem_axis_rulethickness,
chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b,
@@ -72,19 +73,18 @@ chem_axis_rulethickness := 1pt ;
chem_emwidth := 10pt ; % EmWidth or \the\emwidth does not work...
chem_b_length := 3 chem_emwidth ;
chem_text_offset := -.3chem_emwidth ; % -.71chem_emwidth ; % 1/sqrt(2)
-chem_center_offset := .5 chem_emwidth ;
-chem_picture_offset := chem_emwidth ;
+chem_center_offset := .5chem_emwidth ;
chem_dbl_offset := .05 ;
chem_bb_angle := angle(1,2chem_dbl_offset) ;
chem_text_min := 0.75 ;
chem_text_max := 1.25 ;
-chem_dot_factor := 4 ; % *linewidth
+chem_dot_factor := 2 ; % *linewidth
chem_sb_pair := (0.25,0.75) ; %chem_sb_dash := dashpattern(off 0.25 on 0.5 off 0.25) ;
chem_sb_pair.m := (0.25,1 ) ; %chem_sb_dash.m := dashpattern(off 0.25 on 0.75) ;
chem_sb_pair.p := (0 ,0.75) ; %chem_sb_dash.p := dashpattern(on 0.75 off 0.25) ;
-chem_sb_pair.b := (0, 1 ) ; %chem_sb_dash.b := dashpattern(on 1) ;
+chem_sb_pair.b := (0 ,1 ) ; %chem_sb_dash.b := dashpattern(on 1) ;
-chem_bd_wedge := false ; % true is incorrect, but quite common...
+chem_bd_wedge := true ; % according to IUPAC 2005
def chem_reset =
chem_rotation := 0 ;
@@ -132,6 +132,8 @@ vardef chem_init_some (suffix $) (expr e) =
fi
if not chem_star[$] :
scaled (.5/(sind .5chem_num1))
+ % carbon-carbon benzene bond length
+ scaled (1.4/1.54)
fi ;
fi ;
@@ -149,7 +151,7 @@ vardef chem_init_some (suffix $) (expr e) =
chem_num2 := i ;
fi
endfor)
- scaled (2*(abs(point chem_num2+.5 of chem_b_path[$]) - chem_dbl_offset))
+ scaled (2*(abs(point chem_num2+.5 of chem_b_path[$]) - 2chem_dbl_offset))
fi ;
chem_r_path[$] :=
@@ -301,17 +303,20 @@ enddef ;
chem_init_all ; % WHY does this not work unless defined and then called?
-
% Like most often in ConTeXt, we will trap but then silently ignore mistaken use,
% unless of course the error be too harmful...
% \startchemical
-def chem_start_structure(expr i, l, r, t, b, rotation, unit, factor, offset, axis, rulethickness, axiscolor) =
+def chem_start_structure(expr i, l, r, t, b, rotation, unit, bond, scale, offset, axis, rulethickness, axiscolor) =
save chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b ;
- chem_emwidth := unit ;
- chem_b_length := factor * unit ;
+ chem_emwidth := unit ; % dynamically set for each structure.
+ chem_text_offset := -.3chem_emwidth ; % -.71chem_emwidth ; % 1/sqrt(2)
+ chem_center_offset := .5chem_emwidth ;
+ chem_b_length := chem_emwidth * bond * scale ;
+ % scale (normally 1) scales the structure but not the text.
+
if numeric l :
chem_setting_l := -l ;
fi
@@ -526,6 +531,17 @@ vardef chem_set (suffix $) =
% This is a fairly complicated optimization and ajustement. It took some
% thinking to get right, so beware!
+ % And then even more time fixing a bug of a rotation +- half the symmetry
+ % angle of a structure depending on the scale and/or the font size
+ % (through chem_b_length).
+
+ % first save the symmetry angle of the structure (as in chem_rot):
+ chem_num0 := if chem_stacked[$] : 3 else : 0 fi ;
+ chem_num9 := if chem_tetra[$] : 360 else :
+ abs(angle(point 0+chem_num0 of chem_b_path[$]) -
+ angle(point 1+chem_num0 of chem_b_path[$]))
+ fi ;
+
if (chem_adjacent<>0) and chem_star[P] and chem_star[$] :
% nop
chem_adjacent := 0 ;
@@ -578,7 +594,8 @@ vardef chem_set (suffix $) =
-((point (chem_adjacent-1) of chem_b_path[P]) chem_transformed(P)) ;
fi
% adjust the bond angles
- chem_rotation := (chem_rotation + angle(chem_pair1)-angle(chem_pair3)) mod 360 ;
+ chem_num4 := (angle(chem_pair1)-angle(chem_pair3)) zmod chem_num9 ;
+ chem_rotation := chem_rotation + chem_num4 ;
if not chem_star[$] :
chem_pair4 :=
if chem_star[P] :
@@ -663,7 +680,8 @@ vardef chem_set (suffix $) =
fi
endfor
if not chem_front[$] : % adjust rotation
- chem_rotation := (chem_rotation + angle(chem_pair1)-angle(chem_pair3)) mod 360 ;
+ chem_num4 := angle(chem_pair1)-angle(chem_pair3) ;
+ chem_rotation := (chem_rotation + chem_num4) mod 360 ;
fi ;
chem_t := identity chem_transformed($) ;
chem_pair4 := (point chem_num3 of chem_b_path[$]) transformed chem_t ;
@@ -671,6 +689,9 @@ vardef chem_set (suffix $) =
currentpicture := currentpicture shifted chem_pair4 ;
chem_origin := chem_origin shifted chem_pair4 ;
fi
+ if not chem_front[$] : % adjust rotation
+ chem_rotation := chem_rotation zmod chem_num9 ;
+ fi
fi
chem_substituent := 0 ;
fi ;
@@ -798,28 +819,39 @@ vardef chem_eb@# (suffix $) (expr f, t, r, c) = % EB
enddef ;
vardef chem_ad@# (suffix $) (expr f, t, r, c) = % AD
- if not chem_star[$] :
- chem_t := identity chem_transformed($) ;
- for i=f upto t :
- chem_drawarrow(
- ((subpath (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$])
- paralleled 2chem_dbl_offset) transformed chem_t,
- r,c,) ;
- endfor
- fi
+ chem_t := identity chem_transformed($) ;
+ for i=f upto t :
+ chem_drawarrow(
+ (
+ (subpath
+ if chem_star[$] :
+ chem_sb_pair@# of chem_r_fragment($,i)
+ ) paralleled 5chem_dbl_offset
+ else :
+ (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$]
+ ) paralleled 2chem_dbl_offset
+ fi
+ ) transformed chem_t,
+ r,c,) ;
+ endfor
enddef ;
vardef chem_au@# (suffix $) (expr f, t, r, c) = % AU
- if not chem_star[$] :
- chem_t := identity chem_transformed($) ;
- for i=f upto t :
- chem_drawarrow(
- reverse(
- (subpath (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$])
- paralleled 2chem_dbl_offset) transformed chem_t,
- r,c,) ;
- endfor
- fi
+ chem_t := identity chem_transformed($) ;
+ for i=f upto t :
+ chem_drawarrow(
+ ((reverse
+ subpath
+ if chem_star[$] :
+ chem_sb_pair@# of chem_r_fragment($,i)
+ ) paralleled -5chem_dbl_offset
+ else :
+ (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$]
+ ) paralleled -2chem_dbl_offset
+ fi
+ ) transformed chem_t,
+ r,c,) ;
+ endfor
enddef ;
vardef chem_es@# (suffix $) (expr f, t, r, c) = % ES
@@ -1004,6 +1036,15 @@ enddef ;
vardef chem_hb@# (suffix $) (expr f, t, r, c) = % HB
if chem_star[$] :
chem_rh@#($,f,t,r,c)
+ else :
+ chem_t := identity chem_transformed($) ;
+ for i=f upto t :
+ chem_draw(
+ (subpath (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$])
+ transformed chem_t,
+ chem_dot_factor*r,c,dashed withdots scaled ((.5chem_b_length/3)/5bp)) ;
+ % not symmetric - needs to be tweaked...
+ endfor
fi
enddef ;
@@ -1548,9 +1589,9 @@ vardef chem_rot (suffix $) (expr d, s) = % ROT
chem_rotation := 0
else :
chem_num0 := if chem_stacked[$] : 3 else : 0 fi ;
- chem_num1 := .5(angle(point d+chem_num0 of chem_b_path[$]) -
+ chem_num1 := .5(angle(point d+chem_num0 of chem_b_path[$]) -
angle(point d+chem_num0-1 of chem_b_path[$])) ;
- chem_rotation := (chem_rotation + s*chem_num1) mod 360 ;
+ chem_rotation := (chem_rotation + s*chem_num1) zmod 360 ;
fi
fi
enddef ;
@@ -1561,7 +1602,7 @@ vardef chem_mir (suffix $) (expr d, s) = % MIR
if not chem_front[$] :
if d=0 : % inversion
if chem_mirror=origin :
- chem_rotation := (chem_rotation + 180*s) mod 360 ;
+ chem_rotation := (chem_rotation + 180*s) zmod 360 ;
else :
chem_mirror := chem_mirror rotated 90 ;
fi
@@ -1577,7 +1618,7 @@ vardef chem_mir (suffix $) (expr d, s) = % MIR
chem_num0 := -360 - chem_num0 ;
fi
chem_num0 := chem_num0 * s ;
- chem_rotation := (chem_rotation + 2chem_num0) mod 360 ;
+ chem_rotation := (chem_rotation + 2chem_num0) zmod 360 ;
chem_mirror := origin ;
fi
fi
diff --git a/metapost/context/base/mp-form.mpiv b/metapost/context/base/mp-form.mpiv
index b58792e1a..88b15e097 100644
--- a/metapost/context/base/mp-form.mpiv
+++ b/metapost/context/base/mp-form.mpiv
@@ -27,4 +27,4 @@ string Fmfont_ ; Fmfont_ := "crap" ;
vardef mfun_format_number(expr fmt, i) =
"\ctxlua{metapost.formatnumber('" & fmt & "'," & if string i : i else : decimal i fi & ")}"
-enddef
+enddef ;
diff --git a/metapost/context/base/mp-func.mpiv b/metapost/context/base/mp-func.mpiv
index 58df711f2..b1b9d6d5d 100644
--- a/metapost/context/base/mp-func.mpiv
+++ b/metapost/context/base/mp-func.mpiv
@@ -23,30 +23,36 @@ mfun_pathconnectors[0] := "," ;
mfun_pathconnectors[1] := "--" ;
mfun_pathconnectors[2] := ".." ;
mfun_pathconnectors[3] := "..." ;
+mfun_pathconnectors[4] := "---" ;
def pathconnectors = mfun_pathconnectors enddef ;
vardef mfun_function (expr f) (expr u, t, b, e, s) =
save x ; numeric x ;
+ save c ; string c ; c := if string f : f else : mfun_pathconnectors[f] fi ;
for xx := b step s until e :
hide (x := xx ;)
if xx > b :
- scantokens(mfun_pathconnectors[f])
+ scantokens(c)
fi
(scantokens(u),scantokens(t))
endfor
enddef ;
-def function = mfun_function enddef ; % let doesn't work here
-def punkedfunction = mfun_function (1) enddef ;
-def curvedfunction = mfun_function (2) enddef ;
-def tightfunction = mfun_function (3) enddef ;
+def function = mfun_function enddef ; % let doesn't work here
+def constructedfunction = mfun_function enddef ;
+def straightfunction = mfun_function (1) enddef ;
+def curvedfunction = mfun_function (2) enddef ;
+
+% def punkedfunction = mfun_function (1) enddef ; % same as straightfunction
+% def tightfunction = mfun_function (3) enddef ; % same as curvedfunction
vardef mfun_constructedpath (expr f) (text t) =
save ok ; boolean ok ; ok := false ;
+ save c ; string c ; c := if string f : f else : mfun_pathconnectors[f] fi ;
for i=t :
if ok :
- scantokens(mfun_pathconnectors[f])
+ scantokens(c)
else :
ok := true ;
fi
@@ -55,24 +61,27 @@ vardef mfun_constructedpath (expr f) (text t) =
enddef ;
def constructedpath = mfun_constructedpath enddef ; % let doesn't work here
-def punkedpath = mfun_constructedpath (1) enddef ;
+def straightpath = mfun_constructedpath (1) enddef ;
def curvedpath = mfun_constructedpath (2) enddef ;
-def tightpath = mfun_constructedpath (3) enddef ;
+
+% def punkedpath = mfun_constructedpath (1) enddef ; % same as straightpath
+% def tightpath = mfun_constructedpath (3) enddef ; % same as curvedpath
vardef mfun_constructedpairs (expr f) (text p) =
save i ; i := -1 ;
+ save c ; string c ; c := if string f : f else : mfun_pathconnectors[f] fi ;
forever :
exitif unknown p[incr(i)] ;
if i>0 :
- scantokens(mfun_pathconnectors[f])
+ scantokens(c)
fi
p[i]
endfor
enddef ;
def constructedpairs = mfun_constructedpairs enddef ; % let doesn't work here
-def punkedpairs = mfun_constructedpairs (1) enddef ;
+def straightpairs = mfun_constructedpairs (1) enddef ;
def curvedpairs = mfun_constructedpairs (2) enddef ;
-def tightpairs = mfun_constructedpairs (3) enddef ;
-
+% def punkedpairs = mfun_constructedpairs (1) enddef ; % same as straightpairs
+% def tightpairs = mfun_constructedpairs (3) enddef ; % same as curvedpairs
diff --git a/metapost/context/base/mp-grap.mpiv b/metapost/context/base/mp-grap.mpiv
index 417bfbe69..4fd8ee5bd 100644
--- a/metapost/context/base/mp-grap.mpiv
+++ b/metapost/context/base/mp-grap.mpiv
@@ -17,7 +17,10 @@ boolean context_grap ; context_grap := true ;
% Below is a modified graph.mp
-if epsilon/4 = 0 : % numbersystem="scaled" : (not reliable...)
+show numbersystem, numberprecision ;
+
+%if epsilon/4 = 0 :
+if numbersystem <> "double" :
errmessage "The graph macros require the double precision number system." ;
endinput ;
fi
@@ -52,11 +55,11 @@ fi
% endgraph end of graph--the result is a picture
% option `plot <picture>' draws picture at each path knot, turns off pen
-% Gtemplate.<tickcmd> template paths for tick marks and grid lines
+% graph_template.<tickcmd> template paths for tick marks and grid lines
% graph_margin_fraction.low,
% graph_margin_fraction.high fractions determining margins when no setrange
-% Glmarks[], Gumarks, Gemarks loop text strings used by auto.<x or y>
-% Gmarks, Gminlog numeric parameters used by auto.<x or y>
+% graph_log_marks[], graph_lin_marks, graph_exp_marks loop text strings used by auto.<x or y>
+% graph_minimum_number_of_marks, graph_log_minimum numeric parameters used by auto.<x or y>
% Autoform is the format string used by autogrid
% Autoform_X, Autoform_Y if defined, are used instead
@@ -64,23 +67,27 @@ fi
% are of the form X_.<suffix>, Y_.<suffix>, or Z_.<suffix>, or they start
% with `graph_'
-% Depends on :
-input string.mp
+% Used to depend on :
+
+% input string.mp
% Private version of a few marith macros, fixed for double math...
-newinternal Mzero; Mzero := -16384; % Anything at least this small is treated as zero
-newinternal mlogten ; mlogten := mlog(10) ;
-newinternal singleinfinity ; singleinfinity := 2**128 ;
-newinternal doubleinfinity ; doubleinfinity := 2**1024 ;
-% Note that we get arithmetic overflows if we set to -doubleinfinity below.
-% (but "only on odd days"...)
+
+newinternal Mzero ; Mzero := -16384; % Anything at least this small is treated as zero
+newinternal mlogten ; mlogten := mlog(10) ;
+newinternal largestmantissa ; largestmantissa := 2**52 ; % internal double warningcheck
+newinternal singleinfinity ; singleinfinity := 2**128 ;
+newinternal doubleinfinity ; doubleinfinity := 2**1024 ;
+%Mzero := -largestmantissa ; % Note that we get arithmetic overflows if we set to -doubleinfinity
% Safely convert a number to mlog form, trapping zero.
+
vardef graph_mlog primary x =
if unknown x: whatever
elseif x=0: Mzero
else: mlog(abs x) fi
enddef ;
+
vardef graph_exp primary x =
if unknown x: whatever
elseif x<=Mzero: 0
@@ -89,21 +96,25 @@ enddef ;
% and add the following for utility/completeness
% (replacing the definitions in mp-tool.mpiv).
+
vardef logten primary x =
if unknown x: whatever
elseif x=0: Mzero
else: mlog(abs x)/mlog(10) fi
enddef ;
+
vardef ln primary x =
if unknown x: whatever
elseif x=0: Mzero
else: mlog(abs x)/256 fi
enddef ;
+
vardef exp primary x =
if unknown x: whatever
elseif x<= Mzero: 0
else: (mexp 256)**x fi
enddef ;
+
vardef powten primary x =
if unknown x: whatever
elseif x<= Mzero: 0
@@ -112,6 +123,7 @@ enddef ;
% Convert x from mlog form into a pair whose xpart gives a mantissa and whose
% ypart gives a power of ten.
+
vardef graph_Meform(expr x) =
if x<=Mzero : origin
else :
@@ -122,6 +134,7 @@ vardef graph_Meform(expr x) =
enddef ;
% Modified from above.
+
vardef graph_Feform(expr x) =
interim warningcheck :=0 ;
if x=0 : origin
@@ -146,6 +159,7 @@ def graph_suffix(suffix $) = % convert from x or y to X_ or Y_
enddef ;
% New :
+
save graph_background ; color graph_background ; % if defined, fill the frame.
save graph_close_file ; boolean graph_close_file ; graph_close_file = false ;
@@ -200,17 +214,20 @@ enddef ;
% user to alter the behavior of these macros.
% Not very modifiable : log, linear,
% graph_frame_pair_a, graph_frame_pair_b, graph_margin_pair
-% Modifiable : Gtemplate.suffix, Glmarks[], Gumarks, Gemarks, Gmarks,
-% Gminlog, Autoform
+% Modifiable : graph_template.suffix,
+% graph_log_marks[], graph_lin_marks, graph_exp_marks,
+% graph_minimum_number_of_marks,
+% graph_log_minimum, Autoform
newinternal log, linear ; % coordinate system codes
log :=1 ; linear :=2;
+
% note that mp-tool.mpiv defines log as log10.
%%%%%%%%%%%%%%%%%%%%%% Coordinates : setcoords, setrange %%%%%%%%%%%%%%%%%%%%%%
-% Graph-related usr input is `user graph coordinates' as specified by arguments
+% Graph-related user input is `user graph coordinates' as specified by arguments
% 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 :
@@ -227,14 +244,15 @@ vardef graph_set_default_bounds = % Set default Z_.low, Z_.high
graph_margin_pair$ ;
endfor
enddef ;
+
pair graph_margin_pair.low, graph_margin_pair.high ;
graph_margin_pair.high = -graph_margin_pair.low = (.00002,.00002) ;
+% Set $, $$, $$$ so that shifting by $ then transforming by $$ and then $$$ maps
+% the essential bounding box of graph_current_graph into (0,0)..Z_.graph_dimensions.
+% The `essential bounding box' is either what Z_.low and Z_.high imply
+% or the result of ignoring pen widths in graph_current_graph.
-% Set $, $$, $$$ so that shifting by $ then transforming by $$ and then $$$
-% maps the essential bounding box of graph_current_graph into (0,0)..Z_.graph_dimensions. The
-% `essential bounding box' is either what Z_.low and Z_.high imply or the
-% result of ignoring pen widths in graph_current_graph.
vardef graph_remap(suffix $,$$,$$$) =
save p_ ;
graph_set_default_bounds ;
@@ -245,10 +263,10 @@ vardef graph_remap(suffix $,$$,$$$) =
(Z_.high+$) transformed $$ = p_ ;
p_ transformed $$$ = Z_.graph_dimensions ;
enddef ;
+
graph_margin_fraction.low=-.07 ; % bbox fraction for default range start
graph_margin_fraction.high=1.07 ; % bbox fraction for default range stop
-
def graph_with_pen_and_color(expr q) =
withpen penpart q withcolor
if colormodel q=1 :
@@ -268,7 +286,7 @@ enddef ;
% Pair o is the value of p that makes tp (0,0). This implements the trick
% whereby using 1 instead of 0 for the width or height or the setbounds path
% for a label picture suppresses shifting in x or y.
-%
+
%vardef graph_picture_conversion@#(expr q, o)(text tp) =
% save p ;
% if stroked q :
@@ -284,8 +302,9 @@ enddef ;
% addto @# also q shifted ((tp)-llcorner q) ;
% fi
%enddef ;
-%
+
% This new version makes gdraw clip the result to the window defined with setrange
+
vardef graph_picture_conversion@#(expr q, o)(text tp) =
save p ;
save do_clip, tp_clipped ; boolean do_clip ; do_clip := true ;
@@ -315,12 +334,11 @@ enddef ;
def graph_coordinate_multiplication(expr a,b) = (xpart a*xpart b, ypart a*ypart b) enddef ;
-
vardef graph_clear_bounds@# = numeric @#.low, @#.high ; enddef;
-
% Finalize anything drawn in the present coordinate system and set up a new
% system as requested
+
vardef setcoords(expr tx, ty) =
interim warningcheck :=0 ;
if length graph_current_graph>0 :
@@ -335,10 +353,10 @@ vardef setcoords(expr tx, ty) =
X_.graph_coordinate_type := tx ; Y_.graph_coordinate_type := ty;
enddef ;
-
% Set Z_.low and Z_.high to correspond to given range of user graph
% coordinates. The text argument should be a sequence of pairs and/or strings
% with 4 components in all.
+
vardef setrange(text t) =
interim warningcheck :=0 ;
save r_ ; r_=0;
@@ -353,8 +371,8 @@ vardef setrange(text t) =
endfor
enddef ;
-
% @# is X_ or Y_ ; l and h are numeric or string
+
vardef graph_set_bounds@#(expr l, h) =
graph_clear_bounds@# ;
if @#graph_coordinate_type>0 :
@@ -382,15 +400,12 @@ vardef graph_set_bounds@#(expr l, h) =
fi
enddef ;
-
-
-
-
%%%%%%%%%%%%%%%%%%%%%%%%% Converting path coordinates %%%%%%%%%%%%%%%%%%%%%%%%%
% Find the result of scanning path p and using macros tx and ty to adjust the
% x and y parts of each coordinate pair. Boolean parameter c tells whether to
% force the result to be polygonal.
+
vardef graph_scan_path(expr p, c)(suffix tx, ty) =
if (str tx="") and (str ty="") : p
else :
@@ -409,26 +424,29 @@ vardef graph_scan_path(expr p, c)(suffix tx, ty) =
if pair p : point 0 of fi r_
fi
enddef ;
-vardef graph_pair_adjust(expr p)(suffix tx, ty) = (tx xpart p, ty ypart p) enddef ;
+vardef graph_pair_adjust(expr p)(suffix tx, ty) = (tx xpart p, ty ypart p) enddef ;
% Convert path p from user graph coords to internal graph coords.
+
vardef graph_convert_user_path_to_internal primary p =
interim warningcheck :=0 ;
- 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)
- transformed (identity
- if X_.graph_coordinate_type<0 : xscaled -1 fi
- if Y_.graph_coordinate_type<0 : yscaled -1 fi)
+ 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)
+ transformed (identity
+ if X_.graph_coordinate_type<0 : xscaled -1 fi
+ if Y_.graph_coordinate_type<0 : yscaled -1 fi)
+ fi
enddef ;
-
% Convert label location t_ from user graph coords to internal graph coords.
% The label location should be a pair, or two numbers/strings. If t_ is empty
% or a single item of non-pair type, just return t_. Unknown coordinates
% produce unknown components in the result.
+
vardef graph_label_convert_user_to_internal(text t_) =
save n_ ; n_=0;
interim warningcheck :=0 ;
@@ -448,23 +466,56 @@ vardef graph_label_convert_user_to_internal(text t_) =
fi
enddef ;
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Reading data files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Read a line from file f, extract whitespace-separated tokens ignoring any
% initial "%", and return true if at least one token is found. The tokens
% are stored in @#1, @#2, .. with "" in the last @#[] entry.
+
+% String manipulation routines for MetaPost
+% It is harmless to input this file more than once.
+
+vardef isdigit primary d =
+ ("0"<=d)and(d<="9")
+enddef ;
+
+% Number of initial characters of string s where `c <character>' is true
+
+vardef graph_cspan(expr s)(text c) =
+ 0
+ for i=1 upto length s:
+ exitunless c substring (i-1,i) of s;
+ + 1
+ endfor
+enddef ;
+
+% String s is composed of items separated by white space. Lop off the first
+% item and the surrounding white space and return just the item.
+
+vardef graph_loptok suffix s =
+ save t, k;
+ k = graph_cspan(s," ">=);
+ if k > 0 :
+ s := substring(k,infinity) of s ;
+ fi
+ k := graph_cspan(s," "<);
+ string t;
+ t = substring (0,k) of s;
+ s := substring (k,infinity) of s;
+ s := substring (graph_cspan(s," ">=),infinity) of s;
+ t
+enddef ;
+
vardef graph_read_line@#(expr f) =
save n_, s_ ; string s_;
s_ = readfrom f ;
string @#[] ;
if s_<>EOF :
@#0 := s_ ;
- @#1 := loptok s_ ;
+ @#1 := graph_loptok s_ ;
n_ = if @#1="%" : 0 else : 1 fi ;
forever :
- @#[incr n_] := loptok s_ ;
+ @#[incr n_] := graph_loptok s_ ;
exitif @#[n_]="" ;
endfor
@#1<>""
@@ -472,12 +523,13 @@ vardef graph_read_line@#(expr f) =
fi
enddef ;
-
% Execute c for each line of data read from file f, and stop at the first
% line with no data. Commands c can use line number i and tokens $1, $2, ...
+% and j is the number of fields.
+
def gdata(expr f)(suffix $)(text c) =
- boolean flag ;
- for i=1 upto infinity :
+ %boolean flag ; % not used?
+ for i=1 upto largestmantissa :
exitunless graph_read_line$(f) ;
c
endfor
@@ -486,8 +538,8 @@ def gdata(expr f)(suffix $)(text c) =
fi
enddef ;
-
% Read a path from file f. The path is terminated by blank line or EOF.
+
vardef graph_readpath(expr f) =
interim warningcheck :=0 ;
save s ;
@@ -497,9 +549,9 @@ vardef graph_readpath(expr f) =
)
enddef ;
-
% Append coordinates t to polygonal path @#. The coordinates can be numerics,
% strings, or a single pair.
+
vardef augment@#(text t) =
interim warningcheck := 0 ;
if not path begingroup @# endgroup :
@@ -513,12 +565,11 @@ vardef augment@#(text t) =
fi
enddef ;
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Drawing and filling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Unknown pair components are set to 0 because glabel and gdotlabel understand
% unknown coordinates as `0 in absolute units'.
+
vardef graph_unknown_pair_bbox(expr p) =
interim warningcheck:=0 ;
if known p : addto graph_current_bb doublepath p ;
@@ -535,6 +586,7 @@ enddef ;
% Initiate a gdraw or gfill command. This must be done before scanning the
% argument, because that could invoke the `if known graph_plot_picture' test in a following
% plot option .
+
def graph_addto =
def graph_errorbar_text = enddef ;
color graph_foreground ;
@@ -542,8 +594,8 @@ def graph_addto =
graph_last_drawn := graph_plot_picture := nullpicture ; addto graph_last_drawn
enddef;
+% Handle the part of a gdraw command that uses path or data file p.
-% Handle the part of a Gdraw command that uses path or data file p.
def graph_draw expr p =
if string p : hide(graph_last_path := graph_readpath(p) ;)
graph_convert_user_path_to_internal graph_last_path
@@ -556,8 +608,8 @@ def graph_draw expr p =
withpen currentpen graph_withlist _op_
enddef ;
+% Handle the part of a gdraw command that uses path or data file p.
-% Handle the part of a Gdraw command that uses path or data file p.
def graph_fill expr p =
if string p : hide(graph_last_path := graph_readpath(p) --cycle ;)
graph_convert_user_path_to_internal graph_last_path
@@ -571,8 +623,8 @@ enddef ;
def gdraw = graph_addto doublepath graph_draw enddef ;
def gfill = graph_addto contour graph_fill enddef ;
-
% This is used in graph_draw and graph_fill to allow postprocessing graph_last_drawn
+
def graph_withlist text t_ = t_ ; graph_post_draw; enddef;
def witherrorbars(text t) text options =
@@ -584,6 +636,8 @@ def witherrorbars(text t) text options =
options
enddef ;
+% new feature: graph_errorbars
+
picture graph_errorbar_picture ; graph_errorbar_picture := image(draw (left--right) scaled .5 ;) ;
%picture graph_xbar_picture ; graph_xbar_picture := image(draw (down--up) scaled .5 ;) ;
%picture graph_ybar_picture ; graph_ybar_picture := image(draw (left--right) scaled .5 ;) ;
@@ -646,6 +700,7 @@ enddef ;
% Set graph_plot_picture so the postprocessing step will plot picture p at each path knot.
% Also select nullpen to suppress stroking.
+
def plot expr p =
if known graph_plot_picture :
withpen nullpen
@@ -657,20 +712,19 @@ def plot expr p =
enddef ;
% This hides a semicolon that could prematurely end graph_withlist's text argument
+
def graph_addto_currentpicture primary p = addto currentpicture also p ; enddef;
def graph_setbounds = setbounds currentpicture to enddef ;
-
-def gdrawarrow = graph_number_of_arrowheads :=1 ; gdraw enddef;
-def gdrawdblarrow = graph_number_of_arrowheads :=2 ; gdraw enddef;
-
+def gdrawarrow = graph_number_of_arrowheads := 1 ; gdraw enddef;
+def gdrawdblarrow = graph_number_of_arrowheads := 2 ; gdraw enddef;
% Post-process the filled or stroked picture graph_last_drawn as follows : (1) update
% the bounding box information ; (2) transfer it to graph_current_graph unless the pen has
% been set to nullpen to disable stroking ; (3) plot graph_plot_picture at each knot.
+
vardef graph_post_draw =
- save p ;
- path p ; p=pathpart graph_last_drawn;
+ save p ; path p ; p = pathpart graph_last_drawn ;
graph_unknown_pair_bbox(p) ;
if filled graph_last_drawn or not graph_is_null(penpart graph_last_drawn) :
addto graph_current_graph also graph_last_drawn ;
@@ -687,17 +741,23 @@ vardef graph_post_draw =
if graph_number_of_arrowheads>1 :
graph_draw_arrowhead(reverse p, graph_with_pen_and_color(graph_last_drawn)) ;
fi
- graph_number_of_arrowheads :=0 ;
+ graph_number_of_arrowheads := 0 ;
fi
enddef ;
-vardef graph_is_null(expr p) = (urcorner p=origin) and (llcorner p=origin) enddef ;
+vardef graph_is_null(expr p) = (urcorner p=origin) and (llcorner p=origin) enddef ;
vardef graph_draw_arrowhead(expr p)(text w) = % Draw arrowhead for path p, with list w
+ %save r ; r := angle(precontrol infinity of p shifted -point infinity of p) ;
addto graph_current_graph also
- image(filldraw arrowhead(
- graph_arrowhead_extent(precontrol infinity of p, point infinity of p)) w ;
- graph_setbounds point infinity of p..cycle) ;
+ image(fill arrowhead (graph_arrowhead_extent(precontrol infinity of p,point infinity of p)) w ;
+ draw arrowhead (graph_arrowhead_extent(precontrol infinity of p,point infinity of p)) w
+ undashed ;
+%if (r mod 90 <> 0) : % orientation can be wrong due to remapping
+% draw textext("\tfxx " & decimal r) shifted point infinity of p withcolor blue ;
+%fi
+ graph_setbounds point infinity of p..cycle ;
+ ) ; % rotatedabout(point infinity of p,-r) ;
enddef ;
vardef graph_arrowhead_extent(expr p, q) =
@@ -705,8 +765,6 @@ vardef graph_arrowhead_extent(expr p, q) =
q
enddef ;
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Drawing labels %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Argument c is a drawing command that needs an additional argument p that gives
@@ -714,6 +772,7 @@ enddef ;
% path. Unknown components of p cause the setbounds path to have width or height 1 instead of 0.
% Then graph_unknown_pair_bbox sets these components to 0 and graph_picture_conversion
% suppresses subsequent repositioning.
+
def graph_draw_label(expr p)(suffix $)(text c) =
save sdim_ ; pair sdim_;
sdim_ := (if unknown xpart p : 1+ fi 0, if unknown ypart p : 1+ fi 0) ;
@@ -722,14 +781,13 @@ def graph_draw_label(expr p)(suffix $)(text c) =
image(c(p) ; graph_setbounds p--p+sdim_--cycle) _op_
enddef ;
-
% Stash the result drawing command c in the graph_label table using with list w and
% an index based on angle mfun_laboff$.
+
vardef graph_stash_label(suffix $)(text c) text w =
graph_label[1.5+angle mfun_laboff$ /90] = image(c(origin) w) ;
enddef ;
-
def graph_label_location primary p =
if pair p : graph_draw_label(p)
elseif numeric p : graph_draw_label(point p of pathpart graph_last_drawn)
@@ -737,33 +795,31 @@ def graph_label_location primary p =
fi
enddef ;
-
% Place label p at user graph coords t using with list w. (t is a time, a pair
% or 2 numerics or strings).
+
vardef glabel@#(expr p)(text t) text w =
graph_label_location graph_label_convert_user_to_internal(t) (@#,label@#(p)) w ; enddef;
-
% Place label p at user graph coords t using with list w and draw a dot there.
% (t is a time, a pair, or 2 numerics or strings).
+
vardef gdotlabel@#(expr p)(text t) text w =
graph_label_location graph_label_convert_user_to_internal(t) (@#,dotlabel@#(p)) w ; enddef;
-
def OUT = enddef ; % location text for outside labels
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%% Grid lines, ticks, etc. %%%%%%%%%%%%%%%%%%%%%%%%%%
% Grid lines and tick marks are transformed versions of the templates below.
% In the template paths, (0,0) is on the edge of the frame and inward is to
% the right.
-path Gtemplate.tick, Gtemplate.itick, Gtemplate.otick, Gtemplate.grid ;
-Gtemplate.tick = (-3.5bp,0)--(3.5bp,0) ;
-Gtemplate.itick = origin--(7bp,0) ;
-Gtemplate.otick = (-7bp,0)--origin ;
-Gtemplate.grid = origin--(1,0) ;
+
+path graph_template.tick, graph_template.itick, graph_template.otick, graph_template.grid ;
+graph_template.tick = (-3.5bp,0)--(3.5bp,0) ;
+graph_template.itick = origin--(7bp,0) ;
+graph_template.otick = (-7bp,0)--origin ;
+graph_template.grid = origin--(1,0) ;
vardef tick@#(expr f,u) text w = graph_tick_label(@#,@,false,f,u,w) ; enddef;
@@ -774,75 +830,82 @@ vardef otick@#(expr f,u) text w = graph_tick_label(@#,@,false,f,u,w) ; enddef;
vardef grid@#(expr f,u) text w = graph_tick_label(@#,@,true,f,u,w) ; enddef;
-% Produce a tick or grid mark for label suffix $, Gtemplate suffix $$,
-% coordinate value u, and with list w. Boolean c tells whether Gtemplate$$
+% Produce a tick or grid mark for label suffix $, graph_template suffix $$,
+% coordinate value u, and with list w. Boolean c tells whether graph_template$$
% needs scaling by X_.graph_dimensions or Y_.graph_dimensions,
% and f gives a format string or a label picture.
+
def graph_tick_label(suffix $,$$)(expr c, f, u)(text w) =
- graph_draw_label(graph_label_convert_user_to_internal(graph_generate_label_position($,u)),,draw graph_gridline_picture$($$,c,f,u,w) shifted)
+ graph_draw_label(graph_label_convert_user_to_internal(graph_generate_label_position($,u)),,
+ draw graph_gridline_picture$($$,c,f,u,w) shifted)
enddef ;
-
% Generate label positioning arguments appropriate for label suffix $ and
% coordinate u.
+
def graph_generate_label_position(suffix $)(expr u) =
- if xpart mfun_laboff.$=0 : u,whatever else : whatever,u fi
+ if pair u : u elseif xpart mfun_laboff.$=0 : u,whatever else : whatever,u fi
enddef ;
-
% Generate a picture of a grid line labeled with coordinate value u, picture
% or format string f, and with list w. Suffix @# is bot, top, lft, or rt,
-% suffix $ identifies entries in the Gtemplate table, and boolean c tells
-% whether to scale Gtemplate$.
+% suffix $ identifies entries in the graph_template table, and boolean c tells
+% whether to scale graph_template$.
+
vardef graph_gridline_picture@#(suffix $)(expr c, f, u)(text w) =
if unknown u : graph_error(u,"Label coordinate should be known") ; nullpicture
else :
save p ; path p;
interim warningcheck :=0 ;
graph_autogrid_needed :=false ;
- p = Gtemplate$ zscaled -mfun_laboff@#
- if c : Gxyscale fi
- shifted (((.5 + mfun_laboff@# dotprod (.5,.5)) * mfun_laboff@#) Gxyscale) ;
+ p = graph_template$ zscaled -mfun_laboff@#
+ if c : graph_xyscale fi
+ shifted (((.5 + mfun_laboff@# dotprod (.5,.5)) * mfun_laboff@#) graph_xyscale) ;
image(draw p w ;
label@#(if string f : format(f,u) else : f fi, point 0 of p))
fi
enddef ;
-def Gxyscale = xscaled X_.graph_dimensions yscaled Y_.graph_dimensions enddef ;
+def graph_xyscale = xscaled X_.graph_dimensions yscaled Y_.graph_dimensions enddef ;
% Draw the frame or the part corresponding to label suffix @# using with list w.
+
vardef frame@# text w =
graph_frame_needed :=false ;
picture p_ ;
p_ = image(draw
if str@#<>"" : subpath round(angle mfun_laboff@#*graph_frame_pair_a+graph_frame_pair_b) of fi
- unitsquare Gxyscale w) ;
+ unitsquare graph_xyscale w) ;
graph_draw_label((whatever,whatever),,draw p_ shifted) ;
enddef ;
-pair graph_frame_pair_a ; graph_frame_pair_a=(1,1)/90; % unitsquare subpath is linear in label angle
-pair graph_frame_pair_b ; graph_frame_pair_b=(.75,2.25);
-
-
+pair graph_frame_pair_a ; graph_frame_pair_a=(1,1)/90; % unitsquare subpath is linear in label angle
+pair graph_frame_pair_b ; graph_frame_pair_b=(.75,2.25);
%%%%%%%%%%%%%%%%%%%%%%%%%% Automatic grid selection %%%%%%%%%%%%%%%%%%%%%%%%%%
-string Glmarks[] ; % marking options per decade for logarithmic scales
-string Gumarks ; % mark spacing options per decade for linear scales
-string Gemarks ; % exponent spacing options for logarithmic scales
-newinternal Gmarks, Gminlog ;
-Gmarks := 4 ; % minimum number marks generated by auto.x or auto.y
-Gminlog := mlog 3 ; % revert to uniform marks when largest/smallest < this
+string graph_log_marks[] ; % marking options per decade for logarithmic scales
+string graph_lin_marks ; % mark spacing options per decade for linear scales
+string graph_exp_marks ; % exponent spacing options for logarithmic scales
+newinternal graph_minimum_number_of_marks, graph_log_minimum ;
+graph_minimum_number_of_marks := 4 ; % minimum number marks generated by auto.x or auto.y
+graph_log_minimum := mlog 3 ; % revert to uniform marks when largest/smallest < this
+
+def Gfor(text t) = for i=t endfor enddef ; % to shorten the mark templates below
-def Gfor(text t) = for i=t endfor enddef ; % to shorten the mark templates below
-Glmarks[1]="1,2,5" ;
-Glmarks[2]="1,1.5,2,3,4,5,7" ;
-Glmarks[3]="1Gfor(6upto10 :,i/5)Gfor(5upto10 :,i/2)Gfor(6upto9 :,i)" ;
-Glmarks[4]="1Gfor(11upto20 :,i/10)Gfor(11upto25 :,i/5)Gfor(11upto19 :,i/2)" ;
-Glmarks[5]="1Gfor(21upto40 :,i/20)Gfor(21upto50 :,i/10)Gfor(26upto49 :,i/5)" ;
-Gumarks="10,5,2" ; % start with 10 and go down; a final `,1' is appended
-Gemarks="20,10,5,2,1" ;
+graph_log_marks[1]="1,2,5" ;
+graph_log_marks[2]="1,1.5,2,3,4,5,7" ;
+graph_log_marks[3]="1Gfor(6upto10 :,i/5)Gfor(5upto10 :,i/2)Gfor(6upto9 :,i)" ;
+graph_log_marks[4]="1Gfor(11upto20 :,i/10)Gfor(11upto25 :,i/5)Gfor(11upto19 :,i/2)" ;
+graph_log_marks[5]="1Gfor(21upto40 :,i/20)Gfor(21upto50 :,i/10)Gfor(26upto49 :,i/5)" ;
+graph_lin_marks="10,5,2" ; % start with 10 and go down; a final `,1' is appended
+graph_exp_marks="20,10,5,2,1" ;
+Ten_to0 = 1 ;
+Ten_to1 = 10 ;
+Ten_to2 = 100 ;
+Ten_to3 = 1000 ;
+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
@@ -851,6 +914,7 @@ Gemarks="20,10,5,2,1" ;
% are upper and lower bounds in
% `modified exponential form'. In modified exponential form, (x,y) means
% (x/1000)*10^y, where 1000<=abs x<10000.
+
vardef graph_bounds@# =
interim warningcheck :=0 ;
save l, h ;
@@ -859,28 +923,29 @@ vardef graph_bounds@# =
if abs @#graph_coordinate_type=log :
graph_modified_lower := graph_Meform(l)+graph_modified_bias ;
graph_modified_higher := graph_Meform(h)+graph_modified_bias ;
- if h-l >= Gminlog : log else : linear fi
+ if h-l >= graph_log_minimum : log else : linear fi
else :
graph_modified_lower := graph_Feform(l)+graph_modified_bias ;
graph_modified_higher := graph_Feform(h)+graph_modified_bias ;
linear
fi
enddef ;
+
pair graph_modified_bias ; graph_modified_bias=(0,3);
pair graph_modified_lower, graph_modified_higher ;
+% Scan graph_log_marks[k] and evaluate tokens t for each m where l<=m<=h.
-% Scan Glmarks[k] and evaluate tokens t for each m where l<=m<=h.
def graph_scan_marks(expr k, l, h)(text t) =
- for m=scantokens Glmarks[k] :
+ for m=scantokens graph_log_marks[k] :
exitif m>h ;
if m>=l : t fi
endfor
enddef ;
-
-% Scan Gmark[k] and evaluate tokens t for each m and e where m*10^e belongs
+% Scan graph_log_marks[k] and evaluate tokens t for each m and e where m*10^e belongs
% between l and h (inclusive), where both l and h are in modified exponent form.
+
def graph_scan_mark(expr k, l, h)(text t) =
for e=ypart l upto ypart h :
graph_scan_marks(k, if e>ypart l : 1 else : xpart l/1000 fi,
@@ -888,27 +953,29 @@ def graph_scan_mark(expr k, l, h)(text t) =
endfor
enddef ;
-
% Select a k for which graph_scan_mark(k,...) gives enough marks.
+
vardef graph_select_mark =
save k ;
k = 0 ;
forever :
- exitif unknown Glmarks[k+1] ;
- exitif 0 graph_scan_mark(incr k, graph_modified_lower, graph_modified_higher, +1) >= Gmarks ;
+ exitif unknown graph_log_marks[k+1] ;
+ exitif 0 graph_scan_mark(incr k, graph_modified_lower, graph_modified_higher, +1)
+ >= graph_minimum_number_of_marks ;
endfor
k
enddef ;
-
-% Try to select an exponent spacing from Gemarks. If successful, set @# and
+% Try to select an exponent spacing from graph_exp_marks. If successful, set @# and
% return true
+
vardef graph_select_exponent_mark@# =
numeric @# ;
- for e=scantokens Gemarks :
+ for e=scantokens graph_exp_marks :
@# = e ;
exitif floor(ypart graph_modified_higher/e) -
- floor(graph_modified_exponent_ypart(graph_modified_lower)/e) >= Gmarks ;
+ floor(graph_modified_exponent_ypart(graph_modified_lower)/e)
+ >= graph_minimum_number_of_marks ;
numeric @# ;
endfor
known @#
@@ -916,17 +983,17 @@ enddef ;
vardef graph_modified_exponent_ypart(expr p) = ypart p if xpart p=1000 : -1 fi enddef ;
-
% Compute the mark spacing d between xpart graph_modified_lower and xpart graph_modified_higher.
+
vardef graph_tick_mark_spacing =
interim warningcheck :=0 ;
save m, n, d ;
- m = Gmarks ;
+ m = graph_minimum_number_of_marks ;
n = 1 for i=1 upto
(mlog(xpart graph_modified_higher-xpart graph_modified_lower) - mlog m)/mlogten :
*10 endfor ;
if n<=1000 :
- for x=scantokens Gumarks :
+ for x=scantokens graph_lin_marks :
d = n*x ;
exitif 0 graph_generate_numbers(d,+1)>=m ;
numeric d ;
@@ -935,25 +1002,24 @@ vardef graph_tick_mark_spacing =
if known d : d else : n fi
enddef ;
-
def graph_generate_numbers(expr d)(text t) =
for m = d*ceiling(xpart graph_modified_lower/d) step d until xpart graph_modified_higher :
t
endfor
enddef ;
-
% Evaluate tokens t for exponents e in multiples of d in the range determined
% by graph_modified_lower and graph_modified_higher.
+
def graph_generate_exponents(expr d)(text t) =
for e = d*floor(graph_modified_exponent_ypart(graph_modified_lower)/d+1)
step d until d*floor(ypart graph_modified_higher/d) : t
endfor
enddef ;
-
% Adjust graph_modified_lower and graph_modified_higher so their exponent parts match
% and they are in true exponent form ((x,y) means x*10^y). Return the new exponent.
+
vardef graph_match_exponents =
interim warningcheck := 0 ;
save e ;
@@ -966,10 +1032,10 @@ vardef graph_match_exponents =
e
enddef ;
-
% Assume e is an integer and either m=0 or 1<=abs(m)<10000. Find m*(10^e)
% and represent the result as a string if its absolute value would be at least
% 4096 or less than .1. It is OK to return 0 as a string or a numeric.
+
vardef graph_factor_and_exponent_to_string(expr m, e) =
if (e>3)or(e<-4) :
decimal m & "e" & decimal e
@@ -984,7 +1050,6 @@ vardef graph_factor_and_exponent_to_string(expr m, e) =
fi
enddef ;
-
def auto suffix $ =
hide(def graph_comma= hide(def graph_comma=,enddef) enddef)
if graph_bounds.graph_suffix($)=log :
@@ -1002,7 +1067,6 @@ def auto suffix $ =
fi
enddef ;
-
string Autoform ; Autoform = "%g";
%vardef autogrid(suffix tx, ty) text w =
@@ -1053,12 +1117,11 @@ vardef autogrid(suffix tx, ty) text w =
fi
enddef ;
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% endgraph %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
def endgraph =
if graph_autogrid_needed : autogrid(otick.bot, otick.lft) ; fi
- if graph_frame_needed : frame ; fi
+ if graph_frame_needed : frame ; fi
setcoords(linear,linear) ;
interim truecorners :=1 ;
for b=bbox graph_finished_graph :
@@ -1075,14 +1138,9 @@ enddef ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% We format in luatex (using \mathematics{}) ...
% we could pass via variables and save escaping as that is inefficient
-Ten_to0 = 1 ;
-Ten_to1 = 10 ;
-Ten_to2 = 100 ;
-Ten_to3 = 1000 ;
-Ten_to4 = 10000 ;
-
if unknown context_mlib :
vardef escaped_format(expr s) =
@@ -1108,6 +1166,8 @@ if unknown context_mlib :
fi ;
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
% A couple of extensions :
% Define a function plotsymbol() returning a picture : 10 different shapes,
diff --git a/metapost/context/base/mp-luas.mpiv b/metapost/context/base/mp-luas.mpiv
new file mode 100644
index 000000000..c919ba215
--- /dev/null
+++ b/metapost/context/base/mp-luas.mpiv
@@ -0,0 +1,99 @@
+%D \module
+%D [ file=mp-luas.mpiv,
+%D version=2014.04.14,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=\LUA,
+%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.
+
+if known context_luas : endinput ; fi ;
+
+% When I prototyped the runscript primitive I was just thinking of a usage like
+% the original \directlua primitive in luatex: genererate something and pipe
+% that back to metapost, and have access to some internals. Instead of compiling
+% the code a the metapost end here we delegate that to the lua end. Only strings
+% get passed. Of course in the end the real usage got a bit beyong the intended
+% usage. So, in addition to some definitions here there are and will be use in
+% other metafun modules too. Of course in retrospect I should have done this five
+% years earlier.
+
+boolean context_luas ; context_luas := true ;
+
+% First variant:
+%
+% let lua = runscript ;
+%
+% Second variant:
+%
+% vardef lua (text t) =
+% runscript(for s = t : s & endfor "")
+% enddef;
+%
+% Third variant:
+%
+% vardef lua (text t) =
+% runscript("" for s = t :
+% if string s :
+% & s
+% elseif numeric s :
+% & decimal s
+% elseif boolean s :
+% & if s : "true" else "false" fi
+% fi endfor)
+% enddef;
+%
+% Fourth variant:
+
+vardef mlib_luas_luacall(text t) =
+ runscript("" for s = t :
+ if string s :
+ & s
+ elseif numeric s :
+ & decimal s
+ elseif boolean s :
+ & if s : "true" else "false" fi
+ fi endfor
+ )
+enddef ;
+
+vardef mlib_luas_lualist(expr c)(text t) =
+ save b ; boolean b ; b := false ;
+ runscript(c & "(" for s = t :
+ if b :
+ & ","
+ else :
+ hide(b := true)
+ fi
+ if string s :
+ & ditto & s & ditto
+ elseif numeric s :
+ & decimal s
+ elseif boolean s :
+ & if s : "true" else "false" fi
+ fi endfor & ")"
+ )
+enddef ;
+
+def luacall = mlib_luas_luacall enddef ; % why no let
+
+vardef lualist@#(text t) = mlib_luas_lualist(str @#)(t) enddef ;
+
+string mlib_luas_s ; % saves save/restore
+
+vardef lua@#(text t) =
+ mlib_luas_s := str @# ;
+ if length(mlib_luas_s) > 0 :
+ mlib_luas_lualist(mlib_luas_s,t)
+ else :
+ mlib_luas_luacall(t)
+ fi
+enddef ;
+
+vardef MP@#(text t) =
+ mlib_luas_lualist("MP." & str @#,t)
+enddef ;
diff --git a/metapost/context/base/mp-mlib.mpiv b/metapost/context/base/mp-mlib.mpiv
index 12840b28e..b19f47f1e 100644
--- a/metapost/context/base/mp-mlib.mpiv
+++ b/metapost/context/base/mp-mlib.mpiv
@@ -60,32 +60,70 @@ def namedcolor (expr n) =
withprescript "sp_name=" & n
enddef ;
+% def spotcolor(expr n, v) =
+% 1
+% withprescript "sp_type=spot"
+% withprescript "sp_name=" & n
+% withprescript "sp_value=" & (if numeric v : decimal v else : v fi)
+% enddef ;
+%
+% def multitonecolor(expr name, fractions, components, value) =
+% 1
+% withprescript "sp_type=multitone"
+% withprescript "sp_name=" & name
+% withprescript "sp_fractions=" & decimal fractions
+% withprescript "sp_components=" & components
+% withprescript "sp_value=" & value
+% enddef ;
+
def spotcolor(expr n, v) =
1
withprescript "sp_type=spot"
withprescript "sp_name=" & n
- withprescript "sp_value=" & v
+ withprescript "sp_value=" & colordecimals v
enddef ;
-def multitonecolor(expr name, fractions, components, value) =
+def multitonecolor(expr name)(text t) =
1
withprescript "sp_type=multitone"
- withprescript "sp_name=" & name
- withprescript "sp_fractions=" & decimal fractions
- withprescript "sp_components=" & components
- withprescript "sp_value=" & value
+ withprescript "sp_name=" & name
+ withprescript "sp_value=" & colordecimalslist(t)
enddef ;
-def transparent(expr alternative, transparency)(text c) =
+def transparent(expr a, t)(text c) = % use withtransparency instead
1 % this permits withcolor x intoshade y
- withprescript "tr_alternative=" & decimal transparency_alternative_to_number(alternative)
- withprescript "tr_transparency=" & decimal transparency
+ withprescript "tr_alternative=" & decimal transparency_alternative_to_number(a)
+ withprescript "tr_transparency=" & decimal t
withcolor c
enddef ;
-def withtransparency(expr alternative, transparency) =
- withprescript "tr_alternative=" & decimal transparency_alternative_to_number(alternative)
- withprescript "tr_transparency=" & decimal transparency
+% def withtransparency(expr a, t) =
+% withprescript "tr_alternative=" & decimal transparency_alternative_to_number(a)
+% withprescript "tr_transparency=" & decimal t
+% enddef ;
+
+let transparency = 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)
+
+def withtransparency (expr t) (text rest) =
+ if pair t :
+ withprescript "tr_alternative=" & decimal transparency_alternative_to_number(xpart t)
+ withprescript "tr_transparency=" & decimal ypart t
+ else :
+ mfun_with_transparency (transparency_alternative_to_number(t))
+ fi rest
+enddef ;
+
+def mfun_with_transparency (expr a) expr t =
+ withprescript "tr_alternative=" & decimal a
+ withprescript "tr_transparency=" & decimal t
enddef ;
def cmyk(expr c, m, y, k) = % provided for downward compability
@@ -96,7 +134,8 @@ enddef ;
newinternal textextoffset ; textextoffset := 0 ;
-numeric mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ; % we can consider using colors (less hash space)
+%%%%%%% 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 ;
@@ -135,44 +174,10 @@ extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ;
% flush twice: once in location in order to pick up e.g. color properties,
% and once at the end because we need to flush missing ones.
-% vardef rawtextext(expr str) =
-% if str = "" :
-% nullpicture
-% elseif mfun_trial_run :
-% mfun_tt_n := mfun_tt_n + 1 ;
-% mfun_tt_o := image(draw origin) ; % save drawoptions
-% addto mfun_tt_p doublepath unitsquare
-% withprescript "tx_number=" & decimal mfun_tt_n
-% withprescript "tx_stage=extra"
-% withpostscript str ;
-% image (
-% addto currentpicture doublepath unitsquare
-% withprescript "tx_number=" & decimal mfun_tt_n
-% withprescript "tx_stage=trial"
-% withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
-% withpostscript str
-% ; )
-% else :
-% mfun_tt_n := mfun_tt_n + 1 ;
-% if known mfun_tt_d[mfun_tt_n] :
-% image (
-% addto currentpicture doublepath unitsquare
-% xscaled mfun_tt_w[mfun_tt_n]
-% yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n])
-% withprescript "tx_number=" & decimal mfun_tt_n
-% withprescript "tx_stage=final"
-% % withpostscript str ; % for tracing
-% ; ) shifted (0,-mfun_tt_d[mfun_tt_n])
-% else :
-% image (
-% addto currentpicture doublepath unitsquare
-% ; )
-% fi
-% fi
-% enddef ;
+% see mp-keep.mpiv for older code
-% vardef rawtextext(expr str) = % todo: avoid currentpicture
-% if str = "" :
+% vardef rawtextext(expr s) = % todo: avoid currentpicture
+% if s = "" :
% nullpicture
% else :
% mfun_tt_n := mfun_tt_n + 1 ;
@@ -180,15 +185,12 @@ extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ;
% if mfun_trial_run :
% mfun_tt_o := nullpicture ;
% addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
-% addto mfun_tt_p doublepath unitsquare
-% withprescript "tx_number=" & decimal mfun_tt_n
-% withprescript "tx_stage=extra"
-% withpostscript str ;
% addto mfun_tt_c doublepath unitsquare
% withprescript "tx_number=" & decimal mfun_tt_n
% withprescript "tx_stage=trial"
% withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
-% withpostscript str ;
+% withpostscript s ;
+% addto mfun_tt_p also mfun_tt_c ;
% elseif known mfun_tt_d[mfun_tt_n] :
% addto mfun_tt_c doublepath unitsquare
% xscaled mfun_tt_w[mfun_tt_n]
@@ -203,8 +205,8 @@ extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ;
% fi
% enddef ;
-vardef rawtextext(expr str) = % todo: avoid currentpicture
- if str = "" :
+vardef rawtextext(expr s) = % todo: avoid currentpicture
+ if s = "" :
nullpicture
else :
mfun_tt_n := mfun_tt_n + 1 ;
@@ -216,17 +218,16 @@ vardef rawtextext(expr str) = % todo: avoid currentpicture
withprescript "tx_number=" & decimal mfun_tt_n
withprescript "tx_stage=trial"
withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
- withpostscript str ;
+ withpostscript s ;
addto mfun_tt_p also mfun_tt_c ;
- elseif known mfun_tt_d[mfun_tt_n] :
+ else :
+ mfun_tt_b := lua.mp.tt_dimensions(mfun_tt_n) ;
addto mfun_tt_c doublepath unitsquare
- xscaled mfun_tt_w[mfun_tt_n]
- yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n])
- shifted (0,-mfun_tt_d[mfun_tt_n])
+ xscaled redpart mfun_tt_b
+ yscaled (greenpart mfun_tt_b + bluepart mfun_tt_b)
+ shifted (0,- bluepart mfun_tt_b)
withprescript "tx_number=" & decimal mfun_tt_n
withprescript "tx_stage=final" ;
- else :
- addto mfun_tt_c doublepath unitsquare ; % unitpicture
fi ;
mfun_tt_c
fi
@@ -234,7 +235,10 @@ enddef ;
% More text
-defaultfont := "Mono" ; % was cmr10, could be lmmono10-regular, but is fed into context anyway
+defaultfont := "Mono" ;
+defaultscale := 1 ;
+
+extra_beginfig := extra_beginfig & "defaultscale:=1;" ;
vardef fontsize expr name =
save size ; numeric size ;
@@ -366,6 +370,8 @@ vardef thetextext@#(expr p,z) =
% interim labeloffset := textextoffset ;
if string p :
thetextext@#(rawtextext(p),z)
+ elseif numeric p :
+ thetextext@#(rawtextext(decimal p),z)
else :
p
if (mfun_labtype@# >= 10) :
@@ -401,19 +407,171 @@ enddef ;
let normalinfont = infont ;
-primarydef str infont name = % nasty hack
+primarydef s infont name = % nasty hack
if name = "" :
- textext(str)
+ textext(s)
else :
- textext("\definedfont[" & name & "]" & str)
+ textext("\definedfont[" & name & "]" & s)
fi
enddef ;
+% Helper
+
+string mfun_prescript_separator ; mfun_prescript_separator := char(13) ;
+
% Shades
-newinternal shadefactor ; shadefactor := 1 ;
-pair shadeoffset ; shadeoffset := origin ;
-boolean trace_shades ; trace_shades := false ;
+% for while we had this:
+
+newinternal shadefactor ; shadefactor := 1 ; % currently obsolete
+pair shadeoffset ; shadeoffset := origin ; % currently obsolete
+boolean trace_shades ; trace_shades := false ; % still there
+
+% def withlinearshading (expr a, b) =
+% withprescript "sh_type=linear"
+% withprescript "sh_domain=0 1"
+% withprescript "sh_factor=" & decimal shadefactor
+% withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset)
+% withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset)
+% enddef ;
+%
+% def withcircularshading (expr a, b, ra, rb) =
+% withprescript "sh_type=circular"
+% withprescript "sh_domain=0 1"
+% withprescript "sh_factor=" & decimal shadefactor
+% withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset)
+% withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset)
+% withprescript "sh_radius_a=" & decimal ra
+% withprescript "sh_radius_b=" & decimal rb
+% enddef ;
+%
+% def withshading (expr how)(text rest) =
+% if how = "linear" :
+% withlinearshading(rest)
+% elseif how = "circular" :
+% withcircularshading(rest)
+% else :
+% % nothing
+% fi
+% enddef ;
+%
+% def withfromshadecolor expr t =
+% withprescript "sh_color=into"
+% withprescript "sh_color_a=" & colordecimals t
+% enddef ;
+
+% def withtoshadecolor expr t =
+% withprescript "sh_color=into"
+% withprescript "sh_color_b=" & colordecimals t
+% enddef ;
+
+% but this is nicer
+
+path mfun_shade_path ;
+
+primarydef p withshademethod m =
+ hide(mfun_shade_path := p ;)
+ p
+ withprescript "sh_domain=0 1"
+ withprescript "sh_color=into"
+ withprescript "sh_color_a=" & colordecimals white
+ withprescript "sh_color_b=" & colordecimals black
+ if m = "linear" :
+ withprescript "sh_type=linear"
+ withprescript "sh_factor=1"
+ withprescript "sh_center_a=" & ddecimal llcorner p
+ withprescript "sh_center_b=" & ddecimal urcorner p
+ else :
+ withprescript "sh_type=circular"
+ withprescript "sh_factor=1.2"
+ withprescript "sh_center_a=" & ddecimal center p
+ withprescript "sh_center_b=" & ddecimal center p
+ withprescript "sh_radius_a=" & decimal 0
+ withprescript "sh_radius_b=" & decimal ( max (
+ (xpart center p - xpart llcorner p) ++ (ypart center p - ypart llcorner p),
+ (xpart center p - xpart ulcorner p) ++ (ypart ulcorner p - ypart center p),
+ (xpart lrcorner p - xpart center p) ++ (ypart center p - ypart lrcorner p),
+ (xpart urcorner p - xpart center p) ++ (ypart urcorner p - ypart center p)
+ ) )
+ fi
+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)
+enddef ;
+
+def withshadecenter expr a =
+ withprescript "sh_center_a=" & ddecimal (
+ center mfun_shade_path shifted (
+ xpart a * bbwidth (mfun_shade_path)/2,
+ ypart a * bbheight(mfun_shade_path)/2
+ )
+ )
+enddef ;
+
+def withshadedomain expr d =
+ withprescript "sh_domain=" & ddecimal d
+enddef ;
+
+def withshadefactor expr f =
+ withprescript "sh_factor=" & decimal f
+enddef ;
+
+def withshadecolors (expr a, b) =
+ withprescript "sh_color=into"
+ withprescript "sh_color_a=" & colordecimals a
+ withprescript "sh_color_b=" & colordecimals b
+enddef ;
+
+primarydef a shadedinto b = % withcolor red shadedinto green
+ 1 % does not work with transparency
+ withprescript "sh_color=into"
+ withprescript "sh_color_a=" & colordecimals a
+ withprescript "sh_color_b=" & colordecimals b
+enddef ;
+
+primarydef p withshade sc =
+ p withprescript mfun_defined_cs_pre[sc]
+enddef ;
+
+def defineshade suffix s =
+ mfun_defineshade(str s)
+enddef ;
+
+def mfun_defineshade (expr s) text t =
+ expandafter def scantokens s = t enddef ;
+enddef ;
+
+def shaded text s =
+ s
+enddef ;
+
+% Old macros:
+
+def withcircularshade (expr a, b, ra, rb, ca, cb) =
+ withprescript "sh_type=circular"
+ withprescript "sh_domain=0 1"
+ withprescript "sh_factor=1"
+ withprescript "sh_color_a=" & colordecimals ca
+ withprescript "sh_color_b=" & colordecimals cb
+ withprescript "sh_center_a=" & ddecimal a % (a shifted shadeoffset)
+ withprescript "sh_center_b=" & ddecimal b % (b shifted shadeoffset)
+ withprescript "sh_radius_a=" & decimal ra
+ withprescript "sh_radius_b=" & decimal rb
+enddef ;
+
+def withlinearshade (expr a, b, ca, cb) =
+ withprescript "sh_type=linear"
+ withprescript "sh_domain=0 1"
+ withprescript "sh_factor=1"
+ withprescript "sh_color_a=" & colordecimals ca
+ withprescript "sh_color_b=" & colordecimals cb
+ withprescript "sh_center_a=" & ddecimal a % (a shifted shadeoffset)
+ withprescript "sh_center_b=" & ddecimal b % (b shifted shadeoffset)
+enddef ;
+
+% replaced (obsolete):
def set_linear_vector (suffix a,b)(expr p,n) =
if (n=1) : a := llcorner p ; b := urcorner p ;
@@ -428,7 +586,7 @@ def set_linear_vector (suffix a,b)(expr p,n) =
fi ;
enddef ;
-def set_circular_vector (suffix ab, r)(expr p,n) =
+def set_circular_vector (suffix ab,r)(expr p,n) =
if (n=1) : ab := llcorner p ;
elseif (n=2) : ab := lrcorner p ;
elseif (n=3) : ab := urcorner p ;
@@ -451,7 +609,7 @@ enddef ;
def linear_shade (expr p, n, ca, cb) =
begingroup ;
- save a, b, sh ; pair a, b ;
+ save a, b ; pair a, b ;
set_linear_vector(a,b)(p,n) ;
fill p withlinearshade(a,b,ca,cb) ;
if trace_shades :
@@ -460,43 +618,19 @@ def linear_shade (expr p, n, ca, cb) =
endgroup ;
enddef ;
-def withcircularshade (expr a, b, ra, rb, ca, cb) =
- withprescript "sh_type=circular"
- withprescript "sh_domain=0 1"
- withprescript "sh_factor=" & decimal shadefactor
- withprescript "sh_color_a=" & colordecimals ca
- withprescript "sh_color_b=" & colordecimals cb
- withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset)
- withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset)
- withprescript "sh_radius_a=" & decimal ra
- withprescript "sh_radius_b=" & decimal rb
-enddef ;
-
-def withlinearshade (expr a, b, ca, cb) =
- withprescript "sh_type=linear"
- withprescript "sh_domain=0 1"
- withprescript "sh_factor=" & decimal shadefactor
- withprescript "sh_color_a=" & colordecimals ca
- withprescript "sh_color_b=" & colordecimals cb
- withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset)
- withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset)
-enddef ;
-
string mfun_defined_cs_pre[] ; numeric mfun_defined_cs ; mfun_defined_cs := 0 ;
-string mfun_prescript_separator ; mfun_prescript_separator := char(13) ;
-
vardef define_circular_shade (expr a, b, ra, rb, ca, cb) =
mfun_defined_cs := mfun_defined_cs + 1 ;
mfun_defined_cs_pre[mfun_defined_cs] := "sh_type=circular"
- & mfun_prescript_separator & "sh_domain=0 1"
- & mfun_prescript_separator & "sh_factor=" & decimal shadefactor
- & mfun_prescript_separator & "sh_color_a=" & colordecimals ca
- & mfun_prescript_separator & "sh_color_b=" & colordecimals cb
- & mfun_prescript_separator & "sh_center_a=" & ddecimal (a shifted shadeoffset)
- & mfun_prescript_separator & "sh_center_b=" & ddecimal (b shifted shadeoffset)
- & mfun_prescript_separator & "sh_radius_a=" & decimal ra
- & mfun_prescript_separator & "sh_radius_b=" & decimal rb
+ & mfun_prescript_separator & "sh_domain=0 1"
+ & mfun_prescript_separator & "sh_factor=1"
+ & mfun_prescript_separator & "sh_color_a=" & colordecimals ca
+ & mfun_prescript_separator & "sh_color_b=" & colordecimals cb
+ & mfun_prescript_separator & "sh_center_a=" & ddecimal a % (a shifted shadeoffset)
+ & mfun_prescript_separator & "sh_center_b=" & ddecimal b % (b shifted shadeoffset)
+ & mfun_prescript_separator & "sh_radius_a=" & decimal ra
+ & mfun_prescript_separator & "sh_radius_b=" & decimal rb
;
mfun_defined_cs
enddef ;
@@ -504,52 +638,49 @@ enddef ;
vardef define_linear_shade (expr a, b, ca, cb) =
mfun_defined_cs := mfun_defined_cs + 1 ;
mfun_defined_cs_pre[mfun_defined_cs] := "sh_type=linear"
- & mfun_prescript_separator & "sh_domain=0 1"
- & mfun_prescript_separator & "sh_factor=" & decimal shadefactor
- & mfun_prescript_separator & "sh_color_a=" & colordecimals ca
- & mfun_prescript_separator & "sh_color_b=" & colordecimals cb
- & mfun_prescript_separator & "sh_center_a=" & ddecimal (a shifted shadeoffset)
- & mfun_prescript_separator & "sh_center_b=" & ddecimal (b shifted shadeoffset)
+ & mfun_prescript_separator & "sh_domain=0 1"
+ & mfun_prescript_separator & "sh_factor=1"
+ & mfun_prescript_separator & "sh_color_a=" & colordecimals ca
+ & mfun_prescript_separator & "sh_color_b=" & colordecimals cb
+ & mfun_prescript_separator & "sh_center_a=" & ddecimal a % (a shifted shadeoffset)
+ & mfun_prescript_separator & "sh_center_b=" & ddecimal b % (b shifted shadeoffset)
;
mfun_defined_cs
enddef ;
-primarydef p withshade sc =
- p withprescript mfun_defined_cs_pre[sc]
-enddef ;
-
-
-vardef define_sampled_linear_shade(expr a,b,n)(text t) =
- mfun_defined_cs := mfun_defined_cs + 1 ;
- mfun_defined_cs_pre[mfun_defined_cs] := "ssh_type=linear"
- & mfun_prescript_separator & "ssh_center_a=" & ddecimal (a shifted shadeoffset)
- & mfun_prescript_separator & "ssh_center_b=" & ddecimal (b shifted shadeoffset)
- & mfun_prescript_separator & "ssh_nofcolors=" & decimal n
- & mfun_prescript_separator & "ssh_domain=" & domstr
- & mfun_prescript_separator & "ssh_extend=" & extstr
- & mfun_prescript_separator & "ssh_colors=" & colstr
- & mfun_prescript_separator & "ssh_bounds=" & bndstr
- & mfun_prescript_separator & "ssh_ranges=" & ranstr
- ;
- mfun_defined_cs
-enddef ;
-
-vardef define_sampled_circular_shade(expr a,b,ra,rb,n)(text t) =
- mfun_defined_cs := mfun_defined_cs + 1 ;
- mfun_defined_cs_pre[mfun_defined_cs] := "ssh_type=circular"
- & mfun_prescript_separator & "ssh_center_a=" & ddecimal (a shifted shadeoffset)
- & mfun_prescript_separator & "ssh_radius_a=" & decimal ra
- & mfun_prescript_separator & "ssh_center_b=" & ddecimal (b shifted shadeoffset)
- & mfun_prescript_separator & "ssh_radius_b=" & decimal rb
- & mfun_prescript_separator & "ssh_nofcolors=" & decimal n
- & mfun_prescript_separator & "ssh_domain=" & domstr
- & mfun_prescript_separator & "ssh_extend=" & extstr
- & mfun_prescript_separator & "ssh_colors=" & colstr
- & mfun_prescript_separator & "ssh_bounds=" & bndstr
- & mfun_prescript_separator & "ssh_ranges=" & ranstr
- ;
- mfun_defined_cs
-enddef ;
+% I lost the example code that uses this:
+%
+% vardef define_sampled_linear_shade(expr a,b,n)(text t) =
+% mfun_defined_cs := mfun_defined_cs + 1 ;
+% mfun_defined_cs_pre[mfun_defined_cs] := "ssh_type=linear"
+% & mfun_prescript_separator & "ssh_center_a=" & ddecimal (a shifted shadeoffset)
+% & mfun_prescript_separator & "ssh_center_b=" & ddecimal (b shifted shadeoffset)
+% & mfun_prescript_separator & "ssh_nofcolors=" & decimal n
+% & mfun_prescript_separator & "ssh_domain=" & domstr
+% & mfun_prescript_separator & "ssh_extend=" & extstr
+% & mfun_prescript_separator & "ssh_colors=" & colstr
+% & mfun_prescript_separator & "ssh_bounds=" & bndstr
+% & mfun_prescript_separator & "ssh_ranges=" & ranstr
+% ;
+% mfun_defined_cs
+% enddef ;
+%
+% vardef define_sampled_circular_shade(expr a,b,ra,rb,n)(text t) =
+% mfun_defined_cs := mfun_defined_cs + 1 ;
+% mfun_defined_cs_pre[mfun_defined_cs] := "ssh_type=circular"
+% & mfun_prescript_separator & "ssh_center_a=" & ddecimal (a shifted shadeoffset)
+% & mfun_prescript_separator & "ssh_radius_a=" & decimal ra
+% & mfun_prescript_separator & "ssh_center_b=" & ddecimal (b shifted shadeoffset)
+% & mfun_prescript_separator & "ssh_radius_b=" & decimal rb
+% & mfun_prescript_separator & "ssh_nofcolors=" & decimal n
+% & mfun_prescript_separator & "ssh_domain=" & domstr
+% & mfun_prescript_separator & "ssh_extend=" & extstr
+% & mfun_prescript_separator & "ssh_colors=" & colstr
+% & mfun_prescript_separator & "ssh_bounds=" & bndstr
+% & mfun_prescript_separator & "ssh_ranges=" & ranstr
+% ;
+% mfun_defined_cs
+% enddef ;
% vardef predefined_linear_shade (expr p, n, ca, cb) =
% save a, b, sh ; pair a, b ;
@@ -564,53 +695,6 @@ enddef ;
% define_circular_shade(ab,ab,0,r,ca,cb)
% enddef ;
-% NEW EXPERIMENTAL CODE
-
-def withlinearshading (expr a, b) =
- withprescript "sh_type=linear"
- withprescript "sh_domain=0 1"
- withprescript "sh_factor=" & decimal shadefactor
- withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset)
- withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset)
-enddef ;
-
-def withcircularshading (expr a, b, ra, rb) =
- withprescript "sh_type=circular"
- withprescript "sh_domain=0 1"
- withprescript "sh_factor=" & decimal shadefactor
- withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset)
- withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset)
- withprescript "sh_radius_a=" & decimal ra
- withprescript "sh_radius_b=" & decimal rb
-enddef ;
-
-def withfromshadecolor expr t =
- withprescript "sh_color=into"
- withprescript "sh_color_a=" & colordecimals t
-enddef ;
-
-def withtoshadecolor expr t =
- withprescript "sh_color=into"
- withprescript "sh_color_b=" & colordecimals t
-enddef ;
-
-def withshading (expr how)(text rest) =
- if how = "linear" :
- withlinearshading(rest)
- elseif how = "circular" :
- withcircularshading(rest)
- else :
- % nothing
- fi
-enddef ;
-
-primarydef a shadedinto b =
- 1 % does not work with transparency
- withprescript "sh_color=into"
- withprescript "sh_color_a=" & colordecimals a
- withprescript "sh_color_b=" & colordecimals b
-enddef ;
-
% Layers
def onlayer primary name =
@@ -655,10 +739,10 @@ enddef ;
% Positions
-def register (expr label, width, height, offset) =
+def register (expr tag, width, height, offset) =
% draw image (
addto currentpicture doublepath unitsquare xscaled width yscaled height shifted offset
- withprescript "ps_label=" & label ;
+ withprescript "ps_label=" & tag ;
% ) ; % no transformations
enddef ;
@@ -670,8 +754,8 @@ extra_endfig := extra_endfig & "mfun_reset_tex_texts ; " ;
% Bonus
-vardef verbatim(expr str) =
- ditto & "\detokenize{" & str & "}" & ditto
+vardef verbatim(expr s) =
+ ditto & "\detokenize{" & s & "}" & ditto
enddef ;
% New
@@ -747,7 +831,7 @@ primarydef t asgroup s = % s = isolated|knockout
endgroup
enddef ;
-% Also experimental
+% Also experimental ... needs to be made better ... so it can change!
string mfun_auto_align[] ;
@@ -781,6 +865,9 @@ enddef ;
% passvariable("boolean",false) ;
% passvariable("path",fullcircle scaled 1cm) ;
+% we could use the new lua interface but there is not that much gain i.e.
+% we still need to serialize
+
vardef mfun_point_to_string(expr p,i) =
decimal xpart (point i of p) & " " &
decimal ypart (point i of p) & " " &
@@ -821,6 +908,10 @@ vardef mfun_cmykcolor_to_string(expr c) =
decimal blackpart c
enddef ;
+vardef mfun_greycolor_to_string(expr n) =
+ decimal n
+enddef ;
+
vardef mfun_path_to_string(expr p) =
mfun_point_to_string(p,0) for i=1 upto length(p) : & " " & mfun_point_to_string(p,i) endfor
enddef ;
@@ -847,6 +938,7 @@ vardef tostring(expr value) =
elseif pair value : mfun_pair_to_string(value)
elseif rgbcolor value : mfun_rgbcolor_to_string(value)
elseif cmykcolor value : mfun_cmykcolor_to_string(value)
+ elseif greycolor value : mfun_greycolor_to_string(value)
elseif boolean value : mfun_boolean_to_string(value)
elseif path value : mfun_path_to_string(value)
elseif transform value : mfun_transform_to_string(value)
@@ -1042,23 +1134,80 @@ enddef ;
% moved here from mp-grap.mpiv
+% vardef escaped_format(expr s) =
+% "" for n=0 upto length(s) : &
+% if ASCII substring (n,n+1) of s = 37 :
+% "@"
+% else :
+% substring (n,n+1) of s
+% fi
+% endfor
+% enddef ;
+
+numeric mfun_esc_b ; % begin
+numeric mfun_esc_l ; % length
+string mfun_esc_s ; % character
+
+mfun_esc_s := "%" ; % or: char(37)
+
+% this one is the fastest when we have a match
+
+% vardef escaped_format(expr s) =
+% "" for n=0 upto length(s)-1 : &
+% % if ASCII substring (n,n+1) of s = 37 :
+% if substring (n,n+1) of s = mfun_esc_s :
+% "@"
+% else :
+% substring (n,n+1) of s
+% fi
+% endfor
+% enddef ;
+
+% this one wins when we have no match
+
vardef escaped_format(expr s) =
- "" for n=0 upto length(s) : &
- if ASCII substring (n,n+1) of s = 37 :
- "@"
- else :
- substring (n,n+1) of s
+ mfun_esc_b := 0 ;
+ mfun_esc_l := length(s) ;
+ for n=0 upto mfun_esc_l-1 :
+ % if ASCII substring (n,n+1) of s = 37 :
+ if substring (n,n+1) of s = mfun_esc_s :
+ if mfun_esc_b = 0 :
+ ""
+ fi
+ if n >= mfun_esc_b :
+ & (substring (mfun_esc_b,n) of s)
+ exitif numeric begingroup mfun_esc_b := n+1 endgroup ; % hide
+ fi
+ & "@"
fi
endfor
+ if mfun_esc_b = 0 :
+ s
+ % elseif mfun_esc_b > 0 :
+ elseif mfun_esc_b < mfun_esc_l :
+ & (substring (mfun_esc_b,mfun_esc_l) of s)
+ fi
enddef ;
-vardef strfmt(expr f, x) = % maybe use mfun_ namespace
- "\MPgraphformat{" & escaped_format(f) & "}{" & mfun_tagged_string(x) & "}"
-enddef ;
-
-vardef varfmt(expr f, x) = % maybe use mfun_ namespace
- "\MPformatted{" & escaped_format(f) & "}{" & mfun_tagged_string(x) & "}"
-enddef ;
+vardef strfmt(expr f, x) = "\MPgraphformat{" & escaped_format(f) & "}{" & mfun_tagged_string(x) & "}" enddef ;
+vardef varfmt(expr f, x) = "\MPformatted{" & escaped_format(f) & "}{" & mfun_tagged_string(x) & "}" enddef ;
vardef format (expr f, x) = textext(strfmt(f, x)) enddef ;
vardef formatted(expr f, x) = textext(varfmt(f, x)) enddef ;
+
+% could be this (something to discuss with alan as it involves graph):
+%
+% vardef format (expr f,x) = lua.mp.graphformat(f,mfun_tagged_string(x) enddef ;
+% vardef formatted(expr f,x) = lua.mp.format (f, x) enddef ;
+%
+% def strfmt = format enddef ; % old
+% def varfmt = formatted enddef ; % old
+
+% new
+
+def eofill text t = fill t withpostscript "evenodd" enddef ;
+%%% eoclip text t = clip t withpostscript "evenodd" enddef ; % no postscripts yet
+
+% def withrule expr r =
+% if (t = "even-odd") or (t = "evenodd") : withpostscript "evenodd" fi
+% enddef ;
diff --git a/metapost/context/base/mp-page.mpiv b/metapost/context/base/mp-page.mpiv
index 9c538d42a..a6fa3fba3 100644
--- a/metapost/context/base/mp-page.mpiv
+++ b/metapost/context/base/mp-page.mpiv
@@ -11,73 +11,309 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D This module is rather preliminary and subjected to
-%D changes.
+%D This module is rather preliminary and subjected to changes.
if known context_page : endinput ; fi ;
boolean context_page ; context_page := true ;
+% def LoadPageState =
+% % now always set
+% enddef ;
+%
+% if unknown PageStateAvailable :
+% boolean PageStateAvailable ;
+% PageStateAvailable := false ;
+% fi ;
+%
+% if unknown OnRightPage :
+% boolean OnRightPage ;
+% OnRightPage := true ;
+% fi ;
+%
+% if unknown OnOddPage :
+% boolean OnOddPage ;
+% OnOddPage := true ;
+% fi ;
+%
+% if unknown InPageBody :
+% boolean InPageBody ;
+% InPageBody := false ;
+% fi ;
+%
+% string CurrentLayout ;
+%
+% CurrentLayout := "default" ;
+%
+% PageNumber := 0 ;
+% PaperHeight := 845.04684pt ;
+% PaperWidth := 597.50787pt ;
+% PrintPaperHeight := 845.04684pt ;
+% PrintPaperWidth := 597.50787pt ;
+% TopSpace := 71.12546pt ;
+% BottomSpace := 0.0pt ;
+% BackSpace := 71.13275pt ;
+% CutSpace := 0.0pt ;
+% MakeupHeight := 711.3191pt ;
+% MakeupWidth := 426.78743pt ;
+% TopHeight := 0.0pt ;
+% TopDistance := 0.0pt ;
+% HeaderHeight := 56.90294pt ;
+% HeaderDistance := 0.0pt ;
+% TextHeight := 597.51323pt ;
+% FooterDistance := 0.0pt ;
+% FooterHeight := 56.90294pt ;
+% BottomDistance := 0.0pt ;
+% BottomHeight := 0.0pt ;
+% LeftEdgeWidth := 0.0pt ;
+% LeftEdgeDistance := 0.0pt ;
+% LeftMarginWidth := 75.58197pt ;
+% LeftMarginDistance := 11.99829pt ;
+% TextWidth := 426.78743pt ;
+% RightMarginDistance := 11.99829pt ;
+% RightMarginWidth := 75.58197pt ;
+% RightEdgeDistance := 0.0pt ;
+% RightEdgeWidth := 0.0pt ;
+%
+% PageOffset := 0.0pt ;
+% PageDepth := 0.0pt ;
+%
+% LayoutColumns := 0 ;
+% LayoutColumnDistance:= 0.0pt ;
+% LayoutColumnWidth := 0.0pt ;
+%
+% LeftEdge := -4 ; Top := -40 ;
+% LeftEdgeSeparator := -3 ; TopSeparator := -30 ;
+% LeftMargin := -2 ; Header := -20 ;
+% LeftMarginSeparator := -1 ; HeaderSeparator := -10 ;
+% Text := 0 ; Text := 0 ;
+% RightMarginSeparator := +1 ; FooterSeparator := +10 ;
+% RightMargin := +2 ; Footer := +20 ;
+% RightEdgeSeparator := +3 ; BottomSeparator := +30 ;
+% RightEdge := +4 ; Bottom := +40 ;
+%
+% Margin := LeftMargin ; % obsolete
+% Edge := LeftEdge ; % obsolete
+% InnerMargin := RightMargin ; % obsolete
+% InnerEdge := RightEdge ; % obsolete
+% OuterMargin := LeftMargin ; % obsolete
+% OuterEdge := LeftEdge ; % obsolete
+%
+% InnerMarginWidth := 0pt ;
+% OuterMarginWidth := 0pt ;
+% InnerMarginDistance := 0pt ;
+% OuterMarginDistance := 0pt ;
+%
+% InnerEdgeWidth := 0pt ;
+% OuterEdgeWidth := 0pt ;
+% InnerEdgeDistance := 0pt ;
+% OuterEdgeDistance := 0pt ;
+%
+% % path Area[][] ;
+% % pair Location[][] ;
+% % path Field[][] ;
+%
+% % numeric Hstep[] ;
+% % numeric Hsize[] ;
+% % numeric Vstep[] ;
+% % numeric Vsize[] ;
+%
+% path Page ;
+%
+% numeric HorPos ;
+% numeric VerPos ;
+%
+% % for VerPos=Top step 10 until Bottom:
+% % for HorPos=LeftEdge step 1 until RightEdge:
+% % Area[HorPos][VerPos] := origin--cycle ;
+% % Area[VerPos][HorPos] := Area[HorPos][VerPos] ;
+% % Location[HorPos][VerPos] := origin ;
+% % Location[VerPos][HorPos] := Location[HorPos][VerPos] ;
+% % Field[HorPos][VerPos] := origin--cycle ;
+% % Field[VerPos][HorPos] := Field[HorPos][VerPos] ;
+% % endfor ;
+% % endfor ;
+%
+% % def LoadPageState =
+% % scantokens "input mp-state.tmp" ;
+% % enddef ;
+%
+% numeric mfun_temp ;
+%
+% def SwapPageState =
+% if not OnRightPage :
+% BackSpace := PaperWidth-MakeupWidth-BackSpace ;
+% CutSpace := PaperWidth-MakeupWidth-CutSpace ;
+% mfun_temp := LeftMarginWidth ;
+% LeftMarginWidth := RightMarginWidth ;
+% RightMarginWidth := mfun_temp ;
+% mfun_temp := LeftMarginDistance ;
+% LeftMarginDistance := RightMarginDistance ;
+% RightMarginDistance := mfun_temp ;
+% mfun_temp := LeftEdgeWidth ;
+% LeftEdgeWidth := RightEdgeWidth ;
+% RightEdgeWidth := mfun_temp ;
+% mfun_temp := LeftEdgeDistance ;
+% LeftEdgeDistance := RightEdgeDistance ;
+% RightEdgeDistance := mfun_temp ;
+%
+% % these are now available as ..Width and ..Distance
+%
+% Margin := LeftMargin ;
+% Edge := LeftEdge ;
+% InnerMargin := RightMargin ;
+% InnerEdge := RightEdge ;
+% OuterMargin := LeftMargin ;
+% OuterEdge := LeftEdge ;
+% else :
+% Margin := RightMargin ;
+% Edge := RightEdge ;
+% InnerMargin := LeftMargin ;
+% InnerEdge := LeftEdge ;
+% OuterMargin := RightMargin ;
+% OuterEdge := RightEdge ;
+% fi ;
+% enddef ;
+
+% the new way:
+
+def LoadPageState =
+ % now always set
+enddef ;
+
if unknown PageStateAvailable :
boolean PageStateAvailable ;
PageStateAvailable := false ;
fi ;
-if unknown OnRightPage :
- boolean OnRightPage ;
- OnRightPage := true ;
-fi ;
+string CurrentLayout ; CurrentLayout := "default" ;
+
+vardef PaperHeight = lua.mp.PaperHeight () enddef ;
+vardef PaperWidth = lua.mp.PaperWidth () enddef ;
+vardef PrintPaperHeight = lua.mp.PrintPaperHeight () enddef ;
+vardef PrintPaperWidth = lua.mp.PrintPaperWidth () enddef ;
+vardef TopSpace = lua.mp.TopSpace () enddef ;
+vardef BottomSpace = lua.mp.BottomSpace () enddef ;
+vardef BackSpace = lua.mp.BackSpace () enddef ;
+vardef CutSpace = lua.mp.CutSpace () enddef ;
+vardef MakeupHeight = lua.mp.MakeupHeight () enddef ;
+vardef MakeupWidth = lua.mp.MakeupWidth () enddef ;
+vardef TopHeight = lua.mp.TopHeight () enddef ;
+vardef TopDistance = lua.mp.TopDistance () enddef ;
+vardef HeaderHeight = lua.mp.HeaderHeight () enddef ;
+vardef HeaderDistance = lua.mp.HeaderDistance () enddef ;
+vardef TextHeight = lua.mp.TextHeight () enddef ;
+vardef FooterDistance = lua.mp.FooterDistance () enddef ;
+vardef FooterHeight = lua.mp.FooterHeight () enddef ;
+vardef BottomDistance = lua.mp.BottomDistance () enddef ;
+vardef BottomHeight = lua.mp.BottomHeight () enddef ;
+vardef LeftEdgeWidth = lua.mp.LeftEdgeWidth () enddef ;
+vardef LeftEdgeDistance = lua.mp.LeftEdgeDistance () enddef ;
+vardef LeftMarginWidth = lua.mp.LeftMarginWidth () enddef ;
+vardef LeftMarginDistance = lua.mp.LeftMarginDistance () enddef ;
+vardef TextWidth = lua.mp.TextWidth () enddef ;
+vardef RightMarginDistance = lua.mp.RightMarginDistance () enddef ;
+vardef RightMarginWidth = lua.mp.RightMarginWidth () enddef ;
+vardef RightEdgeDistance = lua.mp.RightEdgeDistance () enddef ;
+vardef RightEdgeWidth = lua.mp.RightEdgeWidth () enddef ;
+vardef InnerMarginDistance = lua.mp.InnerMarginDistance () enddef ;
+vardef InnerMarginWidth = lua.mp.InnerMarginWidth () enddef ;
+vardef OuterMarginDistance = lua.mp.OuterMarginDistance () enddef ;
+vardef OuterMarginWidth = lua.mp.OuterMarginWidth () enddef ;
+vardef InnerEdgeDistance = lua.mp.InnerEdgeDistance () enddef ;
+vardef InnerEdgeWidth = lua.mp.InnerEdgeWidth () enddef ;
+vardef OuterEdgeDistance = lua.mp.OuterEdgeDistance () enddef ;
+vardef OuterEdgeWidth = lua.mp.OuterEdgeWidth () enddef ;
+vardef PageOffset = lua.mp.PageOffset () enddef ;
+vardef PageDepth = lua.mp.PageDepth () enddef ;
+vardef LayoutColumns = lua.mp.LayoutColumns () enddef ;
+vardef LayoutColumnDistance = lua.mp.LayoutColumnDistance() enddef ;
+vardef LayoutColumnWidth = lua.mp.LayoutColumnWidth () enddef ;
+
+vardef OnRightPage = lua.mp.OnRightPage () enddef ;
+vardef OnOddPage = lua.mp.OnOddPage () enddef ;
+vardef InPageBody = lua.mp.InPageBody () enddef ;
+
+vardef RealPageNumber = lua.mp.RealPageNumber () enddef ;
+vardef PageNumber = lua.mp.PageNumber () enddef ;
+vardef NOfPages = lua.mp.NOfPages () enddef ;
+vardef LastPageNumber = lua.mp.LastPageNumber () enddef ; % duplicates
+
+vardef CurrentColumn = lua.mp.CurrentColumn () enddef ;
+vardef NOfColumns = lua.mp.NOfColumns () enddef ;
+
+vardef BaseLineSkip = lua.mp.BaseLineSkip () enddef ;
+vardef LineHeight = lua.mp.LineHeight () enddef ;
+vardef BodyFontSize = lua.mp.BodyFontSize () enddef ;
+
+vardef TopSkip = lua.mp.TopSkip () enddef ;
+vardef StrutHeight = lua.mp.StrutHeight () enddef ;
+vardef StrutDepth = lua.mp.StrutDepth () enddef ;
+
+vardef CurrentWidth = lua.mp.CurrentWidth () enddef ;
+vardef CurrentHeight = lua.mp.CurrentHeight () enddef ;
+
+vardef HSize = lua.mp.HSize () enddef ; % duplicates
+vardef VSize = lua.mp.VSize () enddef ; % duplicates
+
+vardef EmWidth = lua.mp.EmWidth () enddef ;
+vardef ExHeight = lua.mp.ExHeight () enddef ;
+
+vardef PageFraction = lua.mp.PageFraction () enddef ;
+
+vardef SpineWidth = lua.mp.SpineWidth () enddef ;
+vardef PaperBleed = lua.mp.PaperBleed () enddef ;
+
+boolean mfun_swapped ;
-if unknown OnOddPage :
- boolean OnOddPage ;
- OnOddPage := true ;
-fi ;
+def SwapPageState =
+ mfun_swapped := true ; % eventually this will go !
+enddef ;
-if unknown InPageBody :
- boolean InPageBody ;
- InPageBody := false ;
-fi ;
+extra_beginfig := extra_beginfig & "mfun_swapped := false ;" ;
+
+vardef LeftMarginWidth = if mfun_swapped and not OnRightPage : lua.mp.RightMarginWidth () else : lua.mp.LeftMarginWidth () fi enddef ;
+vardef RightMarginWidth = if mfun_swapped and not OnRightPage : lua.mp.LeftMarginWidth () else : lua.mp.RightMarginWidth () fi enddef ;
+vardef LeftMarginDistance = if mfun_swapped and not OnRightPage : lua.mp.RightMarginDistance() else : lua.mp.LeftMarginDistance () fi enddef ;
+vardef RightMarginDistance = if mfun_swapped and not OnRightPage : lua.mp.LeftMarginDistance () else : lua.mp.RightMarginDistance() fi enddef ;
+
+vardef LeftEdgeWidth = if mfun_swapped and not OnRightPage : lua.mp.RightEdgeWidth () else : lua.mp.LeftEdgeWidth () fi enddef ;
+vardef RightEdgeWidth = if mfun_swapped and not OnRightPage : lua.mp.LeftEdgeWidth () else : lua.mp.RightEdgeWidth () fi enddef ;
+vardef LeftEdgeDistance = if mfun_swapped and not OnRightPage : lua.mp.RightEdgeDistance () else : lua.mp.LeftEdgeDistance () fi enddef ;
+vardef RightEdgeDistance = if mfun_swapped and not OnRightPage : lua.mp.LeftEdgeDistance () else : lua.mp.RightEdgeDistance () fi enddef ;
+
+vardef BackSpace = if mfun_swapped and not OnRightPage : PaperWidth - MakeupWidth - fi lua.mp.BackSpace() enddef ;
+vardef CutSpace = if mfun_swapped and not OnRightPage : PaperWidth - MakeupWidth - fi lua.mp.CutSpace () enddef ;
+
+% better use:
+
+vardef OuterMarginWidth = if not OnRightPage : lua.mp.LeftMarginWidth () else : lua.mp.RightMarginWidth () fi enddef ;
+vardef InnerMarginWidth = if not OnRightPage : lua.mp.RightMarginWidth () else : lua.mp.LeftMarginWidth () fi enddef ;
+vardef OuterMarginDistance = if not OnRightPage : lua.mp.LeftMarginDistance () else : lua.mp.RightMarginDistance() fi enddef ;
+vardef InnerMarginDistance = if not OnRightPage : lua.mp.RightMarginDistance() else : lua.mp.leftMarginDistance () fi enddef ;
+
+vardef OuterEdgeWidth = if not OnRightPage : lua.mp.LeftEdgeWidth () else : lua.mp.RightEdgeWidth () fi enddef ;
+vardef InnerEdgeWidth = if not OnRightPage : lua.mp.RightEdgeWidth () else : lua.mp.LeftEdgeWidth () fi enddef ;
+vardef OuterEdgeDistance = if not OnRightPage : lua.mp.LeftEdgeDistance () else : lua.mp.RightEdgeDistance () fi enddef ;
+vardef InnerEdgeDistance = if not OnRightPage : lua.mp.RightEdgeDistance () else : lua.mp.leftEdgeDistance () fi enddef ;
-string CurrentLayout ;
-
-CurrentLayout := "default" ;
-
-PageNumber := 0 ;
-PaperHeight := 845.04684pt ;
-PaperWidth := 597.50787pt ;
-PrintPaperHeight := 845.04684pt ;
-PrintPaperWidth := 597.50787pt ;
-TopSpace := 71.12546pt ;
-BottomSpace := 0.0pt ;
-BackSpace := 71.13275pt ;
-CutSpace := 0.0pt ;
-MakeupHeight := 711.3191pt ;
-MakeupWidth := 426.78743pt ;
-TopHeight := 0.0pt ;
-TopDistance := 0.0pt ;
-HeaderHeight := 56.90294pt ;
-HeaderDistance := 0.0pt ;
-TextHeight := 597.51323pt ;
-FooterDistance := 0.0pt ;
-FooterHeight := 56.90294pt ;
-BottomDistance := 0.0pt ;
-BottomHeight := 0.0pt ;
-LeftEdgeWidth := 0.0pt ;
-LeftEdgeDistance := 0.0pt ;
-LeftMarginWidth := 75.58197pt ;
-LeftMarginDistance := 11.99829pt ;
-TextWidth := 426.78743pt ;
-RightMarginDistance := 11.99829pt ;
-RightMarginWidth := 75.58197pt ;
-RightEdgeDistance := 0.0pt ;
-RightEdgeWidth := 0.0pt ;
-
-PageOffset := 0.0pt ;
-PageDepth := 0.0pt ;
-
-LayoutColumns := 0 ;
-LayoutColumnDistance:= 0.0pt ;
-LayoutColumnWidth := 0.0pt ;
+vardef OuterSpaceWidth = if not OnRightPage : lua.mp.BackSpace () else : lua.mp.CutSpace () fi enddef ;
+vardef InnerSpaceWidth = if not OnRightPage : lua.mp.CutSpace () else : lua.mp.BackSpace () fi enddef ;
+
+% vardef CurrentLayout = lua.mp.CurrentLayout () enddef ;
+
+vardef OverlayWidth = lua.mp.OverlayWidth () enddef ;
+vardef OverlayHeight = lua.mp.OverlayHeight () enddef ;
+vardef OverlayDepth = lua.mp.OverlayDepth () enddef ;
+vardef OverlayLineWidth = lua.mp.OverlayLineWidth() enddef ;
+vardef OverlayOffset = lua.mp.OverlayOffset () enddef ;
+
+vardef defaultcolormodel = lua.mp.defaultcolormodel() enddef ;
+
+% def OverlayLineColor = lua.mp.OverlayLineColor() enddef ;
+% def OverlayColor = lua.mp.OverlayColor () enddef ;
+
+% Next we implement the the page area model. First some constants.
LeftEdge := -4 ; Top := -40 ;
LeftEdgeSeparator := -3 ; TopSeparator := -30 ;
@@ -89,37 +325,28 @@ RightMargin := +2 ; Footer := +20 ;
RightEdgeSeparator := +3 ; BottomSeparator := +30 ;
RightEdge := +4 ; Bottom := +40 ;
-Margin := LeftMargin ; % obsolete
-Edge := LeftEdge ; % obsolete
-InnerMargin := RightMargin ; % obsolete
-InnerEdge := RightEdge ; % obsolete
-OuterMargin := LeftMargin ; % obsolete
-OuterEdge := LeftEdge ; % obsolete
+% Margin := LeftMargin ; % obsolete
+% Edge := LeftEdge ; % obsolete
+% InnerMargin := RightMargin ; % obsolete
+% InnerEdge := RightEdge ; % obsolete
+% OuterMargin := LeftMargin ; % obsolete
+% OuterEdge := LeftEdge ; % obsolete
-InnerMarginWidth := 0pt ;
-OuterMarginWidth := 0pt ;
-InnerMarginDistance := 0pt ;
-OuterMarginDistance := 0pt ;
+numeric HorPos ; HorPos := 0 ;
+numeric VerPos ; VerPos := 0 ;
-InnerEdgeWidth := 0pt ;
-OuterEdgeWidth := 0pt ;
-InnerEdgeDistance := 0pt ;
-OuterEdgeDistance := 0pt ;
+% We used to initialize these variables each (sub)run but at some point MP
+% became too slow for this. See later.
% path Area[][] ;
% pair Location[][] ;
% path Field[][] ;
-
+%
% numeric Hstep[] ;
% numeric Hsize[] ;
% numeric Vstep[] ;
% numeric Vsize[] ;
-
-path Page ;
-
-numeric HorPos ;
-numeric VerPos ;
-
+%
% for VerPos=Top step 10 until Bottom:
% for HorPos=LeftEdge step 1 until RightEdge:
% Area[HorPos][VerPos] := origin--cycle ;
@@ -130,46 +357,8 @@ numeric VerPos ;
% Field[VerPos][HorPos] := Field[HorPos][VerPos] ;
% endfor ;
% endfor ;
-
-% def LoadPageState =
-% scantokens "input mp-state.tmp" ;
-% enddef ;
-
-def SwapPageState =
- if not OnRightPage :
- BackSpace := PaperWidth-MakeupWidth-BackSpace ;
- CutSpace := PaperWidth-MakeupWidth-CutSpace ;
- i := LeftMarginWidth ;
- LeftMarginWidth := RightMarginWidth ;
- RightMarginWidth := i ;
- i := LeftMarginDistance ;
- LeftMarginDistance := RightMarginDistance ;
- RightMarginDistance := i ;
- i := LeftEdgeWidth ;
- LeftEdgeWidth := RightEdgeWidth ;
- RightEdgeWidth := i ;
- i := LeftEdgeDistance ;
- LeftEdgeDistance := RightEdgeDistance ;
- RightEdgeDistance := i ;
-
- % these are now available as ..Width and ..Distance
-
- Margin := LeftMargin ;
- Edge := LeftEdge ;
- InnerMargin := RightMargin ;
- InnerEdge := RightEdge ;
- OuterMargin := LeftMargin ;
- OuterEdge := LeftEdge ;
- else :
- Margin := RightMargin ;
- Edge := RightEdge ;
- InnerMargin := LeftMargin ;
- InnerEdge := LeftEdge ;
- OuterMargin := RightMargin ;
- OuterEdge := RightEdge ;
- fi ;
-enddef ;
-
+%
+%
% def SetPageAreas =
%
% numeric Vsize[], Hsize[], Vstep[], Hstep[] ;
@@ -338,29 +527,55 @@ def SetPageField =
endfor ;
enddef ;
-def SetPagePage =
- path Page ;
- Page := unitsquare xscaled PaperWidth yscaled PaperHeight ;
+def mfun_page_Area = hide(SetPageArea ;) Area enddef ;
+def mfun_page_Location = hide(SetPageLocation ;) Location enddef ;
+def mfun_page_Field = hide(SetPageField ;) Field enddef ;
+def mfun_page_Vsize = hide(SetPageVsize ;) Vsize enddef ;
+def mfun_page_Hsize = hide(SetPageHsize ;) Hsize enddef ;
+def mfun_page_Vstep = hide(SetPageVstep ;) Vstep enddef ;
+def mfun_page_Hstep = hide(SetPageHstep ;) Hstep enddef ;
+
+def SetAreaVariables =
+ let Area = mfun_page_Area ;
+ let Location = mfun_page_Location ;
+ let Field = mfun_page_Field ;
+ let Vsize = mfun_page_Vsize ;
+ let Hsize = mfun_page_Hsize ;
+ let Vstep = mfun_page_Vstep ;
+ let Hstep = mfun_page_Hstep ;
enddef ;
-def mfun_page_Area = hide(SetPageArea ;) Area enddef ;
-def mfun_page_Location = hide(SetPageLocation ;) Location enddef ;
-def mfun_page_Field = hide(SetPageField ;) Field enddef ;
-def mfun_page_Vsize = hide(SetPageVsize ;) Vsize enddef ;
-def mfun_page_Hsize = hide(SetPageHsize ;) Hsize enddef ;
-def mfun_page_Vstep = hide(SetPageVstep ;) Vstep enddef ;
-def mfun_page_Hstep = hide(SetPageHstep ;) Hstep enddef ;
-def mfun_page_Page = hide(SetPagePage ;) Page enddef ;
+% we should make Page no path .. from now on don't assume this .. for a while we keek it
+
+vardef FrontPageWidth = PaperWidth enddef ;
+vardef BackPageWidth = PaperWidth enddef ;
+vardef CoverWidth = 2 * PaperWidth + SpineWidth enddef ;
+vardef CoverHeight = PaperHeight enddef ;
+
+vardef FrontPageHeight = PaperHeight enddef ;
+vardef BackPageHeight = PaperHeight enddef ;
+vardef SpineHeight = PaperHeight enddef ;
+
+def SetPagePage = path Page ; Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; enddef ;
+def SetPageCoverPage = path CoverPage ; CoverPage := unitsquare xscaled CoverWidth yscaled CoverHeight ; enddef ;
+def SetPageSpine = path Spine ; Spine := unitsquare xscaled SpineWidth yscaled CoverHeight shifted (BackPageWidth,0) ; enddef ;
+def SetPageBackPage = path BackPage ; BackPage := unitsquare xscaled BackPageWidth yscaled CoverHeight ; enddef ;
+def SetPageFrontPage = path FrontPage ; FrontPage := unitsquare xscaled FrontPageWidth yscaled CoverHeight shifted (BackPageWidth+SpineWidth,0) ; enddef ;
+
+def mfun_page_Page = hide(SetPagePage ;) Page enddef ;
+def mfun_page_CoverPage = hide(SetPageCoverPage;) CoverPage enddef ;
+def mfun_page_Spine = hide(SetPageSpine ;) Spine enddef ;
+def mfun_page_BackPage = hide(SetPageBackPage ;) BackPage enddef ;
+def mfun_page_FrontPage = hide(SetPageFrontPage;) FrontPage enddef ;
def SetPageVariables =
- let Area = mfun_page_Area ;
- let Location = mfun_page_Location ;
- let Field = mfun_page_Field ;
- let Vsize = mfun_page_Vsize ;
- let Hsize = mfun_page_Hsize ;
- let Vstep = mfun_page_Vstep ;
- let Hstep = mfun_page_Hstep ;
- let Page = mfun_page_Page ;
+ SetAreaVariables ;
+ %
+ let Page = mfun_page_Page ;
+ let CoverPage = mfun_page_CoverPage ;
+ let Spine = mfun_page_Spine ;
+ let BackPage = mfun_page_BackPage ;
+ let FrontPage = mfun_page_FrontPage ;
enddef ;
SetPageVariables ;
@@ -393,45 +608,10 @@ enddef ;
def BoundCoverAreas =
% todo: add cropmarks
- bboxmargin := 0 ; setbounds currentpicture to Paper enlarged PaperBleed ;
-enddef ;
-
-def SetCoverAreas =
-
- if unknown SpineWidth :
- SpineWidth := 8mm ;
- fi ;
-
- if unknown PaperBleed :
- PaperBleed := 0 ;
- fi ;
-
- FrontPageWidth := PaperWidth ;
- BackPageWidth := PaperWidth ;
- PaperWidth := 2 * PaperWidth + SpineWidth ;
-
- FrontPageHeight := PaperHeight ;
- BackPageHeight := PaperHeight ;
- PaperHeight := PaperHeight ;
- SpineHeight := PaperHeight ;
-
- path Paper ; Paper := unitsquare xscaled PaperWidth yscaled PaperHeight ;
- path Spine ; Spine := unitsquare xscaled SpineWidth yscaled PaperHeight shifted (BackPageWidth,0);
- path BackPage ; BackPage := unitsquare xscaled BackPageWidth yscaled PaperHeight ;
- path FrontPage ; FrontPage := unitsquare xscaled FrontPageWidth yscaled PaperHeight shifted (BackPageWidth+SpineWidth,0) ;
-
+ bboxmargin := 0 ; setbounds currentpicture to CoverPage enlarged PaperBleed ;
enddef ;
-% def StartCover =
-% begingroup ;
-% if PageStateAvailable :
-% LoadPageState ;
-% % SwapPageState ;
-% fi ;
-% SetPageAreas ;
-% SetCoverAreas ;
-% BoundCoverAreas ;
-% enddef ;
+let SetCoverAreas = SetPageVariables ; % compatiblity
def StartCover =
begingroup ;
diff --git a/metapost/context/base/mp-tool.mpii b/metapost/context/base/mp-tool.mpii
index f363f655e..a5bb345a1 100644
--- a/metapost/context/base/mp-tool.mpii
+++ b/metapost/context/base/mp-tool.mpii
@@ -5,17 +5,13 @@
%D subtitle=auxiliary macros,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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.
-% a cleanup is needed, like using image and alike
-% use a few more "newinternal"'s
-
-%D This module is rather preliminary and subjected to
-%D changes.
+% def loadfile(expr name) = scantokens("input " & name & ";") enddef ;
if known context_tool : endinput ; fi ;
@@ -32,6 +28,8 @@ let @## = @# ;
if not known mpversion : string mpversion ; mpversion := "0.641" ; fi ;
+newinternal metapostversion ; metapostversion := scantokens(mpversion) ;
+
% vardef mpversiongt(expr s) =
% scantokens (mpversion & " > " & if numeric s : decimal s else : s fi)
% enddef ;
@@ -85,20 +83,14 @@ mpprocset := 1 ;
%
% protect ;
-%D By including this module, \METAPOST\ automatically writes a
-%D high resolution boundingbox to the \POSTSCRIPT\ file. This
-%D hack is due to John Hobby himself.
-
-% When somehow the first one gets no HiRes, then make sure
-% that the format matches the mem sizes in the config file.
-
-string space ; space = char 32 ;
+string space ; space := char 32 ;
+string CRLF ; CRLF := char 10 & char 13 ;
vardef ddecimal primary p =
- decimal xpart p & " " & decimal ypart p
+ decimal xpart p & " " & decimal ypart p
enddef ;
-%D Plain compatibility
+%D Plain compatibility:
string plain_compatibility_data ; plain_compatibility_data := "" ;
@@ -112,7 +104,7 @@ def stopplaincompatibility =
enddef ;
% is now built in
-
+%
% extra_endfig := extra_endfig
% & "special "
% & "("
@@ -124,6 +116,11 @@ enddef ;
% & "&ddecimal urcorner currentpicture"
% & ");";
+%D More neutral:
+
+let triplet = rgbcolor ;
+let quadruplet = cmykcolor ;
+
%D Crap (experimental, not used):
def forcemultipass =
@@ -132,12 +129,28 @@ enddef ;
%D Colors:
-nocolormodel := 1 ;
-greycolormodel := 3 ;
-rgbcolormodel := 5 ;
-cmykcolormodel := 7 ;
+newinternal nocolormodel ; nocolormodel := 1 ;
+newinternal greycolormodel ; greycolormodel := 3 ;
+newinternal graycolormodel ; graycolormodel := 3 ;
+newinternal rgbcolormodel ; rgbcolormodel := 5 ;
+newinternal cmykcolormodel ; cmykcolormodel := 7 ;
let grayscale = numeric ;
+let greyscale = numeric ;
+
+vardef colorpart expr c =
+ if not picture c :
+ 0
+ elseif colormodel c = greycolormodel :
+ greypart c
+ elseif colormodel c = rgbcolormodel :
+ (redpart c,greenpart c,bluepart c)
+ elseif colormodel c = cmykcolormodel :
+ (cyanpart c,magentapart c,yellowpart c,blackpart c)
+ else :
+ 0 % black
+ fi
+enddef ;
vardef colorlike(text c) text v = % colorlike(a) b, c, d ;
save _p_ ; picture _p_ ;
@@ -148,25 +161,19 @@ vardef colorlike(text c) text v = % colorlike(a) b, c, d ;
elseif (colormodel _p_ = rgbcolormodel) :
rgbcolor i ;
else :
- grayscale i ;
+ greycolor i ;
fi ;
endfor ;
enddef ;
-% if (unknown colormodel) :
-% def colormodel =
-% rgbcolormodel
-% enddef ;
-% fi ;
-
%D Also handy (when we flush colors):
vardef dddecimal primary c =
- decimal redpart c & " " & decimal greenpart c & " " & decimal bluepart c
+ decimal redpart c & " " & decimal greenpart c & " " & decimal bluepart c
enddef ;
vardef ddddecimal primary c =
- decimal cyanpart c & " " & decimal magentapart c & " " & decimal yellowpart c & " " & decimal blackpart c
+ decimal cyanpart c & " " & decimal magentapart c & " " & decimal yellowpart c & " " & decimal blackpart c
enddef ;
vardef colordecimals primary c =
@@ -193,39 +200,34 @@ enddef ;
%D we need some trickery when we have multiple files.
if unknown collapse_data :
- boolean collapse_data ; collapse_data := false ;
+ boolean collapse_data ;
+ collapse_data := false ;
fi ;
boolean savingdata ; savingdata := false ;
boolean savingdatadone ; savingdatadone := false ;
def savedata expr txt =
- if collapse_data :
- write txt to data_mpd_file ;
- else :
- write if savingdata : txt else :
- "\MPdata{" & decimal charcode & "}{" & txt & "}"
- fi
- & "%" to data_mpd_file ;
- fi ;
+ write if collapse_data :
+ txt
+ else :
+ if savingdata : txt else : "\MPdata{" & decimal charcode & "}{" & txt & "}" fi & "%"
+ fi to data_mpd_file ;
enddef ;
def startsavingdata =
- savingdata := true ;
- savingdatadone := true ;
- if collapse_data :
- write
- "\MPdata{" & decimal charcode & "}{%"
- to
- data_mpd_file ;
- fi ;
+ savingdata := true ;
+ savingdatadone := true ;
+ if collapse_data :
+ write "\MPdata{" & decimal charcode & "}{%" to data_mpd_file ;
+ fi ;
enddef ;
def stopsavingdata =
- if collapse_data :
- write "}%" to data_mpd_file ;
- fi ;
- savingdata := false ;
+ if collapse_data :
+ write "}%" to data_mpd_file ;
+ fi ;
+ savingdata := false ;
enddef ;
def finishsavingdata =
@@ -253,119 +255,130 @@ def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; endd
%D box, draw the graphics that may not count, and restore the
%D bounding box.
%D
-%D \starttypen
+%D \starttyping
%D push_boundingbox currentpicture;
%D pop_boundingbox currentpicture;
-%D \stoptypen
+%D \stoptyping
%D
%D The bounding box can be called with:
%D
-%D \starttypen
+%D \starttyping
%D boundingbox currentpicture
%D inner_boundingbox currentpicture
%D outer_boundingbox currentpicture
-%D \stoptypen
+%D \stoptyping
%D
%D Especially the latter one can be of use when we include
%D the graphic in a document that is clipped to the bounding
%D box. In such occasions one can use:
%D
-%D \starttypen
+%D \starttyping
%D set_outer_boundingbox currentpicture;
-%D \stoptypen
+%D \stoptyping
%D
%D Its counterpart is:
%D
-%D \starttypen
+%D \starttyping
%D set_inner_boundingbox p
-%D \stoptypen
+%D \stoptyping
-path pushed_boundingbox;
+path mfun_boundingbox_stack ;
+numeric mfun_boundingbox_stack_depth ;
-def push_boundingbox text p =
- pushed_boundingbox := boundingbox p;
-enddef;
+mfun_boundingbox_stack_depth := 0 ;
-def pop_boundingbox text p =
- setbounds p to pushed_boundingbox;
-enddef;
+def pushboundingbox text p =
+ mfun_boundingbox_stack_depth := mfun_boundingbox_stack_depth + 1 ;
+ mfun_boundingbox_stack[mfun_boundingbox_stack_depth] := boundingbox p ;
+enddef ;
+
+def popboundingbox text p =
+ setbounds p to mfun_boundingbox_stack[mfun_boundingbox_stack_depth] ;
+ mfun_boundingbox_stack[mfun_boundingbox_stack_depth] := origin ;
+ mfun_boundingbox_stack_depth := mfun_boundingbox_stack_depth - 1 ;
+enddef ;
+
+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
+ if (path p) or (picture p) :
+ llcorner p -- lrcorner p -- urcorner p -- ulcorner p
+ else :
+ origin
+ fi -- cycle
enddef;
-vardef inner_boundingbox primary p =
- top rt llcorner p --
- top lft lrcorner p --
- bot lft urcorner p --
- bot rt ulcorner p -- cycle
+vardef innerboundingbox primary p =
+ top rt llcorner p --
+ top lft lrcorner p --
+ bot lft urcorner p --
+ bot rt ulcorner p -- cycle
enddef;
-vardef outer_boundingbox primary p =
- bot lft llcorner p --
- bot rt lrcorner p --
- top rt urcorner p --
- top lft ulcorner p -- cycle
+vardef outerboundingbox primary p =
+ bot lft llcorner p --
+ bot rt lrcorner p --
+ top rt urcorner p --
+ top lft ulcorner p -- cycle
enddef;
-def innerboundingbox = inner_boundingbox enddef ;
-def outerboundingbox = outer_boundingbox enddef ;
+def inner_boundingbox = innerboundingbox enddef ;
+def outer_boundingbox = outerboundingbox enddef ;
-vardef set_inner_boundingbox text q =
- setbounds q to inner_boundingbox q;
+vardef set_inner_boundingbox text q = % obsolete
+ setbounds q to innerboundingbox q;
enddef;
-vardef set_outer_boundingbox text q =
- setbounds q to outer_boundingbox q;
+vardef set_outer_boundingbox text q = % obsolete
+ setbounds q to outerboundingbox q;
enddef;
-%D Some missing functions can be implemented rather
-%D straightforward:
-
-numeric Pi ; Pi := 3.1415926 ;
+%D Some missing functions can be implemented rather straightforward (thanks to
+%D Taco and others):
-vardef sqr primary x = (x*x) enddef ;
-vardef log primary x = (if x=0: 0 else: mlog(x)/mlog(10) fi) enddef ;
-vardef ln primary x = (if x=0: 0 else: mlog(x)/256 fi) enddef ;
-vardef exp primary x = ((mexp 256)**x) enddef ;
-vardef inv primary x = (if x=0: 0 else: x**-1 fi) enddef ;
+pi := 3.14159265358979323846 ; radian := 180/pi ; % 2pi*radian = 360 ;
-vardef pow (expr x,p) = (x**p) enddef ;
+% let +++ = ++ ;
-vardef asin primary x = (x+(x**3)/6+3(x**5)/40) enddef ;
-vardef acos primary x = (asin(-x)) enddef ;
-vardef atan primary x = (x-(x**3)/3+(x**5)/5-(x**7)/7) enddef ;
-vardef tand primary x = (sind(x)/cosd(x)) enddef ;
+numeric Pi ; Pi := pi ; % for some old compatibility reasons i guess
-%D Here are Taco Hoekwater's alternatives (but
-%D vardef'd and primaried).
+vardef sqr primary x = x*x enddef ;
+vardef log primary x = if x=0: 0 else: mlog(x)/mlog(10) fi enddef ;
+vardef ln primary x = if x=0: 0 else: mlog(x)/256 fi enddef ;
+vardef exp primary x = (mexp 256)**x enddef ;
+vardef inv primary x = if x=0: 0 else: x**-1 fi enddef ;
-pi := 3.1415926 ; radian := 180/pi ; % 2pi*radian = 360 ;
+vardef pow (expr x,p) = x**p enddef ;
-vardef tand primary x = (sind(x)/cosd(x)) enddef ;
-vardef cotd primary x = (cosd(x)/sind(x)) enddef ;
+vardef tand primary x = sind(x)/cosd(x) enddef ;
+vardef cotd primary x = cosd(x)/sind(x) enddef ;
-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 cot primary x = (cos(x)/sin(x)) enddef ;
+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 cot primary x = cos(x)/sin(x) enddef ;
-vardef asin primary x = angle((1+-+x,x)) enddef ;
-vardef acos primary x = angle((x,1+-+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 invsin primary x = (asin(x))/radian enddef ;
+vardef invcos primary x = (acos(x))/radian enddef ;
+vardef invtan primary x = (atan(x))/radian enddef ;
-vardef acosh primary x = ln(x+(x+-+1)) enddef ;
-vardef asinh primary x = ln(x+(x++1)) enddef ;
+vardef acosh primary x = ln(x+(x+-+1)) enddef ;
+vardef asinh primary x = ln(x+(x++1)) enddef ;
vardef sinh primary x = save xx ; xx = exp x ; (xx-1/xx)/2 enddef ;
vardef cosh primary x = save xx ; xx = exp x ; (xx+1/xx)/2 enddef ;
+%D Sometimes this is handy:
+
+def undashed =
+ dashed nullpicture
+enddef ;
+
%D We provide two macros for drawing stripes across a shape.
%D The first method (with the n suffix) uses another method,
%D slower in calculation, but more efficient when drawn. The
@@ -374,101 +387,218 @@ vardef cosh primary x = save xx ; xx = exp x ; (xx+1/xx)/2 enddef ;
%D the second argument identifier the way the shape is to be
%D drawn.
%D
-%D \starttypen
+%D \starttyping
%D stripe_path_n
%D (dashed evenly withcolor blue)
%D (filldraw)
%D fullcircle xscaled 100 yscaled 40 shifted (50,50) withpen pencircle scaled 4;
-%D \stoptypen
+%D \stoptyping
%D
%D The a (or angle) alternative supports arbitrary angles and
%D is therefore more versatile.
%D
-%D \starttypen
+%D \starttyping
%D stripe_path_a
%D (withpen pencircle scaled 2 withcolor red)
%D (draw)
%D fullcircle xscaled 100 yscaled 40 withcolor blue;
-%D \stoptypen
+%D \stoptyping
+%D
+%D We have two alternatives, controlled by arguments or defaults (when arguments
+%D are zero).
+%D
+%D The newer and nicer interface is used as follows (triggered by a question by Mari):
+%D
+%D \starttyping
+%D draw image (draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green) numberstriped (1,10,3) withcolor red ;
+%D draw image (draw fullcircle scaled 3cm shifted (3cm,0cm) withcolor green) numberstriped (2,20,3) withcolor green ;
+%D draw image (draw fullcircle scaled 3cm shifted (3cm,3cm) withcolor green) numberstriped (3,10,5) withcolor blue ;
+%D draw image (draw fullcircle scaled 3cm shifted (0cm,3cm) withcolor green) numberstriped (4,20,5) withcolor yellow ;
+%D
+%D draw image (draw fullcircle scaled 3cm shifted (6cm,0cm) withcolor green) anglestriped (1,20,2) withcolor red ;
+%D draw image (draw fullcircle scaled 3cm shifted (9cm,0cm) withcolor green) anglestriped (2,40,2) withcolor green ;
+%D draw image (draw fullcircle scaled 3cm shifted (9cm,3cm) withcolor green) anglestriped (3,60,2) withcolor blue ;
+%D draw image (draw fullcircle scaled 3cm shifted (6cm,3cm) withcolor green) anglestriped (4,80,2) withcolor yellow ;
%D
-%D The first alternative obeys:
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (9cm,0cm) numberstriped (1,10,3) withcolor red ;
+%D
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (12cm,0cm) numberstriped (2,10,3) withcolor red ;
+%D
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (9cm,5cm) numberstriped (3,10,3) withcolor red ;
+%D
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (12cm,5cm) numberstriped (4,10,3) withcolor red ;
+%D \stoptyping
stripe_n := 10;
stripe_slot := 3;
-
-%D When no pen dimensions are passed, the slot determines
-%D the spacing.
-%D
-%D The angle alternative is influenced by:
-
stripe_gap := 5;
stripe_angle := 45;
+def mfun_tool_striped_number_action text extra =
+ for i = 1/used_n step 1/used_n until 1 :
+ draw point (1+i) of bounds -- point (3-i) of bounds withpen pencircle scaled penwidth extra ;
+ endfor ;
+ for i = 0 step 1/used_n until 1 :
+ draw point (3+i) of bounds -- point (1-i) of bounds withpen pencircle scaled penwidth extra ;
+ endfor ;
+enddef ;
+
+def mfun_tool_striped_set_options(expr option) =
+ save isinner, swapped ;
+ boolean isinner, swapped ;
+ if option = 1 :
+ isinner := false ;
+ swapped := false ;
+ elseif option = 2 :
+ isinner := true ;
+ swapped := false ;
+ elseif option = 3 :
+ isinner := false ;
+ swapped := true ;
+ elseif option = 4 :
+ isinner := true ;
+ swapped := true ;
+ else :
+ isinner := false ;
+ swapped := false ;
+ fi ;
+enddef ;
+
+vardef mfun_tool_striped_number(expr option, p, s_n, s_slot) text extra =
+ image (
+ begingroup ;
+ save pattern, shape, bounds, penwidth, used_n, used_slot ;
+ picture pattern, shape ; path bounds ; numeric used_s, used_slot ;
+ mfun_tool_striped_set_options(option) ;
+ used_slot := if s_slot = 0 : stripe_slot else : s_slot fi ;
+ used_n := if s_n = 0 : stripe_n else : s_n fi ;
+ shape := image(draw p) ;
+ bounds := boundingbox shape ;
+ penwidth := min(ypart urcorner shape - ypart llcorner shape, xpart urcorner shape - xpart llcorner shape) / (used_slot * used_n) ;
+ pattern := image (
+ if isinner :
+ mfun_tool_striped_number_action extra ;
+ for s within shape :
+ if stroked s or filled s :
+ clip currentpicture to pathpart s ;
+ fi
+ endfor ;
+ else :
+ for s within shape :
+ if stroked s or filled s :
+ draw image (
+ mfun_tool_striped_number_action extra ;
+ clip currentpicture to pathpart s ;
+ ) ;
+ fi ;
+ endfor ;
+ fi ;
+ ) ;
+ if swapped :
+ addto currentpicture also shape ;
+ addto currentpicture also pattern ;
+ else :
+ addto currentpicture also pattern ;
+ 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 ;
+
+vardef mfun_tool_striped_angle(expr option, p, s_angle, s_gap) text extra =
+ 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 ;
+ mfun_tool_striped_set_options(option) ;
+ used_angle := if s_angle = 0 : stripe_angle else : s_angle fi ;
+ used_gap := if s_gap = 0 : stripe_gap else : s_gap fi ;
+ shape := image(draw p) ;
+ centrum := center 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) ;
+ 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 ;
+ fi
+ endfor ;
+ else :
+ for s within shape :
+ if stroked s or filled s :
+ draw image (
+ mfun_tool_striped_angle_action extra ;
+ clip currentpicture to pathpart s ;
+ ) ;
+ fi ;
+ endfor ;
+ fi ;
+ ) ;
+ if swapped :
+ addto currentpicture also shape ;
+ addto currentpicture also pattern ;
+ else :
+ addto currentpicture also pattern ;
+ addto currentpicture also shape ;
+ fi ;
+ currentpicture := currentpicture shifted - centrum ;
+ endgroup ;
+ )
+enddef;
+
+newinternal striped_normal_inner ; striped_normal_inner := 1 ;
+newinternal striped_reverse_inner ; striped_reverse_inner := 2 ;
+newinternal striped_normal_outer ; striped_normal_outer := 3 ;
+newinternal striped_reverse_outer ; striped_reverse_outer := 4 ;
+
+secondarydef p anglestriped s =
+ mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)
+enddef ;
+
+secondarydef p numberstriped s =
+ mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)
+enddef ;
+
+% for old times sake:
+
def stripe_path_n (text s_spec) (text s_draw) expr s_path =
- do_stripe_path_n (s_spec) (s_draw) (s_path)
+ do_stripe_path_n (s_spec) (s_draw) (s_path)
enddef;
def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text =
- begingroup
- save curpic, newpic, bb, pp, ww;
- picture curpic, newpic;
- path bb, pp;
- pp := s_path;
- curpic := currentpicture;
- currentpicture := nullpicture;
- s_draw pp s_text;
- bb := boundingbox currentpicture;
- newpic := currentpicture;
- currentpicture := nullpicture;
- ww := min(ypart urcorner newpic - ypart llcorner newpic,
- xpart urcorner newpic - xpart llcorner newpic);
- ww := ww/(stripe_slot*stripe_n);
- for i=1/stripe_n step 1/stripe_n until 1:
- draw point (1+i) of bb -- point (3-i) of bb
- withpen pencircle scaled ww s_spec ;
- endfor;
- for i=0 step 1/stripe_n until 1:
- draw point (3+i) of bb -- point (1-i) of bb
- withpen pencircle scaled ww s_spec;
- endfor;
- clip currentpicture to pp;
- addto newpic also currentpicture;
- currentpicture := curpic;
- addto currentpicture also newpic;
- endgroup
-enddef;
+ draw image(s_draw s_path s_text) numberstriped(3,0,0) s_spec ;
+enddef ;
def stripe_path_a (text s_spec) (text s_draw) expr s_path =
- do_stripe_path_a (s_spec) (s_draw) (s_path)
+ do_stripe_path_a (s_spec) (s_draw) (s_path)
enddef;
def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text =
- begingroup
- save curpic, newpic, pp; picture curpic, newpic; path pp ;
- pp := s_path ;
- curpic := currentpicture;
- currentpicture := nullpicture;
- s_draw pp s_text ;
- def do_stripe_rotation (expr p) =
- (currentpicture rotatedaround(center p,stripe_angle))
- enddef ;
- s_max := max
- (xpart llcorner do_stripe_rotation(currentpicture),
- xpart urcorner do_stripe_rotation(currentpicture),
- ypart llcorner do_stripe_rotation(currentpicture),
- ypart urcorner do_stripe_rotation(currentpicture));
- newpic := currentpicture;
- currentpicture := nullpicture;
- for i=-s_max-.5stripe_gap step stripe_gap until s_max:
- draw (-s_max,i)--(s_max,i) s_spec;
- endfor;
- currentpicture := do_stripe_rotation(newpic);
- clip currentpicture to pp ;
- addto newpic also currentpicture;
- currentpicture := curpic;
- addto currentpicture also newpic;
- endgroup
-enddef;
+ draw image(s_draw s_path s_text) anglestriped(3,0,0) s_spec ;
+enddef ;
%D A few normalizing macros:
%D
@@ -507,46 +637,43 @@ enddef;
% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture;
% currentpicture := currentpicture scaled (the_width/natural_width) ;
-% TODO TODO TODO TODO, not yet ok
-
primarydef p xsized w =
- (p if (bbwidth (p)>0) and (w>0) : scaled (w/bbwidth (p)) fi)
+ (p if (bbwidth (p)>0) and (w>0) : scaled (w/bbwidth (p)) fi)
enddef ;
primarydef p ysized h =
- (p if (bbheight(p)>0) and (h>0) : scaled (h/bbheight(p)) fi)
+ (p if (bbheight(p)>0) and (h>0) : scaled (h/bbheight(p)) fi)
enddef ;
primarydef p xysized s =
- begingroup ;
+ 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
+ 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 sized wh =
- (p xysized wh)
-enddef ;
+let sized = xysized ;
-def xscale_currentpicture(expr w) =
- currentpicture := currentpicture xsized w ;
+def xscale_currentpicture(expr w) = % obsolete
+ currentpicture := currentpicture xsized w ;
enddef;
-def yscale_currentpicture(expr h) =
- currentpicture := currentpicture ysized h ;
+def yscale_currentpicture(expr h) = % obsolete
+ currentpicture := currentpicture ysized h ;
enddef;
-def xyscale_currentpicture(expr w, h) =
- currentpicture := currentpicture xysized (w,h) ;
+def xyscale_currentpicture(expr w, h) = % obsolete
+ currentpicture := currentpicture xysized (w,h) ;
enddef;
-def scale_currentpicture(expr w, h) =
- currentpicture := currentpicture xsized w ;
- currentpicture := currentpicture ysized h ;
+def scale_currentpicture(expr w, h) = % obsolete
+ currentpicture := currentpicture xsized w ;
+ currentpicture := currentpicture ysized h ;
enddef;
%D A full circle is centered at the origin, while a unitsquare
@@ -562,28 +689,28 @@ unitcircle := fullcircle shifted urcorner fullcircle ;
path urcircle, ulcircle, llcircle, lrcircle ;
-urcircle := origin--(+.5,0)&(+.5,0){up} ..(0,+.5)&(0,+.5)--cycle ;
-ulcircle := origin--(0,+.5)&(0,+.5){left} ..(-.5,0)&(-.5,0)--cycle ;
-llcircle := origin--(-.5,0)&(-.5,0){down} ..(0,-.5)&(0,-.5)--cycle ;
-lrcircle := origin--(0,-.5)&(0,-.5){right}..(+.5,0)&(+.5,0)--cycle ;
+urcircle := origin -- (+.5,0) & (+.5,0){up} .. (0,+.5) & (0,+.5) -- cycle ;
+ulcircle := origin -- (0,+.5) & (0,+.5){left} .. (-.5,0) & (-.5,0) -- cycle ;
+llcircle := origin -- (-.5,0) & (-.5,0){down} .. (0,-.5) & (0,-.5) -- cycle ;
+lrcircle := origin -- (0,-.5) & (0,-.5){right} .. (+.5,0) & (+.5,0) -- cycle ;
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 ;
+path urtriangle, ultriangle, lltriangle, lrtriangle ; % watch out: it's contrary to what you expect and starts in the origin
-urtriangle := origin--(+.5,0)--(0,+.5)--cycle ;
-ultriangle := origin--(0,+.5)--(-.5,0)--cycle ;
-lltriangle := origin--(-.5,0)--(0,-.5)--cycle ;
-lrtriangle := origin--(0,-.5)--(+.5,0)--cycle ;
+urtriangle := origin -- (+.5,0) -- (0,+.5) -- cycle ;
+ultriangle := origin -- (0,+.5) -- (-.5,0) -- cycle ;
+lltriangle := origin -- (-.5,0) -- (0,-.5) -- cycle ;
+lrtriangle := origin -- (0,-.5) -- (+.5,0) -- cycle ;
path unitdiamond, fulldiamond ;
-unitdiamond := (.5,0)--(1,.5)--(.5,1)--(0,.5)--cycle ;
+unitdiamond := (.5,0) -- (1,.5) -- (.5,1) -- (0,.5) -- cycle ;
fulldiamond := unitdiamond shifted - center unitdiamond ;
%D More robust:
@@ -598,46 +725,49 @@ fulldiamond := unitdiamond shifted - center unitdiamond ;
%D Shorter
-primarydef p xyscaled q =
- begingroup ; save qq ; pair qq ; qq = paired(q) ;
- ( p
- if xpart qq<>0 : xscaled (xpart qq) fi
- if ypart qq<>0 : yscaled (ypart qq) fi )
- endgroup
+primarydef p xyscaled q = % secundarydef does not work out well
+ begingroup
+ save qq ; pair qq ;
+ qq = paired(q) ;
+ p
+ if xpart qq <> 0 : xscaled (xpart qq) fi
+ if ypart qq <> 0 : yscaled (ypart qq) fi
+ endgroup
enddef ;
-%D Experimenteel, zie folder-3.tex.
+%D Some personal code that might move to another module
def set_grid(expr w, h, nx, ny) =
- boolean grid[][] ; boolean grid_full ;
- grid_w := w ;
- grid_h := h ;
- grid_nx := nx ;
- grid_ny := ny ;
- grid_x := round(w/grid_nx) ; % +.5) ;
- grid_y := round(h/grid_ny) ; % +.5) ;
- grid_left := (1+grid_x)*(1+grid_y) ;
- grid_full := false ;
- for i=0 upto grid_x:
- for j=0 upto grid_y:
- grid[i][j] := false ;
+ boolean grid[][] ; boolean grid_full ;
+ numeric grid_w, grid_h, grid_nx, grid_ny, grid_x, grid_y, grid_left ;
+ grid_w := w ;
+ grid_h := h ;
+ grid_nx := nx ;
+ grid_ny := ny ;
+ grid_x := round(w/grid_nx) ; % +.5) ;
+ grid_y := round(h/grid_ny) ; % +.5) ;
+ grid_left := (1+grid_x)*(1+grid_y) ;
+ grid_full := false ;
+ for i=0 upto grid_x :
+ for j=0 upto grid_y :
+ grid[i][j] := false ;
+ endfor ;
endfor ;
- endfor ;
enddef ;
vardef new_on_grid(expr _dx_, _dy_) =
- dx := _dx_ ;
- dy := _dy_ ;
- ddx := min(round(dx/grid_nx),grid_x) ; % +.5),grid_x) ;
- ddy := min(round(dy/grid_ny),grid_y) ; % +.5),grid_y) ;
- if not grid_full and not grid[ddx][ddy]:
- grid[ddx][ddy] := true ;
- grid_left := grid_left-1 ;
- grid_full := (grid_left=0) ;
- true
- else:
- false
- fi
+ dx := _dx_ ;
+ dy := _dy_ ;
+ ddx := min(round(dx/grid_nx),grid_x) ; % +.5),grid_x) ;
+ ddy := min(round(dy/grid_ny),grid_y) ; % +.5),grid_y) ;
+ if not grid_full and not grid[ddx][ddy] :
+ grid[ddx][ddy] := true ;
+ grid_left := grid_left-1 ;
+ grid_full := (grid_left=0) ;
+ true
+ else :
+ false
+ fi
enddef ;
%D usage: \type{innerpath peepholed outerpath}.
@@ -650,79 +780,71 @@ enddef ;
%D endfig;
secondarydef p peepholed q =
- begingroup ;
- save start ; pair start ; start := point 0 of p ;
- if xpart start >= xpart center p :
- if ypart start >= ypart center p :
- urcorner q -- ulcorner q -- llcorner q -- lrcorner q --
- reverse p -- lrcorner q -- cycle
- else :
- lrcorner q -- urcorner q -- ulcorner q -- llcorner q --
- reverse p -- llcorner q -- cycle
- fi
- else :
- if ypart start > ypart center p :
- ulcorner q -- llcorner q -- lrcorner q -- urcorner q --
- reverse p -- urcorner q -- cycle
+ begingroup
+ save start ; pair start ;
+ start := point 0 of p ;
+ if xpart start >= xpart center p :
+ if ypart start >= ypart center p :
+ urcorner q -- ulcorner q -- llcorner q -- lrcorner q --
+ reverse p -- lrcorner q -- cycle
+ else :
+ lrcorner q -- urcorner q -- ulcorner q -- llcorner q --
+ reverse p -- llcorner q -- cycle
+ fi
else :
- llcorner q -- lrcorner q -- urcorner q -- ulcorner q --
- reverse p -- ulcorner q -- cycle
+ if ypart start > ypart center p :
+ ulcorner q -- llcorner q -- lrcorner q -- urcorner q --
+ reverse p -- urcorner q -- cycle
+ else :
+ llcorner q -- lrcorner q -- urcorner q -- ulcorner q --
+ reverse p -- ulcorner q -- cycle
+ fi
fi
- fi
- endgroup
+ endgroup
enddef ;
boolean intersection_found ;
secondarydef p intersection_point q =
- begingroup
+ begingroup
save x_, y_ ;
(x_,y_) = p intersectiontimes q ;
if x_<0 :
- intersection_found := false ;
- center p % origin
+ intersection_found := false ;
+ center p % origin
else :
- intersection_found := true ;
- .5[point x_ of p, point y_ of q]
+ intersection_found := true ;
+ .5[point x_ of p, point y_ of q]
fi
- endgroup
+ endgroup
enddef ;
%D New, undocumented, experimental:
vardef tensecircle (expr width, height, offset) =
- ((-width/2,-height/2) ... (0,-height/2-offset) ...
- (+width/2,-height/2) ... (+width/2+offset,0) ...
- (+width/2,+height/2) ... (0,+height/2+offset) ...
- (-width/2,+height/2) ... (-width/2-offset,0) ... cycle)
+ (-width/2,-height/2) ... (0,-height/2-offset) ...
+ (+width/2,-height/2) ... (+width/2+offset,0) ...
+ (+width/2,+height/2) ... (0,+height/2+offset) ...
+ (-width/2,+height/2) ... (-width/2-offset,0) ... cycle
enddef ;
-%vardef tensecircle (expr width, height, offset) =
-% ((-width/2,-height/2)..(0,-height/2-offset)..(+width/2,-height/2) &
-% (+width/2,-height/2)..(+width/2+offset,0)..(+width/2,+height/2) &
-% (+width/2,+height/2)..(0,+height/2+offset)..(-width/2,+height/2) &
-% (-width/2,+height/2)..(-width/2-offset,0)..(-width/2,-height/2)..cycle)
-%enddef ;
-
vardef roundedsquare (expr width, height, offset) =
- ((offset,0)--(width-offset,0){right} ..
- (width,offset)--(width,height-offset){up} ..
- (width-offset,height)--(offset,height){left} ..
- (0,height-offset)--(0,offset){down} .. cycle)
+ (offset,0) -- (width-offset,0) {right} ..
+ (width,offset) -- (width,height-offset) {up} ..
+ (width-offset,height) -- (offset,height) {left} ..
+ (0,height-offset) -- (0,offset) {down} .. cycle
enddef ;
%D Some colors.
-color cyan ; cyan = (0,1,1) ;
-color magenta ; magenta = (1,0,1) ;
-color yellow ; yellow = (1,1,0) ;
-
def colortype(expr c) =
if cmykcolor c : cmykcolor elseif rgbcolor c : rgbcolor else : grayscale fi
enddef ;
+
vardef whitecolor(expr c) =
if cmykcolor c : (0,0,0,0) elseif rgbcolor c : (1,1,1) else : 1 fi
enddef ;
+
vardef blackcolor(expr c) =
if cmykcolor c : (0,0,0,1) elseif rgbcolor c : (0,0,0) else : 0 fi
enddef ;
@@ -730,112 +852,74 @@ enddef ;
%D Well, this is the dangerous and naive version:
def drawfill text t =
- fill t ;
- draw t ;
+ fill t ;
+ draw t ;
enddef;
%D This two step approach saves the path first, since it can
%D be a function. Attributes must not be randomized.
def drawfill expr c =
- path _c_ ; _c_ := c ;
- do_drawfill
+ path _c_ ; _c_ := c ;
+ mfun_do_drawfill
enddef ;
-def do_drawfill text t =
- draw _c_ t ;
- fill _c_ t ;
+def mfun_do_drawfill text t =
+ draw _c_ t ;
+ fill _c_ t ;
enddef;
def undrawfill expr c =
- drawfill c withcolor background
+ drawfill c withcolor background % rather useless
enddef ;
%D Moved from mp-char.mp
-vardef paired (expr d) =
- if pair d : d else : (d,d) fi
-enddef ;
-
-vardef tripled (expr d) =
- if color d : d else : (d,d,d) fi
-enddef ;
-
-primarydef p enlarged d =
- (p llmoved d -- p lrmoved d -- p urmoved d -- p ulmoved d -- cycle)
-enddef;
-
-primarydef p llenlarged d =
- (p llmoved d -- lrcorner p -- urcorner p -- ulcorner p -- cycle)
-enddef ;
-
-primarydef p lrenlarged d =
- (llcorner p -- p lrmoved d -- urcorner p -- ulcorner p -- cycle)
+vardef paired primary d =
+ if pair d : d else : (d,d) fi
enddef ;
-primarydef p urenlarged d =
- (llcorner p -- lrcorner p -- p urmoved d -- ulcorner p -- cycle)
+vardef tripled primary d =
+ if color d : d else : (d,d,d) fi
enddef ;
-primarydef p ulenlarged d =
- (llcorner p -- lrcorner p -- urcorner p -- p ulmoved d -- cycle)
-enddef ;
+% maybe secondaries:
-primarydef p llmoved d =
- ((llcorner p) shifted (-xpart paired(d),-ypart paired(d)))
-enddef ;
+primarydef p enlarged d = ( p llmoved d -- p lrmoved d -- p urmoved d -- p ulmoved d -- cycle ) enddef ;
+primarydef p llenlarged d = ( p llmoved d -- lrcorner p -- urcorner p -- ulcorner p -- cycle ) enddef ;
+primarydef p lrenlarged d = ( llcorner p -- p lrmoved d -- urcorner p -- ulcorner p -- cycle ) enddef ;
+primarydef p urenlarged d = ( llcorner p -- lrcorner p -- p urmoved d -- ulcorner p -- cycle ) enddef ;
+primarydef p ulenlarged d = ( llcorner p -- lrcorner p -- urcorner p -- p ulmoved d -- cycle ) enddef ;
-primarydef p lrmoved d =
- ((lrcorner p) shifted (+xpart paired(d),-ypart paired(d)))
-enddef ;
-
-primarydef p urmoved d =
- ((urcorner p) shifted (+xpart paired(d),+ypart paired(d)))
-enddef ;
-
-primarydef p ulmoved d =
- ((ulcorner p) shifted (-xpart paired(d),+ypart paired(d)))
-enddef ;
-
-primarydef p leftenlarged d =
- ((llcorner p) shifted (-d,0) -- lrcorner p --
- urcorner p -- (ulcorner p) shifted (-d,0) -- cycle)
-enddef ;
-
-primarydef p rightenlarged d =
- (llcorner p -- (lrcorner p) shifted (d,0) --
- (urcorner p) shifted (d,0) -- ulcorner p -- cycle)
-enddef ;
-
-primarydef p topenlarged d =
- (llcorner p -- lrcorner p --
- (urcorner p) shifted (0,d) -- (ulcorner p) shifted (0,d) -- cycle)
-enddef ;
+primarydef p llmoved d = ( (llcorner p) shifted (-xpart paired(d),-ypart paired(d)) ) enddef ;
+primarydef p lrmoved d = ( (lrcorner p) shifted (+xpart paired(d),-ypart paired(d)) ) enddef ;
+primarydef p urmoved d = ( (urcorner p) shifted (+xpart paired(d),+ypart paired(d)) ) enddef ;
+primarydef p ulmoved d = ( (ulcorner p) shifted (-xpart paired(d),+ypart paired(d)) ) enddef ;
-primarydef p bottomenlarged d =
- (llcorner p shifted (0,-d) -- lrcorner p shifted (0,-d) --
- urcorner p -- ulcorner p -- cycle)
-enddef ;
+primarydef p leftenlarged d = ( (llcorner p) shifted (-d,0) -- lrcorner p -- urcorner p -- (ulcorner p) shifted (-d,0) -- cycle ) enddef ;
+primarydef p rightenlarged d = ( llcorner p -- (lrcorner p) shifted (d,0) -- (urcorner p) shifted (d,0) -- ulcorner p -- cycle ) enddef ;
+primarydef p topenlarged d = ( llcorner p -- lrcorner p -- (urcorner p) shifted (0,d) -- (ulcorner p) shifted (0,d) -- cycle ) enddef ;
+primarydef p bottomenlarged d = ( llcorner p shifted (0,-d) -- lrcorner p shifted (0,-d) -- urcorner p -- ulcorner p -- cycle ) enddef ;
%D Handy for testing/debugging:
-primarydef p crossed d =
+primarydef p crossed d = (
if pair p :
- (p shifted (-d, 0) -- p --
- p shifted ( 0,-d) -- p --
- p shifted (+d, 0) -- p --
- p shifted ( 0,+d) -- p -- cycle)
+ p shifted (-d, 0) -- p --
+ p shifted ( 0,-d) -- p --
+ p shifted (+d, 0) -- p --
+ p shifted ( 0,+d) -- p -- cycle
else :
- (center p shifted (-d, 0) -- llcorner p --
- center p shifted ( 0,-d) -- lrcorner p --
- center p shifted (+d, 0) -- urcorner p --
- center p shifted ( 0,+d) -- ulcorner p -- cycle)
+ center p shifted (-d, 0) -- llcorner p --
+ center p shifted ( 0,-d) -- lrcorner p --
+ center p shifted (+d, 0) -- urcorner p --
+ center p shifted ( 0,+d) -- ulcorner p -- cycle
fi
-enddef ;
+) enddef ;
%D Also handy (math ladders):
-vardef laddered expr p =
+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)
@@ -849,182 +933,143 @@ enddef ;
% vardef topboundary primary p = (urcorner p -- ulcorner p) enddef ;
% vardef leftboundary primary p = (ulcorner p -- llcorner p) enddef ;
-vardef bottomboundary primary p =
- if pair p : p else : (llcorner p -- lrcorner p) fi
-enddef ;
-
-vardef rightboundary primary p =
- if pair p : p else : (lrcorner p -- urcorner p) fi
-enddef ;
-
-vardef topboundary primary p =
- if pair p : p else : (urcorner p -- ulcorner p) fi
-enddef ;
-
-vardef leftboundary primary p =
- if pair p : p else : (ulcorner p -- llcorner p) fi
-enddef ;
+vardef bottomboundary primary p = if pair p : p else : (llcorner p -- lrcorner p) fi enddef ;
+vardef rightboundary primary p = if pair p : p else : (lrcorner p -- urcorner p) fi enddef ;
+vardef topboundary primary p = if pair p : p else : (urcorner p -- ulcorner p) fi enddef ;
+vardef leftboundary primary p = if pair p : p else : (ulcorner p -- llcorner p) fi enddef ;
%D Nice too:
primarydef p superellipsed s =
- superellipse
- (.5[lrcorner p,urcorner p],
- .5[urcorner p,ulcorner p],
- .5[ulcorner p,llcorner p],
- .5[llcorner p,lrcorner p],
- s)
-enddef ;
+ superellipse (
+ .5[lrcorner p,urcorner p],
+ .5[urcorner p,ulcorner p],
+ .5[ulcorner p,llcorner p],
+ .5[llcorner p,lrcorner p],
+ s
+ )
+enddef ;
+
+primarydef p squeezed s = (
+ (llcorner p .. .5[llcorner p,lrcorner p] shifted ( 0, ypart paired(s)) .. lrcorner p) &
+ (lrcorner p .. .5[lrcorner p,urcorner p] shifted (-xpart paired(s), 0) .. urcorner p) &
+ (urcorner p .. .5[urcorner p,ulcorner p] shifted ( 0,-ypart paired(s)) .. ulcorner p) &
+ (ulcorner p .. .5[ulcorner p,llcorner p] shifted ( xpart paired(s), 0) .. llcorner p) & cycle
+) enddef ;
-primarydef p squeezed s =
- ((llcorner p .. .5[llcorner p,lrcorner p] shifted ( 0, ypart paired(s)) .. lrcorner p) &
- (lrcorner p .. .5[lrcorner p,urcorner p] shifted (-xpart paired(s), 0) .. urcorner p) &
- (urcorner p .. .5[urcorner p,ulcorner p] shifted ( 0,-ypart paired(s)) .. ulcorner p) &
- (ulcorner p .. .5[ulcorner p,llcorner p] shifted ( xpart paired(s), 0) .. llcorner p) & cycle)
+primarydef p randomshifted s =
+ begingroup ;
+ save ss ; pair ss ;
+ ss := paired(s) ;
+ p shifted (-.5xpart ss + uniformdeviate xpart ss,-.5ypart ss + uniformdeviate ypart ss)
+ endgroup
enddef ;
-primarydef p randomshifted s =
- begingroup ; save ss ; pair ss ; ss := paired(s) ;
- p shifted (-.5xpart ss + uniformdeviate xpart ss,
- -.5ypart ss + uniformdeviate ypart ss)
- endgroup
-enddef ;
-
-%primarydef p randomized s =
-% for i=0 upto length(p)-1 :
-% ((point i of p) randomshifted s) .. controls
-% ((postcontrol i of p) randomshifted s) and
-% ((precontrol (i+1) of p) randomshifted s) ..
-% endfor cycle
-%enddef ;
-
-primarydef p randomized s =
- (if path p :
- for i=0 upto length(p)-1 :
- ((point i of p) randomshifted s) .. 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) randomshifted s)
- fi
- elseif pair p :
- p randomshifted s
- elseif cmykcolor p :
- if color s :
- (uniformdeviate cyanpart s * cyanpart p,
- uniformdeviate magentapart s * magentapart p,
- uniformdeviate yellowpart s * yellowpart p,
- uniformdeviate blackpart s * blackpart p)
- elseif pair s :
- ((xpart s + uniformdeviate (ypart s - xpart s)) * p)
- else :
- (uniformdeviate s * p)
- fi
- elseif rgbcolor p :
- if color s :
- (uniformdeviate redpart s * redpart p,
- uniformdeviate greenpart s * greenpart p,
- uniformdeviate bluepart s * bluepart p)
- elseif pair s :
- ((xpart s + uniformdeviate (ypart s - xpart s)) * p)
- else :
- (uniformdeviate s * p)
- fi
- elseif color p :
- if color s :
- (uniformdeviate graypart s * graypart p)
- elseif pair s :
- ((xpart s + uniformdeviate (ypart s - xpart s)) * p)
+primarydef p randomized s = (
+ if path p :
+ for i=0 upto length(p)-1 :
+ ((point i of p) randomshifted s) .. 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) randomshifted s)
+ fi
+ elseif pair p :
+ p randomshifted s
+ elseif cmykcolor p :
+ if color s :
+ ((uniformdeviate cyanpart s) * cyanpart p,
+ (uniformdeviate magentapart s) * magentapart p,
+ (uniformdeviate yellowpart s) * yellowpart p,
+ (uniformdeviate blackpart s) * blackpart p)
+ elseif pair s :
+ ((xpart s + (uniformdeviate (ypart s - xpart s))) * p)
+ else :
+ ((uniformdeviate s) * p)
+ fi
+ elseif rgbcolor p :
+ if color s :
+ ((uniformdeviate redpart s) * redpart p,
+ (uniformdeviate greenpart s) * greenpart p,
+ (uniformdeviate bluepart s) * bluepart p)
+ elseif pair s :
+ ((xpart s + (uniformdeviate (ypart s - xpart s))) * p)
+ else :
+ ((uniformdeviate s) * p)
+ fi
+ elseif color p :
+ if color s :
+ ((uniformdeviate greypart s) * greypart p)
+ elseif pair s :
+ ((xpart s + (uniformdeviate (ypart s - xpart s))) * p)
+ else :
+ ((uniformdeviate s) * p)
+ fi
else :
- (uniformdeviate s * p)
+ p + uniformdeviate s
fi
- else :
- p + uniformdeviate s
- fi)
-enddef ;
+) enddef ;
%D Not perfect (alternative for interpath)
vardef interpolated(expr s, p, q) =
- save m ; m := max(length(p),length(q)) ;
- (if path p :
- for i=0 upto m-1 :
- s[point (i /m) along p,
- point (i /m) along q] .. controls
- s[postcontrol (i /m) along p,
- postcontrol (i /m) along q] and
- s[precontrol ((i+1)/m) along p,
- precontrol ((i+1)/m) along q] ..
- endfor
- if cycle p :
- cycle
- else :
- s[point infinity of p,
- point infinity of q]
- fi
- else :
- a[p,q]
- fi)
+ save m ; numeric m ;
+ m := max(length(p),length(q)) ;
+ if path p :
+ for i=0 upto m-1 :
+ s[point (i /m) along p,point (i /m) along q] .. controls
+ s[postcontrol (i /m) along p,postcontrol (i /m) along q] and
+ s[precontrol ((i+1)/m) along p,precontrol ((i+1)/m) along q] ..
+ endfor
+ if cycle p :
+ cycle
+ else :
+ s[point infinity of p,point infinity of q]
+ fi
+ else :
+ a[p,q]
+ fi
enddef ;
%D Interesting too:
-% primarydef p parallel s =
-% begingroup ; save q, b ; path q ; numeric b ;
-% b := xpart (lrcorner p - llcorner p) ;
-% q := p if b>0 : scaled ((b+2s)/b) fi ;
-% (q shifted (center p-center q))
-% endgroup
-% enddef ;
-
-%primarydef p parallel s =
-% begingroup ; save q, w,h ; path q ; numeric w, h ;
-% w := bbwidth(p) ; h := bbheight(p) ;
-% q := p if (w>0) and (h>0) :
-% xyscaled ((w+2*xpart paired(s))/w,(h+2*ypart paired(s))/h) fi ;
-% (q shifted (center p-center q))
-% endgroup
-%enddef ;
-
-primarydef p paralleled d =
+primarydef p paralleled d = (
p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p)
-enddef ;
+) enddef ;
vardef punked primary p =
- (point 0 of p for i=1 upto length(p)-1 : -- point i of p endfor
- if cycle p : -- cycle else : -- point length(p) of p fi)
+ point 0 of p for i=1 upto length(p)-1 : -- point i of p endfor
+ if cycle p : -- cycle else : -- point length(p) of p fi
enddef ;
vardef curved primary p =
- (point 0 of p for i=1 upto length(p)-1 : .. point i of p endfor
- if cycle p : .. cycle else : .. point length(p) of p fi)
+ point 0 of p for i=1 upto length(p)-1 : .. point i of p endfor
+ if cycle p : .. cycle else : .. point length(p) of p fi
enddef ;
primarydef p blownup s =
- begingroup
- save _p_ ; path _p_ ; _p_ := p xysized
- (bbwidth (p)+2(xpart paired(s)),
- bbheight(p)+2(ypart paired(s))) ;
- (_p_ shifted (center p - center _p_))
- endgroup
+ begingroup
+ save _p_ ; path _p_ ;
+ _p_ := p xysized (bbwidth(p)+2(xpart paired(s)),bbheight(p)+2(ypart paired(s))) ;
+ (_p_ shifted (center p - center _p_))
+ endgroup
enddef ;
%D Rather fundamental.
% not yet ok
-def leftrightpath(expr p, l) = % used in s-pre-19
- save q, r, t, b ; path q, r ; pair t, b ;
- t := (ulcorner p -- urcorner p) intersection_point p ;
- b := (llcorner p -- lrcorner p) intersection_point p ;
- r := if xpart directionpoint t of p < 0 : reverse p else : p fi ; % r is needed, else problems when reverse is fed
- q := r cutbefore if l: t else: b fi ;
- q := q if xpart point 0 of r > 0 : &
- r fi cutafter if l: b else: t fi ;
- q
+vardef leftrightpath(expr p, l) = % used in s-pre-19
+ save q, r, t, b ; path q, r ; pair t, b ;
+ t := (ulcorner p -- urcorner p) intersection_point p ;
+ b := (llcorner p -- lrcorner p) intersection_point p ;
+ r := if xpart directionpoint t of p < 0 : reverse p else : p fi ; % r is needed, else problems when reverse is fed
+ q := r cutbefore if l: t else: b fi ;
+ q := q if xpart point 0 of r > 0 : & r fi cutafter if l: b else: t fi ;
+ q
enddef ;
vardef leftpath expr p = leftrightpath(p,true ) enddef ;
@@ -1033,10 +1078,10 @@ vardef rightpath expr p = leftrightpath(p,false) enddef ;
%D Drawoptions
def saveoptions =
- save _op_ ; def _op_ = enddef ;
+ save _op_ ; def _op_ = enddef ;
enddef ;
-%D Tracing.
+%D Tracing. (not yet in lexer)
let normaldraw = draw ;
let normalfill = fill ;
@@ -1046,7 +1091,6 @@ let normalfill = fill ;
def normalfill expr c = addto currentpicture contour c _op_ enddef ;
def normaldraw expr p = addto currentpicture if picture p: also p else: doublepath p withpen currentpen fi _op_ enddef ;
-
def drawlineoptions (text t) = def _lin_opt_ = t enddef ; enddef ;
def drawpointoptions (text t) = def _pnt_opt_ = t enddef ; enddef ;
def drawcontroloptions(text t) = def _ctr_opt_ = t enddef ; enddef ;
@@ -1056,13 +1100,13 @@ def drawboundoptions (text t) = def _bnd_opt_ = t enddef ; enddef ;
def drawpathoptions (text t) = def _pth_opt_ = t enddef ; enddef ;
def resetdrawoptions =
- drawlineoptions (withpen pencircle scaled 1pt withcolor .5white) ;
- drawpointoptions (withpen pencircle scaled 4pt withcolor black) ;
- drawcontroloptions(withpen pencircle scaled 2.5pt withcolor black) ;
- drawlabeloptions () ;
- draworiginoptions (withpen pencircle scaled 1pt withcolor .5white) ;
- drawboundoptions (dashed evenly _ori_opt_) ;
- drawpathoptions (withpen pencircle scaled 5pt withcolor .8white) ;
+ drawlineoptions (withpen pencircle scaled 1pt withcolor .5white) ;
+ drawpointoptions (withpen pencircle scaled 4pt withcolor black) ;
+ drawcontroloptions(withpen pencircle scaled 2.5pt withcolor black) ;
+ drawlabeloptions () ;
+ draworiginoptions (withpen pencircle scaled 1pt withcolor .5white) ;
+ drawboundoptions (dashed evenly _ori_opt_) ;
+ drawpathoptions (withpen pencircle scaled 5pt withcolor .8white) ;
enddef ;
resetdrawoptions ;
@@ -1070,96 +1114,95 @@ resetdrawoptions ;
%D Path.
def drawpath expr p =
- normaldraw p _pth_opt_
+ normaldraw p _pth_opt_
enddef ;
%D Arrow.
vardef drawarrowpath expr p =
- save autoarrows ; boolean autoarrows ; autoarrows := true ;
- drawarrow p _pth_opt_
+ save autoarrows ; boolean autoarrows ; autoarrows := true ;
+ drawarrow p _pth_opt_
enddef ;
-%def drawarrowpath expr p =
-% begingroup ;
-% save autoarrows ; boolean autoarrows ; autoarrows := true ;
-% save arrowpath ; path arrowpath ; arrowpath := p ;
-% _drawarrowpath_
-%enddef ;
+% def drawarrowpath expr p =
+% begingroup ;
+% save autoarrows ; boolean autoarrows ; autoarrows := true ;
+% save arrowpath ; path arrowpath ; arrowpath := p ;
+% _drawarrowpath_
+% enddef ;
%
-%def _drawarrowpath_ text t =
-% drawarrow arrowpath _pth_opt_ t ;
-% endgroup ;
-%enddef ;
+% def _drawarrowpath_ text t =
+% drawarrow arrowpath _pth_opt_ t ;
+% endgroup ;
+% enddef ;
def midarrowhead expr p =
- arrowhead p cutafter
- (point length(p cutafter point .5 along p)+ahlength on p)
+ arrowhead p cutafter (point length(p cutafter point .5 along p)+ahlength on p)
enddef ;
vardef arrowheadonpath (expr p, s) =
- save autoarrows ; boolean autoarrows ; autoarrows := true ;
- set_ahlength(scaled ahfactor) ; % added
- arrowhead p if s<1 : cutafter (point (s*arclength(p)+.5ahlength) on p) fi
+ save autoarrows ; boolean autoarrows ;
+ autoarrows := true ;
+ set_ahlength(scaled ahfactor) ; % added
+ arrowhead p if s<1 : cutafter (point (s*arclength(p)+.5ahlength) on p) fi
enddef ;
%D Points.
def drawpoint expr c =
- if string c :
- string _c_ ; _c_ := "(" & c & ")" ;
- dotlabel.urt(_c_, scantokens _c_) ;
- drawdot scantokens _c_
- else :
- dotlabel.urt("(" & decimal xpart c & "," & decimal ypart c & ")", c) ;
- drawdot c
- fi _pnt_opt_
+ if string c :
+ string _c_ ;
+ _c_ := "(" & c & ")" ;
+ dotlabel.urt(_c_, scantokens _c_) ;
+ drawdot scantokens _c_
+ else :
+ dotlabel.urt("(" & decimal xpart c & "," & decimal ypart c & ")", c) ;
+ drawdot c
+ fi _pnt_opt_
enddef ;
%D PathPoints.
-def drawpoints expr c = path _c_ ; _c_ := c ; do_drawpoints enddef ;
-def drawcontrolpoints expr c = path _c_ ; _c_ := c ; do_drawcontrolpoints enddef ;
-def drawcontrollines expr c = path _c_ ; _c_ := c ; do_drawcontrollines enddef ;
-def drawpointlabels expr c = path _c_ ; _c_ := c ; do_drawpointlabels enddef ;
+def drawpoints expr c = path _c_ ; _c_ := c ; mfun_draw_points enddef ;
+def drawcontrolpoints expr c = path _c_ ; _c_ := c ; mfun_draw_controlpoints enddef ;
+def drawcontrollines expr c = path _c_ ; _c_ := c ; mfun_draw_controllines enddef ;
+def drawpointlabels expr c = path _c_ ; _c_ := c ; mfun_draw_pointlabels enddef ;
-def do_drawpoints text t =
- for _i_=0 upto length(_c_) :
- normaldraw point _i_ of _c_ _pnt_opt_ t ;
- endfor ;
+def mfun_draw_points text t =
+ for _i_=0 upto length(_c_) :
+ normaldraw point _i_ of _c_ _pnt_opt_ t ;
+ endfor ;
enddef;
-def do_drawcontrolpoints text t =
- for _i_=0 upto length(_c_) :
- normaldraw precontrol _i_ of _c_ _ctr_opt_ t ;
- normaldraw postcontrol _i_ of _c_ _ctr_opt_ t ;
- endfor ;
+def mfun_draw_controlpoints text t =
+ for _i_=0 upto length(_c_) :
+ normaldraw precontrol _i_ of _c_ _ctr_opt_ t ;
+ normaldraw postcontrol _i_ of _c_ _ctr_opt_ t ;
+ endfor ;
enddef;
-def do_drawcontrollines text t =
- for _i_=0 upto length(_c_) :
- normaldraw point _i_ of _c_ -- precontrol _i_ of _c_ _lin_opt_ t ;
- normaldraw point _i_ of _c_ -- postcontrol _i_ of _c_ _lin_opt_ t ;
- endfor ;
+def mfun_draw_controllines text t =
+ for _i_=0 upto length(_c_) :
+ normaldraw point _i_ of _c_ -- precontrol _i_ of _c_ _lin_opt_ t ;
+ normaldraw point _i_ of _c_ -- postcontrol _i_ of _c_ _lin_opt_ t ;
+ endfor ;
enddef;
boolean swappointlabels ; swappointlabels := false ;
-def do_drawpointlabels text t =
- for _i_=0 upto length(_c_) :
- pair _u_ ; _u_ := unitvector(direction _i_ of _c_)
- rotated if swappointlabels : - fi 90 ;
- pair _p_ ; _p_ := (point _i_ of _c_) ;
- _u_ := 12 * defaultscale * _u_ ;
- normaldraw thelabel ( decimal _i_,
- _p_ shifted if cycle _c_ and (_i_=0) : - fi _u_ ) _lab_opt_ t ;
- endfor ;
+def mfun_draw_pointlabels text t =
+ for _i_=0 upto length(_c_) :
+ pair _u_ ; _u_ := unitvector(direction _i_ of _c_) rotated if swappointlabels : - fi 90 ;
+ pair _p_ ; _p_ := (point _i_ of _c_) ;
+ _u_ := 12 * defaultscale * _u_ ;
+ normaldraw thelabel ( decimal _i_, _p_ shifted if cycle _c_ and (_i_=0) : - fi _u_ ) _lab_opt_ t ;
+ endfor ;
enddef;
%D Bounding box.
def drawboundingbox expr p =
- normaldraw boundingbox p _bnd_opt_
+ normaldraw boundingbox p _bnd_opt_
enddef ;
%D Origin.
@@ -1167,10 +1210,8 @@ enddef ;
numeric originlength ; originlength := .5cm ;
def draworigin text t =
- normaldraw (origin shifted (0, originlength) --
- origin shifted (0,-originlength)) _ori_opt_ t ;
- normaldraw (origin shifted ( originlength,0) --
- origin shifted (-originlength,0)) _ori_opt_ t ;
+ normaldraw (origin shifted (0, originlength) -- origin shifted (0,-originlength)) _ori_opt_ t ;
+ normaldraw (origin shifted ( originlength,0) -- origin shifted (-originlength,0)) _ori_opt_ t ;
enddef;
%D Axis.
@@ -1178,101 +1219,108 @@ enddef;
numeric tickstep ; tickstep := 5mm ;
numeric ticklength ; ticklength := 2mm ;
-def drawxticks expr c = path _c_ ; _c_ := c ; do_drawxticks enddef ;
-def drawyticks expr c = path _c_ ; _c_ := c ; do_drawyticks enddef ;
-def drawticks expr c = path _c_ ; _c_ := c ; do_drawticks enddef ;
+def drawxticks expr c = path _c_ ; _c_ := c ; mfun_draw_xticks enddef ;
+def drawyticks expr c = path _c_ ; _c_ := c ; mfun_draw_yticks enddef ;
+def drawticks expr c = path _c_ ; _c_ := c ; mfun_draw_ticks enddef ;
% Adding eps prevents disappearance due to rounding errors.
-def do_drawxticks text t =
- for i=0 step -tickstep until xpart llcorner _c_ - eps :
- if (i<=xpart lrcorner _c_) :
- normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ;
- fi ;
- endfor ;
- for i=0 step tickstep until xpart lrcorner _c_ + eps :
- if (i>=xpart llcorner _c_) :
- normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ;
- fi ;
- endfor ;
- normaldraw (llcorner _c_ -- ulcorner _c_)
- shifted (-xpart llcorner _c_,0) _ori_opt_ t ;
+def mfun_draw_xticks text t =
+ for i=0 step -tickstep until xpart llcorner _c_ - eps :
+ if (i<=xpart lrcorner _c_) :
+ normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ for i=0 step tickstep until xpart lrcorner _c_ + eps :
+ if (i>=xpart llcorner _c_) :
+ normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ normaldraw (llcorner _c_ -- ulcorner _c_) shifted (-xpart llcorner _c_,0) _ori_opt_ t ;
enddef ;
-def do_drawyticks text t =
- for i=0 step -tickstep until ypart llcorner _c_ - eps :
- if (i<=ypart ulcorner _c_) :
- normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ;
- fi ;
- endfor ;
- for i=0 step tickstep until ypart ulcorner _c_ + eps :
- if (i>=ypart llcorner _c_) :
- normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ;
- fi ;
- endfor ;
- normaldraw (llcorner _c_ -- lrcorner _c_)
- shifted (0,-ypart llcorner _c_) _ori_opt_ t ;
+def mfun_draw_yticks text t =
+ for i=0 step -tickstep until ypart llcorner _c_ - eps :
+ if (i<=ypart ulcorner _c_) :
+ normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ for i=0 step tickstep until ypart ulcorner _c_ + eps :
+ if (i>=ypart llcorner _c_) :
+ normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ normaldraw (llcorner _c_ -- lrcorner _c_) shifted (0,-ypart llcorner _c_) _ori_opt_ t ;
enddef ;
-def do_drawticks text t =
- drawxticks _c_ t ;
- drawyticks _c_ t ;
+def mfun_draw_ticks text t =
+ drawxticks _c_ t ;
+ drawyticks _c_ t ;
enddef ;
%D All of it except axis.
def drawwholepath expr p =
- draworigin ;
- drawpath p ;
- drawcontrollines p ;
- drawcontrolpoints p ;
- drawpoints p ;
- drawboundingbox p ;
- drawpointlabels p ;
+ draworigin ;
+ drawpath p ;
+ drawcontrollines p ;
+ drawcontrolpoints p ;
+ drawpoints p ;
+ drawboundingbox p ;
+ drawpointlabels p ;
enddef ;
%D Tracing.
def visualizeddraw expr c =
- if picture c : normaldraw c else : path _c_ ; _c_ := c ; do_visualizeddraw fi
+ if picture c : normaldraw c else : path _c_ ; _c_ := c ; do_visualizeddraw fi
enddef ;
def visualizedfill expr c =
- if picture c : normalfill c else : path _c_ ; _c_ := c ; do_visualizedfill fi
+ if picture c : normalfill c else : path _c_ ; _c_ := c ; do_visualizedfill fi
enddef ;
def do_visualizeddraw text t =
- draworigin ;
- drawpath _c_ t ;
- drawcontrollines _c_ ;
- drawcontrolpoints _c_ ;
- drawpoints _c_ ;
- drawboundingbox _c_ ;
- drawpointlabels _c_ ;
+ draworigin ;
+ drawpath _c_ t ;
+ drawcontrollines _c_ ;
+ drawcontrolpoints _c_ ;
+ drawpoints _c_ ;
+ drawboundingbox _c_ ;
+ drawpointlabels _c_ ;
enddef ;
def do_visualizedfill text t =
- if cycle _c_ : normalfill _c_ t fi ;
- draworigin ;
- drawcontrollines _c_ ;
- drawcontrolpoints _c_ ;
- drawpoints _c_ ;
- drawboundingbox _c_ ;
- drawpointlabels _c_ ;
+ if cycle _c_ : normalfill _c_ t fi ;
+ draworigin ;
+ drawcontrollines _c_ ;
+ drawcontrolpoints _c_ ;
+ drawpoints _c_ ;
+ drawboundingbox _c_ ;
+ drawpointlabels _c_ ;
enddef ;
def visualizepaths =
- let fill = visualizedfill ;
- let draw = visualizeddraw ;
+ let fill = visualizedfill ;
+ let draw = visualizeddraw ;
enddef ;
def naturalizepaths =
- let fill = normalfill ;
- let draw = normaldraw ;
+ let fill = normalfill ;
+ let draw = normaldraw ;
enddef ;
extra_endfig := extra_endfig & " naturalizepaths ; " ;
+%D Nice tracer:
+
+def drawboundary primary p =
+ draw p dashed evenly withcolor white ;
+ draw p dashed oddly withcolor black ;
+ draw (- llcorner p) withpen pencircle scaled 3 withcolor white ;
+ draw (- llcorner p) withpen pencircle scaled 1.5 withcolor black ;
+enddef ;
+
%D Also handy:
extra_beginfig := extra_beginfig & " truecorners := 0 ; " ; % restores
@@ -1287,46 +1335,57 @@ boolean autoarrows ; autoarrows := false ;
numeric ahfactor ; ahfactor := 2.5 ;
def set_ahlength (text t) =
-% ahlength := (ahfactor*pen_size(_op_ t)) ; % _op_ added
-% problem: _op_ can contain color so a no-go, we could apply the transform
-% but i need to figure out the best way (fakepicture and take components).
- ahlength := (ahfactor*pen_size(t)) ;
+ % ahlength := (ahfactor*pen_size(_op_ t)) ; % _op_ added
+ % problem: _op_ can contain color so a no-go, we could apply the transform
+ % but i need to figure out the best way (fakepicture and take components).
+ ahlength := (ahfactor*pen_size(t)) ;
enddef ;
vardef pen_size (text t) =
- save p ; picture p ; p := nullpicture ;
- addto p doublepath (top origin -- bot origin) t ;
- (ypart urcorner p - ypart lrcorner p)
+ save p ; picture p ; p := nullpicture ;
+ addto p doublepath (top origin -- bot origin) t ;
+ (ypart urcorner p - ypart lrcorner p)
enddef ;
%D The next two macros are adapted versions of plain
%D \METAPOST\ definitions.
+vardef arrowpath expr p = % patch by Peter Rolf: supports squared pen and shifting (hh: maybe just use center of head as first)
+ (p cutafter makepath(pencircle scaled 2(ahlength*cosd(.5ahangle)) shifted point length p of p))
+enddef;
+
+% def _finarr text t =
+% if autoarrows : set_ahlength (t) fi ;
+% draw arrowpath _apth t ; % arrowpath added
+% filldraw arrowhead _apth t ;
+% enddef;
+
def _finarr text t =
- if autoarrows : set_ahlength (t) fi ;
- draw _apth t ;
- filldraw arrowhead _apth t ;
+ if autoarrows : set_ahlength (t) fi ;
+ draw arrowpath _apth t ; % arrowpath added
+ fill arrowhead _apth t ;
+ draw arrowhead _apth t ;
enddef;
-def _findarr text t =
- if autoarrows : set_ahlength (t) fi ;
- draw _apth t ;
- fill arrowhead _apth withpen currentpen t ;
- fill arrowhead reverse _apth withpen currentpen t ;
-enddef ;
+def _finarr text t =
+ if autoarrows : set_ahlength (t) fi ;
+ draw arrowpath _apth t ; % arrowpath added
+ fill arrowhead _apth t ;
+ draw arrowhead _apth t undashed ;
+enddef;
%D Handy too ......
vardef pointarrow (expr pat, loc, len, off) =
- save l, r, s, t ; path l, r ; numeric s ; pair t ;
- t := if pair loc : loc else : point loc along pat fi ;
- s := len/2 - off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
- r := pat cutbefore t ;
- r := (r cutafter point (arctime s of r) of r) ;
- s := len/2 + off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
- l := reverse (pat cutafter t) ;
- l := (reverse (l cutafter point (arctime s of l) of l)) ;
- (l..r)
+ save l, r, s, t ; path l, r ; numeric s ; pair t ;
+ t := if pair loc : loc else : point loc along pat fi ;
+ s := len/2 - off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ r := pat cutbefore t ;
+ r := (r cutafter point (arctime s of r) of r) ;
+ s := len/2 + off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ l := reverse (pat cutafter t) ;
+ l := (reverse (l cutafter point (arctime s of l) of l)) ;
+ (l..r)
enddef ;
def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ;
@@ -1336,23 +1395,19 @@ def centerarrow (expr pat,tim,len) = pointarrow(pat,tim,len, 0) enddef ;
%D The \type {along} and \type {on} operators can be used
%D as follows:
%D
-%D \starttypen
+%D \starttyping
%D drawdot point .5 along somepath ;
%D drawdot point 3cm on somepath ;
-%D \stoptypen
+%D \stoptyping
%D
%D The number denotes a percentage (fraction).
primarydef pct along pat = % also negative
- (arctime (pct * (arclength pat)) of pat) of pat
+ (arctime (pct * (arclength pat)) of pat) of pat
enddef ;
-% primarydef len on pat =
-% (arctime len of pat) of pat
-% enddef ;
-
-primarydef len on pat =
- (arctime if len>0 : len else : (arclength(pat)+len) fi of pat) of pat
+primarydef len on pat = % no outer ( ) .. somehow fails
+ (arctime if len>=0 : len else : (arclength(pat)+len) fi of pat) of pat
enddef ;
% this cuts of a piece from both ends
@@ -1365,69 +1420,55 @@ enddef ;
% enddef ;
tertiarydef pat cutends len =
- begingroup ; save tap ; path tap ;
- tap := pat cutbefore (point (xpart paired(len)) on pat) ;
- (tap cutafter (point -(ypart paired(len)) on tap))
- endgroup
+ begingroup
+ save tap ; path tap ;
+ tap := pat cutbefore (point (xpart paired(len)) on pat) ;
+ (tap cutafter (point -(ypart paired(len)) on tap))
+ endgroup
enddef ;
%D To be documented.
path freesquare ;
-freesquare := ((-1,0)--(-1,-1)--(0,-1)--(+1,-1)--
- (+1,0)--(+1,+1)--(0,+1)--(-1,+1)--cycle) scaled .5 ;
+freesquare := (
+ (-1,0) -- (-1,-1) -- (0,-1) -- (+1,-1) --
+ (+1,0) -- (+1,+1) -- (0,+1) -- (-1,+1) -- cycle
+) scaled .5 ;
numeric freelabeloffset ; freelabeloffset := 3pt ;
numeric freedotlabelsize ; freedotlabelsize := 3pt ;
vardef thefreelabel (expr str, loc, ori) =
- save s, p, q, l ; picture s ; path p, q ; pair l ;
- interim labeloffset := freelabeloffset ;
- s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ;
- setbounds s to boundingbox s enlarged freelabeloffset ;
- p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
- q := freesquare xyscaled (urcorner s - llcorner s) ;
-% l := point (xpart (p intersectiontimes (ori--loc))) of q ;
- l := point xpart (p intersectiontimes
- (ori--((1+eps)*arclength(ori--loc)*unitvector(loc-ori)))) of q ;
- setbounds s to boundingbox s enlarged -freelabeloffset ; % new
- %draw boundingbox s shifted -l withpen pencircle scaled .5pt withcolor red ;
- (s shifted -l)
-enddef ;
-
-% better?
-
-vardef thefreelabel (expr str, loc, ori) =
- save s, p, q, l ; picture s ; path p, q ; pair l ;
- interim labeloffset := freelabeloffset ;
- s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ;
- setbounds s to boundingbox s enlarged freelabeloffset ;
- p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
- q := freesquare xyscaled (urcorner s - llcorner s) ;
- l := point xpart (p intersectiontimes (ori--loc shifted (loc-ori))) of q ;
- setbounds s to boundingbox s enlarged -freelabeloffset ; % new
- %draw boundingbox s shifted -l withpen pencircle scaled .5pt withcolor red ;
- (s shifted -l)
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ interim labeloffset := freelabeloffset ;
+ s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ;
+ setbounds s to boundingbox s enlarged freelabeloffset ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point xpart (p intersectiontimes (ori--loc shifted (loc-ori))) of q ;
+ setbounds s to boundingbox s enlarged -freelabeloffset ; % new
+ % draw boundingbox s shifted -l withpen pencircle scaled .5pt withcolor red ;
+ (s shifted -l)
enddef ;
vardef freelabel (expr str, loc, ori) =
- draw thefreelabel(str,loc,ori) ;
+ draw thefreelabel(str,loc,ori) ;
enddef ;
vardef freedotlabel (expr str, loc, ori) =
- interim linecap:=rounded ;
- draw loc withpen pencircle scaled freedotlabelsize ;
- draw thefreelabel(str,loc,ori) ;
+ interim linecap := rounded ;
+ draw loc withpen pencircle scaled freedotlabelsize ;
+ draw thefreelabel(str,loc,ori) ;
enddef ;
-%D \starttypen
+%D \starttyping
%D drawarrow anglebetween(line_a,line_b,somelabel) ;
-%D \stoptypen
+%D \stoptyping
-% angleoffset ; angleoffset := 0pt ;
-numeric anglelength ; anglelength := 20pt ;
-numeric anglemethod ; anglemethod := 1 ;
+newinternal angleoffset ; angleoffset := 0pt ;
+newinternal anglelength ; anglelength := 20pt ;
+newinternal anglemethod ; anglemethod := 1 ;
% vardef anglebetween (expr a, b, str) = % path path string
% save pointa, pointb, common, middle, offset ;
@@ -1466,63 +1507,66 @@ numeric anglemethod ; anglemethod := 1 ;
% enddef ;
vardef anglebetween (expr a, b, str) = % path path string
- save pointa, pointb, common, middle, offset ;
- pair pointa, pointb, common, middle, offset ;
- save curve ; path curve ;
- save where ; numeric where ;
- if round point 0 of a = round point 0 of b :
- common := point 0 of a ;
- else :
- common := a intersectionpoint b ;
- fi ;
- pointa := point anglelength on a ;
- pointb := point anglelength on b ;
- where := turningnumber (common--pointa--pointb--cycle) ;
- middle := (reverse(common--pointa) rotatedaround (pointa,-where*90))
- intersection_point
- (reverse(common--pointb) rotatedaround (pointb, where*90)) ;
- if not intersection_found :
- middle := point .5 along
- ((reverse(common--pointa) rotatedaround (pointa,-where*90)) --
- ( (common--pointb) rotatedaround (pointb, where*90))) ;
- fi ;
- if anglemethod = 0 :
- curve := pointa{unitvector(middle-pointa)}.. pointb;
- middle := point .5 along curve ;
- curve := common ;
- elseif anglemethod = 1 :
- curve := pointa{unitvector(middle-pointa)}.. pointb;
- middle := point .5 along curve ;
- elseif anglemethod = 2 :
- middle := common rotatedaround(.5[pointa,pointb],180) ;
- curve := pointa--middle--pointb ;
- elseif anglemethod = 3 :
- curve := pointa--middle--pointb ;
- elseif anglemethod = 4 :
- curve := pointa..controls middle..pointb ;
- middle := point .5 along curve ;
- fi ;
- draw thefreelabel(str, middle, common) ; % withcolor black ;
- curve
+ save pointa, pointb, common, middle, offset ;
+ pair pointa, pointb, common, middle, offset ;
+ save curve ; path curve ;
+ save where ; numeric where ;
+ if round point 0 of a = round point 0 of b :
+ common := point 0 of a ;
+ else :
+ common := a intersectionpoint b ;
+ fi ;
+ pointa := point anglelength on a ;
+ pointb := point anglelength on b ;
+ where := turningnumber (common--pointa--pointb--cycle) ;
+ middle := (reverse(common--pointa) rotatedaround (pointa,-where*90))
+ intersection_point
+ (reverse(common--pointb) rotatedaround (pointb, where*90)) ;
+ if not intersection_found :
+ middle := point .5 along
+ ((reverse(common--pointa) rotatedaround (pointa,-where*90)) --
+ ( (common--pointb) rotatedaround (pointb, where*90))) ;
+ fi ;
+ if anglemethod = 0 :
+ curve := pointa{unitvector(middle-pointa)}.. pointb;
+ middle := point .5 along curve ;
+ curve := common ;
+ elseif anglemethod = 1 :
+ curve := pointa{unitvector(middle-pointa)}.. pointb;
+ middle := point .5 along curve ;
+ elseif anglemethod = 2 :
+ middle := common rotatedaround(.5[pointa,pointb],180) ;
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 3 :
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 4 :
+ curve := pointa..controls middle..pointb ;
+ middle := point .5 along curve ;
+ fi ;
+ draw thefreelabel(str, middle, common) ; % withcolor black ;
+ curve
enddef ;
% Stack
-picture currentpicturestack[] ;
-numeric currentpicturedepth ; currentpicturedepth := 0 ;
+picture mfun_current_picture_stack[] ;
+numeric mfun_current_picture_depth ;
+
+mfun_current_picture_depth := 0 ;
def pushcurrentpicture =
- currentpicturedepth := currentpicturedepth + 1 ;
- currentpicturestack[currentpicturedepth] := currentpicture ;
- currentpicture := nullpicture ;
+ mfun_current_picture_depth := mfun_current_picture_depth + 1 ;
+ mfun_current_picture_stack[mfun_current_picture_depth] := currentpicture ;
+ currentpicture := nullpicture ;
enddef ;
def popcurrentpicture text t = % optional text
- if currentpicturedepth > 0 :
- addto currentpicturestack[currentpicturedepth] also currentpicture t ;
- currentpicture := currentpicturestack[currentpicturedepth] ;
- currentpicturedepth := currentpicturedepth - 1 ;
- fi ;
+ if mfun_current_picture_depth > 0 :
+ addto mfun_current_picture_stack[mfun_current_picture_depth] also currentpicture t ;
+ currentpicture := mfun_current_picture_stack[mfun_current_picture_depth] ;
+ mfun_current_picture_stack[mfun_current_picture_depth] := nullpicture ;
+ mfun_current_picture_depth := mfun_current_picture_depth - 1 ;
+ fi ;
enddef ;
%D colorcircle(size, red, green, blue) ;
@@ -1603,71 +1647,76 @@ enddef ;
% popcurrentpicture ;
% enddef ;
-vardef colorcircle (expr size, red, green, blue) =
- save r, g, b, c, m, y, w ; save radius ;
- path r, g, b, c, m, y, w ; numeric radius ;
+vardef colorcircle (expr size, red, green, blue) = % might move
+ save r, g, b, c, m, y, w ; save radius ;
+ path r, g, b, c, m, y, w ; numeric radius ;
- radius := 5cm ; pickup pencircle scaled (radius/25) ;
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
- transform t ; t := identity rotatedaround(origin,120) ;
+ transform t ; t := identity rotatedaround(origin,120) ;
- r := fullcircle rotated 90 scaled radius
- shifted (0,radius/4) rotatedaround(origin,135) ;
+ r := fullcircle rotated 90 scaled radius shifted (0,radius/4) rotatedaround(origin,135) ;
- b := r transformed t ; g := b transformed t ;
+ b := r transformed t ; g := b transformed t ;
- c := buildcycle(subpath(1,7) of g,subpath(1,7) of b) ;
- y := c transformed t ; m := y transformed t ;
+ c := buildcycle(subpath(1,7) of g,subpath(1,7) of b) ;
+ y := c transformed t ; m := y transformed t ;
- w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ;
+ w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ;
- pushcurrentpicture ;
+ pushcurrentpicture ;
- fill r withcolor red ;
- fill g withcolor green ;
- fill b withcolor blue ;
- fill c withcolor white-red ;
- fill m withcolor white-green ;
- fill y withcolor white-blue ;
- fill w withcolor white ;
+ fill r withcolor red ;
+ fill g withcolor green ;
+ fill b withcolor blue ;
+ fill c withcolor white - red ;
+ fill m withcolor white - green ;
+ fill y withcolor white - blue ;
+ fill w withcolor white ;
- for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ;
+ for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ;
- currentpicture := currentpicture xsized size ;
+ currentpicture := currentpicture xsized size ;
- popcurrentpicture ;
+ popcurrentpicture ;
enddef ;
% penpoint (i,2) of somepath -> inner / outer point
vardef penpoint expr pnt of p =
- save n, d ; numeric n, d ;
- (n,d) = if pair pnt : pnt else : (pnt,1) fi ;
- (point n of p shifted ((penoffset direction n of p of currentpen) scaled d))
+ save n, d ; numeric n, d ;
+ (n,d) = if pair pnt : pnt else : (pnt,1) fi ;
+ (point n of p shifted ((penoffset direction n of p of currentpen) scaled d))
enddef ;
% nice: currentpicture := inverted currentpicture ;
primarydef p uncolored c =
- if color p :
- c - p
- else :
- image
- (for i within p :
- addto currentpicture
- if stroked i or filled i :
- if filled i : contour else : doublepath fi pathpart i
- dashed dashpart i withpen penpart i
- else :
- also i
- fi
- withcolor c-(redpart i, greenpart i, bluepart i) ;
- endfor ; )
+ if color p :
+ c - p
+ else :
+ image (
+ for i within p :
+ addto currentpicture
+ if stroked i or filled i :
+ if filled i :
+ contour
+ else :
+ doublepath
+ fi
+ pathpart i
+ dashed dashpart i withpen penpart i
+ else :
+ also i
+ fi
+ withcolor c-(redpart i, greenpart i, bluepart i) ;
+ endfor ;
+ )
fi
enddef ;
vardef inverted primary p =
- (p uncolored white)
+ p uncolored white
enddef ;
% primarydef p softened c =
@@ -1692,45 +1741,54 @@ enddef ;
% enddef ;
primarydef p softened c =
- begingroup
- save cc ; color cc ; cc := tripled(c) ;
- if color p :
- (redpart cc * redpart p,
- greenpart cc * greenpart p,
- bluepart cc * bluepart p)
- else :
- image
- (for i within p :
- addto currentpicture
- if stroked i or filled i :
- if filled i : contour else : doublepath fi pathpart i
- dashed dashpart i withpen penpart i
- else :
- also i
- fi
- withcolor (redpart cc * redpart i,
- greenpart cc * greenpart i,
- bluepart cc * bluepart i) ;
- endfor ;)
- fi
- endgroup
+ begingroup
+ save cc ; color cc ; cc := tripled(c) ;
+ if color p :
+ (redpart cc * redpart p,greenpart cc * greenpart p, bluepart cc * bluepart p)
+ else :
+ image (
+ for i within p :
+ addto currentpicture
+ if stroked i or filled i :
+ if filled i :
+ contour
+ else :
+ doublepath
+ fi
+ pathpart i
+ dashed dashpart i withpen penpart i
+ else :
+ also i
+ fi
+ withcolor (redpart cc * redpart i, greenpart cc * greenpart i, bluepart cc * bluepart i) ;
+ endfor ;
+ )
+ fi
+ endgroup
enddef ;
vardef grayed primary p =
- if color p :
- tripled(.30redpart p+.59greenpart p+.11bluepart p)
- else :
- image
- (for i within p :
- addto currentpicture
- if stroked i or filled i :
- if filled i : contour else : doublepath fi pathpart i
- dashed dashpart i withpen penpart i
- else :
- also i
- fi
- withcolor tripled(.30redpart i+.59greenpart i+.11bluepart i) ;
- endfor ; )
+ if color p :
+ tripled(.30redpart p+.59greenpart p+.11bluepart p)
+ else :
+ image (
+ for i within p :
+ addto currentpicture
+ if stroked i or filled i :
+ if filled i :
+ contour
+ else :
+ doublepath
+ fi
+ pathpart i
+ dashed dashpart i
+ withpen penpart i
+ else :
+ also i
+ fi
+ withcolor tripled(.30redpart i+.59greenpart i+.11bluepart i) ;
+ endfor ;
+ )
fi
enddef ;
@@ -1758,10 +1816,10 @@ def condition primary b = if b : "true" else : "false" fi enddef ;
% undocumented
primarydef p stretched s =
- begingroup
- save pp ; path pp ; pp := p xyscaled s ;
- (pp shifted ((point 0 of p) - (point 0 of pp)))
- endgroup
+ begingroup
+ save pp ; path pp ; pp := p xyscaled s ;
+ (pp shifted ((point 0 of p) - (point 0 of pp)))
+ endgroup
enddef ;
% primarydef p enlonged len =
@@ -1833,40 +1891,40 @@ def yshifted expr dy = shifted(0,dy) enddef ;
%
def readfile (expr name) =
- begingroup ; save ok ; boolean ok ;
- if (readfrom (name) <> EOF) :
- ok := false ;
- elseif (readfrom (name) <> EOF) :
- ok := false ;
- else :
- ok := true ;
- fi ;
- if not ok :
- scantokens("input " & name & " ") ;
- fi ;
- closefrom (name) ;
- endgroup ;
+ begingroup ; save ok ; boolean ok ;
+ if (readfrom (name) <> EOF) :
+ ok := false ;
+ elseif (readfrom (name) <> EOF) :
+ ok := false ;
+ else :
+ ok := true ;
+ fi ;
+ if not ok :
+ scantokens("input " & name & " ") ;
+ fi ;
+ closefrom (name) ;
+ endgroup ;
enddef ;
% permits redefinition of end in macro
inner end ;
-% real fun
+% this will be redone (when needed) using scripts and backend handling
let normalwithcolor = withcolor ;
def remapcolors =
- def withcolor primary c = normalwithcolor remappedcolor(c) enddef ;
+ def withcolor primary c = normalwithcolor remappedcolor(c) enddef ;
enddef ;
def normalcolors =
- let withcolor = normalwithcolor ;
+ let withcolor = normalwithcolor ;
enddef ;
def resetcolormap =
- color color_map[][][] ;
- normalcolors ;
+ color color_map[][][] ;
+ normalcolors ;
enddef ;
resetcolormap ;
@@ -1882,15 +1940,15 @@ def g_color primary c = greenpart c enddef ;
def b_color primary c = bluepart c enddef ;
def remapcolor(expr old, new) =
- color_map[r_color old][g_color old][b_color old] := new ;
+ color_map[redpart old][greenpart old][bluepart old] := new ;
enddef ;
def remappedcolor(expr c) =
- if known color_map[r_color c][g_color c][b_color c] :
- color_map[r_color c][g_color c][b_color c]
- else :
- c
- fi
+ if known color_map[redpart c][greenpart c][bluepart c] :
+ color_map[redpart c][greenpart c][bluepart c]
+ else :
+ c
+ fi
enddef ;
% def refill suffix c = do_repath (1) (c) enddef ;
@@ -1930,11 +1988,11 @@ enddef ;
% Thanks to Jens-Uwe Morawski for pointing out that we need
% to treat bounded and clipped components as local pictures.
-def recolor suffix p = p := repathed (0,p) enddef ;
-def refill suffix p = p := repathed (1,p) enddef ;
-def redraw suffix p = p := repathed (2,p) enddef ;
-def retext suffix p = p := repathed (3,p) enddef ;
-def untext suffix p = p := repathed (4,p) enddef ;
+def recolor suffix p = p := repathed (0,p) enddef ;
+def refill suffix p = p := repathed (1,p) enddef ;
+def redraw suffix p = p := repathed (2,p) enddef ;
+def retext suffix p = p := repathed (3,p) enddef ;
+def untext suffix p = p := repathed (4,p) enddef ;
% primarydef p recolored t = repathed(0,p) t enddef ;
% primarydef p refilled t = repathed(1,p) t enddef ;
@@ -1997,69 +2055,80 @@ def reprocess suffix p = p := repathed (22,p) enddef ; % no attributes
% also 11 and 12
vardef repathed (expr mode, p) text t =
- begingroup ;
- if mode=0 : save withcolor ; remapcolors ; fi ;
- save _p_, _pp_, _ppp_, _f_, _b_, _t_ ;
- picture _p_, _pp_, _ppp_ ; color _f_ ; path _b_ ; transform _t_ ;
- _b_ := boundingbox p ; _p_ := nullpicture ;
- for i within p :
- _f_ := (redpart i, greenpart i, bluepart i) ;
- if bounded i :
- _pp_ := repathed(mode,i) t ;
- setbounds _pp_ to pathpart i ;
- addto _p_ also _pp_ ;
- elseif clipped i :
- _pp_ := repathed(mode,i) t ;
- clip _pp_ to pathpart i ;
- addto _p_ also _pp_ ;
- elseif stroked i :
- if mode=21 :
- _ppp_ := i ; % indirectness is needed
- addto _p_ also image(scantokens(t & " pathpart _ppp_")
- dashed dashpart i withpen penpart i
- withcolor _f_ ; ) ;
- elseif mode=22 :
- _ppp_ := i ; % indirectness is needed
- addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
- else :
- addto _p_ doublepath pathpart i
- dashed dashpart i withpen penpart i
- withcolor _f_ % (redpart i, greenpart i, bluepart i)
- if mode=2 : t fi ;
- fi ;
- elseif filled i :
- if mode=11 :
- _ppp_ := i ; % indirectness is needed
- addto _p_ also image(scantokens(t & " pathpart _ppp_")
- withcolor _f_ ; ) ;
- elseif mode=12 :
- _ppp_ := i ; % indirectness is needed
- addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
- else :
- addto _p_ contour pathpart i
- withcolor _f_
- if (mode=1) and (_f_<>refillbackground) : t fi ;
- fi ;
- elseif textual i : % textpart i <> "" :
- if mode <> 4 :
- % transform _t_ ;
- % (xpart _t_, xxpart _t_, xypart _t_) = (xpart i, xxpart i, xypart i) ;
- % (ypart _t_, yypart _t_, yxpart _t_) = (ypart i, yypart i, yxpart i) ;
- % addto _p_ also
- % textpart i infont fontpart i % todo : other font
- % transformed _t_
- % withpen penpart i
- % withcolor _f_
- % if mode=3 : t fi ;
- addto _p_ also i if mode=3 : t fi ;
- fi ;
- else :
- addto _p_ also i ;
+ begingroup ;
+ if mode = 0 :
+ save withcolor ;
+ remapcolors ;
fi ;
- endfor ;
- setbounds _p_ to _b_ ;
- _p_
- endgroup
+ save _p_, _pp_, _ppp_, _f_, _b_, _t_ ;
+ picture _p_, _pp_, _ppp_ ; color _f_ ; path _b_ ; transform _t_ ;
+ _b_ := boundingbox p ;
+ _p_ := nullpicture ;
+ for i within p :
+ _f_ := (redpart i, greenpart i, bluepart i) ;
+ if bounded i :
+ _pp_ := repathed(mode,i) t ;
+ setbounds _pp_ to pathpart i ;
+ addto _p_ also _pp_ ;
+ elseif clipped i :
+ _pp_ := repathed(mode,i) t ;
+ clip _pp_ to pathpart i ;
+ addto _p_ also _pp_ ;
+ elseif stroked i :
+ if mode=21 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")
+ dashed dashpart i withpen penpart i
+ withcolor _f_ ; ) ;
+ elseif mode=22 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
+ else :
+ addto _p_ doublepath pathpart i
+ dashed dashpart i withpen penpart i
+ withcolor _f_ % (redpart i, greenpart i, bluepart i)
+ if mode = 2 :
+ t
+ fi ;
+ fi ;
+ elseif filled i :
+ if mode=11 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")
+ withcolor _f_ ; ) ;
+ elseif mode=12 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
+ else :
+ addto _p_ contour pathpart i
+ withcolor _f_
+ if (mode=1) and (_f_<>refillbackground) :
+ t
+ fi ;
+ fi ;
+ elseif textual i : % textpart i <> "" :
+ if mode <> 4 :
+ % transform _t_ ;
+ % (xpart _t_, xxpart _t_, xypart _t_) = (xpart i, xxpart i, xypart i) ;
+ % (ypart _t_, yypart _t_, yxpart _t_) = (ypart i, yypart i, yxpart i) ;
+ % addto _p_ also
+ % textpart i infont fontpart i % todo : other font
+ % transformed _t_
+ % withpen penpart i
+ % withcolor _f_
+ % if mode=3 : t fi ;
+ addto _p_ also i
+ if mode=3 :
+ t
+ fi ;
+ fi ;
+ else :
+ addto _p_ also i ;
+ fi ;
+ endfor ;
+ setbounds _p_ to _b_ ;
+ _p_
+ endgroup
enddef ;
% After a question of Denis on how to erase a z variable, Jacko
@@ -2087,11 +2156,11 @@ enddef ;
% which i decided to simplify to:
def clearxy text s =
- if false for $ := s : or true endfor :
- forsuffixes $ := s : x$ := whatever ; y$ := whatever ; endfor ;
- else :
- save x, y ;
- fi
+ if false for $ := s : or true endfor :
+ forsuffixes $ := s : x$ := whatever ; y$ := whatever ; endfor ;
+ else :
+ save x, y ;
+ fi
enddef ;
% so now we can say: clearxy ; as well as clearxy 1, 2, 3 ;
@@ -2103,48 +2172,68 @@ enddef ;
% show x0 ; z0 = (30,30) ;
primarydef p smoothed d =
- (p llmoved (-xpart paired(d),0) -- p lrmoved (-xpart paired(d),0) {right} ..
- p lrmoved (0,-ypart paired(d)) -- p urmoved (0,-ypart paired(d)) {up} ..
- p urmoved (-xpart paired(d),0) -- p ulmoved (-xpart paired(d),0) {left} ..
- p ulmoved (0,-ypart paired(d)) -- p llmoved (0,-ypart paired(d)) {down} .. cycle)
+ (p llmoved (-xpart paired(d),0) -- p lrmoved (-xpart paired(d),0) {right} ..
+ p lrmoved (0,-ypart paired(d)) -- p urmoved (0,-ypart paired(d)) {up} ..
+ p urmoved (-xpart paired(d),0) -- p ulmoved (-xpart paired(d),0) {left} ..
+ p ulmoved (0,-ypart paired(d)) -- p llmoved (0,-ypart paired(d)) {down} .. cycle)
enddef ;
primarydef p cornered c =
- ((point 0 of p) shifted (c*(unitvector(point 1 of p - point 0 of p))) --
- for i=1 upto length(p) :
- (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) --
- (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) ..
- controls point i of p ..
- endfor cycle)
+ ((point 0 of p) shifted (c*(unitvector(point 1 of p - point 0 of p))) --
+ for i=1 upto length(p) :
+ (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) --
+ (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) ..
+ controls point i of p ..
+ endfor cycle)
enddef ;
% cmyk color support
vardef cmyk(expr c,m,y,k) =
- (1-c-k,1-m-k,1-y-k)
+ (1-c-k,1-m-k,1-y-k)
enddef ;
% handy
-vardef bbwidth (expr p) = % vardef width_of primary p =
- if known p :
- if path p or picture p :
- xpart (lrcorner p - llcorner p)
- else :
- 0
- fi
+% vardef bbwidth (expr p) = % vardef width_of primary p =
+% if known p :
+% if path p or picture p :
+% xpart (lrcorner p - llcorner p)
+% else :
+% 0
+% fi
+% else :
+% 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 bbheight (expr p) = % vardef heigth_of primary p =
- if known p :
- if path p or picture p :
- ypart (urcorner p - lrcorner p)
- else :
- 0
- fi
+% vardef bbheight (expr p) = % vardef heigth_of primary p =
+% if known p :
+% if path p or picture p :
+% ypart (urcorner p - lrcorner p)
+% else :
+% 0
+% fi
+% else :
+% 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
@@ -2153,122 +2242,87 @@ enddef ;
color nocolor ; numeric noline ; % both unknown signals
def dowithpath (expr p, lw, lc, bc) =
- if known p :
- if known bc :
- fill p withcolor bc ;
- fi ;
- if known lw and known lc :
- draw p withpen pencircle scaled lw withcolor lc ;
- elseif known lw :
- draw p withpen pencircle scaled lw ;
- elseif known lc :
- draw p withcolor lc ;
+ if known p :
+ if known bc :
+ fill p withcolor bc ;
+ fi ;
+ if known lw and known lc :
+ draw p withpen pencircle scaled lw withcolor lc ;
+ elseif known lw :
+ draw p withpen pencircle scaled lw ;
+ elseif known lc :
+ draw p withcolor lc ;
+ fi ;
fi ;
- fi ;
enddef ;
% result from metafont discussion list (denisr/boguslawj)
-def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ;
-def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ;
+def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ;
+def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ;
-% not perfect, but useful since it removes redundant points.
+let == = = ;
-% vardef dostraightened(expr sign, p) =
-% if length(p)>2 : % was 1, but straight lines are ok
-% save pp ; path pp ;
-% pp := point 0 of p ;
-% for i=1 upto length(p)-1 :
-% if round(point i of p) <> round(point length(pp) of pp) :
-% pp := pp -- point i of p ;
-% fi ;
-% endfor ;
-% save n, ok ; numeric n ; boolean ok ;
-% n := length(pp) ; ok := false ;
-% if n>2 :
-% for i=0 upto n : % evt hier ook round
-% if unitvector(round(point i of pp -
-% point if i=0 : n else : i-1 fi of pp)) <>
-% sign * unitvector(round(point if i=n : 0 else : i+1 fi of pp -
-% point i of pp)) :
-% if ok : -- else : ok := true ; fi point i of pp
-% fi
-% endfor
-% if ok and (cycle p) : -- cycle fi
-% else :
-% pp
-% fi
-% else :
-% p
-% fi
-% enddef ;
+% added
-% vardef simplified expr p =
-% (reverse dostraightened(+1,dostraightened(+1,reverse p)))
-% enddef ;
+picture oddly ; % evenly already defined
-% vardef unspiked expr p =
-% (reverse dostraightened(-1,dostraightened(-1,reverse p)))
-% enddef ;
+evenly := dashpattern(on 3 off 3) ;
+oddly := dashpattern(off 3 on 3) ;
+
+% not perfect, but useful since it removes redundant points.
-% simplified : remove same points as well as redundant points
-% unspiked : remove same points as well as areas with zero distance
-
-vardef dostraightened(expr sign, p) =
- save _p_, _q_ ; path _p_, _q_ ;
- _p_ := p ;
- forever :
- _q_ := dodostraightened(sign, _p_) ;
- exitif length(_p_) = length(_q_) ;
- _p_ := _q_ ;
- endfor ;
- _q_
-enddef ;
-
-vardef dodostraightened(expr sign, p) =
- if length(p)>2 : % was 1, but straight lines are ok
- save pp ; path pp ;
- pp := point 0 of p ;
- for i=1 upto length(p)-1 :
- if round(point i of p) <> round(point length(pp) of pp) :
- pp := pp -- point i of p ;
- fi ;
+vardef mfun_straightened(expr sign, p) =
+ save _p_, _q_ ; path _p_, _q_ ;
+ _p_ := p ;
+ forever :
+ _q_ := mfun_do_straightened(sign, _p_) ;
+ exitif length(_p_) = length(_q_) ;
+ _p_ := _q_ ;
endfor ;
- save n, ok ; numeric n ; boolean ok ;
- n := length(pp) ; ok := false ;
- if n>2 :
- for i=0 upto n : % evt hier ook round
- if unitvector(round(point i of pp -
- point if i=0 : n else : i-1 fi of pp)) <>
- sign * unitvector(round(point if i=n : 0 else : i+1 fi of pp -
- point i of pp)) :
- if ok : -- else : ok := true ; fi point i of pp
+ _q_
+enddef ;
+
+vardef mfun_do_straightened(expr sign, p) =
+ if length(p)>2 : % was 1, but straight lines are ok
+ save pp ; path pp ;
+ pp := point 0 of p ;
+ for i=1 upto length(p)-1 :
+ if round(point i of p) <> round(point length(pp) of pp) :
+ pp := pp -- point i of p ;
+ fi ;
+ endfor ;
+ save n, ok ; numeric n ; boolean ok ;
+ n := length(pp) ; ok := false ;
+ if n>2 :
+ for i=0 upto n : % evt hier ook round
+ if unitvector(round(point i of pp - point if i=0 : n else : i-1 fi of pp)) <>
+ sign * unitvector(round(point if i=n : 0 else : i+1 fi of pp - point i of pp)) :
+ if ok :
+ --
+ else :
+ ok := true ;
+ fi point i of pp
+ fi
+ endfor
+ if ok and (cycle p) :
+ -- cycle
+ fi
+ else :
+ pp
fi
- endfor
- if ok and (cycle p) : -- cycle fi
else :
- pp
+ p
fi
- else :
- p
- fi
enddef ;
-% vardef simplified expr p =
-% dostraightened(+1,p)
-% enddef ;
-
-% vardef unspiked expr p =
-% dostraightened(-1,p)
-% enddef ;
-
-vardef simplified expr p =
- (reverse dostraightened(+1,dostraightened(+1,reverse p)))
-enddef ;
+vardef simplified expr p = (
+ reverse mfun_straightened(+1,mfun_straightened(+1,reverse p))
+) enddef ;
-vardef unspiked expr p =
- (reverse dostraightened(-1,dostraightened(-1,reverse p)))
-enddef ;
+vardef unspiked expr p = (
+ reverse mfun_straightened(-1,mfun_straightened(-1,reverse p))
+) enddef ;
% path p ;
% p := (2cm,1cm) -- (2cm,1cm) -- (2cm,1cm) -- (3cm,1cm) --
@@ -2289,213 +2343,197 @@ enddef ;
path originpath ; originpath := origin -- cycle ;
vardef unitvector primary z =
- if abs z = abs origin : z else : z/abs z fi
+ if abs z = abs origin : z else : z/abs z fi
enddef;
% also new
-vardef anchored@#(expr p, z) =
- p shifted (z + (labxf@#*lrcorner p + labyf@#*ulcorner p
- + (1-labxf@#-labyf@#)*llcorner p))
-enddef ;
+% vardef anchored@#(expr p, z) = % maybe use the textext variant
+% p shifted (z + (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))
+% enddef ;
% epsed(1.2345)
vardef epsed (expr e) =
- e if e>0 : + eps elseif e<0 : - eps fi
+ e if e>0 : + eps elseif e<0 : - eps fi
enddef ;
% handy
def withgray primary g =
- withcolor (g,g,g)
+ withcolor (g,g,g)
enddef ;
% for metafun
-if unknown darkred : color darkred ; darkred := .625(1,0,0) fi ;
-if unknown darkyellow : color darkyellow ; darkyellow := .625(1,1,0) fi ;
-if unknown darkgray : color darkgray ; darkgray := .625(1,1,1) fi ;
-if unknown lightgray : color lightgray ; lightgray := .875(1,1,1) fi ;
+if unknown darkred : color darkred ; darkred := .625(1,0,0) fi ;
+if unknown darkgreen : color darkgreen ; darkgreen := .625(0,1,0) fi ;
+if unknown darkblue : color darkblue ; darkblue := .625(0,0,1) fi ;
+if unknown darkcyan : color darkcyan ; darkcyan := .625(0,1,1) fi ;
+if unknown darkmagenta : color darkmagenta ; darkmagenta := .625(1,0,1) fi ;
+if unknown darkyellow : color darkyellow ; darkyellow := .625(1,1,0) fi ;
+if unknown darkgray : color darkgray ; darkgray := .625(1,1,1) fi ;
+if unknown lightgray : color lightgray ; lightgray := .875(1,1,1) fi ;
% an improved plain mp macro
vardef center primary p =
- if pair p : p else : .5[llcorner p, urcorner p] fi
+ if pair p :
+ p
+ else :
+ .5[llcorner p, urcorner p]
+ fi
enddef;
% new, yet undocumented
vardef rangepath (expr p, d, a) =
- (if length p>0 :
- (d*unitvector(direction 0 of p) rotated a)
- shifted point 0 of p
- -- p --
- (d*unitvector(direction length(p) of p) rotated a)
- shifted point length(p) of p
- else :
- p
- fi)
+ if length p>0 :
+ (d*unitvector(direction 0 of p) rotated a) shifted point 0 of p
+ -- p --
+ (d*unitvector(direction length(p) of p) rotated a) shifted point length(p) of p
+ else :
+ p
+ fi
enddef ;
% under construction
-vardef straightpath(expr a, b, method) =
- if (method<1) or (method>6) :
- (a--b)
- elseif method = 1 :
- (a --
- if xpart a > xpart b :
- if ypart a > ypart b :
- (xpart b,ypart a) --
- elseif ypart a < ypart b :
- (xpart a,ypart b) --
- fi
- elseif xpart a < xpart b :
- if ypart a > ypart b :
- (xpart a,ypart b) --
- elseif ypart a < ypart b :
- (xpart b,ypart a) --
- fi
+vardef straightpath (expr a, b, method) =
+ if (method<1) or (method>6) :
+ (a--b)
+ elseif method = 1 :
+ (a --
+ if xpart a > xpart b :
+ if ypart a > ypart b :
+ (xpart b,ypart a) --
+ elseif ypart a < ypart b :
+ (xpart a,ypart b) --
+ fi
+ elseif xpart a < xpart b :
+ if ypart a > ypart b :
+ (xpart a,ypart b) --
+ elseif ypart a < ypart b :
+ (xpart b,ypart a) --
+ fi
+ fi
+ b)
+ elseif method = 3 :
+ (a --
+ if xpart a > xpart b :
+ (xpart b,ypart a) --
+ elseif xpart a < xpart b :
+ (xpart a,ypart b) --
+ fi
+ b)
+ elseif method = 5 :
+ (a --
+ if ypart a > ypart b :
+ (xpart b,ypart a) --
+ elseif ypart a < ypart b :
+ (xpart a,ypart b) --
+ fi
+ b)
+ else :
+ (reverse straightpath(b,a,method-1))
fi
- b)
- elseif method = 3 :
- (a --
- if xpart a > xpart b :
- (xpart b,ypart a) --
- elseif xpart a < xpart b :
- (xpart a,ypart b) --
- fi
- b)
- elseif method = 5 :
- (a --
- if ypart a > ypart b :
- (xpart b,ypart a) --
- elseif ypart a < ypart b :
- (xpart a,ypart b) --
- fi
- b)
- else :
- (reverse straightpath(b,a,method-1))
- fi
enddef ;
% handy for myself
def addbackground text t =
- begingroup ; save p, b ; picture p ; path b ;
- b := boundingbox currentpicture ;
- p := currentpicture ; currentpicture := nullpicture ;
- fill b t ; setbounds currentpicture to b ; addto currentpicture also p ;
- endgroup ;
+ begingroup ;
+ save p, b ; picture p ; path b ;
+ b := boundingbox currentpicture ;
+ p := currentpicture ; currentpicture := nullpicture ;
+ fill b t ;
+ setbounds currentpicture to b ;
+ addto currentpicture also p ;
+ endgroup ;
enddef ;
% makes a (line) into an infinite one (handy for calculating
% intersection points
vardef infinite expr p =
- (-infinity*unitvector(direction 0 of p)
+ (-infinity*unitvector(direction 0 of p)
shifted point 0 of p
- -- p --
- +infinity*unitvector(direction length(p) of p)
- shifted point length(p) of p)
+ -- p --
+ +infinity*unitvector(direction length(p) of p)
+ shifted point length(p) of p)
enddef ;
% obscure macros: create var from string and replace - and :
-% (needed for process color id's)
+% (needed for process color id's) .. will go away
-string _clean_ascii_[] ;
+string mfun_clean_ascii[] ;
def register_dirty_chars(expr str) =
for i = 0 upto length(str)-1 :
- _clean_ascii_[ASCII substring(i,i+1) of str] := "_" ;
+ mfun_clean_ascii[ASCII substring(i,i+1) of str] := "_" ;
endfor ;
enddef ;
register_dirty_chars("+-*/:;., ") ;
vardef cleanstring (expr s) =
- save ss ; string ss, si ; ss = "" ; save i ;
- for i=0 upto length(s) :
- si := substring(i,i+1) of s ;
- ss := ss & if known _clean_ascii_[ASCII si] : _clean_ascii_[ASCII si] else : si fi ;
- endfor ;
- ss
+ save ss ; string ss, si ; ss = "" ; save i ;
+ for i=0 upto length(s) :
+ si := substring(i,i+1) of s ;
+ ss := ss & if known mfun_clean_ascii[ASCII si] : mfun_clean_ascii[ASCII si] else : si fi ;
+ endfor ;
+ ss
enddef ;
vardef asciistring (expr s) =
- save ss ; string ss, si ; ss = "" ; save i ;
- for i=0 upto length(s) :
- si := substring(i,i+1) of s ;
- if (ASCII si >= ASCII "0") and (ASCII si <= ASCII "9") :
- ss := ss & char(scantokens(si) + ASCII "A") ;
- else :
- ss := ss & si ;
- fi ;
- endfor ;
- ss
-enddef ;
-
-vardef setunstringed (expr s, v) =
- scantokens(cleanstring(s)) := v ;
+ save ss ; string ss, si ; ss = "" ; save i ;
+ for i=0 upto length(s) :
+ si := substring(i,i+1) of s ;
+ if (ASCII si >= ASCII "0") and (ASCII si <= ASCII "9") :
+ ss := ss & char(scantokens(si) + ASCII "A") ;
+ else :
+ ss := ss & si ;
+ fi ;
+ endfor ;
+ ss
enddef ;
vardef setunstringed (expr s, v) =
- scantokens(cleanstring(s)) := v ;
+ scantokens(cleanstring(s)) := v ;
enddef ;
vardef getunstringed (expr s) =
- scantokens(cleanstring(s))
+ scantokens(cleanstring(s))
enddef ;
vardef unstringed (expr s) =
- expandafter known scantokens(cleanstring(s))
-enddef ;
-
-% new
-
-% vardef colorpart(expr i) =
-% (redpart i, greenpart i,bluepart i)
-% enddef ;
-
-vardef colorpart(expr c) =
- if colormodel c = 3 :
- graypart c
- elseif colormodel c = 5 :
- (redpart c,greenpart c,bluepart c)
- elseif colormodel c = 7 :
- (cyanpart c,magentapart c,yellowpart c,blackpart c)
- fi
+ expandafter known scantokens(cleanstring(s))
enddef ;
% for david arnold:
% showgrid(-5,10,1cm,-10,10,1cm);
-def showgrid (expr MinX, MaxX, DeltaX, MinY, MaxY, DeltaY)=
- begingroup
- save defaultfont, defaultscale, size ;
- string defaultfont ; defaultfont := "cmtt10"; % i.e. infofont
- numeric defaultscale ; defaultscale := 8pt / fontsize defaultfont;
- numeric size ; size := 2pt ;
+def showgrid (expr MinX, MaxX, DeltaX, MinY, MaxY, DeltaY) = % will move
+ begingroup
+ save size ; numeric size ; size := 2pt ;
for x=MinX upto MaxX :
- for y=MinY upto MaxY :
- draw (x*DeltaX, y*DeltaY)
- withpen pencircle scaled
- if (x mod 5 = 0) and (y mod 5 = 0) :
- 1.5size withcolor .50white
- else :
- size withcolor .75white
- fi ;
- endfor ;
+ for y=MinY upto MaxY :
+ draw (x*DeltaX, y*DeltaY) withpen pencircle scaled
+ if (x mod 5 = 0) and (y mod 5 = 0) :
+ 1.5size withcolor .50white
+ else :
+ size withcolor .75white
+ fi ;
+ endfor ;
endfor ;
for x=MinX upto MaxX:
- label.bot(decimal x, (x*DeltaX,-size));
+ label.bot(textext("\infofont " & decimal x), (x*DeltaX,-size)) ;
endfor ;
for y=MinY upto MaxY:
- label.lft(decimal y, (-size,y*DeltaY)) ;
+ label.lft(textext("\infofont " & decimal y), (-size,y*DeltaY)) ;
endfor ;
- endgroup
+ endgroup
enddef;
% new, handy for:
@@ -2525,26 +2563,24 @@ enddef;
%
% \useMPgraphic{map}{n=3}
-vardef phantom (text t) =
- picture _p_ ; _p_ := image(t) ; addto _p_ also currentpicture ;
- setbounds currentpicture to boundingbox _p_ ;
+vardef phantom (text t) = % to be checked
+ picture _p_ ;
+ _p_ := image(t) ;
+ addto _p_ also currentpicture ;
+ setbounds currentpicture to boundingbox _p_ ;
enddef ;
vardef c_phantom (expr b) (text t) =
- if b :
- picture _p_ ; _p_ := image(t) ; addto _p_ also currentpicture ;
- setbounds currentpicture to boundingbox _p_ ;
- else :
- t ;
- fi ;
+ if b :
+ picture _p_ ;
+ _p_ := image(t) ;
+ addto _p_ also currentpicture ;
+ setbounds currentpicture to boundingbox _p_ ;
+ else :
+ t ;
+ fi ;
enddef ;
-% mark paths (for external progs to split)
-
-% def somepath(expr p)
-% p
-% enddef ;
-
%D Handy:
def break =
@@ -2553,27 +2589,228 @@ enddef ;
%D New too:
-primarydef p xstretched w =
- (p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi)
-enddef ;
+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 ystretched h = (
+ p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi
+) enddef ;
primarydef p snapped s =
- hide ( if path p :
- forever :
- exitif (bbheight(p) <= s) and (bbwidth(p) <= s) ;
- p := p scaled (1/2) ;
- endfor ;
- elseif numeric p :
- forever :
- exitif p <= s ;
- p := p scaled (1/2) ;
+ hide (
+ if path p :
+ forever :
+ exitif (bbheight(p) <= s) and (bbwidth(p) <= s) ;
+ p := p scaled (1/2) ;
+ endfor ;
+ elseif numeric p :
+ forever :
+ exitif p <= s ;
+ p := p scaled (1/2) ;
+ endfor ;
+ fi ;
+ )
+ p
+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) ;
+
+% This could be standard mplib 2 behaviour:
+
+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 ;
+
+% draw image (...) ... ; % prescripts prepended to first, postscripts appended to last
+% draw decorated (...) ... ; % prescripts prepended to each, postscripts appended to each
+% draw redecorated (...) ... ; % prescripts assigned to each, postscripts assigned to each
+% draw undecorated (...) ... ; % following properties are ignored, existing properties are kept
+%
+% draw decorated (
+% draw fullcircle scaled 20cm withpen pencircle scaled 20mm withcolor red withtransparency (1,.40) ;
+% draw fullcircle scaled 15cm withpen pencircle scaled 15mm withcolor green withtransparency (1,.30) ;
+% draw fullcircle scaled 10cm withpen pencircle scaled 10mm withcolor blue withtransparency (1,.20) ;
+% )
+% withcolor blue
+% withtransparency (1,.125) % selectively applied
+% withpen pencircle scaled 10mm
+% ;
+
+% vardef image (text imagedata) = % already defined
+% save currentpicture ;
+% picture currentpicture ;
+% currentpicture := nullpicture ;
+% imagedata ;
+% currentpicture
+% enddef ;
+
+vardef undecorated (text imagedata) text decoration =
+ save currentpicture ;
+ picture currentpicture ;
+ currentpicture := nullpicture ;
+ imagedata ;
+ currentpicture
+enddef ;
+
+
+if metapostversion < 1.770 :
+
+ vardef decorated (text imagedata) text decoration =
+ save mfun_decorated_path, currentpicture ;
+ picture mfun_decorated_path, currentpicture ;
+ currentpicture := nullpicture ;
+ imagedata ;
+ mfun_decorated_path := currentpicture ;
+ currentpicture := nullpicture ;
+ for i within mfun_decorated_path :
+ addto currentpicture
+ if stroked i :
+ doublepath pathpart i
+ dashed dashpart i
+ withpen penpart i
+ withcolor colorpart i
+ decoration
+ elseif filled i :
+ contour pathpart i
+ withpen penpart i
+ withcolor colorpart i
+ decoration
+ elseif textual i :
+ also i
+ withcolor colorpart i
+ decoration
+ else :
+ also i
+ fi
+ ;
+ endfor ;
+ currentpicture
+ enddef ;
+
+else:
+
+ vardef decorated (text imagedata) text decoration =
+ save mfun_decorated_path, currentpicture ;
+ picture mfun_decorated_path, currentpicture ;
+ currentpicture := nullpicture ;
+ imagedata ;
+ mfun_decorated_path := currentpicture ;
+ currentpicture := nullpicture ;
+ for i within mfun_decorated_path :
+ addto currentpicture
+ if stroked i :
+ doublepath pathpart i
+ dashed dashpart i
+ withpen penpart i
+ withcolor colorpart i
+ withprescript prescriptpart i
+ withpostscript postscriptpart i
+ decoration
+ elseif filled i :
+ contour pathpart i
+ withpen penpart i
+ withcolor colorpart i
+ withprescript prescriptpart i
+ withpostscript postscriptpart i
+ decoration
+ elseif textual i :
+ also i
+ withcolor colorpart i
+ withprescript prescriptpart i
+ withpostscript postscriptpart i
+ decoration
+ else :
+ also i
+ fi
+ ;
+ endfor ;
+ currentpicture
+ enddef ;
+
+fi ;
+
+vardef redecorated (text imagedata) text decoration =
+ save mfun_decorated_path, currentpicture ;
+ picture mfun_decorated_path, currentpicture ;
+ currentpicture := nullpicture ;
+ imagedata ;
+ mfun_decorated_path := currentpicture ;
+ currentpicture := nullpicture ;
+ for i within mfun_decorated_path :
+ addto currentpicture
+ if stroked i :
+ doublepath pathpart i
+ dashed dashpart i
+ withpen penpart i
+ decoration
+ elseif filled i :
+ contour pathpart i
+ withpen penpart i
+ decoration
+ elseif textual i :
+ also i
+ decoration
+ else :
+ also i
+ fi
+ ;
endfor ;
- fi ; )
- p
+ currentpicture
enddef ;
+% path mfun_bleed_box ;
+
+% primarydef p bleeded d =
+% image (
+% mfun_bleed_box := boundingbox p ;
+% if pair d :
+% draw p xysized (bbwidth(p)+2*xpart d,bbheight(p)+2*ypart d) shifted -d ;
+% else :
+% draw p xysized (bbwidth(p)+2d,bbheight(p)+2d) shifted (-d,-d) ;
+% fi ;
+% setbounds currentpicture to mfun_bleed_box ;
+% )
+% enddef ;
+
+%D New helpers:
+
+def beginglyph(expr unicode, width, height, depth) =
+ beginfig(unicode) ; % the number is irrelevant
+ charcode := unicode ;
+ charwd := width ;
+ charht := height ;
+ chardp := depth ;
+enddef ;
+
+def endglyph =
+ setbounds currentpicture to (boundingbox unitsquare xscaled charwd yscaled (charht + chardp) shifted (0,-chardp)) ;
+ if known charscale :
+ currentpicture := currentpicture scaled charscale ;
+ fi ;
+ endfig ;
+enddef ;
+
+%D Dimensions have bever been an issue as traditional MP can't make that large
+%D pictures, but with double mode we need a catch:
+
+newinternal maxdimensions ; maxdimensions := 14000 ;
+
+def mfun_apply_max_dimensions = % not a generic helper, we want to protect this one
+ if bbwidth currentpicture > maxdimensions :
+ currentpicture := currentpicture if bbheight currentpicture > bbwidth currentpicture : ysized else : xsized fi maxdimensions ;
+ elseif bbheight currentpicture > maxdimensions :
+ currentpicture := currentpicture ysized maxdimensions ;
+ fi ;
+enddef;
+
+extra_endfig := extra_endfig & "mfun_apply_max_dimensions ;" ;
+
let dump = relax ;
diff --git a/metapost/context/base/mp-tool.mpiv b/metapost/context/base/mp-tool.mpiv
index 672a051c2..e497e2f72 100644
--- a/metapost/context/base/mp-tool.mpiv
+++ b/metapost/context/base/mp-tool.mpiv
@@ -57,8 +57,15 @@ mpprocset := 1 ;
%
% protect ;
-string space ; space := char 32 ;
-string CRLF ; CRLF := char 10 & char 13 ;
+string space ; space := char 32 ;
+string percent ; percent := char 37 ;
+string crlf ; crlf := char 10 & char 13 ;
+string dquote ; dquote := char 34 ;
+
+let SPACE = space ;
+let CRLF = crlf ;
+let DQUOTE = dquote ;
+let PERCENT = percent ;
vardef ddecimal primary p =
decimal xpart p & " " & decimal ypart p
@@ -90,8 +97,8 @@ newinternal graycolormodel ; graycolormodel := 3 ;
newinternal rgbcolormodel ; rgbcolormodel := 5 ;
newinternal cmykcolormodel ; cmykcolormodel := 7 ;
-let grayscale = numeric ;
-let greyscale = numeric ;
+let grayscale = graycolor ;
+let greyscale = greycolor ;
vardef colorpart expr c =
if not picture c :
@@ -141,6 +148,39 @@ vardef colordecimals primary c =
fi
enddef ;
+vardef colordecimalslist(text t) =
+ save b ; boolean b ; b := false ;
+ for s=t :
+ if b : & " " & fi
+ colordecimals(s)
+ hide(b := true ;)
+ endfor
+enddef ;
+
+% vardef _ctx_color_spec_ primary c =
+% if cmykcolor c :
+% "c=" & decimal cyanpart c &
+% ",m=" & decimal magentapart c &
+% ",y=" & decimal yellowpart c &
+% ",k=" & decimal blackpart c
+% elseif rgbcolor c :
+% "r=" & decimal redpart c &
+% ",g=" & decimal greenpart c &
+% ",b=" & decimal bluepart c
+% else :
+% "s=" & decimal c
+% fi
+% enddef ;
+%
+% vardef _ctx_color_spec_list_(text t) =
+% save b ; boolean b ; b := false ;
+% for s=t :
+% if b : & " " & fi
+% _ctx_color_spec_(s)
+% hide(b := true ;)
+% endfor
+% enddef ;
+
%D We have standardized data file names:
def job_name =
@@ -152,7 +192,8 @@ def data_mpd_file =
enddef ;
%D Because \METAPOST\ has a hard coded limit of 4~datafiles,
-%D we need some trickery when we have multiple files.
+%D we need some trickery when we have multiple files. This will
+%D be redone (via \LUA).
if unknown collapse_data :
boolean collapse_data ;
@@ -289,10 +330,14 @@ vardef set_outer_boundingbox text q = % obsolete
setbounds q to outerboundingbox q;
enddef;
-%D Some missing functions can be implemented rather
-%D straightforward:
+%D Some missing functions can be implemented rather straightforward (thanks to
+%D Taco and others):
+
+% oldpi := 3.14159265358979323846 ; % from <math.h>
+pi := 3.14159265358979323846264338327950288419716939937510 ; % 50 digits
+radian := 180/pi ; % 2pi*radian = 360 ;
-numeric Pi ; Pi := 3.1415926 ;
+% let +++ = ++ ;
vardef sqr primary x = x*x enddef ;
vardef log primary x = if x=0: 0 else: mlog(x)/mlog(10) fi enddef ;
@@ -302,15 +347,6 @@ vardef inv primary x = if x=0: 0 else: x**-1 fi enddef ;
vardef pow (expr x,p) = x**p enddef ;
-vardef asin primary x = x+(x**3)/6+3(x**5)/40 enddef ;
-vardef acos primary x = asin(-x) enddef ;
-vardef atan primary x = x-(x**3)/3+(x**5)/5-(x**7)/7 enddef ;
-vardef tand primary x = sind(x)/cosd(x) enddef ;
-
-%D Here are Taco Hoekwater's alternatives (but vardef'd and primaried).
-
-pi := 3.1415926 ; radian := 180/pi ; % 2pi*radian = 360 ;
-
vardef tand primary x = sind(x)/cosd(x) enddef ;
vardef cotd primary x = cosd(x)/sind(x) enddef ;
@@ -321,9 +357,11 @@ vardef cot primary x = cos(x)/sin(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 ;
vardef acosh primary x = ln(x+(x+-+1)) enddef ;
vardef asinh primary x = ln(x+(x++1)) enddef ;
@@ -331,6 +369,11 @@ vardef asinh primary x = ln(x+(x++1)) enddef ;
vardef sinh primary x = save xx ; xx = exp x ; (xx-1/xx)/2 enddef ;
vardef cosh primary x = save xx ; xx = exp x ; (xx+1/xx)/2 enddef ;
+%D Like mod, but useful for anglesl it returns (-.5d,+.5d] and is used
+%D in for instance mp-chem.
+
+primarydef a zmod b = (-((b/2 - a) mod b) + b/2) enddef ;
+
%D Sometimes this is handy:
def undashed =
@@ -631,6 +674,15 @@ ultriangle := origin -- (0,+.5) -- (-.5,0) -- cycle ;
lltriangle := origin -- (-.5,0) -- (0,-.5) -- cycle ;
lrtriangle := origin -- (0,-.5) -- (+.5,0) -- cycle ;
+path triangle, uptriangle, downtriangle, lefttriangle, righttriangle ;
+
+triangle := (1,0) -- (1,0) rotated 120 -- (1,0) rotated -120 -- cycle ;
+
+uptriangle := triangle rotated 90 ;
+downtriangle := triangle rotated -90 ;
+lefttriangle := triangle rotated 180 ;
+righttriangle := triangle ;
+
path unitdiamond, fulldiamond ;
unitdiamond := (.5,0) -- (1,.5) -- (.5,1) -- (0,.5) -- cycle ;
@@ -768,8 +820,8 @@ vardef whitecolor(expr c) =
if cmykcolor c : (0,0,0,0) elseif rgbcolor c : (1,1,1) else : 1 fi
enddef ;
-vardef blackcolor(expr c) =
- if cmykcolor c : (0,0,0,1) elseif rgbcolor c : (0,0,0) else : 0 fi
+vardef blackcolor expr c =
+ if cmykcolor c : (0,0,0,1) elseif rgbcolor c : (0,0,0) else : 0 fi
enddef ;
%D Well, this is the dangerous and naive version:
@@ -1223,7 +1275,7 @@ enddef ;
extra_endfig := extra_endfig & " naturalizepaths ; " ;
-%D Noce tracer:
+%D Nice tracer:
def drawboundary primary p =
draw p dashed evenly withcolor white ;
@@ -1318,7 +1370,7 @@ primarydef pct along pat = % also negative
enddef ;
primarydef len on pat = % no outer ( ) .. somehow fails
- (arctime if len>0 : len else : (arclength(pat)+len) fi of pat) of pat
+ (arctime if len>=0 : len else : (arclength(pat)+len) fi of pat) of pat
enddef ;
% this cuts of a piece from both ends
@@ -1539,9 +1591,13 @@ primarydef p softened c =
enddef ;
vardef grayed primary p =
- if color p :
+ if rgbcolor p :
tripled(.30redpart p+.59greenpart p+.11bluepart p)
- else :
+ elseif cmykcolor p :
+ tripled(.30*(1-cyanpart i)+.59*(1-magentapart i)+.11*(1-yellowpart i)+blackpart i)
+ elseif greycolor p :
+ p
+ elseif picture p :
image (
for i within p :
addto currentpicture
@@ -1557,12 +1613,24 @@ vardef grayed primary p =
else :
also i
fi
- withcolor tripled(.30redpart i+.59greenpart i+.11bluepart i) ;
+ if unknown colorpart i :
+ % nothing
+ elseif rgbcolor colorpart i :
+ withcolor tripled(.30redpart i+.59greenpart i+.11bluepart i) ;
+ elseif cmykcolor colorpart i :
+ withcolor tripled(.30*(1-cyanpart i)+.59*(1-magentapart i)+.11*(1-yellowpart i)+blackpart i) ;
+ else :
+ withcolor colorpart i ;
+ fi
endfor ;
)
- fi
+ else :
+ p
+ fi
enddef ;
+let greyed = grayed ;
+
% yes or no: "text" infont "cmr12" at 24pt ;
% let normalinfont = infont ;
@@ -2030,7 +2098,7 @@ enddef ;
% handy
def withgray primary g =
- withcolor (g,g,g)
+ withcolor g
enddef ;
% for metafun
@@ -2253,7 +2321,7 @@ enddef ;
%D Handy:
def break =
- exitif true fi ;
+ exitif true ; % fi
enddef ;
%D New too:
@@ -2266,23 +2334,31 @@ primarydef p ystretched h = (
p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi
) enddef ;
-primarydef p snapped s =
- hide (
- if path p :
- forever :
- exitif (bbheight(p) <= s) and (bbwidth(p) <= s) ;
- p := p scaled (1/2) ;
- endfor ;
- elseif numeric p :
- forever :
- exitif p <= s ;
- p := p scaled (1/2) ;
- endfor ;
- fi ;
- )
- p
+%D Newer:
+
+vardef area expr p =
+ % we could calculate the boundingbox once
+ (xpart llcorner boundingbox p,0) -- p --
+ (xpart lrcorner boundingbox p,0) -- cycle
enddef ;
+vardef basiccolors[] =
+ if @ = 0 :
+ white
+ else :
+ save n ; n := @ mod 7 ;
+ if n = 1 : red
+ elseif n = 2 : green
+ elseif n = 3 : blue
+ elseif n = 4 : cyan
+ elseif n = 5 : magenta
+ elseif n = 6 : yellow
+ else : black
+ fi
+ fi
+enddef ;
+
+
% vardef somecolor = (1,1,0,0) enddef ;
% fill OverlayBox withcolor (rcomponent somecolor,gcomponent somecolor,bcomponent somecolor) ;
@@ -2329,7 +2405,6 @@ vardef undecorated (text imagedata) text decoration =
currentpicture
enddef ;
-
if metapostversion < 1.770 :
vardef decorated (text imagedata) text decoration =
@@ -2449,25 +2524,76 @@ enddef ;
% )
% enddef ;
+vardef mfun_snapped(expr p, s) =
+ if p < 0 : - ( - else : ( fi p div s) * s % the less tokens the better
+enddef ;
+
+vardef mfun_applied(expr p, s)(suffix a) =
+ if path p :
+ if pair s :
+ for i=0 upto length(p)-1 :
+ (a(xpart point i of p,xpart s),a(ypart point i of p,ypart s)) --
+ endfor
+ if cycle p :
+ cycle
+ else :
+ (a(xpart point length(p) of p,xpart s),a(ypart point length(p) of p,ypart s))
+ fi
+ else :
+ for i=0 upto length(p)-1 :
+ (a(xpart point i of p,s),a(ypart point i of p,s)) --
+ endfor
+ if cycle p :
+ cycle
+ else :
+ (a(xpart point length(p) of p,s),a(ypart point length(p) of p,s))
+ fi
+ fi
+ elseif pair p :
+ if pair s :
+ (a(xpart p,xpart s),a(ypart p,ypart s))
+ else :
+ (a(xpart p,s),a(ypart p,s))
+ fi
+ elseif cmykcolor p :
+ (a(cyanpart p,s),a(magentapart p,s),a(yellowpart p,s),a(blackpart p,s))
+ elseif rgbcolor p :
+ (a(redpart p,s),a(greenpart p,s),a(bluepart p,s))
+ elseif graycolor p :
+ a(p,s)
+ elseif numeric p :
+ a(p,s)
+ else
+ p
+ fi
+enddef ;
+
+primarydef p snapped s =
+ mfun_applied(p,s)(mfun_snapped) % so we can play with variants
+enddef ;
+
%D New helpers:
+newinternal charscale ; charscale := 1 ; % persistent so one needs to 'reset' it to 0 or 1
+
def beginglyph(expr unicode, width, height, depth) =
beginfig(unicode) ; % the number is irrelevant
charcode := unicode ;
charwd := width ;
charht := height ;
chardp := depth ;
+ % charscale := 1 ; % can be set for a whole font, so no reset here
enddef ;
def endglyph =
setbounds currentpicture to (boundingbox unitsquare xscaled charwd yscaled (charht + chardp) shifted (0,-chardp)) ;
- if known charscale :
+ if known charscale : if (charscale > 0) and (charscale <> 1) :
currentpicture := currentpicture scaled charscale ;
- fi ;
+ fi ; fi ;
endfig ;
enddef ;
-%D Dimensions have bever been an issue as traditional MP can't make that large
+%D Dimensions have never been an issue as traditional MP can't make that large
%D pictures, but with double mode we need a catch:
newinternal maxdimensions ; maxdimensions := 14000 ;