From 2017d30b4ca772c8eeac4fc0eb9b54e547a9a1d8 Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Tue, 17 May 2016 19:31:15 +0200 Subject: 2016-05-17 19:25:00 --- metapost/context/base/common/metafun.mp | 8 + metapost/context/base/common/mp-back.mp | 5 + metapost/context/base/common/mp-fobg.mp | 5 + metapost/context/base/common/mp-symb.mp | 6 + metapost/context/base/metafun.mp | 8 - metapost/context/base/metafun.mpii | 65 - metapost/context/base/metafun.mpiv | 58 - metapost/context/base/mp-abck.mpiv | 269 -- metapost/context/base/mp-apos.mpiv | 102 - metapost/context/base/mp-asnc.mpiv | 177 -- metapost/context/base/mp-back.mp | 205 -- metapost/context/base/mp-bare.mpiv | 93 - metapost/context/base/mp-base.mpii | 591 ---- metapost/context/base/mp-base.mpiv | 956 ------- metapost/context/base/mp-butt.mpii | 77 - metapost/context/base/mp-butt.mpiv | 77 - metapost/context/base/mp-char.mpii | 1006 ------- metapost/context/base/mp-char.mpiv | 1116 -------- metapost/context/base/mp-chem.mpiv | 1731 ------------ metapost/context/base/mp-core.mpii | 1418 ---------- metapost/context/base/mp-core.mpiv | 1561 ----------- metapost/context/base/mp-crop.mpiv | 194 -- metapost/context/base/mp-figs.mpii | 47 - metapost/context/base/mp-figs.mpiv | 47 - metapost/context/base/mp-fobg.mp | 87 - metapost/context/base/mp-form.mpii | 392 --- metapost/context/base/mp-form.mpiv | 30 - metapost/context/base/mp-func.mpii | 58 - metapost/context/base/mp-func.mpiv | 87 - metapost/context/base/mp-grap.mpiv | 1706 ------------ metapost/context/base/mp-grid.mpii | 149 -- metapost/context/base/mp-grid.mpiv | 142 - metapost/context/base/mp-grph.mpii | 310 --- metapost/context/base/mp-grph.mpiv | 263 -- metapost/context/base/mp-idea.mpiv | 30 - metapost/context/base/mp-luas.mpiv | 99 - metapost/context/base/mp-mlib.mpiv | 1213 --------- metapost/context/base/mp-page.mpii | 659 ----- metapost/context/base/mp-page.mpiv | 664 ----- metapost/context/base/mp-shap.mpii | 206 -- metapost/context/base/mp-shap.mpiv | 218 -- metapost/context/base/mp-spec.mpii | 782 ------ metapost/context/base/mp-step.mpii | 317 --- metapost/context/base/mp-step.mpiv | 376 --- metapost/context/base/mp-symb.mp | 351 --- metapost/context/base/mp-text.mpii | 275 -- metapost/context/base/mp-text.mpiv | 163 -- metapost/context/base/mp-tool.mpii | 2816 -------------------- metapost/context/base/mp-tool.mpiv | 2611 ------------------ metapost/context/base/mp-txts.mpii | 66 - metapost/context/base/mpii/metafun.mpii | 65 + metapost/context/base/mpii/mp-back.mpii | 205 ++ metapost/context/base/mpii/mp-base.mpii | 591 ++++ metapost/context/base/mpii/mp-butt.mpii | 77 + metapost/context/base/mpii/mp-char.mpii | 1006 +++++++ metapost/context/base/mpii/mp-core.mpii | 1418 ++++++++++ metapost/context/base/mpii/mp-figs.mpii | 47 + metapost/context/base/mpii/mp-fobg.mpii | 87 + metapost/context/base/mpii/mp-form.mpii | 392 +++ metapost/context/base/mpii/mp-func.mpii | 58 + metapost/context/base/mpii/mp-grid.mpii | 149 ++ metapost/context/base/mpii/mp-grph.mpii | 310 +++ metapost/context/base/mpii/mp-page.mpii | 659 +++++ metapost/context/base/mpii/mp-shap.mpii | 206 ++ metapost/context/base/mpii/mp-spec.mpii | 782 ++++++ metapost/context/base/mpii/mp-step.mpii | 317 +++ metapost/context/base/mpii/mp-text.mpii | 275 ++ metapost/context/base/mpii/mp-tool.mpii | 2816 ++++++++++++++++++++ metapost/context/base/mpii/mp-txts.mpii | 66 + metapost/context/base/mpiv/metafun.mpiv | 58 + metapost/context/base/mpiv/mp-abck.mpiv | 269 ++ metapost/context/base/mpiv/mp-apos.mpiv | 102 + metapost/context/base/mpiv/mp-asnc.mpiv | 177 ++ metapost/context/base/mpiv/mp-back.mpiv | 205 ++ metapost/context/base/mpiv/mp-bare.mpiv | 93 + metapost/context/base/mpiv/mp-base.mpiv | 956 +++++++ metapost/context/base/mpiv/mp-butt.mpiv | 77 + metapost/context/base/mpiv/mp-char.mpiv | 1116 ++++++++ metapost/context/base/mpiv/mp-chem.mpiv | 1731 ++++++++++++ metapost/context/base/mpiv/mp-core.mpiv | 1561 +++++++++++ metapost/context/base/mpiv/mp-cows.mpiv | 156 ++ metapost/context/base/mpiv/mp-crop.mpiv | 194 ++ metapost/context/base/mpiv/mp-figs.mpiv | 47 + metapost/context/base/mpiv/mp-fobg.mpiv | 87 + metapost/context/base/mpiv/mp-form.mpiv | 30 + metapost/context/base/mpiv/mp-func.mpiv | 87 + metapost/context/base/mpiv/mp-grap.mpiv | 1706 ++++++++++++ metapost/context/base/mpiv/mp-grid.mpiv | 142 + metapost/context/base/mpiv/mp-grph.mpiv | 348 +++ metapost/context/base/mpiv/mp-idea.mpiv | 30 + metapost/context/base/mpiv/mp-luas.mpiv | 99 + metapost/context/base/mpiv/mp-mlib.mpiv | 1462 ++++++++++ metapost/context/base/mpiv/mp-page.mpiv | 695 +++++ metapost/context/base/mpiv/mp-shap.mpiv | 218 ++ metapost/context/base/mpiv/mp-step.mpiv | 376 +++ metapost/context/base/mpiv/mp-symb.mpiv | 351 +++ metapost/context/base/mpiv/mp-text.mpiv | 163 ++ metapost/context/base/mpiv/mp-tool.mpiv | 2729 +++++++++++++++++++ metapost/context/fonts/bidi-symbols.mp | 73 - metapost/context/fonts/bidi-symbols.tex | 33 - metapost/context/fonts/demo-symbols.mp | 21 - metapost/context/fonts/demo-symbols.tex | 21 - metapost/context/fonts/mpiv/bidi-symbols.mp | 73 + metapost/context/fonts/mpiv/bidi-symbols.tex | 33 + metapost/context/fonts/mpiv/demo-symbols.mp | 21 + metapost/context/fonts/mpiv/demo-symbols.tex | 21 + metapost/context/fonts/mpiv/punkfont-bold.mp | 4 + .../context/fonts/mpiv/punkfont-boldslanted.mp | 5 + metapost/context/fonts/mpiv/punkfont-characters.mp | 726 +++++ .../context/fonts/mpiv/punkfont-definitions.mp | 115 + metapost/context/fonts/mpiv/punkfont-slanted.mp | 4 + metapost/context/fonts/mpiv/punkfont.mp | 2 + metapost/context/fonts/punkfont-bold.mp | 4 - metapost/context/fonts/punkfont-boldslanted.mp | 5 - metapost/context/fonts/punkfont-characters.mp | 726 ----- metapost/context/fonts/punkfont-definitions.mp | 115 - metapost/context/fonts/punkfont-slanted.mp | 4 - metapost/context/fonts/punkfont.mp | 2 - 118 files changed, 25819 insertions(+), 24872 deletions(-) create mode 100644 metapost/context/base/common/metafun.mp create mode 100644 metapost/context/base/common/mp-back.mp create mode 100644 metapost/context/base/common/mp-fobg.mp create mode 100644 metapost/context/base/common/mp-symb.mp delete mode 100644 metapost/context/base/metafun.mp delete mode 100644 metapost/context/base/metafun.mpii delete mode 100644 metapost/context/base/metafun.mpiv delete mode 100644 metapost/context/base/mp-abck.mpiv delete mode 100644 metapost/context/base/mp-apos.mpiv delete mode 100644 metapost/context/base/mp-asnc.mpiv delete mode 100644 metapost/context/base/mp-back.mp delete mode 100644 metapost/context/base/mp-bare.mpiv delete mode 100644 metapost/context/base/mp-base.mpii delete mode 100644 metapost/context/base/mp-base.mpiv delete mode 100644 metapost/context/base/mp-butt.mpii delete mode 100644 metapost/context/base/mp-butt.mpiv delete mode 100644 metapost/context/base/mp-char.mpii delete mode 100644 metapost/context/base/mp-char.mpiv delete mode 100644 metapost/context/base/mp-chem.mpiv delete mode 100644 metapost/context/base/mp-core.mpii delete mode 100644 metapost/context/base/mp-core.mpiv delete mode 100644 metapost/context/base/mp-crop.mpiv delete mode 100644 metapost/context/base/mp-figs.mpii delete mode 100644 metapost/context/base/mp-figs.mpiv delete mode 100644 metapost/context/base/mp-fobg.mp delete mode 100644 metapost/context/base/mp-form.mpii delete mode 100644 metapost/context/base/mp-form.mpiv delete mode 100644 metapost/context/base/mp-func.mpii delete mode 100644 metapost/context/base/mp-func.mpiv delete mode 100644 metapost/context/base/mp-grap.mpiv delete mode 100644 metapost/context/base/mp-grid.mpii delete mode 100644 metapost/context/base/mp-grid.mpiv delete mode 100644 metapost/context/base/mp-grph.mpii delete mode 100644 metapost/context/base/mp-grph.mpiv delete mode 100644 metapost/context/base/mp-idea.mpiv delete mode 100644 metapost/context/base/mp-luas.mpiv delete mode 100644 metapost/context/base/mp-mlib.mpiv delete mode 100644 metapost/context/base/mp-page.mpii delete mode 100644 metapost/context/base/mp-page.mpiv delete mode 100644 metapost/context/base/mp-shap.mpii delete mode 100644 metapost/context/base/mp-shap.mpiv delete mode 100644 metapost/context/base/mp-spec.mpii delete mode 100644 metapost/context/base/mp-step.mpii delete mode 100644 metapost/context/base/mp-step.mpiv delete mode 100644 metapost/context/base/mp-symb.mp delete mode 100644 metapost/context/base/mp-text.mpii delete mode 100644 metapost/context/base/mp-text.mpiv delete mode 100644 metapost/context/base/mp-tool.mpii delete mode 100644 metapost/context/base/mp-tool.mpiv delete mode 100644 metapost/context/base/mp-txts.mpii create mode 100644 metapost/context/base/mpii/metafun.mpii create mode 100644 metapost/context/base/mpii/mp-back.mpii create mode 100644 metapost/context/base/mpii/mp-base.mpii create mode 100644 metapost/context/base/mpii/mp-butt.mpii create mode 100644 metapost/context/base/mpii/mp-char.mpii create mode 100644 metapost/context/base/mpii/mp-core.mpii create mode 100644 metapost/context/base/mpii/mp-figs.mpii create mode 100644 metapost/context/base/mpii/mp-fobg.mpii create mode 100644 metapost/context/base/mpii/mp-form.mpii create mode 100644 metapost/context/base/mpii/mp-func.mpii create mode 100644 metapost/context/base/mpii/mp-grid.mpii create mode 100644 metapost/context/base/mpii/mp-grph.mpii create mode 100644 metapost/context/base/mpii/mp-page.mpii create mode 100644 metapost/context/base/mpii/mp-shap.mpii create mode 100644 metapost/context/base/mpii/mp-spec.mpii create mode 100644 metapost/context/base/mpii/mp-step.mpii create mode 100644 metapost/context/base/mpii/mp-text.mpii create mode 100644 metapost/context/base/mpii/mp-tool.mpii create mode 100644 metapost/context/base/mpii/mp-txts.mpii create mode 100644 metapost/context/base/mpiv/metafun.mpiv create mode 100644 metapost/context/base/mpiv/mp-abck.mpiv create mode 100644 metapost/context/base/mpiv/mp-apos.mpiv create mode 100644 metapost/context/base/mpiv/mp-asnc.mpiv create mode 100644 metapost/context/base/mpiv/mp-back.mpiv create mode 100644 metapost/context/base/mpiv/mp-bare.mpiv create mode 100644 metapost/context/base/mpiv/mp-base.mpiv create mode 100644 metapost/context/base/mpiv/mp-butt.mpiv create mode 100644 metapost/context/base/mpiv/mp-char.mpiv create mode 100644 metapost/context/base/mpiv/mp-chem.mpiv create mode 100644 metapost/context/base/mpiv/mp-core.mpiv create mode 100644 metapost/context/base/mpiv/mp-cows.mpiv create mode 100644 metapost/context/base/mpiv/mp-crop.mpiv create mode 100644 metapost/context/base/mpiv/mp-figs.mpiv create mode 100644 metapost/context/base/mpiv/mp-fobg.mpiv create mode 100644 metapost/context/base/mpiv/mp-form.mpiv create mode 100644 metapost/context/base/mpiv/mp-func.mpiv create mode 100644 metapost/context/base/mpiv/mp-grap.mpiv create mode 100644 metapost/context/base/mpiv/mp-grid.mpiv create mode 100644 metapost/context/base/mpiv/mp-grph.mpiv create mode 100644 metapost/context/base/mpiv/mp-idea.mpiv create mode 100644 metapost/context/base/mpiv/mp-luas.mpiv create mode 100644 metapost/context/base/mpiv/mp-mlib.mpiv create mode 100644 metapost/context/base/mpiv/mp-page.mpiv create mode 100644 metapost/context/base/mpiv/mp-shap.mpiv create mode 100644 metapost/context/base/mpiv/mp-step.mpiv create mode 100644 metapost/context/base/mpiv/mp-symb.mpiv create mode 100644 metapost/context/base/mpiv/mp-text.mpiv create mode 100644 metapost/context/base/mpiv/mp-tool.mpiv delete mode 100644 metapost/context/fonts/bidi-symbols.mp delete mode 100644 metapost/context/fonts/bidi-symbols.tex delete mode 100644 metapost/context/fonts/demo-symbols.mp delete mode 100644 metapost/context/fonts/demo-symbols.tex create mode 100644 metapost/context/fonts/mpiv/bidi-symbols.mp create mode 100644 metapost/context/fonts/mpiv/bidi-symbols.tex create mode 100644 metapost/context/fonts/mpiv/demo-symbols.mp create mode 100644 metapost/context/fonts/mpiv/demo-symbols.tex create mode 100644 metapost/context/fonts/mpiv/punkfont-bold.mp create mode 100644 metapost/context/fonts/mpiv/punkfont-boldslanted.mp create mode 100644 metapost/context/fonts/mpiv/punkfont-characters.mp create mode 100644 metapost/context/fonts/mpiv/punkfont-definitions.mp create mode 100644 metapost/context/fonts/mpiv/punkfont-slanted.mp create mode 100644 metapost/context/fonts/mpiv/punkfont.mp delete mode 100644 metapost/context/fonts/punkfont-bold.mp delete mode 100644 metapost/context/fonts/punkfont-boldslanted.mp delete mode 100644 metapost/context/fonts/punkfont-characters.mp delete mode 100644 metapost/context/fonts/punkfont-definitions.mp delete mode 100644 metapost/context/fonts/punkfont-slanted.mp delete mode 100644 metapost/context/fonts/punkfont.mp (limited to 'metapost') diff --git a/metapost/context/base/common/metafun.mp b/metapost/context/base/common/metafun.mp new file mode 100644 index 000000000..ae0a6d6fd --- /dev/null +++ b/metapost/context/base/common/metafun.mp @@ -0,0 +1,8 @@ +if known metafunversion : endinput ; fi ; + +if known mplib : + input metafun.mpiv +else : + input metafun.mpii +fi ; + diff --git a/metapost/context/base/common/mp-back.mp b/metapost/context/base/common/mp-back.mp new file mode 100644 index 000000000..ecfb0c816 --- /dev/null +++ b/metapost/context/base/common/mp-back.mp @@ -0,0 +1,5 @@ +if known mplib : + input mp-back.mpiv +else : + input mp-back.mpii +fi ; diff --git a/metapost/context/base/common/mp-fobg.mp b/metapost/context/base/common/mp-fobg.mp new file mode 100644 index 000000000..b61ea4724 --- /dev/null +++ b/metapost/context/base/common/mp-fobg.mp @@ -0,0 +1,5 @@ +if known mplib : + input mp-fobg.mpiv +else : + input mp-fobg.mpii +fi ; diff --git a/metapost/context/base/common/mp-symb.mp b/metapost/context/base/common/mp-symb.mp new file mode 100644 index 000000000..b39ceaab7 --- /dev/null +++ b/metapost/context/base/common/mp-symb.mp @@ -0,0 +1,6 @@ +if known mplib : + input mp-symb.mpiv +else : + input mp-symb.mpii +fi ; + diff --git a/metapost/context/base/metafun.mp b/metapost/context/base/metafun.mp deleted file mode 100644 index ae0a6d6fd..000000000 --- a/metapost/context/base/metafun.mp +++ /dev/null @@ -1,8 +0,0 @@ -if known metafunversion : endinput ; fi ; - -if known mplib : - input metafun.mpiv -else : - input metafun.mpii -fi ; - diff --git a/metapost/context/base/metafun.mpii b/metapost/context/base/metafun.mpii deleted file mode 100644 index 9c55191f7..000000000 --- a/metapost/context/base/metafun.mpii +++ /dev/null @@ -1,65 +0,0 @@ -%D \module -%D [ file=metafun.mp, -%D version=2000.07.15, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=format generation file, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -%D When generating many graphics at runtime, it can save run -%D time to use a format file. We could have named this file -%D \type {context}, but this is error prone, because it forces -%D to use the progname \type {mpost} or \type {context} -%D explicitly, depending on the needs. When using the format, -%D a mismatch in the memory specification of \type {mpost} or -%D \type {context} (the \TEX\ one) could lead to lost strings -%D (and as a result in buggy boundingbox and special -%D handling). By using the name \type {metatex} we make sure -%D that we use (unless overloaded) the settings of \type -%D {mpost}. - -%D First we input John Hobby's metapost plain file. However, -%D because we want to prevent dependency problems and in the -%D end even may use a patched version, we prefer to use a -%D copy. - -input "mp-base.mpii" ; -input "mp-tool.mpii" ; -input "mp-spec.mpii" ; -input "mp-core.mpii" ; -input "mp-page.mpii" ; -input "mp-text.mpii" ; -input "mp-txts.mpii" ; -input "mp-shap.mpii" ; -input "mp-butt.mpii" ; -input "mp-char.mpii" ; -input "mp-step.mpii" ; -input "mp-grph.mpii" ; -input "mp-figs.mpii" ; -%%%%% "mp-form.mpii" ; -input "mp-grid.mpii" ; -input "mp-func.mpii" ; - -string metafunversion ; - -metafunversion = "metafun ii" & " " & - decimal year & "-" & - decimal month & "-" & - decimal day & " " & - if ((time div 60) < 10) : "0" & fi - decimal (time div 60) & ":" & - if ((time-(time div 60)*60) < 10) : "0" & fi - decimal (time-(time div 60)*60) ; - -let normalend = end ; - -def end = - ; message "" ; message metafunversion ; message "" ; normalend ; -enddef ; - -% dump ; diff --git a/metapost/context/base/metafun.mpiv b/metapost/context/base/metafun.mpiv deleted file mode 100644 index b1d4f32e7..000000000 --- a/metapost/context/base/metafun.mpiv +++ /dev/null @@ -1,58 +0,0 @@ -%D \module -%D [ file=metafun.mp, -%D version=2000.07.15, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=format generation file, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -%D First we input John Hobby's metapost plain file. However, because we want to -%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 -input "mp-grph.mpiv" ; % todo: namespace and cleanup -input "mp-grid.mpiv" ; % todo: namespace and cleanup -input "mp-form.mpiv" ; % under (re)construction -input "mp-figs.mpiv" ; % obsolete, needs checking -input "mp-func.mpiv" ; % under construction -% "mp-text.mpiv" ; % loaded on demand -% "mp-char.mpiv" ; % loaded on demand -% "mp-step.mpiv" ; % loaded on demand -% "mp-chem.mpiv" ; % loaded on demand - -string metafunversion ; metafunversion = - "metafun iv" & " " & - decimal year & "-" & - decimal month & "-" & - decimal day & " " & - if ((time div 60) < 10) : "0" & fi - decimal (time div 60) & ":" & - if ((time-(time div 60)*60) < 10) : "0" & fi - decimal (time-(time div 60)*60) ; - -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 ; - -% dump ; % obsolete in mplib diff --git a/metapost/context/base/mp-abck.mpiv b/metapost/context/base/mp-abck.mpiv deleted file mode 100644 index abd7d8848..000000000 --- a/metapost/context/base/mp-abck.mpiv +++ /dev/null @@ -1,269 +0,0 @@ -%D \module -%D [ file=mp-abck.mpiv, -%D version=2012.02.19, % was mp-core: 1999.08.01, anchoring -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=anchored background macros, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -if known context_abck : endinput ; fi ; - -boolean context_abck ; context_abck := true ; - -path multiregs[], % region used for multipar (tracing only) - multipars[], % effective area (shape) - multibox ; % main boundingbox (of main region) - -string multikind[] ; % region state: single | first | middle | last (new method) - -numeric multilocs[], % 1=begin 2=between 3=end (old method) - nofmultipars ; % number of calculated areas - -numeric par_strut_height, - par_strut_depth, - par_line_height ; - -nofmultipars := 0 ; -par_strut_height := 0 ; -par_strut_depth := 0 ; -par_line_height := 0 ; - -def boxgridoptions = withcolor .8red enddef ; -def boxlineoptions = withcolor .8blue enddef ; -def boxfilloptions = withcolor .8white enddef ; - -numeric boxgridtype ; boxgridtype := 0 ; -numeric boxlinetype ; boxlinetype := 1 ; -numeric boxfilltype ; boxfilltype := 1 ; -numeric boxdashtype ; boxdashtype := 0 ; -pair boxgriddirection ; boxgriddirection := up ; -numeric boxgridwidth ; boxgridwidth := 1pt ; -numeric boxlinewidth ; boxlinewidth := 1pt ; -numeric boxlineradius ; boxlineradius := 0 ; -numeric boxlineoffset ; boxlineoffset := 0 ; -numeric boxfilloffset ; boxfilloffset := 0 ; -numeric boxgriddistance ; boxgriddistance := .5cm ; -numeric boxgridshift ; boxgridshift := 0 ; - -def abck_show_path(expr p, r, c) = - draw p withpen pencircle scaled .5pt withcolor c ; - if length(p) > 2 : - begingroup ; save _c_ ; path _c_ ; _c_ := fullcircle scaled r ; - for i=0 upto length(p) if cycle p : -1 fi : - fill _c_ shifted point i of p withcolor white ; - draw _c_ shifted point i of p withpen pencircle scaled .5pt withcolor c ; - endfor ; - fi ; -enddef ; - -vardef abck_draw_path(expr p) = - if (length p > 2) and (bbwidth(p) > 1) and (bbheight(p) > 1) : - save pp ; path pp ; - pp := p if (boxlineradius>0) and (boxlinetype=2) : cornered boxlineradius fi ; - if boxfilltype > 0 : - if boxfilloffset > 0 : - interim linejoin := mitered ; - filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ; - else : - fill pp boxfilloptions ; - fi ; - fi ; - if boxlinetype > 0 : - draw pp boxlineoptions withpen pencircle scaled boxlinewidth ; - fi ; - fi ; -enddef ; - -def abck_grid_line(expr start, width) = - % 1 = normal, 2 = with background (i.e. no shine-through) - if boxdashtype = 2 : - draw start -- start shifted (width,0) - withpen pencircle scaled boxgridwidth - boxfilloptions ; - fi ; - draw start -- start shifted (width,0) - if boxdashtype > 0 : - dashed evenly - fi - withpen pencircle scaled boxgridwidth - boxgridoptions ; -enddef ; - -vardef abck_baseline_grid(expr pxy, pdir, at_baseline) = - save width ; width := bbwidth(pxy) ; - save height ; height := bbheight(pxy) ; - if (par_line_height > 0) and (height > 1) and (width > 1) and (boxgridwidth > 0) : - save i, grid, bb ; picture grid ; pair start ; path bb ; - grid := image ( % fails with inlinespace - if pdir = up : - for i = if at_baseline : par_strut_depth else : 0 fi step par_line_height until max(height,par_line_height) : - abck_grid_line(llcorner pxy shifted (0,+i),width) ; - endfor ; - else : - for i = if at_baseline : par_strut_height else : 0 fi step par_line_height until height : - abck_grid_line(ulcorner pxy shifted (0,-i),width) ; - endfor ; - fi ; - ) ; - clip grid to pxy ; - bb := boundingbox grid ; - grid := grid shifted (0,boxgridshift) ; - setbounds grid to bb ; - grid - else : - nullpicture - fi -enddef ; - -vardef abck_graphic_grid(expr pxy, dx, dy, x, y) = - if (bbheight(pxy) > dy) and (bbwidth(pxy) > dx) and (boxgridwidth > 0) : - save grid ; picture grid ; - grid := image ( - for i = xpart llcorner pxy step dx until xpart lrcorner pxy : - draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) withpen pencircle scaled boxgridwidth ; - endfor ; - for i = ypart llcorner pxy step dy until ypart ulcorner pxy : - draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) withpen pencircle scaled boxgridwidth ; - endfor - ) shifted (x,y) ; - clip grid to pxy ; - grid - else : - nullpicture - fi -enddef ; - -def draw_multi_pars = - for i=1 upto nofmultipars : - abck_draw_path(multipars[i]) ; - if boxgridtype = 1 : - draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ; - elseif boxgridtype = 2 : - draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,false) ; - elseif boxgridtype = 3 : - draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ; - draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; - elseif boxgridtype = 4 : - draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; - elseif boxgridtype = 11 : - draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; - elseif boxgridtype = 12 : - draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; - fi ; - endfor ; -enddef ; - -def show_multi_pars = - for i=1 upto nofmultipars : - abck_show_path(multipars[i], 6pt, .5blue) ; - endfor ; -enddef ; - -def show_multi_kind = - for i=1 upto nofmultipars : - fill multipars[i] - withcolor - if multikind[i] = "single" : yellow - elseif multikind[i] = "first" : red - elseif multikind[i] = "middle" : green - elseif multikind[i] = "last" : blue - fi - withtransparency (1,.5) - ; - endfor ; -enddef ; - -def multi_side_draw_options = enddef ; - -def draw_multi_side = - begingroup ; save p ; picture p ; - for i=1 upto nofmultipars : - p := image ( fill leftboundary multipars[i] - shifted (-boxlineoffset,0) - rightenlarged boxlinewidth boxlineoptions ; - ) ; - setbounds p to multipars[i] ; - draw p ; - endfor ; - endgroup ; -enddef ; - -def draw_multi_side_path text t = - begingroup ; save p ; picture p ; - for i=1 upto nofmultipars : - p := image ( draw leftboundary multipars[i] - shifted (-boxlineoffset,0) - withpen pensquare scaled boxlinewidth boxlineoptions t ; - ) ; - setbounds p to multipars[i] ; - draw p ; - endfor ; - endgroup ; -enddef ; - -% some extras - -path posboxes[], - posregions[] ; - -numeric multipages[], - nofposboxes ; - -nofposboxes := 0 ; - -% For the moment we keep these as they can be in use but they will -% disappear. - -pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; -path pxy[] ; -numeric hxy[], wxy[], dxy[], nxy[] ; - -def box_found (expr n,x,y,w,h,d) = - not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) -enddef ; - -def initialize_box_pos (expr pos,n,x,y,w,h,d) = - pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; - path pxy ; numeric hxy, wxy, dxy, nxy; - lxy := (x,y) ; - llxy := (x,y-d) ; - lrxy := (x+w,y-d) ; - urxy := (x+w,y+h) ; - ulxy := (x,y+h) ; - wxy := w ; - hxy := h ; - dxy := d ; - rxy := lxy shifted (wxy,0) ; - pxy := llxy--lrxy--urxy--ulxy--cycle ; - cxy := center pxy ; - nxy := n ; - freeze_box(pos) ; -enddef ; - -def freeze_box (expr pos) = - lxy[pos] := lxy ; - llxy[pos] := llxy ; - lrxy[pos] := lrxy ; - urxy[pos] := urxy ; - ulxy[pos] := ulxy ; - wxy[pos] := wxy ; - hxy[pos] := hxy ; - dxy[pos] := dxy ; - rxy[pos] := rxy ; - pxy[pos] := pxy ; - cxy[pos] := cxy ; - nxy[pos] := nxy ; -enddef ; - -def initialize_box (expr n,x,y,w,h,d) = - numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; -enddef ; - -def anchor_box (expr n,x,y,w,h,d) = - currentpicture := currentpicture shifted (-x,-y) ; -enddef ; diff --git a/metapost/context/base/mp-apos.mpiv b/metapost/context/base/mp-apos.mpiv deleted file mode 100644 index 7b7737754..000000000 --- a/metapost/context/base/mp-apos.mpiv +++ /dev/null @@ -1,102 +0,0 @@ -%D \module -%D [ file=mp-apos.mpiv, -%D version=2012.02.19, % was mp-core: 1999.08.01, anchoring -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=anchored background macros, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -if known context_apos : endinput ; fi ; - -boolean context_apos ; context_apos := true ; - -path posboxes[], - posregions[] ; - -numeric multipages[], - nofposboxes ; - -nofposboxes := 0 ; - -def boxlineoptions = withcolor .8blue enddef ; -def boxfilloptions = withcolor .8white enddef ; - -def connect_positions = - if nofposboxes = 2 : - pickup pencircle scaled boxlinewidth ; - path pa ; pa := posboxes[1] enlarged boxlineoffset ; - path pb ; pb := posboxes[2] enlarged boxlineoffset ; - if pospages[1] = pospages[2] : - draw posboxes[1] boxlineoptions ; - path pc ; pc := center pa {up} .. {down} center pb ; - pair cc ; cc := (pc intersection_point pa) ; - if intersection_found : - pc := pc cutbefore cc ; - cc := (pc intersection_point pb) ; - if intersection_found : - pc := pc cutafter cc ; - drawarrow pc boxlineoptions ; - drawarrow reverse pc boxlineoptions ; - fi ; - fi ; - elseif pospages[1] == RealPageNumber : - draw posboxes[1] boxlineoptions ; - path pc ; pc := center pa {up} ... {right} urcorner (posregions[1] enlarged (20pt,20pt)) ; - pair cc ; cc := (pc intersection_point pa) ; - if intersection_found : - pc := pc cutbefore cc ; - drawarrow pc boxlineoptions ; - fi ; - elseif pospages[2] == RealPageNumber : - draw posboxes[2] boxlineoptions ; - path pc ; pc := ulcorner (posregions[2] enlarged (20pt,20pt)) {right} ... {down} center pb ; - pair cc ; cc := (pc intersection_point pb) ; - if intersection_found : - pc := pc cutafter cc ; - drawarrow pc boxlineoptions ; - fi ; - fi ; - fi ; -enddef ; - -% anch-bar: - -def anch_sidebars_draw (expr p_b_self, p_e_self, y_b_self, y_e_self, h_b_self, d_e_self, - x, y, w, h, alternative, distance, linewidth, linecolor, topoffset, bottomoffset) = - % beware, we anchor at (x,y) - begingroup ; - if alternative = 1 : - interim linecap := rounded ; - else : - interim linecap := butt ; - fi ; - save a, b ; pair a, b ; - if p_b_self = p_e_self : - a := (-distance,y_b_self+h_b_self-y) ; - b := (-distance,y_e_self-d_e_self-y) ; - elseif RealPageNumber = p_b_self : - a := (-distance,y_b_self+h_b_self-y) ; - b := (-distance,0) ; - elseif RealPageNumber = p_e_self : - a := (-distance,h) ; - b := (-distance,y_e_self-d_e_self-y) ; - else : - a := (-distance,h) ; - b := (-distance,0) ; - fi ; - a := (xpart a, min(ypart a + topoffset, h)) ; - b := (xpart b, max(ypart b - bottomoffset,0)) ; - draw - a -- b - if alternative = 1 : - dashed (withdots scaled (linewidth/2)) - fi - withpen pencircle scaled linewidth - withcolor linecolor ; - endgroup ; -enddef ; diff --git a/metapost/context/base/mp-asnc.mpiv b/metapost/context/base/mp-asnc.mpiv deleted file mode 100644 index 2626e4d58..000000000 --- a/metapost/context/base/mp-asnc.mpiv +++ /dev/null @@ -1,177 +0,0 @@ -%D \module -%D [ file=mp-asnc.mpiv, -%D version=2012.02.19, % was mp-core: 1999.08.01, anchoring -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=anchored background macros, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -if known context_asnc : endinput ; fi ; - -boolean context_av ; context_asnc := true ; - -% will be replaced - -numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; -pair sync_xy[][] ; color sync_c[][] ; - -def ResetSyncTasks = - path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; - NOfSyncPaths := CurrentSyncClass := 0 ; - if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; - if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; - if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; - if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; - if (SyncLeftOffset = 0) and (SyncWidth = 0) : - SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; - fi ; -enddef ; - -ResetSyncTasks ; - -vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = - save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; - o shifted (leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,bottomoffset) -- - o shifted (leftoffset,bottomoffset) -- cycle -enddef ; - -def SetSyncColor(expr n, i, c) = - sync_c[n][i] := c ; -enddef ; - -def SetSyncThreshold(expr n, i, th) = - sync_th[n][i] := th ; -enddef ; - -vardef TheSyncColor(expr n, i) = - if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi -enddef ; - -vardef TheSyncThreshold(expr n, i) = - if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi -enddef ; - -vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = - ResetSyncTasks ; - if known sync_n[n] : - CurrentSyncClass := n ; - save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; - for i=1 upto sync_n[n] : - if RealPageNumber > sync_p[n][i] : - l := i ; - elseif RealPageNumber = sync_p[n][i] : - NOfSyncPaths := NOfSyncPaths + 1 ; - if not ok : - if i>1 : - if sync_t[n][i-1] = sync_t[n][i] : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i-1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - ok := true ; - fi ; - endfor ; - if (NOfSyncPaths = 0) and (l > 0) : - NOfSyncPaths := 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := l ; - fi ; - if NOfSyncPaths > 0 : - for i = 1 upto NOfSyncPaths-1 : - SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; - endfor ; - if unknown SyncThresholdMethod : - numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; - fi ; - if extendtop : - if SyncThresholdMethod = 1 : - if NOfSyncPaths>1 : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; - if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : - SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; - fi ; - fi ; - else : - for i = 1 upto NOfSyncPaths : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; - if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : - SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; - fi ; - endfor ; - fi ; - fi ; - if prestartnext : - if NOfSyncPaths>1 : - if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; - if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : - SyncPaths[NOfSyncPaths+1] := - (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - lrcorner SyncPaths[NOfSyncPaths] -- - llcorner SyncPaths[NOfSyncPaths] -- cycle ; - SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - fi ; - fi ; - fi ; - else : - if NOfSyncPaths>1 : - d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; - if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : - NOfSyncPaths := NOfSyncPaths - 1 ; - SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; - fi ; - fi ; - fi ; - if (NOfSyncPaths>1) and collapse : - save j ; numeric j ; j := 1 ; - for i = 2 upto NOfSyncPaths : - if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : - SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; - SyncTasks[j] := SyncTasks[i] ; - else : - j := j + 1 ; - SyncPaths[j] := SyncPaths[i] ; - SyncTasks[j] := SyncTasks[i] ; - fi ; - endfor ; - NOfSyncPaths := j ; - fi ; - fi ; - fi ; -enddef ; - -def SyncTask(expr n) = - if known SyncTasks[n] : SyncTasks[n] else : 0 fi -enddef ; - -def FlushSyncTasks = - for i = 1 upto NOfSyncPaths : - ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; - endfor ; -enddef ; - -def ProcessSyncTask(expr p, c) = - fill p withcolor c ; -enddef ; diff --git a/metapost/context/base/mp-back.mp b/metapost/context/base/mp-back.mp deleted file mode 100644 index f588adea9..000000000 --- a/metapost/context/base/mp-back.mp +++ /dev/null @@ -1,205 +0,0 @@ -%D \module -%D [ file=mp-back.mp, -%D version=2000.05.31, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=backgrounds, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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_back : endinput ; fi ; - -boolean context_back ; context_back := true ; - -def some_hash ( expr hash_width , - hash_height , - hash_linewidth , - hash_linecolor , - hash_angle , - hash_gap ) = - - stripe_gap := hash_gap ; - stripe_angle := hash_angle ; - drawoptions (withpen pencircle scaled hash_linewidth - withcolor hash_linecolor) ; - path p ; p := unitsquare xscaled hash_width yscaled hash_height ; - stripe_path_a () (draw) p ; % next we move it all to quadrant 1 - currentpicture := currentpicture shifted urcorner currentpicture ; - -enddef ; - -def some_double_back (expr back_type , - back_width , - back_height , - back_delta , - back_linewidth , - back_linecolor , - back_fillcolor , - back_topcolor , - back_bottomcolor , - back_leftcolor , - back_rightcolor ) = - - numeric ww ; ww := back_width ; - numeric hh ; hh := back_height ; - numeric dd ; dd := back_delta ; - - color back_nillcolor ; back_nillcolor := back_topcolor ; - - path p ; p := fullsquare xscaled ww yscaled hh ; - path q ; q := fullsquare xscaled (ww-2dd) yscaled (hh-2dd) ; - path r ; r := llcorner p -- - lrcorner p shifted (-3dd,0) .. controls lrcorner p .. - lrcorner p shifted (0, 3dd) -- - urcorner p shifted (0,-3dd) .. controls urcorner p .. - urcorner p shifted (-3dd,0) -- - ulcorner p -- cycle ; - path s ; s := r xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; - path t ; t := llcorner p -- - lrcorner p -- - urcorner p shifted (0,-3dd) .. controls urcorner p .. - urcorner p shifted (-3dd,0) -- - ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. - ulcorner p shifted (0,-3dd) -- - llcorner p -- cycle ; - path u ; u := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; - path v ; v := llcorner p shifted ( 3dd,0) -- - lrcorner p shifted (-3dd,0) .. controls lrcorner p .. - lrcorner p shifted (0, 3dd) -- - urcorner p shifted (0,-3dd) .. controls urcorner p .. - urcorner p shifted (-3dd,0) -- - ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. - ulcorner p shifted (0,-3dd) .. - llcorner p shifted (0, 3dd) .. controls llcorner p .. cycle ; % {down} .. cycle ; - path w ; w := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; - path a ; a := llcorner p -- ulcorner p -- - ulcorner q -- llcorner q -- cycle ; - path b ; b := llcorner p -- lrcorner p -- - lrcorner q -- llcorner q -- cycle ; - path c ; c := lrcorner p -- urcorner p -- - urcorner q -- lrcorner q -- cycle ; - path d ; d := ulcorner p -- urcorner p -- - urcorner q -- ulcorner q -- cycle ; - path e ; e := llcorner p -- lrcorner p -- - urcorner p -- urcorner q -- - lrcorner q -- llcorner q -- cycle ; - path f ; f := llcorner p -- ulcorner p -- - urcorner p -- urcorner q -- - ulcorner q -- llcorner q -- cycle ; - - linecap := butt ; pickup pencircle scaled back_linewidth ; - - if back_type=1 : - - fill p withcolor back_fillcolor ; - fill a withcolor back_leftcolor ; - fill b withcolor back_bottomcolor ; - fill c withcolor back_rightcolor ; - fill d withcolor back_topcolor ; - draw a withcolor back_linecolor ; - draw d withcolor back_linecolor ; - draw b withcolor back_linecolor ; - draw c withcolor back_linecolor ; - - elseif back_type=2 : - - fill p withcolor back_fillcolor ; - fill e withcolor back_bottomcolor ; - fill f withcolor back_topcolor ; - draw e withcolor back_linecolor ; - draw f withcolor back_linecolor ; - - elseif back_type=3 : - - fill v withcolor back_nillcolor ; - fill w withcolor back_fillcolor ; - draw v withcolor back_linecolor ; - draw w withcolor back_linecolor ; - - elseif back_type=4 : - - fill t withcolor back_nillcolor ; - fill u withcolor back_fillcolor ; - draw t withcolor back_linecolor ; - draw u withcolor back_linecolor ; - - elseif back_type=5 : - - t := t rotatedaround(center t,180) ; - u := u rotatedaround(center u,180) ; - - fill t withcolor back_nillcolor ; - fill u withcolor back_fillcolor ; - draw t withcolor back_linecolor ; - draw u withcolor back_linecolor ; - - elseif back_type=6 : - - r := r rotatedaround(center r,180) ; - s := s rotatedaround(center s,180) ; - - fill r withcolor back_nillcolor ; - fill s withcolor back_fillcolor ; - draw r withcolor back_linecolor ; - draw s withcolor back_linecolor ; - - elseif back_type=7 : - - fill r withcolor back_nillcolor ; - fill s withcolor back_fillcolor ; - draw r withcolor back_linecolor ; - draw s withcolor back_linecolor ; - -fi ; - -enddef ; - -endinput ; - -beginfig (1) ; - -some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, .6white, .7white, .6white) - -currentpicture := currentpicture shifted (0,-3cm) ; - -some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, .6white, white, white) - -currentpicture := currentpicture shifted (0,-3cm) ; - -some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, white, white, white) - -currentpicture := currentpicture shifted (0,-3cm) ; - -some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, white, white, white) - -currentpicture := currentpicture shifted (0,-3cm) ; - -some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, white, white, white) - -currentpicture := currentpicture shifted (0,-3cm) ; - -some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, white, white, white) - -currentpicture := currentpicture shifted (0,-3cm) ; - -some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, white, white, white) - -currentpicture := currentpicture shifted (0,-3cm) ; - -some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm, - .5white, .8white, .7white, white, white, white) - -endfig ; - -end . diff --git a/metapost/context/base/mp-bare.mpiv b/metapost/context/base/mp-bare.mpiv deleted file mode 100644 index c6194b1ee..000000000 --- a/metapost/context/base/mp-bare.mpiv +++ /dev/null @@ -1,93 +0,0 @@ -%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 deleted file mode 100644 index 7af4bc436..000000000 --- a/metapost/context/base/mp-base.mpii +++ /dev/null @@ -1,591 +0,0 @@ -% This is (currently) a copy of the plain.mp file. We use a copy -% because (1) we want to make sure that there are no unresolved -% dependencies, and (2) we may patch this file eventually. -% -% colorpart will be overloaded later (we already had that one) -% _findarr now has a filldraw, was fill in 0.63 - -% This file gives the macros for plain MetaPost -% It contains all the features of plain METAFONT except those specific to -% font-making. (See The METAFONTbook by D.E. Knuth). -% There are also a number of macros for labeling figures, etc. -string base_name, base_version; base_name="plain"; base_version="1.004 for metafun ii"; - -message "Preloading the plain mem file, version "&base_version; - -delimiters (); % this makes parentheses behave like parentheses -def upto = step 1 until enddef; % syntactic sugar -def downto = step -1 until enddef; -def exitunless expr c = exitif not c enddef; -let relax = \; % ignore the word `relax', as in TeX -let \\ = \; % double relaxation is like single -def ]] = ] ] enddef; % right brackets should be loners -def -- = {curl 1}..{curl 1} enddef; -def --- = .. tension infinity .. enddef; -def ... = .. tension atleast 1 .. enddef; - -def gobble primary g = enddef; -primarydef g gobbled gg = enddef; -def hide(text t) = exitif numeric begingroup t;endgroup; enddef; -def ??? = hide(interim showstopping:=1; showdependencies) enddef; -def stop expr s = message s; gobble readstring enddef; - -warningcheck:=1; -tracinglostchars:=1; - -def interact = % sets up to make "show" commands stop - hide(showstopping:=1; tracingonline:=1) enddef; - -def loggingall = % puts tracing info into the log - tracingcommands:=3; tracingtitles:=1; tracingequations:=1; - tracingcapsules:=1; tracingspecs:=2; tracingchoices:=1; tracinglostchars:=1; - tracingstats:=1; tracingoutput:=1; tracingmacros:=1; tracingrestores:=1; - enddef; - -def tracingall = % turns on every form of tracing - tracingonline:=1; showstopping:=1; loggingall enddef; - -def tracingnone = % turns off every form of tracing - tracingcommands:=0; tracingtitles:=0; tracingequations:=0; - tracingcapsules:=0; tracingspecs:=0; tracingchoices:=0; tracinglostchars:=0; - tracingstats:=0; tracingoutput:=0; tracingmacros:=0; tracingrestores:=0; - enddef; - - - -%% dash patterns - -vardef dashpattern(text t) = - save on, off, w; - let on=_on_; - let off=_off_; - w = 0; - nullpicture t -enddef; - -tertiarydef p _on_ d = - begingroup save pic; - picture pic; pic=p; - addto pic doublepath (w,w)..(w+d,w); - w := w+d; - pic shifted (0,d) - endgroup -enddef; - -tertiarydef p _off_ d = - begingroup w:=w+d; - p shifted (0,d) - endgroup -enddef; - - - -%% basic constants and mathematical macros - -% numeric constants -newinternal eps,epsilon,infinity,_; -eps := .00049; % this is a pretty small positive number -epsilon := 1/256/256; % but this is the smallest -infinity := 4095.99998; % and this is the largest -_ := -1; % internal constant to make macros unreadable but shorter - -newinternal mitered, rounded, beveled, butt, squared; -mitered:=0; rounded:=1; beveled:=2; % linejoin types -butt:=0; rounded:=1; squared:=2; % linecap types - - -% pair constants -pair right,left,up,down,origin; -origin=(0,0); up=-down=(0,1); right=-left=(1,0); - -% path constants -path quartercircle,halfcircle,fullcircle,unitsquare; -fullcircle = makepath pencircle; -halfcircle = subpath (0,4) of fullcircle; -quartercircle = subpath (0,2) of fullcircle; -unitsquare=(0,0)--(1,0)--(1,1)--(0,1)--cycle; - -% transform constants -transform identity; -for z=origin,right,up: z transformed identity = z; endfor - -% color constants -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 -def colorpart primary t = - if colormodel t=7: - (cyanpart t, magentapart t, yellowpart t, blackpart t) - elseif colormodel t=5: - (redpart t, greenpart t, bluepart t) - elseif colormodel t=3: - (greypart t) - elseif colormodel t=1: - false - else: - %%% For clipping and bounding paths, etc. - if defaultcolormodel=7: (0,0,0,1) - elseif defaultcolormodel=5: black - elseif defaultcolormodel=3: 0 - else: false - fi - fi -enddef; - -% picture constants -picture blankpicture,evenly,withdots; -blankpicture=nullpicture; % `display blankpicture...' -evenly=dashpattern(on 3 off 3); % `dashed evenly' -withdots=dashpattern(off 2.5 on 0 off 2.5); % `dashed withdots' - -% string constants -string ditto, EOF; -ditto = char 34; % ASCII double-quote mark -EOF = char 0; % end-of-file for readfrom and write..to - -% pen constants -pen pensquare,penrazor,penspeck; -pensquare = makepen(unitsquare shifted -(.5,.5)); -penrazor = makepen((-.5,0)--(.5,0)--cycle); -penspeck=pensquare scaled eps; - -% nullary operators -vardef whatever = save ?; ? enddef; - -% unary operators -let abs = length; - -vardef round primary u = - if numeric u: floor(u+.5) - elseif pair u: (round xpart u, round ypart u) - else: u fi enddef; - -vardef ceiling primary x = -floor(-x) enddef; - -vardef byte primary s = - if string s: ASCII fi s enddef; - -vardef dir primary d = right rotated d enddef; - -vardef unitvector primary z = z/abs z enddef; - -vardef inverse primary T = - transform T_; T_ transformed T = identity; T_ enddef; - -vardef counterclockwise primary c = - if turningnumber c <= 0: reverse fi c enddef; - -vardef tensepath expr r = - for k=0 upto length r - 1: point k of r --- endfor - if cycle r: cycle else: point infinity of r fi enddef; - -vardef center primary p = .5[llcorner p, urcorner p] enddef; - - - -% binary operators - -primarydef x mod y = (x-y*floor(x/y)) enddef; -primarydef x div y = floor(x/y) enddef; -primarydef w dotprod z = (xpart w * xpart z + ypart w * ypart z) enddef; - -primarydef x**y = if y=2: x*x else: takepower y of x fi enddef; -def takepower expr y of x = - if x>0: mexp(y*mlog x) - elseif (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=_ 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; - -vardef directionpoint expr z of p = - a_:=directiontime z of p; - if a_<0: errmessage("The direction doesn't occur"); fi - point a_ of p enddef; - -secondarydef p intersectionpoint q = - begingroup save x_,y_; (x_,y_)=p intersectiontimes q; - if x_<0: errmessage("The paths don't intersect"); origin - else: .5[point x_ of p, point y_ of q] fi endgroup -enddef; - -tertiarydef p softjoin q = - begingroup c_:=fullcircle scaled 2join_radius shifted point 0 of q; - a_:=ypart(c_ intersectiontimes p); b_:=ypart(c_ intersectiontimes q); - if a_<0:point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi - ... if b_<0:{direction infinity of q}point infinity of q - else: subpath(b_,infinity) of q fi endgroup enddef; -newinternal join_radius,a_,b_; path c_; - - -path cuttings; % what got cut off - -tertiarydef a cutbefore b = % tries to cut as little as possible - begingroup save t; - (t, whatever) = a intersectiontimes b; - if t<0: - cuttings:=point 0 of a; - a - else: cuttings:= subpath (0,t) of a; - subpath (t,length a) of a - fi - endgroup -enddef; - -tertiarydef a cutafter b = - reverse (reverse a cutbefore b) - hide(cuttings:=reverse cuttings) -enddef; - - - -% special operators -vardef incr suffix $ = $:=$+1; $ enddef; -vardef decr suffix $ = $:=$-1; $ enddef; - -def reflectedabout(expr w,z) = % reflects about the line w..z - transformed - begingroup transform T_; - w transformed T_ = w; z transformed T_ = z; - xxpart T_ = -yypart T_; xypart T_ = yxpart T_; % T_ is a reflection - T_ endgroup enddef; - -def rotatedaround(expr z, d) = % rotates d degrees around z - shifted -z rotated d shifted z enddef; -let rotatedabout = rotatedaround; % for roundabout people - -vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings - save u_; setu_ u; for uu = t: if uuu_: u_:=uu; fi endfor - u_ enddef; - -def setu_ primary u = - if pair u: pair u_ elseif string u: string u_ fi; - u_=u enddef; - -def flex(text t) = % t is a list of pairs - hide(n_:=0; for z=t: z_[incr n_]:=z; endfor - dz_:=z_[n_]-z_1) - z_1 for k=2 upto n_-1: ...z_[k]{dz_} endfor ...z_[n_] enddef; -newinternal n_; pair z_[],dz_; - -def superellipse(expr r,t,l,b,s)= - r{up}...(s[xpart t,xpart r],s[ypart r,ypart t]){t-r}... - t{left}...(s[xpart t,xpart l],s[ypart l,ypart t]){l-t}... - l{down}...(s[xpart b,xpart l],s[ypart l,ypart b]){b-l}... - b{right}...(s[xpart b,xpart r],s[ypart r,ypart b]){r-b}...cycle enddef; - -vardef interpath(expr a,p,q) = - for t=0 upto length p-1: a[point t of p, point t of q] - ..controls a[postcontrol t of p, postcontrol t of q] - and a[precontrol t+1 of p, precontrol t+1 of q] .. endfor - if cycle p: cycle - else: a[point infinity of p, point infinity of q] fi enddef; - -vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false - tx_:=true_x; fx_:=false_x; - forever: x_:=.5[tx_,fx_]; exitif abs(tx_-fx_)<=tolerance; - if @#(x_): tx_ else: fx_ fi :=x_; endfor - x_ enddef; % now x_ is near where @# changes from true to false -newinternal tolerance, tx_,fx_,x_; tolerance:=.01; - -vardef buildcycle(text ll) = - save ta_, tb_, k_, i_, pp_; path pp_[]; - k_=0; - for q=ll: pp_[incr k_]=q; endfor - i_=k_; - for i=1 upto k_: - (ta_[i], length pp_[i_]-tb_[i_]) = - pp_[i] intersectiontimes reverse pp_[i_]; - if ta_[i]<0: - errmessage("Paths "& decimal i &" and "& decimal i_ &" don't intersect"); - fi - i_ := i; - endfor - for i=1 upto k_: subpath (ta_[i],tb_[i]) of pp_[i] .. endfor - cycle -enddef; - - - -%% units of measure - -mm=2.83464; pt=0.99626; dd=1.06601; bp:=1; -cm=28.34645; pc=11.95517; cc=12.79213; in:=72; - -vardef magstep primary m = mexp(46.67432m) enddef; - - - -%% macros for drawing and filling - -def drawoptions(text t) = - def _op_ = t enddef -enddef; - -linejoin:=rounded; % parameters that effect drawing -linecap:=rounded; -miterlimit:=10; - -drawoptions(); - -pen currentpen; -picture currentpicture; - -def fill expr c = addto currentpicture contour c _op_ enddef; -def draw expr p = - addto currentpicture - if picture p: - also p - else: - doublepath p withpen currentpen - fi - _op_ -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 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; -def unfilldraw expr c = filldraw c withcolor background enddef; -def undrawdot expr z = drawdot z withcolor background enddef; -def erase text t = - def _e_ = withcolor background hide(def _e_=enddef;) enddef; - t _e_ -enddef; -def _e_= enddef; - -def cutdraw text t = - begingroup interim linecap:=butt; draw t _e_; endgroup enddef; - -vardef image(text t) = - save currentpicture; - picture currentpicture; - currentpicture := nullpicture; - t; - currentpicture -enddef; - -def pickup secondary q = - if numeric q: numeric_pickup_ else: pen_pickup_ fi q enddef; -def numeric_pickup_ primary q = - if unknown pen_[q]: errmessage "Unknown pen"; clearpen - else: currentpen:=pen_[q]; - pen_lft:=pen_lft_[q]; - pen_rt:=pen_rt_[q]; - pen_top:=pen_top_[q]; - pen_bot:=pen_bot_[q]; - currentpen_path:=pen_path_[q] fi; 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; - path currentpen_path; enddef; -newinternal pen_lft,pen_rt,pen_top,pen_bot,pen_count_; - -vardef savepen = pen_[incr pen_count_]=currentpen; - pen_lft_[pen_count_]=pen_lft; - pen_rt_[pen_count_]=pen_rt; - pen_top_[pen_count_]=pen_top; - pen_bot_[pen_count_]=pen_bot; - pen_path_[pen_count_]=currentpen_path; - pen_count_ enddef; - -def clearpen = currentpen:=nullpen; - pen_lft:=pen_rt:=pen_top:=pen_bot:=0; - path currentpen_path; - enddef; -def clear_pen_memory = - pen_count_:=0; - numeric pen_lft_[],pen_rt_[],pen_top_[],pen_bot_[]; - pen currentpen,pen_[]; - path currentpen_path, pen_path_[]; - enddef; - -vardef lft primary x = x + if pair x: (pen_lft,0) else: pen_lft fi enddef; -vardef rt primary x = x + if pair x: (pen_rt,0) else: pen_rt fi enddef; -vardef top primary y = y + if pair y: (0,pen_top) else: pen_top fi enddef; -vardef bot primary y = y + if pair y: (0,pen_bot) else: pen_bot fi enddef; - -vardef penpos@#(expr b,d) = - (x@#r-x@#l,y@#r-y@#l)=(b,0) rotated d; - x@#=.5(x@#l+x@#r); y@#=.5(y@#l+y@#r) enddef; - -def penstroke text t = - forsuffixes e = l,r: path_.e:=t; endfor - fill path_.l -- reverse path_.r -- cycle enddef; -path path_.l,path_.r; - - - -%% High level drawing commands - -newinternal ahlength, ahangle; -ahlength := 4; % default arrowhead length 4bp -ahangle := 45; % default head angle 45 degrees - -vardef arrowhead expr p = - save q,e; path q; pair e; - e = point length p of p; - q = gobble(p shifted -e cutafter makepath(pencircle scaled 2ahlength)) - cuttings; - (q rotated .5ahangle & reverse q rotated -.5ahangle -- cycle) shifted e -enddef; - -path _apth; -def drawarrow expr p = _apth:=p; _finarr enddef; -def drawdblarrow expr p = _apth:=p; _findarr enddef; - -def _finarr text t = - draw _apth t; - filldraw arrowhead _apth t -enddef; - -def _findarr text t = - draw _apth t; - filldraw arrowhead _apth withpen currentpen t; - filldraw arrowhead reverse _apth withpen currentpen t -enddef; - - - -%% macros for labels - -newinternal bboxmargin; bboxmargin:=2bp; - -vardef bbox primary p = - llcorner p-(bboxmargin,bboxmargin) -- lrcorner p+(bboxmargin,-bboxmargin) - -- urcorner p+(bboxmargin,bboxmargin) -- ulcorner p+(-bboxmargin,bboxmargin) - -- cycle -enddef; - -string defaultfont; -newinternal defaultscale, labeloffset; -defaultfont = "cmr10"; -defaultscale := 1; -labeloffset := 3bp; - -vardef thelabel@#(expr s,z) = % Position s near z - save p; picture p; - if picture s: p=s - else: p = s infont defaultfont scaled defaultscale - fi; - p shifted (z + labeloffset*laboff@# - - (labxf@#*lrcorner p + labyf@#*ulcorner p - + (1-labxf@#-labyf@#)*llcorner p - ) - ) -enddef; - -def label = draw thelabel enddef; -newinternal dotlabeldiam; dotlabeldiam:=3bp; -vardef dotlabel@#(expr s,z) text t_ = - label@#(s,z) t_; - interim linecap:=rounded; - draw z withpen pencircle scaled dotlabeldiam t_; -enddef; -def makelabel = dotlabel enddef; - -pair laboff, laboff.lft, laboff.rt, laboff.top, laboff.bot; -pair laboff.ulft, laboff.llft, laboff.urt, laboff.lrt; -laboff =(0,0); labxf =.5; labyf =.5; -laboff.lft=(-1,0); labxf.lft=1; labyf.lft=.5; -laboff.rt =(1,0); labxf.rt =0; labyf.rt =.5; -laboff.bot=(0,-1); labxf.bot=.5; labyf.bot=1; -laboff.top=(0,1); labxf.top=.5; labyf.top=0; -laboff.ulft=(-.7,.7);labxf.ulft=1; labyf.ulft=0; -laboff.urt=(.7,.7); labxf.urt=0; labyf.urt=0; -laboff.llft=-(.7,.7);labxf.llft=1; labyf.llft=1; -laboff.lrt=(.7,-.7); labxf.lrt=0; labyf.lrt=1; - -vardef labels@#(text t) = - forsuffixes $=t: - label@#(str$,z$); endfor - enddef; -vardef dotlabels@#(text t) = - forsuffixes $=t: - dotlabel@#(str$,z$); endfor - enddef; -vardef penlabels@#(text t) = - forsuffixes $$=l,,r: forsuffixes $=t: - makelabel@#(str$.$$,z$.$$); endfor endfor - enddef; - - -def range expr x = numtok[x] enddef; -def numtok suffix x=x enddef; -tertiarydef m thru n = - m for x=m+1 step 1 until n: , numtok[x] endfor enddef; - - - -%% Overall adminstration - -string extra_beginfig, extra_endfig; -extra_beginfig = extra_endfig = "" ; - -def beginfig(expr c) = - begingroup - charcode:=c; - clearxy; clearit; clearpen; - pickup defaultpen; - drawoptions(); - scantokens extra_beginfig; -enddef; - -def endfig = - ; % added by HH - scantokens extra_endfig; - shipit ; - endgroup -enddef; - - -%% last-minute items - -vardef z@#=(x@#,y@#) enddef; - -def clearxy = save x,y enddef; -def clearit = currentpicture:=nullpicture enddef; -def shipit = shipout currentpicture enddef; - -let bye = end; outer end,bye; - -clear_pen_memory; % initialize the `savepen' mechanism -clearit; - -newinternal defaultpen; -pickup pencircle scaled .5bp; % set default line width -defaultpen := savepen; diff --git a/metapost/context/base/mp-base.mpiv b/metapost/context/base/mp-base.mpiv deleted file mode 100644 index 28eb57fb8..000000000 --- a/metapost/context/base/mp-base.mpiv +++ /dev/null @@ -1,956 +0,0 @@ -% This is a reformatted copy of the plain.mp file. We use a copy -% because (1) we want to make sure that there are no unresolved -% dependencies, and (2) we may patch this file eventually. - -% This file gives the macros for plain MetaPost It contains all the -% features of plain METAFONT except those specific to font-making. -% There are also a number of macros for labeling figures, etc. - -% For practical reasons I have moved some new code here (and might -% remove some code as well). After all, there is no development in -% this format. - -string base_name, base_version ; - -base_name := "plain" ; -base_version := "1.004 for metafun iv" ; - -message "loading metafun, including plain.mp version " & base_version ; - -delimiters () ; % this makes parentheses behave like parentheses - -def upto = step 1 until enddef ; -def downto = step -1 until enddef ; - -def exitunless expr c = - exitif not c -enddef ; - -let relax = \ ; % ignore the word relax, as in TeX -let \\ = \ ; % double relaxation is like single - -def [[ = [ [ enddef ; -def ]] = ] ] enddef ; - -def -- = - {curl 1} .. {curl 1} -enddef ; - -def --- = - .. tension infinity .. -enddef ; - -def ... = - .. tension atleast 1 .. -enddef ; - -def gobble primary g = -enddef ; - -primarydef g gobbled gg = -enddef ; - -def hide(text t) = - exitif numeric begingroup t ; endgroup ; -enddef ; - -def ??? = - hide ( - interim showstopping := 1 ; - showdependencies - ) -enddef ; - -def stop expr s = - message s ; - gobble readstring -enddef ; - -warningcheck :=1 ; -tracinglostchars :=1 ; - -def interact = % sets up to make "show" commands stop - hide ( - showstopping := 1 ; - tracingonline := 1 ; - ) -enddef ; - -def loggingall = % puts tracing info into the log - tracingcommands := 3 ; - tracingtitles := 1 ; - tracingequations := 1 ; - tracingcapsules := 1 ; - tracingspecs := 2 ; - tracingchoices := 1 ; - tracinglostchars := 1 ; - tracingstats := 1 ; - tracingoutput := 1 ; - tracingmacros := 1 ; - tracingrestores := 1 ; -enddef ; - -def tracingall = % turns on every form of tracing - tracingonline := 1 ; - showstopping := 1 ; - loggingall ; -enddef ; - -def tracingnone = % turns off every form of tracing - tracingcommands := 0 ; - tracingtitles := 0 ; - tracingequations := 0 ; - tracingcapsules := 0 ; - tracingspecs := 0 ; - tracingchoices := 0 ; - tracinglostchars := 0 ; - tracingstats := 0 ; - tracingoutput := 0 ; - tracingmacros := 0 ; - tracingrestores := 0 ; -enddef ; - -%% dash patterns - -vardef dashpattern(text t) = - save on, off, w ; - let on = _on_ ; - let off = _off_ ; - w = 0 ; - nullpicture t -enddef ; - -tertiarydef p _on_ d = - begingroup save pic ; - picture pic; - pic = p ; - addto pic doublepath (w,w) .. (w+d,w) ; - w := w + d ; - pic shifted (0,d) - endgroup -enddef ; - -tertiarydef p _off_ d = - begingroup w := w + d ; - p shifted (0,d) - endgroup -enddef ; - -%% basic constants and mathematical macros - -% numeric constants - -newinternal eps, epsilon, infinity, _ ; - -eps := .00049 ; % this is a pretty small positive number -epsilon := 1/256/256 ; % but this is the smallest -infinity := 4095.99998 ; % and this is the largest -_ := -1 ; % internal constant to make macros unreadable but shorter - -% linejoin and linecap types - -newinternal mitered, rounded, beveled, butt, squared ; - -mitered := 0 ; rounded := 1 ; beveled := 2 ; -butt := 0 ; rounded := 1 ; squared := 2 ; - -% pair constants - -pair right, left, up, down, origin; - -origin = (0,0) ; -up = -down = (0,1) ; -right = -left = (1,0) ; - -% path constants - -path quartercircle, halfcircle, fullcircle, unitsquare ; - -fullcircle = makepath pencircle ; -halfcircle = subpath (0,4) of fullcircle ; -quartercircle = subpath (0,2) of fullcircle ; -unitsquare = (0,0) -- (1,0) -- (1,1) -- (0,1) -- cycle ; - -% transform constants - -transform identity ; - -for z=origin,right,up : - z transformed identity = z ; -endfor - -% color constants (all in rgb color space) - -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 ; % obsolete - -let graypart = greypart ; -let greycolor = numeric ; -let graycolor = numeric ; - -% color part (will be overloaded) - -def colorpart primary t = - if colormodel t=7: - (cyanpart t, magentapart t, yellowpart t, blackpart t) - elseif colormodel t = 5 : - (redpart t, greenpart t, bluepart t) - elseif colormodel t = 3 : - (greypart t) - elseif colormodel t = 1 : - false - elseif defaultcolormodel = 7 : - (0,0,0,1) - elseif defaultcolormodel = 5 : - black - elseif defaultcolormodel = 3 : - 0 - else : - false - fi -enddef ; - -% picture constants - -picture blankpicture, evenly, withdots ; - -blankpicture = nullpicture ; % display blankpicture... -evenly = dashpattern(on 3 off 3) ; % dashed evenly -withdots = dashpattern(off 2.5 on 0 off 2.5) ; % dashed withdots - -% string constants - -string ditto, EOF ; - -ditto = char 34 ; % ASCII double-quote mark -EOF = char 0 ; % end-of-file for readfrom and write..to - -% pen constants - -pen pensquare, penrazor, penspeck ; - -pensquare = makepen(unitsquare shifted -(.5,.5)) ; -penrazor = makepen((-.5,0) -- (.5,0) -- cycle) ; -penspeck = pensquare scaled eps ; - -% nullary operators - -vardef whatever = - save ? ; - ? -enddef ; - -% unary operators - -let abs = length ; - -vardef round primary u = - if numeric u : - floor(u+.5) - elseif pair u : - (round xpart u, round ypart u) - else : - u - fi -enddef ; - -vardef ceiling primary x = - -floor(-x) -enddef ; - -vardef byte primary s = - if string s : - ASCII - fi s -enddef ; - -vardef dir primary d = - right rotated d -enddef ; - -vardef unitvector primary z = - z/abs z -enddef ; - -vardef inverse primary T = - transform T_ ; - T_ transformed T = identity ; - T_ -enddef ; - -vardef counterclockwise primary c = - if turningnumber c <= 0 : - reverse - fi c -enddef ; - -vardef tensepath expr r = - for k=0 upto length r - 1 : - point k of r --- - endfor - if cycle r : - cycle - else : - point infinity of r - fi -enddef ; - -vardef center primary p = - .5[llcorner p, urcorner p] -enddef ; - -% binary operators - -primarydef x mod y = - (x-y*floor(x/y)) -enddef ; - -primarydef x div y = - floor(x/y) -enddef ; - -primarydef w dotprod z = - (xpart w * xpart z + ypart w * ypart z) -enddef ; - -primarydef x**y = - if y = 2 : - x*x - else : - takepower y of x - fi -enddef ; - -def takepower expr y of x = - if x>0 : - mexp(y*mlog x) - elseif (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 ; - -% 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 ; - -vardef directionpoint expr z of p = - a_ := directiontime z of p ; - if a_ < 0 : - errmessage("The direction doesn't occur") ; - fi - point a_ of p -enddef ; - -secondarydef p intersectionpoint q = - begingroup - save x_, y_ ; - (x_,y_) = p intersectiontimes q ; - if x_ < 0 : - errmessage("The paths don't intersect") ; - origin - else : - .5[point x_ of p, point y_ of q] - fi - endgroup -enddef ; - -tertiarydef p softjoin q = - begingroup - c_ := fullcircle scaled 2join_radius shifted point 0 of q ; - a_ := ypart(c_ intersectiontimes p) ; - b_ := ypart(c_ intersectiontimes q) ; - if a_ < 0 : - point 0 of p{direction 0 of p} - else : - subpath(0,a_) of p - fi - ... - if b_ < 0 : - {direction infinity of q} point infinity of q - else : - subpath(b_,infinity) of q - fi - endgroup -enddef ; - -newinternal join_radius, a_, b_ ; path c_ ; - -path cuttings ; % what got cut off - -tertiarydef a cutbefore b = % tries to cut as little as possible - begingroup - save t ; - (t, whatever) = a intersectiontimes b ; - if t < 0 : - cuttings := point 0 of a ; - a - else : - cuttings := subpath (0,t) of a ; - subpath (t,length a) of a - fi - endgroup -enddef ; - -tertiarydef a cutafter b = - reverse (reverse a cutbefore b) - hide(cuttings := reverse cuttings) -enddef ; - -% special operators - -vardef incr suffix $ = $:=$+1; $ enddef ; -vardef decr suffix $ = $:=$-1; $ enddef ; - -def reflectedabout(expr w,z) = % reflects about the line w..z - transformed - begingroup - transform T_ ; - w transformed T_ = w ; - z transformed T_ = z ; - xxpart T_ = -yypart T_ ; - xypart T_ = yxpart T_ ; % T_ is a reflection - T_ - endgroup -enddef ; - -def rotatedaround(expr z, d) = % rotates d degrees around z - shifted -z rotated d shifted z -enddef ; - -let rotatedabout = rotatedaround ; % for roundabout people - -vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings - save u_ ; - setu_ u ; - for uu = t : - if uu < u_ : - u_ := uu ; - fi - endfor - u_ -enddef ; - -vardef max(expr u)(text t) = % t is a list of numerics, pairs, or strings - save u_ ; - setu_ u ; - for uu = t : - if uu > u_ : - u_ := uu ; - fi - endfor - u_ -enddef ; - -def setu_ primary u = - if pair u : - pair u_ - elseif string u : - string u_ - fi ; - u_=u -enddef ; - -def flex(text t) = % t is a list of pairs - hide ( - n_ := 0 ; - for z=t : - z_[incr n_] := z ; - endfor - dz_ := z_[n_]-z_1 - ) - z_1 for k=2 upto n_-1 : - ... z_[k]{dz_} - endfor ... z_[n_] -enddef ; - -newinternal n_; pair z_[],dz_; - -def superellipse(expr r,t,l,b,s) = - r { up } ... (s[xpart t,xpart r],s[ypart r,ypart t]) { t-r } ... - t { left } ... (s[xpart t,xpart l],s[ypart l,ypart t]) { l-t } ... - l { down } ... (s[xpart b,xpart l],s[ypart l,ypart b]) { b-l } ... - b { right } ... (s[xpart b,xpart r],s[ypart r,ypart b]) { r-b } ... cycle enddef ; - -vardef interpath(expr a,p,q) = - for t=0 upto length p-1 : - a[point t of p, point t of q] .. controls a[postcontrol t of p, postcontrol t of q] and a[precontrol t+1 of p, precontrol t+1 of q] .. - endfor - if cycle p : - cycle - else : - a[point infinity of p, point infinity of q] - fi -enddef ; - -vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false - tx_:=true_x; fx_:=false_x; - forever : - x_ := .5[tx_,fx_] ; - exitif abs(tx_-fx_) <= tolerance ; - if @#(x_) : - tx_ - else : - fx_ - fi := x_ ; - endfor - x_ % now x_ is near where @# changes from true to false -enddef ; - -newinternal tolerance, tx_, fx_, x_ ; - -tolerance := .01 ; - -vardef buildcycle(text ll) = - save ta_, tb_, k_, i_, pp_ ; path pp_[] ; - k_ = 0 ; - for q=ll : - pp_[incr k_] = q ; - endfor - i_ = k_ ; - for i=1 upto k_ : - (ta_[i], length pp_[i_]-tb_[i_]) = pp_[i] intersectiontimes reverse pp_[i_] ; - if ta_[i]<0 : - errmessage("Paths "& decimal i &" and "& decimal i_ &" don't intersect") ; - fi - i_ := i; - endfor - for i=1 upto k_ : - subpath (ta_[i],tb_[i]) of pp_[i] .. - endfor - cycle -enddef ; - -%% units of measure - -mm := 2.83464 ; -pt := 0.99626 ; -dd := 1.06601 ; -bp := 1 ; -cm := 28.34645 ; -pc := 11.95517 ; -cc := 12.79213 ; -in := 72 ; - -vardef magstep primary m = % obsolete - mexp(46.67432m) -enddef ; - -%% macros for drawing and filling - -def drawoptions(text t) = - def _op_ = t enddef -enddef ; - -% parameters that effect drawing - -linejoin := rounded ; -linecap := rounded ; -miterlimit := 10 ; - -drawoptions() ; - -pen currentpen ; -picture currentpicture ; - -def fill expr c = - addto currentpicture contour c _op_ -enddef ; - -def draw expr p = - addto currentpicture - if picture p : - also p - else : - doublepath p withpen currentpen - fi - _op_ -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 ; -% -% 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 ; -def undraw expr p = draw p withcolor background enddef ; -def unfilldraw expr c = filldraw c withcolor background enddef ; -def undrawdot expr z = drawdot z withcolor background enddef ; - -def erase text t = - def _e_ = - withcolor background hide(def _e_ = enddef ;) - enddef ; - t _e_ -enddef ; - -def _e_ = enddef ; - -def cutdraw text t = - begingroup - interim linecap := butt ; - draw t _e_ ; - endgroup -enddef ; - -vardef image(text t) = - save currentpicture ; - picture currentpicture ; - currentpicture := nullpicture ; - t ; - currentpicture -enddef ; - -def pickup secondary q = - if numeric q : - numeric_pickup_ - else : - pen_pickup_ - fi q -enddef ; - -def numeric_pickup_ primary q = - if unknown pen_[q] : - errmessage "Unknown pen" ; - clearpen - else : - currentpen := pen_ [q] ; - pen_lft := pen_lft_[q] ; - pen_rt := pen_rt_ [q] ; - pen_top := pen_top_[q] ; - pen_bot := pen_bot_[q] ; - currentpen_path := pen_path_[q] - fi ; -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 ; - path currentpen_path ; -enddef ; - -newinternal pen_lft, pen_rt, pen_top, pen_bot, pen_count_ ; - -vardef savepen = - pen_[incr pen_count_] = currentpen ; - pen_lft_ [pen_count_] = pen_lft ; - pen_rt_ [pen_count_] = pen_rt ; - pen_top_ [pen_count_] = pen_top ; - pen_bot_ [pen_count_] = pen_bot ; - pen_path_[pen_count_] = currentpen_path ; - pen_count_ -enddef ; - -def clearpen = - currentpen := nullpen; - pen_lft := pen_rt := pen_top := pen_bot := 0 ; - path currentpen_path ; -enddef ; - -def clear_pen_memory = - pen_count_ := 0 ; - numeric pen_lft_[], pen_rt_[], pen_top_[], pen_bot_[] ; - pen currentpen, pen_[]; - path currentpen_path, pen_path_[] ; -enddef ; - -vardef lft primary x = x + if pair x: (pen_lft,0) else: pen_lft fi enddef ; -vardef rt primary x = x + if pair x: (pen_rt,0) else: pen_rt fi enddef ; -vardef top primary y = y + if pair y: (0,pen_top) else: pen_top fi enddef ; -vardef bot primary y = y + if pair y: (0,pen_bot) else: pen_bot fi enddef ; - -vardef penpos@#(expr b,d) = - (x@#r-x@#l,y@#r-y@#l) = (b,0) rotated d ; - x@# = .5(x@#l+x@#r) ; - y@# = .5(y@#l+y@#r) ; % ; added HH -enddef ; - -path path_.l, path_.r ; - -def penstroke text t = - forsuffixes e = l, r : - path_.e := t ; - endfor - fill path_.l -- reverse path_.r -- cycle -enddef ; - -%% High level drawing commands - -newinternal ahlength, ahangle ; - -ahlength := 4 ; % default arrowhead length 4bp -ahangle := 45 ; % default head angle 45 degrees - -vardef arrowhead expr p = - save q, e ; path q ; pair e ; - e = point length p of p ; - q = gobble(p shifted -e cutafter makepath(pencircle scaled 2ahlength)) cuttings ; - (q rotated .5ahangle & reverse q rotated -.5ahangle -- cycle) shifted e -enddef ; - -path _apth ; - -def drawarrow expr p = _apth := p ; _finarr enddef ; -def drawdblarrow expr p = _apth := p ; _findarr enddef ; - -def _finarr text t = - draw _apth t ; - filldraw arrowhead _apth t -enddef ; - -def _findarr text t = % this had fill in 0.63 (potential incompatibility) - draw _apth t ; - filldraw arrowhead _apth withpen currentpen t ; - filldraw arrowhead reverse _apth withpen currentpen t ; % ; added HH -enddef ; - -%% macros for labels - -newinternal bboxmargin ; - -bboxmargin := 2bp ; % this can bite you - -vardef bbox primary p = - llcorner p - ( bboxmargin, bboxmargin) -- - lrcorner p + ( bboxmargin,-bboxmargin) -- - urcorner p + ( bboxmargin, bboxmargin) -- - ulcorner p + (-bboxmargin, bboxmargin) -- cycle -enddef ; - -string defaultfont ; newinternal defaultscale, labeloffset ; - -defaultfont := "cmr10" ; -defaultscale := 1 ; -labeloffset := 3bp ; - -vardef thelabel@#(expr s,z) = % Position s near z - save p ; picture p ; - if picture s : - p = s - else : - p = s infont defaultfont scaled defaultscale - fi ; - p shifted (z + labeloffset*laboff@# - ( labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p) ) -enddef ; - -def label = - draw thelabel -enddef ; - -newinternal dotlabeldiam ; - -dotlabeldiam := 3bp ; - -vardef dotlabel@#(expr s,z) text t_ = - label@#(s,z) t_ ; - % label@#(s,z) ; - interim linecap := rounded ; - draw z withpen pencircle scaled dotlabeldiam t_ ; -enddef ; - -def makelabel = - dotlabel -enddef ; - -% this will be overloaded - -pair laboff, laboff.lft, laboff.rt, laboff.top, laboff.bot ; -pair laboff.ulft, laboff.llft, laboff.urt, laboff.lrt ; - -laboff = (0,0) ; labxf = .5 ; labyf = .5 ; -laboff.lft = (-1,0) ; labxf.lft = 1 ; labyf.lft = .5 ; -laboff.rt = (1,0) ; labxf.rt = 0 ; labyf.rt = .5 ; -laboff.bot = (0,-1) ; labxf.bot = .5 ; labyf.bot = 1 ; -laboff.top = (0,1) ; labxf.top = .5 ; labyf.top = 0 ; -laboff.ulft = (-.7,.7) ; labxf.ulft = 1 ; labyf.ulft = 0 ; -laboff.urt = (.7,.7) ; labxf.urt = 0 ; labyf.urt = 0 ; -laboff.llft = -(.7,.7) ; labxf.llft = 1 ; labyf.llft = 1 ; -laboff.lrt = (.7,-.7) ; labxf.lrt = 0 ; labyf.lrt = 1 ; - -vardef labels@#(text t) = - forsuffixes $=t : - label@#(str$,z$) ; - endfor -enddef ; - -% till lhere - -vardef dotlabels@#(text t) = - forsuffixes $=t: - dotlabel@#(str$,z$) ; - endfor -enddef ; - -vardef penlabels@#(text t) = - forsuffixes $$=l,,r : - forsuffixes $=t : - makelabel@#(str$.$$,z$.$$) ; - endfor - endfor -enddef ; - -% range 4 thru 10 - -def range expr x = - _numtok_[x] -enddef ; - -def _numtok_ suffix x = - x -enddef ; - -tertiarydef m thru n = - m for x=m+1 step 1 until n : - , _numtok_[x] - endfor -enddef ; - -%% Overall administration - -string extra_beginfig, extra_endfig ; - -extra_beginfig := "" ; -extra_endfig := "" ; - -def beginfig(expr c) = - begingroup - charcode := c ; - clearxy ; - clearit ; - clearpen ; - pickup defaultpen ; - drawoptions() ; - scantokens extra_beginfig ; -enddef ; - -def endfig = - ; % added by HH - scantokens extra_endfig ; - shipit ; - endgroup -enddef ; - -%% last-minute items - -vardef z@# = - (x@#,y@#) -enddef ; - -def clearxy = - save x, y -enddef ; - -def clearit = - currentpicture := nullpicture -enddef ; - -def shipit = - shipout currentpicture -enddef ; - -let bye = end ; -outer end, bye ; - -clear_pen_memory ; % initialize the savepen mechanism -clearit ; - -% set default line width - -newinternal defaultpen ; - -pickup pencircle scaled .5bp ; - -defaultpen := savepen ; diff --git a/metapost/context/base/mp-butt.mpii b/metapost/context/base/mp-butt.mpii deleted file mode 100644 index 107886bb5..000000000 --- a/metapost/context/base/mp-butt.mpii +++ /dev/null @@ -1,77 +0,0 @@ -%D \module -%D [ file=mp-butt.mpii, -%D version=2000.05.31, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=buttons, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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_butt : endinput ; fi ; - -boolean context_butt ; context_butt := true ; - -def predefinedbutton (expr button_type, button_size, button_linecolor, button_fillcolor) = - - begingroup ; - - save button_linewidth, p, d, l ; - - numeric button_linewidth ; button_linewidth := button_size/10 ; - - drawoptions (withpen pencircle scaled button_linewidth withcolor button_linecolor) ; - - path p ; p := unitsquare scaled button_size ; - numeric d ; d := button_size ; - numeric l ; l := button_linewidth ; - - fill p withcolor button_fillcolor ; - draw p ; - - if button_type = 101 : - draw (d-2l,2l)--(2l,.5d)--(d-2l,d-2l)--cycle ; - elseif button_type = 102 : - draw (2l,2l)--(d-2l,.5d)--(2l,d-2l)--cycle ; - elseif button_type = 103 : - for i=2l step 2l until d-2l : - draw (2l,i)--(2l ,i) ; - draw (4l,i)--(d-2l,i) ; - endfor ; - elseif button_type = 104 : - for i=2l step 2l until d-2l : - draw (2l ,i)--(d/2-l,i) ; - draw (d/2+l,i)--(d-2l ,i) ; - endfor ; - elseif button_type = 105 : - fill fullcircle scaled (.2d) shifted (.5d,.7d) ; - fill fullcircle xscaled (.6d) yscaled d shifted (.5d,0) ; - clip currentpicture to p ; - draw p ; - elseif button_type = 106 : - draw (2l,2l)--(d-2l,d-2l) ; - draw (d-2l,2l)--(2l,d-2l) ; - elseif button_type = 107 : - p := (3l,d-2l)--(d-3l,d-2l)--(.5d,4l)--cycle ; - fill p ; draw p ; - draw (.5d,2l) ; - elseif button_type = 108 : - draw (.5d,2l)--(d-2l,d-2l)--(2l,d-2l)--cycle ; - elseif button_type = 109 : - draw (.5d,d-2l)--(d-2l,2l)--(2l,2l)--cycle ; - elseif button_type = 110 : - button_linewidth := button_linewidth/2 ; - draw p enlarged (-2l,-l) ; - for i=2l step l until d-2l : - draw (3l,i)--(d-3l,i) ; - endfor ; - fi ; - - endgroup ; - -enddef ; - -let some_button = predefinedbutton diff --git a/metapost/context/base/mp-butt.mpiv b/metapost/context/base/mp-butt.mpiv deleted file mode 100644 index 6f5b90a7e..000000000 --- a/metapost/context/base/mp-butt.mpiv +++ /dev/null @@ -1,77 +0,0 @@ -%D \module -%D [ file=mp-butt.mpiv, -%D version=2000.05.31, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=buttons, -%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_butt : endinput ; fi ; - -boolean context_butt ; context_butt := true ; - -def predefinedbutton (expr button_type, button_size, button_linecolor, button_fillcolor) = - - begingroup ; - - save button_linewidth, p, d, l ; - - numeric button_linewidth ; button_linewidth := button_size/10 ; - - drawoptions (withpen pencircle scaled button_linewidth withcolor button_linecolor) ; - - path p ; p := unitsquare scaled button_size ; - numeric d ; d := button_size ; - numeric l ; l := button_linewidth ; - - fill p withcolor button_fillcolor ; - draw p ; - - if button_type = 101 : - draw (d-2l,2l)--(2l,.5d)--(d-2l,d-2l)--cycle ; - elseif button_type = 102 : - draw (2l,2l)--(d-2l,.5d)--(2l,d-2l)--cycle ; - elseif button_type = 103 : - for i=2l step 2l until d-2l : - draw (2l,i)--(2l ,i) ; - draw (4l,i)--(d-2l,i) ; - endfor ; - elseif button_type = 104 : - for i=2l step 2l until d-2l : - draw (2l ,i)--(d/2-l,i) ; - draw (d/2+l,i)--(d-2l ,i) ; - endfor ; - elseif button_type = 105 : - fill fullcircle scaled (.2d) shifted (.5d,.7d) ; - fill fullcircle xscaled (.6d) yscaled d shifted (.5d,0) ; - clip currentpicture to p ; - draw p ; - elseif button_type = 106 : - draw (2l,2l)--(d-2l,d-2l) ; - draw (d-2l,2l)--(2l,d-2l) ; - elseif button_type = 107 : - p := (3l,d-2l)--(d-3l,d-2l)--(.5d,4l)--cycle ; - fill p ; draw p ; - draw (.5d,2l) ; - elseif button_type = 108 : - draw (.5d,2l)--(d-2l,d-2l)--(2l,d-2l)--cycle ; - elseif button_type = 109 : - draw (.5d,d-2l)--(d-2l,2l)--(2l,2l)--cycle ; - elseif button_type = 110 : - button_linewidth := button_linewidth/2 ; - draw p enlarged (-2l,-l) ; - for i=2l step l until d-2l : - draw (3l,i)--(d-3l,i) ; - endfor ; - fi ; - - endgroup ; - -enddef ; - -let some_button = predefinedbutton diff --git a/metapost/context/base/mp-char.mpii b/metapost/context/base/mp-char.mpii deleted file mode 100644 index 63a71eff8..000000000 --- a/metapost/context/base/mp-char.mpii +++ /dev/null @@ -1,1006 +0,0 @@ -% to be cleaned up, namespace needed ! ! ! ! ! - -%D \module -%D [ file=mp-char.mpii, -%D version=1998.10.10, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=charts, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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 unknown context_shap : input "mp-shap.mpii" ; fi ; -if known context_flow : endinput ; fi ; - -boolean context_char ; context_char := true ; - -% kan naar elders - -current_position := 0 ; - -def save_text_position (expr p) = % beware: clip shift needed - current_position := current_position + 1 ; - savedata - "\MPposition{" & decimal current_position & "}{" - & decimal xpart p & "}{" - & decimal ypart p & "}%" ; -enddef ; - -%D settings - -grid_width := 60pt ; grid_height := 40pt ; -shape_width := 45pt ; shape_height := 30pt ; - -chart_offset := 2pt ; -color chart_background_color ; chart_background_color := white ; - -%D test mode - -boolean show_mid_points ; show_mid_points := false ; -boolean show_con_points ; show_con_points := false ; -boolean show_all_points ; show_all_points := false ; - -%D shapes - -color shape_line_color, shape_fill_color ; - -shape_line_width := 2pt ; -shape_line_color := .5white ; -shape_fill_color := .9white ; - -shape_node := 0 ; -shape_action := 24 ; -shape_procedure := 5 ; -shape_product := 12 ; -shape_decision := 14 ; -shape_archive := 19 ; -shape_loop := 35 ; -shape_wait := 6 ; -shape_subprocedure := 20 ; shape_sub_procedure := 20 ; -shape_singledocument := 32 ; shape_single_document := 32 ; -shape_multidocument := 33 ; shape_multi_document := 33 ; -shape_right := 66 ; -shape_left := 67 ; -shape_up := 68 ; -shape_down := 69 ; - -% vardef some_shape_path (expr type) == imported from mp-shap - -def show_shapes (expr n) = - - begin_chart(n,8,10) ; - show_con_points := true ; - for i=0 upto 7 : - for j=0 upto 9 : - new_shape(i+1,j+1,i*10+j); - endfor ; - endfor ; - end_chart ; - -enddef ; - -%D connections - -def new_chart = - - color connection_line_color ; - - connection_line_width := shape_line_width ; - connection_line_color := .8white ; - connection_smooth_size := 5pt ; - connection_arrow_size := 4pt ; - connection_dash_size := 3pt ; - - max_x := 6 ; - max_y := 4 ; - - numeric xypoint ; xypoint := 0 ; - - pair xypoints [] ; - - boolean xyfree [][] ; - path xypath [][] ; - numeric xysx [][] ; - numeric xysy [][] ; - color xyfill [][] ; - color xydraw [][] ; - numeric xyline [][] ; - boolean xypeep [][] ; - picture xypicture[][] ; - - numeric cpath ; cpath := 0 ; - path cpaths [] ; - numeric cline [] ; - color ccolor [] ; - boolean carrow [] ; - boolean cdash [] ; - boolean ccross [] ; - - boolean smooth ; smooth := true ; - boolean peepshape ; peepshape := false ; - boolean arrowtip ; arrowtip := true ; - boolean dashline ; dashline := false ; - boolean forcevalid ; forcevalid := false ; - boolean touchshape ; touchshape := false ; - boolean showcrossing ; showcrossing := false ; - - picture dash_pattern ; - - boolean reverse_y ; reverse_y := true ; - -enddef ; - -new_chart ; - -def y_pos (expr y) = - if reverse_y : max_y + 1 - y else : y fi -enddef ; - -def initialize_grid (expr maxx, maxy) = - begingroup ; - save i, j ; - max_x := maxx ; - max_y := maxy ; - dsp_x := 0 ; - dsp_y := 0 ; - for x=1 upto max_x : - for y=1 upto max_y : - xyfree [x][y] := true ; - xyfill [x][y] := shape_fill_color ; - xydraw [x][y] := shape_line_color ; - xyline [x][y] := shape_line_width ; - endfor ; - endfor ; - endgroup ; -enddef ; - -def scaled_to_grid = - xscaled grid_width yscaled grid_height -enddef ; - -def xy_offset (expr x, y) = - (x+.5,y+.5) -enddef ; - -def draw_shape (expr x, yy, p, sx, sy) = - begingroup ; - save y ; - y := y_pos(yy) ; - xypath [x][y] := (p xscaled sx yscaled sy) shifted xy_offset(x,y) ; - xyfree [x][y] := false ; - xysx [x][y] := sx ; - xysy [x][y] := sy ; - xyfill [x][y] := shape_fill_color ; - xydraw [x][y] := shape_line_color ; - xyline [x][y] := shape_line_width ; - xypeep [x][y] := peepshape ; - endgroup ; -enddef ; - -vardef i_point (expr x, y, p, t) = - begingroup ; - save q, ok ; - pair q ; - boolean ok ; - q := xypath[x][y] intersection_point ((p) shifted xy_offset(x,y)) ; - ok := true ; -% if xpart q < -.5 : ok := false ; q := (-.45,ypart q) fi ; -% if xpart q > .5 : ok := false ; q := ( .45,ypart q) fi ; -% if ypart q < -.5 : ok := false ; q := (xpart q,-.45) fi ; -% if ypart q > .5 : ok := false ; q := (xpart q, .45) fi ; - if not ok : - message (t & " of shape (" & decimal x & "," & decimal y & ") limited") ; - fi ; - q - endgroup -enddef ; - -vardef trimmed (expr x, y, z, t) = - if touchshape and t : xyline[x][y]/z else : epsilon fi -enddef ; - -zfactor := 1/3 ; - -vardef xy_bottom (expr x, y, z, t) = - i_point (x, y, ((0,0)--(0,-2)) shifted (zfactor*z*xysx[x][y],0), "bottom") - shifted(0,-trimmed(x,y,grid_height,t)) -enddef ; - -vardef xy_top (expr x, y, z, t) = - i_point (x, y, ((0,0)--(0,2)) shifted (zfactor*z*xysx[x][y],0), "top") - shifted(0,trimmed(x,y,grid_height,t)) -enddef ; - -vardef xy_left (expr x, y, z, t) = - i_point (x, y, ((0,0)--(-2,0)) shifted (0,zfactor*z*xysy[x][y]), "left") - shifted(-trimmed(x,y,grid_width,t),0) -enddef ; - -vardef xy_right (expr x, y, z, t) = - i_point (x, y, ((0,0)--(2,0)) shifted (0,zfactor*z*xysy[x][y]), "right") - shifted(trimmed(x,y,grid_width,t),0) -enddef ; - -def flush_shapes = - for x=1 upto max_x : - for y=1 upto max_y : - flush_shape (x, y) ; - endfor ; - endfor ; -enddef ; - -def flush_pictures = - for x=1 upto max_x : - for y=1 upto max_y : - flush_picture (x, y) ; - endfor ; - endfor ; -enddef ; - - -def draw_connection_point (expr x, y, z) = - pickup pencircle scaled if (z=0): 2 fi xyline[x][y] ; - drawdot xy_bottom(x,y,z,false) scaled_to_grid withcolor (1,0,0) ; - drawdot xy_top (x,y,z,false) scaled_to_grid withcolor (0,1,0) ; - drawdot xy_left (x,y,z,false) scaled_to_grid withcolor (0,0,1) ; - drawdot xy_right (x,y,z,false) scaled_to_grid withcolor (1,1,0) ; -enddef ; - -def flush_shape (expr x, yy) = - begingroup ; - save y ; - y := y_pos(yy) ; - if not xyfree[x][y] : - pickup pencircle scaled xyline[x][y] ; - if xypeep[x][y] : - fill (xypath[x][y] peepholed (unitsquare shifted (x,y))) - scaled_to_grid withpen pencircle scaled 0 - withcolor chart_background_color ; - else : - fill xypath[x][y] scaled_to_grid withcolor xyfill[x][y] ; - fi ; - draw xypath[x][y] scaled_to_grid withcolor xydraw[x][y] ; - if show_con_points or show_all_points : - draw_connection_point (x, y, 0) ; - fi ; - if show_all_points : - for i=-1 upto 1 : - draw_connection_point (x, y, i) ; - endfor ; - fi ; - fi ; - endgroup ; -enddef ; - -vardef points_initialized (expr xfrom, yfrom, xto, yto, n) = - if not xyfree[xfrom][yfrom] and not xyfree[xto][yto] : - xypoint := n ; true - else : - xypoint := 0 ; false - fi -enddef ; - -def collapse_points = - % remove redundant points - n := 1 ; - for i=2 upto xypoint: - if not (xypoints[i]=xypoints[n]) : - n := n + 1 ; - xypoints[n] := xypoints[i] - fi ; - endfor ; - xypoint := n ; - % make straight lines - if xypoints[2]=xypoints[xypoint-1] : - xypoints[3] := xypoints[xypoint] ; - xypoint := 3 ; - fi ; -enddef ; - -vardef smooth_connection (expr a,b) = - sx := connection_smooth_size/grid_width ; - sy := connection_smooth_size/grid_height ; - if ypart a = ypart b : - a shifted (if xpart a >= xpart b : - fi sx,0) -% a shifted (sx*xpart unitvector(b-a),0) - else : - a shifted (0,if ypart a >= ypart b : - fi sy) -% a shifted (0,sy*ypart unitvector(b-a)) - fi -enddef ; - -vardef trim_points = - begingroup - save p, a, b, d, i ; path p ; pair d ; - p := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; - if touchshape : - a := shape_line_width/grid_width ; - b := shape_line_width/grid_height ; - else : - a := epsilon ; - b := epsilon ; - fi ; - d := direction infinity of p ; - xypoints[xypoint] := xypoints[xypoint] shifted - if xpart d < 0 : (+a,0) ; - elseif xpart d > 0 : (-a,0) ; - elseif ypart d < 0 : (0,+b) ; - elseif ypart d > 0 : (0,-b) ; - else : origin ; - fi ; - d := direction 0 of p ; - xypoints[1] := xypoints[1] shifted - if xpart d < 0 : (-a,0) ; - elseif xpart d > 0 : (+a,0) ; - elseif ypart d < 0 : (0,-b) ; - elseif ypart d > 0 : (0,+b) ; - else : origin ; - fi ; - endgroup -enddef ; - -vardef trim_points = enddef ; - -vardef connection_path = - if reverse_connection : reverse fi (xypoints[1]-- - for i=2 upto xypoint-1 : - if smooth : - smooth_connection(xypoints[i],xypoints[i-1]) .. - controls xypoints[i] and xypoints[i] .. - smooth_connection(xypoints[i],xypoints[i+1]) -- - else : - xypoints[i]-- - fi - endfor - xypoints[xypoint]) -enddef ; - -% vardef connection_path = -% sx := connection_smooth_size/grid_width ; -% sy := connection_smooth_size/grid_height ; -% if reverse_connection : reverse fi -% (for i=1 upto xypoint-1 : xypoints[i] -- endfor xypoints[xypoint]) -% if smooth : cornered max(sx,sy) fi -% enddef ; -% -% primarydef p cornered c = -% if cycle p : -% ((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) -% else : -% ((point 0 of p) -- -% for i=1 upto length(p)-1 : -% (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 -% (point length(p) of p)) -% fi -% enddef ; - -def draw_connection = - if xypoint>0 : - collapse_points ; - trim_points ; - cpath := cpath + 1 ; - cpaths[cpath] := connection_path scaled_to_grid ; - cline[cpath] := connection_line_width ; - ccolor[cpath] := connection_line_color ; - carrow[cpath] := arrowtip ; - cdash[cpath] := dashline ; - ccross[cpath] := showcrossing ; - else : - message("no connection defined") ; - fi ; - reverse_connection := false ; -enddef ; - -def flush_connections = - pair ip ; - boolean crossing ; - ahlength := connection_arrow_size ; - dash_pattern := dashpattern(on connection_dash_size off connection_dash_size ) ; - for i=1 upto cpath : - if ccross[i] : - crossing := false ; - for j=1 upto i : - %if not ((point infinity of cpaths[i] = point infinity of cpaths[j]) or - % (point 0 of cpaths[i] = point 0 of cpaths[j])) : - if not (point infinity of cpaths[i] = point infinity of cpaths[j]) : - ip := cpaths[i] intersection_point cpaths[j] ; - if intersection_found : crossing := true fi ; - fi ; - endfor ; - if crossing : - pickup pencircle scaled 2cline[i] ; - %draw cpaths[i] withcolor chart_background_color ; - path cp ; cp := cpaths[i] ; - cp := cp cutbefore point .05 length cp of cp ; - cp := cp cutafter point .95 length cp of cp ; - draw cp withcolor chart_background_color ; - fi ; - fi ; - pickup pencircle scaled cline[i] ; - if carrow[i] : - if cdash[i] : - drawarrow cpaths[i] withcolor ccolor[i] dashed dash_pattern ; - else : - drawarrow cpaths[i] withcolor ccolor[i] ; - fi ; - else : - if cdash[i] : - draw cpaths[i] withcolor ccolor[i] dashed dash_pattern ; - else : - draw cpaths[i] withcolor ccolor[i] ; - fi ; - fi ; - draw_midpoint (i) ; - endfor ; -enddef ; - -def draw_midpoint (expr n) = - begingroup - save p ; - pair p ; - p := point .5*length(cpaths[n]) of cpaths[n]; - pickup pencircle scaled 2cline[n] ; - save_text_position (p) ; - if show_mid_points : - drawdot p withcolor .7white ; - fi ; - endgroup ; -enddef ; - -def flush_picture(expr x, y) = - if known xypicture[x][y]: - draw xypicture[x][y] shifted xy_offset((x+0.5)*grid_width,(max_y-y+1.5)*grid_height) ; - fi ; -enddef ; - -def chart_draw_picture(expr x, y, p) = - xypicture[x][y] := p ; -enddef ; - -boolean reverse_connection ; reverse_connection := false ; - -vardef up_on_grid (expr n) = - (xpart xypoints[n],(ypart xypoints[n]+1) div 1) -enddef ; - -vardef down_on_grid (expr n) = - (xpart xypoints[n],(ypart xypoints[n]) div 1) -enddef ; - -vardef left_on_grid (expr n) = - ((xpart xypoints[n]) div 1, ypart xypoints[n]) -enddef ; - -vardef right_on_grid (expr n) = - ((xpart xypoints[n]+1) div 1, ypart xypoints[n]) -enddef ; - -vardef x_on_grid (expr n, xfrom, xto, zfrom) = - if (xfrom=xto) and not (zfrom=0) : - if (zfrom=1) : right_on_grid(2) else : left_on_grid(2) fi - elseif xpart xypoints[1] < xpart xypoints[6] : - right_on_grid(n) - else : - left_on_grid(n) - fi -enddef ; - -vardef y_on_grid (expr n, yfrom, yto, zfrom) = - if (yfrom=yto) and not (zfrom=0) : - if (zfrom=1) : up_on_grid(2) else : down_on_grid(2) fi - elseif ypart xypoints[1] < ypart xypoints[6] : - up_on_grid(n) - else : - down_on_grid(n) - fi -enddef ; - -vardef xy_on_grid (expr n, m) = - (xpart xypoints[n], ypart xypoints[m]) -enddef ; - -vardef down_to_grid (expr a,b) = - (xpart xypoints[a], - ypart xypoints[if ypart xypoints[a]ypart xypoints[b]:a else:b fi]) -enddef ; - -vardef left_to_grid (expr a,b) = - (xpart xypoints[if xpart xypoints[a]xpart xypoints[b]:a else:b fi], - ypart xypoints[a]) -enddef ; - -% vardef boundingboxfraction(expr p, f) = -% ((boundingbox p) enlarged (-f*bbwidth(p),-f*bbheight(p))) -% enddef ; - -vardef valid_connection (expr xfrom, yfrom, xto, yto) = - begingroup ; - save ok, vc, pp ; - boolean ok ; - % check for slanted lines - ok := true ; - for i=1 upto xypoint-1 : - if not ((xpart xypoints[i]=xpart xypoints[i+1]) or - (ypart xypoints[i]=ypart xypoints[i+1])) : ok := false ; - fi ; - endfor ; - if not ok : - %message("slanted"); - false - elseif forcevalid : - %message("force"); - true - elseif (xfrom=xto) and (yfrom=yto) : - %message("self"); - false - else : - % check for crossing shapes - pair vc ; - path pp ; - - pair xyfirst, xylast ; - xyfirst := xypoints[1] ; - xylast := xypoints[xypoint] ; - trim_points ; - pp := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; - xypoints[1] := xyfirst ; - xypoints[xypoint] := xylast ; - - for i=1 upto max_x : - for j=1 upto max_y : % was bug: xfrom,yto - if not ( ( (i,j)=(xfrom,yfrom) ) or ( (i,j)=(xto,yto) ) ) : - if not xyfree[i][j] : - vc := pp intersection_point xypath[i][j] ; - if intersection_found : ok := false fi ; - fi ; - fi ; - endfor ; - endfor ; - %if not ok: message("crossing") ; fi ; - ok - fi - endgroup -enddef ; - -def connect_top_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,6) : - xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; - xypoints[6] := xy_bottom(xto,yto,zto,true) ; - xypoints[2] := up_on_grid(1) ; - xypoints[5] := down_on_grid(6) ; - xypoints[3] := up_to_grid(2,5) ; - xypoints[4] := up_to_grid(2,5) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; - xypoints[4] := xy_on_grid(3,5) ; - fi ; - %%%% begin experiment - xypoints[3] := xypoints[3] shifted (dsp_x,0) ; - xypoints[4] := xypoints[4] shifted (dsp_x,0) ; - if dsp_y>0 : - xypoints[2] := xypoints[2] shifted (0,dsp_y) ; - xypoints[3] := xypoints[3] shifted (0,dsp_y) ; - elseif dsp_y<0 : - xypoints[4] := xypoints[4] shifted (0,dsp_y) ; - xypoints[5] := xypoints[5] shifted (0,dsp_y) ; - fi - %%%% end experiment - draw_connection ; - fi ; -enddef ; - -def connect_left_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,6) : - xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; - xypoints[6] := xy_right(xto,yto,zto,true) ; - xypoints[2] := left_on_grid(1) ; - xypoints[5] := right_on_grid(6) ; - xypoints[3] := left_to_grid(2,5) ; - xypoints[4] := left_to_grid(2,5) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; - xypoints[4] := xy_on_grid(5,3) ; - fi ; - draw_connection ; - fi ; -enddef ; - -def connect_left_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,5) : - xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; - xypoints[5] := xy_top(xto,yto,zto,true) ; - xypoints[2] := left_on_grid(1) ; - xypoints[4] := up_on_grid(5) ; - xypoints[3] := left_to_grid(2,5) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := xy_on_grid(2,4) ; - fi ; - draw_connection ; - fi ; -enddef ; - -def connect_left_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,5) : - xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; - xypoints[5] := xy_bottom(xto,yto,zto,true) ; - xypoints[2] := left_on_grid(1) ; - xypoints[4] := down_on_grid(5) ; - xypoints[3] := left_to_grid(2,5) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := xy_on_grid(2,4) ; - fi ; - draw_connection ; - fi ; -enddef ; - -def connect_right_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,5) : - xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; - xypoints[5] := xy_top(xto,yto,zto,true) ; - xypoints[2] := right_on_grid(1) ; - xypoints[4] := up_on_grid(5) ; - xypoints[3] := right_to_grid(2,5) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := xy_on_grid(2,4) ; - fi ; - draw_connection ; - fi ; -enddef ; - -def connect_right_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,5) : - xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; - xypoints[5] := xy_bottom(xto,yto,zto,true) ; - xypoints[2] := right_on_grid(1) ; - xypoints[4] := down_on_grid(5) ; - xypoints[3] := right_to_grid(2,5) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := xy_on_grid(2,4) ; - fi ; - %%%% begin experiment - xypoints[2] := xypoints[2] shifted (dsp_x,0) ; - xypoints[3] := xypoints[3] shifted (dsp_x,0) ; - if dsp_y>0 : - xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; - xypoints[4] := xypoints[4] shifted (0,-dsp_y) ; - elseif dsp_y<0 : - xypoints[3] := xypoints[3] shifted (0,dsp_y) ; - xypoints[4] := xypoints[4] shifted (0,dsp_y) ; - fi - %%%% end experiment - draw_connection ; - fi ; -enddef ; - -def connect_left_left (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,6) : - xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; - xypoints[6] := xy_left(xto,yto,zto,true) ; - xypoints[2] := left_on_grid(1) ; - xypoints[5] := left_on_grid(6) ; - xypoints[3] := left_to_grid(2,5) ; - xypoints[4] := left_to_grid(5,2) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; - xypoints[4] := xy_on_grid(5,3) ; - fi ; - draw_connection ; - fi ; -enddef ; - -def connect_right_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,6) : - xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; - xypoints[6] := xy_right(xto,yto,zto,true) ; - xypoints[2] := right_on_grid(1) ; - xypoints[5] := right_on_grid(6) ; - xypoints[3] := right_to_grid(2,5) ; - xypoints[4] := right_to_grid(5,2) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; - xypoints[4] := xy_on_grid(5,3) ; - fi ; - draw_connection ; - fi ; -enddef ; - -def connect_top_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,6) : - xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; - xypoints[6] := xy_top(xto,yto,zto,true) ; - xypoints[2] := up_on_grid(1) ; - xypoints[5] := up_on_grid(6) ; - xypoints[3] := up_to_grid(2,5) ; - xypoints[4] := up_to_grid(5,2) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; - xypoints[4] := xy_on_grid(3,5) ; - fi ; - draw_connection ; - fi ; -enddef ; - -def connect_bottom_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; - if points_initialized(xfrom,yfrom,xto,yto,6) : - xypoints[1] := xy_bottom(xfrom,yfrom,zfrom,true) ; - xypoints[6] := xy_bottom(xto,yto,zto,true) ; - xypoints[2] := down_on_grid(1) ; - xypoints[5] := down_on_grid(6) ; - xypoints[3] := down_to_grid(2,5) ; - xypoints[4] := down_to_grid(5,2) ; - if not valid_connection(xfrom,yfrom,xto,yto) : - xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; - xypoints[4] := xy_on_grid(3,5) ; - fi ; - %%%% begin experiment - xypoints[3] := xypoints[3] shifted (dsp_x,0) ; - xypoints[4] := xypoints[4] shifted (dsp_x,0) ; - if dsp_y<0 : - xypoints[2] := xypoints[2] shifted (0,-dsp_y) ; - xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; - elseif dsp_y>0 : - xypoints[4] := xypoints[4] shifted (0,dsp_y) ; - xypoints[5] := xypoints[5] shifted (0,dsp_y) ; - fi - %%%% end experiment - draw_connection ; - fi ; -enddef ; - -def connect_bottom_top (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - reverse_connection := true ; - connect_top_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def connect_right_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - reverse_connection := true ; - connect_left_right (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def connect_top_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - reverse_connection := true ; - connect_left_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def connect_bottom_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - reverse_connection := true ; - connect_left_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def connect_top_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - reverse_connection := true ; - connect_right_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def connect_bottom_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - reverse_connection := true ; - connect_right_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def draw_test_shape (expr x, y) = - draw_shape(x,y,fullcircle, .7, .7) ; -enddef ; - -def draw_test_shapes = - for i=1 upto max_x : - for j=1 upto max_y : - draw_test_shape(i,j) ; - endfor ; - endfor ; -enddef; - -def draw_test_area = - pickup pencircle scaled .5shape_line_width ; - draw (unitsquare xscaled max_x yscaled max_y shifted (1,1)) - scaled_to_grid withcolor blue ; -enddef ; - -def show_connection (expr n, m) = - - begin_chart(100+n,6,6) ; - - draw_test_area ; - - smooth := true ; - arrowtip := true ; - dashline := true ; - - draw_test_shape(2,2) ; draw_test_shape(4,5) ; - draw_test_shape(3,3) ; draw_test_shape(5,1) ; - draw_test_shape(2,5) ; draw_test_shape(1,3) ; - draw_test_shape(6,2) ; draw_test_shape(4,6) ; - - if (m=1) : - connect_top_bottom (2,2,0) (4,5,0) ; - connect_top_bottom (3,3,0) (5,1,0) ; - connect_top_bottom (2,5,0) (1,3,0) ; - connect_top_bottom (6,2,0) (4,6,0) ; - elseif (m=2) : - connect_top_top (2,2,0) (4,5,0) ; - connect_top_top (3,3,0) (5,1,0) ; - connect_top_top (2,5,0) (1,3,0) ; - connect_top_top (6,2,0) (4,6,0) ; - elseif (m=3) : - connect_bottom_bottom (2,2,0) (4,5,0) ; - connect_bottom_bottom (3,3,0) (5,1,0) ; - connect_bottom_bottom (2,5,0) (1,3,0) ; - connect_bottom_bottom (6,2,0) (4,6,0) ; - elseif (m=4) : - connect_left_right (2,2,0) (4,5,0) ; - connect_left_right (3,3,0) (5,1,0) ; - connect_left_right (2,5,0) (1,3,0) ; - connect_left_right (6,2,0) (4,6,0) ; - elseif (m=5) : - connect_left_left (2,2,0) (4,5,0) ; - connect_left_left (3,3,0) (5,1,0) ; - connect_left_left (2,5,0) (1,3,0) ; - connect_left_left (6,2,0) (4,6,0) ; - elseif (m=6) : - connect_right_right (2,2,0) (4,5,0) ; - connect_right_right (3,3,0) (5,1,0) ; - connect_right_right (2,5,0) (1,3,0) ; - connect_right_right (6,2,0) (4,6,0) ; - elseif (m=7) : - connect_left_top (2,2,0) (4,5,0) ; - connect_left_top (3,3,0) (5,1,0) ; - connect_left_top (2,5,0) (1,3,0) ; - connect_left_top (6,2,0) (4,6,0) ; - elseif (m=8) : - connect_left_bottom (2,2,0) (4,5,0) ; - connect_left_bottom (3,3,0) (5,1,0) ; - connect_left_bottom (2,5,0) (1,3,0) ; - connect_left_bottom (6,2,0) (4,6,0) ; - elseif (m=9) : - connect_right_top (2,2,0) (4,5,0) ; - connect_right_top (3,3,0) (5,1,0) ; - connect_right_top (2,5,0) (1,3,0) ; - connect_right_top (6,2,0) (4,6,0) ; - else : - connect_right_bottom (2,2,0) (4,5,0) ; - connect_right_bottom (3,3,0) (5,1,0) ; - connect_right_bottom (2,5,0) (1,3,0) ; - connect_right_bottom (6,2,0) (4,6,0) ; - fi ; - - end_chart ; - -enddef ; - -def show_connections = - for f=1 upto 10 : - show_connection(f,f) ; - endfor ; -enddef ; - -%D charts - -def clip_chart (expr minx, miny, maxx, maxy) = - cmin_x := minx ; - cmax_x := maxx ; - cmin_y := miny ; - cmax_y := maxy ; -enddef ; - -def begin_chart (expr n, maxx, maxy) = - new_chart ; - chart_figure := n ; - chart_scale := 1 ; - if chart_figure>0: beginfig(chart_figure) ; fi ; - startsavingdata ; - initialize_grid (maxx, maxy) ; - bboxmargin := 0 ; - cmin_x := 1 ; - cmax_x := maxx ; - cmin_y := 1 ; - cmax_y := maxy ; -enddef ; - -def end_chart = - flush_shapes ; - flush_connections ; - flush_pictures ; - cmin_x := cmin_x ; - cmax_x := cmin_x+cmax_x ; - cmin_y := cmin_y-1 ; - cmax_y := cmin_y+cmax_y ; - if reverse_y : - cmin_y := y_pos(cmin_y) ; - cmax_y := y_pos(cmax_y) ; - fi ; - path p ; - p := (((cmin_x,cmin_y)--(cmax_x,cmin_y)-- - (cmax_x,cmax_y)--(cmin_x,cmax_y)--cycle)) - scaled_to_grid ; - %draw p withcolor red ; - p := p enlarged chart_offset ; - clip currentpicture to p ; - setbounds currentpicture to p ; - savedata - "\MPclippath{" & - decimal xpart llcorner p & "}{" & - decimal ypart llcorner p & "}{" & - decimal xpart urcorner p & "}{" & - decimal ypart urcorner p & "}%" ; - savedata - "\MPareapath{" & - decimal (xpart llcorner p + 2chart_offset) & "}{" & - decimal (ypart llcorner p + 2chart_offset) & "}{" & - decimal (xpart urcorner p - 2chart_offset) & "}{" & - decimal (ypart urcorner p - 2chart_offset) & "}%" ; - currentpicture := currentpicture scaled chart_scale ; - stopsavingdata ; - if chart_figure>0: endfig ; fi ; -enddef ; - -def new_shape (expr x, y, n) = - if known n : - if (x>0) and (x<=max_x) and (y>0) and (y<=max_y) : - sx := shape_width/grid_width ; - sy := shape_height/grid_height ; - draw_shape(x,y,some_shape_path(n), sx, sy) ; - else : - message ("shape outside grid ignored") ; - fi ; - else - message ("shape not known" ) ; - fi ; -enddef ; - -def begin_sub_chart = - begingroup ; - save shape_line_width , connection_line_width ; - save shape_line_color, shape_fill_color, connection_line_color ; - color shape_line_color, shape_fill_color, connection_line_color ; - save smooth, arrowtip, dashline, peepshape ; - boolean smooth, arrowtip, dashline, peepshape ; -enddef ; - -def end_sub_chart = - endgroup ; -enddef ; - -% show_shapes(100) ; -% -% show_connections ; -% -% begin_chart (1,4,5) ; -% %clip_chart(1,1,1,2) ; -% new_shape (1,1,31) ; -% new_shape (1,2,3) ; -% new_shape (4,4,5) ; -% connect_top_left (1,1,0) (4,4,0) ; -% connect_bottom_top (1,2,0) (4,4,0) ; -% connect_left_right (1,2,0) (1,1,0) ; -% end_chart ; diff --git a/metapost/context/base/mp-char.mpiv b/metapost/context/base/mp-char.mpiv deleted file mode 100644 index f604accd8..000000000 --- a/metapost/context/base/mp-char.mpiv +++ /dev/null @@ -1,1116 +0,0 @@ -%D \module -%D [ file=mp-char.mpiv, -%D version=2011.10.1, % 1998.10.10, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=charts, -%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. - -%D This is ancient code .. but I see no need to rewrite it. This is -%D already a partial rewrite but more could be delegated to \LUA\ -%D when used in \CONTEXT\ but it does not pay off now to look into -%D that. - -%D For historic reason we first build and then flush but we could -%D as well flush directly which would save us caching. - -if unknown context_shap : input "mp-shap.mpiv" ; fi ; -if known context_flow : endinput ; fi ; - -boolean context_flow ; context_flow := true ; - -%D settings - -numeric flow_grid_width ; flow_grid_width := 60pt ; -numeric flow_shape_width ; flow_shape_width := 45pt ; -numeric flow_grid_height ; flow_grid_height := 40pt ; -numeric flow_shape_height ; flow_shape_height := 30pt ; -numeric flow_chart_offset ; flow_chart_offset := 2pt ; -color flow_chart_background_color ; flow_chart_background_color := white ; -boolean flow_show_mid_points ; flow_show_mid_points := false ; -boolean flow_show_con_points ; flow_show_con_points := false ; -boolean flow_show_all_points ; flow_show_all_points := false ; -numeric flow_shape_line_width ; flow_shape_line_width := 2pt ; -color flow_shape_line_color ; flow_shape_line_color := .5white ; -color flow_shape_fill_color ; flow_shape_fill_color := .9white ; -color flow_connection_line_color ; flow_connection_line_color := .2white ; - -numeric flow_connection_line_width ; flow_connection_line_width := flow_shape_line_width ; - -numeric flow_connection_smooth_size ; flow_connection_smooth_size := 5pt ; -numeric flow_connection_arrow_size ; flow_connection_arrow_size := 4pt ; -numeric flow_connection_dash_size ; flow_connection_dash_size := 3pt ; - -numeric flow_max_x ; flow_max_x := 6 ; -numeric flow_max_y ; flow_max_y := 4 ; - -boolean flow_smooth ; flow_smooth := true ; -boolean flow_peepshape ; flow_peepshape := false ; -boolean flow_arrowtip ; flow_arrowtip := true ; -boolean flow_dashline ; flow_dashline := false ; -boolean flow_forcevalid ; flow_forcevalid := false ; -boolean flow_touchshape ; flow_touchshape := false ; -boolean flow_showcrossing ; flow_showcrossing := false ; -boolean flow_reverse_y ; flow_reverse_y := true ; - -picture flow_dash_pattern ; flow_dash_pattern := nullpicture ; - -numeric flow_shape_node ; flow_shape_node := 0 ; -numeric flow_shape_action ; flow_shape_action := 24 ; -numeric flow_shape_procedure ; flow_shape_procedure := 5 ; -numeric flow_shape_product ; flow_shape_product := 12 ; -numeric flow_shape_decision ; flow_shape_decision := 14 ; -numeric flow_shape_archive ; flow_shape_archive := 19 ; -numeric flow_shape_loop ; flow_shape_loop := 35 ; -numeric flow_shape_wait ; flow_shape_wait := 6 ; -numeric flow_shape_subprocedure ; flow_shape_subprocedure := 20 ; -numeric flow_shape_singledocument ; flow_shape_singledocument := 32 ; -numeric flow_shape_multidocument ; flow_shape_multidocument := 33 ; -numeric flow_shape_right ; flow_shape_right := 66 ; -numeric flow_shape_left ; flow_shape_left := 67 ; -numeric flow_shape_up ; flow_shape_up := 68 ; -numeric flow_shape_down ; flow_shape_down := 69 ; - -numeric flow_label_offset ; flow_label_offset := 0 ; -numeric flow_exit_offset ; flow_exit_offset := 0 ; -numeric flow_comment_offset ; flow_comment_offset := 0 ; - -% vardef some_shape_path (expr type) == imported from mp-shap - -def flow_show_shapes(expr n) = - flow_begin_chart(n,8,10) ; - flow_show_con_points := true ; - for i=0 upto 7 : - for j=0 upto 9 : - flow_new_shape(i+1,j+1,i*10+j); - endfor ; - endfor ; - flow_end_chart ; -enddef ; - -%D connections - -def flow_new_chart = - - flow_grid_width := 60pt ; - flow_shape_width := 45pt ; - flow_grid_height := 40pt ; - flow_shape_height := 30pt ; - flow_chart_offset := 2pt ; - flow_chart_background_color := white ; - flow_show_mid_points := false ; - flow_show_con_points := false ; - flow_show_all_points := false ; - flow_shape_line_width := 2pt ; - flow_shape_line_color := .5white ; - flow_shape_fill_color := .9white ; - flow_connection_line_color := .2white ; - flow_connection_line_width := flow_shape_line_width ; - flow_connection_smooth_size := 5pt ; - flow_connection_arrow_size := 4pt ; - flow_connection_dash_size := 3pt ; - flow_label_offset := 0 ; - flow_exit_offset := 0 ; - flow_comment_offset := 0 ; - - flow_max_x := 6 ; - flow_max_y := 4 ; - - flow_smooth := true ; - flow_peepshape := false ; - flow_arrowtip := true ; - flow_dashline := false ; - flow_forcevalid := false ; - flow_touchshape := false ; - flow_showcrossing := false ; - flow_reverse_y := true ; - - flow_dash_pattern := nullpicture ; - - numeric flow_xypoint ; flow_xypoint := 0 ; - numeric flow_cpath ; flow_cpath := 0 ; - - pair flow_xypoints [] ; - boolean flow_xyfree [][] ; - path flow_xypath [][] ; - numeric flow_xysx [][] ; - numeric flow_xysy [][] ; - color flow_xyfill [][] ; - color flow_xydraw [][] ; - numeric flow_xyline [][] ; - boolean flow_xypeep [][] ; - picture flow_xytext [][] ; - picture flow_xylabel [][] ; - picture flow_xyexit [][] ; - picture flow_xycomment [][] ; - path flow_cpaths [] ; - numeric flow_cline [] ; - color flow_ccolor [] ; - boolean flow_carrow [] ; - boolean flow_cdash [] ; - boolean flow_ccross [] ; - picture flow_tpicture [][] ; - picture flow_bpicture [][] ; - picture flow_lpicture [][] ; - picture flow_rpicture [][] ; - path flow_connections[][][] ; - - predefined_shapes[61] := (fullcircle scaled (1.5*predefined_shapes_yradius) xscaled (flow_grid_height/flow_grid_width)) ; - predefined_shapes[62] := (fullcircle scaled (2.0*predefined_shapes_yradius) xscaled (flow_grid_height/flow_grid_width)) ; - -enddef ; - -flow_new_chart ; - -def flow_y_pos(expr y) = -% if flow_reverse_y : - flow_max_y + 1 - y -% else : -% y -% fi -enddef ; - -def flow_initialize_grid(expr maxx, maxy) = - flow_max_x := maxx ; - flow_max_y := maxy ; - flow_dsp_x := 0 ; - flow_dsp_y := 0 ; - for x=1 upto flow_max_x : - for y=1 upto flow_max_y : - flow_xyfree[x][y] := true ; - flow_xyfill[x][y] := flow_shape_fill_color ; - flow_xydraw[x][y] := flow_shape_line_color ; - flow_xyline[x][y] := flow_shape_line_width ; - endfor ; - endfor ; -enddef ; - -def flow_scaled_to_grid = - xscaled flow_grid_width yscaled flow_grid_height -enddef ; - -def flow_xy_offset(expr x, y) = - (x+.5,y+.5) -enddef ; - -def flow_draw_shape(expr x, yy, p, sx, sy) = - begingroup ; - save y ; numeric y ; - y := flow_y_pos(yy) ; - flow_xypath [x][y] := (p xscaled sx yscaled sy) shifted flow_xy_offset(x,y) ; - flow_xyfree [x][y] := false ; - flow_xysx [x][y] := sx ; - flow_xysy [x][y] := sy ; - flow_xyfill [x][y] := flow_shape_fill_color ; - flow_xydraw [x][y] := flow_shape_line_color ; - flow_xyline [x][y] := flow_shape_line_width ; - flow_xypeep [x][y] := flow_peepshape ; - endgroup ; -enddef ; - -vardef flow_i_point (expr x, y, p, t) = - begingroup ; - save q, ok ; pair q ; boolean ok ; - q := flow_xypath[x][y] intersection_point ((p) shifted flow_xy_offset(x,y)) ; - ok := true ; - if not ok : - message (t & " of shape (" & decimal x & "," & decimal y & ") limited") ; - fi ; - q - endgroup -enddef ; - -vardef flow_trimmed (expr x, y, z, t) = - if flow_touchshape and t : - flow_xyline[x][y]/z - else : - epsilon - fi -enddef ; - -numeric flow_zfactor ; flow_zfactor := 1/3 ; - -vardef flow_xy_bottom (expr x, y, z, t) = - flow_i_point(x, y, ((0,0)--(0,-2)) shifted (flow_zfactor*z*flow_xysx[x][y],0), "bottom") - shifted(0,-flow_trimmed(x,y,flow_grid_height,t)) -enddef ; - -vardef flow_xy_top (expr x, y, z, t) = - flow_i_point (x, y, ((0,0)--(0,2)) shifted (flow_zfactor*z*flow_xysx[x][y],0), "top") - shifted(0,flow_trimmed(x,y,flow_grid_height,t)) -enddef ; - -vardef flow_xy_left (expr x, y, z, t) = - flow_i_point (x, y, ((0,0)--(-2,0)) shifted (0,flow_zfactor*z*flow_xysy[x][y]), "left") - shifted(-flow_trimmed(x,y,flow_grid_width,t),0) -enddef ; - -vardef flow_xy_right (expr x, y, z, t) = - flow_i_point (x, y, ((0,0)--(2,0)) shifted (0,flow_zfactor*z*flow_xysy[x][y]), "right") - shifted(flow_trimmed(x,y,flow_grid_width,t),0) -enddef ; - -def flow_flush_shapes = - for x=1 upto flow_max_x : - for y=1 upto flow_max_y : - flow_flush_shape(x, y) ; - endfor ; - endfor ; -enddef ; - -def flow_flush_pictures = - for x=1 upto flow_max_x : - for y=1 upto flow_max_y : - flow_flush_picture(x, y) ; - endfor ; - endfor ; -enddef ; - -def flow_draw_connection_point(expr x, y, z) = - pickup pencircle scaled if (z=0): 2 fi flow_xyline[x][y] ; - drawdot flow_xy_bottom(x,y,z,false) flow_scaled_to_grid withcolor (1,0,0) ; - drawdot flow_xy_top (x,y,z,false) flow_scaled_to_grid withcolor (0,1,0) ; - drawdot flow_xy_left (x,y,z,false) flow_scaled_to_grid withcolor (0,0,1) ; - drawdot flow_xy_right (x,y,z,false) flow_scaled_to_grid withcolor (1,1,0) ; -enddef ; - -def flow_flush_shape(expr x, yy) = - begingroup ; - save y ; numeric y ; - y := flow_y_pos(yy) ; - if not flow_xyfree[x][y] : - pickup pencircle scaled flow_xyline[x][y] ; - if flow_xypeep[x][y] : - fill (flow_xypath[x][y] peepholed (unitsquare shifted (x,y))) - flow_scaled_to_grid withpen pencircle scaled 0 - withcolor flow_chart_background_color ; - else : - fill flow_xypath[x][y] flow_scaled_to_grid withcolor flow_xyfill[x][y] ; - fi ; - draw flow_xypath[x][y] flow_scaled_to_grid withcolor flow_xydraw[x][y] ; - if flow_show_con_points or flow_show_all_points : - flow_draw_connection_point(x, y, 0) ; - fi ; - if flow_show_all_points : - for i=-1 upto 1 : - flow_draw_connection_point(x, y, i) ; - endfor ; - fi ; - fi ; - endgroup ; -enddef ; - -vardef flow_points_initialized(expr xfrom, yfrom, xto, yto, n) = - if unknown flow_xyfree[xfrom][yfrom] or unknown flow_xyfree[xto][yto] : - flow_xypoint := 0 ; false - elseif not flow_xyfree[xfrom][yfrom] and not flow_xyfree[xto][yto] : - flow_xypoint := n ; true - else : - flow_xypoint := 0 ; false - fi -enddef ; - -def flow_collapse_points = % this can become a core macro - begingroup ; - % remove redundant points - save n ; numeric n ; - n := 1 ; - for i=2 upto flow_xypoint : - if not (flow_xypoints[i] = flow_xypoints[n]) : - n := n + 1 ; - flow_xypoints[n] := flow_xypoints[i] - fi ; - endfor ; - flow_xypoint := n ; - % make straight lines - if flow_xypoints[2] = flow_xypoints[flow_xypoint-1] : - flow_xypoints[3] := flow_xypoints[flow_xypoint] ; - flow_xypoint := 3 ; - fi ; - endgroup ; -enddef ; - -vardef flow_smooth_connection(expr a,b) = - if ypart a = ypart b : - a shifted ( if xpart a >= xpart b : - fi (flow_connection_smooth_size/flow_grid_width ),0) - else : - a shifted (0,if ypart a >= ypart b : - fi (flow_connection_smooth_size/flow_grid_height) ) - fi -enddef ; - -vardef flow_trim_points = - begingroup - save p, a, b, d, i ; numeric a, b ; path p ; pair d ; - p := for i=1 upto flow_xypoint-1 : flow_xypoints[i]-- endfor flow_xypoints[flow_xypoint] ; - if flow_touchshape : - a := flow_shape_line_width/flow_grid_width ; - b := flow_shape_line_width/flow_grid_height ; - else : - a := epsilon ; - b := epsilon ; - fi ; - d := direction infinity of p ; - flow_xypoints[flow_xypoint] := flow_xypoints[flow_xypoint] shifted - if xpart d < 0 : (+a,0) ; - elseif xpart d > 0 : (-a,0) ; - elseif ypart d < 0 : (0,+b) ; - elseif ypart d > 0 : (0,-b) ; - else : origin ; - fi ; - d := direction 0 of p ; - flow_xypoints[1] := flow_xypoints[1] shifted - if xpart d < 0 : (-a,0) ; - elseif xpart d > 0 : (+a,0) ; - elseif ypart d < 0 : (0,-b) ; - elseif ypart d > 0 : (0,+b) ; - else : origin ; - fi ; - endgroup -enddef ; - -vardef flow_trim_points = enddef ; - -vardef flow_connection_path = - if flow_reverse_connection : reverse fi (flow_xypoints[1] -- - for i=2 upto flow_xypoint-1 : - if flow_smooth : - flow_smooth_connection(flow_xypoints[i],flow_xypoints[i-1]) .. - controls flow_xypoints[i] and flow_xypoints[i] .. - flow_smooth_connection(flow_xypoints[i],flow_xypoints[i+1]) -- - else : - flow_xypoints[i] -- - fi - endfor - flow_xypoints[flow_xypoint]) -enddef ; - -def flow_draw_connection(expr i,xfrom,yfrom,xto,yto) = % 'i' is a comment reference - if flow_xypoint > 0 : - flow_collapse_points ; - flow_trim_points ; - flow_cpath := flow_cpath + 1 ; % maybe also store as x,y - flow_cpaths[flow_cpath] := flow_connection_path flow_scaled_to_grid ; - flow_cline[flow_cpath] := flow_connection_line_width ; - flow_ccolor[flow_cpath] := flow_connection_line_color ; - flow_carrow[flow_cpath] := flow_arrowtip ; - flow_cdash[flow_cpath] := flow_dashline ; - flow_ccross[flow_cpath] := flow_showcrossing ; - if flow_reverse_connection : - flow_connections[xto] [yto] [i] := flow_cpaths[flow_cpath] ; - else : - flow_connections[xfrom][yfrom][i] := flow_cpaths[flow_cpath] ; - fi ; - else : - message("no connection defined") ; - fi ; - flow_reverse_connection := false ; -enddef ; - -def flow_flush_connections = % protect locals - begingroup ; - save ip, crossing, cp ; numeric ip ; boolean crossing ; path cp ; - ahlength := flow_connection_arrow_size ; - flow_dash_pattern := dashpattern(on flow_connection_dash_size off flow_connection_dash_size) ; - for i=1 upto flow_cpath : - if flow_ccross[i] : - crossing := false ; - for j=1 upto i : - if not (point infinity of flow_cpaths[i] = point infinity of flow_cpaths[j]) : - ip := flow_cpaths[i] intersection_point flow_cpaths[j] ; - if intersection_found : crossing := true fi ; - fi ; - endfor ; - if crossing : - pickup pencircle scaled 2flow_cline[i] ; - cp := flow_cpaths[i] ; - cp := cp cutbefore point .05 length cp of cp ; - cp := cp cutafter point .95 length cp of cp ; - draw cp withcolor flow_chart_background_color ; - fi ; - fi ; - pickup pencircle scaled flow_cline[i] ; - if flow_carrow[i] : - if flow_cdash[i] : - drawarrow flow_cpaths[i] withcolor flow_ccolor[i] dashed flow_dash_pattern ; - else : - drawarrow flow_cpaths[i] withcolor flow_ccolor[i] ; - fi ; - else : - if flow_cdash[i] : - draw flow_cpaths[i] withcolor flow_ccolor[i] dashed flow_dash_pattern ; - else : - draw flow_cpaths[i] withcolor flow_ccolor[i] ; - fi ; - fi ; - flow_draw_midpoint(i) ; - endfor ; - endgroup ; -enddef ; - -def flow_draw_midpoint (expr n) = - begingroup - save p ; pair p ; - p := point .5*length(flow_cpaths[n]) of flow_cpaths[n]; - pickup pencircle scaled 2flow_cline[n] ; - if flow_show_mid_points : - drawdot p withcolor .7white ; - fi ; - endgroup ; -enddef ; - -def flow_flush_picture(expr x, yy) = - begingroup ; - save y ; numeric y ; - y := flow_y_pos(yy) ; % maybe move this to the makers - if known flow_xytext[x][y] : - draw flow_xytext[x][y] ; - fi ; - if known flow_xylabel[x][y] : - draw flow_xylabel[x][y] ; - fi ; - if known flow_xyexit[x][y] : - draw flow_xyexit[x][y] ; - fi ; - if known flow_xycomment[x][y] : - draw flow_xycomment[x][y] ; - fi ; - endgroup ; -enddef ; - -vardef flow_offset(expr x, y) = - flow_xy_offset((x+0.5)*flow_grid_width,(flow_max_y-y+1.5)*flow_grid_height) - shifted (-flow_xyline[x][y]/4,-flow_xyline[x][y]/4) % terrible hack (some compensation) -enddef ; - -def flow_chart_draw_text(expr x, y, p) = - if known flow_xytext[x][y] : - addto flow_xytext[x][y] also - else : - flow_xytext[x][y] := - fi - p shifted flow_offset(x,y) ; -enddef ; - -def flow_chart_draw_label (expr x, y, loc, txt) = - begingroup ; - save p, s ; path p ; picture s ; - p := fullsquare xscaled flow_grid_width yscaled flow_grid_height ; - p := p shifted flow_offset(x,y) ; - s := txt ; - setbounds s to boundingbox s enlarged flow_label_offset ; - if known flow_xylabel[x][y] : - addto flow_xylabel[x][y] also - else : - flow_xylabel[x][y] := - fi - if loc = "tr" : anchored.llft(s,0.5[ulcorner p,urcorner p]) ; - elseif loc = "t" : anchored.bot (s,0.5[ulcorner p,urcorner p]) ; - elseif loc = "tl" : anchored.lrt (s,0.5[ulcorner p,urcorner p]) ; - elseif loc = "br" : anchored.ulft(s,0.5[llcorner p,lrcorner p]) ; - elseif loc = "b" : anchored.top (s,0.5[llcorner p,lrcorner p]) ; - elseif loc = "bl" : anchored.urt (s,0.5[llcorner p,lrcorner p]) ; - elseif loc = "lb" : anchored.urt (s,0.5[ulcorner p,llcorner p]) ; - elseif loc = "l" : anchored.rt (s,0.5[ulcorner p,llcorner p]) ; - elseif loc = "lt" : anchored.lrt (s,0.5[ulcorner p,llcorner p]) ; - elseif loc = "rb" : anchored.ulft(s,0.5[urcorner p,lrcorner p]) ; - elseif loc = "r" : anchored.lft (s,0.5[urcorner p,lrcorner p]) ; - elseif loc = "rt" : anchored.llft(s,0.5[urcorner p,lrcorner p]) ; - else : anchored (s,center p) ; - fi ; - endgroup ; -enddef ; - -def flow_chart_draw_exit (expr x, y, loc, txt) = - begingroup ; - save p, s ; path p ; picture s ; - p := fullsquare xscaled flow_grid_width yscaled flow_grid_height ; - p := p shifted flow_offset(x,y) ; - s := txt ; - setbounds s to boundingbox s enlarged flow_exit_offset ; - if known flow_xyexit[x][y] : - addto flow_xyexit[x][y] also - else : - flow_xyexit[x][y] := - fi - if loc = "t" : anchored.top(s,0.5[ulcorner p,urcorner p]) ; - elseif loc = "b" : anchored.bot(s,0.5[llcorner p,lrcorner p]) ; - elseif loc = "l" : anchored.lft(s,0.5[ulcorner p,llcorner p]) ; - elseif loc = "r" : anchored.rt (s,0.5[urcorner p,lrcorner p]) ; - else : anchored (s,center p) ; - fi ; - endgroup ; -enddef ; - -def flow_chart_draw_comment (expr x, y, i, loc, len, txt) = % per connection - begingroup ; - if known flow_connections[x][y][i] : - save p, q, s ; path p, q ; picture s ; - p := fullsquare xscaled flow_shape_width yscaled flow_shape_height ; - p := p shifted flow_offset(x,y) ; - q := flow_connections[x][y][i] ; % already relocated - s := txt ; - setbounds s to boundingbox s enlarged flow_comment_offset ; - if known flow_xycomment[x][y] : - addto flow_xycomment[x][y] also - else : - flow_xycomment[x][y] := - fi - if loc = "tr" : anchored.llft(s,if len = 0 : 0.5[ulcorner p,urcorner p] else : point len along q fi) ; - elseif loc = "t" : anchored.bot (s,if len = 0 : 0.5[ulcorner p,urcorner p] else : point len along q fi) ; - elseif loc = "tl" : anchored.lrt (s,if len = 0 : 0.5[ulcorner p,urcorner p] else : point len along q fi) ; - elseif loc = "br" : anchored.ulft(s,if len = 0 : 0.5[llcorner p,lrcorner p] else : point len along q fi) ; - elseif loc = "b" : anchored.top (s,if len = 0 : 0.5[llcorner p,lrcorner p] else : point len along q fi) ; - elseif loc = "bl" : anchored.urt (s,if len = 0 : 0.5[llcorner p,lrcorner p] else : point len along q fi) ; - elseif loc = "lb" : anchored.urt (s,if len = 0 : 0.5[ulcorner p,llcorner p] else : point len along q fi) ; - elseif loc = "l" : anchored.rt (s,if len = 0 : 0.5[ulcorner p,llcorner p] else : point len along q fi) ; - elseif loc = "lt" : anchored.lrt (s,if len = 0 : 0.5[ulcorner p,llcorner p] else : point len along q fi) ; - elseif loc = "rb" : anchored.ulft(s,if len = 0 : 0.5[urcorner p,lrcorner p] else : point len along q fi) ; - elseif loc = "r" : anchored.lft (s,if len = 0 : 0.5[urcorner p,lrcorner p] else : point len along q fi) ; - elseif loc = "rt" : anchored.llft(s,if len = 0 : 0.5[urcorner p,lrcorner p] else : point len along q fi) ; - elseif loc = "tr:*" : anchored.llft(s,point 0 of q) ; - elseif loc = "t:*" : anchored.bot (s,point 0 of q) ; - elseif loc = "tl:*" : anchored.lrt (s,point 0 of q) ; - elseif loc = "br:*" : anchored.ulft(s,point 0 of q) ; - elseif loc = "b:*" : anchored.top (s,point 0 of q) ; - elseif loc = "bl:*" : anchored.urt (s,point 0 of q) ; - elseif loc = "lb:*" : anchored.urt (s,point 0 of q) ; - elseif loc = "l:*" : anchored.rt (s,point 0 of q) ; - elseif loc = "lt:*" : anchored.lrt (s,point 0 of q) ; - elseif loc = "rb:*" : anchored.ulft(s,point 0 of q) ; - elseif loc = "r:*" : anchored.lft (s,point 0 of q) ; - elseif loc = "rt:*" : anchored.llft(s,point 0 of q) ; - else : anchored (s,point 0 of q) ; - fi ; - fi ; - endgroup ; -enddef ; - -boolean flow_reverse_connection ; flow_reverse_connection := false ; - -vardef flow_up_on_grid (expr n) = - (xpart flow_xypoints[n],(ypart flow_xypoints[n]+1) div 1) -enddef ; - -vardef flow_down_on_grid (expr n) = - (xpart flow_xypoints[n],(ypart flow_xypoints[n]) div 1) -enddef ; - -vardef flow_left_on_grid (expr n) = - ((xpart flow_xypoints[n]) div 1, ypart flow_xypoints[n]) -enddef ; - -vardef flow_right_on_grid (expr n) = - ((xpart flow_xypoints[n]+1) div 1, ypart flow_xypoints[n]) -enddef ; - -vardef flow_x_on_grid (expr n, xfrom, xto, zfrom) = - if (xfrom = xto) and not (zfrom = 0) : - if (zfrom=1) : flow_right_on_grid(2) else : flow_left_on_grid(2) fi - elseif xpart flow_xypoints[1] < xpart flow_xypoints[6] : - flow_right_on_grid(n) - else : - flow_left_on_grid(n) - fi -enddef ; - -vardef flow_y_on_grid (expr n, yfrom, yto, zfrom) = - if (yfrom = yto) and not (zfrom = 0) : - if (zfrom = 1) : flow_up_on_grid(2) else : flow_down_on_grid(2) fi - elseif ypart flow_xypoints[1] < ypart flow_xypoints[6] : - flow_up_on_grid(n) - else : - flow_down_on_grid(n) - fi -enddef ; - -vardef flow_xy_on_grid (expr n, m) = - (xpart flow_xypoints[n], ypart flow_xypoints[m]) -enddef ; - -vardef flow_down_to_grid (expr a,b) = - (xpart flow_xypoints[a], ypart flow_xypoints[if ypart flow_xypoints[a]ypart flow_xypoints[b] : a else : b fi]) -enddef ; - -vardef flow_left_to_grid (expr a,b) = - (xpart flow_xypoints[if xpart flow_xypoints[a]xpart flow_xypoints[b] : a else : b fi], ypart flow_xypoints[a]) -enddef ; - -vardef flow_valid_connection (expr xfrom, yfrom, xto, yto) = - begingroup ; - save ok, vc, pp ; boolean ok ; pair vc ; path pp ; - save flow_xyfirst, flow_xylast ; pair flow_xyfirst, flow_xylast ; - % check for slanted lines - ok := true ; - for i=1 upto flow_xypoint-1 : - if not ((xpart flow_xypoints[i]=xpart flow_xypoints[i+1]) or (ypart flow_xypoints[i]=ypart flow_xypoints[i+1])) : - ok := false ; - fi ; - endfor ; - if not ok : - % message("slanted"); - false - elseif flow_forcevalid : - % message("force"); - true - elseif (xfrom=xto) and (yfrom=yto) : - % message("self"); - false - else : - % check for crossing shapes - flow_xyfirst := flow_xypoints[1] ; - flow_xylast := flow_xypoints[flow_xypoint] ; - flow_trim_points ; - pp := for i=1 upto flow_xypoint-1 : flow_xypoints[i]-- endfor flow_xypoints[flow_xypoint] ; - flow_xypoints[1] := flow_xyfirst ; - flow_xypoints[flow_xypoint] := flow_xylast ; - for i=1 upto flow_max_x : - for j=1 upto flow_max_y : % was bug: xfrom,yto - if not ( ( (i,j)=(xfrom,yfrom) ) or ( (i,j)=(xto,yto) ) ) : - if not flow_xyfree[i][j] : - vc := pp intersection_point flow_xypath[i][j] ; - if intersection_found : - ok := false - fi ; - fi ; - fi ; - endfor ; - endfor ; - % if not ok: message("crossing") ; fi ; - ok - fi - endgroup -enddef ; - -def flow_connect_top_bottom (expr n) (expr xfrom, yyfrom, zfrom) (expr xto, yyto, zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,6) : - flow_xypoints[1] := flow_xy_top(xfrom,yfrom,zfrom,true) ; - flow_xypoints[6] := flow_xy_bottom(xto,yto,zto,true) ; - flow_xypoints[2] := flow_up_on_grid(1) ; - flow_xypoints[5] := flow_down_on_grid(6) ; - flow_xypoints[3] := flow_up_to_grid(2,5) ; - flow_xypoints[4] := flow_up_to_grid(2,5) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_x_on_grid(2,xfrom,xto,zfrom) ; - flow_xypoints[4] := flow_xy_on_grid(3,5) ; - fi ; - %%%% begin experiment - flow_xypoints[3] := flow_xypoints[3] shifted (flow_dsp_x,0) ; - flow_xypoints[4] := flow_xypoints[4] shifted (flow_dsp_x,0) ; - if flow_dsp_y>0 : - flow_xypoints[2] := flow_xypoints[2] shifted (0,flow_dsp_y) ; - flow_xypoints[3] := flow_xypoints[3] shifted (0,flow_dsp_y) ; - elseif flow_dsp_y<0 : - flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; - flow_xypoints[5] := flow_xypoints[5] shifted (0,flow_dsp_y) ; - fi - %%%% end experiment - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_left_right (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,6) : - flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; - flow_xypoints[6] := flow_xy_right(xto,yto,zto,true) ; - flow_xypoints[2] := flow_left_on_grid(1) ; - flow_xypoints[5] := flow_right_on_grid(6) ; - flow_xypoints[3] := flow_left_to_grid(2,5) ; - flow_xypoints[4] := flow_left_to_grid(2,5) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_y_on_grid(2,yfrom,yto,zfrom) ; - flow_xypoints[4] := flow_xy_on_grid(5,3) ; - fi ; - %%%% begin experiment - if flow_dsp_y <> 0 : - flow_xypoints[3] := flow_xypoints[3] shifted (0,-flow_dsp_y) ; - flow_xypoints[4] := flow_xypoints[4] shifted (0,-flow_dsp_y) ; - fi ; - %%%% end experiment - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_left_top (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,5) : - flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; - flow_xypoints[5] := flow_xy_top(xto,yto,zto,true) ; - flow_xypoints[2] := flow_left_on_grid(1) ; - flow_xypoints[4] := flow_up_on_grid(5) ; - flow_xypoints[3] := flow_left_to_grid(2,5) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_xy_on_grid(2,4) ; - fi ; - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_left_bottom (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,5) : - flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; - flow_xypoints[5] := flow_xy_bottom(xto,yto,zto,true) ; - flow_xypoints[2] := flow_left_on_grid(1) ; - flow_xypoints[4] := flow_down_on_grid(5) ; - flow_xypoints[3] := flow_left_to_grid(2,5) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_xy_on_grid(2,4) ; - fi ; - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_right_top (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,5) : - flow_xypoints[1] := flow_xy_right(xfrom,yfrom,zfrom,true) ; - flow_xypoints[5] := flow_xy_top(xto,yto,zto,true) ; - flow_xypoints[2] := flow_right_on_grid(1) ; - flow_xypoints[4] := flow_up_on_grid(5) ; - flow_xypoints[3] := flow_right_to_grid(2,5) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_xy_on_grid(2,4) ; - fi ; - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_right_bottom (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,5) : - flow_xypoints[1] := flow_xy_right(xfrom,yfrom,zfrom,true) ; - flow_xypoints[5] := flow_xy_bottom(xto,yto,zto,true) ; - flow_xypoints[2] := flow_right_on_grid(1) ; - flow_xypoints[4] := flow_down_on_grid(5) ; - flow_xypoints[3] := flow_right_to_grid(2,5) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_xy_on_grid(2,4) ; - fi ; - %%%% begin experiment - flow_xypoints[2] := flow_xypoints[2] shifted (flow_dsp_x,0) ; - flow_xypoints[3] := flow_xypoints[3] shifted (flow_dsp_x,0) ; - if flow_dsp_y>0 : - flow_xypoints[3] := flow_xypoints[3] shifted (0,-flow_dsp_y) ; - flow_xypoints[4] := flow_xypoints[4] shifted (0,-flow_dsp_y) ; - elseif flow_dsp_y<0 : - flow_xypoints[3] := flow_xypoints[3] shifted (0,flow_dsp_y) ; - flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; - fi - %%%% end experiment - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_left_left (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,6) : - flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; - flow_xypoints[6] := flow_xy_left(xto,yto,zto,true) ; - flow_xypoints[2] := flow_left_on_grid(1) ; - flow_xypoints[5] := flow_left_on_grid(6) ; - flow_xypoints[3] := flow_left_to_grid(2,5) ; - flow_xypoints[4] := flow_left_to_grid(5,2) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_y_on_grid(2,yfrom,yto,zfrom) ; - flow_xypoints[4] := flow_xy_on_grid(5,3) ; - fi ; - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_right_right (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,6) : - flow_xypoints[1] := flow_xy_right(xfrom,yfrom,zfrom,true) ; - flow_xypoints[6] := flow_xy_right(xto,yto,zto,true) ; - flow_xypoints[2] := flow_right_on_grid(1) ; - flow_xypoints[5] := flow_right_on_grid(6) ; - flow_xypoints[3] := flow_right_to_grid(2,5) ; - flow_xypoints[4] := flow_right_to_grid(5,2) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_y_on_grid(2,yfrom,yto,zfrom) ; - flow_xypoints[4] := flow_xy_on_grid(5,3) ; - fi ; - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_top_top (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,6) : - flow_xypoints[1] := flow_xy_top(xfrom,yfrom,zfrom,true) ; - flow_xypoints[6] := flow_xy_top(xto,yto,zto,true) ; - flow_xypoints[2] := flow_up_on_grid(1) ; - flow_xypoints[5] := flow_up_on_grid(6) ; - flow_xypoints[3] := flow_up_to_grid(2,5) ; - flow_xypoints[4] := flow_up_to_grid(5,2) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_x_on_grid(2,xfrom,xto,zfrom) ; - flow_xypoints[4] := flow_xy_on_grid(3,5) ; - fi ; - %%%% begin experiment (todo: not value but just + and ) - if flow_dsp_y <> 0 : - flow_xypoints[2] := flow_xypoints[2] shifted (0,flow_dsp_y) ; - flow_xypoints[3] := flow_xypoints[3] shifted (0,flow_dsp_y) ; - flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; - flow_xypoints[5] := flow_xypoints[5] shifted (0,flow_dsp_y) ; - fi ; - %%%% end experiment - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_bottom_bottom (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = - yfrom := flow_y_pos(yyfrom) ; - yto := flow_y_pos(yyto) ; - if flow_points_initialized(xfrom,yfrom,xto,yto,6) : - flow_xypoints[1] := flow_xy_bottom(xfrom,yfrom,zfrom,true) ; - flow_xypoints[6] := flow_xy_bottom(xto,yto,zto,true) ; - flow_xypoints[2] := flow_down_on_grid(1) ; - flow_xypoints[5] := flow_down_on_grid(6) ; - flow_xypoints[3] := flow_down_to_grid(2,5) ; - flow_xypoints[4] := flow_down_to_grid(5,2) ; - if not flow_valid_connection(xfrom,yfrom,xto,yto) : - flow_xypoints[3] := flow_x_on_grid(2,xfrom,xto,zfrom) ; - flow_xypoints[4] := flow_xy_on_grid(3,5) ; - fi ; - %%%% begin experiment - flow_xypoints[3] := flow_xypoints[3] shifted (flow_dsp_x,0) ; - flow_xypoints[4] := flow_xypoints[4] shifted (flow_dsp_x,0) ; - if flow_dsp_y<0 : - flow_xypoints[2] := flow_xypoints[2] shifted (0,-flow_dsp_y) ; - flow_xypoints[3] := flow_xypoints[3] shifted (0,-flow_dsp_y) ; - elseif flow_dsp_y>0 : - flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; - flow_xypoints[5] := flow_xypoints[5] shifted (0,flow_dsp_y) ; - fi - %%%% end experiment - flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; - fi ; -enddef ; - -def flow_connect_bottom_top (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - flow_reverse_connection := true ; - flow_connect_top_bottom (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def flow_connect_right_left (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - flow_reverse_connection := true ; - flow_connect_left_right (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def flow_connect_top_left (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - flow_reverse_connection := true ; - flow_connect_left_top (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def flow_connect_bottom_left (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - flow_reverse_connection := true ; - flow_connect_left_bottom (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def flow_connect_top_right (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - flow_reverse_connection := true ; - flow_connect_right_top (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def flow_connect_bottom_right (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = - flow_reverse_connection := true ; - flow_connect_right_bottom (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; -enddef ; - -def flow_draw_test_shape(expr x, y) = - flow_draw_shape(x,y,fullcircle, .7, .7) ; -enddef ; - -def flow_draw_test_shapes = - for i=1 upto flow_max_x : - for j=1 upto flow_max_y : - flow_draw_test_shape(i,j) ; - endfor ; - endfor ; -enddef; - -def flow_draw_test_area = - pickup pencircle scaled .5flow_shape_line_width ; - draw (unitsquare xscaled flow_max_x yscaled flow_max_y shifted (1,1)) flow_scaled_to_grid withcolor blue ; -enddef ; - -def flow_show_connection(expr n, m) = - - flow_begin_chart(100+n,6,6) ; - - flow_draw_test_area ; - - flow_smooth := true ; - flow_arrowtip := true ; - flow_dashline := true ; - - flow_draw_test_shape(2,2) ; flow_draw_test_shape(4,5) ; - flow_draw_test_shape(3,3) ; flow_draw_test_shape(5,1) ; - flow_draw_test_shape(2,5) ; flow_draw_test_shape(1,3) ; - flow_draw_test_shape(6,2) ; flow_draw_test_shape(4,6) ; - - if (m=1) : - flow_connect_top_bottom (0) (2,2,0) (4,5,0) ; - flow_connect_top_bottom (0) (3,3,0) (5,1,0) ; - flow_connect_top_bottom (0) (2,5,0) (1,3,0) ; - flow_connect_top_bottom (0) (6,2,0) (4,6,0) ; - elseif (m=2) : - flow_connect_top_top (0) (2,2,0) (4,5,0) ; - flow_connect_top_top (0) (3,3,0) (5,1,0) ; - flow_connect_top_top (0) (2,5,0) (1,3,0) ; - flow_connect_top_top (0) (6,2,0) (4,6,0) ; - elseif (m=3) : - flow_connect_bottom_bottom (0) (2,2,0) (4,5,0) ; - flow_connect_bottom_bottom (0) (3,3,0) (5,1,0) ; - flow_connect_bottom_bottom (0) (2,5,0) (1,3,0) ; - flow_connect_bottom_bottom (0) (6,2,0) (4,6,0) ; - elseif (m=4) : - flow_connect_left_right (0) (2,2,0) (4,5,0) ; - flow_connect_left_right (0) (3,3,0) (5,1,0) ; - flow_connect_left_right (0) (2,5,0) (1,3,0) ; - flow_connect_left_right (0) (6,2,0) (4,6,0) ; - elseif (m=5) : - flow_connect_left_left (0) (2,2,0) (4,5,0) ; - flow_connect_left_left (0) (3,3,0) (5,1,0) ; - flow_connect_left_left (0) (2,5,0) (1,3,0) ; - flow_connect_left_left (0) (6,2,0) (4,6,0) ; - elseif (m=6) : - flow_connect_right_right (0) (2,2,0) (4,5,0) ; - flow_connect_right_right (0) (3,3,0) (5,1,0) ; - flow_connect_right_right (0) (2,5,0) (1,3,0) ; - flow_connect_right_right (0) (6,2,0) (4,6,0) ; - elseif (m=7) : - flow_connect_left_top (0) (2,2,0) (4,5,0) ; - flow_connect_left_top (0) (3,3,0) (5,1,0) ; - flow_connect_left_top (0) (2,5,0) (1,3,0) ; - flow_connect_left_top (0) (6,2,0) (4,6,0) ; - elseif (m=8) : - flow_connect_left_bottom (0) (2,2,0) (4,5,0) ; - flow_connect_left_bottom (0) (3,3,0) (5,1,0) ; - flow_connect_left_bottom (0) (2,5,0) (1,3,0) ; - flow_connect_left_bottom (0) (6,2,0) (4,6,0) ; - elseif (m=9) : - flow_connect_right_top (0) (2,2,0) (4,5,0) ; - flow_connect_right_top (0) (3,3,0) (5,1,0) ; - flow_connect_right_top (0) (2,5,0) (1,3,0) ; - flow_connect_right_top (0) (6,2,0) (4,6,0) ; - else : - flow_connect_right_bottom (0) (2,2,0) (4,5,0) ; - flow_connect_right_bottom (0) (3,3,0) (5,1,0) ; - flow_connect_right_bottom (0) (2,5,0) (1,3,0) ; - flow_connect_right_bottom (0) (6,2,0) (4,6,0) ; - fi ; - - flow_end_chart ; - -enddef ; - -def flow_show_connections = - for f=1 upto 10 : - flow_show_connection(f,f) ; - endfor ; -enddef ; - -%D charts - -def flow_clip_chart(expr minx, miny, maxx, maxy) = - flow_cmin_x := minx ; - flow_cmax_x := maxx ; - flow_cmin_y := miny ; - flow_cmax_y := maxy ; -enddef ; - -def flow_begin_chart(expr n, maxx, maxy) = - flow_new_chart ; - flow_chart_figure := n ; - flow_chart_scale := 1 ; - if flow_chart_figure>0: - beginfig(flow_chart_figure) ; - fi ; - flow_initialize_grid (maxx, maxy) ; - bboxmargin := 0 ; - flow_cmin_x := 1 ; - flow_cmax_x := maxx ; - flow_cmin_y := 1 ; - flow_cmax_y := maxy ; -enddef ; - -def flow_end_chart = - begingroup ; - save p ; path p ; - flow_flush_shapes ; - flow_flush_connections ; - flow_flush_pictures ; - flow_cmin_x := flow_cmin_x ; - flow_cmax_x := flow_cmin_x+flow_cmax_x ; - flow_cmin_y := flow_cmin_y-1 ; - flow_cmax_y := flow_cmin_y+flow_cmax_y ; - if flow_reverse_y : - flow_cmin_y := flow_y_pos(flow_cmin_y) ; - flow_cmax_y := flow_y_pos(flow_cmax_y) ; - fi ; - p := (((flow_cmin_x,flow_cmin_y)--(flow_cmax_x,flow_cmin_y)-- - (flow_cmax_x,flow_cmax_y)--(flow_cmin_x,flow_cmax_y)--cycle)) - flow_scaled_to_grid ; - %draw p withcolor red ; - p := p enlarged flow_chart_offset ; - clip currentpicture to p ; - setbounds currentpicture to p ; - endgroup ; - currentpicture := currentpicture scaled flow_chart_scale ; - if flow_chart_figure>0: - endfig ; - fi ; -enddef ; - -def flow_new_shape(expr x, y, n) = - if known n : - if (x>0) and (x<=flow_max_x) and (y>0) and (y<=flow_max_y) : - flow_draw_shape(x,y,some_shape_path(n), flow_shape_width/flow_grid_width, flow_shape_height/flow_grid_height) ; - else : - message ("shape outside grid ignored") ; - fi ; - else : - message ("shape not known" ) ; - fi ; -enddef ; - -def flow_begin_sub_chart = - begingroup ; - save flow_shape_line_width, flow_connection_line_width ; - save flow_shape_line_color, flow_shape_fill_color, flow_connection_line_color ; - color flow_shape_line_color, flow_shape_fill_color, flow_connection_line_color ; - save flow_smooth, flow_arrowtip, flow_dashline, flow_peepshape ; - boolean flow_smooth, flow_arrowtip, flow_dashline, flow_peepshape ; -enddef ; - -def flow_end_sub_chart = - endgroup ; -enddef ; - diff --git a/metapost/context/base/mp-chem.mpiv b/metapost/context/base/mp-chem.mpiv deleted file mode 100644 index b861d3f12..000000000 --- a/metapost/context/base/mp-chem.mpiv +++ /dev/null @@ -1,1731 +0,0 @@ -%D \module -%D [ file=mp-chem.mpiv, -%D version=2009.05.13, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=chemicals, -%D author=Hans Hagen \& Alan Braslau, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -%D This module is incomplete and experimental. Okay, it's not that bad but we do need -%D some disclaimer. - -% either consistent setting or not - -if known context_chem : endinput ; fi ; - -boolean context_chem ; context_chem := true ; - -numeric - chem_num[], % scratch - 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_center_offset, chem_dbl_offset, - chem_bb_angle, chem_axis_rulethickness, - chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b, - chem_setting_rotation, chem_emwidth, chem_b_length, - chem_front_b[] ; - -boolean - chem_setting_axis, - chem_doing_pb, chem_bd_wedge, - chem_star[], chem_front[], chem_stacked[], chem_tetra[] ; - -string - chem_previous ; - -path - chem_path[], % scratch - chem_b_path[], chem_c_path[], - chem_r_path[], chem_r_path.lft[], chem_r_path.rt[] ; - -pair - chem_origin, chem_mirror, - chem_pair[], % scratch - chem_sb_pair, chem_sb_pair.m, chem_sb_pair.p, chem_sb_pair.b ; - -picture - chem_pic, % scratch - % The use of dashpattern is found to dot the starting point with chem_sb_dash.m... - %chem_sb_dash, chem_sb_dash.m, chem_sb_dash.p, chem_sb_dash.b, - chem_axis_color ; - -transform - chem_t ; % scratch - -color lightblue ; lightblue := (173/255,216/255,230/255) ; - -% debugging - -boolean chem_trace_nesting ; chem_trace_nesting := false ; -boolean chem_trace_text ; chem_trace_text := false ; -boolean chem_trace_boundingbox ; chem_trace_boundingbox := false ; - -chem_axis_color := image(draw origin withcolor lightblue) ; -chem_setting_axis := false ; -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 := .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 := 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_bd_wedge := true ; % according to IUPAC 2005 - -def chem_reset = - chem_rotation := 0 ; - chem_mirror := origin ; - chem_adjacent := 0 ; - chem_substituent := 0 ; - chem_substituent.lft := 0 ; - chem_substituent.rt := 0 ; - chem_stack_n := 0 ; - chem_doing_pb := false ; - chem_origin := origin ; - chem_previous := "one" ; - pair chem_mark_pair[] ; -enddef ; - -chem_reset ; - -newinternal numeric - one, carbon, alkyl, newmanstagger, newmaneclipsed, - three, four, five, six, seven, eight, nine, - fivefront, sixfront, chair, boat ; - -vardef chem_init_some (suffix $) (expr e) = - if not known chem_star[$] : chem_star[$] := false ; fi - if not known chem_front[$] : chem_front[$] := false ; fi - if not known chem_stacked[$] : chem_stacked[$] := false ; fi - if not known chem_tetra[$] : chem_tetra[$] := false ; fi - - % We define all paths as closed, so that they may be indexed mod length. - if path(e) : - chem_b_path[$] := e if not cycle(e) : -- cycle fi ; - chem_num0 := length(chem_b_path[$]) ; - else : % polygon - chem_num0 := e ; - chem_num1 := 360/chem_num0 ; - chem_b_path[$] := - ( - for i=0 upto chem_num0-1 : - dir(if chem_star[$] : -i else : (.5-i) fi *chem_num1) -- - endfor - cycle - ) - if chem_front[$] : - rotated (chem_num1-90) - fi - if not chem_star[$] : - scaled (.5/(sind .5chem_num1)) - % carbon-carbon benzene bond length - scaled (1.4/1.54) - fi ; - fi ; - - if chem_front[$] and (not known chem_front_b[$]) : - chem_front_b[$] := floor(.5(length chem_b_path[$])) + 1 ; - fi - - chem_num2 := 0 ; - chem_c_path[$] := - reverse(fullcircle) rotated angle(point 0 of chem_b_path[$]) - if not chem_star[$] : - hide (for i=0 upto chem_num0-1: - if abs(point i+.5 of chem_b_path[$]) < - abs(point chem_num2+.5 of chem_b_path[$]) : - chem_num2 := i ; - fi - endfor) - scaled (2*(abs(point chem_num2+.5 of chem_b_path[$]) - 2chem_dbl_offset)) - fi ; - - chem_r_path[$] := - if chem_star[$] : - chem_b_path[$] - else : - ( - for i=0 upto chem_num0-1 : - (unitvector point i of chem_b_path[$]) - shifted point i of chem_b_path[$] -- - endfor - cycle - ) - fi ; - - chem_r_path.lft[$] := - ( - for i=0 upto chem_num0-1 : - if chem_front[$] : - up - scaled .5 - shifted point i of chem_b_path[$] - elseif chem_star[$] : - point i of chem_b_path[$] - else : - point i+1 of chem_b_path[$] - rotatedabout(point i of chem_b_path[$],180) - fi -- - endfor - cycle - ) ; - chem_r_path.rt[$] := - ( - for i=0 upto chem_num0-1 : - if chem_front[$] : - down - scaled .5 - shifted point i of chem_b_path[$] - elseif chem_star[$] : - point i+2 of chem_b_path[$] - else : - point i-1 of chem_b_path[$] - rotatedabout(point i of chem_b_path[$],180) - fi -- - endfor - cycle - ) ; - -enddef ; - -% The following is used only once: -def chem_init_all = -begingroup - save a, b, c, d, e ; numeric a, b, c, d, e ; - save lft, rt ; path lft, rt ; - - % tetrahedrial angle - a := 2angle(1,sqrt 2) ; - - % solve for chair - 2b = 180 - .5a ; - 4c = 180 - .5a ; - d + e = 360 - 2a ; - d = 5e ; % this is the one tunable parameter which fixes the perspective. - z2 = z1 shifted dir(90+a+d) ; - z3 = z2 shifted dir(270-a) ; - z4 = z3 shifted dir(90+a) ; - z6 = z1 shifted dir(90+a) ; - z5 = z6 shifted dir(270-a) ; - z4 = z1 xyscaled (-1,-1) ; - z5 = z2 xyscaled (-1,-1) ; - - save indx ; numeric indx ; indx = 2 ; % starting value doesn't matter, really. - % polygons - three := incr indx ; % 3 (these numbers don't matter - they are just indices) - four := incr indx ; % 4 - five := incr indx ; % 5 - six := incr indx ; % 6 - seven := incr indx ; % 7 - eight := incr indx ; % 8 - nine := incr indx ; % 9 - - chem_init_some(three,3) ; - chem_init_some(four, 4) ; - chem_init_some(five, 5) ; - chem_init_some(six, 6) ; - chem_init_some(seven,7) ; - chem_init_some(eight,8) ; - chem_init_some(nine, 9) ; - - % star-form - one := incr indx ; % 10 - carbon := incr indx ; % 11 - alkyl := incr indx ; % 12 - newmanstagger := incr indx ; % 13 - newmaneclipsed := incr indx ; % 14 - - chem_star[one] := true ; - chem_star[carbon] := true ; chem_tetra[carbon] := true ; - chem_star[alkyl] := true ; chem_tetra[alkyl] := true ; - chem_star[newmanstagger] := true ; chem_tetra[newmanstagger] := true ; - chem_star[newmaneclipsed] := true ; chem_tetra[newmaneclipsed] := true ; - chem_stacked[newmanstagger] := true ; - chem_stacked[newmaneclipsed] := true ; - chem_init_some(one, 8) ; - chem_init_some(carbon, dir(0)--dir(360-a)--dir(180-.5a+b)--dir(180-.5a)) ; - chem_init_some(alkyl, dir(0)--dir(360-a)--dir(360-a-90)--dir(90)) ; - chem_init_some(newmanstagger, dir(30)--dir(270)--dir(150)--dir(330)--dir(210)--dir(90)) ; - chem_init_some(newmaneclipsed, dir(30)--dir(270)--dir(150)--dir(0)--dir(240)--dir(120)) ; - - % front views - fivefront := incr indx ; % 15 - sixfront := incr indx ; % 16 - chair := incr indx ; % 17 - boat := incr indx ; % 18 - - chem_front[fivefront] := true ; chem_front_b[fivefront] := 3 ; - chem_front[sixfront] := true ; chem_front_b[sixfront] := 3 ; - chem_init_some(fivefront,5) ; - chem_init_some(sixfront, 6) ; - % chair - chem_front[chair] := true ; chem_front_b[chair] := 4 ; - chem_init_some(chair, z1--z2--z3--z4--z5--z6) ; - lft := dir(90-a)--down--dir(90+a+d)--down--dir(90+a)--down ; - rt := up--dir(270+a)--up--dir(270-a)--up--dir(90+e) ; - chem_r_path.lft[chair] := - for i=0 upto 5 : point i of lft shifted point i of chem_b_path[chair] -- endfor - cycle ; - chem_r_path.rt[chair] := - for i=0 upto 5 : point i of rt shifted point i of chem_b_path[chair] -- endfor - cycle ; - % boat - chem_front[boat] := true ; chem_front_b[boat] := 4 ; - chem_init_some(boat, - for i=1 upto 4 : point i-1 of chem_b_path[sixfront] -- endfor - point 2 of chem_b_path[sixfront] yscaled .5 -- - point 1 of chem_b_path[sixfront] yscaled .5 - ) ; - lft := dir(30+.5a)--dir(330+.5a)--dir(210-.5a)--dir(150-.5a)--dir(120)--dir(60) ; - rt := dir(30-.5a)--dir(330-.5a)--dir(210+.5a)--dir(150+.5a)--dir(120+a)--dir(60-a) ; - chem_r_path.lft[boat] := - for i=0 upto 5 : point i of lft shifted point i of chem_b_path[boat] -- endfor - cycle ; - chem_r_path.rt[boat] := - for i=0 upto 5 : point i of rt shifted point i of chem_b_path[boat] -- endfor - cycle ; -endgroup -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, bond, scale, offset, axis, rulethickness, axiscolor) = - save chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b ; - - 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 - if numeric r : - chem_setting_r := r ; - fi - if numeric t : - chem_setting_t := t ; - fi - if numeric b : - chem_setting_b := -b ; - fi - chem_setting_rotation := rotation ; - chem_setting_offset := offset ; - chem_setting_axis := if boolean axis : axis else : (axis<>0) fi ; - chem_axis_rulethickness := .75*(rulethickness) ; % axis 50% thinner than frame and bonds. - chem_axis_color := image(draw origin withcolor axiscolor) ; % so we handle all color models - - chem_reset ; -enddef ; - -% \stopchemical - -vardef chem_stop_structure = - % Make sure that all of the saved stack has been restored... (this was a gotcha!) - forever : - exitif chem_stack_n=0 ; - chem_restore ; - endfor - - currentpicture := (currentpicture shifted -chem_origin) rotated chem_setting_rotation ; - - save l, r, b, t ; - l := min(xpart llcorner currentpicture, xpart lrcorner currentpicture) ; - r := max(xpart llcorner currentpicture, xpart lrcorner currentpicture) ; - b := min(ypart llcorner currentpicture, ypart ulcorner currentpicture) ; - t := max(ypart llcorner currentpicture, ypart ulcorner currentpicture) ; - - if unknown chem_setting_l : chem_setting_l := l ; fi - if unknown chem_setting_r : chem_setting_r := r ; fi - if unknown chem_setting_b : chem_setting_b := b ; fi - if unknown chem_setting_t : chem_setting_t := t ; fi - - if chem_setting_axis : % put it behind the picture - chem_pic := currentpicture ; currentpicture := nullpicture ; - chem_num0 := .5chem_b_length ; - chem_num1 := .2chem_num0 ; - % draw the axes to the bounding box of the entire structure, - % not necessarily the bounding box of the final figure - draw (l,0) -- (r,0) - withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; - draw (0,b) -- (0,t) - withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; - for i = 0 step chem_num0 until r : - draw (i,-chem_num1) -- (i,chem_num1) - withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; - endfor - for i = 0 step -chem_num0 until l : - draw (i,-chem_num1) -- (i,chem_num1) - withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; - endfor - for i = 0 step chem_num0 until t : - draw (-chem_num1,i) -- (chem_num1,i) - withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; - endfor - for i = 0 step -chem_num0 until b : - draw (-chem_num1,i) -- (chem_num1,i) - withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; - endfor - addto currentpicture also chem_pic ; - fi ; - if chem_trace_boundingbox : - fill boundingbox currentpicture withcolor blue withtransparency(1,.25) ; - fi ; - setbounds currentpicture to - ((chem_setting_l,chem_setting_b) -- (chem_setting_r,chem_setting_b) -- - (chem_setting_r,chem_setting_t) -- (chem_setting_l,chem_setting_t) -- cycle) ; - if chem_trace_boundingbox : - fill boundingbox currentpicture withcolor red withtransparency(1,.25) ; - fi ; -enddef ; - -% \chemical - -vardef chem_start_component = enddef ; -vardef chem_stop_component = enddef ; - -vardef chem_pb = % PB : - if chem_trace_nesting : - draw boundingbox currentpicture - withpen pencircle scaled 1mm withcolor colorpart(chem_axis_color) ; - draw origin withpen pencircle scaled 2mm withcolor colorpart(chem_axis_color) ; - fi ; - chem_doing_pb := true ; -enddef ; - -vardef chem_pe = % PE - if chem_trace_nesting : - draw boundingbox currentpicture withpen pencircle scaled .5mm withcolor red ; - draw origin withpen pencircle scaled 1mm withcolor red ; - fi ; - currentpicture := currentpicture shifted -chem_origin ; - if chem_trace_nesting : - draw origin withpen pencircle scaled .5mm withcolor green ; - fi ; - chem_origin := origin ; - chem_doing_pb := false ; -enddef ; - -vardef chem_do (expr pos) = - if (unknown chem_doing_pb) or (not chem_doing_pb) : - pos - else : - chem_doing_pb := false ; - currentpicture := currentpicture shifted -pos ; - chem_origin := chem_origin shifted -pos ; - origin % nullpicture - fi -enddef ; - - -picture chem_stack_p[] ; -pair chem_stack_origin[], chem_stack_mirror[] ; -numeric chem_stack_rotation[] ; -string chem_stack_previous[] ; - -vardef chem_save = % SAVE - chem_stack_p [incr chem_stack_n] := currentpicture ; - chem_stack_origin [ chem_stack_n] := chem_origin ; chem_origin := origin ; - chem_stack_rotation[ chem_stack_n] := chem_rotation ; - chem_stack_mirror [ chem_stack_n] := chem_mirror ; - chem_stack_previous[ chem_stack_n] := chem_previous ; - currentpicture := nullpicture ; -enddef ; - -vardef chem_restore = % RESTORE - if chem_stack_n>0 : - currentpicture := currentpicture shifted -chem_origin ; - addto chem_stack_p [chem_stack_n] also currentpicture ; - currentpicture := chem_stack_p [chem_stack_n] ; - chem_stack_p[chem_stack_n] := nullpicture ; - chem_origin := chem_stack_origin [chem_stack_n] ; - chem_rotation := chem_stack_rotation[chem_stack_n] ; - chem_mirror := chem_stack_mirror [chem_stack_n] ; - chem_previous := chem_stack_previous[chem_stack_n] ; - chem_stack_n := chem_stack_n - 1 ; - fi ; -enddef ; - -% chem_adj and chem_sub are to be followed by chem_set(n) which does all the work... - -vardef chem_adj (suffix $) (expr d, s) = % ADJ - % scale s is ignored (for now?) - if not chem_front[$] : - chem_substituent := 0 ; - chem_substituent.lft := 0 ; - chem_substituent.rt := 0 ; - chem_adjacent := d ; - fi -enddef ; - -vardef chem_lsub (suffix $) (expr d, s) = % LSUB - chem_sub.lft($,d,s) ; -enddef ; - -vardef chem_rsub (suffix $) (expr d, s) = % RSUB - chem_sub.rt ($,d,s) ; -enddef ; - -vardef chem_sub@# (suffix $) (expr d, s) = % SUB - % scale s is ignored (for now?) - chem_adjacent := 0 ; - chem_substituent := 0 ; - chem_substituent.lft := 0 ; - chem_substituent.rt := 0 ; - % then : - chem_substituent@# := d ; -enddef ; - -def chem_transformed (suffix $) = % not vardef! - scaled chem_b_length - if not chem_front[$] : - if chem_mirror<>origin : reflectedabout(origin,chem_mirror) fi - rotated chem_rotation - fi -enddef ; - -vardef chem_draw (expr what, r, c) (text extra) = - draw what - withpen pencircle scaled r - withcolor c %\MPcolor{c} - extra ; -enddef ; - -vardef chem_fill (expr what, r, c) (text extra) = - fill what - withpen pencircle scaled r - withcolor c %\MPcolor{c} - extra ; -enddef ; - -vardef chem_drawarrow (expr what, r, c) (text extra) = - drawarrow what - withpen pencircle scaled r - withcolor c %\MPcolor{c} - extra ; -enddef ; - -vardef chem_set (suffix $) = - forsuffixes P = scantokens chem_previous : - - % 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 ; - elseif (chem_adjacent<>0) and (chem_front[P] or chem_front[$]) : - % not allowed for FRONT - chem_adjacent := 0 ; - elseif chem_adjacent<>0 : - chem_substituent := 0 ; - chem_substituent.lft := 0 ; - chem_substituent.rt := 0 ; - % move to the bond midpoint of the first structure - chem_pair0 := center ( - if chem_star[P] : - origin -- point (chem_adjacent-1) - else : - subpath (chem_adjacent-1,chem_adjacent) - fi - of chem_b_path[P] - ) chem_transformed(P) ; - % find the closest opposite bond of the second structure - chem_pair1 := chem_pair0 rotated if chem_star[P] : 90 else : 180 fi ; - chem_num0 := abs(chem_pair1) ; - chem_num1 := if chem_tetra[$] : 1 else : length chem_b_path[$] fi ; - % only consider even indices (cardinal points) for ONE - chem_num2 := if chem_star[$] and not chem_tetra[$] : 2 else : 1 fi ; - for i=0 step chem_num2 until chem_num1 : - chem_pair2 := ( - ( - unitvector - center ( - if chem_star[$] : - origin -- point i - else : - subpath (i,i+1) - fi - of chem_b_path[$]) - ) - scaled chem_num0 - ) chem_transformed($) ; - if i=0 : - chem_pair3 := chem_pair2 ; - chem_num3 := 0 ; - elseif (abs(chem_pair1 shifted -chem_pair2)) < (abs(chem_pair1 shifted -chem_pair3)) : - chem_pair3 := chem_pair2 ; - chem_num3 := i ; - fi - endfor - if chem_star[$] : - chem_pair4 := chem_pair0 shifted - -((point (chem_adjacent-1) of chem_b_path[P]) chem_transformed(P)) ; - fi - % adjust the bond angles - 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] : - (point chem_num3 - else : - center(subpath (chem_num3,chem_num3+1) - fi - of chem_b_path[$]) - chem_transformed($) ; - fi - if not chem_star[P] : - chem_pair4 := chem_pair4 shifted -chem_pair0 ; - fi - currentpicture := currentpicture shifted chem_pair4 ; - chem_origin := chem_origin shifted chem_pair4 ; - chem_adjacent := 0 ; - fi ; - - % Insure that only one, if any, will be nonzero - if ((chem_substituent <> 0) and (chem_substituent.lft <> 0)) or - ((chem_substituent <> 0) and (chem_substituent.rt <> 0)) or - ((chem_substituent.lft <> 0) and (chem_substituent.rt <> 0)) : - chem_substituent := 0 ; - chem_substituent.lft := 0 ; - chem_substituent.rt := 0 ; - fi - if (chem_substituent <> 0) or (chem_substituent.lft <> 0) or (chem_substituent.rt <> 0) : - % move origin to radical endpoint of the first structure - if chem_substituent.lft > 0 : - chem_pair0 := point chem_substituent.lft-1 of chem_r_path.lft[P] ; - chem_substituent := chem_substituent.lft ; - chem_substituent.lft := 0 ; - elseif chem_substituent.rt > 0 : - chem_pair0 := point chem_substituent.rt-1 of chem_r_path.rt[P] ; - chem_substituent := chem_substituent.rt ; - chem_substituent.rt := 0 ; - else : - chem_pair0 := point chem_substituent-1 of chem_r_path[P] ; - fi - chem_pair1 := chem_pair0 if not chem_star[P] : - shifted -(point chem_substituent-1 of chem_b_path[P]) fi ; - chem_t := identity chem_transformed(P) ; - chem_pair0 := chem_pair0 transformed chem_t ; % radical - chem_pair1 := chem_pair1 transformed chem_t ; % recentered (see below) - currentpicture := currentpicture shifted -chem_pair0 ; - chem_origin := chem_origin shifted -chem_pair0 ; - if (not (chem_star[P] and chem_star[$])) or chem_tetra[P] or chem_tetra[$] : - if chem_tetra[P] and chem_tetra[$] and ((chem_substituent=1) or (chem_substituent=2)): - chem_rotation := (chem_rotation + 180) mod 360 ; % trans-alkane - chem_pair2 := (point .5 of chem_b_path[$]) ; % bisector, not chem_transformed - if chem_mirror=origin : - chem_mirror := chem_pair2 ; - else : - chem_num0 := angle(chem_mirror)-angle(chem_pair2) ; - if (chem_num0>0) and (chem_num0> 180) : - chem_num0 := 360 - chem_num0 ; - elseif (chem_num0<0) and (chem_num0<-180) : - chem_num0 := -360 - chem_num0 ; - fi - chem_rotation := (chem_rotation + 2chem_num0) mod 360 ; - chem_mirror := origin ; - fi - fi - chem_t := identity chem_transformed($) ; - chem_pair1 := chem_pair1 rotated 180 ; % opposite direction of radical bond - % find the closest node - chem_num0 := abs(chem_pair1) ; % distance - % search to find the nearest node of $; only consider 1 and 2 for CARBON,ALKYL - chem_num1 := if chem_tetra[$] : 1 else : length chem_b_path[$] fi ; - % only consider even indices (cardinal points) for ONE - chem_num2 := if chem_star[$] and not chem_tetra[$] : 2 else : 1 fi ; - for i=0 step chem_num2 until chem_num1 : - chem_pair2 := (unitvector(point i of chem_b_path[$]) scaled chem_num0) - transformed chem_t ; - if i=0 : - chem_pair3 := chem_pair2 ; - chem_num3 := 0 ; - elseif (abs(chem_pair1 shifted -chem_pair2)) < - (abs(chem_pair1 shifted -chem_pair3)) : - chem_pair3 := chem_pair2 ; - chem_num3 := i ; - fi - endfor - if not chem_front[$] : % adjust rotation - 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 ; - if not chem_star[$] : - 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 ; - endfor - chem_previous := str $ ; -enddef ; - -% line (f_rom, t_o, r_ule, c_olor) - -vardef chem_b@# (suffix $) (expr f, t, r, c) = % B - if chem_star[$] : - chem_r@#($,f,t,r,c) ; - elseif length(str @#)>0 : - chem_sb@#($,f,t,r,c) ; - else : - chem_draw( - (subpath (f-1,t) of chem_b_path[$]) chem_transformed($), - r,c,) ; - fi -enddef ; - -vardef chem_sb@# (suffix $) (expr f, t, r, c) = % SB - if chem_star[$] : - chem_sr@#($,f,t,r,c) ; - else : - %chem_draw( - % (subpath (f-1,t) of chem_b_path[$]) chem_transformed($), - % r,c,dashed chem_sb_dash@# scaled chem_b_length) ; - 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, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_sd@# (suffix $) (expr f, t, r, c) = % SD - if chem_star[$] : - chem_rd@#($,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, - r,c,dashed evenly) ; - endfor - fi -enddef ; - -vardef chem_r_fragment@# (suffix $) (expr i) = - ( - if chem_star[$] : - origin - else : - point i-1 of chem_b_path[$] - fi -- - point i-1 of chem_r_path@#[$] - ) % no ; -enddef ; - -vardef chem_r@# (suffix $) (expr f, t, r, c) = % R - if length(str @#)>0 : - chem_sr@#($,f,t,r,c) ; - else : - chem_sr.b($,f,t,r,c) ; - fi -enddef ; - -vardef chem_er@# (suffix $) (expr f, t, r, c) = % ER - if length(str @#)>0: - chem_dr@#($,f,t,r,c) ; - else : - chem_dr.b($,f,t,r,c) ; - fi -enddef ; - -vardef chem_dr@# (suffix $) (expr f, t, r, c) = % DR - if not chem_front[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := (subpath chem_sb_pair@# of chem_r_fragment($,i)) ; - chem_draw( - (chem_path0 paralleled chem_dbl_offset) transformed chem_t, - r,c,) ; - chem_draw( - (chem_path0 paralleled -chem_dbl_offset) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_lr@# (suffix $) (expr f, t, r, c) = % LR - if length(str @#)>0 : - chem_lsr@#($,f,t,r,c) ; - else : - chem_lsr.b($,f,t,r,c) ; - fi -enddef ; - -vardef chem_rr@# (suffix $) (expr f, t, r, c) = % RR - if length(str @#)>0 : - chem_rsr@#($,f,t,r,c) ; - else : - chem_rsr.b($,f,t,r,c) ; - fi -enddef ; - -vardef chem_eb@# (suffix $) (expr f, t, r, c) = % EB - if not chem_star[$] : - %chem_draw( - % ((subpath (f-1,t) of chem_b_path[$]) paralleled -2chem_dbl_offset) - % chem_transformed($), - % r,c,dashed chem_sb_dash scaled chem_b_length) ; - for i=f upto t : - chem_t := identity chem_transformed($) ; - chem_draw( - ((subpath (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$]) - paralleled -2chem_dbl_offset) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_ad@# (suffix $) (expr f, t, r, c) = % AD - 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 - 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 - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - ((point i-1 of chem_r_path[$]) scaled (xpart chem_sb_pair)) transformed chem_t, - chem_dot_factor*r,c,) ; - endfor - fi -enddef ; - -vardef chem_ed@# (suffix $) (expr f, t, r, c) = % ED - chem_t := identity chem_transformed($) ; - for i=f upto t : - if chem_star[$] : - chem_path0 := subpath chem_sb_pair of chem_r_fragment($,i) ; - chem_draw( - (point 0 of (chem_path0 paralleled -chem_dbl_offset)) transformed chem_t, - chem_dot_factor*r,c,) ; - chem_draw( - (point 0 of (chem_path0 paralleled chem_dbl_offset)) transformed chem_t, - chem_dot_factor*r,c,) ; - else : - chem_draw( - ((subpath (chem_sb_pair shifted (i-1,i-1)) of chem_b_path[$]) - paralleled -2chem_dbl_offset) transformed chem_t, - r,c,dashed evenly) ; - fi - endfor -enddef ; - -vardef chem_ep@# (suffix $) (expr f, t, r, c) = % EP - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair of chem_r_fragment($,i) ; - chem_draw( - (point 0 of (chem_path0 paralleled -chem_dbl_offset) -- - point 0 of (chem_path0 paralleled chem_dbl_offset)) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_et@# (suffix $) (expr f, t, r, c) = % ET - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair of chem_r_fragment($,i) ; - chem_draw( - (point 0 of (chem_path0 paralleled -2chem_dbl_offset)) transformed chem_t, - chem_dot_factor*r,c,) ; - chem_draw( - (point 0 of chem_path0) transformed chem_t, - chem_dot_factor*r,c,) ; - chem_draw( - (point 0 of (chem_path0 paralleled 2chem_dbl_offset)) transformed chem_t, - chem_dot_factor*r,c,) ; - endfor - fi -enddef ; - -vardef chem_db@# (suffix $) (expr f, t, r, c) = % DB - if chem_star[$] : - chem_dr@#($,f,t,r,c) ; - elseif not chem_front[$] : - chem_t := identity chem_transformed($) ; - %chem_draw( - % ((subpath (f-1,t) of chem_b_path[$]) paralleled -chem_dbl_offset) - % transformed chem_t, - % r,c,dashed chem_sb_dash@# scaled chem_b_length) ; - %chem_draw( - % ((subpath (f-1,t) of chem_b_path[$]) paralleled chem_dbl_offset) - % transformed chem_t, - % r,c,dashed chem_sb_dash@# scaled chem_b_length) ; - for i=f upto t : - chem_path0 := subpath (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$] ; - chem_draw( - (chem_path0 paralleled -chem_dbl_offset) transformed chem_t, - r,c,) ; - chem_draw( - (chem_path0 paralleled chem_dbl_offset) transformed chem_t, - r,c,) ; - % todo : this should be cut-off where it overlaps a neighboring standard bond. - endfor - fi -enddef ; - -vardef chem_tb@# (suffix $) (expr f, t, r, c) = % TB - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_draw( - (chem_path0 paralleled -2chem_dbl_offset) transformed chem_t, - r,c,) ; - chem_draw( - chem_path0 transformed chem_t, - r,c,) ; - chem_draw( - (chem_path0 paralleled 2chem_dbl_offset) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_sr@# (suffix $) (expr f, t, r, c) = % SR - chem_t := identity chem_transformed($) ; - if chem_stacked[$] : - chem_num0 := length chem_b_path[$] ; chem_num1 := floor(.5chem_num0) ; - for i=f upto t : - chem_draw( - (subpath (if i>chem_num1: .5,ypart fi chem_sb_pair@#) of chem_r_fragment($,i)) - transformed chem_t, - r,c,) ; - endfor - else : - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment($,i)) - transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_rd@# (suffix $) (expr f, t, r, c) = % RD - chem_t := identity chem_transformed($) ; - if chem_stacked[$] : - chem_num0 := length chem_b_path[$] ; chem_num1 := floor(.5chem_num0) ; - for i=f upto t : - chem_draw( - (subpath (if i>chem_num1: .5,ypart fi chem_sb_pair@#) of chem_r_fragment($,i)) - transformed chem_t, - r,c,dashed evenly) ; - endfor - else : - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment($,i)) - transformed chem_t, - r,c,dashed evenly) ; - endfor - fi -enddef ; - -vardef chem_rh@# (suffix $) (expr f, t, r, c) = % RH - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment($,i)) - transformed chem_t, - chem_dot_factor*r,c,dashed withdots scaled ((.5chem_b_length/3)/5bp)) ; - % not symmetric - needs to be tweaked... - endfor -enddef ; - -vardef chem_lrh@# (suffix $) (expr f, t, r, c) = % LRH - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment.lft($,i)) - transformed chem_t, - chem_dot_factor*r,c,dashed withdots scaled ((.5chem_b_length/3)/5bp)) ; - % not symmetric - needs to be tweaked... - endfor -enddef ; - -vardef chem_rrh@# (suffix $) (expr f, t, r, c) = % RRH - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment.rt($,i)) - transformed chem_t, - chem_dot_factor*r,c,dashed withdots scaled ((.5chem_b_length/3)/5bp)) ; - % not symmetric - needs to be tweaked... - endfor -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 ; - -vardef chem_bb@# (suffix $) (expr f, t, r, c) = % BB - if chem_star[$] : - chem_rb@#($,f,t,r,c) ; - elseif chem_front[$] : - chem_t := identity chem_transformed($) ; - chem_draw( - (subpath (f-1,t) of chem_b_path[$]) transformed chem_t, - r,c,) ; - chem_num0 := length chem_b_path[$] ; % total number of bonds - chem_num1 := chem_front_b[$] ; % number of bonds to be made bold - % bold bonds within f and t - chem_num2 := if f<0 :((f+1) mod chem_num0) + chem_num0 else : ((f-1) mod chem_num0) + 1 fi ; - chem_num3 := if t<0 :((t+1) mod chem_num0) + chem_num0 else : ((t-1) mod chem_num0) + 1 fi ; - if chem_num31) : - chem_path0 := subpath (if chem_num2>2 : chem_num2-1 else : 1 fi, - if chem_num3=chem_num1 : - chem_fill( - (point chem_num1 of chem_b_path[$] -- - point chem_num1-1 of chem_b_path[$] shifted (0,-chem_dbl_offset) -- - point chem_num1-1 of chem_b_path[$] shifted (0, chem_dbl_offset) -- - cycle) transformed chem_t, - r,c,) ; - fi - fi - fi -enddef ; - -vardef chem_rb@# (suffix $) (expr f, t, r, c) = % RB - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_fill( - (point 0 of chem_path0 -- - point 1 of chem_path0 - rotatedaround(point 0 of chem_path0, -chem_bb_angle) -- - point 1 of chem_path0 - rotatedaround(point 0 of chem_path0, chem_bb_angle) -- - cycle) transformed chem_t, - r,c,) ; - endfor -enddef ; - -vardef chem_lrb@# (suffix $) (expr f, t, r, c) = % LRB - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.lft($,i) ; - chem_fill( - (point 0 of chem_path0 -- - point 1 of chem_path0 - rotatedaround(point 0 of chem_path0, -chem_bb_angle) -- - point 1 of chem_path0 - rotatedaround(point 0 of chem_path0, chem_bb_angle) -- - cycle) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_rrb@# (suffix $) (expr f, t, r, c) = % RRB - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.rt($,i) ; - chem_fill( - (point 0 of chem_path0 -- - point 1 of chem_path0 - rotatedaround(point 0 of chem_path0, -chem_bb_angle) -- - point 1 of chem_path0 - rotatedaround(point 0 of chem_path0, chem_bb_angle) -- - cycle) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_lsr@# (suffix $) (expr f, t, r, c) = % LSR - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment.lft($,i)) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_rsr@# (suffix $) (expr f, t, r, c) = % RSR - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment.rt($,i)) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_lrd@# (suffix $) (expr f, t, r, c) = % LRD - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment.lft($,i)) transformed chem_t, - r,c,dashed evenly) ; - endfor - fi -enddef ; - -vardef chem_rrd@# (suffix $) (expr f, t, r, c) = % RRD - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of chem_r_fragment.rt($,i)) transformed chem_t, - r,c,dashed evenly) ; - endfor - fi -enddef ; - -vardef chem_s@# (suffix $) (expr f, t, r, c) = % S - if length(str @#)>0 : - chem_ss@#($,f,t,r,c) ; - else : - chem_ss.b($,f,t,r,c) ; - fi -enddef ; - -vardef chem_ss@# (suffix $) (expr f, t, r, c) = % SS - if not (chem_star[$] or chem_front[$]) : - chem_draw( - subpath chem_sb_pair@# of (point f-2 of chem_b_path[$] -- point t of chem_b_path[$]) - chem_transformed($), - r,c,) ; - fi -enddef ; - -vardef chem_mid@# (suffix $) (expr f, t, r, c) = % MID - if length(str @#)>0 : - chem_mids@#($,f,t,r,c) ; - else : - chem_mids.b($,f,t,r,c) ; - fi -enddef ; - -vardef chem_mids@# (suffix $) (expr f, t, r, c) = % MIDS - if not (chem_star[$] or chem_front[$]) : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_draw( - (subpath chem_sb_pair@# of (origin -- point i-1 of chem_b_path[$])) - transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_cd (suffix $) (expr r, c) = % CD - chem_draw( - chem_c_path[$] chem_transformed($), - r,c,dashed evenly) ; -enddef ; - -vardef chem_c (suffix $) (expr r, c) = % C - chem_draw( - chem_c_path[$] chem_transformed($), - r,c,) ; -enddef ; - -vardef chem_ccd (suffix $) (expr f, t, r, c) = % CCD - chem_num0 := ypart((origin--center(subpath (f-2,f-1) of chem_b_path[$])) - intersectiontimes chem_c_path[$]) ; - chem_num1 := ypart((origin--center(subpath (t-1,t) of chem_b_path[$])) - intersectiontimes chem_c_path[$]) ; - if chem_num1>chem_num0 : - chem_num0 := chem_num0 + length chem_c_path[$] ; - fi - chem_draw( - subpath (chem_num1,chem_num0) of chem_c_path[$] chem_transformed($), - r,c,dashed evenly) ; -enddef ; - -vardef chem_cc (suffix $) (expr f, t, r, c) = % CC - chem_num0 := ypart((origin--center(subpath (f-2,f-1) of chem_b_path[$])) - intersectiontimes chem_c_path[$]) ; - chem_num1 := ypart((origin--center(subpath (t-1,t) of chem_b_path[$])) - intersectiontimes chem_c_path[$]) ; - if chem_num1>chem_num0 : - chem_num0 := chem_num0 + length chem_c_path[$] ; - fi - chem_draw( - subpath (chem_num1,chem_num0) of chem_c_path[$] chem_transformed($), - r,c,) ; -enddef ; - -vardef chem_ldb@# (suffix $) (expr f, t, r, c) = % LD - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_draw( - chem_path0 transformed chem_t, - r,c,) ; - chem_draw( - (chem_path0 paralleled 2chem_dbl_offset) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_rdb@# (suffix $) (expr f, t, r, c) = % LD - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_draw( - chem_path0 transformed chem_t, - r,c,) ; - chem_draw( - (chem_path0 paralleled -2chem_dbl_offset) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_ldd@# (suffix $) (expr f, t, r, c) = % LDD - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_draw( - chem_path0 transformed chem_t, - r,c,) ; - chem_draw( - (chem_path0 paralleled 2chem_dbl_offset) transformed chem_t, - r,c,dashed evenly) ; - endfor - fi -enddef ; - -vardef chem_rdd@# (suffix $) (expr f, t, r, c) = % RDD - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_draw( - chem_path0 transformed chem_t, - r,c,) ; - chem_draw( - (chem_path0 paralleled -2chem_dbl_offset) transformed chem_t, - r,c,dashed evenly) ; - endfor - fi -enddef ; - -vardef chem_oe@# (suffix $) (expr f, t, r, c) = % OE - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; - chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; - chem_draw( - ( point 0 of chem_path0 -- - .2[point 0 of chem_path0, point infinity of chem_path0].. - .3[point 0 of chem_path1, point infinity of chem_path1].. - .4[point 0 of chem_path0, point infinity of chem_path0].. - .5[point 0 of chem_path2, point infinity of chem_path2].. - .6[point 0 of chem_path0, point infinity of chem_path0].. - .7[point 0 of chem_path1, point infinity of chem_path1].. - .8[point 0 of chem_path0, point infinity of chem_path0]-- - point infinity of chem_path0) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_bw@# (suffix $) (expr f, t, r, c) = % BW - if chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; - chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; - chem_draw( - ( point 0 of chem_path0.. - .1[point 0 of chem_path1, point infinity of chem_path1].. - .2[point 0 of chem_path0, point infinity of chem_path0].. - .3[point 0 of chem_path2, point infinity of chem_path2].. - .4[point 0 of chem_path0, point infinity of chem_path0].. - .5[point 0 of chem_path1, point infinity of chem_path1].. - .6[point 0 of chem_path0, point infinity of chem_path0].. - .7[point 0 of chem_path2, point infinity of chem_path2].. - .8[point 0 of chem_path0, point infinity of chem_path0].. - .9[point 0 of chem_path1, point infinity of chem_path1].. - point infinity of chem_path0) transformed chem_t, - r,c,) ; - endfor - fi -enddef ; - -vardef chem_bd@# (suffix $) (expr f, t, r, c) = % BD - if chem_star[$] : chem_rbd#@($,f,t,r,c) ; fi -enddef ; - -vardef chem_rbd@# (suffix $) (expr f, t, r, c) = % RBD - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; - if chem_bd_wedge : - chem_path1 := chem_path0 rotated -chem_bb_angle ; - chem_path2 := chem_path0 rotated chem_bb_angle ; - else : - chem_path1 := chem_path0 paralleled -chem_dbl_offset ; - chem_path2 := chem_path0 paralleled chem_dbl_offset ; - fi - for j=0 upto 3 : - chem_draw( - (point (j/3) of chem_path1 -- point (j/3) of chem_path2) transformed chem_t, - 2r,c,) ; - endfor - endfor -enddef ; - -vardef chem_lrbd@# (suffix $) (expr f, t, r, c) = % LRBD - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.lft($,i) ; - if chem_bd_wedge : - chem_path1 := chem_path0 rotated -chem_bb_angle ; - chem_path2 := chem_path0 rotated chem_bb_angle ; - else : - chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; - chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; - fi - for j=0 upto 3 : - chem_draw( - (point (j/3) of chem_path1 -- point (j/3) of chem_path2) transformed chem_t, - 2r,c,) ; - endfor - endfor - fi -enddef ; - -vardef chem_rrbd@# (suffix $) (expr f, t, r, c) = % RRBD - if not chem_star[$] : - chem_t := identity chem_transformed($) ; - for i=f upto t : - chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.rt($,i) ; - if chem_bd_wedge : - chem_path1 := chem_path0 rotated -chem_bb_angle ; - chem_path2 := chem_path0 rotated chem_bb_angle ; - else : - chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; - chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; - fi - for j=0 upto 3 : - chem_draw( - (point (j/3) of chem_path1 -- point (j/3) of chem_path2) transformed chem_t, - 2r,c,) ; - endfor - endfor - fi -enddef ; - -% text, number (no alignment on number); - -vardef chem_z@#(suffix $) (expr p) (text t) = % Z - draw chem_text@# - (t,chem_do( - if p=0 : - origin - else : - (point p-1 of chem_b_path[$]) chem_transformed($) - fi - )) ; -enddef ; - -vardef chem_cz@#(suffix $) (expr p) (text t) = chem_z@#($,p,t) ; enddef ; % CZ ? - -vardef chem_midz@#(suffix $) (expr p) (text t) = % MIDZ - if not (chem_star[$] or chem_front[$]) : - draw chem_text@# - (t,chem_do( - (xpart chem_sb_pair, 0) scaled (xpart point 0 of chem_b_path[$]) - chem_transformed($) - )) ; - fi -enddef ; - -vardef chem_rz@#(suffix $) (expr p) (text t) = % RZ - draw chem_text@# - (t, chem_do((point p-1 of chem_r_path[$]) chem_transformed($))) ; -enddef ; - -vardef chem_lrz@#(suffix $) (expr p) (text t) = % LRZ - if not chem_star[$] : - draw chem_text@# - (t, - chem_do((point p-1 of chem_r_path.lft[$]) chem_transformed($))) ; - fi -enddef ; - -vardef chem_rrz@#(suffix $) (expr p) (text t) = % RRZ - if not chem_star[$] : - draw chem_text@# - (t, chem_do((point p-1 of chem_r_path.rt[$]) chem_transformed($))) ; - fi -enddef ; - -vardef chem_zn@#(suffix $) (expr p) (text t) = % ZN - chem_zt($,p,t) ; -enddef ; - -vardef chem_zt@#(suffix $) (expr p) (text t) = % ZT - draw chem_text@#(t,chem_do ((point p-1 of chem_b_path[$]) chem_transformed($) - scaled chem_text_min)) ; -enddef ; - -vardef chem_zln@#(suffix $) (expr p) (text t) = % ZLN - chem_zlt($,p,t) ; -enddef ; - -vardef chem_zlt@#(suffix $) (expr p) (text t) = % ZLT - draw chem_text@#(t, chem_do((point p-1.5 of chem_b_path[$]) chem_transformed($) - scaled chem_text_min)) ; -enddef ; - -vardef chem_zrn@#(suffix $) (expr p) (text t) = % ZRN - chem_zrt($,p,t) ; -enddef ; - -vardef chem_zrt@#(suffix $) (expr p) (text t) = % ZRT - draw chem_text@#(t, chem_do((point p-0.5 of chem_b_path[$]) chem_transformed($) - scaled chem_text_min)) ; -enddef ; - -vardef chem_crz@#(suffix $) (expr p) (text t) = % CRZ ???? - if chem_star[$] : - draw chem_text@#(t, chem_do((point p-1 of chem_b_path[$] enlonged chem_center_offset) - chem_transformed($))) ; - fi -enddef ; - -vardef chem_rn@#(suffix $) (expr i, t) = % RN - chem_rt($,i,t) ; -enddef ; - -vardef chem_rt@#(suffix $) (expr p) (text t) = % RT - draw chem_text@#(t, chem_do((center chem_r_fragment($,p)) chem_transformed($))) ; -enddef ; - -vardef chem_lrn@#(suffix $) (expr i, t) = % LRN - chem_lrt($,i,t) ; -enddef ; - -vardef chem_lrt@#(suffix $) (expr p) (text t) = % LRT - draw chem_text@#(t, chem_do((center chem_r_fragment.lft($,p)) chem_transformed($))) ; -enddef ; - -vardef chem_rrn@# (suffix $) (expr i, t) = % RRN - chem_rrt($,i,t) ; -enddef ; - -vardef chem_rrt@#(suffix $) (expr p) (text t) = % RRT - draw chem_text@#(t, chem_do((center chem_r_fragment.rt($,p)) chem_transformed($))) ; -enddef ; - -vardef chem_symbol(expr t) = draw textext(t) ; enddef ; - -vardef chem_align@#(expr pic) = - pic - if (mfun_labtype@# >= 10) : - shifted (0,ypart center pic) - fi - shifted (-(mfun_labxf@#*lrcorner pic + mfun_labyf@#*ulcorner pic + (1-mfun_labxf@#-mfun_labyf@#)*llcorner pic)) -enddef ; - -vardef chem_text@#(expr txt, z) = - chem_pic := textext(txt) ; - if length(str @#)=0 : - chem_pic := chem_align(chem_pic) ; - elseif (str @#) = "auto" : - if z<>origin : - chem_num0 := abs(angle(z rotated chem_setting_rotation)) ; - if chem_num0<=60 : - chem_pic := chem_align.rt (chem_pic) xshifted chem_text_offset ; - elseif chem_num0>=120 : - chem_pic := chem_align.lft(chem_pic) xshifted -chem_text_offset ; - else : - chem_pic := chem_align (chem_pic) ; - fi - else : - chem_pic := chem_align (chem_pic) ; - fi - else : - chem_pic := chem_align@#(chem_pic) shifted (chem_text_offset*mfun_laboff@#) ; - fi - chem_pic := (chem_pic rotated -chem_setting_rotation) shifted z ; - - if chem_trace_text : - draw z withpen pencircle scaled 2pt withcolor red ; - draw boundingbox chem_pic withpen pencircle scaled 1pt withcolor red ; - fi - - chem_pic -enddef ; - -% transform - -% rotations and reflections - -vardef chem_rot (suffix $) (expr d, s) = % ROT - if not chem_front[$] : - if d=0 : - 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[$]) - - angle(point d+chem_num0-1 of chem_b_path[$])) ; - chem_rotation := (chem_rotation + s*chem_num1) zmod 360 ; - fi - fi -enddef ; - -vardef chem_mir (suffix $) (expr d, s) = % MIR - % We take the scale factor s to multiply the rotation, but only ONCE. - % For example: CARBON,.5MIR12 will give a rotation by 104° - if not chem_front[$] : - if d=0 : % inversion - if chem_mirror=origin : - chem_rotation := (chem_rotation + 180*s) zmod 360 ; - else : - chem_mirror := chem_mirror rotated 90 ; - fi - else : - chem_pair0 := (point d-1 of chem_b_path[$]) scaled s ; % not chem_transformed - if chem_mirror=origin : - chem_mirror := chem_pair0 ; - else : - chem_num0 := angle(chem_mirror)-angle(chem_pair0) ; - if (chem_num0>0) and (chem_num0> 180) : - chem_num0 := 360 - chem_num0 ; - elseif (chem_num0<0) and (chem_num0<-180) : - chem_num0 := -360 - chem_num0 ; - fi - chem_num0 := chem_num0 * s ; - chem_rotation := (chem_rotation + 2chem_num0) zmod 360 ; - chem_mirror := origin ; - fi - fi - fi -enddef ; - -% translations - -vardef chem_dir (suffix $) (expr d, s) = % DIR (same as MOV(d-1)MOV(d+1)) - if not chem_front[$] : - if d=0 : - currentpicture := currentpicture shifted -chem_origin ; - chem_origin := origin ; - else : - chem_pair0 := - (((point d-2 of chem_b_path[$]) shifted (point d of chem_b_path[$])) scaled s) - chem_transformed($) ; - currentpicture := currentpicture shifted -chem_pair0 ; - chem_origin := chem_origin shifted -chem_pair0 ; - fi - fi -enddef ; - -vardef chem_mov (suffix $) (expr d, s) = % MOV - if d=0 : - currentpicture := currentpicture shifted -chem_origin ; - chem_origin := origin ; - else : - chem_pair0 := ((point d-1 of chem_b_path[$]) scaled s) chem_transformed($) ; - currentpicture := currentpicture shifted -chem_pair0 ; - chem_origin := chem_origin shifted -chem_pair0 ; - fi ; -enddef ; - -vardef chem_mark (suffix $) (expr d, s) = % MARK - % scale s is ignored - if d<>0 : - chem_mark_pair[d] := -chem_origin ; - fi -enddef ; - -vardef chem_marked (expr d) = - if d=0 : - chem_origin - elseif known chem_mark_pair[d] : - chem_mark_pair[d] shifted chem_origin - else : - origin - fi -enddef ; - -vardef chem_number@#(suffix $) (expr p) (text t) = chem_label@#($,p,t) enddef ; % NUMBER -vardef chem_label@# (suffix $) (expr p) (text t) = % LABEL - draw chem_text@#(t,chem_do(chem_marked(p))) ; -enddef ; - -vardef chem_move (suffix $) (expr d, s) = % MOVE - chem_pair0 := chem_marked(d) scaled s ; - currentpicture := currentpicture shifted -chem_pair0 ; - chem_origin := chem_origin shifted -chem_pair0 ; -enddef ; - -vardef chem_diff (suffix $) (expr d, s) = % DIFF - chem_pair0 := (chem_marked(d) shifted -chem_origin) scaled s ; - currentpicture := currentpicture shifted -chem_pair0 ; - chem_origin := chem_origin shifted -chem_pair0 ; -enddef ; - -vardef chem_line (suffix $) (expr f, t, r, c) = % LINE - draw if f=t : origin else : chem_marked(f) fi -- chem_marked(t) - % no chem_transformed - withpen pencircle scaled r - withcolor c %\MPcolor{c} -enddef ; - -vardef chem_dash (suffix $) (expr f, t, r, c) = % DASH - draw if f=t : origin else : chem_marked(f) fi -- chem_marked(t) - % no chem_transformed - withpen pencircle scaled r - withcolor c %\MPcolor{c} - dashed evenly ; -enddef ; - -vardef chem_arrow (suffix $) (expr f, t, r, c) = % ARROW - drawarrow if f=t : origin else : chem_marked(f) fi -- chem_marked(t) - % no chem_transformed - withpen pencircle scaled r - withcolor c %\MPcolor{c} -enddef ; - - -vardef chem_rm (suffix $) (expr d, s) = % RM - if (not chem_front[$]) and (d<>0) : - chem_pair0 := ((point d-1 of chem_r_path[$]) scaled s) chem_transformed($) ; - currentpicture := currentpicture shifted -chem_pair0 ; - chem_origin := chem_origin shifted -chem_pair0 ; - fi ; -enddef ; - -vardef chem_off (suffix $) (expr d, s) = % OFF - if d=0 : - currentpicture := currentpicture shifted -chem_origin ; - chem_origin := origin ; - else : - chem_pair0 := (unitvector(point d-1 of chem_b_path[one])) scaled chem_setting_offset*s ; - % not chem_transformed - currentpicture := currentpicture shifted -chem_pair0 ; - chem_origin := chem_origin shifted -chem_pair0 ; - fi ; -enddef ; diff --git a/metapost/context/base/mp-core.mpii b/metapost/context/base/mp-core.mpii deleted file mode 100644 index 33e9b386e..000000000 --- a/metapost/context/base/mp-core.mpii +++ /dev/null @@ -1,1418 +0,0 @@ -if known context_core : endinput ; fi ; - -boolean context_core ; context_core := true ; - -pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; -path pxy[] ; -numeric hxy[], wxy[], dxy[], nxy[] ; - -def box_found (expr n,x,y,w,h,d) = - not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) -enddef ; - -def initialize_box_pos (expr pos,n,x,y,w,h,d) = - pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; - path pxy ; numeric hxy, wxy, dxy, nxy; - lxy := (x,y) ; - llxy := (x,y-d) ; - lrxy := (x+w,y-d) ; - urxy := (x+w,y+h) ; - ulxy := (x,y+h) ; - wxy := w ; - hxy := h ; - dxy := d ; - rxy := lxy shifted (wxy,0) ; - pxy := llxy--lrxy--urxy--ulxy--cycle ; - cxy := center pxy ; - nxy := n ; - freeze_box(pos) ; -enddef ; - -def freeze_box (expr pos) = - lxy[pos] := lxy ; - llxy[pos] := llxy ; - lrxy[pos] := lrxy ; - urxy[pos] := urxy ; - ulxy[pos] := ulxy ; - wxy[pos] := wxy ; - hxy[pos] := hxy ; - dxy[pos] := dxy ; - rxy[pos] := rxy ; - pxy[pos] := pxy ; - cxy[pos] := cxy ; - nxy[pos] := nxy ; -enddef ; - -def initialize_box (expr n,x,y,w,h,d) = - - numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; - -enddef ; - -def initialize_area (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td) = - - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - - do_initialize_area (fpos, tpos) ; - -enddef ; - -def do_initialize_area (expr fpos, tpos) = - lxy := lxy[fpos] ; - llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; - lrxy := lrxy[tpos] ; - urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; - ulxy := ulxy[fpos] ; - wxy := xpart lrxy - xpart llxy ; - hxy := hxy[fpos] ; - dxy := dxy[tpos] ; - rxy := lxy shifted (wxy,0) ; - pxy := llxy--lrxy--urxy--ulxy--cycle ; - cxy := center pxy ; -enddef ; - -def set_par_line_height (expr ph, pd) = - par_strut_height := - if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ; - par_strut_depth := - if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ; - par_line_height := - par_strut_height + par_strut_depth ; -enddef ; - -def initialize_par (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td, - mn,mx,my,mw,mh,md, - pn,px,py,pw,ph,pd, - rw,rl,rr,rh,ra,ri) = - - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; - numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; - - numeric par_strut_height, par_strut_depth, par_line_height ; - - set_par_line_height (ph, pd) ; - - do_initialize_area (fpos, tpos) ; - do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; - -enddef ; - -def initialize_area_par (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td, - wn,wx,wy,ww,wh,wd) = - - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ; - - numeric par_strut_height, par_strut_depth, par_line_height ; - - set_par_line_height (wh, wd) ; - - numeric ffpos ; ffpos := 4 ; initialize_box_pos(ffpos,wn,wx,fy,0,wh,wd) ; - numeric ttpos ; ttpos := 5 ; initialize_box_pos(ttpos,wn,wx+ww,ty,0,wh,wd) ; - - do_initialize_area (ffpos, ttpos) ; - - numeric mpos ; mpos := 6 ; freeze_box(mpos) ; - - do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; - -enddef ; - -def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = - - pair lref, rref, pref, lhref, rhref ; - - % clip the page area to the left and right skips - - llxy[mpos] := llxy[mpos] shifted (+rl,0) ; - lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; - urxy[mpos] := urxy[mpos] shifted (-rr,0) ; - ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; - - % fixate the leftskip, rightskip and hanging indentation - - lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; - rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; - - pref := lxy[ppos] ; - - if nxy[tpos] > nxy[fpos] : - if nxy[fpos] = nxy[mpos] : - % first of multiple pages - llxy[tpos] := llxy[mpos] ; - lrxy[tpos] := lrxy[mpos] ; - urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; - ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; - boxgriddirection := down ; - elseif nxy[tpos] = nxy[mpos] : - % last of multiple pages - llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; - lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; - urxy[fpos] := urxy[mpos] ; - ulxy[fpos] := ulxy[mpos] ; - boxgriddirection := up ; - else : - % middle of multiple pages - llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; - lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; - urxy[fpos] := urxy[mpos] ; - ulxy[fpos] := ulxy[mpos] ; - llxy[tpos] := llxy[mpos] ; - lrxy[tpos] := lrxy[mpos] ; - urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; - ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; - boxgriddirection := up ; - fi ; - else : - % just one page - boxgriddirection := up ; - fi ; - - path txy, bxy, pxy, mxy ; - - txy := originpath ; % top - bxy := originpath ; % bottom - pxy := originpath ; % composed - - boolean lefthang, righthang, somehang ; - - % we only hang on the first of a multiple page background - - if nxy[mpos] > nxy[fpos] : - lefthang := righthang := somehang := false ; - else : - lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; - fi ; - - if lefthang : - mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; - elseif righthang : - mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; - else : - mxy := originpath ; - fi ; - - if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : - - % We have a one-liner. Watch how er use the bottom pos for - % determining the height. - - llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; - ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; - - else : - - % We have a multi-liner. For convenience we now correct the - % begin and end points for indentation. - - if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : - llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; - ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; - else : - llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; - ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; - fi ; - - if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : - lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; - urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; - else : - lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; - urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; - fi ; - - fi ; - - somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and - (ypart llxy[tpos]0 : - left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; - right_skip := rw - left_skip - ww ; - else : - left_skip := rl ; - right_skip := rr ; - fi ; - - path multipar, multipars[] ; - numeric multiref, multirefs[] ; - numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end - - numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; - - % locals .. why can't i move these outside? - -vardef _pmp_set_multipar_ (expr i) = - ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip - if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) -enddef ; - -vardef _pmp_snapped_multi_pos_ (expr p) = - if snap_multi_par_tops : - if abs(ypart p - ypart ulcorner multipar) < par_line_height : - (xpart p,ypart ulcorner multipar) - else : - p - fi - else : - p - fi -enddef ; - -vardef _pmp_estimated_par_lines_ (expr h) = - round(h/par_line_height) -enddef ; - -vardef _pmp_top_multi_par_(expr p) = - (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p))) -enddef ; - -vardef _pmp_multi_par_tsc_(expr p) = - if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi -enddef ; - -vardef _pmp_estimated_multi_par_height_ (expr n, t) = - if round(par_line_height)=0 : - 0 - else : - save ok, h ; boolean ok ; - numeric h ; h := 0 ; - ok := false ; - if (nxy[fpos]=RealPageNumber-1) : - for i := 1 upto NOfSavedTextAreas : - if (InsideSavedTextArea(i,par_start_pos)) : - ok := true ; - h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - - ypart llcorner SavedTextAreas[i]) ; - elseif ok : - h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ; - fi ; - endfor ; - fi ; - if ok : - for i := 1 upto n-1 : - h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; - endfor ; - else : - % already: ok := false ; - for i := 1 upto n-1 : - if (InsideTextArea(i,par_start_pos)) : - ok := true ; - h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; - elseif ok : - h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; - fi ; - endfor ; - fi ; - h - fi -enddef ; - -vardef _pmp_left_top_hang_ (expr same_area) = - - par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; - - if (par_hang_indent>0) and (par_hang_after<0) and obey_multi_par_hang : - pair _ul_ ; _ul_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])); - pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llxy[tpos])) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := min(0,round(par_hang_after + - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - (xpart _ul_ + par_hang_indent, ypart lrxy[fpos]) -- - (xpart _ul_ + par_hang_indent, ypart _pa_) -- - (xpart ulcorner multipar, ypart _pa_) - else : - (xpart ulcorner multipar, ypart lrxy[fpos]) - fi -enddef ; - -vardef _pmp_right_top_hang_ (expr same_area) = - - par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; - - if (par_hang_indent<0) and (par_hang_after<0) and obey_multi_par_hang : - pair _ur_ ; _ur_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; - pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := min(0,round(par_hang_after + - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - (xpart urcorner multipar, ypart _pa_) -- - (xpart _ur_ + par_hang_indent, ypart _pa_) -- - (xpart _ur_ + par_hang_indent, ypart _pmp_snapped_multi_pos_(urxy[fpos])) - else : - (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) - fi -enddef ; - -vardef _pmp_x_left_top_hang_ (expr i, t) = - par_hang_after := min(0,ra + _pmp_estimated_multi_par_height_(i,t)) ; - if (par_hang_indent>0) and (par_hang_after<0) : - pair _ul_ ; _ul_ := ulcorner multipar ; - pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; - if t : - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos])); - fi ; - if abs(ypart _pa_-ypart llxy[tpos])0) and (par_hang_after>0) and obey_multi_par_hang : - _ll_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])) ; - _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := max(0,round(par_hang_after - - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - _pa_ -- - (xpart _pa_ + par_hang_indent,ypart _pa_) -- - (xpart _pa_ + par_hang_indent,ypart _sa_) - else : - (xpart llcorner multipar, ypart _sa_) - fi -enddef ; - -vardef _pmp_right_bottom_hang_ (expr same_area) = - pair _lr_, _sa_, _pa_ ; - _sa_ := if same_area : _pmp_snapped_multi_pos_(ulxy[tpos]) else : lrcorner multipar fi ; - if (par_hang_indent<0) and (par_hang_after>0) and obey_multi_par_hang : - _lr_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; - _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := max(0,round(par_hang_after - - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - (xpart _pa_ + par_hang_indent,ypart _sa_) -- - (xpart _pa_ + par_hang_indent,ypart _pa_) -- - _pa_ - else : - (xpart lrcorner multipar, ypart _sa_) - fi -enddef ; - -vardef _pmp_x_left_bottom_hang_ (expr i, t) = - pair _ll_, _sa_, _pa_ ; - _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; - if (par_hang_indent>0) and (ra>0) : - par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i,t)) ; - _ll_ := ulcorner multipar ; - _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; - % we need to compensate for topskip enlarged areas - if abs(ypart _pa_ - ypart _sa_) > par_line_height : - (xpart _pa_ + par_hang_indent,ypart _sa_) -- - (xpart _pa_ + par_hang_indent,ypart _pa_) -- - fi - _pa_ - else : - (xpart llcorner multipar, ypart _sa_) - fi -enddef ; - -vardef _pmp_x_right_bottom_hang_ (expr i, t) = - pair _lr_, _sa_, _pa_ ; - _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ; - if (par_hang_indent<0) and (ra>0) : - par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i, t)) ; - _lr_ := urcorner multipar ; - _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; - % we need to compensate for topskip enlarged areas - _pa_ - if abs(ypart _pa_ - ypart _sa_) > par_line_height : - -- (xpart _pa_ + par_hang_indent,ypart _pa_) - -- (xpart _pa_ + par_hang_indent,ypart _sa_) - fi - else : - (xpart lrcorner multipar, ypart _sa_) - fi -enddef ; - -% def _pmp_test_multipar_ = -% multipar := boundingbox multipar ; -% enddef ; - - % first loop - - ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; - - if enable_multi_par_fallback and - (nxy[fpos]=RealPageNumber) and - (nxy[tpos]=RealPageNumber) and not - (InsideSomeTextArea(lxy[fpos]) and - InsideSomeTextArea(rxy[tpos])) : - - % fallback - - % multipar := - % llxy[fpos] -- - % lrxy[tpos] -- - % urxy[tpos] -- - % ulxy[fpos] -- cycle ; - % - % save_multipar (1,1,multipar) ; - - % we need to take the boundingbox because there can be - % more lines and we want a proper rectange - - multipar := - ulxy[fpos] -- - urxy[tpos] -- - lrxy[fpos] -- - llxy[tpos] -- cycle ; - - save_multipar (1,1,boundingbox(multipar)) ; - - else : - - % normal - - for i=1 upto NOfTextAreas : - - TopSkipCorrection := 0 ; - - multipar := _pmp_set_multipar_(i) ; - - % watch how we compensate for negative indentation - - if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) : - - % first one in chain - - ii := i ; - -% if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : - if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : - - % in same area - - nn := i ; - - if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : - - TopSkipCorrection := TopSkip - StrutHeight ; - - if round(ypart ulxy[fpos] + TopSkipCorrection) = - round(ypart ulcorner TextAreas[i]) : - ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ; - urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ; - else : - TopSkipCorrection := 0 ; - fi ; - - fi ; - - if ypart llxy[fpos] = ypart llxy[tpos] : - - multipar := - llxy[fpos] -- - lrxy[tpos] -- - %urxy[tpos] -- - _pmp_snapped_multi_pos_(urxy[tpos]) -- - %ulxy[fpos] -- - _pmp_snapped_multi_pos_(ulxy[fpos]) -- - cycle ; - - save_multipar (i,1,multipar) ; - - elseif (ypart llxy[fpos] = ypart ulxy[tpos]) and - (xpart llxy[tpos] < xpart llxy[fpos]) : - - % two loners - - multipar := if obey_multi_par_hang : - - _pmp_right_bottom_hang_(true) -- - _pmp_right_top_hang_(true) -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - - else : - - llxy[fpos] -- - (xpart urcorner multipar, ypart llxy[fpos]) -- - (xpart urcorner multipar, ypart ulxy[fpos]) -- - _pmp_snapped_multi_pos_(ulxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - multipar := _pmp_set_multipar_(i) ; - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(true) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - _pmp_left_top_hang_(true) -- - - else : - - (xpart llcorner multipar, ypart llxy[tpos]) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - (xpart llcorner multipar, ypart ulxy[tpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - else : - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(true) -- - llxy[tpos] -- - %ulxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - _pmp_right_bottom_hang_(true) -- - _pmp_right_top_hang_(true) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - _pmp_left_top_hang_(true) -- - - else : - - (xpart llcorner multipar, ypart llxy[tpos]) -- - llxy[tpos] -- - %ulxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - (xpart lrcorner multipar, ypart ulxy[tpos]) -- - (xpart urcorner multipar, ypart urxy[fpos]) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - fi ; - - else : - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(false) -- - _pmp_right_bottom_hang_(false) -- - _pmp_right_top_hang_(false) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - _pmp_left_top_hang_(false) -- - - else : - - llcorner multipar -- - lrcorner multipar -- - (xpart urcorner multipar, ypart urxy[fpos]) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - fi ; - -% elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : - elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : - - % last one in chain - - nn := i ; - - if obey_multi_par_hang and obey_multi_par_more : - - multipar := - _pmp_x_left_top_hang_(i,true) -- - _pmp_x_right_top_hang_(i,true) -- - _pmp_x_right_bottom_hang_(i,true) -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - llxy[tpos] -- - _pmp_x_left_bottom_hang_(i,true) -- - cycle ; - - else : - - multipar := - ulcorner multipar -- - urcorner multipar -- - (xpart lrcorner multipar, ypart urxy[tpos]) -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - llxy[tpos] -- - (xpart llcorner multipar, ypart llxy[tpos]) -- - cycle ; - - fi ; - - save_multipar (i,3,multipar) ; - - elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) : % and (NOfTextColumns>1)) : - - save_multipar (i,2,multipar) ; - - else : - % handled later - fi ; - - endfor ; - - % second loop - - if force_multi_par_chain or (ii > 1) : - - for i=ii+1 upto nn-1 : - - % rest of chain / todo : hang - -% hm, the second+ column in column sets now gets lost in a NOfTextColumns - - if (not check_multi_par_chain) or - ((nxy[fpos]RealPageNumber)) - : - - multipar := _pmp_set_multipar_(i) ; - - if obey_multi_par_hang and obey_multi_par_more : - - multipar := - _pmp_x_left_top_hang_(i,false) -- - _pmp_x_right_top_hang_(i,false) -- - _pmp_x_right_bottom_hang_(i,false) -- - _pmp_x_left_bottom_hang_(i,false) -- - cycle ; - - fi ; - - save_multipar(i,2,multipar) ; - - fi ; - - endfor ; - - fi ; - - % end of normal/fallback - -fi ; - -% if span_multi_column_pars : -% endgroup ; -% fi ; - - % potential safeguard: - - % for i=1 upto nofmultipars : - % if length p <= 4 : - % multipars[i] := boundingbox(multipars[i]) ; - % fi ; - % end ; - - % quick hack for gb: - - one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; - -enddef ; - -color boxgridcolor ; boxgridcolor := .8red ; -color boxlinecolor ; boxlinecolor := .8blue ; -color boxfillcolor ; boxfillcolor := .8white ; -numeric boxgridtype ; boxgridtype := 0 ; -numeric boxlinetype ; boxlinetype := 1 ; -numeric boxfilltype ; boxfilltype := 1 ; -numeric boxdashtype ; boxdashtype := 0 ; -pair boxgriddirection ; boxgriddirection := up ; -numeric boxgridwidth ; boxgridwidth := 1pt ; -numeric boxlinewidth ; boxlinewidth := 1pt ; -numeric boxlineradius ; boxlineradius := 0pt ; -numeric boxfilloffset ; boxfilloffset := 0pt ; -numeric boxgriddistance ; boxgriddistance := .5cm ; -numeric boxgridshift ; boxgridshift := 0pt ; - -def draw_box = - draw pxy withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; - draw lxy -- rxy withcolor boxlinecolor withpen pencircle scaled boxgridwidth ; -enddef ; - -def draw_par = % 1 2 3 11 12 - do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ; - for i = pxy, txy, bxy : - if boxgridtype = 1 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; - elseif boxgridtype = 2 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,false) withcolor boxgridcolor ; - elseif boxgridtype = 3 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; - draw baseline_grid (i,boxgriddirection,true ) - shifted (0,ExHeight) withcolor boxgridcolor ; - elseif boxgridtype = 4 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) - shifted (0,ExHeight/2) withcolor boxgridcolor ; - elseif boxgridtype = 11 : - draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; - elseif boxgridtype = 12 : - draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; - fi ; - endfor ; -enddef ; - -def do_show_par (expr p, r, c) = - if length(p) > 2 : for i=0 upto length(p) : - draw fullcircle scaled r shifted point i of p - withpen pencircle scaled .5pt withcolor c ; - endfor ; fi ; - draw p withpen pencircle scaled .5pt withcolor c ; -enddef ; - -def show_par = - if length(mxy) > 2 : - draw mxy dashed evenly - withpen pencircle scaled .5pt withcolor .5white ; - fi ; - do_show_par(txy, 4pt, .5green) ; - do_show_par(bxy, 6pt, .5blue ) ; - do_show_par(pxy, 8pt, .5red ) ; - draw pref withpen pencircle scaled 2pt ; -enddef ; - -def sort_multi_pars = - if nofmultipars>1 : - begingroup ; save _p_, _n_ ; path _p_ ; numeric _n_ ; - for i := 1 upto nofmultipars : - if multilocs[i] = 3 : - _p_ := multipars[nofmultipars] ; - multipars[nofmultipars] := multipars[i] ; - multipars[i] := _p_ ; - _n_ := multirefs[nofmultipars] ; - multirefs[nofmultipars] := multirefs[i] ; - multirefs[i] := _n_ ; - _n_ := multilocs[nofmultipars] ; - multilocs[nofmultipars] := multilocs[i] ; - multilocs[i] := _n_ ; - fi ; - endfor ; - endgroup ; - fi ; -enddef ; - - -def collapse_multi_pars = - if nofmultipars>1 : - begingroup ; save _nofmultipars_ ; numeric _nofmultipars_ ; - _nofmultipars_ := 1 ; - sort_multi_pars ; % block not in order: 1, 3, 2.... - for i:=1 upto nofmultipars-1 : - if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and - (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : -multilocs[_nofmultipars_] := multilocs[i+1] ; -multirefs[_nofmultipars_] := multirefs[i+1] ; - multipars[_nofmultipars_] := - ulcorner multipars[_nofmultipars_] -- - urcorner multipars[_nofmultipars_] -- - lrcorner multipars[i+1] -- - llcorner multipars[i+1] -- cycle ; - else : - _nofmultipars_ := _nofmultipars_ + 1 ; - multipars[_nofmultipars_] := multipars[i+1] ; - multilocs[_nofmultipars_] := multilocs[i+1] ; - multirefs[_nofmultipars_] := multirefs[i+1] ; - fi ; - endfor ; - nofmultipars := _nofmultipars_ ; - endgroup ; - fi ; -enddef ; - -% def draw_multi_pars = -% for i=1 upto nofmultipars : -% do_draw_par(multipars[i]) ; -% if boxgridtype= 1 : -% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; -% elseif boxgridtype= 2 : -% draw baseline_grid (multipars[i],up,false) ; % withcolor boxgridcolor ; -% elseif boxgridtype= 3 : -% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; -% draw baseline_grid (multipars[i],up,true ) -% shifted (0,ExHeight) ; % withcolor boxgridcolor ; -% elseif boxgridtype= 4 : -% draw baseline_grid (multipars[i],up,true ) -% shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; -% elseif boxgridtype=11 : -% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; -% elseif boxgridtype=12 : -% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; -% fi ; -% endfor ; -% enddef ; - -def draw_multi_pars = - for i=1 upto nofmultipars : - do_draw_par(multipars[i]) ; - if boxgridtype= 1 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; - elseif boxgridtype= 2 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; % withcolor boxgridcolor ; - elseif boxgridtype= 3 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; % withcolor boxgridcolor ; - elseif boxgridtype= 4 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; - elseif boxgridtype=11 : - draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; - elseif boxgridtype=12 : - draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; - fi ; - endfor ; -enddef ; - -def show_multi_pars = - for i=1 upto nofmultipars : - do_show_par(multipars[i], 6pt, .5blue) ; - endfor ; -enddef ; - -vardef do_draw_par (expr p) = - if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : - save pp ; path pp ; - if (boxlineradius>0) and (boxlinetype=2) : - pp := p cornered boxlineradius ; - else : - pp := p ; - fi ; - if boxfilltype>0 : - if boxfilloffset>0 : - % temporary hack - begingroup ; interim linejoin := mitered ; - filldraw pp withcolor boxfillcolor withpen pencircle scaled (2*boxfilloffset) ; - endgroup ; - else : - fill pp withcolor boxfillcolor ; - fi ; - fi ; - if boxlinetype>0 : - draw pp withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; - fi ; - fi ; -enddef ; - -vardef baseline_grid (expr pxy, pdir, at_baseline) = - if (par_line_height>0) and (bbheight(pxy)>1) and (bbwidth(pxy)>1) and (boxgridwidth>0) : - save i, grid, bb ; picture grid ; pair start ; path bb ; - def _do_ (expr start) = - % 1 = normal, 2 = with background (i.e. no shine-through) - if boxdashtype = 2 : - draw start -- start shifted (bbwidth(pxy),0) - withpen pencircle scaled boxgridwidth - withcolor boxfillcolor ; - fi ; - draw start -- start shifted (bbwidth(pxy),0) - if boxdashtype > 0 : dashed evenly fi - withpen pencircle scaled boxgridwidth - withcolor boxgridcolor ; - enddef ; - grid := image - ( %fails with inlinespace - % - if pdir=up : - for i = if at_baseline : par_strut_depth else : 0 fi - step par_line_height - until max(bbheight(pxy),par_line_height) : - _do_ (llcorner pxy shifted (0,+i)) ; - endfor ; - else : - for i = if at_baseline : par_strut_height else : 0 fi - step par_line_height - until bbheight(pxy) : - _do_ (ulcorner pxy shifted (0,-i)) ; - endfor ; - fi ; - ) ; - clip grid to pxy ; - bb := boundingbox grid ; - grid := grid shifted (0,boxgridshift) ; - setbounds grid to bb ; - grid - else : - nullpicture - fi -enddef ; - -vardef graphic_grid (expr pxy, dx, dy, x, y) = - if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : - save grid ; picture grid ; - grid := image - ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy : - draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) - withpen pencircle scaled boxgridwidth ; - endfor ; - for i = ypart llcorner pxy step dy until ypart ulcorner pxy : - draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) - withpen pencircle scaled boxgridwidth ; - endfor ) shifted (x,y) ; - clip grid to pxy ; - grid - else : - nullpicture - fi -enddef ; - -def anchor_box (expr n,x,y,w,h,d) = - currentpicture := currentpicture shifted (-x,-y) ; -enddef ; - -let draw_area = draw_box ; -let anchor_area = anchor_box ; -let anchor_par = anchor_box ; - - -numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; -pair sync_xy[][] ; color sync_c[][] ; - -def ResetSyncTasks = - path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; - NOfSyncPaths := CurrentSyncClass := 0 ; - if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; - if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; - if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; - if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; - if (SyncLeftOffset = 0) and (SyncWidth = 0) : - SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; - fi ; -enddef ; - -ResetSyncTasks ; - -vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = - save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; - o shifted (leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,bottomoffset) -- - o shifted (leftoffset,bottomoffset) -- cycle -enddef ; - -def SetSyncColor(expr n, i, c) = - sync_c[n][i] := c ; -enddef ; - -def SetSyncThreshold(expr n, i, th) = - sync_th[n][i] := th ; -enddef ; - -vardef TheSyncColor(expr n, i) = - if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi -enddef ; - -vardef TheSyncThreshold(expr n, i) = - if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi -enddef ; - -vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = - ResetSyncTasks ; - if known sync_n[n] : - CurrentSyncClass := n ; - save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; - for i=1 upto sync_n[n] : - if RealPageNumber > sync_p[n][i] : - l := i ; - elseif RealPageNumber = sync_p[n][i] : - NOfSyncPaths := NOfSyncPaths + 1 ; - if not ok : - if i>1 : - if sync_t[n][i-1] = sync_t[n][i] : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i-1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - ok := true ; - fi ; - endfor ; - if (NOfSyncPaths = 0) and (l > 0) : - NOfSyncPaths := 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := l ; - fi ; - if NOfSyncPaths > 0 : - for i = 1 upto NOfSyncPaths-1 : - SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; - endfor ; - if unknown SyncThresholdMethod : - numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; - fi ; - if extendtop : - if SyncThresholdMethod = 1 : - if NOfSyncPaths>1 : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; - if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : - SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; - fi ; - fi ; - else : - for i = 1 upto NOfSyncPaths : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; - if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : - SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; - fi ; - endfor ; - fi ; - fi ; - if prestartnext : - if NOfSyncPaths>1 : - if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; - if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : - SyncPaths[NOfSyncPaths+1] := - (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - lrcorner SyncPaths[NOfSyncPaths] -- - llcorner SyncPaths[NOfSyncPaths] -- cycle ; - SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - fi ; - fi ; - fi ; - else : - if NOfSyncPaths>1 : - d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; - if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : - NOfSyncPaths := NOfSyncPaths - 1 ; - SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; - fi ; - fi ; - fi ; - if (NOfSyncPaths>1) and collapse : - save j ; numeric j ; j := 1 ; - for i = 2 upto NOfSyncPaths : - if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : - SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; - SyncTasks[j] := SyncTasks[i] ; - else : - j := j + 1 ; - SyncPaths[j] := SyncPaths[i] ; - SyncTasks[j] := SyncTasks[i] ; - fi ; - endfor ; - NOfSyncPaths := j ; - fi ; - fi ; - fi ; -enddef ; - -def SyncTask(expr n) = - if known SyncTasks[n] : SyncTasks[n] else : 0 fi -enddef ; - -def FlushSyncTasks = - for i = 1 upto NOfSyncPaths : - ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; - endfor ; -enddef ; - -def ProcessSyncTask(expr p, c) = - fill p withcolor c ; -enddef ; - -% for Jelle Huisman -% -% \setupcolors[state=start] -% \dontcomplain -% \definecolumnset[example][n=3,distance=5mm] -% \startMPextensions -% multi_column_first_page_hack := true ; -% \stopMPextensions -% \startuseMPgraphic{mpos:par:trick} -% for i=1 upto nofmultipars-1 : draw (rightboundary multipars[i]) shifted (2.5mm, 0) ; endfor ; -% \stopuseMPgraphic -% \definetextbackground[test][mp=mpos:par:trick,method=mpos:par:columnset] -% \starttext -% \definecolumnsetspan[chapter][n=3] -% \startcolumnset[example] -% \startcolumnsetspan[chapter] -% \chapter{Chapter One} -% \stopcolumnsetspan -% \starttextbackground[test] \dorecurse {3}{\input knuth } \stoptextbackground -% \stopcolumnset -% \startcolumnset[example] -% \startcolumnsetspan[chapter] -% \chapter{Chapter One} -% \stopcolumnsetspan -% \starttextbackground[test] \dorecurse {10}{\input knuth } \stoptextbackground -% \stopcolumnset -% \stoptext -% -% fast variant: -% -% \startuseMPgraphic{whatever} -% for i=1 upto NOfTextColumns-1 : -% draw (rightboundary TextColumns[i]) shifted (2.5mm,0) shifted -\MPxy\textanchor ; -% endfor ; -% setbounds currentpicture to OverlayBox ; -% \stopuseMPgraphic -% \defineoverlay[whatever][\useMPgraphic{whatever}] -% \setupbackgrounds[text][background=whatever] diff --git a/metapost/context/base/mp-core.mpiv b/metapost/context/base/mp-core.mpiv deleted file mode 100644 index 9b7182908..000000000 --- a/metapost/context/base/mp-core.mpiv +++ /dev/null @@ -1,1561 +0,0 @@ -%D \module -%D [ file=mp-core.mpiv, -%D version=1999.08.01, % anchoring -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=background macros, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -if known context_core : endinput ; fi ; - -boolean context_core ; context_core := true ; - -%D Copied to here .. not used any more. - -if unknown NOfTextColumns : numeric NOfTextColumns ; NOfTextColumns := 1 ; fi ; -if unknown NOfTextAreas : numeric NOfTextAreas ; NOfTextAreas := 1 ; fi ; - -def SaveTextAreas = - path SavedTextAreas [] ; - path SavedTextColumns[] ; - numeric NOfSavedTextAreas ; - numeric NOfSavedTextColumns ; - for i=1 upto NOfTextAreas : - SavedTextAreas[i] := TextAreas[i] ; - endfor ; - for i=1 upto NOfTextColumns : - SavedTextColumns[i] := TextColumns[i] ; - endfor ; - NOfSavedTextAreas := NOfTextAreas ; - NOfSavedTextColumns := NOfTextColumns ; -enddef ; - -def ResetTextAreas = - path TextAreas[], TextColumns[], PlainTextArea, RegionTextArea ; - numeric NOfTextAreas ; NOfTextAreas := 0 ; - numeric NOfTextColumns ; NOfTextColumns := 0 ; - numeric nofmultipars ; nofmultipars := 0 ; - TextAreas[0] := TextColumns[0] := origin -- cycle ; -enddef ; - -ResetTextAreas ; SaveTextAreas ; ; - -def RegisterTextArea (expr x, y, w, h, d) = - begingroup ; - save p ; path p ; - p := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; - if NOfTextAreas>0 : - % if needed, concatenate areas - if (round(llcorner TextAreas[NOfTextAreas]) = round(ulcorner p)) and - (round(lrcorner TextAreas[NOfTextAreas]) = round(urcorner p)) : - p := - ulcorner TextAreas[NOfTextAreas] -- - urcorner TextAreas[NOfTextAreas] -- - lrcorner p -- - llcorner p -- cycle ; - else : - NOfTextAreas := NOfTextAreas + 1 ; - fi ; - else : - NOfTextAreas := NOfTextAreas + 1 ; - fi ; - TextAreas[NOfTextAreas] := p ; - if NOfTextColumns>0 : - if (round(xpart llcorner TextColumns[NOfTextColumns]) = round(xpart ulcorner p)) and - (round(xpart lrcorner TextColumns[NOfTextColumns]) = round(xpart urcorner p)) : - p := - ulcorner TextColumns[NOfTextColumns] -- - urcorner TextColumns[NOfTextColumns] -- - lrcorner p -- - llcorner p -- cycle ; - else : - NOfTextColumns := NOfTextColumns + 1 ; - fi ; - else : - NOfTextColumns := NOfTextColumns + 1 ; - fi ; - TextColumns[NOfTextColumns] := p ; - endgroup ; -enddef ; - -%D We store a local area in slot zero. - -def RegisterPlainTextArea(expr x,y,w,h,d) = - PlainTextArea := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; -enddef ; - -def RegisterRegionTextArea(expr x,y,w,h,d) = - RegionTextArea := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; - % RegionTextArea := RegionTextArea enlarged 2mm ; -enddef ; - -def RegisterLocalTextArea (expr x, y, w, h, d) = - TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; -enddef ; - -def ResetLocalTextArea = - TextAreas[0] := TextColumns[0] := origin -- cycle ; -enddef ; - -ResetLocalTextArea ; - -vardef InsideTextArea (expr _i_, _xy_) = - (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and - (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and - (round(ypart _xy_) >= round(ypart llcorner TextAreas[_i_])) and - (round(ypart _xy_) <= round(ypart urcorner TextAreas[_i_])) -enddef ; - -vardef InsideSavedTextArea (expr _i_, _xy_) = - (round(xpart _xy_) >= round(xpart llcorner SavedTextAreas[_i_])) and - (round(xpart _xy_) <= round(xpart lrcorner SavedTextAreas[_i_])) and - (round(ypart _xy_) >= round(ypart llcorner SavedTextAreas[_i_])) and - (round(ypart _xy_) <= round(ypart urcorner SavedTextAreas[_i_])) -enddef ; - -vardef InsideSomeTextArea (expr _xy_) = - save ok ; boolean ok ; ok := false ; - for i := 1 upto NOfTextAreas : - if InsideTextArea(i,_xy_) : - ok := true ; % we can move the exit here - fi ; - exitif ok ; - endfor ; - ok -enddef ; - -vardef InsideSomeSavedTextArea (expr _xy_) = - save ok ; boolean ok ; ok := false ; - for i := 1 upto NOfSavedTextAreas : - if InsideSavedTextArea(i,_xy_) : - ok := true ; - fi ; - exitif ok ; - endfor ; - ok -enddef ; - -vardef TextAreaX (expr x) = - numeric _TextAreaX_ ; _TextAreaX_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) : - _TextAreaX_ := xpart llcorner TextAreas[i] ; - fi ; - endfor ; - _TextAreaX_ -enddef ; - -vardef TextAreaY (expr y) = - numeric _TextAreaY_ ; _TextAreaY_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(y) >= round(ypart llcorner TextAreas[NOfTextAreas])) and - (round(y) <= round(ypart ulcorner TextAreas[NOfTextAreas])) : - _TextAreaY_ := ypart llcorner TextAreas[NOfTextAreas] ; - fi ; - endfor ; - _TextAreaY_ -enddef ; - -vardef TextAreaXY (expr x, y) = - pair _TextAreaXY_ ; _TextAreaXY_ := origin ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) and - (round(y) >= round(ypart llcorner TextAreas[i])) and - (round(y) <= round(ypart ulcorner TextAreas[i])) : - _TextAreaXY_ := llconer TextAreas[i] ; - fi ; - endfor ; - _TextAreaXY_ -enddef ; - -vardef TextAreaW (expr x) = - numeric _TextAreaW_ ; _TextAreaW_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) : - _TextAreaW_ := bbwidth(TextAreas[i]) ; - fi ; - endfor ; - _TextAreaW_ -enddef ; - -vardef TextAreaH (expr y) = - numeric _TextAreaH_ ; _TextAreaH_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(y) >= round(ypart llcorner TextAreas[i])) and - (round(y) <= round(ypart ulcorner TextAreas[i])) : - _TextAreaH_ := bbheight(TextAreas[i]) ; - fi ; - endfor ; - _TextAreaH_ -enddef ; - -vardef TextAreaWH (expr x, y) = - pair _TextAreaWH_ ; _TextAreaWH_ := origin ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) and - (round(y) >= round(ypart llcorner TextAreas[i])) and - (round(y) <= round(ypart ulcorner TextAreas[i])) : - _TextAreaWH_ := (bbwidth(TextAreas[i]),bbheight(TextAreas[i])) ; - fi ; - endfor ; - _TextAreaWH_ -enddef ; - -%D Till here. - -pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; -path pxy[] ; -numeric hxy[], wxy[], dxy[], nxy[] ; - -def box_found (expr n,x,y,w,h,d) = - not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) -enddef ; - -def initialize_box_pos (expr pos,n,x,y,w,h,d) = - pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; - path pxy ; numeric hxy, wxy, dxy, nxy; - lxy := (x,y) ; - llxy := (x,y-d) ; - lrxy := (x+w,y-d) ; - urxy := (x+w,y+h) ; - ulxy := (x,y+h) ; - wxy := w ; - hxy := h ; - dxy := d ; - rxy := lxy shifted (wxy,0) ; - pxy := llxy--lrxy--urxy--ulxy--cycle ; - cxy := center pxy ; - nxy := n ; - freeze_box(pos) ; -enddef ; - -def freeze_box (expr pos) = - lxy[pos] := lxy ; - llxy[pos] := llxy ; - lrxy[pos] := lrxy ; - urxy[pos] := urxy ; - ulxy[pos] := ulxy ; - wxy[pos] := wxy ; - hxy[pos] := hxy ; - dxy[pos] := dxy ; - rxy[pos] := rxy ; - pxy[pos] := pxy ; - cxy[pos] := cxy ; - nxy[pos] := nxy ; -enddef ; - -def initialize_box (expr n,x,y,w,h,d) = - numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; -enddef ; - -def initialize_area (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td) = - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - do_initialize_area (fpos, tpos) ; -enddef ; - -def do_initialize_area (expr fpos, tpos) = - lxy := lxy[fpos] ; - llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; - lrxy := lrxy[tpos] ; - urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; - ulxy := ulxy[fpos] ; - wxy := xpart lrxy - xpart llxy ; - hxy := hxy[fpos] ; - dxy := dxy[tpos] ; - rxy := lxy shifted (wxy,0) ; - pxy := llxy--lrxy--urxy--ulxy--cycle ; - cxy := center pxy ; -enddef ; - -def set_par_line_height (expr ph, pd) = - par_strut_height := if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ; - par_strut_depth := if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ; - par_line_height := par_strut_height + par_strut_depth ; -enddef ; - -def initialize_par (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td, - mn,mx,my,mw,mh,md, - pn,px,py,pw,ph,pd, - rw,rl,rr,rh,ra,ri) = - - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; - numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; - - numeric par_strut_height, par_strut_depth, par_line_height ; - - set_par_line_height (ph, pd) ; - - do_initialize_area (fpos, tpos) ; - do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; - -enddef ; - -def initialize_area_par (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td, - wn,wx,wy,ww,wh,wd) = - - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ; - - numeric par_strut_height, par_strut_depth, par_line_height ; - - set_par_line_height (wh, wd) ; - - numeric ffpos ; ffpos := 4 ; initialize_box_pos(ffpos,wn,wx,fy,0,wh,wd) ; - numeric ttpos ; ttpos := 5 ; initialize_box_pos(ttpos,wn,wx+ww,ty,0,wh,wd) ; - - do_initialize_area (ffpos, ttpos) ; - - numeric mpos ; mpos := 6 ; freeze_box(mpos) ; - - do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; - -enddef ; - -def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = - - pair lref, rref, pref, lhref, rhref ; - - % clip the page area to the left and right skips - - llxy[mpos] := llxy[mpos] shifted (+rl,0) ; - lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; - urxy[mpos] := urxy[mpos] shifted (-rr,0) ; - ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; - - % fixate the leftskip, rightskip and hanging indentation - - lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; - rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; - - pref := lxy[ppos] ; - - if nxy[tpos] > nxy[fpos] : - if nxy[fpos] = nxy[mpos] : - % first of multiple pages - llxy[tpos] := llxy[mpos] ; - lrxy[tpos] := lrxy[mpos] ; - urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; - ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; - boxgriddirection := down ; - elseif nxy[tpos] = nxy[mpos] : - % last of multiple pages - llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; - lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; - urxy[fpos] := urxy[mpos] ; - ulxy[fpos] := ulxy[mpos] ; - boxgriddirection := up ; - else : - % middle of multiple pages - llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; - lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; - urxy[fpos] := urxy[mpos] ; - ulxy[fpos] := ulxy[mpos] ; - llxy[tpos] := llxy[mpos] ; - lrxy[tpos] := lrxy[mpos] ; - urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; - ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; - boxgriddirection := up ; - fi ; - else : - % just one page - boxgriddirection := up ; - fi ; - - path txy, bxy, pxy, mxy ; - - txy := originpath ; % top - bxy := originpath ; % bottom - pxy := originpath ; % composed - - boolean lefthang, righthang, somehang ; - - % we only hang on the first of a multiple page background - - if nxy[mpos] > nxy[fpos] : - lefthang := righthang := somehang := false ; - else : - lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; - fi ; - - if lefthang : - mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; - elseif righthang : - mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; - else : - mxy := originpath ; - fi ; - - if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : - - % We have a one-liner. Watch how er use the bottom pos for - % determining the height. - - llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; - ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; - - else : - - % We have a multi-liner. For convenience we now correct the - % begin and end points for indentation. - - if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : - llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; - ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; - else : - llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; - ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; - fi ; - - if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : - lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; - urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; - else : - lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; - urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; - fi ; - - fi ; - - somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and - (ypart llxy[tpos]0 : - left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; - right_skip := rw - left_skip - ww ; - else : - left_skip := rl ; - right_skip := rr ; - fi ; - - path multipar, multipars[] ; - numeric multiref, multirefs[] ; - numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end - - numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; - - % locals .. why can't i move these outside? - - vardef _pmp_set_multipar_ (expr i) = - ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip - if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) - enddef ; - - vardef _pmp_snapped_multi_pos_ (expr p) = - if snap_multi_par_tops : - if abs(ypart p - ypart ulcorner multipar) < par_line_height : - (xpart p,ypart ulcorner multipar) - else : - p - fi - else : - p - fi - enddef ; - - vardef _pmp_estimated_par_lines_ (expr h) = - round(h/par_line_height) - enddef ; - - vardef _pmp_top_multi_par_(expr p) = - (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p))) - enddef ; - - vardef _pmp_multi_par_tsc_(expr p) = - if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi - enddef ; - - vardef _pmp_estimated_multi_par_height_ (expr n, t) = - if round(par_line_height)=0 : - 0 - else : - save ok, h ; boolean ok ; - numeric h ; h := 0 ; - ok := false ; - if (nxy[fpos]=RealPageNumber-1) : - for i := 1 upto NOfSavedTextAreas : - if (InsideSavedTextArea(i,par_start_pos)) : - ok := true ; - h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner SavedTextAreas[i]) ; - elseif ok : - h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ; - fi ; - endfor ; - fi ; - if ok : - for i := 1 upto n-1 : - h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; - endfor ; - else : - % already: ok := false ; - for i := 1 upto n-1 : - if (InsideTextArea(i,par_start_pos)) : - ok := true ; - h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; - elseif ok : - h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; - fi ; - endfor ; - fi ; - h - fi - enddef ; - - vardef _pmp_left_top_hang_ (expr same_area) = - - par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; - - if (par_hang_indent>0) and (par_hang_after<0) and obey_multi_par_hang : - pair _ul_ ; _ul_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])); - pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llxy[tpos])) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := min(0,round(par_hang_after + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - (xpart _ul_ + par_hang_indent, ypart lrxy[fpos]) -- - (xpart _ul_ + par_hang_indent, ypart _pa_) -- - (xpart ulcorner multipar, ypart _pa_) - else : - (xpart ulcorner multipar, ypart lrxy[fpos]) - fi - enddef ; - - vardef _pmp_right_top_hang_ (expr same_area) = - - par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; - - if (par_hang_indent<0) and (par_hang_after<0) and obey_multi_par_hang : - pair _ur_ ; _ur_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; - pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := min(0,round(par_hang_after + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - (xpart urcorner multipar, ypart _pa_) -- - (xpart _ur_ + par_hang_indent, ypart _pa_) -- - (xpart _ur_ + par_hang_indent, ypart _pmp_snapped_multi_pos_(urxy[fpos])) - else : - (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) - fi - enddef ; - - vardef _pmp_x_left_top_hang_ (expr i, t) = - par_hang_after := min(0,ra + _pmp_estimated_multi_par_height_(i,t)) ; - if (par_hang_indent>0) and (par_hang_after<0) : - pair _ul_ ; _ul_ := ulcorner multipar ; - pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; - if t : - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos])); - fi ; - if abs(ypart _pa_-ypart llxy[tpos])0) and (par_hang_after>0) and obey_multi_par_hang : - _ll_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])) ; - _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := max(0,round(par_hang_after - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - _pa_ -- - (xpart _pa_ + par_hang_indent,ypart _pa_) -- - (xpart _pa_ + par_hang_indent,ypart _sa_) - else : - (xpart llcorner multipar, ypart _sa_) - fi - enddef ; - - vardef _pmp_right_bottom_hang_ (expr same_area) = - pair _lr_, _sa_, _pa_ ; - _sa_ := if same_area : _pmp_snapped_multi_pos_(ulxy[tpos]) else : lrcorner multipar fi ; - if (par_hang_indent<0) and (par_hang_after>0) and obey_multi_par_hang : - _lr_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; - _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; - if same_area : - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; - fi ; - if obey_multi_par_more and (round(par_line_height)>0) : - par_hang_after := max(0,round(par_hang_after - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; - fi ; - (xpart _pa_ + par_hang_indent,ypart _sa_) -- - (xpart _pa_ + par_hang_indent,ypart _pa_) -- - _pa_ - else : - (xpart lrcorner multipar, ypart _sa_) - fi - enddef ; - - vardef _pmp_x_left_bottom_hang_ (expr i, t) = - pair _ll_, _sa_, _pa_ ; - _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; - if (par_hang_indent>0) and (ra>0) : - par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i,t)) ; - _ll_ := ulcorner multipar ; - _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; - % we need to compensate for topskip enlarged areas - if abs(ypart _pa_ - ypart _sa_) > par_line_height : - (xpart _pa_ + par_hang_indent,ypart _sa_) -- - (xpart _pa_ + par_hang_indent,ypart _pa_) -- - fi - _pa_ - else : - (xpart llcorner multipar, ypart _sa_) - fi - enddef ; - - vardef _pmp_x_right_bottom_hang_ (expr i, t) = - pair _lr_, _sa_, _pa_ ; - _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ; - if (par_hang_indent<0) and (ra>0) : - par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i, t)) ; - _lr_ := urcorner multipar ; - _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; - _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; - % we need to compensate for topskip enlarged areas - _pa_ - if abs(ypart _pa_ - ypart _sa_) > par_line_height : - -- (xpart _pa_ + par_hang_indent,ypart _pa_) - -- (xpart _pa_ + par_hang_indent,ypart _sa_) - fi - else : - (xpart lrcorner multipar, ypart _sa_) - fi - enddef ; - - % def _pmp_test_multipar_ = - % multipar := boundingbox multipar ; - % enddef ; - - % first loop - - ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; - - if enable_multi_par_fallback and (nxy[fpos]=RealPageNumber) - and (nxy[tpos]=RealPageNumber) and not (InsideSomeTextArea(lxy[fpos]) and InsideSomeTextArea(rxy[tpos])) : - - % fallback - - % multipar := - % llxy[fpos] -- - % lrxy[tpos] -- - % urxy[tpos] -- - % ulxy[fpos] -- cycle ; - % - % save_multipar (1,1,multipar) ; - - % we need to take the boundingbox because there can be - % more lines and we want a proper rectange - - multipar := - ulxy[fpos] -- - urxy[tpos] -- - lrxy[fpos] -- - llxy[tpos] -- cycle ; - - save_multipar (1,1,boundingbox(multipar)) ; - - else : - - % normal - - for i=1 upto NOfTextAreas : - - TopSkipCorrection := 0 ; - - multipar := _pmp_set_multipar_(i) ; - - % watch how we compensate for negative indentation - - if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) : - - % first one in chain - - ii := i ; - - if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : - - % in same area - - nn := i ; - - if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : - - TopSkipCorrection := TopSkip - StrutHeight ; - - if round(ypart ulxy[fpos] + TopSkipCorrection) = round(ypart ulcorner TextAreas[i]) : - ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ; - urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ; - else : - TopSkipCorrection := 0 ; - fi ; - - fi ; - - if ypart llxy[fpos] = ypart llxy[tpos] : - - multipar := - llxy[fpos] -- - lrxy[tpos] -- - _pmp_snapped_multi_pos_(urxy[tpos]) -- - _pmp_snapped_multi_pos_(ulxy[fpos]) -- - cycle ; - - save_multipar (i,1,multipar) ; - - elseif (ypart llxy[fpos] = ypart ulxy[tpos]) and (xpart llxy[tpos] < xpart llxy[fpos]) : - - % two loners - - multipar := if obey_multi_par_hang : - - _pmp_right_bottom_hang_(true) -- - _pmp_right_top_hang_(true) -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - - else : - - llxy[fpos] -- - (xpart urcorner multipar, ypart llxy[fpos]) -- - (xpart urcorner multipar, ypart ulxy[fpos]) -- - _pmp_snapped_multi_pos_(ulxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - multipar := _pmp_set_multipar_(i) ; - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(true) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - _pmp_left_top_hang_(true) -- - - else : - - (xpart llcorner multipar, ypart llxy[tpos]) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - (xpart llcorner multipar, ypart ulxy[tpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - else : - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(true) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - _pmp_right_bottom_hang_(true) -- - _pmp_right_top_hang_(true) -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - _pmp_left_top_hang_(true) -- - - else : - - (xpart llcorner multipar, ypart llxy[tpos]) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - (xpart lrcorner multipar, ypart ulxy[tpos]) -- - (xpart urcorner multipar, ypart urxy[fpos]) -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - fi ; - - else : - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(false) -- - _pmp_right_bottom_hang_(false) -- - _pmp_right_top_hang_(false) -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - _pmp_left_top_hang_(false) -- - - else : - - llcorner multipar -- - lrcorner multipar -- - (xpart urcorner multipar, ypart urxy[fpos]) -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - fi ; - - elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : - - % last one in chain - - nn := i ; - - if obey_multi_par_hang and obey_multi_par_more : - - multipar := - _pmp_x_left_top_hang_(i,true) -- - _pmp_x_right_top_hang_(i,true) -- - _pmp_x_right_bottom_hang_(i,true) -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - llxy[tpos] -- - _pmp_x_left_bottom_hang_(i,true) -- - cycle ; - - else : - - multipar := - ulcorner multipar -- - urcorner multipar -- - (xpart lrcorner multipar, ypart urxy[tpos]) -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - llxy[tpos] -- - (xpart llcorner multipar, ypart llxy[tpos]) -- - cycle ; - - fi ; - - save_multipar (i,3,multipar) ; - - elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) and (NOfTextColumns>1)) : - - save_multipar (i,2,multipar) ; - - else : - % handled later - fi ; - - endfor ; - - - % second loop - - if force_multi_par_chain or (ii > 1) : - - for i=ii+1 upto nn-1 : - - % rest of chain / todo : hang - - % hm, the second+ column in column sets now gets lost in a NOfTextColumns - - if (not check_multi_par_chain) or ((nxy[fpos]RealPageNumber)) : - - multipar := _pmp_set_multipar_(i) ; - - if obey_multi_par_hang and obey_multi_par_more : - - multipar := - _pmp_x_left_top_hang_(i,false) -- - _pmp_x_right_top_hang_(i,false) -- - _pmp_x_right_bottom_hang_(i,false) -- - _pmp_x_left_bottom_hang_(i,false) -- - cycle ; - - fi ; - - save_multipar(i,2,multipar) ; - - fi ; - - endfor ; - - fi ; - - % end of normal/fallback - - fi ; - - if span_multi_column_pars : - endgroup ; - fi ; - - % potential safeguard: - - % for i=1 upto nofmultipars : - % if length p <= 4 : - % multipars[i] := boundingbox(multipars[i]) ; - % fi ; - % end ; - - % quick hack for gb: - - one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; - -enddef ; - -def boxgridoptions = withcolor .8red enddef ; -def boxlineoptions = withcolor .8blue enddef ; -def boxfilloptions = withcolor .8white enddef ; - -numeric boxgridtype ; boxgridtype := 0 ; -numeric boxlinetype ; boxlinetype := 1 ; -numeric boxfilltype ; boxfilltype := 1 ; -numeric boxdashtype ; boxdashtype := 0 ; -pair boxgriddirection ; boxgriddirection := up ; -numeric boxgridwidth ; boxgridwidth := 1pt ; -numeric boxlinewidth ; boxlinewidth := 1pt ; -numeric boxlineradius ; boxlineradius := 0pt ; -numeric boxfilloffset ; boxfilloffset := 0pt ; -numeric boxgriddistance ; boxgriddistance := .5cm ; -numeric boxgridshift ; boxgridshift := 0pt ; - -def draw_box = - draw pxy boxlineoptions withpen pencircle scaled boxlinewidth ; - draw lxy -- rxy boxlineoptions withpen pencircle scaled boxgridwidth ; -enddef ; - -def draw_par = % 1 2 3 11 12 - do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ; - for i = pxy, txy, bxy : - if boxgridtype = 1 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) boxgridoptions ; - elseif boxgridtype = 2 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,false) boxgridoptions ; - elseif boxgridtype = 3 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) boxgridoptions ; - draw baseline_grid (i,boxgriddirection,true ) shifted (0,ExHeight) boxgridoptions ; - elseif boxgridtype = 4 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) shifted (0,ExHeight/2) boxgridoptions ; - elseif boxgridtype = 11 : - draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; - elseif boxgridtype = 12 : - draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; - fi ; - endfor ; -enddef ; - -def do_show_par (expr p, r, c) = - if length(p) > 2 : - for i=0 upto length(p) : - draw fullcircle scaled r shifted point i of p withpen pencircle scaled .5pt withcolor c ; - endfor ; - fi ; - draw p withpen pencircle scaled .5pt withcolor c ; -enddef ; - -def show_par = - if length(mxy) > 2 : - draw mxy dashed evenly withpen pencircle scaled .5pt withcolor .5white ; - fi ; - do_show_par(txy, 4pt, .5green) ; - do_show_par(bxy, 6pt, .5blue ) ; - do_show_par(pxy, 8pt, .5red ) ; - draw pref withpen pencircle scaled 2pt ; -enddef ; - -def sort_multi_pars = - if nofmultipars>1 : - begingroup ; - save _p_, _n_ ; path _p_ ; numeric _n_ ; - for i := 1 upto nofmultipars : - if multilocs[i] = 3 : - _p_ := multipars[nofmultipars] ; - multipars[nofmultipars] := multipars[i] ; - multipars[i] := _p_ ; - _n_ := multirefs[nofmultipars] ; - multirefs[nofmultipars] := multirefs[i] ; - multirefs[i] := _n_ ; - _n_ := multilocs[nofmultipars] ; - multilocs[nofmultipars] := multilocs[i] ; - multilocs[i] := _n_ ; - fi ; - endfor ; - endgroup ; - fi ; -enddef ; - -def collapse_multi_pars = - if nofmultipars>1 : - begingroup ; - save _nofmultipars_ ; numeric _nofmultipars_ ; - _nofmultipars_ := 1 ; - sort_multi_pars ; % block not in order: 1, 3, 2.... - for i:=1 upto nofmultipars-1 : - if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and - (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : - multilocs[_nofmultipars_] := multilocs[i+1] ; - multirefs[_nofmultipars_] := multirefs[i+1] ; - multipars[_nofmultipars_] := - ulcorner multipars[_nofmultipars_] -- - urcorner multipars[_nofmultipars_] -- - lrcorner multipars[i+1] -- - llcorner multipars[i+1] -- cycle ; - else : - _nofmultipars_ := _nofmultipars_ + 1 ; - multipars[_nofmultipars_] := multipars[i+1] ; - multilocs[_nofmultipars_] := multilocs[i+1] ; - multirefs[_nofmultipars_] := multirefs[i+1] ; - fi ; - endfor ; - nofmultipars := _nofmultipars_ ; - endgroup ; - fi ; -enddef ; - -def draw_multi_pars = - for i=1 upto nofmultipars : - do_draw_par(multipars[i]) ; - if boxgridtype= 1 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; - elseif boxgridtype= 2 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; - elseif boxgridtype= 3 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; - elseif boxgridtype= 4 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; - elseif boxgridtype=11 : - draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; - elseif boxgridtype=12 : - draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; - fi ; - endfor ; -enddef ; - -def show_multi_pars = - for i=1 upto nofmultipars : - do_show_par(multipars[i], 6pt, .5blue) ; - endfor ; -enddef ; - -vardef do_draw_par (expr p) = - if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : - save pp ; path pp ; - if (boxlineradius>0) and (boxlinetype=2) : - pp := p cornered boxlineradius ; - else : - pp := p ; - fi ; - if boxfilltype>0 : - if boxfilloffset>0 : - % temporary hack - begingroup ; - interim linejoin := mitered ; - filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ; - endgroup ; - else : - fill pp boxfilloptions ; - fi ; - fi ; - if boxlinetype>0 : - draw pp boxlineoptions withpen pencircle scaled boxlinewidth ; - fi ; - fi ; -enddef ; - -vardef baseline_grid (expr pxy, pdir, at_baseline) = - save width ; width := bbwidth(pxy) ; - save height ; height := bbheight(pxy) ; - if (par_line_height>0) and (height>1) and (width>1) and (boxgridwidth>0) : - save i, grid, bb ; picture grid ; pair start ; path bb ; - def _do_ (expr start) = - % 1 = normal, 2 = with background (i.e. no shine-through) - if boxdashtype = 2 : - draw start -- start shifted (width,0) - withpen pencircle scaled boxgridwidth - boxfilloptions ; - fi ; - draw start -- start shifted (width,0) - if boxdashtype > 0 : - dashed evenly - fi - withpen pencircle scaled boxgridwidth - boxgridoptions ; - enddef ; - grid := image ( % fails with inlinespace - if pdir=up : - for i = if at_baseline : par_strut_depth else : 0 fi step par_line_height until max(height,par_line_height) : - _do_ (llcorner pxy shifted (0,+i)) ; - endfor ; - else : - for i = if at_baseline : par_strut_height else : 0 fi step par_line_height until height : - _do_ (ulcorner pxy shifted (0,-i)) ; - endfor ; - fi ; - ) ; - clip grid to pxy ; - bb := boundingbox grid ; - grid := grid shifted (0,boxgridshift) ; - setbounds grid to bb ; - grid - else : - nullpicture - fi -enddef ; - -vardef graphic_grid (expr pxy, dx, dy, x, y) = - if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : - save grid ; picture grid ; - grid := image ( - for i = xpart llcorner pxy step dx until xpart lrcorner pxy : - draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) withpen pencircle scaled boxgridwidth ; - endfor ; - for i = ypart llcorner pxy step dy until ypart ulcorner pxy : - draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) withpen pencircle scaled boxgridwidth ; - endfor - ) shifted (x,y) ; - clip grid to pxy ; - grid - else : - nullpicture - fi -enddef ; - -def anchor_box (expr n,x,y,w,h,d) = - currentpicture := currentpicture shifted (-x,-y) ; -enddef ; - -let draw_area = draw_box ; -let anchor_area = anchor_box ; -let anchor_par = anchor_box ; - -numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; -pair sync_xy[][] ; color sync_c[][] ; - -def ResetSyncTasks = - path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; - NOfSyncPaths := CurrentSyncClass := 0 ; - if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; - if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; - if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; - if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; - if (SyncLeftOffset = 0) and (SyncWidth = 0) : - SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; - fi ; -enddef ; - -ResetSyncTasks ; - -vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = - save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; - o shifted (leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,bottomoffset) -- - o shifted (leftoffset,bottomoffset) -- cycle -enddef ; - -def SetSyncColor(expr n, i, c) = - sync_c[n][i] := c ; -enddef ; - -def SetSyncThreshold(expr n, i, th) = - sync_th[n][i] := th ; -enddef ; - -vardef TheSyncColor(expr n, i) = - if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi -enddef ; - -vardef TheSyncThreshold(expr n, i) = - if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi -enddef ; - -vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = - ResetSyncTasks ; - if known sync_n[n] : - CurrentSyncClass := n ; - save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; - for i=1 upto sync_n[n] : - if RealPageNumber > sync_p[n][i] : - l := i ; - elseif RealPageNumber = sync_p[n][i] : - NOfSyncPaths := NOfSyncPaths + 1 ; - if not ok : - if i>1 : - if sync_t[n][i-1] = sync_t[n][i] : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i-1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - ok := true ; - fi ; - endfor ; - if (NOfSyncPaths = 0) and (l > 0) : - NOfSyncPaths := 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := l ; - fi ; - if NOfSyncPaths > 0 : - for i = 1 upto NOfSyncPaths-1 : - SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; - endfor ; - if unknown SyncThresholdMethod : - numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; - fi ; - if extendtop : - if SyncThresholdMethod = 1 : - if NOfSyncPaths>1 : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; - if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : - SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; - fi ; - fi ; - else : - for i = 1 upto NOfSyncPaths : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; - if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : - SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; - fi ; - endfor ; - fi ; - fi ; - if prestartnext : - if NOfSyncPaths>1 : - if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; - if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : - SyncPaths[NOfSyncPaths+1] := - (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - lrcorner SyncPaths[NOfSyncPaths] -- - llcorner SyncPaths[NOfSyncPaths] -- cycle ; - SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - fi ; - fi ; - fi ; - else : - if NOfSyncPaths>1 : - d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; - if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : - NOfSyncPaths := NOfSyncPaths - 1 ; - SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; - fi ; - fi ; - fi ; - if (NOfSyncPaths>1) and collapse : - save j ; numeric j ; j := 1 ; - for i = 2 upto NOfSyncPaths : - if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : - SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; - SyncTasks[j] := SyncTasks[i] ; - else : - j := j + 1 ; - SyncPaths[j] := SyncPaths[i] ; - SyncTasks[j] := SyncTasks[i] ; - fi ; - endfor ; - NOfSyncPaths := j ; - fi ; - fi ; - fi ; -enddef ; - -def SyncTask(expr n) = - if known SyncTasks[n] : SyncTasks[n] else : 0 fi -enddef ; - -def FlushSyncTasks = - for i = 1 upto NOfSyncPaths : - ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; - endfor ; -enddef ; - -def ProcessSyncTask(expr p, c) = - fill p withcolor c ; -enddef ; diff --git a/metapost/context/base/mp-crop.mpiv b/metapost/context/base/mp-crop.mpiv deleted file mode 100644 index 00bcdcb44..000000000 --- a/metapost/context/base/mp-crop.mpiv +++ /dev/null @@ -1,194 +0,0 @@ -%D \module -%D [ file=mp-crop.mpiv, -%D version=2011.06.23, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=Cropmarks, -%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_crop : endinput ; fi ; - -boolean context_crop ; context_crop := true ; - -vardef crop_marks_lines (expr box, len, offset, nx, ny) = - save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ; - p := image ( - x := if nx = 0 : 1 else : nx - 1 fi ; - y := if ny = 0 : 1 else : ny - 1 fi ; - w := bbwidth (box) / x ; - h := bbheight(box) / y ; - for i=0 upto y : - draw ((llcorner box) -- (llcorner box) shifted (-len,0)) shifted (-offset,i*h) ; - draw ((lrcorner box) -- (lrcorner box) shifted ( len,0)) shifted ( offset,i*h) ; - endfor ; - for i=0 upto x : - draw ((llcorner box) -- (llcorner box) shifted (0,-len)) shifted (i*w,-offset) ; - draw ((ulcorner box) -- (ulcorner box) shifted (0, len)) shifted (i*w, offset) ; - endfor ; - ) ; - setbounds p to box ; - p -enddef ; - -vardef crop_marks_cmyk = - save p ; picture p ; p := image ( - fill ulcircle scaled 12.5 withcolor (1,0,0,0) ; - fill urcircle scaled 12.5 withcolor (0,1,0,0) ; - fill lrcircle scaled 12.5 withcolor (0,0,1,0) ; - fill llcircle scaled 12.5 withcolor (0,0,0,1) ; - draw (-10,0) -- (10,0) ; - draw (0,-10) -- (0,10) ; - draw fullcircle scaled 12.5 ; - ) ; - setbounds p to fullsquare scaled 20 ; - p -enddef ; - -vardef crop_marks_gray = - save p ; picture p ; p := image ( - fill ulcircle scaled 12.5 withcolor (0.00) ; - fill urcircle scaled 12.5 withcolor (0.25) ; - fill lrcircle scaled 12.5 withcolor (0.50) ; - fill llcircle scaled 12.5 withcolor (0.75) ; - draw (-10,0) -- (10,0) ; - draw (0,-10) -- (0,10) ; - draw (-6,0) -- (6,0) withcolor white ; - draw (0,-6) -- (0,6) withcolor white ; - draw fullcircle scaled 12.5 ; - ) ; - setbounds p to fullsquare scaled 20 ; - p -enddef ; - -vardef crop_marks_cmykrgb = - save p ; picture p ; p := image ( - fill ulcircle scaled 15 withcolor (1,0,0) ; - fill urcircle scaled 15 withcolor (0,1,0) ; - fill lrcircle scaled 15 withcolor (0,0,1) ; - fill llcircle scaled 15 withcolor (.5,.5,.5) ; - fill ulcircle scaled 10 withcolor (1,0,0,0) ; - fill urcircle scaled 10 withcolor (0,1,0,0) ; - fill lrcircle scaled 10 withcolor (0,0,1,0) ; - fill llcircle scaled 10 withcolor (0,0,0,1) ; - draw (-10,0) -- (10,0) ; - draw (0,-10) -- (0,10) ; - draw fullcircle scaled 10 ; - draw fullcircle scaled 15 ; - ) ; - setbounds p to fullsquare scaled 20 ; - p -enddef ; - -vardef crop_color(expr c, h, w, dx, dy, ts) = - image ( - save p ; path p ; - for i=1 upto 6 : - p := fullsquare - xscaled w - yscaled h - shifted (dx,dy-i*h) ; - fill p - withcolor (crop_colors[i]*c) ; - draw textext("\format{'@0.2f'," & decimal crop_colors[i] & "}") - scaled ts - shifted center p withcolor white ; - endfor ; - ) -enddef ; - -vardef crop_gray(expr c, h, w, dx, dy, ts) = - image ( - save p ; path p ; - for i=.05 step .05 until 1 : - p := fullsquare - xscaled w - yscaled h - shifted (20*(i-1)*w+dx,dy) ; - fill p - withcolor (i*c) ; - draw textext("\format{'@0.2f'," & decimal i & "}") - scaled ts - shifted center p withcolor white ; - endfor ; - ) -enddef ; - -% draw crop_marks_cmyk shifted llcorner more ; -% draw crop_marks_cmyk shifted lrcorner more ; -% draw crop_marks_cmyk shifted ulcorner more ; -% draw crop_marks_cmyk shifted urcorner more ; - -def page_marks_add_color(expr width, height, length, offset) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - numeric crop_colors[] ; - crop_colors[1] := 1 ; - crop_colors[2] := 0.95 ; - crop_colors[3] := 0.75 ; - crop_colors[4] := 0.50 ; - crop_colors[5] := 0.25 ; - crop_colors[6] := 0.05 ; - - numeric h ; h := height / 20 ; - numeric w ; w := width / 20 ; - numeric d ; d := offset + length/2 ; - - draw crop_color((1,0,0,0),h,length,xpart ulcorner page - d, 10h,length/20) ; - draw crop_color((0,1,0,0),h,length,xpart ulcorner page - d,3.5h,length/20) ; - draw crop_color((0,0,1,0),h,length,xpart ulcorner page - d, -3h,length/20) ; - - draw crop_color((0,1,1,0),h,length,xpart urcorner page + d, 10h,length/20) ; - draw crop_color((1,0,1,0),h,length,xpart urcorner page + d,3.5h,length/20) ; - draw crop_color((1,1,0,0),h,length,xpart urcorner page + d, -3h,length/20) ; - - draw crop_gray((0,0,0,1),length, w,-xpart llcorner page,-ypart llcorner page + d ,w/20) ; - draw crop_gray((1,0,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d + 1length/3,w/20) ; - draw crop_gray((0,1,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 0length/3,w/20) ; - draw crop_gray((0,0,1,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 1length/3,w/20) ; - - setbounds currentpicture to page ; - -enddef ; - -def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - draw crop_marks_gray shifted center(topboundary more) shifted (0, offset+length); - draw crop_marks_cmyk shifted center(bottomboundary more) shifted (0,-offset-length); - - setbounds currentpicture to page ; - -enddef ; - -def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - draw crop_marks_lines(page,length,offset,nx,ny) ; - - setbounds currentpicture to page ; - -enddef ; - -def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - for s=llcorner more, lrcorner more, ulcorner more, urcorner more : - draw textext(decimal n) shifted s ; - endfor ; - - setbounds currentpicture to page ; - -enddef ; diff --git a/metapost/context/base/mp-figs.mpii b/metapost/context/base/mp-figs.mpii deleted file mode 100644 index d4fcc2b35..000000000 --- a/metapost/context/base/mp-figs.mpii +++ /dev/null @@ -1,47 +0,0 @@ -%D \module -%D [ file=mp-figs.mpii, -%D version=2003.01.15, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=figures, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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_figs : endinput ; fi ; - -boolean context_figs ; context_figs := true ; - -% todo: check defined - -def registerfigure(expr name,width,height) = - begingroup ; - save s ; string s ; s := cleanstring(name) ; - scantokens( s & "_width := " & decimal(width )) ; - scantokens( s & "_height := " & decimal(height)) ; - endgroup ; -enddef ; - -vardef figuresize(expr name) = - save s, p ; string s ; pair p ; - s := cleanstring(name) ; - scantokens( "p := " & "(" & s & "_width" & "," & s & "_height" & ")" ) ; - p -enddef ; - -vardef figurewidth(expr name) = - xpart figuresize(name) -enddef ; - -vardef figureheight(expr name) = - ypart figuresize(name) -enddef ; - -let figuredimensions = figuresize ; % for old times sake - -def naturalfigure(expr name) = - externalfigure name xyscaled(figuresize(name)) -enddef ; diff --git a/metapost/context/base/mp-figs.mpiv b/metapost/context/base/mp-figs.mpiv deleted file mode 100644 index aac7c5ad2..000000000 --- a/metapost/context/base/mp-figs.mpiv +++ /dev/null @@ -1,47 +0,0 @@ -%D \module -%D [ file=mp-figs.mpiv, -%D version=2003.01.15, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=figures, -%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_figs : endinput ; fi ; - -boolean context_figs ; context_figs := true ; - -% todo: check defined - -def registerfigure(expr name,width,height) = - begingroup ; - save s ; string s ; s := cleanstring(name) ; - scantokens( s & "_width := " & decimal(width )) ; - scantokens( s & "_height := " & decimal(height)) ; - endgroup ; -enddef ; - -vardef figuresize(expr name) = - save s, p ; string s ; pair p ; - s := cleanstring(name) ; - scantokens( "p := " & "(" & s & "_width" & "," & s & "_height" & ")" ) ; - p -enddef ; - -vardef figurewidth(expr name) = - xpart figuresize(name) -enddef ; - -vardef figureheight(expr name) = - ypart figuresize(name) -enddef ; - -let figuredimensions = figuresize ; % for old times sake - -def naturalfigure(expr name) = - externalfigure name xyscaled(figuresize(name)) -enddef ; diff --git a/metapost/context/base/mp-fobg.mp b/metapost/context/base/mp-fobg.mp deleted file mode 100644 index f8b709572..000000000 --- a/metapost/context/base/mp-fobg.mp +++ /dev/null @@ -1,87 +0,0 @@ -%D \module -%D [ file=mp-fobg.mp, -%D version=2004.03.12, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=Formatting Objects, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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_fobg : endinput ; fi ; - -boolean context_fobg ; context_fobg := true ; - -FoNone := 0 ; FoHidden := 1 ; FoDotted := 2 ; FoDashed := 3 ; FoSolid := 4 ; -FoDouble := 5 ; FoGroove := 6 ; FoRidge := 7 ; FoInset := 8 ; FoOutset := 9 ; -FoAll := 0 ; FoTop := 1 ; FoBottom := 2 ; FoLeft := 3 ; FoRight := 4 ; -FoMedium := .5pt ; FoThin := FoMedium/2 ; FoThick := FoMedium*2 ; - -color FoBackgroundColor, FoNoColor, FoLineColor[] ; FoNoColor := (-1,-1,-1) ; -numeric FoLineWidth[], FoLineStyle[] ; -boolean FoFrame, FoBackground, FoSplit ; - -FoFrame := FoBackground := FoSplit := false ; -FoBackgroundColor := white ; -FoDashFactor := .5 ; -FoDotFactor := .375 ; - -for i = FoAll upto FoRight : - FoLineColor[i] := black ; - FoLineWidth[i] := .5pt ; - FoLineStyle[i] := FoNone ; -endfor ; - -def DrawFoFrame(expr n, p) = - drawoptions(withcolor FoLineColor[n] withpen pencircle scaled FoLineWidth[n]) ; - if FoLineStyle[n] = FoNone : - % nothing - elseif FoLineStyle[n] = FoHidden : - % nothing - elseif FoLineStyle[n] = FoDotted : - draw p dashed (withdots scaled (FoDotFactor*FoLineWidth[n])) ; - elseif FoLineStyle[n] = FoDashed : - draw p dashed (evenly scaled (FoDashFactor*FoLineWidth[n])) ; - elseif FoLineStyle[n] = FoSolid : - draw p ; - elseif FoLineStyle[n] = FoDouble : - draw p enlarged FoLineWidth[n] ; draw p enlarged -FoLineWidth[n] ; - elseif FoLineStyle[n] = FoGroove : - draw p ; - draw p withpen pencircle scaled .5FoLineWidth[n] withcolor (inverted FoLineColor[n] softened .5) ; - elseif FoLineStyle[n] = FoRidge : - draw p withcolor (inverted FoLineColor[n] softened .5) ; - draw p withpen pencircle scaled .5FoLineWidth[n] ; - elseif FoLineStyle[n] = FoInset : - draw p ; draw p inset 2.5FoLineWidth[n] ; - elseif FoLineStyle[n] = FoOutset : - draw p ; draw p outset 2.5FoLineWidth[n] ; - fi ; -enddef ; - -primarydef p outset d = - ((lrcorner p -- urcorner p -- ulcorner p -- llcorner p -- cycle) - shifted (d*(-1,1)) cutbefore topboundary p) cutafter leftboundary p -enddef ; - -primarydef p inset d = - ((ulcorner p -- llcorner p -- lrcorner p -- urcorner p -- cycle) - shifted (d*(1,-1)) cutbefore bottomboundary p) cutafter rightboundary p -enddef ; - -vardef equalpaths(expr p, q) = - if length(p) = length(q) : - save ok ; boolean ok ; ok := true ; - for i = 0 upto length(p)-1 : - ok := ok and (round(point i of p) = round(point i of q)) ; - endfor ; - ok - else : - false - fi -enddef ; - -endinput ; diff --git a/metapost/context/base/mp-form.mpii b/metapost/context/base/mp-form.mpii deleted file mode 100644 index d1dac32db..000000000 --- a/metapost/context/base/mp-form.mpii +++ /dev/null @@ -1,392 +0,0 @@ -% Hans Hagen / October 2000 -% -% This file is mostly a copy from the file format.mp, that -% comes with MetaPost and is written by John Hobby. This file -% is meant to be compatible, but has a few more features, -% controlled by the variables: -% -% fmt_initialize when false, initialization is skipped -% fmt_precision the default accuracy (default=3) -% fmt_separator the pattern separator (default=%) -% fmt_zerocheck activate extra sci notation zero check -% -% instead of a picture, one can format a number in a for TeX -% acceptable input string - -boolean mant_font ; mant_font := true ; % signals graph not to load form - -if known context_form : endinput ; fi ; - -boolean context_form ; context_form := true ; - -if unknown fmt_metapost : boolean fmt_metapost ; fmt_metapost := true ; fi ; % == use old method -if unknown fmt_precision : numeric fmt_precision ; fmt_precision := 3 ; fi ; -if unknown fmt_initialize : boolean fmt_initialize ; fmt_initialize := true ; fi ; -if unknown fmt_separator : string fmt_separator ; fmt_separator := "%" ; fi ; -if unknown fmt_zerocheck : boolean fmt_zerocheck ; fmt_zerocheck := false ; fi ; - -% As said, all clever code is from John, the more stupid -% extensions are mine. The following string variables are -% responsible for the TeX formatting. - -% TeX specs when using TeX instead of pseudo TeX. - -string sFebraise_ ; sFebraise_ := "{" ; -string sFeeraise_ ; sFeeraise_ := "}" ; -string sFebmath_ ; sFebmath_ := "$" ; -string sFeemath_ ; sFeemath_ := "$" ; - -string sFmneg_ ; sFmneg_ := "-" ; -string sFemarker_ ; sFemarker_ := "{\times}10^" ; -string sFeneg_ ; sFeneg_ := "-" ; -string sFe_plus ; sFe_plus := "" ; % "+" - -def sFe_base = Fline_up_("1", sFemarker_) enddef ; - -% Macros for generating typeset pictures of computed numbers -% -% format(f,x) typeset generalized number x using format string f -% Mformat(f,x) like format, but x is in Mlog form (see marith.mp) -% init_numbers(s,m,x,sn,e) choose typeset style given sample sign, mantissa,... -% roundd(x,d) round numeric x to d places right of decimal point -% Fe_base what precedes the exponent for typeset powers of 10 -% Fe_plus plus sign if any for typesetting positive exponents -% Ten_to[] powers of ten for indices 0,1,2,3,4 -% -% New are: -% -% formatstr(f,x) TeX string representing x using format f -% Mformatstr(f,x) like Mformatstr, but x is in Mlog form - -% Other than the above-documented user interface, all -% externally visible names start with F and end with _. - -% Allow big numbers in token lists - -begingroup interim warningcheck := 0 ; - -%%% Load auxiliary macros. - -input string ; -input marith ; - -%%% Choosing the Layout %%% - -picture Fmneg_, Femarker_, Feneg_, Fe_base, Fe_plus ; -string Fmfont_, Fefont_ ; -numeric Fmscale_, Fescale_, Feraise_ ; - -% Argument -% -% s is a leading minus sign -% m is a 1-digit mantissa -% x is whatever follows the mantissa -% sn is a leading minus for the exponent, and -% e is a 1-digit exponent. -% -% Numbers in scientific notation are constructed by placing -% these pieces side-by-side; decimal numbers use only m -% and/or s. To get exponents with leading plus signs, assign -% to Fe_plus after calling init_numbers. To do something -% special with a unit mantissa followed by x, assign to -% Fe_base after calling init_numbers. - -vardef init_numbers(expr s, m, x, sn, e) = - Fmneg_ := s ; - for p within m : - Fmfont_ := fontpart p ; - Fmscale_ := xxpart p ; - exitif true ; - endfor - Femarker_ := x ; - Feneg_ := sn ; - for p within e : - Fefont_ := fontpart p ; - Fescale_ := xxpart p ; - Feraise_ := ypart llcorner p ; - exitif true ; - endfor - if fmt_metapost : - Fe_base := Fline_up_("1" infont Fmfont_ scaled Fmscale_, Femarker_) ; - % else : - % sFe_base := Fline_up_("1", sFemarker_) ; - fi ; - Fe_plus := nullpicture ; -enddef ; - -%%% Low-Level Typesetting %%% - -vardef Fmant_(expr x) = %%% adapted by HH %%% - if fmt_metapost : - (decimal abs x infont Fmfont_ scaled Fmscale_) - else : - (decimal abs x) - fi -enddef ; - -vardef Fexp_(expr x) = %%% adapted by HH %%% - if fmt_metapost : - (decimal x infont Fefont_ scaled Fescale_ shifted (0,Feraise_)) - else : - (decimal x) - fi -enddef ; - -vardef Fline_up_(text t_) = %%% adapted by HH %%% - if fmt_metapost : - save p_, c_ ; - picture p_ ; p_ = nullpicture ; - pair c_ ; c_ = (0,0) ; - for q_ = t_ : - addto p_ also q_ if string q_ : infont defaultfont scaled defaultscale fi - shifted c_ ; - c_ := (xpart lrcorner p_, 0) ; - endfor - p_ - else : - "" for q_ = t_ : & q_ endfor - fi -enddef ; - -vardef Fdec_o_(expr x) = %%% adapted by HH %%% - if x<0 : - Fline_up_(if fmt_metapost : Fmneg_ else : sFmneg_ fi, Fmant_(x)) - else : - Fmant_(x) - fi -enddef ; - -vardef Fsci_o_(expr x, e) = %%% adapted by HH %%% - if fmt_metapost : - Fline_up_ - (if x < 0 : Fmneg_,fi - if abs x = 1 : Fe_base else : Fmant_(x), Femarker_ fi, - if e < 0 : Feneg_ else : Fe_plus fi, - Fexp_(abs e)) - else : - Fline_up_ - (if x < 0 : sFmneg_, fi - if abs x = 1 : sFe_base else : Fmant_(x), sFemarker_ fi, - sFebraise_, - if e < 0 : sFeneg_ else : sFe_plus fi, - Fexp_(abs e), - sFeeraise_) - fi -enddef ; - -% Assume prologues=1 implies troff mode. TeX users who want -% prologues on should use some other positive value. The mpx -% file mechanism requires separate input files here. -% -% if fmt_initialize : %%% adapted by HH -% if prologues = 1 : input troffnum else : input texnum fi -% fi ; -% -% wrong assumption, so we need: - -if fmt_initialize : - input texnum ; -fi ; - -%%% Scaling and Rounding %%% - -% Find a pair p where x = xpart p*10**ypart p and either p = -% (0,0) or xpart p is between 1000 and 9999.99999. This is -% the `exponent form' of x. - -vardef Feform_(expr x) = - interim warningcheck := 0 ; - if string x : - Meform(Mlog_str x) - else : - save b, e ; - b = x ; e = 0 ; - if abs b >= 10000 : - (b/10, 1) - elseif b = 0 : - origin - else : - forever : - exitif abs b >= 1000 ; - b := b*10 ; e := e-1 ; - endfor - (b, e) - fi - fi -enddef ; - -% The marith.mp macros include a similar macro Meform that -% converts from `Mlog form' to exponent form. In case -% rounding has made the xpart of an exponent form number too -% large, fix it. - -vardef Feadj_(expr x, y) = - if abs x >= 10000 : (x/10, y+1) else : (x,y) fi -enddef ; - -% Round x to d places right of the decimal point. When d<0, -% round to the nearest multiple of 10 to the -d. - -vardef roundd(expr x, d) = - if abs d > 4 : - if d > 0 : x else : 0 fi - elseif d > 0 : - save i ; i = floor x ; - i + round(Ten_to[d]*(x-i))/Ten_to[d] - else : - round(x/Ten_to[-d])*Ten_to[-d] - fi -enddef ; - -Ten_to0 = 1 ; -Ten_to1 = 10 ; -Ten_to2 = 100 ; -Ten_to3 = 1000 ; -Ten_to4 = 10000 ; - -% Round an exponent form number p to k significant figures. - -primarydef p Fprec_ k = - Feadj_(roundd(xpart p,k-4), ypart p) -enddef ; - -% Round an exponent form number p to k digits right of the -% decimal point. - -primarydef p Fdigs_ k = - Feadj_(roundd(xpart p,k+ypart p), ypart p) -enddef ; - -%%% High-Level Routines %%% - -% The following operators convert z from exponent form and -% produce typeset output: Formsci_ generates scientific -% notation; Formdec_ generates decimal notation; and -% Formgen_ generates whatever is likely to be most compact. - -vardef Formsci_(expr z) = %%% adapted by HH %%% - if fmt_zerocheck and (z = origin) : - Fsci_o_(0,0) - else : - Fsci_o_(xpart z/1000, ypart z + 3) - fi -enddef ; - -vardef Formdec_(expr z) = - if ypart z > 0 : - Formsci_(z) - else : - Fdec_o_ - (xpart z if ypart z >= -4 : - /Ten_to[-ypart z] - else : - for i = ypart z upto -5 : /(10) endfor /10000 - fi) - fi -enddef ; - -vardef Formgen_(expr q) = - clearxy ; (x,y) = q ; - if x = 0 : Formdec_ - elseif y >= -6 : Formdec_ - else : Formsci_ - fi (q) -enddef ; - -def Fset_item_(expr s) = %%% adapted by HH %%% - if s <> "" : - if fmt_metapost : - s infont defaultfont scaled defaultscale, - else : - s, - fi - fi -enddef ; - -% For each format letter, the table below tells how to -% round and typeset a quantity z in exponent form. -% -% e scientific, p significant figures -% f decimal, p digits right of the point -% g decimal or scientific, p sig. figs. -% G decimal or scientific, p digits - -string fmt_[] ; - -fmt_[ASCII "e"] = "Formsci_(z Fprec_ p)" ; -fmt_[ASCII "f"] = "Formdec_(z Fdigs_ p)" ; -fmt_[ASCII "g"] = "Formgen_(z Fprec_ p)" ; -fmt_[ASCII "G"] = "Formgen_(z Fdigs_ p)" ; - -% The format and Mformat macros take a format string f and -% generate typeset output for a numeric quantity x. String f -% should contain a `%' followed by an optional number and one -% of the format letters defined above. The number should be -% an integer giving the precision (default 3). - -vardef isfmtseparator primary c = %%% added by HH %%% - ((c <> fmt_separator) and (c <> "%")) -enddef ; - -def initialize_form_numbers = - initialize_numbers ; % in context: do_initialize_numbers ; -enddef ; - -vardef dofmt_@#(expr f, x) = %%% adapted by HH %%% - initialize_form_numbers ; - if f = "" : - if fmt_metapost : nullpicture else : "" fi - else : - interim warningcheck := 0 ; - save k, l, s, p, z ; - pair z ; z = @#(x) ; - % the next adaption is okay - % k = 1 + cspan(f, fmt_separator <> ) ; - % but best is to support both % and fmt_separator - k = 1 + cspan(f, isfmtseparator) ; - % - l-k = cspan(substring(k,infinity) of f, isdigit) ; - p = if l > k : - scantokens substring(k,l) of f - else : - fmt_precision - fi ; - string s ; s = fmt_[ASCII substring (l,l+1) of f] ; - if unknown s : - if k <= length f : - errmessage("No valid format letter found in "&f) ; - fi - s = if fmt_metapost : "nullpicture" else : "" fi ; - fi - Fline_up_ - (Fset_item_(substring (0,k-1) of f) - if not fmt_metapost : sFebmath_, fi - scantokens s, - if not fmt_metapost : sFeemath_, fi - Fset_item_(substring (l+1,infinity) of f) - if fmt_metapost : nullpicture else : "" fi) - fi - hide (fmt_metapost := true) -enddef ; - -%%% so far %%% - -vardef format (expr f, x) = - fmt_metapost := true ; dofmt_.Feform_(f,x) -enddef ; - -vardef Mformat(expr f, x) = - fmt_metapost := true ; dofmt_.Meform (f,x) -enddef ; - -vardef formatstr (expr f, x) = - fmt_metapost := false ; dofmt_.Feform_(f,x) -enddef ; - -vardef Mformatstr(expr f, x) = - fmt_metapost := false ; dofmt_.Meform (f,x) -enddef ; - -% Restore warningcheck to previous value. - -endgroup ; diff --git a/metapost/context/base/mp-form.mpiv b/metapost/context/base/mp-form.mpiv deleted file mode 100644 index 88b15e097..000000000 --- a/metapost/context/base/mp-form.mpiv +++ /dev/null @@ -1,30 +0,0 @@ -%D \module -%D [ file=mp-form.mpiv, -%D version=2011.10.14, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=form support, -%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. - -% The graph package will be replaced by our own variant using -% MetaPost 2 features and textext. - -if known context_form : endinput ; fi ; - -boolean context_form ; context_form := true ; - -string Fmfont_ ; Fmfont_ := "crap" ; - -% The following function accept a number or string that can be -% converted to a number by \LUA. The first argument is a format -% where @ can be used instead of %. The number is typeset in math -% mode and @3e is converted into @.3e. - -vardef mfun_format_number(expr fmt, i) = - "\ctxlua{metapost.formatnumber('" & fmt & "'," & if string i : i else : decimal i fi & ")}" -enddef ; diff --git a/metapost/context/base/mp-func.mpii b/metapost/context/base/mp-func.mpii deleted file mode 100644 index 94e400b91..000000000 --- a/metapost/context/base/mp-func.mpii +++ /dev/null @@ -1,58 +0,0 @@ -%D \module -%D [ file=mp-func.mpii, -%D version=2001.12.29, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=function hacks, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -%D Under construction. - -if known context_func : endinput ; fi ; - -boolean context_func ; context_func := true ; - -string pathconnectors[] ; - -pathconnectors[0] := "," ; -pathconnectors[1] := "--" ; -pathconnectors[2] := ".." ; -pathconnectors[3] := "..." ; - -vardef function (expr f) (expr u, t, b, e, s) = save x ; numeric x ; - for xx := b step s until e : - hide (x := xx ;) if xx>b : scantokens(pathconnectors[f]) fi - (scantokens(u),scantokens(t)) - endfor -enddef ; - -def punkedfunction = function (1) enddef ; -def curvedfunction = function (2) enddef ; -def tightfunction = function (3) enddef ; - -vardef constructedpath (expr f) (text t) = - save ok ; boolean ok ; ok := false ; - for i=t : - if ok : scantokens(pathconnectors[f]) else : ok := true ; fi i - endfor -enddef ; - -def punkedpath = constructedpath (1) enddef ; -def curvedpath = constructedpath (2) enddef ; -def tightpath = constructedpath (3) enddef ; - -vardef constructedpairs (expr f) (text p) = - save i ; i := -1 ; - forever : exitif unknown p[incr(i)] ; - if i>0 : scantokens(pathconnectors[f]) fi p[i] - endfor -enddef ; - -def punkedpairs = constructedpairs (1) enddef ; -def curvedpairs = constructedpairs (2) enddef ; -def tightpairs = constructedpairs (3) enddef ; diff --git a/metapost/context/base/mp-func.mpiv b/metapost/context/base/mp-func.mpiv deleted file mode 100644 index b1b9d6d5d..000000000 --- a/metapost/context/base/mp-func.mpiv +++ /dev/null @@ -1,87 +0,0 @@ -%D \module -%D [ file=mp-func.mpiv, -%D version=2001.12.29, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=function hacks, -%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. - -%D Under construction. - -if known context_func : endinput ; fi ; - -boolean context_func ; context_func := true ; - -string mfun_pathconnectors[] ; - -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(c) - fi - (scantokens(u),scantokens(t)) - endfor -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(c) - else : - ok := true ; - fi - i - endfor -enddef ; - -def constructedpath = mfun_constructedpath enddef ; % let doesn't work here -def straightpath = mfun_constructedpath (1) enddef ; -def curvedpath = mfun_constructedpath (2) 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(c) - fi - p[i] - endfor -enddef ; - -def constructedpairs = mfun_constructedpairs enddef ; % let doesn't work here -def straightpairs = mfun_constructedpairs (1) enddef ; -def curvedpairs = mfun_constructedpairs (2) 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 deleted file mode 100644 index 4fd8ee5bd..000000000 --- a/metapost/context/base/mp-grap.mpiv +++ /dev/null @@ -1,1706 +0,0 @@ -%D \module -%D [ file=mp-grap.mpiv, -%D version=2012.10.16, % 2008.09.08 and earlier, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=graph packagesupport, -%D author=Hans Hagen \& Alan Braslau, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -if known context_grap : endinput ; fi ; - -boolean context_grap ; context_grap := true ; - -% Below is a modified graph.mp - -show numbersystem, numberprecision ; - -%if epsilon/4 = 0 : -if numbersystem <> "double" : - errmessage "The graph macros require the double precision number system." ; - endinput ; -fi - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% $Id : graph.mp,v 1.2 2004/09/19 21 :47 :10 karl Exp $ -% Public domain. - -% Macros for drawing graphs - -% begingraph(width,height) begin a new graph -% setcoords(xtype,ytype) sets up a new coordinate system (log,-linear..) -% setrange(lo,hi) set coord ranges (numeric and string args OK) -% gdraw [with...] draw a line in current coord system -% gfill [with...] fill a region using current coord system -% gdrawarrow .., gdrawdblarrow.. like gdraw, but with 1 or 2 arrowheads -% augment(loc) append given coordinates to a polygonal path -% glabel(pic,loc) place label pic near graph coords or time loc -% gdotlabel(pic,loc) same with dot -% OUT loc value for labels relative to whole graph -% gdata(file,s,text) read coords from file ; evaluate t w/ tokens s[] -% auto. default x or y tick locations (for interation) -% tick.(fmt,u) draw centered tick from given side at u w/ format -% itick.(fmt,u) draw inward tick from given side at u w/ format -% otick.(fmt,u) draw outward tick at coord u ; label format fmt -% grid.(fmt,u) draw grid line at u with given side labeled -% autogrid([itick|.. bot|..],..) iterate over auto.x, auto.y, drawing tick/grids -% frame.[bot|top..] draw frame (or one side of the frame) -% graph_frame_needed := false ; after begingraph, not to draw a frame at all -% graph_background := color ; fill color for frame, if defined -% endgraph end of graph--the result is a picture - -% option `plot ' draws picture at each path knot, turns off pen -% graph_template. template paths for tick marks and grid lines -% graph_margin_fraction.low, -% graph_margin_fraction.high fractions determining margins when no setrange -% graph_log_marks[], graph_lin_marks, graph_exp_marks loop text strings used by auto. -% graph_minimum_number_of_marks, graph_log_minimum numeric parameters used by auto. -% Autoform is the format string used by autogrid -% Autoform_X, Autoform_Y if defined, are used instead - -% Other than the above-documented user interface, all externally visible names -% are of the form X_., Y_., or Z_., or they start -% with `graph_' - -% 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 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 - else: mexp(x) fi -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 - else: 10**x fi -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 : - save e, m ; e=floor(x/mlogten)-3; m := mexp(x-e*mlogten) ; - if abs m<1000 : m := m*10 ; e := e-1 ; elseif abs m>=10000 : m := m/10 ; e := e+1 ; fi - (m, e) - fi -enddef ; - -% Modified from above. - -vardef graph_Feform(expr x) = - interim warningcheck :=0 ; - if x=0 : origin - else : - save e, m ; e=floor(if x<0 : -mlog(-x) else : mlog(x) fi/mlogten)-3; m := x/(10**e) ; - if abs m<1000 : m := m*10 ; e := e-1 ; elseif abs m>=10000 : m := m/10 ; e := e+1 ; fi - (m, e) - fi -enddef ; - -vardef graph_error(expr x,s) = - interim showstopping :=0 ; - show x ; errmessage s ; -enddef ; - -%%%%%%%%%%%%%%%%%%%%%%%% Data structures, begingraph %%%%%%%%%%%%%%%%%%%%%%%% - -vardef Z_@# = (X_@#,Y_@#) enddef ; % used in place of plain.mp's z convention - -def graph_suffix(suffix $) = % convert from x or y to X_ or Y_ - if str$="x" : X_ else : Y_ fi -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 ; - -def begingraph(expr w, h) = - begingroup - save X_, Y_ ; - X_.graph_coordinate_type = - Y_.graph_coordinate_type = linear ; % coordinate system for each axis - Z_.graph_dimensions = (w,h) ; % dimensions of graph not counting axes etc. - %also, Z_.low, Z_.high user-specified coordinate ranges in units used in graph_current_graph - - save graph_finished_graph ; - picture graph_finished_graph ; % the finished part of the graph - graph_finished_graph = nullpicture ; - save graph_current_graph ; - picture graph_current_graph ; % what has been drawn in current coords - graph_current_graph = nullpicture ; - save graph_current_bb ; - picture graph_current_bb ; % picture whose bbox is graph_current_graph's w/ linewidths 0 - graph_current_bb = nullpicture ; - save graph_last_drawn ; - picture graph_last_drawn ; % result of last gdraw or gfill - graph_last_drawn = nullpicture ; - save graph_last_path ; - path graph_last_path ; % last gdraw or gfill path in data coordinates. - save graph_plot_picture ; - picture graph_plot_picture ; % a picture from the `plot' option known when plot allowed - save graph_foreground ; - color graph_foreground ; % drawing color, if set. - save graph_label ; - picture graph_label[] ; % labels to place around the whole graph when it is done - save graph_autogrid_needed ; - boolean graph_autogrid_needed ; % whether autogrid is needed - graph_autogrid_needed = true ; - save graph_frame_needed ; - boolean graph_frame_needed ; % whether frame needs to be drawn - graph_frame_needed = true ; - save graph_number_of_arrowheads ; % number of arrowheads for next gdraw - graph_number_of_arrowheads = 0 ; - - if known graph_background : % new feature! - fill origin--(w,0)--(w,h)--(0,h)--cycle withcolor graph_background ; - fi -enddef ; - -% Additional variables not explained above : -% graph_modified_lower, graph_modified_higher pairs giving bounds used in auto -% graph_exponent, graph_comma variables and macros used in auto -% graph_modified_bias -% an offset to graph_modified_lower and graph_modified_higher to ease computing exponents -% Some additional variables function as constants. Most can be modified by the -% user to alter the behavior of these macros. -% Not very modifiable : log, linear, -% graph_frame_pair_a, graph_frame_pair_b, graph_margin_pair -% 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 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 : -% log means internal graph coords = mlog(user graph coords) -% -log means internal graph coords = -mlog(user graph coords) -% linear means internal graph coords = (user graph coords) -% -linear means internal graph coords = -(user graph coords) - - -vardef graph_set_default_bounds = % Set default Z_.low, Z_.high - forsuffixes $=low,high : - (if known X_$ : whatever else : X_$ fi, if known Y_$ : whatever else : Y_$ fi) - = graph_margin_fraction$[llcorner graph_current_bb,urcorner graph_current_bb] + - 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. - -vardef graph_remap(suffix $,$$,$$$) = - save p_ ; - graph_set_default_bounds ; - pair p_, $ ; $=-Z_.low; - p_ = (max(X_.high-X_.low,.9), max(Y_.high-Y_.low,.9)) ; - transform $$, $$$ ; - forsuffixes #=$$,$$$ : xpart#=ypart#=xypart#=yxpart#=0 ; endfor - (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 : - false - elseif colormodel q=3 : - (greypart q) - elseif colormodel q=5 : - (redpart q, greenpart q, bluepart q) - elseif colormodel q=7 : - (cyanpart q, magentapart q, yellowpart q, blackpart q) - fi -enddef ; - -% Add picture component q to picture @# and change part p to tp, -% where p is something from q that needs coordinate transformation. -% The type of p is pair or path. -% 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 : -% path p ; p=pathpart q; -% addto @# doublepath tp graph_with_pen_and_color(q) dashed dashpart q ; -% elseif filled q : -% path p ; p=pathpart q; -% addto @# contour tp graph_with_pen_and_color(q) ; -% else : -% interim truecorners :=0 ; -% pair p ; p=llcorner q; -% if urcorner q<>p : p := p + graph_coordinate_multiplication(o-p,urcorner q-p) ; fi -% 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 ; - picture tp_clipped ; tp_clipped := nullpicture; - if stroked q : - path p ; p=pathpart q; - addto tp_clipped doublepath tp graph_with_pen_and_color(q) dashed dashpart q ; - %draw bbox tp_clipped withcolor red ; - elseif filled q : - path p ; p=pathpart q; - addto tp_clipped contour tp graph_with_pen_and_color(q) ; - %draw bbox tp_clipped withcolor green ; - else : - if (urcorner q<>llcorner q) : do_clip := false ; fi % Do not clip the axis labels; - interim truecorners := 0 ; - pair p ; p=llcorner q; - if urcorner q<>p : p := p + graph_coordinate_multiplication(o-p,urcorner q-p) ; fi - addto tp_clipped also q shifted ((tp)-llcorner q) ; - %draw bbox tp_clipped withcolor if do_clip : cyan else : blue fi ; - fi - if do_clip : - clip tp_clipped to origin--(xpart Z_.graph_dimensions,0)--Z_.graph_dimensions-- - (0,ypart Z_.graph_dimensions)--cycle ; - fi - addto @# also tp_clipped ; -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 : - save s, S, T ; - graph_remap(s, S, T) ; - for q within graph_current_graph : - graph_picture_conversion.graph_finished_graph(q,-s,p shifted s transformed S transformed T) ; - endfor - graph_current_graph := graph_current_bb := nullpicture ; - fi - graph_clear_bounds.X_ ; graph_clear_bounds.Y_; - 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; - string r_[]s ; - for x_= - for p_=t : if pair p_ : xpart p_, ypart fi p_, endfor : - r_[incr r_] if string x_ : s fi = x_ ; - if r_>2 : - graph_set_bounds if r_=3 : X_ else : Y_ fi (r_[r_-2] if unknown r_[r_-2] : s fi, x_) ; - fi - exitif r_=4 ; - 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 : - @#low = if unknown l : - whatever - else : - if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l - fi ; - @#high = if unknown h : - whatever - else : - if abs @#graph_coordinate_type=log : graph_mlog fi if string h : scantokens fi h - fi ; - else : - -@#high = if unknown l : - whatever - else : - if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l - fi ; - -@#low = if unknown h : - whatever - else : - if abs @#graph_coordinate_type=log : graph_mlog fi if string h : scantokens fi h - fi ; - 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 : - save r_ ; path r_; - r_ := graph_pair_adjust(point 0 of p, tx, ty) - if path p : - for t=1 upto length p : - if c : -- - else : ..controls graph_pair_adjust(postcontrol(t-1) of p, tx, ty) - and graph_pair_adjust(precontrol t of p, tx, ty) .. - fi - graph_pair_adjust(point t of p, tx, ty) - endfor - if cycle p : &cycle fi - fi ; - 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 ; - -% Convert path p from user graph coords to internal graph coords. - -vardef graph_convert_user_path_to_internal primary p = - interim warningcheck :=0 ; - 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 ; - if 0 for x_=t_ : +1 if pair x_ : +1 fi endfor <= 1 : - t_ - else : - n_0 = n_1 = 0 ; - point 0 of graph_convert_user_path_to_internal ( - for x_= - for y_=t_ : if pair y_ : xpart y_, ypart fi y_, endfor - 0, 0 : - if known x_ : if string x_ : scantokens fi x_ - else : hide(n_[n_] :=whatever) 0 - fi - exitif incr n_=2 ; - ,endfor) + (n_0,n_1) - 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 ' 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 := graph_loptok s_ ; - n_ = if @#1="%" : 0 else : 1 fi ; - forever : - @#[incr n_] := graph_loptok s_ ; - exitif @#[n_]="" ; - endfor - @#1<>"" - else : false - 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 ; % not used? - for i=1 upto largestmantissa : - exitunless graph_read_line$(f) ; - c - endfor - if graph_close_file : - closefrom f ; - 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 ; - gdata(f, s, if i>1 :--fi - if s2="" : ( i, scantokens s1) - else : (scantokens s1, scantokens s2) fi - ) -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 : - graph_error(begingroup @# endgroup, "Cannot augment--not a path") ; - else : - def graph_comma= hide(def graph_comma=,enddef) enddef ; - if known @# : @# :=@#-- else : @#= fi - (for p=t : - graph_comma if string p : scantokens fi p - endfor) ; - 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 ; - else : - save x,y ; - z = llcorner graph_current_bb ; - if unknown xpart p : xpart p= else : x := fi 0 ; - if unknown ypart p : ypart p= else : y := fi 0 ; - addto graph_current_bb doublepath (p+z) ; - fi - graph_current_bb := image(fill llcorner graph_current_bb..urcorner graph_current_bb--cycle) ; -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 ; - path graph_last_path ; - 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. - -def graph_draw expr p = - if string p : hide(graph_last_path := graph_readpath(p) ;) - graph_convert_user_path_to_internal graph_last_path - elseif path p or pair p : - hide(graph_last_path := p ;) - graph_convert_user_path_to_internal p - else : graph_error(p,"gdraw argument should be a data file or a path") - origin - fi - withpen currentpen graph_withlist _op_ -enddef ; - -% 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 - elseif cycle p : hide(graph_last_path := p ;) - graph_convert_user_path_to_internal p - else : graph_error(p,"gfill argument should be a data file or a cyclic path") - origin..cycle - fi graph_withlist _op_ -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 = - hide( - def graph_errorbar_text = t enddef ; - save pic ; picture pic ; pic := image(draw origin _op_ options ;) ; - if color colorpart pic : graph_foreground := colorpart pic ; fi - ) - 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 ;) ; - -vardef graph_errorbars(text t) = - if known graph_last_path : - save n, p, q ; path p ; pair q ; - save pic ; picture pic[] ; pic0 := nullpicture ; - pic1 := if known graph_xbar_picture : graph_xbar_picture - elseif known graph_errorbar_picture : graph_errorbar_picture rotated 90 - else : nullpicture fi ; - pic2 := if known graph_ybar_picture : graph_ybar_picture - elseif known graph_errorbar_picture : graph_errorbar_picture - else : nullpicture fi ; - if length pic1>0 : - pic1 := pic1 scaled graph_shapesize ; - setbounds pic1 to origin..cycle ; - fi - if length pic2>0 : - pic2 := pic2 scaled graph_shapesize ; - setbounds pic2 to origin..cycle ; - fi - for i=0 upto length graph_last_path : - clearxy ; z = point i of graph_last_path ; - n := 1 ; - for $=t : - if known $ : - q := if path $ : if length $>i : point i of $ else : origin fi - elseif pair $ : $ elseif numeric $ : ($,$) else : origin fi ; - if q<>origin : - p := graph_convert_user_path_to_internal (( - if n=1 : - (-xpart q,0)--(ypart q,0) - else : - (0,-xpart q)--(0,ypart q) - fi ) shifted z) ; - addto pic0 doublepath p ; - if length pic[n]>0 : - if ypart q<>0 : - addto pic0 also pic[n] shifted point 1 of p ; - fi - if xpart q<>0 : - addto pic0 also pic[n] rotated 180 shifted point 0 of p ; - fi - fi - fi - fi - exitif incr n>3 ; - endfor - endfor - if length pic0>0 : - save bg, fg ; color bg, fg ; - bg := if known graph_background : graph_background else : background fi ; - fg := if known graph_foreground : graph_foreground else : black fi ; - addto graph_current_graph also pic0 withpen currentpen scaled 2 _op_ withcolor bg ; - addto graph_current_graph also pic0 withpen currentpen scaled .5 _op_ withcolor fg ; - fi - fi -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 - hide (graph_plot_picture := image( - if bounded p : for q within p : graph_addto_currentpicture q endfor % Save memory - else : graph_addto_currentpicture p - fi graph_setbounds origin..cycle)) - fi -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; - -% 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 ; - 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 ; - fi - graph_errorbars(graph_errorbar_text) ; - if length graph_plot_picture>0 : - for i=0 upto length p if cycle p : -1 fi : - addto graph_current_graph also graph_plot_picture shifted point i of p ; - endfor - picture graph_plot_picture ; - fi - if graph_number_of_arrowheads>0 : - graph_draw_arrowhead(p, graph_with_pen_and_color(graph_last_drawn)) ; - 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 ; - fi -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(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) = - if p<>q : (q - 100pt*unitvector(q-p)) -- fi - q -enddef ; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Drawing labels %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% Argument c is a drawing command that needs an additional argument p that gives -% a location in internal graph coords. Draw in graph_current_graph enclosed in a setbounds -% 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) ; - graph_unknown_pair_bbox(p) ; - addto graph_current_graph also - 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) - else : graph_stash_label - 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 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; - -vardef itick@#(expr f,u) text w = graph_tick_label(@#,@,false,f,u,w) ; enddef; - -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 $, 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) -enddef ; - -% Generate label positioning arguments appropriate for label suffix $ and -% coordinate u. - -def graph_generate_label_position(suffix $)(expr u) = - 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 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 = 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 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 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); - -%%%%%%%%%%%%%%%%%%%%%%%%%% Automatic grid selection %%%%%%%%%%%%%%%%%%%%%%%%%% - -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 - -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 -% type of grid spacing to use. Bounds are returned in variables local to -% begingraph..endgraph : pairs graph_modified_lower and graph_modified_higher -% are upper and lower bounds in -% `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 ; - graph_set_default_bounds ; - if @#graph_coordinate_type>0 : (l,h) else : -(h,l) fi = (@#low, @#high) ; - 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 >= 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. - -def graph_scan_marks(expr k, l, h)(text t) = - for m=scantokens graph_log_marks[k] : - exitif m>h ; - if m>=l : t fi - endfor -enddef ; - -% 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, - if e= graph_minimum_number_of_marks ; - endfor - k -enddef ; - -% 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 graph_exp_marks : - @# = e ; - exitif floor(ypart graph_modified_higher/e) - - floor(graph_modified_exponent_ypart(graph_modified_lower)/e) - >= graph_minimum_number_of_marks ; - numeric @# ; - endfor - known @# -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 = 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 graph_lin_marks : - d = n*x ; - exitif 0 graph_generate_numbers(d,+1)>=m ; - numeric d ; - endfor - fi - 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 ; - e+3 = if graph_modified_lower=graph_modified_bias : ypart graph_modified_higher - elseif graph_modified_higher=graph_modified_bias : ypart graph_modified_lower - else : max(ypart graph_modified_lower, ypart graph_modified_higher) fi ; - forsuffixes $=graph_modified_lower, graph_modified_higher : - $ := (xpart $ for i=ypart $ upto e+2 : /(10) endfor, e) ; - endfor - 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 - elseif e>=0 : - if abs m=.1 : x else : decimal m & "e" & decimal e fi - fi -enddef ; - -def auto suffix $ = - hide(def graph_comma= hide(def graph_comma=,enddef) enddef) - if graph_bounds.graph_suffix($)=log : - if graph_select_exponent_mark.graph_exponent : - graph_generate_exponents(graph_exponent, - graph_comma graph_factor_and_exponent_to_string(1,e)) - else : - graph_scan_mark(graph_select_mark, graph_modified_lower, graph_modified_higher, - graph_comma graph_factor_and_exponent_to_string(m,e)) - fi - else : - hide(graph_exponent :=graph_match_exponents) - graph_generate_numbers(graph_tick_mark_spacing, - graph_comma graph_factor_and_exponent_to_string(m,graph_exponent)) - fi -enddef ; - -string Autoform ; Autoform = "%g"; - -%vardef autogrid(suffix tx, ty) text w = -% graph_autogrid_needed :=false ; -% if str tx<>"" : for x=auto.x : tx(Autoform,x) w ; endfor fi -% if str ty<>"" : for y=auto.y : ty(Autoform,y) w ; endfor fi -%enddef ; - -% We redefine autogrid, adding the possibility of differing X and Y -% formats. - -% string Autoform_X ; Autoform_X := "@.0e" ; -% string Autoform_Y ; Autoform_Y := "@.0e" ; - -vardef autogrid(suffix tx, ty) text w = - graph_autogrid_needed := false ; - if str tx <> "" : - for x=auto.x : - tx ( - if string Autoform_X : - if Autoform_X <> "" : - Autoform_X - else : - Autoform - fi - else : - Autoform - fi, - x - ) w ; - endfor - fi - if str ty <> "" : - for y=auto.y : - ty ( - if string Autoform_Y : - if Autoform_Y <> "" : - Autoform_Y - else : - Autoform - fi - else : - Autoform - fi, - y - ) w ; - endfor - fi -enddef ; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% endgraph %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -def endgraph = - if graph_autogrid_needed : autogrid(otick.bot, otick.lft) ; fi - if graph_frame_needed : frame ; fi - setcoords(linear,linear) ; - interim truecorners :=1 ; - for b=bbox graph_finished_graph : - setbounds graph_finished_graph to b ; - for i=0 step .5 until 3.5 : - if known graph_label[i] : - addto graph_finished_graph also graph_label[i] shifted point i of b ; - fi - endfor - endfor - graph_finished_graph - endgroup -enddef ; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% We format in luatex (using \mathematics{}) ... -% we could pass via variables and save escaping as that is inefficient - -if unknown context_mlib : - - 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 ; - - 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 format (expr f, x) = textext(strfmt(f,x)) enddef ; - vardef formatted(expr f, x) = textext(varfmt(f,x)) enddef ; - -fi ; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% A couple of extensions : - -% Define a function plotsymbol() returning a picture : 10 different shapes, -% unfilled outline, interior filled with different shades of the background. -% This allows overlapping points on a plot to be more distinguishable. - -vardef graph_shapesize = (.33BodyFontSize) enddef ; - -path graph_shape[] ; % (internal) symbol path - -graph_shape[0] := (0,0) ; % point -graph_shape[1] := fullcircle ; % circle -graph_shape[2] := (up -- down) scaled .5 ; % vertical bar - -for i = 3 upto 9 : % polygons - graph_shape[i] := - for j = 0 upto i-1 : - (up scaled .5) rotated (360j/i) -- - endfor cycle ; -endfor - -graph_shape[12] := graph_shape[2] rotated +90 ; % horizontal line -graph_shape[22] := graph_shape[2] rotated +45 ; % backslash -graph_shape[32] := graph_shape[2] rotated -45 ; % slash -graph_shape[13] := graph_shape[3] rotated 180 ; % down triangle -graph_shape[23] := graph_shape[3] rotated -90 ; % right triangle -graph_shape[33] := graph_shape[3] rotated +90 ; % left triangle -graph_shape[14] := graph_shape[4] rotated +45 ; % square -graph_shape[15] := graph_shape[5] rotated 180 ; % down pentagon -graph_shape[16] := graph_shape[6] rotated +90 ; % turned hexagon -graph_shape[17] := graph_shape[7] rotated 180 ; -graph_shape[18] := graph_shape[8] rotated +22.5 ; - -numeric l ; - -for j = 5 upto 9 : - l := length(graph_shape[j]) ; - pair p[] ; - for i = 0 upto l : - p[i] = whatever [point i of graph_shape[j], - point (i+2 mod l) of graph_shape[j]] ; - p[i] = whatever [point (i+1 mod l) of graph_shape[j], - point (i+l-1 mod l) of graph_shape[j]] ; - endfor - graph_shape[20+j] := for i = 0 upto l : point i of graph_shape[j]--p[i]--endfor cycle ; -endfor - -path s ; s := graph_shape[4] ; -path q ; q := s scaled .25 ; -numeric l ; l := length(s) ; - -pair p[] ; - -graph_shape[24] := for i = 0 upto l-1 : - hide( - p[i] = whatever [point i of s, point (i+1 mod l) of s] ; - p[i] = whatever [point i of q, point (i-1+l mod l) of q] ; - p[i+l] = whatever [point i of s, point (i+1 mod l) of s] ; - p[i+l] = whatever [point i+1 of q, point (i+2 mod l) of q] ; - ) - point i of q -- p[i] -- p[i+l] -- -endfor cycle ; - -graph_shape[34] := graph_shape[24] rotated 45 ; - -% usage : gdraw p plot plotsymbol( 1,1) ; % a filled circle -% usage : gdraw p plot plotsymbol(14,0) ; % a square -% usage : gdraw p plot plotsymbol( 4,.5) ; % a 50% filled diamond - -def stars(expr f) = plotsymbol(25,f) enddef ; % a 5-point star -def points(expr f) = plotsymbol( 0,f) enddef ; -def circles(expr f) = plotsymbol( 1,f) enddef ; -def crosses(expr f) = plotsymbol(34,f) enddef ; -def squares(expr f) = plotsymbol(14,f) enddef ; -def diamonds(expr f) = plotsymbol( 4,f) enddef ; % a turned square -def uptriangles(expr f) = plotsymbol( 3,f) enddef ; -def downtriangles(expr f) = plotsymbol(13,f) enddef ; -def lefttriangles(expr f) = plotsymbol(33,f) enddef ; -def righttriangles(expr f) = plotsymbol(23,f) enddef ; - -% f (fill) is color, numeric or boolean, otherwise background. -def plotsymbol(expr n, f) text t = - if known graph_shape[n] : - image( - save bg, fg ; color bg, fg ; - bg := if known graph_background : graph_background else : background fi ; - save pic ; picture pic ; pic := image(draw origin _op_ t ;) ; - if color colorpart pic : graph_foreground := colorpart pic ; fi - fg := if known graph_foreground : graph_foreground else : black fi ; - save p ; path p ; p = graph_shape[n] scaled graph_shapesize ; - draw p withcolor bg withpen currentpen scaled 2 ; % halo - currentpen := currentpen scaled .5 ; - if cycle p : - fill p withcolor - if known f : - if color f : - f - elseif numeric f : - f[bg,fg] - elseif boolean f and f : - fg - else - bg - fi - else : - bg - fi ; - fi - draw p _op_ t ; - ) - else : - nullpicture - fi - t -enddef ; - -% standard resistance color code: rainbow sequence (from /usr/share/X11/rgb.txt) -color resistance_color[] ; string resistance_name[] ; -resistance_color0 = (0,0,0) ; resistance_name0 = "black" ; -resistance_color1 = (165/255,42/255,42/255) ; resistance_name1 = "brown" ; -resistance_color2 = (1,0,0) ; resistance_name2 = "red" ; -resistance_color3 = (1,165/255,0) ; resistance_name3 = "orange" ; -resistance_color4 = (1,1,0) ; resistance_name4 = "yellow" ; -resistance_color5 = (0,1,0) ; resistance_name5 = "green" ; -resistance_color6 = (0,0,1) ; resistance_name6 = "blue" ; -resistance_color7 = (148/255,0,211/255) ; resistance_name7 = "darkviolet" ; -resistance_color8 = (190/255,190/255,190/255) ; resistance_name8 = "gray" ; -resistance_color9 = (1,1,1) ; resistance_name9 = "white" ; - -%def rainbow(expr f) = -% ((abs(5f) mod 5) + 2 - floor((abs(5f) mod 5) + 2)) -% [resistance_color[ floor((abs(5f) mod 5) + 2)], -% resistance_color[ceiling((abs(5f) mod 5) + 2)]] -%enddef ; -def rainbow(expr f) = - hide(numeric n_ ; n_ = (abs(5f) mod 5) + 2 ;) - (n_-floor(n_))[resistance_color[floor n_],resistance_color[ceiling n_]] -enddef ; - -% The following extensions are not specific to graph and could be moved to metafun... - -% sort a path. Efficient en memory use, not so efficient in sorting long paths... - -vardef sortpath (suffix $) (text t) = % t can be "xpart", "ypart", "length", "angle", ... - if path $ : - if length $ > 0 : - save n, k ; n := length $ ; - for i=0 upto n : - k := i ; - for j=i+1 upto n : - if t (point j of $) < t (point k of $) : - k := j ; - fi - endfor - if k>i : - $ := if i>0 : subpath (0,i-1) of $ -- fi - point k of $ -- - subpath (i,k-1) of $ - if k0 : .. fi - (point i of $) - endfor ) - fi -enddef ; - -% return a path of a function func(x) with abscissa running from f to t over n intervals - -def makefunctionpath (expr f, t, n) (text func) = - (for x=f step ((t-f)/(abs n)) until t : - if x<>f : -- fi - (x, func) - endfor ) -enddef ; - -% shift a path, point by point -% -% example : -% -% p1 := addtopath(p0,(.1normaldeviate,.1normaldeviate)) ; - -vardef addtopath (suffix p) (text t) = - if path p : - (for i=0 upto length p : - if i>0 : -- fi - hide(clearxy ; z = point i of p ;) z shifted t - endfor) - fi -enddef ; - -% return a new path of a function func(z) using the same abscissa as an existing path - -vardef functionpath (suffix p) (text func) = - (for i=0 upto length p : - if i>0 : .. fi - (hide(x := xpart(point i of p))x,func) %(hide(clearxy ; z = point i of p)x,func) - endfor ) -enddef ; - -% least-squares "fit" to a polynomial -% -% example : -% -% path p[] ; -% numeric a[] ; a0 := 1 ; a1 := .1 ; a2 := .01 ; a3 := .001 ; a4 := 0.0001 ; -% p0 := makefunctionpath(0,5,10,polynomial_function(a,4,x)) ; -% p1 := addtopath(p0,(0,.001normaldeviate)) ; -% gdraw p0 ; -% gdraw p1 plot plotsymbol(1,.5) ; -% -% numeric b[] ; -% polynomial_fit(p1, b, 4, 1) ; -% gdraw functionpath(p1,polynomial_function(b,4,x)) ; -% -% numeric c[] ; -% linear_fit(p1, c, 1) ; -% gdraw functionpath(p1,linear_function(c,x)) dashed evenly ; - -% a polynomial function : -% -% y = a0 + a1 * x + a2 * x^2 + ... + a[n] * x^n - -vardef polynomial_function (suffix $) (expr n, x) = - (for j=0 upto n : + $[j]*(x**j) endfor) % no ; -enddef ; - -% find the determinant of a (n+1)*(n+1) matrix ; indices run from 0 to n - -vardef det (suffix $) (expr n) = - hide( - numeric determinant ; determinant := 1 ; - save jj ; numeric jj ; - for k=0 upto n : - if $[k][k]=0 : - jj := -1 ; - for j=0 upto n : - if $[k][j]<>0 : - jj := j ; - exitif true ; - fi - endfor - if jj<0 : - determinant := 0 ; - exitif true ; - fi - for j=k upto n : % interchange the columns - temp := $[j][jj] ; - $[j][jj] := $[j][k] ; - $[j][k] := temp ; - endfor - determinant = -determinant ; - fi - exitif determinant=0 ; - determinant := determinant * $[k][k] ; - if k0 : /(abs t) fi ; - elseif pair t : - if t<>origin : - w := 1/(abs t) ; - fi - elseif path t : - if length t>= i: - if point i of t<>origin : - w := 1/(abs point i of t) ; - fi - else : - w := 0 ; - fi ; - fi - fi - x1 := w ; - for j=0 upto 2n : - sumx[j] := sumx[j] + x1 ; - x1 := x1 * x ; - endfor - y1 := y * w ; - for j=0 upto n : - sumy[j] := sumy[j] + y1 ; - y1 := y1 * x ; - endfor - fit_chi_squared := fit_chi_squared + y*y*w ; - endfor - % construct matrices and calculate the polynomial coefficients - save m ; numeric m[][] ; - for j=0 upto n : - for k=0 upto n : - m[j][k] := sumx[j+k] ; - endfor - endfor - save delta ; numeric delta ; - delta := det(m,n) ; % this destroys the matrix m[][], which is OK - if delta = 0 : - fit_chi_squared := 0 ; - for j=0 upto n : - $[j] := 0 ; - endfor - else : - for i=0 upto n : - for j=0 upto n : - for k=0 upto n : - m[j][k] := sumx[j+k] ; - endfor - m[j][i] := sumy[j] ; - endfor - $[i] := det(m,n) / delta ; % matrix m[][] gets destroyed... - endfor - for j=0 upto n : - fit_chi_squared := fit_chi_squared - 2sumy[j]*$[j] ; - for k=0 upto n : - fit_chi_squared := fit_chi_squared + $[j]*$[k]*sumx[j+k] ; - endfor - endfor - % normalize by the number of degrees of freedom - fit_chi_squared := fit_chi_squared / (length(p) - n) ; % length(p)+1-(n+1) - fi - fi -enddef ; - -% y = a0 + a1 * x -% -% of course a line is just a polynomial of order 1 - -vardef linear_function (suffix $) (expr x) = polynomial_function($,1,x) enddef ; -vardef linear_fit (suffix p, $) (text t) = polynomial_fit(p, $, 1, t) ; enddef ; - -% and a constant is polynomial of order 0 - -vardef constant_function (suffix $) (expr x) = polynomial_function($,0,x) enddef ; -vardef constant_fit (suffix p, $) (text t) = polynomial_fit(p, $, 0, t) ; enddef ; - -% y = a1 * exp(a0*x) -% -% exp and ln defined in metafun - -vardef exponential_function (suffix $) (expr x) = $1*exp($0*x) enddef ; - -% since we take a log, this only works for positive ordinates - -vardef exponential_fit (suffix p, $) (text t) = - save a ; numeric a[] ; - save q ; path q[] ; % fit to the log of the ordinate - for i=0 upto length p : - clearxy ; z = point i of p ; - if y>0 : - augment.q0(x,ln(y)) ; - augment.q1( - if known t : - if numeric t : (0,ln(t)) - elseif pair t : (xpart t,ln(ypart t)) - elseif path t : - if length t>=i : - hide(z1 = point i of t;) - (x1,ln(y1)) - else : - origin - fi - fi - else : - (0,1) - fi ) ; - fi - endfor - linear_fit(q0,a,q1) ; - save e ; e := exp(sqrt(fit_chi_squared)) ; - fit_chi_squared := e * e ; - $0 := a1 ; - $1 := exp(a0) ; -enddef ; - -% y = a1 * x**a0 - -vardef power_law_function (suffix $) (expr x) = $1*(x**$0) enddef ; - -% since we take logs, this only works for positive abscissae and ordinates - -vardef power_law_fit (suffix p, $) (text t) = - save a ; numeric a[] ; - save q ; path q[] ; % fit to the logs of the abscissae and ordinates - for i=0 upto length p : - clearxy ; z = point i of p ; - if (x>0) and (y>0) : - augment.q0(ln(x),ln(y)) ; - augment.q1( - if known t : - if numeric t : (0,ln(t)) - elseif pair t : (ln(xpart t),ln(ypart t)) - elseif path t : - if length t>=i : - hide(z1 = point i of t) - (ln(x1),ln(y1)) - else : - origin - fi - fi - else : - (0,1) - fi ) ; - fi - endfor - linear_fit(q0,a,q1) ; - save e ; e := exp(sqrt(fit_chi_squared)) ; - fit_chi_squared := e * e ; - $0 := a1 ; - $1 := exp(a0) ; -enddef ; - -% gaussian : y = a2 * exp(-ln(2)*((x-a0)/a1)^2) -% -% a1 is the hwhm ; sigma := a1/sqrt(2ln(2)) or a1/1.17741 - -newinternal lntwo ; lntwo := ln(2) ; % brrr, why not inline it - -vardef gaussian_function (suffix $) (expr x) = - if $1 = 0 : - if x = $0 : $2 else : 0 fi - else : - $2 * exp(-lntwo*(((x-$0)/$1)**2)) - fi - if known $3 : - + $3 - fi -enddef ; - -% since we take a log, this only works for positive ordinates - -vardef gaussian_fit (suffix p, $) (text t) = - save a ; numeric a[] ; - save q ; path q[] ; % fit to the log of the ordinate - for i=0 upto length p : - clearxy ; z = point i of p ; - if y>0 : - augment.q0(x,ln(y)) ; - augment.q1( - if known t : - if numeric t : (0,ln(t)) - elseif pair t : (xpart t,ln(ypart t)) - elseif path t : - if length t>=i : - hide(z1 = point i of t) - (x1,ln(y1)) - else : - origin - fi - fi - else : - (0,1) - fi ) ; - fi - endfor - polynomial_fit(q0,a,2,q1) ; - save e ; e := exp(sqrt(fit_chi_squared)) ; - fit_chi_squared := e * e ; - $1 := sqrt(-lntwo/a2) ; - $0 := -.5a1/a2 ; - $2 := exp(a0-.25*a1*a1/a2) ; - $3 := 0 ; % polynomial_fit will NOT work with a non-zero background! -enddef ; - -% lorentzian: y = a2 / (1 + ((x - a0)/a1)^2) - -vardef lorentzian_function (suffix $) (expr x) = - if $1 = 0 : - if x = $0 : $2 else : 0 fi - else : - $2 / (1 + ((x - $0)/$1)**2) - fi - if known $3 : - + $3 - fi -enddef ; - -vardef lorentzian_fit (suffix p, $) (text t) = - save a ; numeric a[] ; - save q ; path q ; % fit to the inverse of the ordinate - for i=0 upto length p : - if ypart(point i of p)<>0 : - augment.q(xpart(point i of p), 1/ypart(point i of p)) ; - fi - endfor - polynomial_fit(q,a,2,if t <> 0 : 1/(t) else : 0 fi) ; - fit_chi_squared := 1/fit_chi_squared ; - $0 := -.5a1/a2 ; - $2 := 1/(a0-.25a1*a1/a2) ; - $1 := sqrt((a0-.25a1*a1/a2)/a2) ; - $3 := 0 ; % polynomial_fit will NOT work with a non-zero background! -enddef ; diff --git a/metapost/context/base/mp-grid.mpii b/metapost/context/base/mp-grid.mpii deleted file mode 100644 index ea28d60af..000000000 --- a/metapost/context/base/mp-grid.mpii +++ /dev/null @@ -1,149 +0,0 @@ -%D \module -%D [ file=mp-grid.mpii, -%D version=2000.07.10, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=grid support, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -%D Under construction. - -if known context_grid : endinput ; fi ; - -boolean context_grid ; context_grid := true ; - -string fmt_separator ; fmt_separator := "@" ; -numeric fmt_precision ; fmt_precision := 3 ; -boolean fmt_initialize ; fmt_initialize := false ; -boolean fmt_zerocheck ; fmt_zerocheck := true ; - -if unknown fmt_loaded : input "mp-form.mpii" ; fi ; - -boolean fmt_pictures ; fmt_pictures := true ; - -def do_format = if fmt_pictures : format else : formatstr fi enddef ; -def do_mformat = if fmt_pictures : Mformat else : Mformatstr fi enddef ; - -numeric grid_eps ; grid_eps = eps ; - -def hlingrid (expr Min, Max, Step, Length, Width) text t = - image ( for i=Min step Step until Max+grid_eps : - draw (origin--(Width,0)) shifted (0,i*(Length/Max)) t ; - endfor ; ) ; -enddef ; - -def vlingrid (expr Min, Max, Step, Length, Height) text t = - image ( for i=Min step Step until Max+grid_eps : - draw (origin--(0,Height)) shifted (i*(Length/Max),0) t ; - endfor ; ) ; -enddef ; - -def hloggrid (expr Min, Max, Step, Length, Width) text t = - image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw (origin--(Width,0)) shifted (0,Length*log(i)) t ; - endfor ; ) ; -enddef ; - -def vloggrid (expr Min, Max, Step, Length, Height) text t = - image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw (origin--(0,Height)) shifted (Length*log(i),0) t ; - endfor ; ) ; -enddef ; - -vardef hlintext@#(expr Min, Max, Step, Length, Format) text t = - image ( do_initialize_numbers ; - for i=Min step Step until Max+grid_eps : - draw textext@#(do_format(Format,i)) shifted (0,i*(Length/Max)) t ; - endfor ; ) -enddef ; - -vardef vlintext@#(expr Min, Max, Step, Length, Format) text t = - image ( do_initialize_numbers ; - for i=Min step Step until Max+grid_eps : - draw textext@#(do_format(Format,i)) shifted (i*(Length/Max),0) t ; - endfor ; ) -enddef ; - -vardef hlogtext@#(expr Min, Max, Step, Length, Format) text t = - image ( do_initialize_numbers ; - for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw textext@#(do_format(Format,i)) shifted (0,Length*log(i)) t ; - endfor ; ) -enddef ; - -vardef vlogtext@#(expr Min, Max, Step, Length, Format) text t = - image ( do_initialize_numbers ; - for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw textext@#(do_format(Format,i)) shifted (Length*log(i),0) t ; - endfor ; ) -enddef ; - -vardef hlinlabel@#(expr Min, Max, Step, Length) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw thelabel@#(decimal i,(0,i*(Length/Max))) t ; - endfor ; ) -enddef ; - -vardef vlinlabel@#(expr Min, Max, Step, Length) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw thelabel@#(decimal i,(i*(Length/Max),0)) t ; - endfor ; ) -enddef ; - -boolean numbers_initialized ; numbers_initialized := false ; - -def do_initialize_numbers = - if not numbers_initialized : - init_numbers ( textext.raw("$-$") , - textext.raw("$1$") , - textext.raw("${\times}10$") , - textext.raw("${}^-$") , - textext.raw("${}^2$") ) ; - if unknown _trial_run_ : - numbers_initialized := true ; - else : - % no reset, otherwise textexts get out of sync - % slows down graphics a bit but not much - fi ; - fi ; -enddef ; - -def initialize_numbers = - numbers_initialized := false ; do_initialize_numbers ; -enddef ; - -vardef linlog(expr xy) = ( xpart xy, log(ypart xy)) enddef ; -vardef loglin(expr xy) = (log(xpart xy), ypart xy) enddef ; -vardef loglog(expr xy) = (log(xpart xy), log(ypart xy)) enddef ; -vardef linlin(expr xy) = ( (xpart xy), (ypart xy)) enddef ; - -vardef loglinpath primary p = processpath (p) (loglin) enddef ; -vardef linlogpath primary p = processpath (p) (linlog) enddef ; -vardef loglogpath primary p = processpath (p) (loglog) enddef ; -vardef linlinpath primary p = processpath (p) (linlin) enddef ; - -def processpath (expr p) (text pp) = - if path p : - for i=0 upto length(p)-1 : - (pp(point i of p)) .. controls - (pp(postcontrol i of p)) and - (pp(precontrol (i+1) of p)) .. - endfor - if cycle p : - cycle - else : - (pp(point length(p) of p)) - fi - elseif pair p : - (pp(p)) - else : - p - fi -enddef ; diff --git a/metapost/context/base/mp-grid.mpiv b/metapost/context/base/mp-grid.mpiv deleted file mode 100644 index b9243b1b9..000000000 --- a/metapost/context/base/mp-grid.mpiv +++ /dev/null @@ -1,142 +0,0 @@ -%D \module -%D [ file=mp-grid.mpiv, -%D version=2000.07.10, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=grid support, -%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. - -%D Under construction. - -if known context_grid : endinput ; fi ; - -boolean context_grid ; context_grid := true ; - -string fmt_separator ; fmt_separator := "@" ; -numeric fmt_precision ; fmt_precision := 3 ; -boolean fmt_initialize ; fmt_initialize := false ; -boolean fmt_zerocheck ; fmt_zerocheck := true ; - -if unknown fmt_loaded : input "mp-form.mpiv" ; fi ; - -boolean fmt_pictures ; fmt_pictures := true ; - -def do_format = if fmt_pictures : format else : formatstr fi enddef ; -def do_mformat = if fmt_pictures : Mformat else : Mformatstr fi enddef ; - -numeric grid_eps ; grid_eps = eps ; - -def hlingrid (expr Min, Max, Step, Length, Width) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw (origin--(Width,0)) shifted (0,i*(Length/Max)) t ; - endfor ; - ) ; -enddef ; - -def vlingrid (expr Min, Max, Step, Length, Height) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw (origin--(0,Height)) shifted (i*(Length/Max),0) t ; - endfor ; - ) ; -enddef ; - -def hloggrid (expr Min, Max, Step, Length, Width) text t = - image ( - for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw (origin--(Width,0)) shifted (0,Length*log(i)) t ; - endfor ; - ) ; -enddef ; - -def vloggrid (expr Min, Max, Step, Length, Height) text t = - image ( - for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw (origin--(0,Height)) shifted (Length*log(i),0) t ; - endfor ; - ) ; -enddef ; - -vardef hlintext@#(expr Min, Max, Step, Length, Format) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw textext@#(mfun_format_number(Format,i)) shifted (0,i*(Length/Max)) t ; - endfor ; - ) -enddef ; - -vardef vlintext@#(expr Min, Max, Step, Length, Format) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw textext@#(mfun_format_number(Format,i)) shifted (i*(Length/Max),0) t ; - endfor ; - ) -enddef ; - -vardef hlogtext@#(expr Min, Max, Step, Length, Format) text t = - image ( - for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw textext@#(mfun_format_number(Format,i)) shifted (0,Length*log(i)) t ; - endfor ; - ) -enddef ; - -vardef vlogtext@#(expr Min, Max, Step, Length, Format) text t = - image ( - for i=max(Min,1) step Step until min(Max,10)+grid_eps : - draw textext@#(mfun_format_number(Format,i)) shifted (Length*log(i),0) t ; - endfor ; - ) -enddef ; - -vardef hlinlabel@#(expr Min, Max, Step, Length) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw thelabel@#(decimal i,(0,i*(Length/Max))) t ; - endfor ; - ) -enddef ; - -vardef vlinlabel@#(expr Min, Max, Step, Length) text t = - image ( - for i=Min step Step until Max+grid_eps : - draw thelabel@#(decimal i,(i*(Length/Max),0)) t ; - endfor ; - ) -enddef ; - -vardef linlog(expr xy) = ( xpart xy, log(ypart xy)) enddef ; -vardef loglin(expr xy) = (log(xpart xy), ypart xy) enddef ; -vardef loglog(expr xy) = (log(xpart xy), log(ypart xy)) enddef ; -vardef linlin(expr xy) = ( (xpart xy), (ypart xy)) enddef ; - -vardef loglinpath primary p = processpath (p) (loglin) enddef ; -vardef linlogpath primary p = processpath (p) (linlog) enddef ; -vardef loglogpath primary p = processpath (p) (loglog) enddef ; -vardef linlinpath primary p = processpath (p) (linlin) enddef ; - -vardef processpath (expr p) (text pp) = - if path p : - for i=0 upto length(p)-1 : - pp(point i of p) .. controls - pp(postcontrol i of p) and - pp(precontrol (i+1) of p) .. - endfor - if cycle p : - cycle - else : - pp(point length(p) of p) - fi - elseif pair p : - pp(p) - else : - p - fi -enddef ; - diff --git a/metapost/context/base/mp-grph.mpii b/metapost/context/base/mp-grph.mpii deleted file mode 100644 index 782942946..000000000 --- a/metapost/context/base/mp-grph.mpii +++ /dev/null @@ -1,310 +0,0 @@ -%D \module -%D [ file=mp-grph.mpii, -%D version=2000.12.14, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=graphic text support, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -%D Under construction. - -if known context_grph : endinput ; fi ; - -boolean context_grph ; context_grph := true ; - -string CRLF ; CRLF := char 10 & char 13 ; - -picture _currentpicture_ ; - -numeric _fig_nesting_ ; _fig_nesting_ := 0 ; - -def beginfig (expr c) = - _fig_nesting_ := _fig_nesting_ + 1 ; - if _fig_nesting_ = 1 : - begingroup - charcode := c ; - resetfig ; - scantokens extra_beginfig ; - fi ; -enddef ; - -def endfig = - ; % safeguard - if _fig_nesting_ = 1 : - scantokens extra_endfig; - shipit ; - endgroup ; - fi ; - _fig_nesting_ := _fig_nesting_ - 1 ; -enddef; - - -def resetfig = - clearxy ; - clearit ; - clearpen ; - pickup defaultpen ; - interim linecap := linecap ; - interim linejoin := linejoin ; - interim miterlimit := miterlimit ; - save _background_ ; color _background_ ; _background_ := background ; - save background ; color background ; background := _background_ ; - drawoptions () ; -enddef ; - -def protectgraphicmacros = - save showtext ; - save beginfig ; let beginfig = begingraphictextfig ; - save endfig ; let endfig = endgraphictextfig ; - save end ; let end = relax ; - interim prologues := prologues ; - resetfig ; % resets currentpicture -enddef ; - -numeric currentgraphictext ; currentgraphictext := 0 ; -string graphictextformat ; graphictextformat := "plain" ; -string graphictextstring ; graphictextstring := "" ; -string graphictextfile ; graphictextfile := "dummy.mpo" ; - -def data_mpo_file = job_name & "-mpgraph.mpo" enddef ; -def data_mpy_file = job_name & "-mpgraph.mpy" enddef ; - -if unknown mplib : - - def savegraphictext (expr str) = - if (graphictextstring<>"") : - write graphictextstring to data_mpo_file ; - graphictextstring := "" ; - fi ; - write str to data_mpo_file ; - let erasegraphictextfile = relax ; - enddef ; - - def erasegraphictextfile = - write EOF to data_mpo_file ; - let erasegraphictextfile = relax ; - enddef ; - - extra_beginfig := extra_beginfig & " erasegraphictextfile ;" ; - -fi ; - -def begingraphictextfig (expr n) = - foundpicture := n ; scratchpicture := nullpicture ; -enddef ; - -def endgraphictextfig = - if foundpicture = currentgraphictext : - expandafter endinput - else : - scratchpicture := nullpicture ; - fi ; -enddef ; - -def loadfigure primary filename = - doloadfigure (filename) -enddef ; - -def doloadfigure (expr filename) text figureattributes = - begingroup ; - save figurenumber, figurepicture, number, fixedplace ; - numeric figurenumber ; figurenumber := 0 ; - boolean figureshift ; figureshift := true ; - picture figurepicture ; figurepicture := currentpicture ; - def number primary n = hide(figurenumber := n) enddef ; - def fixedplace = hide(figureshift := false) enddef ; - protectgraphicmacros ; - % defaults - interim linecap := rounded ; - interim linejoin := rounded ; - interim miterlimit := 10 ; - % - currentpicture := nullpicture ; - draw fullcircle figureattributes ; % expand number - currentpicture := nullpicture ; - def beginfig (expr n) = - currentpicture := nullpicture ; - if (figurenumber=n) or (figurenumber=0) : - let endfig = endinput ; - fi ; - enddef ; - let endfig = relax ; - readfile(filename) ; - if figureshift : - currentpicture := currentpicture shifted -llcorner currentpicture ; - fi ; - addto figurepicture also currentpicture figureattributes ; - currentpicture := figurepicture ; - endgroup ; -enddef ; - -def graphictext primary t = - dographictext(t) -enddef ; - -def dographictext (expr t) = - begingroup ; - save figurepicture ; picture figurepicture ; - figurepicture := currentpicture ; currentpicture := nullpicture ; - if graphictextformat<>"" : - graphictextstring := - "% format=" & graphictextformat & CRLF & graphictextstring ; - graphictextformat := "" ; - fi ; - currentgraphictext := currentgraphictext + 1 ; - if unknown mplib : - savegraphictext ("\startTEXpage[scale=10000]" & t & "\stopTEXpage") ; - fi ; - dofinishgraphictext -enddef ; - -def redographictext primary t = - regraphictext(t) -enddef ; - -def regraphictext (expr t) = - begingroup ; - save figurepicture ; picture figurepicture ; - figurepicture := currentpicture ; currentpicture := nullpicture ; - save currentgraphictext ; numeric currentgraphictext ; - currentgraphictext := t ; - dofinishgraphictext -enddef ; - -%D Believe it or not, but it took me half a day to uncover -%D the following neccessity: -%D -%D \starttypen -%D save withfillcolor, withdrawcolor ; -%D \stoptypen -%D -%D When we have more than one graphictext, these will be -%D defined after the first graphic. For some obscure reason, -%D this means that in the next graphic they will be called, but -%D afterwards the data and boolean are not set. Don't ask me -%D why. - -def dofinishgraphictext text x_op_x = - protectgraphicmacros ; % resets currentpicture - interim linecap := butt ; % normally rounded - interim linejoin := mitered ; % normally rounded - interim miterlimit := 10 ; % todo - let normalwithshade = withshade ; - save foundpicture, scratchpicture, str ; - save fill, draw, withshade, reversefill, outlinefill ; - save withfillcolor, withdrawcolor ; % quite important - numeric foundpicture ; picture scratchpicture ; string str ; - def draw expr p = - % the first, naive implementation was: - % addto scratchpicture doublepath p withpen currentpen ; - % but it is better to turn lines into fills - addto scratchpicture contour boundingbox - image (addto currentpicture doublepath p withpen currentpen) ; - enddef ; - def fill expr p = - addto scratchpicture contour p withpen currentpen ; - enddef ; - def f_op_f = enddef ; boolean f_color ; f_color := false ; - def d_op_d = enddef ; boolean d_color ; d_color := false ; - def s_op_s = enddef ; boolean s_color ; s_color := false ; - boolean reverse_fill ; reverse_fill := false ; - boolean outline_fill ; outline_fill := false ; - def reversefill = - hide(reverse_fill := true ) - enddef ; - def outlinefill = - hide(outline_fill := true ) - enddef ; - def withshade primary c = - hide(def s_op_s = normalwithshade c enddef ; s_color := true ) - enddef ; - def withfillcolor primary c = - hide(def f_op_f = withcolor c enddef ; f_color := true ) - enddef ; - def withdrawcolor primary c = - hide(def d_op_d = withcolor c enddef ; d_color := true ) - enddef ; - scratchpicture := nullpicture ; - addto scratchpicture doublepath origin x_op_x ; % pre-roll - for i within scratchpicture : % Below here is a dirty tricky test! - if (urcorner dashpart i) = origin : outline_fill := false ; fi ; - endfor ; - scratchpicture := nullpicture ; - readfile(data_mpy_file) ; - scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ; - if not d_color and not f_color : d_color := true ; fi - if s_color : d_color := false ; f_color := false ; fi ; - currentpicture := figurepicture ; - if d_color and not reverse_fill : - for i within scratchpicture : - if f_color and outline_fill : - addto currentpicture doublepath pathpart i _op_ x_op_x f_op_f - dashed nullpicture ; - fi ; - if filled i : - addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; - fi ; - endfor ; - fi ; - if f_color : - for i within scratchpicture : - if filled i : - addto currentpicture contour pathpart i _op_ x_op_x f_op_f - withpen pencircle scaled 0 ; - fi ; - endfor ; - fi ; - if d_color and reverse_fill : - for i within scratchpicture : - if filled i : - addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; - fi ; - endfor ; - fi ; - if s_color : - for i within scratchpicture : - if filled i : - addto currentpicture contour pathpart i _op_ x_op_x s_op_s ; - fi ; - endfor ; - else : - for i within scratchpicture : - if stroked i : - addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; - fi ; - endfor ; - fi ; - endgroup ; -enddef ; - -def resetgraphictextdirective = - graphictextstring := "" ; -enddef ; - -def graphictextdirective text t = - graphictextstring := graphictextstring & t & CRLF ; -enddef ; - -% example -% -% % graphictextformat := "context" ; -% % graphictextformat := "plain" ; -% -% beginfig (1) ; -% graphictext -% "\vbox{\hsize10cm \input tufte }" -% scaled 8 -% withdrawcolor blue -% withfillcolor red -% withpen pencircle scaled 2pt ; -% endfig ; -% -% beginfig(1) ; -% loadfigure "gracht.mp" rotated 20 ; -% loadfigure "koe.mp" number 1 scaled 2 ; -% endfig ; diff --git a/metapost/context/base/mp-grph.mpiv b/metapost/context/base/mp-grph.mpiv deleted file mode 100644 index a3c057a98..000000000 --- a/metapost/context/base/mp-grph.mpiv +++ /dev/null @@ -1,263 +0,0 @@ -%D \module -%D [ file=mp-grph.mpiv, -%D version=2000.12.14, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=graphic text support, -%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. - -%D Under construction. - -if known context_grph : endinput ; fi ; - -boolean context_grph ; context_grph := true ; - -picture _currentpicture_ ; - -numeric _fig_nesting_ ; _fig_nesting_ := 0 ; - -def beginfig (expr c) = - _fig_nesting_ := _fig_nesting_ + 1 ; - if _fig_nesting_ = 1 : - begingroup - charcode := c ; - resetfig ; - scantokens extra_beginfig ; - fi ; -enddef ; - -def endfig = - ; % safeguard - if _fig_nesting_ = 1 : - scantokens extra_endfig ; - shipit ; - endgroup ; - fi ; - _fig_nesting_ := _fig_nesting_ - 1 ; -enddef; - -def resetfig = - clearxy ; - clearit ; - clearpen ; - pickup defaultpen ; - interim linecap := linecap ; - interim linejoin := linejoin ; - interim miterlimit := miterlimit ; - save _background_ ; color _background_ ; _background_ := background ; - save background ; color background ; background := _background_ ; - drawoptions () ; -enddef ; - -def protectgraphicmacros = - save showtext ; - save beginfig ; let beginfig = begingraphictextfig ; - save endfig ; let endfig = endgraphictextfig ; - save end ; let end = relax ; - interim prologues := prologues ; - resetfig ; % resets currentpicture -enddef ; - -numeric currentgraphictext ; currentgraphictext := 0 ; - -def data_mpo_file = job_name & "-mpgraph.mpo" enddef ; -def data_mpy_file = job_name & "-mpgraph.mpy" enddef ; - -def begingraphictextfig (expr n) = - foundpicture := n ; - scratchpicture := nullpicture ; -enddef ; - -def endgraphictextfig = - if foundpicture = currentgraphictext : - expandafter endinput - else : - scratchpicture := nullpicture ; - fi ; -enddef ; - -def loadfigure primary filename = - doloadfigure (filename) -enddef ; - -def doloadfigure (expr filename) text figureattributes = - begingroup ; - save figurenumber, figurepicture, number, fixedplace ; - numeric figurenumber ; figurenumber := 0 ; - boolean figureshift ; figureshift := true ; - picture figurepicture ; figurepicture := currentpicture ; - def number primary n = hide(figurenumber := n) enddef ; - def fixedplace = hide(figureshift := false) enddef ; - protectgraphicmacros ; - % defaults - interim linecap := rounded ; - interim linejoin := rounded ; - interim miterlimit := 10 ; - % - currentpicture := nullpicture ; - draw fullcircle figureattributes ; % expand number - currentpicture := nullpicture ; - def beginfig (expr n) = - currentpicture := nullpicture ; - if (figurenumber=n) or (figurenumber=0) : - let endfig = endinput ; - fi ; - enddef ; - let endfig = relax ; - readfile(filename) ; - if figureshift : - currentpicture := currentpicture shifted -llcorner currentpicture ; - fi ; - addto figurepicture also currentpicture figureattributes ; - currentpicture := figurepicture ; - endgroup ; -enddef ; - -def graphictext primary t = - hide ( - if mfun_trial_run : - let mfun_graphic_text = mfun_no_graphic_text ; - else : - let mfun_graphic_text = mfun_do_graphic_text ; - fi - ) - mfun_graphic_text(t) -enddef ; - -def mfun_do_graphic_text (expr t) = - % withprescript "gt_stage=final" - begingroup ; - save figurepicture ; picture figurepicture ; - figurepicture := currentpicture ; currentpicture := nullpicture ; - currentgraphictext := currentgraphictext + 1 ; - mfun_finish_graphic_text % picks up directives -enddef ; - -def mfun_no_graphic_text (expr t) text rest = - currentgraphictext := currentgraphictext + 1 ; - draw unitsquare - withprescript "gt_stage=trial" - withprescript "gt_index=" & decimal currentgraphictext - withpostscript t -enddef ; - -def mfun_finish_graphic_text text x_op_x = - protectgraphicmacros ; % resets currentpicture - interim linecap := butt ; % normally rounded - interim linejoin := mitered ; % normally rounded - interim miterlimit := 10 ; % todo - let normalwithshade = withshade ; - save foundpicture, scratchpicture, str ; - save fill, draw, withshade, reversefill, outlinefill ; - save withfillcolor, withdrawcolor ; % quite important - numeric foundpicture ; picture scratchpicture ; string str ; - def draw expr p = - % the first, naive implementation was: - % addto scratchpicture doublepath p withpen currentpen ; - % but it is better to turn lines into fills - addto scratchpicture contour boundingbox - image (addto currentpicture doublepath p withpen currentpen) ; - enddef ; - def fill expr p = - addto scratchpicture contour p withpen currentpen ; - enddef ; - def f_op_f = enddef ; boolean f_color ; f_color := false ; - def d_op_d = enddef ; boolean d_color ; d_color := false ; - def s_op_s = enddef ; boolean s_color ; s_color := false ; - boolean reverse_fill ; reverse_fill := false ; - boolean outline_fill ; outline_fill := false ; - def reversefill = - hide(reverse_fill := true ) - enddef ; - def outlinefill = - hide(outline_fill := true ) - enddef ; - def withshade primary c = - hide(def s_op_s = normalwithshade c enddef ; s_color := true ) - enddef ; - def withfillcolor primary c = - hide(def f_op_f = withcolor c enddef ; f_color := true ) - enddef ; - def withdrawcolor primary c = - hide(def d_op_d = withcolor c enddef ; d_color := true ) - enddef ; - scratchpicture := nullpicture ; - addto scratchpicture doublepath origin x_op_x ; % pre-roll - for i within scratchpicture : % Below here is a dirty tricky test! - if (urcorner dashpart i) = origin : - outline_fill := false ; - fi ; - endfor ; - scratchpicture := nullpicture ; - readfile(data_mpy_file) ; - scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ; - if not d_color and not f_color : - d_color := true ; - fi - if s_color : - d_color := false ; - f_color := false ; - fi ; - currentpicture := figurepicture ; - if d_color and not reverse_fill : - for i within scratchpicture : - if f_color and outline_fill : - addto currentpicture doublepath pathpart i _op_ x_op_x f_op_f dashed nullpicture ; - fi ; - if filled i : - addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; - fi ; - endfor ; - fi ; - if f_color : - for i within scratchpicture : - if filled i : - addto currentpicture contour pathpart i _op_ x_op_x f_op_f withpen pencircle scaled 0 ; - fi ; - endfor ; - fi ; - if d_color and reverse_fill : - for i within scratchpicture : - if filled i : - addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; - fi ; - endfor ; - fi ; - if s_color : - for i within scratchpicture : - if filled i : - addto currentpicture contour pathpart i _op_ x_op_x s_op_s ; - fi ; - endfor ; - else : - for i within scratchpicture : - if stroked i : - addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; - fi ; - endfor ; - fi ; - endgroup ; -enddef ; - -% example -% -% beginfig (1) ; -% graphictext -% "\vbox{\hsize10cm \input tufte }" -% scaled 8 -% withdrawcolor blue -% withfillcolor red -% withpen pencircle scaled 2pt ; -% endfig ; -% -% beginfig(1) ; -% loadfigure "gracht.mp" rotated 20 ; -% loadfigure "koe.mp" number 1 scaled 2 ; -% endfig ; -% -% end diff --git a/metapost/context/base/mp-idea.mpiv b/metapost/context/base/mp-idea.mpiv deleted file mode 100644 index 462d97553..000000000 --- a/metapost/context/base/mp-idea.mpiv +++ /dev/null @@ -1,30 +0,0 @@ -% redpart (1,1,0,0) crashes - -% let normalredpart = redpart ; -% let normalgreenpart = greenpart ; -% let normalbluepart = bluepart ; -% let normalcyanpart = cyanpart ; -% let normalmagentapart = magentapart ; -% let normalyellowpart = yellowpart ; -% let normalblackpart = blackpart ; - -% vardef redpart expr p = if cmykcolor p : 1 - normalcyanpart p elseif rgbcolor p : normalredpart p else : p fi enddef ; -% vardef greenpart expr p = if cmykcolor p : 1 - normalmagentapart p elseif rgbcolor p : normalgreenpart p else : p fi enddef ; -% vardef bluepart expr p = if cmykcolor p : 1 - normalyellowpart p elseif rgbcolor p : normalbluepart p else : p fi enddef ; -% vardef cyanpart expr p = if cmykcolor p : normalcyanpart p elseif rgbcolor p : 1 - normalredpart p else : p fi enddef ; -% vardef magentapart expr p = if cmykcolor p : normalmagentapart p elseif rgbcolor p : 1 - normalgreenpart p else : p fi enddef ; -% vardef yellowpart expr p = if cmykcolor p : normalyellowpart p elseif rgbcolor p : 1 - normalbluepart p else : p fi enddef ; -% vardef blackpart expr p = if cmykcolor p : normalblackpart p elseif rgbcolor p : 0 else : p fi enddef ; - -vardef rcomponent expr p = if rgbcolor p : redpart p elseif cmykcolor p : 1 - cyanpart p else : p fi enddef ; -vardef gcomponent expr p = if rgbcolor p : greenpart p elseif cmykcolor p : 1 - magentapart p else : p fi enddef ; -vardef bcomponent expr p = if rgbcolor p : bluepart p elseif cmykcolor p : 1 - yellowpart p else : p fi enddef ; -vardef ccomponent expr p = if cmykcolor p : cyanpart p elseif rgbcolor p : 1 - redpart p else : p fi enddef ; -vardef mcomponent expr p = if cmykcolor p : magentapart p elseif rgbcolor p : 1 - greenpart p else : p fi enddef ; -vardef ycomponent expr p = if cmykcolor p : yellowpart p elseif rgbcolor p : 1 - bluepart p else : p fi enddef ; -vardef bcomponent expr p = if cmykcolor p : blackpart p elseif rgbcolor p : 0 else : p fi enddef ; - -vardef somecolor = (1,1,0,0) enddef ; - -fill OverlayBox withcolor (rcomponent somecolor,gcomponent somecolor,bcomponent somecolor) ; -fill OverlayBox withcolor (ccomponent somecolor,mcomponent somecolor,ycomponent somecolor,bcomponent somecolor) ; diff --git a/metapost/context/base/mp-luas.mpiv b/metapost/context/base/mp-luas.mpiv deleted file mode 100644 index c919ba215..000000000 --- a/metapost/context/base/mp-luas.mpiv +++ /dev/null @@ -1,99 +0,0 @@ -%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 deleted file mode 100644 index b19f47f1e..000000000 --- a/metapost/context/base/mp-mlib.mpiv +++ /dev/null @@ -1,1213 +0,0 @@ -%D \module -%D [ file=mp-mlib.mpiv, -%D version=2008.03.21, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=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 unknown mplib : endinput ; fi ; -if known context_mlib : endinput ; fi ; - -boolean context_mlib ; context_mlib := true ; - -%D Color and transparency -%D -%D Separable: - -newinternal normaltransparent ; normaltransparent := 1 ; -newinternal multiplytransparent ; multiplytransparent := 2 ; -newinternal screentransparent ; screentransparent := 3 ; -newinternal overlaytransparent ; overlaytransparent := 4 ; -newinternal softlighttransparent ; softlighttransparent := 5 ; -newinternal hardlighttransparent ; hardlighttransparent := 6 ; -newinternal colordodgetransparent ; colordodgetransparent := 7 ; -newinternal colorburntransparent ; colorburntransparent := 8 ; -newinternal darkentransparent ; darkentransparent := 9 ; -newinternal lightentransparent ; lightentransparent := 10 ; -newinternal differencetransparent ; differencetransparent := 11 ; -newinternal exclusiontransparent ; exclusiontransparent := 12 ; - -%D Nonseparable: - -newinternal huetransparent ; huetransparent := 13 ; -newinternal saturationtransparent ; saturationtransparent := 14 ; -newinternal colortransparent ; colortransparent := 15 ; -newinternal luminositytransparent ; luminositytransparent := 16 ; - -vardef transparency_alternative_to_number(expr name) = - if string name : - if expandafter known scantokens(name & "transparent") : - scantokens(name & "transparent") - else : - 0 - fi - elseif name < 17 : - name - else : - 0 - fi -enddef ; - -def namedcolor (expr n) = - 1 - withprescript "sp_type=named" - 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=" & colordecimals v -enddef ; - -def multitonecolor(expr name)(text t) = - 1 - withprescript "sp_type=multitone" - withprescript "sp_name=" & name - withprescript "sp_value=" & colordecimalslist(t) -enddef ; - -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(a) - withprescript "tr_transparency=" & decimal t - withcolor c -enddef ; - -% 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 - (c,m,y,k) -enddef ; - -% Texts (todo: better strut ratio, now .7 hardcoded, should be passed) - -newinternal textextoffset ; textextoffset := 0 ; - -%%%%%%% mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ; % we can consider using colors (less hash space) -color mfun_tt_b ; -numeric mfun_tt_n ; mfun_tt_n := 0 ; -picture mfun_tt_p ; mfun_tt_p := nullpicture ; -picture mfun_tt_o ; mfun_tt_o := nullpicture ; -picture mfun_tt_c ; mfun_tt_c := nullpicture ; - -if unknown mfun_trial_run : - boolean mfun_trial_run ; - mfun_trial_run := false ; -else : - % already defined before the format is loaded -fi ; - -if unknown mfun_first_run : - boolean mfun_first_run ; - mfun_first_run := true ; -else : - % already defined before the format is loaded -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_endfig := "mfun_flush_tex_texts ;" & extra_endfig ; -extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ; - -% We collect and flush them all, as we can also have temporary textexts -% that gets never really flushed but are used for calculations. So, we -% 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. - -% see mp-keep.mpiv for older code - -% vardef rawtextext(expr s) = % todo: avoid currentpicture -% if s = "" : -% 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 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] -% 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 ; - -vardef rawtextext(expr s) = % todo: avoid currentpicture - if s = "" : - 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 s ; - addto mfun_tt_p also mfun_tt_c ; - else : - mfun_tt_b := lua.mp.tt_dimensions(mfun_tt_n) ; - addto mfun_tt_c doublepath unitsquare - 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" ; - fi ; - mfun_tt_c - fi -enddef ; - -% More text - -defaultfont := "Mono" ; -defaultscale := 1 ; - -extra_beginfig := extra_beginfig & "defaultscale:=1;" ; - -vardef fontsize expr name = - save size ; numeric size ; - size := bbwidth(textext("\MPfontsizehskip{" & name & "}")) ; - if size = 0 : - 12pt - else : - size - fi -enddef ; - -pair mfun_laboff ; mfun_laboff := (0,0) ; -pair mfun_laboff.lft ; mfun_laboff.lft := (-1,0) ; -pair mfun_laboff.rt ; mfun_laboff.rt := (1,0) ; -pair mfun_laboff.bot ; mfun_laboff.bot := (0,-1) ; -pair mfun_laboff.top ; mfun_laboff.top := (0,1) ; -pair mfun_laboff.ulft ; mfun_laboff.ulft := (-.7,.7) ; -pair mfun_laboff.urt ; mfun_laboff.urt := (.7,.7) ; -pair mfun_laboff.llft ; mfun_laboff.llft := -(.7,.7) ; -pair mfun_laboff.lrt ; mfun_laboff.lrt := (.7,-.7) ; - -pair mfun_laboff.d ; mfun_laboff.d := mfun_laboff ; -pair mfun_laboff.dlft ; mfun_laboff.dlft := mfun_laboff.lft ; -pair mfun_laboff.drt ; mfun_laboff.drt := mfun_laboff.rt ; -pair mfun_laboff.origin ; mfun_laboff.origin := origin ; -pair mfun_laboff.raw ; mfun_laboff.raw := origin ; - -pair mfun_laboff.l ; mfun_laboff.l := mfun_laboff.lft ; -pair mfun_laboff.r ; mfun_laboff.r := mfun_laboff.rt ; -pair mfun_laboff.b ; mfun_laboff.b := mfun_laboff.bot ; -pair mfun_laboff.t ; mfun_laboff.t := mfun_laboff.top ; -pair mfun_laboff.l_t ; mfun_laboff.l_t := mfun_laboff.ulft ; -pair mfun_laboff.r_t ; mfun_laboff.r_t := mfun_laboff.urt ; -pair mfun_laboff.l_b ; mfun_laboff.l_b := mfun_laboff.llft ; -pair mfun_laboff.r_b ; mfun_laboff.r_b := mfun_laboff.lrt ; -pair mfun_laboff.t_l ; mfun_laboff.t_l := mfun_laboff.ulft ; -pair mfun_laboff.t_r ; mfun_laboff.t_r := mfun_laboff.urt ; -pair mfun_laboff.b_l ; mfun_laboff.b_l := mfun_laboff.llft ; -pair mfun_laboff.b_r ; mfun_laboff.b_r := mfun_laboff.lrt ; - -mfun_labxf := 0.5 ; -mfun_labxf.lft := mfun_labxf.l := 1 ; -mfun_labxf.rt := mfun_labxf.r := 0 ; -mfun_labxf.bot := mfun_labxf.b := 0.5 ; -mfun_labxf.top := mfun_labxf.t := 0.5 ; -mfun_labxf.ulft := mfun_labxf.l_t := mfun_labxf.t_l := 1 ; -mfun_labxf.urt := mfun_labxf.r_t := mfun_labxf.t_r := 0 ; -mfun_labxf.llft := mfun_labxf.l_b := mfun_labxf.b_l := 1 ; -mfun_labxf.lrt := mfun_labxf.r_b := mfun_labxf.b_r := 0 ; - -mfun_labxf.d := mfun_labxf ; -mfun_labxf.dlft := mfun_labxf.lft ; -mfun_labxf.drt := mfun_labxf.rt ; -mfun_labxf.origin := 0 ; -mfun_labxf.raw := 0 ; - -mfun_labyf := 0.5 ; -mfun_labyf.lft := mfun_labyf.l := 0.5 ; -mfun_labyf.rt := mfun_labyf.r := 0.5 ; -mfun_labyf.bot := mfun_labyf.b := 1 ; -mfun_labyf.top := mfun_labyf.t := 0 ; -mfun_labyf.ulft := mfun_labyf.l_t := mfun_labyf.t_l := 0 ; -mfun_labyf.urt := mfun_labyf.r_t := mfun_labyf.t_r := 0 ; -mfun_labyf.llft := mfun_labyf.l_b := mfun_labyf.b_l := 1 ; -mfun_labyf.lrt := mfun_labyf.r_b := mfun_labyf.b_r := 1 ; - -mfun_labyf.d := mfun_labyf ; -mfun_labyf.dlft := mfun_labyf.lft ; -mfun_labyf.drt := mfun_labyf.rt ; -mfun_labyf.origin := 0 ; -mfun_labyf.raw := 0 ; - -mfun_labtype := 0 ; -mfun_labtype.lft := mfun_labtype.l := 1 ; -mfun_labtype.rt := mfun_labtype.r := 2 ; -mfun_labtype.bot := mfun_labtype.b := 3 ; -mfun_labtype.top := mfun_labtype.t := 4 ; -mfun_labtype.ulft := mfun_labtype.l_t := mfun_labtype.t_l := 5 ; -mfun_labtype.urt := mfun_labtype.r_t := mfun_labtype.t_r := 6 ; -mfun_labtype.llft := mfun_labtype.l_b := mfun_labtype.b_l := 7 ; -mfun_labtype.lrt := mfun_labtype.r_b := mfun_labtype.b_r := 8 ; -mfun_labtype.d := 10 ; -mfun_labtype.dlft := 11 ; -mfun_labtype.drt := 12 ; -mfun_labtype.origin := 0 ; -mfun_labtype.raw := 0 ; - -% installlabel.foo ( 0, 1, 1, (.5,-1) ) ; - -vardef installlabel@# (expr type, x, y, offset) = - numeric labtype@# ; labtype@# := type ; - pair laboff @# ; laboff @# := offset ; - numeric labxf @# ; labxf @# := x ; - numeric labyf @# ; labyf @# := y ; -enddef ; - -% we save the plain variant - -vardef plain_thelabel@#(expr p,z) = - if string p : - plain_thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z) - else : - p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) - fi -enddef; - -def plain_label = % takes two arguments, contrary to textext that takes one - draw plain_thelabel -enddef ; - -let mfun_label = label ; -let mfun_thelabel = thelabel ; - -def useplainlabels = % somehow let doesn't work for all code - def label = plain_label enddef ; - def thelabel = plain_thelabel enddef ; -enddef ; - -def usemetafunlabels = - let label = mfun_label ; - let thelabel = mfun_thelabel ; -enddef ; - -plain_compatibility_data := plain_compatibility_data & "save label, thelabel ;" & "useplainlabels ;" ; - -% next comes own own: - -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) : - shifted (0,ypart center p) - fi - shifted (z + textextoffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p)) - fi -enddef ; - -vardef textext@#(expr p) = % no draw here - thetextext@#(p,origin) -enddef ; - -vardef thelabel@#(expr p,z) = - if string p : - thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z) - else : - p shifted (z + labeloffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p)) - fi -enddef; - -def label = % takes two arguments, contrary to textext that takes one - draw thelabel -enddef ; - -vardef anchored@#(expr p, z) = % beware: no "+ mfun_laboff@#" here (never!) - p - if (mfun_labtype@# >= 10) : - shifted (0,ypart center p) - fi - shifted (z + (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p)) -enddef ; - -let normalinfont = infont ; - -primarydef s infont name = % nasty hack - if name = "" : - textext(s) - else : - textext("\definedfont[" & name & "]" & s) - fi -enddef ; - -% Helper - -string mfun_prescript_separator ; mfun_prescript_separator := char(13) ; - -% Shades - -% 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 ; - elseif (n=2) : a := lrcorner p ; b := ulcorner p ; - elseif (n=3) : a := urcorner p ; b := llcorner p ; - elseif (n=4) : a := ulcorner p ; b := lrcorner p ; - elseif (n=5) : a := .5[ulcorner p,llcorner p] ; b := .5[urcorner p,lrcorner p] ; - elseif (n=6) : a := .5[llcorner p,lrcorner p] ; b := .5[ulcorner p,urcorner p] ; - elseif (n=7) : a := .5[lrcorner p,urcorner p] ; b := .5[llcorner p,ulcorner p] ; - elseif (n=8) : a := .5[urcorner p,ulcorner p] ; b := .5[lrcorner p,llcorner p] ; - else : a := .5[ulcorner p,llcorner p] ; b := .5[urcorner p,lrcorner p] ; - fi ; -enddef ; - -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 ; - elseif (n=4) : ab := ulcorner p ; - else : ab := center p ; r := .5r ; - fi ; -enddef ; - -def circular_shade (expr p, n, ca, cb) = - begingroup ; - save ab, r ; pair ab ; numeric r ; - r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; - set_circular_vector(ab,r)(p,n) ; - fill p withcircularshade(ab,ab,0,r,ca,cb) ; - if trace_shades : - drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -def linear_shade (expr p, n, ca, cb) = - begingroup ; - save a, b ; pair a, b ; - set_linear_vector(a,b)(p,n) ; - fill p withlinearshade(a,b,ca,cb) ; - if trace_shades : - drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -string mfun_defined_cs_pre[] ; numeric mfun_defined_cs ; mfun_defined_cs := 0 ; - -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=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 ; - -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=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 ; - -% 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 ; -% set_linear_vector(a,b)(p,n) ; -% define_linear_shade (a,b,ca,cb) -% enddef ; -% -% vardef predefined_circular_shade (expr p, n, ca, cb) = -% save ab, r ; pair ab ; numeric r ; -% r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; -% set_circular_vector(ab,r)(p,n) ; -% define_circular_shade(ab,ab,0,r,ca,cb) -% enddef ; - -% Layers - -def onlayer primary name = - withprescript "la_name=" & name -enddef ; - -% Figures - -% def externalfigure primary filename = -% doexternalfigure (filename) -% enddef ; -% -% def doexternalfigure (expr filename) text transformation = -% if true : % a bit incompatible esp scaled 1cm now scaled the natural size -% draw rawtextext("\externalfigure[" & filename & "]") transformation ; -% else : -% draw unitsquare transformation withprescript "fg_name=" & filename ; -% fi ; -% enddef ; - -def withmask primary filename = - withprescript "fg_mask=" & filename -enddef ; - -def externalfigure primary filename = - if false : - rawtextext("\externalfigure[" & filename & "]") - else : - image ( - addto currentpicture doublepath unitsquare - withprescript "fg_name=" & filename ; - ) -% unitsquare -% withpen pencircle scaled 0 -% withprescript "fg_name=" & filename - fi -enddef ; - -def figure primary filename = - rawtextext("\externalfigure[" & filename & "]") -enddef ; - -% Positions - -def register (expr tag, width, height, offset) = -% draw image ( - addto currentpicture doublepath unitsquare xscaled width yscaled height shifted offset - withprescript "ps_label=" & tag ; -% ) ; % no transformations -enddef ; - -% Housekeeping - -extra_beginfig := extra_beginfig & "currentgraphictext := 0 ; " ; -extra_endfig := extra_endfig & "finishsavingdata ; " ; -extra_endfig := extra_endfig & "mfun_reset_tex_texts ; " ; - -% Bonus - -vardef verbatim(expr s) = - ditto & "\detokenize{" & s & "}" & ditto -enddef ; - -% New - -def bitmapimage(expr xresolution, yresolution, data) = - image ( - addto currentpicture doublepath unitsquare - withprescript "bm_xresolution=" & decimal xresolution - withprescript "bm_yresolution=" & decimal yresolution - withpostscript data ; - ) -enddef ; - -% Experimental: -% -% property p ; p = properties(withcolor (1,1,0,0)) ; -% fill fullcircle scaled 20cm withproperties p ; - -let property = picture ; - -vardef properties(text t) = - image(draw unitcircle t) -enddef ; - -if metapostversion < 1.770 : - - def withproperties expr p = - if colormodel p = 3 : - withcolor greypart p - elseif colormodel p = 5 : - withcolor (redpart p,greenpart p,bluepart p) - elseif colormodel p = 7 : - withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p) - fi - enddef ; - -else : - - def withproperties expr p = - if colormodel p = 3 : - withcolor greypart p - elseif colormodel p = 5 : - withcolor (redpart p,greenpart p,bluepart p) - elseif colormodel p = 7 : - withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p) - fi - withprescript prescriptpart p - withpostscript postscriptpart p - enddef ; - -fi ; - -% Experimental: - -primarydef t asgroup s = % s = isolated|knockout - begingroup - save grouppicture, wrappedpicture, groupbounds ; - picture grouppicture, wrappedpicture ; path groupbounds ; - grouppicture := if picture t : t else : image(draw t) fi ; - groupbounds := boundingbox grouppicture ; - wrappedpicture:= nullpicture ; - addto wrappedpicture contour groupbounds - withprescript "gr_state=start" - withprescript "gr_type=" & s - withprescript "gr_llx=" & decimal xpart llcorner groupbounds - withprescript "gr_lly=" & decimal ypart llcorner groupbounds - withprescript "gr_urx=" & decimal xpart urcorner groupbounds - withprescript "gr_ury=" & decimal ypart urcorner groupbounds ; - addto wrappedpicture also grouppicture ; - addto wrappedpicture contour groupbounds - withprescript "gr_state=stop" ; - wrappedpicture - endgroup -enddef ; - -% Also experimental ... needs to be made better ... so it can change! - -string mfun_auto_align[] ; - -mfun_auto_align[0] := "rt" ; -mfun_auto_align[1] := "urt" ; -mfun_auto_align[2] := "top" ; -mfun_auto_align[3] := "ulft" ; -mfun_auto_align[4] := "lft" ; -mfun_auto_align[5] := "llft" ; -mfun_auto_align[6] := "bot" ; -mfun_auto_align[7] := "lrt" ; -mfun_auto_align[8] := "rt" ; - -def autoalign(expr n) = - scantokens mfun_auto_align[round((n mod 360)/45)] -enddef ; - -% draw textext.autoalign(60) ("\strut oeps 1") ; -% draw textext.autoalign(160)("\strut oeps 2") ; -% draw textext.autoalign(260)("\strut oeps 3") ; -% draw textext.autoalign(360)("\strut oeps 4") ; - -% new -% -% passvariable("version","1.0") ; -% passvariable("number",123) ; -% passvariable("string","whatever") ; -% passvariable("point",(1,2)) ; -% passvariable("triplet",(1,2,3)) ; -% passvariable("quad",(1,2,3,4)) ; -% 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) & " " & - decimal xpart (precontrol i of p) & " " & - decimal ypart (precontrol i of p) & " " & - decimal xpart (postcontrol i of p) & " " & - decimal ypart (postcontrol i of p) -enddef ; - -vardef mfun_transform_to_string(expr t) = - decimal xxpart t & " " & % rx - decimal xypart t & " " & % sx - decimal yxpart t & " " & % sy - decimal yypart t & " " & % ry - decimal xpart t & " " & % tx - decimal ypart t % ty -enddef ; - -vardef mfun_numeric_to_string(expr n) = - decimal n -enddef ; - -vardef mfun_pair_to_string(expr p) = - decimal xpart p & " " & - decimal ypart p -enddef ; - -vardef mfun_rgbcolor_to_string(expr c) = - decimal redpart c & " " & - decimal greenpart c & " " & - decimal bluepart c -enddef ; - -vardef mfun_cmykcolor_to_string(expr c) = - decimal cyanpart c & " " & - decimal magentapart c & " " & - decimal yellowpart 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 ; - -vardef mfun_boolean_to_string(expr b) = - if b : "true" else : "false" fi -enddef ; - -% def passvariable(expr key, value) = -% special -% if numeric value : "1:" & key & "=" & mfun_numeric_to_string(value) -% elseif pair value : "4:" & key & "=" & mfun_pair_to_string(value) -% elseif rgbcolor value : "5:" & key & "=" & mfun_rgbcolor_to_string(value) -% elseif cmykcolor value : "6:" & key & "=" & mfun_cmykcolor_to_string(value) -% elseif boolean value : "3:" & key & "=" & mfun_boolean_to_string(value) -% elseif path value : "7:" & key & "=" & mfun_path_to_string(value) -% elseif transform value : "8:" & key & "=" & mfun_transform_to_string(value) -% else : "2:" & key & "=" & value -% fi ; -% enddef ; - -vardef tostring(expr value) = - if numeric value : mfun_numeric_to_string(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) - else : value - fi -enddef ; - -vardef mfun_tagged_string(expr value) = - if numeric value : "1:" & mfun_numeric_to_string(value) - elseif pair value : "4:" & mfun_pair_to_string(value) - elseif rgbcolor value : "5:" & mfun_rgbcolor_to_string(value) - elseif cmykcolor value : "6:" & mfun_cmykcolor_to_string(value) - elseif boolean value : "3:" & mfun_boolean_to_string(value) - elseif path value : "7:" & mfun_path_to_string(value) - elseif transform value : "8:" & mfun_transform_to_string(value) - else : "2:" & value - fi -enddef ; - -% amore flexible variant for passing data to context - -vardef mfun_point_to_lua(expr p,i) = - "{" & - decimal xpart (point i of p) & "," & - decimal ypart (point i of p) & "," & - decimal xpart (precontrol i of p) & "," & - decimal ypart (precontrol i of p) & "," & - decimal xpart (postcontrol i of p) & "," & - decimal ypart (postcontrol i of p) - & "}" -enddef ; - -vardef mfun_transform_to_lua(expr t) = - "{" & - decimal xxpart t & "," & % rx - decimal xypart t & "," & % sx - decimal yxpart t & "," & % sy - decimal yypart t & "," & % ry - decimal xpart t & "," & % tx - decimal ypart t % ty - & "}" -enddef ; - -vardef mfun_numeric_to_lua(expr n) = - decimal n -enddef ; - -vardef mfun_pair_to_lua(expr p) = - "{" & - decimal xpart p & "," & - decimal ypart p - & "}" -enddef ; - -vardef mfun_rgbcolor_to_lua(expr c) = - "{" & - decimal redpart c & "," & - decimal greenpart c & "," & - decimal bluepart c - & "}" -enddef ; - -vardef mfun_cmykcolor_to_lua(expr c) = - "{" & - decimal cyanpart c & "," & - decimal magentapart c & "," & - decimal yellowpart c & "," & - decimal blackpart c - & "}" -enddef ; - -vardef mfun_path_to_lua(expr p) = - "{" & - mfun_point_to_lua(p,0) for i=1 upto length(p) : & "," & mfun_point_to_lua(p,i) endfor - & "}" -enddef ; - -vardef mfun_boolean_to_lua(expr b) = - if b : "true" else : "false" fi -enddef ; - -vardef mfun_string_to_lua(expr s) = - "[==[" & s & "]==]" -enddef ; - -def mfun_to_lua(expr key)(expr value)(text t) = - special "metapost.variables['" & key & "']=" & t(value) ; -enddef ; - -def mfun_array_to_lua(expr key)(suffix value)(expr first, last, stp)(text t) = - special - "metapost.variables['" & key & "']={" - for i=first step stp until last : - & "[" & decimal i & "]=" & t(value[i]) & "," - endfor - & "}" ; -enddef ; - -def passvariable(expr key, value) = - if numeric value : mfun_to_lua(key,value,mfun_numeric_to_lua) - elseif pair value : mfun_to_lua(key,value,mfun_pair_to_lua) - elseif string value : mfun_to_lua(key,value,mfun_string_to_lua) - elseif boolean value : mfun_to_lua(key,value,mfun_boolean_to_lua) - elseif path value : mfun_to_lua(key,value,mfun_path_to_lua) - elseif rgbcolor value : mfun_to_lua(key,value,mfun_rgbcolor_to_lua) - elseif cmykcolor value : mfun_to_lua(key,value,mfun_cmykcolor_to_lua) - elseif transform value : mfun_to_lua(key,value,mfun_transform_to_lua) - fi ; -enddef ; - -def passarrayvariable(expr key)(suffix values)(expr first, last, stp) = - if numeric values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_numeric_to_lua) - elseif pair values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_pair_to_lua) - elseif string values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_string_to_lua) - elseif boolean values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_boolean_to_lua) - elseif path values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_path_to_lua) - elseif rgbcolor values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_rgbcolor_to_lua) - elseif cmykcolor values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_cmykcolor_to_lua) - elseif transform values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_transform_to_lua) - fi ; -enddef ; - -def startpassingvariable(expr k) = - begingroup ; - save stoppassingvariable, startarray, stoparray, starthash, stophash, index, key, value, slot, entry ; - let stoppassingvariable = mfun_stop_lua_variable ; - let startarray = mfun_start_lua_array ; - let stoparray = mfun_stop_lua_array ; - let starthash = mfun_start_lua_hash ; - let stophash = mfun_stop_lua_hash ; - let index = mfun_lua_index ; - let key = mfun_lua_key ; - let value = mfun_lua_value ; - let slot = mfun_lua_slot ; - let entry = mfun_lua_entry ; - save s ; string s ; - s := "metapost.variables['" & k & "']=" -enddef ; - -def mfun_stop_lua_variable = - ; - special substring(0,length(s)-1) of s ; - endgroup ; -enddef ; - -% currently there is no difference between array and hash - -def mfun_start_lua_array = - & "{" -enddef ; - -def mfun_stop_lua_array = - & "}," -enddef ; - -def mfun_start_lua_hash = - & "{" -enddef ; - -def mfun_stop_lua_hash = - & "}," -enddef ; - -def mfun_lua_key(expr k) = - & "['" & k & "']=" -enddef ; - -def mfun_lua_index(expr k) = - & "[" & decimal k & "]=" -enddef ; - -def mfun_lua_value(expr v) = - if numeric v : & mfun_numeric_to_lua(v) & "," - elseif pair v : & mfun_pair_to_lua(v) & "," - elseif string v : & mfun_string_to_lua(v) & "," - elseif boolean v : & mfun_boolean_to_lua(v) & "," - elseif path v : & mfun_path_to_lua(v) & "," - elseif rgbcolor v : & mfun_rgbcolor_to_lua(v) & "," - elseif cmykcolor v : & mfun_cmykcolor_to_lua(v) & "," - elseif transform v : & mfun_transform_to_lua(v) & "," - fi -enddef ; - -def mfun_lua_entry(expr k, v) = - mfun_lua_key(k) - mfun_lua_value(v) -enddef ; - -def mfun_lua_slot(expr k, v) = - mfun_lua_index(k) - mfun_lua_value(v) -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) = - 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) = "\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.mpii b/metapost/context/base/mp-page.mpii deleted file mode 100644 index 456ee61cc..000000000 --- a/metapost/context/base/mp-page.mpii +++ /dev/null @@ -1,659 +0,0 @@ -%D \module -%D [ file=mp-page.mpii, -%D version=1999.03.10, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=page enhancements, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -%D This module is rather preliminary and subjected to -%D changes. - -if known context_page : endinput ; fi ; - -boolean context_page ; context_page := true ; - -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 ; - -def SaveTextAreas = - path SavedTextAreas [] ; - path SavedTextColumns[] ; - numeric NOfSavedTextAreas ; - numeric NOfSavedTextColumns ; - for i=1 upto NOfTextAreas : - SavedTextAreas[i] := TextAreas[i] ; - endfor ; - for i=1 upto NOfTextColumns : - SavedTextColumns[i] := TextColumns[i] ; - endfor ; - NOfSavedTextAreas := NOfTextAreas ; - NOfSavedTextColumns := NOfTextColumns ; -enddef ; - -def ResetTextAreas = - path TextAreas[], TextColumns[] ; - numeric NOfTextAreas ; NOfTextAreas := 0 ; - numeric NOfTextColumns ; NOfTextColumns := 0 ; - numeric nofmultipars ; nofmultipars := 0 ; - TextAreas[0] := TextColumns[0] := origin -- cycle ; -enddef ; - -ResetTextAreas ; SaveTextAreas ; ; - -def RegisterTextArea (expr x, y, w, h, d) = - begingroup ; save p ; path p ; - p := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; - if NOfTextAreas>0 : - % if needed, concatenate areas - if (round(llcorner TextAreas[NOfTextAreas]) = round(ulcorner p)) and - (round(lrcorner TextAreas[NOfTextAreas]) = round(urcorner p)) : - p := ulcorner TextAreas[NOfTextAreas] -- - urcorner TextAreas[NOfTextAreas] -- - lrcorner p -- - llcorner p -- - cycle ; - else : - NOfTextAreas := NOfTextAreas + 1 ; - fi ; - else : - NOfTextAreas := NOfTextAreas + 1 ; - fi ; - TextAreas[NOfTextAreas] := p ; - if NOfTextColumns>0 : - if (round(xpart llcorner TextColumns[NOfTextColumns]) = round(xpart ulcorner p)) and - (round(xpart lrcorner TextColumns[NOfTextColumns]) = round(xpart urcorner p)) : - p := ulcorner TextColumns[NOfTextColumns] -- - urcorner TextColumns[NOfTextColumns] -- - lrcorner p -- - llcorner p -- - cycle ; - else : - NOfTextColumns := NOfTextColumns + 1 ; - fi ; - else : - NOfTextColumns := NOfTextColumns + 1 ; - fi ; - TextColumns[NOfTextColumns] := p ; - endgroup ; -enddef ; - -%D We store a local area in slot zero. - -def RegisterLocalTextArea (expr x, y, w, h, d) = - TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; -enddef ; - -def ResetLocalTextArea = - TextAreas[0] := TextColumns[0] := origin -- cycle ; -enddef ; - -ResetLocalTextArea ; - -vardef InsideTextArea (expr _i_, _xy_) = - ( (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and - (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and - (round(ypart _xy_) >= round(ypart llcorner TextAreas[_i_])) and - (round(ypart _xy_) <= round(ypart urcorner TextAreas[_i_])) ) -enddef ; - -vardef InsideSavedTextArea (expr _i_, _xy_) = - ( (round(xpart _xy_) >= round(xpart llcorner SavedTextAreas[_i_])) and - (round(xpart _xy_) <= round(xpart lrcorner SavedTextAreas[_i_])) and - (round(ypart _xy_) >= round(ypart llcorner SavedTextAreas[_i_])) and - (round(ypart _xy_) <= round(ypart urcorner SavedTextAreas[_i_])) ) -enddef ; - -vardef InsideSomeTextArea (expr _xy_) = - save ok ; boolean ok ; ok := false ; - for i := 1 upto NOfTextAreas : - if InsideTextArea(i,_xy_) : ok := true ; fi ; - exitif ok ; - endfor ; - ok -enddef ; - -vardef InsideSomeSavedTextArea (expr _xy_) = - save ok ; boolean ok ; ok := false ; - for i := 1 upto NOfSavedTextAreas : - if InsideSavedTextArea(i,_xy_) : ok := true ; fi ; - exitif ok ; - endfor ; - ok -enddef ; - -vardef TextAreaX (expr x) = - numeric _TextAreaX_ ; _TextAreaX_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) : - _TextAreaX_ := xpart llcorner TextAreas[i] ; - fi ; - endfor ; - _TextAreaX_ -enddef ; - -vardef TextAreaY (expr y) = - numeric _TextAreaY_ ; _TextAreaY_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(y) >= round(ypart llcorner TextAreas[NOfTextAreas])) and - (round(y) <= round(ypart ulcorner TextAreas[NOfTextAreas])) : - _TextAreaY_ := ypart llcorner TextAreas[NOfTextAreas] ; - fi ; - endfor ; - _TextAreaY_ -enddef ; - -vardef TextAreaXY (expr x, y) = - pair _TextAreaXY_ ; _TextAreaXY_ := origin ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) and - (round(y) >= round(ypart llcorner TextAreas[i])) and - (round(y) <= round(ypart ulcorner TextAreas[i])) : - _TextAreaXY_ := llconer TextAreas[i] ; - fi ; - endfor ; - _TextAreaXY_ -enddef ; - -vardef TextAreaW (expr x) = - numeric _TextAreaW_ ; _TextAreaW_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) : - _TextAreaW_ := bbwidth(TextAreas[i]) ; - fi ; - endfor ; - _TextAreaW_ -enddef ; - -vardef TextAreaH (expr y) = - numeric _TextAreaH_ ; _TextAreaH_ := 0 ; - for i := 1 upto NOfTextAreas : - if (round(y) >= round(ypart llcorner TextAreas[i])) and - (round(y) <= round(ypart ulcorner TextAreas[i])) : - _TextAreaH_ := bbheight(TextAreas[i]) ; - fi ; - endfor ; - _TextAreaH_ -enddef ; - -vardef TextAreaWH (expr x, y) = - pair _TextAreaWH_ ; _TextAreaWH_ := origin ; - for i := 1 upto NOfTextAreas : - if (round(x) >= round(xpart llcorner TextAreas[i])) and - (round(x) <= round(xpart lrcorner TextAreas[i])) and - (round(y) >= round(ypart llcorner TextAreas[i])) and - (round(y) <= round(ypart ulcorner TextAreas[i])) : - _TextAreaWH_ := (bbwidth(TextAreas[i]),bbheight(TextAreas[i])) ; - fi ; - endfor ; - _TextAreaWH_ -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 ; - -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 [][] ; path Page ; -numeric HorPos ; numeric Hstep [] ; numeric Hsize [] ; -numeric VerPos ; numeric Vstep [] ; numeric Vsize [] ; - -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 ; - -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[] ; - - Vsize[Top] = TopHeight ; - Vsize[TopSeparator] = TopDistance ; - Vsize[Header] = HeaderHeight ; - Vsize[HeaderSeparator] = HeaderDistance ; - Vsize[Text] = TextHeight ; - Vsize[FooterSeparator] = FooterDistance ; - Vsize[Footer] = FooterHeight ; - Vsize[BottomSeparator] = BottomDistance ; - Vsize[Bottom] = BottomHeight ; - - Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; - Vstep[TopSeparator] = PaperHeight-TopSpace ; - Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; - Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; - Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; - Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; - Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; - Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; - Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; - - Hsize[LeftEdge] = LeftEdgeWidth ; - Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; - Hsize[LeftMargin] = LeftMarginWidth ; - Hsize[LeftMarginSeparator] = LeftMarginDistance ; - Hsize[Text] = MakeupWidth ; - Hsize[RightMarginSeparator] = RightMarginDistance ; - Hsize[RightMargin] = RightMarginWidth ; - Hsize[RightEdgeSeparator] = RightEdgeDistance ; - Hsize[RightEdge] = RightEdgeWidth ; - - Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; - Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; - Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; - Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; - Hstep[Text] = BackSpace ; - Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; - Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; - Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; - Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; - - for VerPos=Top step 10 until Bottom: - for HorPos=LeftEdge step 1 until RightEdge: - Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; - Area[VerPos][HorPos] := Area[HorPos][VerPos] ; - Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; - Location[VerPos][HorPos] := Location[HorPos][VerPos] ; - Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ; - Field[VerPos][HorPos] := Field[HorPos][VerPos] ; - endfor ; - endfor ; - - Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; - -enddef ; - -def BoundPageAreas = - - % pickup pencircle scaled 0pt ; - - bboxmargin := 0 ; setbounds currentpicture to Page ; - -enddef ; - -def StartPage = - - begingroup ; - - if PageStateAvailable : - LoadPageState ; - SwapPageState ; - fi ; - - SetPageAreas ; - BoundPageAreas ; - -enddef ; - -def StopPage = - - BoundPageAreas ; - - endgroup ; - -enddef ; - -def OverlayBox = - (unitsquare xyscaled (OverlayWidth,OverlayHeight)) -enddef ; - -% handy - -def innerenlarged = - hide(LoadPageState) - if OnRightPage : leftenlarged else : rightenlarged fi -enddef ; - -def outerenlarged = - hide(LoadPageState) - if OnRightPage : rightenlarged else : leftenlarged fi -enddef ; - -% obsolete - -def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ; -def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ; -def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ; -def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ; - -def Enlarged (expr p, d) = - (llEnlarged (p,d) -- - lrEnlarged (p,d) -- - urEnlarged (p,d) -- - ulEnlarged (p,d) -- cycle) -enddef ; - -% New: - -def position_anchor_bar(expr p_b_self, p_e_self, y_b_self, y_e_self, h_b_self, d_e_self, - distance, linewidth, linecolor) = - StartPage ; - path p ; p := - if p_b_self=p_e_self : - (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) -- - (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ; - elseif RealPageNumber=p_b_self : - (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) -- - (llcorner Field[Text][Text]) ; - elseif RealPageNumber=p_e_self : - (ulcorner Field[Text][Text]) -- - (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ; - else : - (ulcorner Field[Text][Text]) -- - (llcorner Field[Text][Text]) ; - fi ; - p := p shifted (-llcorner Field[Text][Text]-(distance,0)) ; - interim linecap := butt ; - draw p - withpen pencircle scaled linewidth - withcolor linecolor ; - StopPage ; -enddef ; - -% Crop stuff - -vardef crop_marks_lines (expr box, length, offset, nx, ny) = - save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ; - p := image ( - x := if nx = 0 : 1 else : nx - 1 fi ; - y := if ny = 0 : 1 else : ny - 1 fi ; - w := bbwidth (box) / x ; - h := bbheight(box) / y ; - for i=0 upto y : - draw ((llcorner box) -- (llcorner box) shifted (-length,0)) shifted (-offset,i*h) ; - draw ((lrcorner box) -- (lrcorner box) shifted ( length,0)) shifted ( offset,i*h) ; - endfor ; - for i=0 upto x : - draw ((llcorner box) -- (llcorner box) shifted (0,-length)) shifted (i*w,-offset) ; - draw ((ulcorner box) -- (ulcorner box) shifted (0, length)) shifted (i*w, offset) ; - endfor ; - ) ; - setbounds p to box ; - p -enddef ; - -vardef crop_marks_cmyk = - save p ; picture p ; p := image ( - fill ulcircle scaled 12.5 withcolor (1,0,0,0) ; - fill urcircle scaled 12.5 withcolor (0,1,0,0) ; - fill lrcircle scaled 12.5 withcolor (0,0,1,0) ; - fill llcircle scaled 12.5 withcolor (0,0,0,1) ; - draw (-10,0) -- (10,0) ; - draw (0,-10) -- (0,10) ; - draw fullcircle scaled 12.5 ; - ) ; - setbounds p to fullsquare scaled 20 ; - p -enddef ; - -vardef crop_marks_gray = - save p ; picture p ; p := image ( - fill ulcircle scaled 12.5 withcolor (0.00) ; - fill urcircle scaled 12.5 withcolor (0.25) ; - fill lrcircle scaled 12.5 withcolor (0.50) ; - fill llcircle scaled 12.5 withcolor (0.75) ; - draw (-10,0) -- (10,0) ; - draw (0,-10) -- (0,10) ; - draw (-6,0) -- (6,0) withcolor white ; - draw (0,-6) -- (0,6) withcolor white ; - draw fullcircle scaled 12.5 ; - ) ; - setbounds p to fullsquare scaled 20 ; - p -enddef ; - -vardef crop_marks_cmykrgb = - save p ; picture p ; p := image ( - fill ulcircle scaled 15 withcolor (1,0,0) ; - fill urcircle scaled 15 withcolor (0,1,0) ; - fill lrcircle scaled 15 withcolor (0,0,1) ; - fill llcircle scaled 15 withcolor (.5,.5,.5) ; - fill ulcircle scaled 10 withcolor (1,0,0,0) ; - fill urcircle scaled 10 withcolor (0,1,0,0) ; - fill lrcircle scaled 10 withcolor (0,0,1,0) ; - fill llcircle scaled 10 withcolor (0,0,0,1) ; - draw (-10,0) -- (10,0) ; - draw (0,-10) -- (0,10) ; - draw fullcircle scaled 10 ; - draw fullcircle scaled 15 ; - ) ; - setbounds p to fullsquare scaled 20 ; - p -enddef ; - -vardef crop_color(expr c, h, w, dx, dy, ts) = - image ( - save p ; path p ; - for i=1 upto 6 : - p := fullsquare - xscaled w - yscaled h - shifted (dx,dy-i*h) ; - fill p - withcolor (crop_colors[i]*c) ; - draw textext("\format{'@0.2f'," & decimal crop_colors[i] & "}") - scaled ts - shifted center p withcolor white ; - endfor ; - ) -enddef ; - -vardef crop_gray(expr c, h, w, dx, dy, ts) = - image ( - save p ; path p ; - for i=.05 step .05 until 1 : - p := fullsquare - xscaled w - yscaled h - shifted (20*(i-1)*w+dx,dy) ; - fill p - withcolor (i*c) ; - draw textext("\format{'@0.2f'," & decimal i & "}") - scaled ts - shifted center p withcolor white ; - endfor ; - ) -enddef ; - -% draw crop_marks_cmyk shifted llcorner more ; -% draw crop_marks_cmyk shifted lrcorner more ; -% draw crop_marks_cmyk shifted ulcorner more ; -% draw crop_marks_cmyk shifted urcorner more ; - -def page_marks_add_color(expr width, height, length, offset) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - numeric crop_colors[] ; - crop_colors[1] := 1 ; - crop_colors[2] := 0.95 ; - crop_colors[3] := 0.75 ; - crop_colors[4] := 0.50 ; - crop_colors[5] := 0.25 ; - crop_colors[6] := 0.05 ; - - numeric h ; h := height / 20 ; - numeric w ; w := width / 20 ; - numeric d ; d := offset + length/2 ; - - draw crop_color((1,0,0,0),h,length,xpart ulcorner page - d, 10h,length/20) ; - draw crop_color((0,1,0,0),h,length,xpart ulcorner page - d,3.5h,length/20) ; - draw crop_color((0,0,1,0),h,length,xpart ulcorner page - d, -3h,length/20) ; - - draw crop_color((0,1,1,0),h,length,xpart urcorner page + d, 10h,length/20) ; - draw crop_color((1,0,1,0),h,length,xpart urcorner page + d,3.5h,length/20) ; - draw crop_color((1,1,0,0),h,length,xpart urcorner page + d, -3h,length/20) ; - - draw crop_gray((0,0,0,1),length, w,-xpart llcorner page,-ypart llcorner page + d ,w/20) ; - draw crop_gray((1,0,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d + 1length/3,w/20) ; - draw crop_gray((0,1,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 0length/3,w/20) ; - draw crop_gray((0,0,1,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 1length/3,w/20) ; - - setbounds currentpicture to page ; - -enddef ; - -def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - draw crop_marks_gray shifted center(topboundary more) shifted (0, offset+length); - draw crop_marks_cmyk shifted center(bottomboundary more) shifted (0,-offset-length); - - setbounds currentpicture to page ; - -enddef ; - -def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - draw crop_marks_lines(page,length,offset,nx,ny) ; - - setbounds currentpicture to page ; - -enddef ; - -def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace - - path page ; page := fullsquare xscaled width yscaled height ; - path more ; more := page enlarged (offset+length/2,offset+length/2) ; - - for s=llcorner more, lrcorner more, ulcorner more, urcorner more : - draw textext(decimal n) shifted s ; - endfor ; - - setbounds currentpicture to page ; - -enddef ; diff --git a/metapost/context/base/mp-page.mpiv b/metapost/context/base/mp-page.mpiv deleted file mode 100644 index a6fa3fba3..000000000 --- a/metapost/context/base/mp-page.mpiv +++ /dev/null @@ -1,664 +0,0 @@ -%D \module -%D [ file=mp-page.mpiv, -%D version=1999.03.10, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=page enhancements, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -%D 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 ; - -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 ; - -def SwapPageState = - mfun_swapped := true ; % eventually this will go ! -enddef ; - -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 ; - -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 ; -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 - -numeric HorPos ; HorPos := 0 ; -numeric VerPos ; VerPos := 0 ; - -% 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[] ; -% -% 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 SetPageAreas = -% -% numeric Vsize[], Hsize[], Vstep[], Hstep[] ; -% -% Vsize[Top] = TopHeight ; -% Vsize[TopSeparator] = TopDistance ; -% Vsize[Header] = HeaderHeight ; -% Vsize[HeaderSeparator] = HeaderDistance ; -% Vsize[Text] = TextHeight ; -% Vsize[FooterSeparator] = FooterDistance ; -% Vsize[Footer] = FooterHeight ; -% Vsize[BottomSeparator] = BottomDistance ; -% Vsize[Bottom] = BottomHeight ; -% -% Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; -% Vstep[TopSeparator] = PaperHeight-TopSpace ; -% Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; -% Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; -% Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; -% Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; -% Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; -% Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; -% Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; -% -% Hsize[LeftEdge] = LeftEdgeWidth ; -% Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; -% Hsize[LeftMargin] = LeftMarginWidth ; -% Hsize[LeftMarginSeparator] = LeftMarginDistance ; -% Hsize[Text] = MakeupWidth ; -% Hsize[RightMarginSeparator] = RightMarginDistance ; -% Hsize[RightMargin] = RightMarginWidth ; -% Hsize[RightEdgeSeparator] = RightEdgeDistance ; -% Hsize[RightEdge] = RightEdgeWidth ; -% -% Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; -% Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; -% Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; -% Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; -% Hstep[Text] = BackSpace ; -% Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; -% Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; -% Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; -% Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; -% -% for VerPos=Top step 10 until Bottom: -% for HorPos=LeftEdge step 1 until RightEdge: -% Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; -% Area[VerPos][HorPos] := Area[HorPos][VerPos] ; -% Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; -% Location[VerPos][HorPos] := Location[HorPos][VerPos] ; -% Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ; -% Field[VerPos][HorPos] := Field[HorPos][VerPos] ; -% endfor ; -% endfor ; -% -% Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; -% -% enddef ; -% -% def BoundPageAreas = -% % pickup pencircle scaled 0pt ; -% bboxmargin := 0 ; setbounds currentpicture to Page ; -% enddef ; -% -% def StartPage = -% begingroup ; -% if PageStateAvailable : -% LoadPageState ; -% SwapPageState ; -% fi ; -% SetPageAreas ; -% BoundPageAreas ; -% enddef ; -% -% def StopPage = -% BoundPageAreas ; -% endgroup ; -% enddef ; - -% Because metapost > 1.50 has dynamic memory management and is less -% efficient than before we now delay calculations ... (on a document -% with 150 pages the time spent in mp was close to 5 seconds which was -% only due to initialising the page related areas, something that was -% hardly noticeable before. At least now we're back to half a second -% for such a case. - -def SetPageVsize = - numeric Vsize[] ; - Vsize[Top] = TopHeight ; - Vsize[TopSeparator] = TopDistance ; - Vsize[Header] = HeaderHeight ; - Vsize[HeaderSeparator] = HeaderDistance ; - Vsize[Text] = TextHeight ; - Vsize[FooterSeparator] = FooterDistance ; - Vsize[Footer] = FooterHeight ; - Vsize[BottomSeparator] = BottomDistance ; - Vsize[Bottom] = BottomHeight ; -enddef ; - -def SetPageHsize = - numeric Hsize[] ; - Hsize[LeftEdge] = LeftEdgeWidth ; - Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; - Hsize[LeftMargin] = LeftMarginWidth ; - Hsize[LeftMarginSeparator] = LeftMarginDistance ; - Hsize[Text] = MakeupWidth ; - Hsize[RightMarginSeparator] = RightMarginDistance ; - Hsize[RightMargin] = RightMarginWidth ; - Hsize[RightEdgeSeparator] = RightEdgeDistance ; - Hsize[RightEdge] = RightEdgeWidth ; -enddef ; - -def SetPageVstep = - numeric Vstep[] ; - Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; - Vstep[TopSeparator] = PaperHeight-TopSpace ; - Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; - Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; - Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; - Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; - Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; - Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; - Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; -enddef ; - -def SetPageHstep = - numeric Hstep[] ; - Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; - Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; - Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; - Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; - Hstep[Text] = BackSpace ; - Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; - Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; - Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; - Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; -enddef ; - -def SetPageArea = - path Area[][] ; - for VerPos=Top step 10 until Bottom: - for HorPos=LeftEdge step 1 until RightEdge: - Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; - Area[VerPos][HorPos] := Area[HorPos][VerPos] ; - endfor ; - endfor ; -enddef ; - -def SetPageLocation = - pair Location[][] ; - for VerPos=Top step 10 until Bottom: - for HorPos=LeftEdge step 1 until RightEdge: - Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; - Location[VerPos][HorPos] := Location[HorPos][VerPos] ; - endfor ; - endfor ; -enddef ; - -def SetPageField = - path Field[][] ; - for VerPos=Top step 10 until Bottom: - for HorPos=LeftEdge step 1 until RightEdge: - Field[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] shifted (Hstep[HorPos],Vstep[VerPos]) ; - Field[VerPos][HorPos] := Field[HorPos][VerPos] ; - endfor ; - endfor ; -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 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 ; - -% 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 = - 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 ; - -let SetPageAreas = SetPageVariables ; % compatiblity - -def BoundPageAreas = - % pickup pencircle scaled 0pt ; - bboxmargin := 0 ; setbounds currentpicture to Page ; -enddef ; - -def StartPage = - begingroup ; - if mfun_first_run : - if PageStateAvailable : - LoadPageState ; - SwapPageState ; - fi ; - SetPageVariables ; - fi ; - BoundPageAreas ; -enddef ; - -def StopPage = - BoundPageAreas ; - endgroup ; -enddef ; - -% cover pages - -def BoundCoverAreas = - % todo: add cropmarks - bboxmargin := 0 ; setbounds currentpicture to CoverPage enlarged PaperBleed ; -enddef ; - -let SetCoverAreas = SetPageVariables ; % compatiblity - -def StartCover = - begingroup ; - if mfun_first_run : - if PageStateAvailable : - LoadPageState ; - % SwapPageState ; - fi ; - SetPageVariables ; % was SetPageAreas ; - SetCoverAreas ; - fi ; - BoundCoverAreas ; -enddef ; - -def StopCover = - BoundCoverAreas ; - endgroup ; -enddef ; - -% overlays: - -def OverlayBox = - (unitsquare xyscaled (OverlayWidth,OverlayHeight)) -enddef ; - -% handy - -def innerenlarged = - hide(LoadPageState) - if OnRightPage : leftenlarged else : rightenlarged fi -enddef ; - -def outerenlarged = - hide(LoadPageState) - if OnRightPage : rightenlarged else : leftenlarged fi -enddef ; - -% obsolete - -def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ; -def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ; -def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ; -def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ; - -def Enlarged (expr p, d) = - (llEnlarged (p,d) -- - lrEnlarged (p,d) -- - urEnlarged (p,d) -- - ulEnlarged (p,d) -- cycle) -enddef ; diff --git a/metapost/context/base/mp-shap.mpii b/metapost/context/base/mp-shap.mpii deleted file mode 100644 index 17d21314c..000000000 --- a/metapost/context/base/mp-shap.mpii +++ /dev/null @@ -1,206 +0,0 @@ -%D \module -%D [ file=mp-shap.mpii, -%D version=2000.05.31, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=shapes, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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_shap : endinput ; fi ; - -boolean context_shap ; context_shap := true ; - -path predefined_shapes[] ; - -begingroup ; - -save xradius, yradius, xxradius, yyradius ; -save ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; - -numeric xradius, yradius, xxradius, yyradius ; -pair ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; - -xradius := .15 ; -yradius := .15 ; -xxradius := .10 ; -yyradius := .10 ; - -ll := llcorner (unitsquare shifted (-.5,-.5)) ; -lr := lrcorner (unitsquare shifted (-.5,-.5)) ; -ur := urcorner (unitsquare shifted (-.5,-.5)) ; -ul := ulcorner (unitsquare shifted (-.5,-.5)) ; - -llx := ll shifted (xradius,0) ; -lly := ll shifted (0,yradius) ; - -lrx := lr shifted (-xradius,0) ; -lry := lr shifted (0,yradius) ; - -urx := ur shifted (-xradius,0) ; -ury := ur shifted (0,-yradius) ; - -ulx := ul shifted (xradius,0) ; -uly := ul shifted (0,-yradius) ; - -llxx := ll shifted (xxradius,0) ; -llyy := ll shifted (0,yyradius) ; - -lrxx := lr shifted (-xxradius,0) ; -lryy := lr shifted (0,yyradius) ; - -urxx := ur shifted (-xxradius,0) ; -uryy := ur shifted (0,-yyradius) ; - -ulxx := ul shifted (xxradius,0) ; -ulyy := ul shifted (0,-yyradius) ; - -lc := ll shifted (0,.5) ; -rc := lr shifted (0,.5) ; -tc := ul shifted (.5,0) ; -bc := ll shifted (.5,0) ; - -predefined_shapes[ 0] := (origin--cycle) ; -predefined_shapes[ 5] := (llx--lrx{right}...rc...{left}urx--ulx{left}...lc...{right}cycle) ; -predefined_shapes[ 6] := (ll--lrx{right}...rc...{left}urx--ul--cycle) ; -predefined_shapes[ 7] := (ll--lrx{right}...rc...{left}urx--ul--cycle) rotatedaround(origin,180) ; -predefined_shapes[ 8] := (lr--ury{up}...tc...{down}uly--ll--cycle) ; -predefined_shapes[ 9] := (lr--ury{up}...tc...{down}uly--ll--cycle) rotatedaround(origin,180) ; -predefined_shapes[10] := (ll--lr--ur--ul--ll--ur--ul--ll--cycle) ; -predefined_shapes[11] := (ll--lr--ur--ul--ll--lr--ul--ll--cycle) ; -predefined_shapes[12] := (ll--lrx--ur--ulx--cycle) ; -predefined_shapes[13] := (llx--lr--urx--ul--cycle) ; -predefined_shapes[14] := (lly--bc--lry--ury--tc--uly--cycle) ; -predefined_shapes[15] := (llx--lrx--rc--urx--ulx--lc--cycle) ; -predefined_shapes[16] := (ll--lrx--rc--urx--ul--cycle) ; -predefined_shapes[17] := (ll--lrx--rc--urx--ul--cycle) rotatedaround(origin,180) ; -predefined_shapes[18] := (lr--ury--tc--uly--ll--cycle) ; -predefined_shapes[19] := (lr--ury--tc--uly--ll--cycle) rotatedaround(origin,180) ; -predefined_shapes[20] := (ll--lr--ur--ul--ll--llxx--ulxx--ul--ll--lr--ur--urxx--lrxx--cycle) ; -predefined_shapes[21] := (ul--ll--lr--ur--ul--ulyy--uryy--ur--ul--ll--lr--lryy--llyy--cycle) ; -predefined_shapes[22] := (ll--lrx--lry--ur--ulx--uly--cycle) ; -predefined_shapes[23] := (llx--lr--ury--urx--ul--lly--cycle) ; -predefined_shapes[24] := (ll--lr--ur--ul--cycle) ; -predefined_shapes[25] := (llx--lrx--lry--ury--urx--ulx--uly--lly--cycle) ; -predefined_shapes[26] := (ll--lrx--lry--ur--ul--cycle) ; -predefined_shapes[27] := (ll--lr--ury--urx--ul--cycle) rotatedaround(origin,180) ; -predefined_shapes[28] := (ll--lr--ury--urx--ul--cycle) ; -predefined_shapes[29] := (ll--lrx--lry--ur--ul--cycle) rotatedaround(origin,180) ; -predefined_shapes[30] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) rotated 45; -predefined_shapes[31] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; -predefined_shapes[32] := (ll{right}...{right}lry--ur--ul--ll--cycle) ; -predefined_shapes[33] := (ll{right}...{right}lry--ur--ul--ll--cycle--ul--ulx--ulx shifted(0,yyradius)--ur shifted(yyradius,yyradius)--lry shifted(yyradius,yyradius)--lry shifted(0,yyradius)--ur--ul--cycle ) ; -predefined_shapes[34] := (uly..tc..ury & ury..tc shifted (0,-2yradius)..uly & uly--lly & lly..bc..lry & lry--ury & ury..tc shifted (0,-2yradius)..uly & cycle ) ; -predefined_shapes[35] := (bc{right}...rc{up}...tc{left}...lc{down}...cycle) ; -predefined_shapes[36] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) ; -predefined_shapes[37] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) rotatedaround(origin,180) ; -predefined_shapes[38] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) ; -predefined_shapes[39] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) rotatedaround(origin,180) ; -predefined_shapes[40] := (ll--lr--ur--ul--ll--ur--ul--ll--lr--ul--ll--cycle) ; -predefined_shapes[41] := (ll--lr--ur--ul--ll--lr--rc--lc--ll--bc--tc--ul--ll & cycle) ; -predefined_shapes[42] := (ll--lr--origin shifted (+epsilon,0)--ur--ul--origin shifted (-epsilon,0)--cycle) ; -predefined_shapes[43] := (ll--ul--origin shifted (0,+epsilon)--ur--lr--origin shifted (0,-epsilon)--cycle) ; -predefined_shapes[45] := (bc--rc--tc--lc--cycle) ; -predefined_shapes[46] := (ll--ul--rc--cycle) ; -predefined_shapes[47] := (ll--ul--rc--cycle) rotatedaround(origin,180) ; -predefined_shapes[48] := (ul--ur--bc--cycle) rotatedaround(origin,180) ; -predefined_shapes[49] := (ul--ur--bc--cycle) ; -predefined_shapes[56] := (ll--lry--ury--ul--cycle) ; -predefined_shapes[57] := (ll--lry--ury--ul--cycle) rotatedaround(origin,180) ; -predefined_shapes[58] := (ll--ulx--urx--lr--cycle) ; -predefined_shapes[59] := (ll--ulx--urx--lr--cycle) rotatedaround(origin,180); -predefined_shapes[66] := (rc--origin shifted ( epsilon,0) --cycle & rc--origin--cycle ) ; -predefined_shapes[67] := (lc--origin shifted (-epsilon,0) --cycle & lc--origin--cycle ) ; -predefined_shapes[68] := (tc--origin shifted (0, epsilon) --cycle & tc--origin--cycle ) ; -predefined_shapes[69] := (bc--origin shifted (0,-epsilon) --cycle & bc--origin--cycle ) ; -predefined_shapes[75] := (lly--lry--ury--uly--cycle) rotatedaround(origin,180) ; -predefined_shapes[76] := (ll--lr--ur--uly--cycle) rotatedaround(origin,180) ; -predefined_shapes[77] := (ll--lr--ury--ul--cycle) rotatedaround(origin,180) ; -predefined_shapes[78] := (lly--lr--ur--ul--cycle) rotatedaround(origin,180) ; -predefined_shapes[79] := (ll--lry--ur--ul--cycle) rotatedaround(origin,180) ; - -numeric predefined_shapes_xradius ; predefined_shapes_xradius := xradius ; -numeric predefined_shapes_yradius ; predefined_shapes_yradius := yradius ; -numeric predefined_shapes_xxradius ; predefined_shapes_xxradius := xxradius ; -numeric predefined_shapes_yyradius ; predefined_shapes_yyradius := yyradius ; - -endgroup ; - -vardef some_shape_path (expr type) = - if known predefined_shapes[type] : predefined_shapes[type] else : predefined_shapes[0] fi -enddef ; - -def some_shape (expr shape_type, shape_width, shape_height, shape_linewidth, shape_linecolor, shape_fillcolor) = - begingroup ; - save p ; path p ; - p := some_shape_path (shape_type) xscaled shape_width yscaled shape_height ; - pickup pencircle scaled shape_linewidth ; - fill p withcolor shape_fillcolor ; - draw p withcolor shape_linecolor ; - endgroup ; -enddef ; - -vardef drawpredefinedshape (expr t, p, lw, lc, fc) = - save pp ; - if t>1 : % normal shape - path pp ; - pp := some_shape_path(t) xyscaled(bbwidth(p), bbheight(p)) shifted center p ; - fill pp withcolor fc ; - draw pp withpen pencircle scaled lw withcolor lc ; - elseif t=1 : % background only - path pp ; - pp := fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; - fill pp withcolor fc ; - else : % dimensions only - picture pp ; pp := nullpicture ; - setbounds pp to fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; - draw pp ; - fi ; -enddef ; - -vardef drawpredefinedline (expr t, p, lw, lc) = - if (t>0) and (length(p)>1) : - saveoptions ; - drawoptions(withpen pencircle scaled lw withcolor lc) ; - draw p ; - if t = 1 : - draw arrowheadonpath(p,1) ; - elseif t = 2 : - draw arrowheadonpath(reverse p,1) ; - elseif t = 3 : - for $ = p,reverse p : - draw arrowheadonpath($,1) ; - endfor ; - elseif t = 11 : - draw arrowheadonpath(p,1/2) ; - elseif t = 12 : - draw arrowheadonpath(reverse p,1/2) ; - elseif t = 13 : - for $=p,reverse p : - draw arrowheadonpath($,1) ; - endfor ; - for $=p,reverse p : - draw arrowheadonpath($,3/4) ; - endfor ; - elseif t = 21 : - for $=1/5,1/2,4/5 : - draw arrowheadonpath(p,$) ; - endfor ; - elseif t = 22 : - for $=1/5,1/2,4/5 : - draw arrowheadonpath(reverse p,$) ; - endfor ; - elseif t = 23 : - for $=p,reverse p : - draw arrowheadonpath($,1/4) ; - endfor ; - fi ; - fi ; -enddef ; - -let drawshape = drawpredefinedshape ; -let drawline = drawpredefinedline ; diff --git a/metapost/context/base/mp-shap.mpiv b/metapost/context/base/mp-shap.mpiv deleted file mode 100644 index 713656510..000000000 --- a/metapost/context/base/mp-shap.mpiv +++ /dev/null @@ -1,218 +0,0 @@ -%D \module -%D [ file=mp-shap.mpiv, -%D version=2000.05.31, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=shapes, -%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_shap : endinput ; fi ; - -boolean context_shap ; context_shap := true ; - -path predefined_shapes[] ; - -def start_predefined_shape_definition = - - begingroup ; - - save xradius, yradius, xxradius, yyradius ; - save ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; - - numeric xradius, yradius, xxradius, yyradius ; - pair ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; - - xradius := .15 ; - yradius := .15 ; - xxradius := .10 ; - yyradius := .10 ; - - ll := llcorner (unitsquare shifted (-.5,-.5)) ; - lr := lrcorner (unitsquare shifted (-.5,-.5)) ; - ur := urcorner (unitsquare shifted (-.5,-.5)) ; - ul := ulcorner (unitsquare shifted (-.5,-.5)) ; - - llx := ll shifted (xradius,0) ; - lly := ll shifted (0,yradius) ; - - lrx := lr shifted (-xradius,0) ; - lry := lr shifted (0,yradius) ; - - urx := ur shifted (-xradius,0) ; - ury := ur shifted (0,-yradius) ; - - ulx := ul shifted (xradius,0) ; - uly := ul shifted (0,-yradius) ; - - llxx := ll shifted (xxradius,0) ; - llyy := ll shifted (0,yyradius) ; - - lrxx := lr shifted (-xxradius,0) ; - lryy := lr shifted (0,yyradius) ; - - urxx := ur shifted (-xxradius,0) ; - uryy := ur shifted (0,-yyradius) ; - - ulxx := ul shifted (xxradius,0) ; - ulyy := ul shifted (0,-yyradius) ; - - lc := ll shifted (0,.5) ; - rc := lr shifted (0,.5) ; - tc := ul shifted (.5,0) ; - bc := ll shifted (.5,0) ; - -enddef ; - -def stop_predefined_shape_definition = - - endgroup ; - -enddef ; - -start_predefined_shape_definition ; - - predefined_shapes[ 0] := (origin--cycle) ; - predefined_shapes[ 5] := (llx--lrx{right}...rc...{left}urx--ulx{left}...lc...{right}cycle) ; - predefined_shapes[ 6] := (ll--lrx{right}...rc...{left}urx--ul--cycle) ; - predefined_shapes[ 7] := (ll--lrx{right}...rc...{left}urx--ul--cycle) rotatedaround(origin,180) ; - predefined_shapes[ 8] := (lr--ury{up}...tc...{down}uly--ll--cycle) ; - predefined_shapes[ 9] := (lr--ury{up}...tc...{down}uly--ll--cycle) rotatedaround(origin,180) ; - predefined_shapes[10] := (ll--lr--ur--ul--ll--ur--ul--ll--cycle) ; - predefined_shapes[11] := (ll--lr--ur--ul--ll--lr--ul--ll--cycle) ; - predefined_shapes[12] := (ll--lrx--ur--ulx--cycle) ; - predefined_shapes[13] := (llx--lr--urx--ul--cycle) ; - predefined_shapes[14] := (lly--bc--lry--ury--tc--uly--cycle) ; - predefined_shapes[15] := (llx--lrx--rc--urx--ulx--lc--cycle) ; - predefined_shapes[16] := (ll--lrx--rc--urx--ul--cycle) ; - predefined_shapes[17] := (ll--lrx--rc--urx--ul--cycle) rotatedaround(origin,180) ; - predefined_shapes[18] := (lr--ury--tc--uly--ll--cycle) ; - predefined_shapes[19] := (lr--ury--tc--uly--ll--cycle) rotatedaround(origin,180) ; - predefined_shapes[20] := (ll--lr--ur--ul--ll--llxx--ulxx--ul--ll--lr--ur--urxx--lrxx--cycle) ; - predefined_shapes[21] := (ul--ll--lr--ur--ul--ulyy--uryy--ur--ul--ll--lr--lryy--llyy--cycle) ; - predefined_shapes[22] := (ll--lrx--lry--ur--ulx--uly--cycle) ; - predefined_shapes[23] := (llx--lr--ury--urx--ul--lly--cycle) ; - predefined_shapes[24] := (ll--lr--ur--ul--cycle) ; - predefined_shapes[25] := (llx--lrx--lry--ury--urx--ulx--uly--lly--cycle) ; - predefined_shapes[26] := (ll--lrx--lry--ur--ul--cycle) ; - predefined_shapes[27] := (ll--lr--ury--urx--ul--cycle) rotatedaround(origin,180) ; - predefined_shapes[28] := (ll--lr--ury--urx--ul--cycle) ; - predefined_shapes[29] := (ll--lrx--lry--ur--ul--cycle) rotatedaround(origin,180) ; - predefined_shapes[30] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) rotated 45; - predefined_shapes[31] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; - predefined_shapes[32] := (ll{right}...{right}lry--ur--ul--ll--cycle) ; - predefined_shapes[33] := (ll{right}...{right}lry--ur--ul--ll--cycle--ul--ulx--ulx shifted(0,yyradius)--ur shifted(yyradius,yyradius)--lry shifted(yyradius,yyradius)--lry shifted(0,yyradius)--ur--ul--cycle ) ; - predefined_shapes[34] := (uly..tc..ury & ury..tc shifted (0,-2yradius)..uly & uly--lly & lly..bc..lry & lry--ury & ury..tc shifted (0,-2yradius)..uly & cycle ) ; - predefined_shapes[35] := (bc{right}...rc{up}...tc{left}...lc{down}...cycle) ; - predefined_shapes[36] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) ; - predefined_shapes[37] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) rotatedaround(origin,180) ; - predefined_shapes[38] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) ; - predefined_shapes[39] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) rotatedaround(origin,180) ; - predefined_shapes[40] := (ll--lr--ur--ul--ll--ur--ul--ll--lr--ul--ll--cycle) ; - predefined_shapes[41] := (ll--lr--ur--ul--ll--lr--rc--lc--ll--bc--tc--ul--ll & cycle) ; - predefined_shapes[42] := (ll--lr--origin shifted (+epsilon,0)--ur--ul--origin shifted (-epsilon,0)--cycle) ; - predefined_shapes[43] := (ll--ul--origin shifted (0,+epsilon)--ur--lr--origin shifted (0,-epsilon)--cycle) ; - predefined_shapes[45] := (bc--rc--tc--lc--cycle) ; - predefined_shapes[46] := (ll--ul--rc--cycle) ; - predefined_shapes[47] := (ll--ul--rc--cycle) rotatedaround(origin,180) ; - predefined_shapes[48] := (ul--ur--bc--cycle) rotatedaround(origin,180) ; - predefined_shapes[49] := (ul--ur--bc--cycle) ; - predefined_shapes[56] := (ll--lry--ury--ul--cycle) ; - predefined_shapes[57] := (ll--lry--ury--ul--cycle) rotatedaround(origin,180) ; - predefined_shapes[58] := (ll--ulx--urx--lr--cycle) ; - predefined_shapes[59] := (ll--ulx--urx--lr--cycle) rotatedaround(origin,180); - predefined_shapes[66] := (rc--origin shifted ( epsilon,0) --cycle & rc--origin--cycle ) ; - predefined_shapes[67] := (lc--origin shifted (-epsilon,0) --cycle & lc--origin--cycle ) ; - predefined_shapes[68] := (tc--origin shifted (0, epsilon) --cycle & tc--origin--cycle ) ; - predefined_shapes[69] := (bc--origin shifted (0,-epsilon) --cycle & bc--origin--cycle ) ; - predefined_shapes[75] := (lly--lry--ury--uly--cycle) rotatedaround(origin,180) ; - predefined_shapes[76] := (ll--lr--ur--uly--cycle) rotatedaround(origin,180) ; - predefined_shapes[77] := (ll--lr--ury--ul--cycle) rotatedaround(origin,180) ; - predefined_shapes[78] := (lly--lr--ur--ul--cycle) rotatedaround(origin,180) ; - predefined_shapes[79] := (ll--lry--ur--ul--cycle) rotatedaround(origin,180) ; - - numeric predefined_shapes_xradius ; predefined_shapes_xradius := xradius ; - numeric predefined_shapes_yradius ; predefined_shapes_yradius := yradius ; - numeric predefined_shapes_xxradius ; predefined_shapes_xxradius := xxradius ; - numeric predefined_shapes_yyradius ; predefined_shapes_yyradius := yyradius ; - -stop_predefined_shape_definition ; - -vardef some_shape_path (expr type) = - if known predefined_shapes[type] : predefined_shapes[type] else : predefined_shapes[0] fi -enddef ; - -def some_shape (expr shape_type, shape_width, shape_height, shape_linewidth, shape_linecolor, shape_fillcolor) = - begingroup ; - save p ; path p ; - p := some_shape_path (shape_type) xscaled shape_width yscaled shape_height ; - pickup pencircle scaled shape_linewidth ; - fill p withcolor shape_fillcolor ; - draw p withcolor shape_linecolor ; - endgroup ; -enddef ; - -vardef drawpredefinedshape (expr t, p, lw, lc, fc) = - save pp ; - if t>1 : % normal shape - path pp ; - pp := some_shape_path(t) xyscaled(bbwidth(p), bbheight(p)) shifted center p ; - fill pp withcolor fc ; - draw pp withpen pencircle scaled lw withcolor lc ; - elseif t=1 : % background only - path pp ; - pp := fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; - fill pp withcolor fc ; - else : % dimensions only - picture pp ; pp := nullpicture ; - setbounds pp to fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; - draw pp ; - fi ; -enddef ; - -vardef drawpredefinedline (expr t, p, lw, lc) = - if (t>0) and (length(p)>1) : - saveoptions ; - drawoptions(withpen pencircle scaled lw withcolor lc) ; - draw p ; - if t = 1 : - draw arrowheadonpath(p,1) ; - elseif t = 2 : - draw arrowheadonpath(reverse p,1) ; - elseif t = 3 : - for $ = p,reverse p : - draw arrowheadonpath($,1) ; - endfor ; - elseif t = 11 : - draw arrowheadonpath(p,1/2) ; - elseif t = 12 : - draw arrowheadonpath(reverse p,1/2) ; - elseif t = 13 : - for $=p,reverse p : - draw arrowheadonpath($,1) ; - endfor ; - for $=p,reverse p : - draw arrowheadonpath($,3/4) ; - endfor ; - elseif t = 21 : - for $=1/5,1/2,4/5 : - draw arrowheadonpath(p,$) ; - endfor ; - elseif t = 22 : - for $=1/5,1/2,4/5 : - draw arrowheadonpath(reverse p,$) ; - endfor ; - elseif t = 23 : - for $=p,reverse p : - draw arrowheadonpath($,1/4) ; - endfor ; - fi ; - fi ; -enddef ; - -let drawshape = drawpredefinedshape ; -let drawline = drawpredefinedline ; diff --git a/metapost/context/base/mp-spec.mpii b/metapost/context/base/mp-spec.mpii deleted file mode 100644 index 19d81f312..000000000 --- a/metapost/context/base/mp-spec.mpii +++ /dev/null @@ -1,782 +0,0 @@ -%D \module -%D [ file=mp-spec.mpii, -%D version=1999.6.26, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=special extensions, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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. - -% Spot colors are not handled by mptopdf ! - -% let graycolor = numeric ; -% let greycolor = numeric ; -% let withanycolor = withcolor ; - -% rgbcolor red ; red := (1,0,0) ; -% rgbcolor green ; green := (0,1,0) ; -% rgbcolor blue ; blue := (0,0,1) ; -% cmykcolor cyan ; cyan := (1,0,0,0) ; -% cmykcolor magenta ; magenta := (0,1,0,0) ; -% cmykcolor yellow ; yellow := (0,0,1,0) ; -% graycolor black ; black := 0 ; % (0) ; -% graycolor white ; white := 1 ; % (1) ; - -% primarydef p withcolor c = -% p withanycolor (c) -% enddef ; - -% fill fullcircle scaled 10cm withcolor cyan ; -% fill fullcircle scaled 7cm withcolor red ; -% fill fullcircle scaled 4cm withcolor white ; - -% (r,g,b) => cmyk : r=123 g= 1 b=hash -% => spot : r=123 g= 2 b=hash -% => transparent rgb : r=123 g= 3 b=hash -% => transparent cmyk : r=123 g= 4 b=hash -% => transparent spot : r=123 g= 5 b=hash -% => rest : r=123 g=n>10 b=whatever - -%D This module is rather preliminary and subjected to -%D changes. Here we closely cooperates with the \METAPOST\ -%D to \PDF\ converter module built in \CONTEXT\ and provides -%D for instance shading. More information can be found in -%D type {supp-mpe.tex}. - -if known context_spec : endinput ; fi ; - -boolean context_spec ; context_spec := true ; - -numeric _special_counter_ ; _special_counter_ := 0 ; -numeric _color_counter_ ; _color_counter_ := 11 ; % < 10 reserved -numeric _special_signal_ ; _special_signal_ := 123 ; - -numeric _special_div_ ; _special_div_ := 1000 ; - -%D When set to \type {true}, shading will be supported. Some -%D day I will also write an additional directive. - -boolean _inline_specials_ ; _inline_specials_ := false ; - -%D Because we want to output only those specials that are -%D actually used in a figure, we need a bit complicated -%D bookkeeping and collection of specials. At the cost of some -%D obscurity, we now have rather efficient resources. - -string _global_specials_ ; _global_specials_ := "" ; -string _local_specials_ ; _local_specials_ := "" ; - -% vardef add_special_signal = % write the version number -% if (length _global_specials_>0) or (length _local_specials_ >0) : -% special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; -% fi ; -% enddef ; -% -% After some reported problems at the \CONTEXT\ mailing list, -% Taco's came up with: - -% TH: \quotation {Ok, got it. There is a bug in mp-spec.mp (inside metafun). -% Because of a wrapping number, it fails to recognize the fact that there -% are embedded specials at all.} The corrected definition is: - -vardef add_special_signal = % write the version number - if (length _global_specials_ <> 0) or (length _local_specials_ <> 0) : - special ("%%MetaPostSpecials: 2.0 " & decimal _special_signal_ & " " & decimal _special_div_) ; - fi ; -enddef ; - -% \quotation {It now tests for \quote {not equal to zero} instead of -% \quote {larger than zero}: because of all the included files, the -% string \type {_local_specials_} becomes longer than the maximum number -% \quote {length} can return, so it returns -32768 instead, and that is -% of course less than zero.} - -vardef add_extra_specials = - scantokens _global_specials_ ; - scantokens _local_specials_ ; -enddef ; - -vardef reset_extra_specials = - % only local ones - _local_specials_ := "" ; -enddef ; - -boolean insidefigure ; insidefigure := false ; - -% todo: alleen als special gebruikt flush - -extra_beginfig := - " insidefigure := true ; " & - " reset_extra_specials ; " & - extra_beginfig & - " ; " ; - -extra_endfig := - " ; " & - " add_special_signal ; " & - extra_endfig & - " add_extra_specials ; " & - " reset_extra_specials ; " & - " insidefigure := false ; " ; - -def set_extra_special (expr s) = - if insidefigure : - _local_specials_ := _local_specials_ & s ; - else : - _global_specials_ := _global_specials_ & s ; - fi -enddef ; - -def flush_special (expr typ, siz, dat) = - _special_counter_ := _special_counter_ + 1 ; - if _inline_specials_ : - set_extra_special - ( "special " - & "(" & ditto - & dat & " " - & decimal _special_counter_ & " " - & decimal typ & " " - & decimal siz - & " special" - & ditto & ");" ) ; - else : - set_extra_special - ( "special " - & "(" & ditto - & "%%MetaPostSpecial: " - & decimal siz & " " - & dat & " " - & decimal _special_counter_ & " " - & decimal typ - & ditto & ");" ) ; - fi ; -enddef ; - -%D The next hack is needed in case you use a version of -%D \METAPOST\ that does not provide you the means to configure -%D the buffer size. Patrick Gundlach suggested to use arrays -%D in this case. - -boolean bufferhack ; bufferhack := false ; % true ; - -if bufferhack : - - string _global_specials_[] ; numeric _nof_global_specials_ ; - string _local_specials_[] ; numeric _nof_local_specials_ ; - - _nof_global_specials_ := _nof_local_specials_ := 0 ; - - vardef add_special_signal = % write the version number - if (_nof_global_specials_>0) or (_nof_local_specials_>0) : - special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; - fi ; - enddef ; - - vardef add_extra_specials = - for i=1 upto _nof_global_specials_ : - scantokens _global_specials_[i] ; - endfor; - for i=1 upto _nof_local_specials_ : - scantokens _local_specials_[i] ; - endfor; - enddef ; - - vardef reset_extra_specials = - string _local_specials_[] ; _nof_local_specials_ := 0 ; - enddef ; - - def set_extra_special (expr s) = - if insidefigure : - _local_specials_[incr(_nof_local_specials_)] := s ; - else : - _global_specials_[incr(_nof_global_specials_)] := s ; - fi - enddef ; - -fi ; - -%D So far for this hack. - -%D Shade allocation. - -newinternal shadefactor ; shadefactor := 1 ; - -pair shadeoffset ; shadeoffset := origin ; - -% vardef define_linear_shade (expr a, b, ca, cb) = -% flush_special(30, 15, "0 1 " & decimal shadefactor & " " & -% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & -% dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; -% _special_counter_ -% enddef ; - -% vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = -% flush_special(31, 17, "0 1 " & decimal shadefactor & " " & -% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & -% dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; -% _special_counter_ -% enddef ; - -% these tests are not yet robust for new gray/cmyk features; -% -% - we need to get rid of cmykcolor() and - -vardef _is_cmyk_(expr c) = - (redpart c = _special_signal_/_special_div_) and (greenpart c = 1/_special_div_) -enddef ; -vardef _is_spot_(expr c) = - (redpart c = _special_signal_/_special_div_) and (greenpart c = 2/_special_div_) -enddef ; -vardef _is_gray_(expr c) = - (redpart c = greenpart c) and (greenpart c = bluepart c) -enddef ; - -numeric mp_shade_version ; mp_shade_version := 2 ; % more colors, needs new backend - -vardef define_linear_shade (expr a, b, ca, cb) = - save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; - save gray_a, gray_b ; boolean gray_a, gray_b ; - cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; - cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; - if (mp_shade_version > 1) and cmyk_a and cmyk_b : - flush_special(32, 17, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; - elseif (mp_shade_version > 1) and cmyk_a and gray_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; - flush_special(32, 17, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) ) ; - elseif (mp_shade_version > 1) and gray_a and cmyk_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; - flush_special(32, 17, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; - elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : - flush_special(34, 17, "0 1 " & decimal shadefactor & " " & - spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & - spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; - else : - flush_special(30, 15, "0 1 " & decimal shadefactor & " " & - dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & - dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; - fi ; - _special_counter_ -enddef ; - -vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = - save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; - save gray_a, gray_b ; boolean gray_a, gray_b ; - cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; - cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; - if (mp_shade_version > 1) and cmyk_a and cmyk_b : - flush_special(33, 19, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - elseif (mp_shade_version > 1) and cmyk_a and gray_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; - flush_special(33, 19, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - elseif (mp_shade_version > 1) and gray_a and cmyk_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; - flush_special(33, 19, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : - flush_special(35, 19, "0 1 " & decimal shadefactor & " " & - spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - else : - flush_special(31, 17, "0 1 " & decimal shadefactor & " " & - dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - fi ; - _special_counter_ -enddef ; - -%D A few predefined shading macros. - -boolean trace_shades ; trace_shades := false ; - -% if (n=1) : a := llcorner p ; b := urcorner p ; -% elseif (n=2) : a := llcorner p ; b := ulcorner p ; -% elseif (n=3) : a := lrcorner p ; b := ulcorner p ; -% else : a := llcorner p ; b := lrcorner p ; -% fi ; - -def set_linear_vector (suffix a,b)(expr p,n) = - if (n=1) : a := llcorner p ; - b := urcorner p ; - elseif (n=2) : a := lrcorner p ; - b := ulcorner p ; - elseif (n=3) : a := urcorner p ; - b := llcorner p ; - elseif (n=4) : a := ulcorner p ; - b := lrcorner p ; - elseif (n=5) : a := .5[ulcorner p,llcorner p] ; - b := .5[urcorner p,lrcorner p] ; - elseif (n=6) : a := .5[llcorner p,lrcorner p] ; - b := .5[ulcorner p,urcorner p] ; - elseif (n=7) : a := .5[lrcorner p,urcorner p] ; - b := .5[llcorner p,ulcorner p] ; - elseif (n=8) : a := .5[urcorner p,ulcorner p] ; - b := .5[lrcorner p,llcorner p] ; - else : a := .5[ulcorner p,llcorner p] ; - b := .5[urcorner p,lrcorner p] ; - fi ; -enddef ; - -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 ; - elseif (n=4) : ab := ulcorner p ; - else : ab := center p ; r := .5r ; - fi ; -enddef ; - -def linear_shade (expr p, n, ca, cb) = - begingroup ; - save a, b, sh ; pair a, b ; - set_linear_vector(a,b)(p,n) ; - fill p withshade define_linear_shade (a,b,ca,cb) ; - if trace_shades : - drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -def circular_shade (expr p, n, ca, cb) = - begingroup ; - save ab, r ; pair ab ; numeric r ; - r := (xpart lrcorner p - xpart llcorner p) ++ - (ypart urcorner p - ypart lrcorner p) ; - set_circular_vector(ab,r)(p,n) ; - fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ; - if trace_shades : - drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -vardef predefined_linear_shade (expr p, n, ca, cb) = - save a, b, sh ; pair a, b ; - set_linear_vector(a,b)(p,n) ; - define_linear_shade (a,b,ca,cb) -enddef ; - -vardef predefined_circular_shade (expr p, n, ca, cb) = - save ab, r ; pair ab ; numeric r ; - r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; - set_circular_vector(ab,r)(p,n) ; - define_circular_shade(ab,ab,0,r,ca,cb) -enddef ; - -%D Since a \type {fill p withshade s} syntax looks better -%D than some macro, we implement a new primary. - -primarydef p withshade sc = % == p withcolor shadecolor(sh) - hide (_color_counter_ := _color_counter_ + 1) - p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) -enddef ; - -vardef shadecolor(expr sc) = - hide (_color_counter_ := _color_counter_ + 1) - (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) -enddef ; - -%D Figure inclusion. - -%numeric cef ; cef := 0 ; - -def externalfigure primary filename = - doexternalfigure (filename) -enddef ; - -def doexternalfigure (expr filename) text transformation = - begingroup ; save p, t ; picture p ; transform t ; - p := nullpicture ; t := identity transformation ; - flush_special(10, 9, - dddecimal (xxpart t, yxpart t, xypart t) & " " & - dddecimal (yypart t, xpart t, ypart t) & " " & filename) ; - addto p contour unitsquare scaled 0 ; - setbounds p to unitsquare transformed t ; - _color_counter_ := _color_counter_ + 1 ; - draw p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; - endgroup ; -enddef ; - -%D Experimental: - -%numeric currenthyperlink ; currenthyperlink := 0 ; - -def hyperlink primary t = dohyperlink(t) enddef ; -def hyperpath primary t = dohyperpath(t) enddef ; - -def dohyperlink (expr destination) text transformation = - begingroup ; save somepath ; path somepath ; - somepath := fullsquare transformation ; - dohyperpath(destination) somepath ; - endgroup ; -enddef ; - -def dohyperpath (expr destination) expr somepath = - begingroup ; - flush_special(20, 7, - ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " & - ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ; - _color_counter_ := _color_counter_ + 1 ; - fill boundingbox unitsquare scaled 0 withcolor - (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; - endgroup ; -enddef ; - -% \setupinteraction[state=start] -% \setupcolors [state=start] -% -% Hello There! \blank -% -% \startMPcode -% pickup pencircle scaled 5 ; -% draw fullcircle scaled 4cm withcolor red ; -% hyperpath "nextpage" boundingbox currentpicture ; -% draw origin withcolor blue ; -% \stopMPcode -% -% \blank Does it work or not? -% -% \startMPcode -% pickup pencircle scaled 5 ; -% draw fullcircle scaled 4cm withcolor red ; -% hyperpath "nextpage" fullcircle scaled 4cm ; -% draw origin withcolor blue ; -% draw fullcircle scaled 4cm shifted (1cm,1cm); -% \stopMPcode -% -% \blank Does it work or not? \page Hello There! \blank -% -% \startMPcode -% pickup pencircle scaled 5 ; -% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ; -% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ; -% draw fullcircle scaled 1cm ; -% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ; -% draw origin withcolor blue ; -% \stopMPcode -% -% \blank Does it work or not? - -_cmyk_counter_ := 0 ; - -extra_endfig := " ; resetcmykcolors ; " & extra_endfig ; - -def resetcmykcolors = - numeric cmykcolorhash[][][][] ; -enddef ; - -resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true - -string cmykcolorpattern[] ; % needed for transparancies - -vardef cmyk(expr c,m,y,k) = - if cmykcolors : - save ok ; boolean ok ; - if unknown cmykcolorhash[c][m][y][k] : - ok := false ; % not yet defined - elseif cmykcolorhash[c][m][y][k] = -1 : - ok := false ; % locally defined and undefined - else : - ok := true ; % globally already defined - fi ; - if not ok : -% save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; - save s ; string s ; s := ddddecimal (c,m,y,k) ; - _cmyk_counter_ := _cmyk_counter_ + 1 ; - cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; - cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; - flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; - _local_specials_ := _local_specials_ & - " cmykcolorhash[" & decimal c & "][" & decimal m & - "][" & decimal y & "][" & decimal k & "] := -1 ; " ; - fi ; - (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) - else : - (1-c-k,1-m-k,1-y-k) - fi -enddef ; - -% newcolor truecyan, truemagenta, trueyellow ; -% -% truecyan = (1,0,0,0) ; -% truemagenta = (0,1,0,0) ; -% trueyellow = (0,0,1,0) ; - -%D Spot colors - -_spotcolor_counter_ := 0 ; -_spotcolor_number_ := 0 ; - -extra_endfig := " ; resetspotcolors ; " & extra_endfig ; - -def resetspotcolors = - numeric spotcolorhash[][] ; -enddef ; - -resetspotcolors ; boolean spotcolors ; spotcolors := false ; % true - -string spotcolorpattern[] ; % needed for transparancies - -vardef spotcolor(expr p, s) = - multitonecolor(p, 1, "", decimal s) -enddef ; - -vardef multitonecolor(expr n, f, d, p) = % name fractions names factors - if spotcolors : - save ok, pc_tag ; boolean ok ; string pc_tag ; - pc_tag := "_pct_" & n ; - if not unstringed(pc_tag) : - _spotcolor_number_ := _spotcolor_number_ + 1 ; - setunstringed(pc_tag,_spotcolor_number_) ; - fi ; - pp := getunstringed(pc_tag) ; - pc_tag := "_pct_"& decimal f & "_" & if d = "" : n else : d fi & "_" & p ; % check for d empty - if not unstringed(pc_tag) : - _spotcolor_number_ := _spotcolor_number_ + 1 ; - setunstringed(pc_tag,_spotcolor_number_) ; - fi ; - ps := getunstringed(pc_tag) ; - if unknown spotcolorhash[pp][ps] : - ok := false ; % not yet defined - elseif spotcolorhash[pp][ps] = -1 : - ok := false ; % locally defined and undefined - else : - ok := true ; % globally already defined - fi ; - if not ok : - save ss ; string ss ; ss := n & " " & decimal f & " " & if d = "" : n else : d fi & " " & p ; - _spotcolor_counter_ := _spotcolor_counter_ + 1 ; - spotcolorpattern[_spotcolor_counter_/_special_div_] := ss ; - spotcolorhash[pp][ps] := _spotcolor_counter_ ; - flush_special(2, 7, decimal _spotcolor_counter_ & " " & ss) ; - _local_specials_ := _local_specials_ & - "spotcolorhash["&decimal pp&"]["&decimal ps&"]:=-1;" ; - fi ; - (_special_signal_/_special_div_,2/_special_div_,spotcolorhash[pp][ps]/_special_div_) - else : - .5white - fi -enddef ; - -%D Transparency - -normaltransparent := 1 ; multiplytransparent := 2 ; -screentransparent := 3 ; overlaytransparent := 4 ; -softlighttransparent := 5 ; hardlighttransparent := 6 ; -colordodgetransparent := 7 ; colorburntransparent := 8 ; -darkentransparent := 9 ; lightentransparent := 10 ; -differencetransparent := 11 ; exclusiontransparent := 12 ; - -% nottransparent := 0 ; -% compatibletransparent := 99 ; - -% fill fullcircle scaled 10cm withcolor transparant(8,.3,red) ; - -vardef transparent(expr n, t, c) = - save s, ss, nn, cc, is_cmyk, is_spot, ok ; - string s, ss ; numeric nn ; color cc ; boolean is_cmyk, is_spot, ok ; - % transparancy type - if string n : - if expandafter known scantokens(n&"transparent") : - nn := scantokens(n&"transparent") ; - else : - nn := 0 ; - fi - else : % nn := min(n,13) - nn := if n<13 : n else : nn := 0 fi ; - fi ; - % we need to expand the color (can be cmyk(..) or predefined) - cc := c ; % expand color - % check for cmyk special - is_cmyk := (redpart cc = _special_signal_/_special_div_) - and (greenpart cc = 1/_special_div_) ; - is_spot := (redpart cc = _special_signal_/_special_div_) - and (greenpart cc = 2/_special_div_) ; - % build special string, fetch cmyk components - s := decimal nn & " " & decimal t & " " & - if is_cmyk : cmykcolorpattern[bluepart cc] - elseif is_spot : spotcolorpattern[bluepart cc] - else : dddecimal cc fi ; - % check if this one is already used - ss := cleanstring("tr_" & s) ; - % we now have rather unique names, i.e. a color spec of .234 becomes - % tr..._234.... and metapost gives a number overflow (parse error) - % for variables like tr_12345678 which may result from many decimal - % positions (imo mp bug) - ss := asciistring(ss) ; - % efficiency hack - if expandafter unknown scantokens(ss) : - ok := false ; % not yet defined - elseif scantokens(ss) < 0 : - ok := false ; % locally defined and undefined - else : - ok := true ; % globally already defined - fi ; - if not ok : - if is_spot : - flush_special(5, 8, s) ; - elseif is_cmyk : - flush_special(4, 8, s) ; - else : - flush_special(3, 7, s) ; - fi ; - scantokens(ss) := _special_counter_ ; - _local_specials_ := _local_specials_ & "scantokens(" & ditto & ss & ditto & ") := -1 ;" ; - fi ; - % go ahead - if is_spot : - (_special_signal_/_special_div_,5/_special_div_,scantokens(ss)/_special_div_) - elseif is_cmyk : - (_special_signal_/_special_div_,4/_special_div_,scantokens(ss)/_special_div_) - else : - (_special_signal_/_special_div_,3/_special_div_,scantokens(ss)/_special_div_) - fi -enddef ; - -%D This function returns true of false, dependent on transparency. - -vardef is_transparent(text t) = - begingroup ; save transparent ; save _c_, _b_ ; - vardef transparent(expr nn, tt, cc) = _b_ := true ; cc enddef ; - boolean _b_ ; _b_ := false ; - color _c_ ; _c_ := t ; _b_ - endgroup -enddef ; - -% boolean _b_ ; better namespacing -% color _c_ ; -% vardef _transparent_(expr nn, tt, cc) = _b_ := true ; cc enddef ; -% vardef is_transparent(text t) = -% begingroup ; -% save transparent ; -% transparent := _transparent_ ; -% _b_ := false ; -% _c_ := t ; _b_ -% endgroup -% enddef ; - -%D This function returns the not transparent color. - -vardef not_transparent(text t) = - begingroup ; save transparent ; - vardef transparent(expr nn, tt, cc) = cc enddef ; - t endgroup -enddef ; - -%D Basic position tracking: - -def register (expr label, width, height, offset) = - begingroup ; - flush_special(50, 7, - ddecimal offset & " " & - decimal width & " " & - decimal height & " " & label) ; - endgroup ; -enddef ; - -%D We cannot scale cmyk colors directly since this spoils -%D the trigger signal (such colors are no real colors). - -vardef scaledcmyk(expr c,m,y,k,sf) = - cmyk(sf*c,sf*m,sf*y,sf*k) -enddef ; - -vardef scaledcmykasrgb(expr c,m,y,k,sf) = - (sf*(1-c-k,1-m-k,1-y-k)) -enddef ; - -vardef scaledrgbascmyk(expr c,m,y,k,sf) = - scaledcmyk(1-c,1-m,1-y,0,sf) -enddef ; - -vardef scaledrgb(expr r,g,b,sf) = - (sf*(r,g,b)) -enddef ; - -vardef scaledgray(expr s,sf) = - (sf*(s,s,s)) -enddef ; - -% spotcolor is already scaled - -% just an exercise (due to a question by Chof on the context mailing list); scaling of -% 'special' colors is not possible and the next solution is incomplete (spot colors, -% transparency, etc); watch the the tricky chained macro construction - -% vardef normalgray(expr s ) = (s,s,s) enddef ; -% vardef normalrgb (expr r,g,b ) = (r,g,b) enddef ; -% vardef normalcmyk(expr c,m,y,k) = if cmykcolors : save ok ; boolean ok ; if unknown cmykcolorhash[c][m][y][k] : ok := false ; elseif cmykcolorhash[c][m][y][k] = -1 : ok := false ; else : ok := true ; fi ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; _cmyk_counter_ := _cmyk_counter_ + 1 ; cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" & decimal c & "][" & decimal m & "][" & decimal y & "][" & decimal k & "] := -1 ; " ; fi ; (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) else : (1-c-k,1-m-k,1-y-k) fi enddef ; - -% vardef gray(expr s) = normalgray(s ) enddef ; -% vardef rgb (expr r,g,b) = normalrgb (r,g,b ) enddef ; -% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; - -% numeric _scaled_color_t_ ; -% color _scaled_color_c_ ; - -% def withscaledcolor = -% hide ( -% _scaled_color_t_ := 0 ; % direct -% def gray(expr s) = -% hide ( -% _gray_s_ := s ; -% _scaled_color_t_ := 1; % gray -% ) -% 0 -% enddef ; -% def rgb (expr r,g,b) = -% hide ( -% _rgb_r_ := r ; _rgb_g_ := g ; _rgb_b_ := b ; -% _scaled_color_t_ := 2 ; % rgb -% ) -% 0 -% enddef ; -% def cmyk (expr c,m,y,k) = -% hide ( -% _cmyk_c_ := c ; _cmyk_m_ := m ; _cmyk_y_ := y ; _cmyk_k_ := k ; -% _scaled_color_t_ := 3 ; % cmyk -% ) -% 0 -% enddef ; ) -% dowithscaledcolor -% enddef ; - -% def dowithscaledcolor expr t = -% hide ( -% if color t : _scaled_color_c_ := t fi ; -% vardef gray(expr s) = normalgray(s) enddef ; -% vardef rgb (expr r,g,b) = normalrgb (r,g,b) enddef ; -% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; -% ) -% enddef ; - -% def by expr s = -% if _scaled_color_t_ = 0 : -% withcolor s*_scaled_color_c_ -% elseif _scaled_color_t_ = 1 : -% withcolor gray(s*_gray_s_) -% elseif _scaled_color_t_ = 2 : -% withcolor rgb (s*_rgb_r_, s*_rgb_g_, s*_rgb_b_) -% elseif _scaled_color_t_ = 3 : -% withcolor cmyk(s*_cmyk_c_, s*_cmyk_m_, s*_cmyk_y_, s*_cmyk_k_) -% fi -% enddef ; - -% fill fullcircle scaled 10cm withscaledcolor cmyk(0,0,1,0) by .5 ; -% fill fullcircle scaled 8cm withscaledcolor rgb (0,0,1) by .5 ; -% fill fullcircle scaled 6cm withscaledcolor gray(1) by .5 ; -% fill fullcircle scaled 4cm withscaledcolor (0,1,0) by .5 ; diff --git a/metapost/context/base/mp-step.mpii b/metapost/context/base/mp-step.mpii deleted file mode 100644 index e05f00b6e..000000000 --- a/metapost/context/base/mp-step.mpii +++ /dev/null @@ -1,317 +0,0 @@ -%D \module -%D [ file=mp-step.mpii, -%D version=2001.05.22, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=steps, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%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_step : endinput ; fi ; - -boolean context_step ; context_step := true ; - -%D In the associated \TEX\ module \type {m-steps}, we describe -%D three methods. The first method uses a different kind of -%D code than the other two. The method we decided to use, -%D is based on positional information (paths) provided by -%D \CONTEXT. - -def initialize_step_variables = - save line_method, line_h_offset, line_v_offset ; - numeric line_method ; line_method := 1 ; - numeric line_h_offset ; line_h_offset := 3pt ; - numeric line_v_offset ; line_v_offset := 3pt ; -enddef ; - -def begin_step_chart = - initialize_step_variables ; - save steps, texts, t, b, tb, nofcells ; - picture cells[][], texts[][][], lines[][][] ; - numeric t, b ; t := 1 ; b := 2 ; - numeric nofcells ; nofcells := 0 ; -enddef ; - -def analyze_step_chart = - numeric n[], l[][], r[][] ; pair p[] ; - n[t] := n[b] := 0 ; numeric tb ; - for i=1 upto nofcells : for nn = t, b : - if bbwidth(cells[nn][i])>0 : n[nn] := n[nn] + 1 ; fi ; - l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ; - endfor ; endfor ; - % count left and right points - for i=1 upto nofcells-1 : for j=i upto nofcells-1 : for nn = t, b : - if bbwidth(texts[nn][i][j])>0 : - l[nn][i] := l[nn][i] + 1 ; - r[nn][j+1] := r[nn][j+1] + 1 ; - fi ; - endfor ; endfor ; endfor ; - % calculate left and right points - vardef do (expr nn, mm, ii, ss) = - if (l[nn][ii] + r[nn][ii]) > 1 : ss else : .5 fi - [ ulcorner cells[mm][ii], urcorner cells[mm][ii] ] - enddef ; - % combined rows - tb := if n[t]>0 : t else : b fi ; -enddef ; - -vardef get_step_chart_top_line (expr i, j) = - if bbwidth(cells[tb][i])>0 : - if bbwidth(texts[t][i][j])>0 : - if bbwidth(cells[tb][j+1])>0 : - p[1] := top do(t, tb, i, .6) ; - p[3] := top do(t, tb, j+1, .4) ; - p[2] := .5[p[1],p[3]] ; - if line_method = 1 : - p[2] := p[2] shifted (0, ypart - (llcorner texts[t][i][j] - ulcorner cells[tb][j+1])) ; - elseif line_method = 2 : - p[2] := center texts[t][i][j] ; - else : - % nothing - fi ; - p[1] := p[1] shifted (0,+line_v_offset) ; - p[2] := p[2] shifted (0,-line_v_offset) ; - p[3] := p[3] shifted (0,+line_v_offset) ; - (p[1] {up} ... p[2] ... {down} p[3]) - else : - origin - fi - else : - origin - fi - else : - origin - fi -enddef ; - -vardef get_step_chart_bot_line (expr i, j) = - if bbwidth(cells[b][i])>0 : - if bbwidth(texts[b][i][j])>0 : - if bbwidth(cells[b][j+1])>0 : - p[1] := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ; - p[3] := (bot do(b, b, j+1, .4)) shifted (0,-bbheight(cells[b][j+1])) ; - p[2] := .5[p[1],p[3]] ; - if line_method = 1 : - p[2] := p[2] shifted (0, -ypart - (llcorner cells[b][j+1] - ulcorner texts[b][i][j])) ; - elseif line_method = 2 : - p[2] := center texts[b][i][j] ; - fi ; - p[1] := p[1] shifted (0,-line_v_offset) ; - p[2] := p[2] shifted (0,+line_v_offset) ; - p[3] := p[3] shifted (0,-line_v_offset) ; - (p[1] {down} ... p[2] ... {up} p[3]) - else : - origin - fi - else : - origin - fi - else : - origin - fi -enddef ; - -def end_step_chart = - for i=1 upto nofcells : for nn = t, b : - if bbwidth(cells[nn][i]) >0 : draw cells[nn][i] ; fi ; - endfor ; endfor ; - for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b : - if known lines[nn][i][j] : - if bbwidth(lines[nn][i][j])>0 : draw lines[nn][i][j] ; fi ; - fi ; - endfor ; endfor ; endfor ; - for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b : - if bbwidth(texts[nn][i][j])>0 : draw texts[nn][i][j] ; fi ; - endfor ; endfor ; endfor ; -enddef ; - -%D Step tables. - -def begin_step_table = - initialize_step_variables ; - picture cells[], texts[], lines[] ; - numeric nofcells ; nofcells := 0 ; -enddef ; - -def end_step_table = - for i=1 upto nofcells : if known cells[i] : if bbwidth(cells[i])>0 : - draw cells[i] ; - fi ; fi ; endfor ; - for i=1 upto nofcells : if known lines[i] : if bbwidth(lines[i])>0 : - draw lines[i] ; - fi ; fi ; endfor ; - for i=1 upto nofcells : if known texts[i] : if bbwidth(texts[i])>0 : - draw texts[i] ; - fi ; fi ; endfor ; -enddef ; - -vardef get_step_table_line (expr i) = - pair prev, self, next ; - if known texts[i] : - self := lft .5[llcorner texts[i], ulcorner texts[i] ] ; - prev := rt if known texts[i-1] : .3 else : .5 fi [lrcorner cells[i] , urcorner cells[i] ] ; - next := rt if known texts[i+1] : .7 else : .5 fi [lrcorner cells[i+1], urcorner cells[i+1]] ; - self := self shifted (-line_h_offset,0) ; - prev := prev shifted (+line_h_offset,0) ; - next := next shifted (+line_h_offset,0) ; - prev {right} ... self ... {left} next - else : - origin - fi -enddef ; - -%D The older method let \METAPOST\ do the typesetting. The -%D macros needed for that are included here for educational -%D purposes. -%D -%D \starttypen -%D def initialize_step_variables = -%D save line_color, line_width, arrow_alternative, -%D text_fill_color, text_line_color, text_line_width, text_offset, -%D cell_fill_color, cell_line_color, cell_line_width, cell_offset, -%D line_h_offset, line_v_offset ; -%D color line_color ; line_color := .4white ; -%D numeric line_width ; line_width := 1.5pt ; -%D color text_fill_color ; text_fill_color := white ; -%D color text_line_color ; text_line_color := red ; -%D numeric text_line_width ; text_line_width := 1pt ; -%D numeric text_offset ; text_offset := 2pt ; -%D color cell_fill_color ; cell_fill_color := white ; -%D color cell_line_color ; cell_line_color := blue ; -%D numeric cell_line_width ; cell_line_width := 1pt ; -%D numeric cell_offset ; cell_offset := 2pt ; -%D numeric line_alternative ; line_alternative := 1 ; -%D numeric line_h_offset ; line_h_offset := 3pt ; -%D numeric line_v_offset ; line_v_offset := 3pt ; -%D enddef ; -%D -%D def begin_step_chart = -%D begingroup ; -%D initialize_step_variables ; -%D save steps, texts, t, b ; -%D picture cells[][] ; numeric nofcells ; nofcells := 0 ; -%D picture texts[][][] ; numeric noftexts ; noftexts := 0 ; -%D numeric t, b ; t := 1 ; b := 2 ; -%D enddef ; -%D \stoptypen -%D -%D We use a couple of macros to store the content. In the -%D second (third) alternative we will directly fill the -%D cells. -%D -%D \starttypen -%D def set_step_chart_cells (expr one, two) = -%D nofcells := nofcells + 1 ; noftexts := 0 ; -%D cells[t][nofcells] := textext.rt(one) ; -%D cells[b][nofcells] := textext.rt(two) ; -%D enddef ; -%D -%D def set_step_chart_texts (expr one, two) = -%D noftexts := noftexts + 1 ; -%D texts[t][nofcells][noftexts] := textext.rt(one) ; -%D texts[b][nofcells][noftexts] := textext.rt(two) ; -%D enddef ; -%D \stoptypen -%D -%D If you compare the building macro with the later -%D alternative, you will notice that here we explicitly -%D have to calculate the distances and positions. -%D -%D \starttypen -%D def end_step_chart = -%D numeric dx ; dx := 0 ; path p ; -%D numeric n[] ; n[t] := n[b] := 0 ; -%D numeric stepsvdistance[] ; -%D vardef bbwidth (expr p) = (xpart (lrcorner p - llcorner p)) enddef ; -%D vardef bbheight (expr p) = (ypart (urcorner p - lrcorner p)) enddef ; -%D stepsvdistance[t] := stepsvdistance[b] := 0 ; -%D for i=1 upto nofcells : -%D % find largest bbox -%D p := boundingbox steps -%D [if bbwidth(cells[t][i])>bbwidth(cells[b][i]): t else: b fi][i] ; -%D % assign largest bbox -%D for nn = t, b : -%D if bbwidth(cells[nn][i])>0 : -%D setbounds cells[nn][i] to p enlarged cell_offset ; -%D n[nn] := n[nn] + 1 ; -%D fi ; -%D endfor ; -%D % determine height -%D if n[t]>0 : -%D stepsvdistance[t] := bbheight(cells[t][1]) + intertextdistance ; -%D fi ; -%D % add to row -%D for nn = t, b : -%D cells[nn][i] := cells[nn][i] shifted (dx,stepsvdistance[nn]) ; -%D if bbwidth(cells[nn][i])>0 : -%D dowithpath (boundingbox cells[nn][i], -%D cell_line_width, cell_line_color, cell_background_color) ; -%D fi ; -%D endfor ; -%D % calculate position -%D dx := dx + interstepdistance + bbwidth(cells[b][i]) ; -%D endfor ; -%D boolean stacked ; stacked := false ; -%D numeric l[][], r[][], l[][], r[][] ; -%D pair pa, pb, pc ; path p[] ; -%D for i=1 upto nofcells : -%D l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ; -%D endfor ; -%D % count left and right points -%D for i=1 upto nofcells : for j=1 upto nofcells : for nn = t, b : -%D if known texts[nn][i][j] : if bbwidth(texts[nn][i][j])>0 : -%D l[nn][i] := l[nn][i] + 1 ; -%D r[nn][j+i] := r[nn][j+i] + 1 ; -%D stacked := (stacked or (j>1)) ; -%D setbounds texts[nn][i][j] to boundingbox texts[nn][i][j] enlarged cell_offset ; -%D fi fi ; -%D endfor ; endfor ; endfor ; -%D % calculate left and right points -%D vardef do (expr nn, mm, ii, ss) = -%D if (l[nn][ii] > 0) and (r[nn][ii] > 0) : ss else : .5 fi -%D [ ulcorner cells[mm][ii],urcorner cells[mm][ii] ] -%D enddef ; -%D % draw arrow from left to right point -%D def dodo (expr nn, ii, jj, dd) = -%D drawarrow p[nn] -%D withpen pencircle scaled arrow_line_width -%D withcolor arrow_line_color ; -%D transform tr ; tr := identity -%D shifted point .5 along p[nn] -%D shifted -center texts[nn][ii][jj] -%D if not stacked : shifted (0,dd) fi ; -%D dowithpath ((boundingbox texts[nn][ii][jj]) transformed tr, -%D text_line_width, text_line_color, text_fill_color) ; -%D enddef ; -%D % draw top and bottom text boxes -%D for i=1 upto nofcells : for j=1 upto nofcells : -%D pickup pencircle scaled arrow_line_width ; -%D if known texts[t][i][j] : if bbwidth(texts[t][i][j]) > 0 : -%D pa := top do(t, if n[t]>0 : t else : b fi, i, .6) ; -%D pb := top do(t, if n[t]>0 : t else : b fi, j+i, .4) ; -%D pc := .5[pa,pb] shifted (0,+step_arrow_depth) ; -%D p[t] := pa {up} .. if not stacked : pc .. fi {down} pb ; -%D dodo(t, i, j, +intertextdistance) ; -%D fi fi ; -%D if known texts[b][i][j] : if bbwidth(texts[b][i][j]) > 0 : -%D pa := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ; -%D pb := (bot do(b, b, j+i, .4)) shifted (0,-bbheight(cells[b][j+i])) ; -%D pc := .5[pa,pb] shifted (0,-step_arrow_depth) ; -%D p[b] := pa {down} .. if not stacked : pc .. fi {up} pb ; -%D dodo(b, i, j, -intertextdistance) ; -%D fi fi ; -%D endfor ; endfor ; -%D endgroup ; -%D enddef ; -%D \stoptypen -%D -%D If you compare both methods, you will notice that the -%D first method is the cleanest, but not the most efficient -%D (since it needs \TEX\ runs within \METAPOST\ runs within -%D \TEX\ runs). diff --git a/metapost/context/base/mp-step.mpiv b/metapost/context/base/mp-step.mpiv deleted file mode 100644 index f7a7ba5de..000000000 --- a/metapost/context/base/mp-step.mpiv +++ /dev/null @@ -1,376 +0,0 @@ -%D \module -%D [ file=mp-cell.mpiv, % mp-step.mpiv, -%D version=2010.10.07, % 2001.05.22, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=steps, -%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. - -% step prefixes .. no save needed - -if known context_cell : endinput ; fi ; - -boolean context_cell ; context_cell := true ; - -def initialize_step_variables = - save - text_fill_color, text_line_color, text_line_width, text_offset, - cell_fill_color, cell_line_color, cell_line_width, cell_offset, - line_line_color, line_line_width, line_alternative, - line_distance, cell_distance_y, cell_distance_x, - nofcells, chart_vertical ; - - color text_line_color ; text_line_color := red ; - color cell_line_color ; cell_line_color := blue ; - color line_line_color ; line_line_color := green ; - - color text_fill_color ; text_fill_color := white ; - color cell_fill_color ; cell_fill_color := white ; - - numeric text_line_width ; text_line_width := 2pt ; - numeric cell_line_width ; cell_line_width := 2pt ; - numeric line_line_width ; line_line_width := 2pt ; - - numeric text_offset ; text_offset := 4pt ; - numeric cell_offset ; cell_offset := 4pt ; - - numeric line_distance ; line_distance := 10pt ; % between line and text - numeric line_offset ; line_offset := 4pt ; % between center and start of line - numeric line_height ; line_height := 20pt ; - - numeric cell_distance_y ; cell_distance_y := 20pt ; - numeric cell_distance_x ; cell_distance_x := 20pt ; - - numeric text_distance_set ; text_distance_set := 4pt ; - - boolean chart_vertical ; chart_vertical := false ; - - numeric nofcells ; nofcells := 0 ; - -enddef ; - -def step_cells (expr t, b) = - nofcells := nofcells + 1 ; - cells_t[nofcells] := textext.d(t) ; - cells_b[nofcells] := textext.d(b) ; - texts_t[nofcells] := nullpicture ; - texts_m[nofcells] := nullpicture ; - texts_b[nofcells] := nullpicture ; -enddef ; - -def step_texts (expr t, b) = - texts_t[nofcells] := textext.d(t) ; - texts_m[nofcells] := textext.d(m) ; - texts_b[nofcells] := textext.d(b) ; -enddef ; - -def step_begin_cell = - nofcells := nofcells + 1 ; - cells_t[nofcells] := nullpicture ; - cells_b[nofcells] := nullpicture ; - texts_t[nofcells] := nullpicture ; - texts_m[nofcells] := nullpicture ; - texts_b[nofcells] := nullpicture ; -enddef ; - -def step_end_cell = -enddef ; - -def step_cell_top (expr t) = cells_t[nofcells] := textext.d(t) ; enddef ; -def step_cell_bot (expr b) = cells_b[nofcells] := textext.d(b) ; enddef ; -def step_text_top (expr t) = texts_t[nofcells] := textext.d(t) ; enddef ; -def step_text_mid (expr m) = texts_m[nofcells] := textext.d(m) ; enddef ; -def step_text_bot (expr b) = texts_b[nofcells] := textext.d(b) ; enddef ; - -def step_begin_chart = - begingroup ; - initialize_step_variables ; - save nofcells ; numeric nofcells ; nofcells := 0 ; - save cells_t, cells_m, cells_b ; picture cells_t[], cells_m[], cells_b[] ; - save texts_t, texts_m, texts_b ; picture texts_t[], texts_m[], texts_b[] ; -enddef ; - -def step_end_chart = - % we could combine some loops but this is cleaner - save dx, delta ; numeric dx, delta ; - save p ; path p ; - save one_row_only ; boolean one_row_only ; - save cell_t, next_t, text_t ; picture cell_t, next_t, text_t ; - save cell_m, next_m, text_m ; picture cell_m, next_m, text_m ; - save cell_b, next_b, text_b ; picture cell_b, next_b, text_b ; - save height_t, width_t, max_height_t, max_width_t ; numeric height_t, width_t, max_height_t, max_width_t ; - save height_m, width_m, max_height_m, max_width_m ; numeric height_m, width_m, max_height_m, max_width_m ; - save height_b, width_b, max_height_b, max_width_b ; numeric height_b, width_b, max_height_b, max_width_b ; - % check rows - one_row_only := true ; - for i=1 upto nofcells : - if bbwidth(cells_b[i]) > 0 : - one_row_only := false ; - fi ; - endfor ; - % swap and rotate - if chart_vertical : - if one_row_only : - % deal with mid_texts - max_width_t := max_width_m := max_width_b := 0 ; - for i=1 upto nofcells : - width_t := bbwidth(texts_t[i]) ; - width_m := bbwidth(texts_m[i]) ; - width_b := bbwidth(texts_b[i]) ; - if width_t > max_width_t : max_width_t := width_t fi ; - if width_m > max_width_m : max_width_m := width_m fi ; - if width_b > max_width_b : max_width_b := width_b fi ; - endfor ; - if max_width_m > 0 : - for i=1 upto nofcells : - text_t := texts_t[i] ; width_t := bbwidth(text_t) ; - text_m := texts_m[i] ; width_m := bbwidth(text_m) ; - text_b := texts_b[i] ; width_b := bbwidth(text_b) ; - if width_t < max_width_t : - setbounds text_t to boundingbox text_t leftenlarged (max_width_t - width_t) ; - fi ; - if width_m < max_width_m : - setbounds text_m to boundingbox text_m leftenlarged ((max_width_m - width_m)/2) ; - setbounds text_m to boundingbox text_m rightenlarged ((max_width_m - width_m)/2) ; - fi ; - if width_b < max_width_b : - setbounds text_b to boundingbox text_b rightenlarged (max_width_b - width_b) ; - fi ; - text_t := text_t shifted (- xpart llcorner text_t, 0) ; - text_m := text_m shifted (- xpart llcorner text_m, 0) ; - text_b := text_b shifted (- xpart llcorner text_b, 0) ; - texts_t[i] := image ( - draw text_t ; - draw text_m shifted (max_width_t + text_distance_set,0) ; - draw text_b shifted (max_width_t + max_width_m + 2*text_distance_set,0) ; - ) rotated 90 ; - texts_m[i] := texts_b[i] := nullpicture ; - cells_t[i] := cells_t[i] rotated 90 ; - endfor ; - else : - for i=1 upto nofcells : - cells_t[i] := cells_t[i] rotated 90 ; - texts_t[i] := texts_t[i] rotated 90 ; - texts_b[i] := texts_b[i] rotated 90 ; - endfor ; - fi ; - else : - for i=1 upto nofcells : - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - cells_t[i] := cell_b rotated 90 ; - cells_b[i] := cell_t rotated 90 ; - text_t := texts_t[i] ; - text_b := texts_b[i] ; - texts_t[i] := text_b rotated 90 ; - texts_b[i] := text_t rotated 90 ; - endfor ; - fi ; - fi ; - % align horizontal - for i=1 upto nofcells : - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - width_t := bbwidth(cell_t) ; - width_b := bbwidth(cell_b) ; - if (width_t = 0) and (width_b = 0) : - % skip - elseif (width_t > 0) and (width_t < width_b) : - delta := (width_b-width_t)/2 ; - setbounds cell_t to boundingbox cell_t leftenlarged delta rightenlarged delta ; - cells_t[i] := cell_t ; - elseif (width_b > 0) and (width_t > width_b) : - delta := (width_t-width_b)/2 ; - setbounds cell_b to boundingbox cell_b leftenlarged delta rightenlarged delta ; - cells_b[i] := cell_b ; - fi ; - endfor ; - % analyze vertical - max_height_t := 0 ; - max_height_b := 0 ; - for i=1 upto nofcells : - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - height_t := bbheight(cell_t) ; - height_b := bbheight(cell_b) ; - if height_t > 0 : - setbounds cell_t to boundingbox cell_t enlarged cell_offset ; - height_t := height_t + 2 * cell_offset ; - cells_t[i] := cell_t ; - fi ; - if height_b > 0 : - setbounds cell_b to boundingbox cell_b enlarged cell_offset ; - height_b := height_b + 2 * cell_offset ; - cells_b[i] := cell_b ; - fi ; - if height_t > max_height_t : - max_height_t := height_t ; - fi - if height_b > max_height_b : - max_height_b := height_b ; - fi ; - endfor ; - % align vertical - for i=1 upto nofcells : - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - height_t := bbheight(cell_t) ; - height_b := bbheight(cell_b) ; - if height_t > 0 : - delta := (max_height_t-height_t)/2 ; - setbounds cell_t to boundingbox cell_t topenlarged delta bottomenlarged delta ; - fi ; - if height_b > 0 : - delta := (max_height_b-height_b)/2 ; - setbounds cell_b to boundingbox cell_b topenlarged delta bottomenlarged delta ; - fi ; - cells_t[i] := cell_t ; - cells_b[i] := cell_b ; - endfor ; - % position - dx := 0 ; - for i=1 upto nofcells : - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - cell_t := cell_t shifted -llcorner cell_t ; - cell_b := cell_b shifted -llcorner cell_b ; - cell_t := cell_t shifted (dx, 0) ; - cell_b := cell_b shifted (dx,-cell_distance_y-max_height_b) ; - cells_t[i] := cell_t ; - cells_b[i] := cell_b ; - width_t := bbwidth(cell_t) ; - width_b := bbwidth(cell_b) ; - if width_t > 0 : - dx := dx + cell_distance_x + width_t ; - elseif width_b > 0 : - dx := dx + cell_distance_x + width_b ; - fi ; - endfor ; - % flush - for i=1 upto nofcells : - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - width_t := bbwidth(cell_t) ; - width_b := bbwidth(cell_b) ; - if width_t > 0 : - fill boundingbox cell_t withcolor cell_fill_color ; - draw boundingbox cell_t withpen pencircle scaled cell_line_width withcolor cell_line_color ; - draw cell_t ; - fi ; - if width_b > 0 : - fill boundingbox cell_b withcolor cell_fill_color ; - draw boundingbox cell_b withpen pencircle scaled cell_line_width withcolor cell_line_color ; - draw cell_b ; - fi ; - endfor ; - % - def midtopboundary expr p = 0.5[ulcorner boundingbox p, urcorner boundingbox p] enddef ; - def midbottomboundary expr p = 0.5[llcorner boundingbox p, lrcorner boundingbox p] enddef ; - % draw top and bottom text boxes - for i=1 upto nofcells-1 : - text_t := texts_t[i] ; - text_b := texts_b[i] ; - if bbwidth(text_t) > 0 : - setbounds text_t to boundingbox text_t enlarged text_offset ; - texts_t[i] := text_t ; - fi ; - if bbwidth(text_b) > 0 : - setbounds text_b to boundingbox text_b enlarged text_offset ; - texts_b[i] := text_b ; - fi ; - endfor ; - % arrows - for i=1 upto nofcells-1 : - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - next_t := cells_t[i+1] ; - next_b := cells_b[i+1] ; - pair t_a, t_b, t_c, b_a, b_b, b_c ; - t_a := midtopboundary cell_t ; - t_b := midtopboundary next_t ; - t_c := (xpart 0.5[t_a,t_b], ypart t_a+line_height+line_distance) ; - if one_row_only : - b_a := midbottomboundary cell_t ; - b_b := midbottomboundary next_t ; - else : - b_a := midbottomboundary cell_b ; - b_b := midbottomboundary next_b ; - fi ; - b_c := (xpart 0.5[b_a,b_b], ypart b_a-line_height-line_distance) ; - texts_t[i] := thelabel.top(texts_t[i],t_c) ; - texts_b[i] := thelabel.bot(texts_b[i],b_c) ; - endfor ; - % - for i=1 upto nofcells-1 : % todo arrows when empty text - cell_t := cells_t[i] ; - cell_b := cells_b[i] ; - next_t := cells_t[i+1] ; - next_b := cells_b[i+1] ; - text_t := texts_t[i] ; - text_b := texts_b[i] ; - if bbwidth(text_t) > 0 : - if bbwidth(cell_t) > 0 : - drawarrow midtopboundary cell_t - shifted (if i > 1 : line_offset else : 0 fi, cell_line_width) {up} .. - midbottomboundary text_t shifted (0,-line_distance) .. - {down} midtopboundary next_t shifted(if i < nofcells - 1 : -line_offset else : 0 fi,cell_line_width) - withpen pencircle scaled line_line_width - withcolor line_line_color ; - else : - fi ; - fi ; - if bbwidth(text_b) > 0 : - if one_row_only : - cell_b := cell_t ; - next_b := next_t ; - fi ; - if bbwidth(cell_b) > 0 : - drawarrow midbottomboundary cell_b - shifted (if i > 1 : line_offset else : 0 fi, -cell_line_width) {down} .. - midtopboundary text_b shifted (0, line_distance) .. - {up} midbottomboundary next_b shifted (if i < nofcells - 1 : -line_offset else : 0 fi,-cell_line_width) - withpen pencircle scaled line_line_width - withcolor line_line_color ; - else : - fi ; - fi ; - endfor ; - % draw top and bottom text boxes - for i=1 upto nofcells-1 : - text_t := texts_t[i] ; - text_b := texts_b[i] ; - if bbwidth(text_t) > 0 : - fill boundingbox text_t withcolor text_fill_color ; - draw boundingbox text_t withpen pencircle scaled text_line_width withcolor text_line_color ; - draw text_t ; - fi ; - if bbwidth(text_b) > 0 : - fill boundingbox text_b withcolor text_fill_color ; - draw boundingbox text_b withpen pencircle scaled text_line_width withcolor text_line_color ; - draw text_b ; - fi ; - endfor ; - if chart_vertical : - % rotate back - currentpicture := currentpicture rotated -90 ; - fi ; - endgroup ; -enddef ; - -% start_begin_step ; -% step_cells ("\strut test 0", "\strut test 0") ; -% step_cells ("\strut test 1", "\vbox{\hsize3cm \strut oeps 1\crlf oeps 1}") ; -% step_texts ("\strut 1", "\strut 1") ; -% step_cells ("\strut test 2", "\strut oeps 2 oeps 2") ; -% step_cells ("\strut test X", "\strut test X") ; -% step_texts ("\strut 2", "\strut 2") ; -% step_cells ("\strut test 3", "\strut oeps 3 oeps 3") ; -% step_texts ("\strut 3", "\strut 3") ; -% step_cells ("\strut test 4", "\strut oeps 4 oeps 4") ; -% step_texts ("\strut 4", "\strut 4") ; -% stop_end_chart ; diff --git a/metapost/context/base/mp-symb.mp b/metapost/context/base/mp-symb.mp deleted file mode 100644 index a84c84e82..000000000 --- a/metapost/context/base/mp-symb.mp +++ /dev/null @@ -1,351 +0,0 @@ -%D \module -%D [ file=mp-symb.mp, -%D version=very old, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=navigation symbol macros, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -%D Instead of these symbols, you can use the \type {contnav} -%D font by Taco Hoekwater that is derived form this file. - -u := 3; -h := 5u; -wt := 5u; -wb := .25wt; -o := .1u; -pw := .5u; - -drawoptions (withpen pencircle scaled pw); - -path lefttriangle, righttriangle, sublefttriangle, subrighttriangle; - -pair s ; s = (2wb,0) ; - -x1t = x2t = 0; -x3t = wt; -y3t = .5h; -z1t-z2t = (z3t-z2t) rotated 60; - -z4t = (z2t--z3t) intersectionpoint ((z1t--z2t) shifted s) ; -z5t = (z3t--z1t) intersectionpoint ((z1t--z2t) shifted s) ; - -righttriangle = z1t--z2t--z3t--cycle; -lefttriangle = righttriangle rotatedaround((0,.5h), 180) shifted (wt,0); - -subrighttriangle = z4t--((z2t--z3t--z1t) shifted s)--z5t ; -sublefttriangle = subrighttriangle rotatedaround((0,.5h), 180) shifted (wt,0); - -path sidebar; - -x1b = x4b = 0; -x2b = x3b = wb; -y1b = y2b = y1t; -y3b = y4b = y2t; - -sidebar = z1b--z2b--z3b--z4b--cycle; - -path midbar, onebar, twobar; - -hh = abs(y1t-y2t); - -%midbar := unitsquare scaled 2hh/3; -midbar := unitsquare scaled hh; -onebar := unitsquare xscaled (hh/3) yscaled hh; -twobar := onebar; - -def prepareglyph = - drawoptions (withpen pencircle scaled .5u); -enddef; - -def finishglyph = - set_outer_boundingbox currentpicture; - bboxmargin := o; - setbounds currentpicture to bbox currentpicture; -% draw boundingbox currentpicture withcolor red withpen pencircle scaled 1; -enddef; - -beginfig (1); - prepareglyph; - fill lefttriangle; - draw lefttriangle; % draw gets the bbox right, filldraw doesn't - finishglyph; -endfig; - -beginfig (2); - prepareglyph; - fill righttriangle; - draw righttriangle; - finishglyph; -endfig; - -beginfig (3); - prepareglyph; - fill sidebar; - draw sidebar; - fill lefttriangle shifted (.5s); - draw lefttriangle shifted (.5s); - finishglyph; -endfig; - -beginfig (4); - prepareglyph; - fill righttriangle; - draw righttriangle; - fill sidebar shifted (wt,0); - draw sidebar shifted (wt,0); - finishglyph; -endfig; - -beginfig (5); - prepareglyph; - fill lefttriangle; - draw lefttriangle; - fill lefttriangle shifted s; - draw lefttriangle shifted s; - finishglyph; -endfig; - -beginfig (6); - prepareglyph; - fill righttriangle; - draw righttriangle; - fill righttriangle shifted s; - draw righttriangle shifted s; - finishglyph; -endfig; - -beginfig (7); - prepareglyph; - fill midbar; - draw midbar; - finishglyph; -endfig; - -beginfig (8); - prepareglyph; - fill onebar; - draw onebar; - finishglyph; -endfig; - -beginfig (9); - prepareglyph; - fill twobar; - draw twobar; - fill twobar shifted (pw+hh/2,0); - draw twobar shifted (pw+hh/2,0); - finishglyph; -endfig; - -beginfig(101); - prepareglyph; - draw lefttriangle; - finishglyph; -endfig; - -beginfig(102); - prepareglyph; - draw righttriangle; - finishglyph; -endfig; - -beginfig(103); - prepareglyph; - draw sidebar; - draw lefttriangle shifted (.5s); - finishglyph; -endfig; - -beginfig(104); - prepareglyph; - draw righttriangle; - draw sidebar shifted (wt,0); - finishglyph; -endfig; - -beginfig(105); - prepareglyph; - draw lefttriangle; - draw lefttriangle shifted s; - finishglyph; -endfig; - -beginfig(106); - prepareglyph; - draw righttriangle; - draw righttriangle shifted s; - finishglyph; -endfig; - -beginfig(107); - prepareglyph; - draw midbar; - finishglyph; -endfig; - -beginfig(108); - prepareglyph; - draw onebar; - finishglyph; -endfig; - -beginfig(109); - prepareglyph; - draw twobar; - draw twobar shifted (pw+hh/2,0); - finishglyph; -endfig; - -beginfig(201); - prepareglyph; - draw lefttriangle; - finishglyph; -endfig; - -beginfig(202); - prepareglyph; - draw righttriangle; - finishglyph; -endfig; - -beginfig(203); - prepareglyph; - draw sidebar; - draw lefttriangle shifted (.5s); - finishglyph; -endfig; - -beginfig(204); - prepareglyph; - draw righttriangle; - draw sidebar shifted (wt,0); - finishglyph; -endfig; - -beginfig(205); - prepareglyph; - draw sublefttriangle shifted s; - draw lefttriangle shifted s; - finishglyph; -endfig; - -beginfig(206); - prepareglyph; - draw subrighttriangle; - draw righttriangle; - finishglyph; -endfig; - -beginfig(207); - prepareglyph; - draw midbar; - finishglyph; -endfig; - -beginfig(208); - prepareglyph; - draw onebar; - finishglyph; -endfig; - -beginfig(209); - prepareglyph; - draw twobar; - draw twobar shifted (pw+hh/2,0); - finishglyph; -endfig; - - -beginfig(999); - -picture collection [] ; - -prepareglyph ; -draw lefttriangle ; -finishglyph ; -collection[201] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw righttriangle ; -finishglyph ; -collection[202] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw sidebar ; -draw lefttriangle shifted (.5s) ; -finishglyph ; -collection[203] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw righttriangle ; -draw sidebar shifted (wt,0) ; -finishglyph ; -collection[204] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw sublefttriangle shifted s ; -draw lefttriangle shifted s ; -finishglyph ; -collection[205] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw subrighttriangle ; -draw righttriangle ; -finishglyph ; -collection[206] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw midbar ; -finishglyph ; -collection[207] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw onebar ; -finishglyph ; -collection[208] := currentpicture ; -currentpicture := nullpicture ; - -prepareglyph ; -draw twobar ; -draw twobar shifted (pw+hh/2,0) ; -finishglyph ; -collection[209] := currentpicture ; -currentpicture := nullpicture ; - -for i=201 upto 209 : - collection[i] := collection[i] shifted - center collection[i] ; -endfor ; - -addto currentpicture also collection[205] shifted ( 0, 0) - withcolor (.3,.4,.5) ; -addto currentpicture also collection[202] shifted ( 0,1.5h) - withcolor (.5,.6,.7) ; -addto currentpicture also collection[201] shifted (1.5h, 0) - withcolor (.6,.7,.8) ; -addto currentpicture also collection[206] shifted (1.5h,1.5h) - withcolor (.4,.5,.6) ; - -collection[210] := currentpicture ; -currentpicture := nullpicture ; - -bboxmargin := .25u; - -fill bbox collection[210] withcolor .95(1,1,0); -addto currentpicture also collection[210] ; - -endfig ; - -end diff --git a/metapost/context/base/mp-text.mpii b/metapost/context/base/mp-text.mpii deleted file mode 100644 index 5f96f6788..000000000 --- a/metapost/context/base/mp-text.mpii +++ /dev/null @@ -1,275 +0,0 @@ -%D \module -%D [ file=mp-text.mpii, -%D version=2000.07.10, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=text support, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -%D Under construction. - -if known context_text : endinput ; fi ; - -boolean context_text ; context_text := true ; - -if unknown noftexpictures : - numeric noftexpictures ; noftexpictures := 0 ; -fi ; - -if unknown texpictures[1] : - picture texpictures[] ; -fi ; - -numeric textextoffset ; textextoffset := 0 ; - -% vardef textext@#(expr txt) = -% interim labeloffset := textextoffset ; -% noftexpictures := noftexpictures + 1 ; -% if string txt : -% write "% figure " & decimal charcode & " : " & -% "texpictures[" & decimal noftexpictures & "] := btex " & -% txt & " etex ;" to jobname & ".mpt" ; -% if unknown texpictures[noftexpictures] : -% thelabel@#("unknown",origin) -% else : -% thelabel@#(texpictures[noftexpictures],origin) -% fi -% else : -% thelabel@#(txt,origin) -% fi -% enddef ; - -boolean hobbiestextext ; hobbiestextext := false ; -% string textextstring ; textextstring := "" ; - -% def resettextextdirective = -% textextstring := "" ; -% enddef ; - -% def textextdirective text t = -% textextstring := textextstring & t ; -% enddef ; - -vardef textext@#(expr txt) = - save _s_ ; string _s_ ; - interim labeloffset := textextoffset ; - noftexpictures := noftexpictures + 1 ; - if string txt : - if hobbiestextext : % the tex.mp method as fallback (see tex.mp) - write _s_ & "btex " & txt & " etex" to "mptextmp.mp" ; - write EOF to "mptextmp.mp" ; - scantokens "input mptextmp" - else : - write "% figure " & decimal charcode & " : " & - "texpictures[" & decimal noftexpictures & "] := btex " & - txt & " etex ;" to jobname & ".mpt" ; - if unknown texpictures[noftexpictures] : - thelabel@#("unknown",origin) - else : - thelabel@#(texpictures[noftexpictures],origin) - fi - fi - else : - thelabel@#(txt,origin) - fi -enddef ; - -string laboff_ ; laboff_ := "" ; -string laboff_c ; laboff_c := "" ; -string laboff_l ; laboff_l := ".lft" ; -string laboff_r ; laboff_r := ".rt" ; -string laboff_b ; laboff_b := ".bot" ; -string laboff_t ; laboff_t := ".top" ; - -string laboff_lt ; laboff_lt := ".ulft" ; -string laboff_rt ; laboff_rt := ".urt" ; % bugged, conflict with r -string laboff_lb ; laboff_lb := ".llft" ; -string laboff_rb ; laboff_rb := ".lrt" ; -string laboff_tl ; laboff_tl := ".ulft" ; -string laboff_tr ; laboff_tr := ".urt" ; -string laboff_bl ; laboff_bl := ".llft" ; -string laboff_br ; laboff_br := ".lrt" ; - -vardef textextstr(expr s, a) = - save ss ; string ss ; - ss := "laboff_" & a ; - ss := scantokens ss ; - ss := "textext" & ss & "(" & ditto & s & ditto & ")" ; - scantokens ss -enddef ; - -pair laboff.origin ; laboff.origin = (0,0) ; % (infinity,infinity) ; -pair laboff.raw ; laboff.raw = (0,0) ; % (infinity,infinity) ; - -laboff.origin = (0,0) ; labxf.origin := 0 ; labyf.origin := 0 ; -laboff.raw = (0,0) ; labxf.raw := 0 ; labyf.raw := 0 ; - -vardef installlabel@# (expr type, x, y, offset) = - numeric labtype@# ; labtype@# := type ; - pair laboff @# ; laboff @# := offset ; - numeric labxf @# ; labxf @# := x ; - numeric labyf @# ; labyf @# := y ; -enddef ; - -vardef thelabel@#(expr s, z) = - save p ; picture p ; - p = s if not picture s : infont defaultfont scaled defaultscale fi ; -% wrong, see myway textext -% if laboff@#<>laboff.origin : - (p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + - labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))) -% else : -% (p shifted z) -% fi -enddef; - -def build_parshape (expr p, offset_or_path, dx, dy, - baselineskip, strutheight, strutdepth, topskip) = - - if unknown trace_parshape : - boolean trace_parshape ; trace_parshape := false ; - fi ; - - begingroup ; - - save q, l, r, line, tt, bb, - n, hsize, vsize, vvsize, voffset, hoffset, width, indent, - ll, lll, rr, rrr, cp, cq, t, b ; - - path q, l, r, line, tt, bb ; - numeric n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ; - pair ll, lll, rr, rrr, cp, cq, t, b ; - - n := 0 ; cp := center p ; - - if path offset_or_path : - q := offset_or_path ; cq := center q ; - voffset := dy ; - hoffset := dx ; - else : - q := p ; cq := center q ; - hoffset := offset_or_path + dx ; - voffset := offset_or_path + dy ; - fi ; - - hsize := xpart lrcorner q - xpart llcorner q ; - vsize := ypart urcorner q - ypart lrcorner q ; - - q := p shifted - cp ; - - startsavingdata ; - - savedata "\global\parvoffset " & decimal voffset&"bp " ; - savedata "\global\parhoffset " & decimal hoffset&"bp " ; - savedata "\global\parwidth " & decimal hsize&"bp " ; - savedata "\global\parheight " & decimal vsize&"bp " ; - - if not path offset_or_path : - q := q xscaled ((hsize-2hoffset)/hsize) - yscaled ((vsize-2voffset)/vsize) ; - fi ; - - hsize := xpart lrcorner q - xpart llcorner q ; - vsize := ypart urcorner q - ypart lrcorner q ; - - t := (ulcorner q -- urcorner q) intersection_point q ; - b := (llcorner q -- lrcorner q) intersection_point q ; - - if xpart directionpoint t of q < 0 : - q := reverse q ; - fi ; - - l := q cutbefore t ; - l := l if xpart point 0 of q < 0 : & q fi cutafter b ; - - r := q cutbefore b ; - r := r if xpart point 0 of q > 0 : & q fi cutafter t ; - -% tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ; -% bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ; -% -% l := l cutbefore (l intersection_point tt) ; -% l := l cutafter (l intersection_point bb) ; -% r := r cutbefore (r intersection_point bb) ; -% r := r cutafter (r intersection_point tt) ; - - if trace_parshape : - drawarrow p withpen pencircle scaled 2pt withcolor red ; - drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ; - drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ; - fi ; - - vardef found_point (expr lin, pat, sig) = - pair a, b ; - a := pat intersection_point (lin shifted (0,strutheight)) ; - if intersection_found : - a := a shifted (0,-strutheight) ; - else : - a := pat intersection_point lin ; - fi ; - b := pat intersection_point (lin shifted (0,-strutdepth)) ; - if intersection_found : - if sig : - if xpart b > xpart a : a := b shifted (0,strutdepth) fi ; - else : - if xpart b < xpart a : a := b shifted (0,strutdepth) fi ; - fi ; - fi ; - a - enddef ; - - if (strutheight+strutdepth 0 : & q fi cutafter t ; - - % tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ; - % bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ; - - % l := l cutbefore (l intersection_point tt) ; - % l := l cutafter (l intersection_point bb) ; - % r := r cutbefore (r intersection_point bb) ; - % r := r cutafter (r intersection_point tt) ; - - if trace_parshape : - drawarrow p withpen pencircle scaled 2pt withcolor red ; - drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ; - drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ; - fi ; - - vardef found_point (expr lin, pat, sig) = - pair a, b ; - a := pat intersection_point (lin shifted (0,strutheight)) ; - if intersection_found : - a := a shifted (0,-strutheight) ; - else : - a := pat intersection_point lin ; - fi ; - b := pat intersection_point (lin shifted (0,-strutdepth)) ; - if intersection_found : - if sig : - if xpart b > xpart a : a := b shifted (0,strutdepth) fi ; - else : - if xpart b < xpart a : a := b shifted (0,strutdepth) fi ; - fi ; - fi ; - a - enddef ; - - if (strutheight+strutdepth " & if numeric s : decimal s else : s fi) -% enddef ; -% vardef mpversionlt(expr s) = -% scantokens (mpversion & " < " & if numeric s : decimal s else : s fi) -% enddef ; -% vardef mpversioneq(expr s) = -% scantokens (mpversion & " = " & if numeric s : decimal s else : s fi) -% enddef ; - -%D More interesting: -%D -%D \starttyping -%D fill fullcircle scaled 4cm withcolor if mpversiongt("0.6") : red else : green fi ; -%D fill fullcircle scaled 2cm withcolor if mpversionlt(0.6) : blue else : white fi ; -%D fill fullcircle scaled 1cm withcolor if mpversioncmp(0.6,">=") : yellow else : black fi ; -%D \stoptyping - -vardef mpversioncmp(expr s, c) = - scantokens (mpversion & c & if numeric s : decimal s else : s fi) -enddef ; - -vardef mpversionlt (expr s) = mpversioncmp(s, "<") enddef ; -vardef mpversioneq (expr s) = mpversioncmp(s, "=") enddef ; -vardef mpversiongt (expr s) = mpversioncmp(s, ">") enddef ; - -%D We always want \EPS\ conforming output, so we say: - -prologues := 1 ; -warningcheck := 0 ; -mpprocset := 1 ; - -%D Namespace handling: - -% let exclamationmark = ! ; -% let questionmark = ? ; -% -% def unprotect = -% let ! = relax ; -% let ? = relax ; -% enddef ; -% -% def protect = -% let ! = exclamationmark ; -% let ? = questionmark ; -% enddef ; -% -% unprotect ; -% -% mp!some!module = 10 ; show mp!some!module ; show somemodule ; -% -% protect ; - -string space ; space := char 32 ; -string CRLF ; CRLF := char 10 & char 13 ; - -vardef ddecimal primary p = - decimal xpart p & " " & decimal ypart p -enddef ; - -%D Plain compatibility: - -string plain_compatibility_data ; plain_compatibility_data := "" ; - -def startplaincompatibility = - begingroup ; - scantokens plain_compatibility_data ; -enddef ; - -def stopplaincompatibility = - endgroup ; -enddef ; - -% is now built in -% -% extra_endfig := extra_endfig -% & "special " -% & "(" -% & ditto -% & "%%HiResBoundingBox: " -% & ditto -% & "&ddecimal llcorner currentpicture" -% & "&space" -% & "&ddecimal urcorner currentpicture" -% & ");"; - -%D More neutral: - -let triplet = rgbcolor ; -let quadruplet = cmykcolor ; - -%D Crap (experimental, not used): - -def forcemultipass = - % extra_endfig := extra_endfig & "special(" & ditto & "%%MetaPostOption: multipass" & ditto & ");" ; -enddef ; - -%D Colors: - -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_ ; - forsuffixes i=v : - _p_ := image(draw origin withcolor c ;) ; % intercept pre and postscripts - if (colormodel _p_ = cmykcolormodel) : - cmykcolor i ; - elseif (colormodel _p_ = rgbcolormodel) : - rgbcolor i ; - else : - greycolor i ; - fi ; - endfor ; -enddef ; - -%D Also handy (when we flush colors): - -vardef dddecimal primary 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 -enddef ; - -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 ; - -%D We have standardized data file names: - -def job_name = - jobname -enddef ; - -def data_mpd_file = - job_name & "-mp.mpd" -enddef ; - -%D Because \METAPOST\ has a hard coded limit of 4~datafiles, -%D we need some trickery when we have multiple files. - -if unknown collapse_data : - boolean collapse_data ; - collapse_data := false ; -fi ; - -boolean savingdata ; savingdata := false ; -boolean savingdatadone ; savingdatadone := false ; - -def savedata expr txt = - write if collapse_data : - txt - else : - if savingdata : txt else : "\MPdata{" & decimal charcode & "}{" & txt & "}" fi & "%" - fi to data_mpd_file ; -enddef ; - -def startsavingdata = - 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 ; -enddef ; - -def finishsavingdata = - if savingdatadone : - write EOF to data_mpd_file ; - savingdatadone := false ; - fi ; -enddef ; - -%D Instead of a keystroke eating save and allocation -%D sequence, you can use the \citeer {new} alternatives to -%D save and allocate in one command. - -def newcolor text v = forsuffixes i=v : save i ; color i ; endfor ; enddef ; -def newnumeric text v = forsuffixes i=v : save i ; numeric i ; endfor ; enddef ; -def newboolean text v = forsuffixes i=v : save i ; boolean i ; endfor ; enddef ; -def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; enddef ; -def newpath text v = forsuffixes i=v : save i ; path i ; endfor ; enddef ; -def newpicture text v = forsuffixes i=v : save i ; picture i ; endfor ; enddef ; -def newstring text v = forsuffixes i=v : save i ; string i ; endfor ; enddef ; -def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; enddef ; - -%D Sometimes we don't want parts of the graphics add to the -%D bounding box. One way of doing this is to save the bounding -%D box, draw the graphics that may not count, and restore the -%D bounding box. -%D -%D \starttyping -%D push_boundingbox currentpicture; -%D pop_boundingbox currentpicture; -%D \stoptyping -%D -%D The bounding box can be called with: -%D -%D \starttyping -%D boundingbox currentpicture -%D inner_boundingbox currentpicture -%D outer_boundingbox currentpicture -%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 \starttyping -%D set_outer_boundingbox currentpicture; -%D \stoptyping -%D -%D Its counterpart is: -%D -%D \starttyping -%D set_inner_boundingbox p -%D \stoptyping - -path mfun_boundingbox_stack ; -numeric mfun_boundingbox_stack_depth ; - -mfun_boundingbox_stack_depth := 0 ; - -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 -enddef; - -vardef innerboundingbox primary p = - top rt llcorner p -- - top lft lrcorner p -- - bot lft urcorner p -- - bot rt ulcorner p -- cycle -enddef; - -vardef outerboundingbox primary p = - bot lft llcorner p -- - bot rt lrcorner p -- - top rt urcorner p -- - top lft ulcorner p -- cycle -enddef; - -def inner_boundingbox = innerboundingbox enddef ; -def outer_boundingbox = outerboundingbox enddef ; - -vardef set_inner_boundingbox text q = % obsolete - setbounds q to innerboundingbox q; -enddef; - -vardef set_outer_boundingbox text q = % obsolete - setbounds q to outerboundingbox q; -enddef; - -%D Some missing functions can be implemented rather straightforward (thanks to -%D Taco and others): - -pi := 3.14159265358979323846 ; radian := 180/pi ; % 2pi*radian = 360 ; - -% let +++ = ++ ; - -numeric Pi ; Pi := pi ; % for some old compatibility reasons i guess - -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 ; - -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 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 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 ; - -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 -%D first macro divides the sides into n equal parts. The -%D first argument specifies the way the lines are drawn, while -%D the second argument identifier the way the shape is to be -%D drawn. -%D -%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 \stoptyping -%D -%D The a (or angle) alternative supports arbitrary angles and -%D is therefore more versatile. -%D -%D \starttyping -%D stripe_path_a -%D (withpen pencircle scaled 2 withcolor red) -%D (draw) -%D fullcircle xscaled 100 yscaled 40 withcolor blue; -%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 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; -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) -enddef; - -def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text = - 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) -enddef; - -def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text = - draw image(s_draw s_path s_text) anglestriped(3,0,0) s_spec ; -enddef ; - -%D A few normalizing macros: -%D -%D \starttypen -%D xscale_currentpicture ( width ) -%D yscale_currentpicture ( height ) -%D xyscale_currentpicture ( width, height ) -%D scale_currentpicture ( width, height ) -%D \stoptypen - -% def xscale_currentpicture(expr the_width) = -% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; -% currentpicture := currentpicture scaled (the_width/natural_width) ; -% enddef; -% -% def yscale_currentpicture(expr the_height ) = -% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; -% currentpicture := currentpicture scaled (the_height/natural_height) ; -% enddef; -% -% def xyscale_currentpicture(expr the_width, the_height) = -% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; -% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; -% currentpicture := currentpicture -% xscaled (the_width/natural_width) -% yscaled (the_height/natural_height) ; -% enddef; -% -% def scale_currentpicture(expr the_width, the_height) = -% xscale_currentpicture(the_width) ; -% yscale_currentpicture(the_height) ; -% enddef; - -% nog eens uitbreiden zodat path en pic worden afgehandeld. - -% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; -% currentpicture := currentpicture scaled (the_width/natural_width) ; - -primarydef p xsized w = - (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) -enddef ; - -primarydef p xysized s = - begingroup - save wh, w, h ; pair wh ; numeric w, h ; - wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; - p - if (w>0) and (h>0) : - if xpart wh > 0 : xscaled (xpart wh/w) fi - if ypart wh > 0 : yscaled (ypart wh/h) fi - fi - endgroup -enddef ; - -let sized = xysized ; - -def xscale_currentpicture(expr w) = % obsolete - currentpicture := currentpicture xsized w ; -enddef; - -def yscale_currentpicture(expr h) = % obsolete - currentpicture := currentpicture ysized h ; -enddef; - -def xyscale_currentpicture(expr w, h) = % obsolete - currentpicture := currentpicture xysized (w,h) ; -enddef; - -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 -%D is located in the first quadrant. Now guess what kind of -%D path fullsquare and unitcircle do return. - -path fullsquare, unitcircle ; - -fullsquare := unitsquare shifted - center unitsquare ; -unitcircle := fullcircle shifted urcorner fullcircle ; - -%D Some more paths: - -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 ; - -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 ; - -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 ; - -path unitdiamond, fulldiamond ; - -unitdiamond := (.5,0) -- (1,.5) -- (.5,1) -- (0,.5) -- cycle ; -fulldiamond := unitdiamond shifted - center unitdiamond ; - -%D More robust: - -% let normalscaled = scaled ; -% let normalxscaled = xscaled ; -% let normalyscaled = yscaled ; -% -% def scaled expr s = normalscaled (s) enddef ; -% def xscaled expr s = normalxscaled (s) enddef ; -% def yscaled expr s = normalyscaled (s) enddef ; - -%D Shorter - -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 Some personal code that might move to another module - -def set_grid(expr w, h, nx, ny) = - 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 ; -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 -enddef ; - -%D usage: \type{innerpath peepholed outerpath}. -%D -%D beginfig(1); -%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ; -%D fill (fullsquare scaled 200) withcolor red ; -%D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ; -%D fill p peepholed bbox p ; -%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 - else : - llcorner q -- lrcorner q -- urcorner q -- ulcorner q -- - reverse p -- ulcorner q -- cycle - fi - fi - endgroup -enddef ; - -boolean intersection_found ; - -secondarydef p intersection_point q = - begingroup - save x_, y_ ; - (x_,y_) = p intersectiontimes q ; - if x_<0 : - intersection_found := false ; - center p % origin - else : - intersection_found := true ; - .5[point x_ of p, point y_ of q] - fi - 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 -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 -enddef ; - -%D Some colors. - -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 ; - -%D Well, this is the dangerous and naive version: - -def drawfill text 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 ; - mfun_do_drawfill -enddef ; - -def mfun_do_drawfill text t = - draw _c_ t ; - fill _c_ t ; -enddef; - -def undrawfill expr c = - drawfill c withcolor background % rather useless -enddef ; - -%D Moved from mp-char.mp - -vardef paired primary d = - if pair d : d else : (d,d) fi -enddef ; - -vardef tripled primary d = - if color d : d else : (d,d,d) fi -enddef ; - -% maybe secondaries: - -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 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 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 = ( - if pair p : - 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 - fi -) enddef ; - -%D Also handy (math ladders): - -vardef laddered primary p = % was expr - point 0 of p - for i=1 upto length(p) : - -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p) - endfor -enddef ; - -%D Saves typing: - -% vardef bottomboundary primary p = (llcorner p -- lrcorner p) enddef ; -% vardef rightboundary primary p = (lrcorner p -- urcorner p) 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 ; - -%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 ; - -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 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 = ( - 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 : - p + uniformdeviate s - fi -) enddef ; - -%D Not perfect (alternative for interpath) - -vardef interpolated(expr s, p, q) = - 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 paralleled d = ( - p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p) -) 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 -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 -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 -enddef ; - -%D Rather fundamental. - -% not yet ok - -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 ; -vardef rightpath expr p = leftrightpath(p,false) enddef ; - -%D Drawoptions - -def saveoptions = - save _op_ ; def _op_ = enddef ; -enddef ; - -%D Tracing. (not yet in lexer) - -let normaldraw = draw ; -let normalfill = fill ; - -% bugged in mplib so ... - -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 ; -def drawlabeloptions (text t) = def _lab_opt_ = t enddef ; enddef ; -def draworiginoptions (text t) = def _ori_opt_ = t enddef ; enddef ; -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) ; -enddef ; - -resetdrawoptions ; - -%D Path. - -def drawpath expr p = - normaldraw p _pth_opt_ -enddef ; - -%D Arrow. - -vardef drawarrowpath expr p = - 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_ 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) -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 -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_ -enddef ; - -%D PathPoints. - -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 mfun_draw_points text t = - for _i_=0 upto length(_c_) : - normaldraw point _i_ of _c_ _pnt_opt_ t ; - endfor ; -enddef; - -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 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 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_ -enddef ; - -%D Origin. - -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 ; -enddef; - -%D Axis. - -numeric tickstep ; tickstep := 5mm ; -numeric ticklength ; ticklength := 2mm ; - -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 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 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 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 ; -enddef ; - -%D Tracing. - -def visualizeddraw expr c = - 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 -enddef ; - -def do_visualizeddraw text t = - 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_ ; -enddef ; - -def visualizepaths = - let fill = visualizedfill ; - let draw = visualizeddraw ; -enddef ; - -def naturalizepaths = - 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 -extra_beginfig := extra_beginfig & " miterlimit := 10 ; " ; % restores -extra_beginfig := extra_beginfig & " linejoin := rounded ; " ; % restores -extra_beginfig := extra_beginfig & " linecap := rounded ; " ; % restores - -%D Normally, arrowheads don't scale well. So we provide a -%D hack. - -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)) ; -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) -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 arrowpath _apth t ; % arrowpath added - fill arrowhead _apth t ; - draw arrowhead _apth 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) -enddef ; - -def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ; -def leftarrow (expr pat,tim,len) = pointarrow(pat,tim,len,+len) enddef ; -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 \starttyping -%D drawdot point .5 along somepath ; -%D drawdot point 3cm on somepath ; -%D \stoptyping -%D -%D The number denotes a percentage (fraction). - -primarydef pct along pat = % also negative - (arctime (pct * (arclength pat)) of pat) of pat -enddef ; - -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 - -% tertiarydef pat cutends len = -% begingroup ; save tap ; path tap ; -% tap := pat cutbefore (point len on pat) ; -% (tap cutafter (point -len on tap)) -% endgroup -% 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 -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 ; - -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 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) ; -enddef ; - -vardef freedotlabel (expr str, loc, ori) = - interim linecap := rounded ; - draw loc withpen pencircle scaled freedotlabelsize ; - draw thefreelabel(str,loc,ori) ; -enddef ; - -%D \starttyping -%D drawarrow anglebetween(line_a,line_b,somelabel) ; -%D \stoptyping - -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 ; -% 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 := ((common--pointa) rotatedaround (pointa,-where*90)) -% intersectionpoint -% ((common--pointb) rotatedaround (pointb, where*90)) ; -% 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 ; - -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 -enddef ; - -% Stack - -picture mfun_current_picture_stack[] ; -numeric mfun_current_picture_depth ; - -mfun_current_picture_depth := 0 ; - -def pushcurrentpicture = - 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 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) ; - -% vardef colorcircle (expr size, red, green, blue) = -% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; -% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; -% -% radius := 5cm ; pickup pencircle scaled (radius/25) ; -% -% r := g := b := fullcircle scaled radius shifted (0,radius/4) ; -% -% r := r rotatedaround (origin, 15) ; -% g := g rotatedaround (origin,135) ; -% b := b rotatedaround (origin,255) ; -% -% r := r rotatedaround(center r,-90) ; -% g := g rotatedaround(center g, 90) ; -% -% gg := buildcycle(buildcycle(reverse r,b),g) ; -% cc := buildcycle(buildcycle(b,reverse g),r) ; -% -% rr := gg rotatedaround(origin,120) ; -% bb := gg rotatedaround(origin,240) ; -% -% yy := cc rotatedaround(origin,120) ; -% mm := cc rotatedaround(origin,240) ; -% -% pushcurrentpicture ; -% -% fill fullcircle scaled radius withcolor white ; -% -% fill rr withcolor red ; fill cc withcolor white-red ; -% fill gg withcolor green ; fill mm withcolor white-green ; -% fill bb withcolor blue ; fill yy withcolor white-blue ; -% -% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; -% -% currentpicture := currentpicture xsized size ; -% -% popcurrentpicture ; -% enddef ; - -% vardef colorcircle (expr size, red, green, blue) = -% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; -% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; -% -% radius := 5cm ; pickup pencircle scaled (radius/25) ; -% -% transform t ; t := identity rotatedaround(origin,120) ; -% -% r := fullcircle scaled radius -% shifted (0,radius/4) rotatedaround(origin,15) ; -% -% g := r transformed t ; b := g transformed t ; -% -% r := r rotatedaround(center r,-90) ; -% g := g rotatedaround(center g, 90) ; -% -% gg := buildcycle(buildcycle(reverse r,b),g) ; -% cc := buildcycle(buildcycle(b,reverse g),r) ; -% -% rr := gg transformed t ; bb := rr transformed t ; -% yy := cc transformed t ; mm := yy transformed t ; -% -% pushcurrentpicture ; -% -% fill fullcircle scaled radius withcolor white ; -% -% fill rr withcolor red ; fill cc withcolor white-red ; -% fill gg withcolor green ; fill mm withcolor white-green ; -% fill bb withcolor blue ; fill yy withcolor white-blue ; -% -% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; -% -% currentpicture := currentpicture xsized size ; -% -% popcurrentpicture ; -% enddef ; - -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) ; - - transform t ; t := identity rotatedaround(origin,120) ; - - r := fullcircle rotated 90 scaled radius shifted (0,radius/4) rotatedaround(origin,135) ; - - 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 ; - - w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ; - - 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 ; - - for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ; - - currentpicture := currentpicture xsized size ; - - 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)) -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 ; - ) - fi -enddef ; - -vardef inverted primary p = - p uncolored white -enddef ; - -% primarydef p softened c = -% if color p : -% tripled(c) * p -% else : -% image -% (save cc ; color cc ; cc := tripled(c) ; -% 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 -% 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 -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 ; - ) - fi -enddef ; - -% yes or no: "text" infont "cmr12" at 24pt ; - -% let normalinfont = infont ; -% -% numeric lastfontsize ; lastfontsize = fontsize defaultfont ; -% -% def infont primary name = % no vardef, no expr -% hide(lastfontsize := fontsize name) % no ; -% normalinfont name -% enddef ; -% -% def scaledat expr size = -% scaled (size/lastfontsize) -% enddef ; -% -% let at = scaledat ; - -% like decimal - -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 -enddef ; - -% primarydef p enlonged len = -% begingroup -% save al ; al := arclength(p) ; -% if al > 0 : -% if pair p : -% point 1 of ((origin -- p) stretched ((al+len)/al)) -% else : -% p stretched ((al+len)/al) -% fi -% else : -% p -% fi -% endgroup -% enddef ; - -primarydef p enlonged len = - begingroup - if pair p : - save q ; path q ; q := origin -- p ; - save al ; al := arclength(q) ; - if al > 0 : - point 1 of (q stretched ((al+len)/al)) - else : - p - fi - else : - save al ; al := arclength(p) ; - if al > 0 : - p stretched ((al+len)/al) - else : - p - fi - fi - endgroup -enddef ; - -% path p ; p := (0,0) -- (10cm,5cm) ; -% drawarrow p withcolor red ; -% drawarrow p shortened 1cm withcolor green ; - -primarydef p shortened d = - reverse ( ( reverse (p enlonged -d) ) enlonged -d ) -enddef ; - -% yes or no, untested -) - -def xshifted expr dx = shifted(dx,0) enddef ; -def yshifted expr dy = shifted(0,dy) enddef ; - -% also handy - -% right: str = readfrom ("abc" & ".def" ) ; -% wrong: str = readfrom "abc" & ".def" ; - -% Every 62th read fails so we need to try again! - -% def readfile (expr name) = -% if (readfrom (name) <> EOF) : -% scantokens("input " & name & ";") ; -% elseif (readfrom (name) <> EOF) : -% scantokens("input " & name & ";") ; -% fi ; -% closefrom (name) ; -% enddef ; -% -% this sometimes fails on the elseif, so : -% - -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 ; -enddef ; - -% permits redefinition of end in macro - -inner end ; - -% this will be redone (when needed) using scripts and backend handling - -let normalwithcolor = withcolor ; - -def remapcolors = - def withcolor primary c = normalwithcolor remappedcolor(c) enddef ; -enddef ; - -def normalcolors = - let withcolor = normalwithcolor ; -enddef ; - -def resetcolormap = - color color_map[][][] ; - normalcolors ; -enddef ; - -resetcolormap ; - -% color_map_resolution := 1000 ; -% -% def r_color primary c = round(color_map_resolution*redpart c) enddef ; -% def g_color primary c = round(color_map_resolution*greenpart c) enddef ; -% def b_color primary c = round(color_map_resolution*bluepart c) enddef ; - -def r_color primary c = redpart c enddef ; -def g_color primary c = greenpart c enddef ; -def b_color primary c = bluepart c enddef ; - -def remapcolor(expr old, new) = - color_map[redpart old][greenpart old][bluepart old] := new ; -enddef ; - -def remappedcolor(expr c) = - 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 ; -% def redraw suffix c = do_repath (2) (c) enddef ; -% def recolor suffix c = do_repath (0) (c) enddef ; -% -% color refillbackground ; refillbackground := (1,1,1) ; -% -% def do_repath (expr mode) (suffix c) text t = % can it be stroked and filled at the same time ? -% begingroup ; -% if mode=0 : save withcolor ; remapcolors ; fi ; -% save _c_, _cc_, _f_, _b_ ; picture _c_, _cc_ ; color _f_ ; path _b_ ; -% _c_ := c ; _b_ := boundingbox c ; c := nullpicture ; -% for i within _c_ : -% _f_ := (redpart i, greenpart i, bluepart i) ; -% if bounded i : -% setbounds c to pathpart i ; -% elseif clipped i : -% clip c to pathpart i ; -% elseif stroked i : -% addto c doublepath pathpart i -% dashed dashpart i withpen penpart i -% withcolor _f_ % (redpart i, greenpart i, bluepart i) -% if mode=2 : t fi ; -% elseif filled i : -% addto c contour pathpart i -% withcolor _f_ -% if (mode=1) and (_f_<>refillbackground) : t fi ; -% else : -% addto c also i ; -% fi ; -% endfor ; -% setbounds c to _b_ ; -% endgroup ; -% 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 ; - -% primarydef p recolored t = repathed(0,p) t enddef ; -% primarydef p refilled t = repathed(1,p) t enddef ; -% primarydef p redrawn t = repathed(2,p) t enddef ; -% primarydef p retexted t = repathed(3,p) t enddef ; -% primarydef p untexted t = repathed(4,p) t enddef ; - -color refillbackground ; refillbackground := (1,1,1) ; - -% vardef repathed (expr mode, p) text t = -% begingroup ; -% if mode=0 : save withcolor ; remapcolors ; fi ; -% save _p_, _pp_, _f_, _b_, _t_ ; -% picture _p_, _pp_ ; 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 : -% addto _p_ doublepath pathpart i -% dashed dashpart i withpen penpart i -% withcolor _f_ % (redpart i, greenpart i, bluepart i) -% if mode=2 : t fi ; -% elseif filled i : -% addto _p_ contour pathpart i -% withcolor _f_ -% if (mode=1) and (_f_<>refillbackground) : t 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 ; - -def restroke suffix p = p := repathed (21,p) enddef ; % keep attributes -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 ; - fi ; - endfor ; - setbounds _p_ to _b_ ; - _p_ - endgroup -enddef ; - -% After a question of Denis on how to erase a z variable, Jacko -% suggested to assign whatever to x and y. So a clearz -% variable can be defined as: -% -% vardef clearz@# = -% x@# := whatever ; -% y@# := whatever ; -% enddef ; -% -% but Jacko suggested a redefinition of clearxy: -% -% def clearxy text s = -% clearxy_index_:=0; -% for $:=s: -% clearxy_index_:=clearxy_index_+1; endfor; -% if clearxy_index_=0: -% save x,y; -% else: -% forsuffixes $:=s: x$:=whatever; y$:=whatever; endfor; -% fi -% 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 -enddef ; - -% so now we can say: clearxy ; as well as clearxy 1, 2, 3 ; - -% show x0 ; z0 = (10,10) ; -% show x0 ; x0 := whatever ; y0 := whatever ; -% show x0 ; z0 = (20,20) ; -% show x0 ; clearxy 0 ; -% 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) -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) -enddef ; - -% cmyk color support - -vardef cmyk(expr c,m,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 -% 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 -% 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 -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 ; - fi ; - fi ; -enddef ; - -% result from metafont discussion list (denisr/boguslawj) - -def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ; -def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ; - -let == = = ; - -% added - -picture oddly ; % evenly already defined - -evenly := dashpattern(on 3 off 3) ; -oddly := dashpattern(off 3 on 3) ; - -% not perfect, but useful since it removes redundant points. - -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 ; - _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 - else : - p - fi -enddef ; - -vardef simplified expr p = ( - reverse mfun_straightened(+1,mfun_straightened(+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) -- -% (4cm,1cm) -- (4cm,2cm) -- (4cm,2.5cm) -- (4cm,3cm) -- -% (3cm,3cm) -- (2cm,3cm) -- (1cm,3cm) -- (-1cm,3cm) -- -% .5[(-1cm,3cm),(1cm,1cm)] -- (1cm,1cm) -- cycle ; -% -% p := unitcircle scaled 4cm ; -% -% drawpath p ; drawpoints p ; drawpointlabels p ; -% p := p shifted (4cm,0) ; p := straightened p ; -% drawpath p ; drawpoints p ; drawpointlabels p ; -% p := p shifted (4cm,0) ; p := straightened p ; -% drawpath p ; drawpoints p ; drawpointlabels p ; - -% new - -path originpath ; originpath := origin -- cycle ; - -vardef unitvector primary z = - if abs z = abs origin : z else : z/abs z fi -enddef; - -% also new - -% 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 -enddef ; - -% handy - -def withgray primary g = - withcolor (g,g,g) -enddef ; - -% for metafun - -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 -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 -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 - 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 ; -enddef ; - -% makes a (line) into an infinite one (handy for calculating -% intersection points - -vardef infinite expr 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) -enddef ; - -% obscure macros: create var from string and replace - and : -% (needed for process color id's) .. will go away - -string mfun_clean_ascii[] ; - -def register_dirty_chars(expr str) = - for i = 0 upto length(str)-1 : - 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 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 ; -enddef ; - -vardef getunstringed (expr s) = - scantokens(cleanstring(s)) -enddef ; - -vardef unstringed (expr s) = - 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) = % 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 ; - endfor ; - for x=MinX upto MaxX: - label.bot(textext("\infofont " & decimal x), (x*DeltaX,-size)) ; - endfor ; - for y=MinY upto MaxY: - label.lft(textext("\infofont " & decimal y), (-size,y*DeltaY)) ; - endfor ; - endgroup -enddef; - -% new, handy for: -% -% \startuseMPgraphic{map}{n} -% \includeMPgraphic{map:germany} ; -% c_phantom (\MPvar{n}<1) ( -% fill map_germany withcolor \MPcolor{lightgray} ; -% draw map_germany withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% \includeMPgraphic{map:austria} ; -% c_phantom (\MPvar{n}<2) ( -% fill map_austria withcolor \MPcolor{lightgray} ; -% draw map_austria withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% c_phantom (\MPvar{n}<3) ( -% \includeMPgraphic{map:swiss} ; -% fill map_swiss withcolor \MPcolor{lightgray} ; -% draw map_swiss withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% c_phantom (\MPvar{n}<4) ( -% \includeMPgraphic{map:luxembourg} ; -% fill map_luxembourg withcolor \MPcolor{lightgray} ; -% draw map_luxembourg withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% \stopuseMPgraphic -% -% \useMPgraphic{map}{n=3} - -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 ; -enddef ; - -%D Handy: - -def break = - exitif true fi ; -enddef ; - -%D New too: - -primarydef p xstretched w = ( - p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi -) enddef ; - -primarydef p ystretched h = ( - p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi -) enddef ; - -primarydef p 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 -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 ; - 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 deleted file mode 100644 index e497e2f72..000000000 --- a/metapost/context/base/mp-tool.mpiv +++ /dev/null @@ -1,2611 +0,0 @@ -%D \module -%D [ file=mp-tool.mpiv, -%D version=1998.02.15, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=auxiliary macros, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% def loadfile(expr name) = scantokens("input " & name & ";") enddef ; - -if known context_tool : endinput ; fi ; - -boolean context_tool ; context_tool := true ; - -let @## = @# ; - -%D New, version number testing: -%D -%D \starttyping -%D fill fullcircle scaled 2cm withcolor if mpversiongt("0.6") : red else : green fi ; -%D fill fullcircle scaled 1cm withcolor if mpversionlt(0.6) : blue else : white fi ; -%D \stoptyping - -if not known mpversion : string mpversion ; mpversion := "0.641" ; fi ; - -newinternal metapostversion ; metapostversion := scantokens(mpversion) ; - -%D We always want \EPS\ conforming output, so we say: - -prologues := 1 ; -warningcheck := 0 ; -mpprocset := 1 ; - -%D Namespace handling: - -% let exclamationmark = ! ; -% let questionmark = ? ; -% -% def unprotect = -% let ! = relax ; -% let ? = relax ; -% enddef ; -% -% def protect = -% let ! = exclamationmark ; -% let ? = questionmark ; -% enddef ; -% -% unprotect ; -% -% mp!some!module = 10 ; show mp!some!module ; show somemodule ; -% -% protect ; - -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 -enddef ; - -%D Plain compatibility: - -string plain_compatibility_data ; plain_compatibility_data := "" ; - -def startplaincompatibility = - begingroup ; - scantokens plain_compatibility_data ; -enddef ; - -def stopplaincompatibility = - endgroup ; -enddef ; - -%D More neutral: - -let triplet = rgbcolor ; -let quadruplet = cmykcolor ; - -%D Colors: - -newinternal nocolormodel ; nocolormodel := 1 ; -newinternal greycolormodel ; greycolormodel := 3 ; -newinternal graycolormodel ; graycolormodel := 3 ; -newinternal rgbcolormodel ; rgbcolormodel := 5 ; -newinternal cmykcolormodel ; cmykcolormodel := 7 ; - -let grayscale = graycolor ; -let greyscale = greycolor ; - -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_ ; - forsuffixes i=v : - _p_ := image(draw origin withcolor c ;) ; % intercept pre and postscripts - if (colormodel _p_ = cmykcolormodel) : - cmykcolor i ; - elseif (colormodel _p_ = rgbcolormodel) : - rgbcolor i ; - else : - greycolor i ; - fi ; - endfor ; -enddef ; - -%D Also handy (when we flush colors): - -vardef dddecimal primary 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 -enddef ; - -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 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 = - jobname -enddef ; - -def data_mpd_file = - job_name & "-mp.mpd" -enddef ; - -%D Because \METAPOST\ has a hard coded limit of 4~datafiles, -%D we need some trickery when we have multiple files. This will -%D be redone (via \LUA). - -if unknown collapse_data : - boolean collapse_data ; - collapse_data := false ; -fi ; - -boolean savingdata ; savingdata := false ; -boolean savingdatadone ; savingdatadone := false ; - -def savedata expr txt = - write if collapse_data : - txt - else : - if savingdata : txt else : "\MPdata{" & decimal charcode & "}{" & txt & "}" fi & "%" - fi to data_mpd_file ; -enddef ; - -def startsavingdata = - 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 ; -enddef ; - -def finishsavingdata = - if savingdatadone : - write EOF to data_mpd_file ; - savingdatadone := false ; - fi ; -enddef ; - -%D Instead of a keystroke eating save and allocation -%D sequence, you can use the \citeer {new} alternatives to -%D save and allocate in one command. - -def newcolor text v = forsuffixes i=v : save i ; color i ; endfor ; enddef ; -def newnumeric text v = forsuffixes i=v : save i ; numeric i ; endfor ; enddef ; -def newboolean text v = forsuffixes i=v : save i ; boolean i ; endfor ; enddef ; -def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; enddef ; -def newpath text v = forsuffixes i=v : save i ; path i ; endfor ; enddef ; -def newpicture text v = forsuffixes i=v : save i ; picture i ; endfor ; enddef ; -def newstring text v = forsuffixes i=v : save i ; string i ; endfor ; enddef ; -def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; enddef ; - -%D Sometimes we don't want parts of the graphics add to the -%D bounding box. One way of doing this is to save the bounding -%D box, draw the graphics that may not count, and restore the -%D bounding box. -%D -%D \starttyping -%D push_boundingbox currentpicture; -%D pop_boundingbox currentpicture; -%D \stoptyping -%D -%D The bounding box can be called with: -%D -%D \starttyping -%D boundingbox currentpicture -%D inner_boundingbox currentpicture -%D outer_boundingbox currentpicture -%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 \starttyping -%D set_outer_boundingbox currentpicture; -%D \stoptyping -%D -%D Its counterpart is: -%D -%D \starttyping -%D set_inner_boundingbox p -%D \stoptyping - -path mfun_boundingbox_stack ; -numeric mfun_boundingbox_stack_depth ; - -mfun_boundingbox_stack_depth := 0 ; - -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 -enddef; - -vardef innerboundingbox primary p = - top rt llcorner p -- - top lft lrcorner p -- - bot lft urcorner p -- - bot rt ulcorner p -- cycle -enddef; - -vardef outerboundingbox primary p = - bot lft llcorner p -- - bot rt lrcorner p -- - top rt urcorner p -- - top lft ulcorner p -- cycle -enddef; - -def inner_boundingbox = innerboundingbox enddef ; -def outer_boundingbox = outerboundingbox enddef ; - -vardef set_inner_boundingbox text q = % obsolete - setbounds q to innerboundingbox q; -enddef; - -vardef set_outer_boundingbox text q = % obsolete - setbounds q to outerboundingbox q; -enddef; - -%D Some missing functions can be implemented rather straightforward (thanks to -%D Taco and others): - -% oldpi := 3.14159265358979323846 ; % from -pi := 3.14159265358979323846264338327950288419716939937510 ; % 50 digits -radian := 180/pi ; % 2pi*radian = 360 ; - -% let +++ = ++ ; - -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 ; - -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 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 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 ; - -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 = - 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 -%D first macro divides the sides into n equal parts. The -%D first argument specifies the way the lines are drawn, while -%D the second argument identifier the way the shape is to be -%D drawn. -%D -%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 \stoptyping -%D -%D The a (or angle) alternative supports arbitrary angles and -%D is therefore more versatile. -%D -%D \starttyping -%D stripe_path_a -%D (withpen pencircle scaled 2 withcolor red) -%D (draw) -%D fullcircle xscaled 100 yscaled 40 withcolor blue; -%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 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; -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) -enddef; - -def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text = - 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) -enddef; - -def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text = - draw image(s_draw s_path s_text) anglestriped(3,0,0) s_spec ; -enddef ; - -%D A few normalizing macros: - -primarydef p xsized w = - (p if (bbwidth (p)>0) and (w>0) : scaled (w/bbwidth (p)) fi) -enddef ; - -primarydef p ysized h = - (p if (bbheight(p)>0) and (h>0) : scaled (h/bbheight(p)) fi) -enddef ; - -primarydef p xysized s = - begingroup - save wh, w, h ; pair wh ; numeric w, h ; - wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; - p - if (w>0) and (h>0) : - if xpart wh > 0 : xscaled (xpart wh/w) fi - if ypart wh > 0 : yscaled (ypart wh/h) fi - fi - endgroup -enddef ; - -let sized = xysized ; - -def xscale_currentpicture(expr w) = % obsolete - currentpicture := currentpicture xsized w ; -enddef; - -def yscale_currentpicture(expr h) = % obsolete - currentpicture := currentpicture ysized h ; -enddef; - -def xyscale_currentpicture(expr w, h) = % obsolete - currentpicture := currentpicture xysized (w,h) ; -enddef; - -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 -%D is located in the first quadrant. Now guess what kind of -%D path fullsquare and unitcircle do return. - -path fullsquare, unitcircle ; - -fullsquare := unitsquare shifted - center unitsquare ; -unitcircle := fullcircle shifted urcorner fullcircle ; - -%D Some more paths: - -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 ; - -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 ; - -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 ; - -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 ; -fulldiamond := unitdiamond shifted - center unitdiamond ; - -%D More robust: - -% let normalscaled = scaled ; -% let normalxscaled = xscaled ; -% let normalyscaled = yscaled ; -% -% def scaled expr s = normalscaled (s) enddef ; -% def xscaled expr s = normalxscaled (s) enddef ; -% def yscaled expr s = normalyscaled (s) enddef ; - -%D Shorter - -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 Some personal code that might move to another module - -def set_grid(expr w, h, nx, ny) = - 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 ; -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 -enddef ; - -%D usage: \type{innerpath peepholed outerpath}. -%D -%D beginfig(1); -%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ; -%D fill (fullsquare scaled 200) withcolor red ; -%D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ; -%D fill p peepholed bbox p ; -%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 - else : - llcorner q -- lrcorner q -- urcorner q -- ulcorner q -- - reverse p -- ulcorner q -- cycle - fi - fi - endgroup -enddef ; - -boolean intersection_found ; - -secondarydef p intersection_point q = - begingroup - save x_, y_ ; - (x_,y_) = p intersectiontimes q ; - if x_<0 : - intersection_found := false ; - center p % origin - else : - intersection_found := true ; - .5[point x_ of p, point y_ of q] - fi - 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 -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 -enddef ; - -%D Some colors. - -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 ; - -%D Well, this is the dangerous and naive version: - -def drawfill text 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 ; - mfun_do_drawfill -enddef ; - -def mfun_do_drawfill text t = - draw _c_ t ; - fill _c_ t ; -enddef; - -def undrawfill expr c = - drawfill c withcolor background % rather useless -enddef ; - -%D Moved from mp-char.mp - -vardef paired primary d = - if pair d : d else : (d,d) fi -enddef ; - -vardef tripled primary d = - if color d : d else : (d,d,d) fi -enddef ; - -% maybe secondaries: - -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 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 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 = ( - if pair p : - 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 - fi -) enddef ; - -%D Also handy (math ladders): - -vardef laddered primary p = % was expr - point 0 of p - for i=1 upto length(p) : - -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p) - endfor -enddef ; - -%D Saves typing: - -% vardef bottomboundary primary p = (llcorner p -- lrcorner p) enddef ; -% vardef rightboundary primary p = (lrcorner p -- urcorner p) 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 ; - -%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 ; - -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 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 = ( - 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 : - p + uniformdeviate s - fi -) enddef ; - -%D Not perfect (alternative for interpath) - -vardef interpolated(expr s, p, q) = - 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 paralleled d = ( - p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p) -) 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 -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 -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 -enddef ; - -%D Rather fundamental. - -% not yet ok - -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 ; -vardef rightpath expr p = leftrightpath(p,false) enddef ; - -%D Drawoptions - -def saveoptions = - save _op_ ; def _op_ = enddef ; -enddef ; - -%D Tracing. (not yet in lexer) - -let normaldraw = draw ; -let normalfill = fill ; - -% bugged in mplib so ... - -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 ; -def drawlabeloptions (text t) = def _lab_opt_ = t enddef ; enddef ; -def draworiginoptions (text t) = def _ori_opt_ = t enddef ; enddef ; -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) ; -enddef ; - -resetdrawoptions ; - -%D Path. - -def drawpath expr p = - normaldraw p _pth_opt_ -enddef ; - -%D Arrow. - -vardef drawarrowpath expr p = - save autoarrows ; boolean autoarrows ; autoarrows := true ; - drawarrow p _pth_opt_ -enddef ; - -def midarrowhead expr 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 -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_ -enddef ; - -%D PathPoints. - -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 mfun_draw_points text t = - for _i_=0 upto length(_c_) : - normaldraw point _i_ of _c_ _pnt_opt_ t ; - endfor ; -enddef; - -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 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 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_ -enddef ; - -%D Origin. - -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 ; -enddef; - -%D Axis. - -numeric tickstep ; tickstep := 5mm ; -numeric ticklength ; ticklength := 2mm ; - -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 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 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 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 ; -enddef ; - -%D Tracing. - -def visualizeddraw expr c = - 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 -enddef ; - -def do_visualizeddraw text t = - 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_ ; -enddef ; - -def visualizepaths = - let fill = visualizedfill ; - let draw = visualizeddraw ; -enddef ; - -def naturalizepaths = - 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 -extra_beginfig := extra_beginfig & " miterlimit := 10 ; " ; % restores -extra_beginfig := extra_beginfig & " linejoin := rounded ; " ; % restores -extra_beginfig := extra_beginfig & " linecap := rounded ; " ; % restores - -%D Normally, arrowheads don't scale well. So we provide a -%D hack. - -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)) ; -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) -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 arrowpath _apth t ; % arrowpath added - fill arrowhead _apth t ; - draw arrowhead _apth 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) -enddef ; - -def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ; -def leftarrow (expr pat,tim,len) = pointarrow(pat,tim,len,+len) enddef ; -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 \starttyping -%D drawdot point .5 along somepath ; -%D drawdot point 3cm on somepath ; -%D \stoptyping -%D -%D The number denotes a percentage (fraction). - -primarydef pct along pat = % also negative - (arctime (pct * (arclength pat)) of pat) of pat -enddef ; - -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 - -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 -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 ; - -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 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) ; -enddef ; - -vardef freedotlabel (expr str, loc, ori) = - interim linecap := rounded ; - draw loc withpen pencircle scaled freedotlabelsize ; - draw thefreelabel(str,loc,ori) ; -enddef ; - -%D \starttyping -%D drawarrow anglebetween(line_a,line_b,somelabel) ; -%D \stoptyping - -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 ; - 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 mfun_current_picture_stack[] ; -numeric mfun_current_picture_depth ; - -mfun_current_picture_depth := 0 ; - -def pushcurrentpicture = - 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 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) ; - -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) ; - - transform t ; t := identity rotatedaround(origin,120) ; - - r := fullcircle rotated 90 scaled radius shifted (0,radius/4) rotatedaround(origin,135) ; - - 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 ; - - w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ; - - 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 ; - - for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ; - - currentpicture := currentpicture xsized size ; - - 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)) -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 ; - ) - fi -enddef ; - -vardef inverted primary p = - p uncolored white -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 -enddef ; - -vardef grayed primary p = - if rgbcolor p : - tripled(.30redpart p+.59greenpart p+.11bluepart p) - 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 - 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 - 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 ; - ) - else : - p - fi -enddef ; - -let greyed = grayed ; - -% yes or no: "text" infont "cmr12" at 24pt ; - -% let normalinfont = infont ; -% -% numeric lastfontsize ; lastfontsize = fontsize defaultfont ; -% -% def infont primary name = % no vardef, no expr -% hide(lastfontsize := fontsize name) % no ; -% normalinfont name -% enddef ; -% -% def scaledat expr size = -% scaled (size/lastfontsize) -% enddef ; -% -% let at = scaledat ; - -% like decimal - -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 -enddef ; - -primarydef p enlonged len = - begingroup - if pair p : - save q ; path q ; q := origin -- p ; - save al ; al := arclength(q) ; - if al > 0 : - point 1 of (q stretched ((al+len)/al)) - else : - p - fi - else : - save al ; al := arclength(p) ; - if al > 0 : - p stretched ((al+len)/al) - else : - p - fi - fi - endgroup -enddef ; - -% path p ; p := (0,0) -- (10cm,5cm) ; -% drawarrow p withcolor red ; -% drawarrow p shortened 1cm withcolor green ; - -primarydef p shortened d = - reverse ( ( reverse (p enlonged -d) ) enlonged -d ) -enddef ; - -% yes or no, untested -) - -def xshifted expr dx = shifted(dx,0) enddef ; -def yshifted expr dy = shifted(0,dy) enddef ; - -% also handy - -% right: str = readfrom ("abc" & ".def" ) ; -% wrong: str = readfrom "abc" & ".def" ; - -% Every 62th read fails so we need to try again! - -% def readfile (expr name) = -% if (readfrom (name) <> EOF) : -% scantokens("input " & name & ";") ; -% elseif (readfrom (name) <> EOF) : -% scantokens("input " & name & ";") ; -% fi ; -% closefrom (name) ; -% enddef ; -% -% this sometimes fails on the elseif, so : -% - -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 ; -enddef ; - -% permits redefinition of end in macro - -inner end ; - -% this will be redone (when needed) using scripts and backend handling - -let normalwithcolor = withcolor ; - -def remapcolors = - def withcolor primary c = normalwithcolor remappedcolor(c) enddef ; -enddef ; - -def normalcolors = - let withcolor = normalwithcolor ; -enddef ; - -def resetcolormap = - color color_map[][][] ; - normalcolors ; -enddef ; - -resetcolormap ; - -def r_color primary c = redpart c enddef ; -def g_color primary c = greenpart c enddef ; -def b_color primary c = bluepart c enddef ; - -def remapcolor(expr old, new) = - color_map[redpart old][greenpart old][bluepart old] := new ; -enddef ; - -def remappedcolor(expr c) = - if known color_map[redpart c][greenpart c][bluepart c] : - color_map[redpart c][greenpart c][bluepart c] - else : - c - fi -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 ; - -% primarydef p recolored t = repathed(0,p) t enddef ; -% primarydef p refilled t = repathed(1,p) t enddef ; -% primarydef p redrawn t = repathed(2,p) t enddef ; -% primarydef p retexted t = repathed(3,p) t enddef ; -% primarydef p untexted t = repathed(4,p) t enddef ; - -color refillbackground ; refillbackground := (1,1,1) ; - -def restroke suffix p = p := repathed (21,p) enddef ; % keep attributes -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 ; - fi ; - endfor ; - setbounds _p_ to _b_ ; - _p_ - endgroup -enddef ; - -% After a question of Denis on how to erase a z variable, Jacko -% suggested to assign whatever to x and y. So a clearz -% variable can be defined as: -% -% vardef clearz@# = -% x@# := whatever ; -% y@# := whatever ; -% enddef ; -% -% but Jacko suggested a redefinition of clearxy: -% -% def clearxy text s = -% clearxy_index_:=0; -% for $:=s: -% clearxy_index_:=clearxy_index_+1; endfor; -% if clearxy_index_=0: -% save x,y; -% else: -% forsuffixes $:=s: x$:=whatever; y$:=whatever; endfor; -% fi -% 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 -enddef ; - -% so now we can say: clearxy ; as well as clearxy 1, 2, 3 ; - -% show x0 ; z0 = (10,10) ; -% show x0 ; x0 := whatever ; y0 := whatever ; -% show x0 ; z0 = (20,20) ; -% show x0 ; clearxy 0 ; -% 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) -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) -enddef ; - -% cmyk color support - -% vardef cmyk(expr c,m,y,k) = % elsewhere -% (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 -% 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 -% 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 -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 ; - fi ; - fi ; -enddef ; - -% result from metafont discussion list (denisr/boguslawj) - -def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ; -def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ; - -let == = = ; - -% added - -picture oddly ; % evenly already defined - -evenly := dashpattern(on 3 off 3) ; -oddly := dashpattern(off 3 on 3) ; - -% not perfect, but useful since it removes redundant points. - -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 ; - _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 - else : - p - fi -enddef ; - -vardef simplified expr p = ( - reverse mfun_straightened(+1,mfun_straightened(+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) -- -% (4cm,1cm) -- (4cm,2cm) -- (4cm,2.5cm) -- (4cm,3cm) -- -% (3cm,3cm) -- (2cm,3cm) -- (1cm,3cm) -- (-1cm,3cm) -- -% .5[(-1cm,3cm),(1cm,1cm)] -- (1cm,1cm) -- cycle ; -% -% p := unitcircle scaled 4cm ; -% -% drawpath p ; drawpoints p ; drawpointlabels p ; -% p := p shifted (4cm,0) ; p := straightened p ; -% drawpath p ; drawpoints p ; drawpointlabels p ; -% p := p shifted (4cm,0) ; p := straightened p ; -% drawpath p ; drawpoints p ; drawpointlabels p ; - -% new - -path originpath ; originpath := origin -- cycle ; - -vardef unitvector primary z = - if abs z = abs origin : z else : z/abs z fi -enddef; - -% also new - -% 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 -enddef ; - -% handy - -def withgray primary g = - withcolor g -enddef ; - -% for metafun - -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 -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 -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 - 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 ; -enddef ; - -% makes a (line) into an infinite one (handy for calculating -% intersection points - -vardef infinite expr 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) -enddef ; - -% obscure macros: create var from string and replace - and : -% (needed for process color id's) .. will go away - -string mfun_clean_ascii[] ; - -def register_dirty_chars(expr str) = - for i = 0 upto length(str)-1 : - 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 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 ; -enddef ; - -vardef getunstringed (expr s) = - scantokens(cleanstring(s)) -enddef ; - -vardef unstringed (expr s) = - 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) = % 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 ; - endfor ; - for x=MinX upto MaxX: - label.bot(textext("\infofont " & decimal x), (x*DeltaX,-size)) ; - endfor ; - for y=MinY upto MaxY: - label.lft(textext("\infofont " & decimal y), (-size,y*DeltaY)) ; - endfor ; - endgroup -enddef; - -% new, handy for: -% -% \startuseMPgraphic{map}{n} -% \includeMPgraphic{map:germany} ; -% c_phantom (\MPvar{n}<1) ( -% fill map_germany withcolor \MPcolor{lightgray} ; -% draw map_germany withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% \includeMPgraphic{map:austria} ; -% c_phantom (\MPvar{n}<2) ( -% fill map_austria withcolor \MPcolor{lightgray} ; -% draw map_austria withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% c_phantom (\MPvar{n}<3) ( -% \includeMPgraphic{map:swiss} ; -% fill map_swiss withcolor \MPcolor{lightgray} ; -% draw map_swiss withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% c_phantom (\MPvar{n}<4) ( -% \includeMPgraphic{map:luxembourg} ; -% fill map_luxembourg withcolor \MPcolor{lightgray} ; -% draw map_luxembourg withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; -% ) ; -% \stopuseMPgraphic -% -% \useMPgraphic{map}{n=3} - -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 ; -enddef ; - -%D Handy: - -def break = - exitif true ; % fi -enddef ; - -%D New too: - -primarydef p xstretched w = ( - p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi -) enddef ; - -primarydef p ystretched h = ( - p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi -) enddef ; - -%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) ; -% 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 ; - 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 ; - -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 (charscale > 0) and (charscale <> 1) : - currentpicture := currentpicture scaled charscale ; - fi ; fi ; - endfig ; -enddef ; - -%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 ; - -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-txts.mpii b/metapost/context/base/mp-txts.mpii deleted file mode 100644 index d3597488f..000000000 --- a/metapost/context/base/mp-txts.mpii +++ /dev/null @@ -1,66 +0,0 @@ -%D \module -%D [ file=mp-txts.mpii, -%D version=2006.06.08, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=more text support, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA] -%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_txts : endinput ; fi ; - -boolean context_txts ; context_txts := true ; - -%D The real code: - -string txtfile ; txtfile := "" ; -string txtfont ; txtfont := defaultfont ; -string txtpref ; txtpref := "00001::::" ; -numeric txtnext ; txtnext := 0 ; -numeric txtdepth ; txtdepth := 0 ; - -vardef nexttxt = - txtnext := txtnext + 1 ; - txtnext -enddef ; - -picture savedtxts[] ; -numeric depthtxts[] ; - -vardef zerofilled(expr fd) = - if fd<10: "0000" else : - if fd<100: "000" else : - if fd<1000: "00" else : - if fd<10000: "0" else : - fi fi fi fi & decimal fd -enddef; - -vardef savetxt(expr n,w,h,d) text t = - depthtxts[n] := d ; - savedtxts[n] := ((txtpref & zerofilled(n)) infont txtfont) xysized(w,h+d) t -enddef ; - -vardef sometxt(expr n) = - if known savedtxts[n] : - txtdepth := depthtxts[n] ; savedtxts[n] - else : - txtdepth := 0 ; nullpicture - fi -enddef ; - -def loadtxts = - if txtfile <> "" : - readfile(txtfile) ; - fi ; -enddef ; - -def StartTexts = - loadtxts ; -enddef ; - -def StopTexts = -enddef ; diff --git a/metapost/context/base/mpii/metafun.mpii b/metapost/context/base/mpii/metafun.mpii new file mode 100644 index 000000000..9c55191f7 --- /dev/null +++ b/metapost/context/base/mpii/metafun.mpii @@ -0,0 +1,65 @@ +%D \module +%D [ file=metafun.mp, +%D version=2000.07.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=format generation file, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D When generating many graphics at runtime, it can save run +%D time to use a format file. We could have named this file +%D \type {context}, but this is error prone, because it forces +%D to use the progname \type {mpost} or \type {context} +%D explicitly, depending on the needs. When using the format, +%D a mismatch in the memory specification of \type {mpost} or +%D \type {context} (the \TEX\ one) could lead to lost strings +%D (and as a result in buggy boundingbox and special +%D handling). By using the name \type {metatex} we make sure +%D that we use (unless overloaded) the settings of \type +%D {mpost}. + +%D First we input John Hobby's metapost plain file. However, +%D because we want to prevent dependency problems and in the +%D end even may use a patched version, we prefer to use a +%D copy. + +input "mp-base.mpii" ; +input "mp-tool.mpii" ; +input "mp-spec.mpii" ; +input "mp-core.mpii" ; +input "mp-page.mpii" ; +input "mp-text.mpii" ; +input "mp-txts.mpii" ; +input "mp-shap.mpii" ; +input "mp-butt.mpii" ; +input "mp-char.mpii" ; +input "mp-step.mpii" ; +input "mp-grph.mpii" ; +input "mp-figs.mpii" ; +%%%%% "mp-form.mpii" ; +input "mp-grid.mpii" ; +input "mp-func.mpii" ; + +string metafunversion ; + +metafunversion = "metafun ii" & " " & + decimal year & "-" & + decimal month & "-" & + decimal day & " " & + if ((time div 60) < 10) : "0" & fi + decimal (time div 60) & ":" & + if ((time-(time div 60)*60) < 10) : "0" & fi + decimal (time-(time div 60)*60) ; + +let normalend = end ; + +def end = + ; message "" ; message metafunversion ; message "" ; normalend ; +enddef ; + +% dump ; diff --git a/metapost/context/base/mpii/mp-back.mpii b/metapost/context/base/mpii/mp-back.mpii new file mode 100644 index 000000000..f588adea9 --- /dev/null +++ b/metapost/context/base/mpii/mp-back.mpii @@ -0,0 +1,205 @@ +%D \module +%D [ file=mp-back.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=backgrounds, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_back : endinput ; fi ; + +boolean context_back ; context_back := true ; + +def some_hash ( expr hash_width , + hash_height , + hash_linewidth , + hash_linecolor , + hash_angle , + hash_gap ) = + + stripe_gap := hash_gap ; + stripe_angle := hash_angle ; + drawoptions (withpen pencircle scaled hash_linewidth + withcolor hash_linecolor) ; + path p ; p := unitsquare xscaled hash_width yscaled hash_height ; + stripe_path_a () (draw) p ; % next we move it all to quadrant 1 + currentpicture := currentpicture shifted urcorner currentpicture ; + +enddef ; + +def some_double_back (expr back_type , + back_width , + back_height , + back_delta , + back_linewidth , + back_linecolor , + back_fillcolor , + back_topcolor , + back_bottomcolor , + back_leftcolor , + back_rightcolor ) = + + numeric ww ; ww := back_width ; + numeric hh ; hh := back_height ; + numeric dd ; dd := back_delta ; + + color back_nillcolor ; back_nillcolor := back_topcolor ; + + path p ; p := fullsquare xscaled ww yscaled hh ; + path q ; q := fullsquare xscaled (ww-2dd) yscaled (hh-2dd) ; + path r ; r := llcorner p -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p -- cycle ; + path s ; s := r xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path t ; t := llcorner p -- + lrcorner p -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) -- + llcorner p -- cycle ; + path u ; u := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path v ; v := llcorner p shifted ( 3dd,0) -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) .. + llcorner p shifted (0, 3dd) .. controls llcorner p .. cycle ; % {down} .. cycle ; + path w ; w := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path a ; a := llcorner p -- ulcorner p -- + ulcorner q -- llcorner q -- cycle ; + path b ; b := llcorner p -- lrcorner p -- + lrcorner q -- llcorner q -- cycle ; + path c ; c := lrcorner p -- urcorner p -- + urcorner q -- lrcorner q -- cycle ; + path d ; d := ulcorner p -- urcorner p -- + urcorner q -- ulcorner q -- cycle ; + path e ; e := llcorner p -- lrcorner p -- + urcorner p -- urcorner q -- + lrcorner q -- llcorner q -- cycle ; + path f ; f := llcorner p -- ulcorner p -- + urcorner p -- urcorner q -- + ulcorner q -- llcorner q -- cycle ; + + linecap := butt ; pickup pencircle scaled back_linewidth ; + + if back_type=1 : + + fill p withcolor back_fillcolor ; + fill a withcolor back_leftcolor ; + fill b withcolor back_bottomcolor ; + fill c withcolor back_rightcolor ; + fill d withcolor back_topcolor ; + draw a withcolor back_linecolor ; + draw d withcolor back_linecolor ; + draw b withcolor back_linecolor ; + draw c withcolor back_linecolor ; + + elseif back_type=2 : + + fill p withcolor back_fillcolor ; + fill e withcolor back_bottomcolor ; + fill f withcolor back_topcolor ; + draw e withcolor back_linecolor ; + draw f withcolor back_linecolor ; + + elseif back_type=3 : + + fill v withcolor back_nillcolor ; + fill w withcolor back_fillcolor ; + draw v withcolor back_linecolor ; + draw w withcolor back_linecolor ; + + elseif back_type=4 : + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=5 : + + t := t rotatedaround(center t,180) ; + u := u rotatedaround(center u,180) ; + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=6 : + + r := r rotatedaround(center r,180) ; + s := s rotatedaround(center s,180) ; + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + + elseif back_type=7 : + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + +fi ; + +enddef ; + +endinput ; + +beginfig (1) ; + +some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, .7white, .6white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +endfig ; + +end . diff --git a/metapost/context/base/mpii/mp-base.mpii b/metapost/context/base/mpii/mp-base.mpii new file mode 100644 index 000000000..7af4bc436 --- /dev/null +++ b/metapost/context/base/mpii/mp-base.mpii @@ -0,0 +1,591 @@ +% This is (currently) a copy of the plain.mp file. We use a copy +% because (1) we want to make sure that there are no unresolved +% dependencies, and (2) we may patch this file eventually. +% +% colorpart will be overloaded later (we already had that one) +% _findarr now has a filldraw, was fill in 0.63 + +% This file gives the macros for plain MetaPost +% It contains all the features of plain METAFONT except those specific to +% font-making. (See The METAFONTbook by D.E. Knuth). +% There are also a number of macros for labeling figures, etc. +string base_name, base_version; base_name="plain"; base_version="1.004 for metafun ii"; + +message "Preloading the plain mem file, version "&base_version; + +delimiters (); % this makes parentheses behave like parentheses +def upto = step 1 until enddef; % syntactic sugar +def downto = step -1 until enddef; +def exitunless expr c = exitif not c enddef; +let relax = \; % ignore the word `relax', as in TeX +let \\ = \; % double relaxation is like single +def ]] = ] ] enddef; % right brackets should be loners +def -- = {curl 1}..{curl 1} enddef; +def --- = .. tension infinity .. enddef; +def ... = .. tension atleast 1 .. enddef; + +def gobble primary g = enddef; +primarydef g gobbled gg = enddef; +def hide(text t) = exitif numeric begingroup t;endgroup; enddef; +def ??? = hide(interim showstopping:=1; showdependencies) enddef; +def stop expr s = message s; gobble readstring enddef; + +warningcheck:=1; +tracinglostchars:=1; + +def interact = % sets up to make "show" commands stop + hide(showstopping:=1; tracingonline:=1) enddef; + +def loggingall = % puts tracing info into the log + tracingcommands:=3; tracingtitles:=1; tracingequations:=1; + tracingcapsules:=1; tracingspecs:=2; tracingchoices:=1; tracinglostchars:=1; + tracingstats:=1; tracingoutput:=1; tracingmacros:=1; tracingrestores:=1; + enddef; + +def tracingall = % turns on every form of tracing + tracingonline:=1; showstopping:=1; loggingall enddef; + +def tracingnone = % turns off every form of tracing + tracingcommands:=0; tracingtitles:=0; tracingequations:=0; + tracingcapsules:=0; tracingspecs:=0; tracingchoices:=0; tracinglostchars:=0; + tracingstats:=0; tracingoutput:=0; tracingmacros:=0; tracingrestores:=0; + enddef; + + + +%% dash patterns + +vardef dashpattern(text t) = + save on, off, w; + let on=_on_; + let off=_off_; + w = 0; + nullpicture t +enddef; + +tertiarydef p _on_ d = + begingroup save pic; + picture pic; pic=p; + addto pic doublepath (w,w)..(w+d,w); + w := w+d; + pic shifted (0,d) + endgroup +enddef; + +tertiarydef p _off_ d = + begingroup w:=w+d; + p shifted (0,d) + endgroup +enddef; + + + +%% basic constants and mathematical macros + +% numeric constants +newinternal eps,epsilon,infinity,_; +eps := .00049; % this is a pretty small positive number +epsilon := 1/256/256; % but this is the smallest +infinity := 4095.99998; % and this is the largest +_ := -1; % internal constant to make macros unreadable but shorter + +newinternal mitered, rounded, beveled, butt, squared; +mitered:=0; rounded:=1; beveled:=2; % linejoin types +butt:=0; rounded:=1; squared:=2; % linecap types + + +% pair constants +pair right,left,up,down,origin; +origin=(0,0); up=-down=(0,1); right=-left=(1,0); + +% path constants +path quartercircle,halfcircle,fullcircle,unitsquare; +fullcircle = makepath pencircle; +halfcircle = subpath (0,4) of fullcircle; +quartercircle = subpath (0,2) of fullcircle; +unitsquare=(0,0)--(1,0)--(1,1)--(0,1)--cycle; + +% transform constants +transform identity; +for z=origin,right,up: z transformed identity = z; endfor + +% color constants +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 +def colorpart primary t = + if colormodel t=7: + (cyanpart t, magentapart t, yellowpart t, blackpart t) + elseif colormodel t=5: + (redpart t, greenpart t, bluepart t) + elseif colormodel t=3: + (greypart t) + elseif colormodel t=1: + false + else: + %%% For clipping and bounding paths, etc. + if defaultcolormodel=7: (0,0,0,1) + elseif defaultcolormodel=5: black + elseif defaultcolormodel=3: 0 + else: false + fi + fi +enddef; + +% picture constants +picture blankpicture,evenly,withdots; +blankpicture=nullpicture; % `display blankpicture...' +evenly=dashpattern(on 3 off 3); % `dashed evenly' +withdots=dashpattern(off 2.5 on 0 off 2.5); % `dashed withdots' + +% string constants +string ditto, EOF; +ditto = char 34; % ASCII double-quote mark +EOF = char 0; % end-of-file for readfrom and write..to + +% pen constants +pen pensquare,penrazor,penspeck; +pensquare = makepen(unitsquare shifted -(.5,.5)); +penrazor = makepen((-.5,0)--(.5,0)--cycle); +penspeck=pensquare scaled eps; + +% nullary operators +vardef whatever = save ?; ? enddef; + +% unary operators +let abs = length; + +vardef round primary u = + if numeric u: floor(u+.5) + elseif pair u: (round xpart u, round ypart u) + else: u fi enddef; + +vardef ceiling primary x = -floor(-x) enddef; + +vardef byte primary s = + if string s: ASCII fi s enddef; + +vardef dir primary d = right rotated d enddef; + +vardef unitvector primary z = z/abs z enddef; + +vardef inverse primary T = + transform T_; T_ transformed T = identity; T_ enddef; + +vardef counterclockwise primary c = + if turningnumber c <= 0: reverse fi c enddef; + +vardef tensepath expr r = + for k=0 upto length r - 1: point k of r --- endfor + if cycle r: cycle else: point infinity of r fi enddef; + +vardef center primary p = .5[llcorner p, urcorner p] enddef; + + + +% binary operators + +primarydef x mod y = (x-y*floor(x/y)) enddef; +primarydef x div y = floor(x/y) enddef; +primarydef w dotprod z = (xpart w * xpart z + ypart w * ypart z) enddef; + +primarydef x**y = if y=2: x*x else: takepower y of x fi enddef; +def takepower expr y of x = + if x>0: mexp(y*mlog x) + elseif (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=_ 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; + +vardef directionpoint expr z of p = + a_:=directiontime z of p; + if a_<0: errmessage("The direction doesn't occur"); fi + point a_ of p enddef; + +secondarydef p intersectionpoint q = + begingroup save x_,y_; (x_,y_)=p intersectiontimes q; + if x_<0: errmessage("The paths don't intersect"); origin + else: .5[point x_ of p, point y_ of q] fi endgroup +enddef; + +tertiarydef p softjoin q = + begingroup c_:=fullcircle scaled 2join_radius shifted point 0 of q; + a_:=ypart(c_ intersectiontimes p); b_:=ypart(c_ intersectiontimes q); + if a_<0:point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi + ... if b_<0:{direction infinity of q}point infinity of q + else: subpath(b_,infinity) of q fi endgroup enddef; +newinternal join_radius,a_,b_; path c_; + + +path cuttings; % what got cut off + +tertiarydef a cutbefore b = % tries to cut as little as possible + begingroup save t; + (t, whatever) = a intersectiontimes b; + if t<0: + cuttings:=point 0 of a; + a + else: cuttings:= subpath (0,t) of a; + subpath (t,length a) of a + fi + endgroup +enddef; + +tertiarydef a cutafter b = + reverse (reverse a cutbefore b) + hide(cuttings:=reverse cuttings) +enddef; + + + +% special operators +vardef incr suffix $ = $:=$+1; $ enddef; +vardef decr suffix $ = $:=$-1; $ enddef; + +def reflectedabout(expr w,z) = % reflects about the line w..z + transformed + begingroup transform T_; + w transformed T_ = w; z transformed T_ = z; + xxpart T_ = -yypart T_; xypart T_ = yxpart T_; % T_ is a reflection + T_ endgroup enddef; + +def rotatedaround(expr z, d) = % rotates d degrees around z + shifted -z rotated d shifted z enddef; +let rotatedabout = rotatedaround; % for roundabout people + +vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings + save u_; setu_ u; for uu = t: if uuu_: u_:=uu; fi endfor + u_ enddef; + +def setu_ primary u = + if pair u: pair u_ elseif string u: string u_ fi; + u_=u enddef; + +def flex(text t) = % t is a list of pairs + hide(n_:=0; for z=t: z_[incr n_]:=z; endfor + dz_:=z_[n_]-z_1) + z_1 for k=2 upto n_-1: ...z_[k]{dz_} endfor ...z_[n_] enddef; +newinternal n_; pair z_[],dz_; + +def superellipse(expr r,t,l,b,s)= + r{up}...(s[xpart t,xpart r],s[ypart r,ypart t]){t-r}... + t{left}...(s[xpart t,xpart l],s[ypart l,ypart t]){l-t}... + l{down}...(s[xpart b,xpart l],s[ypart l,ypart b]){b-l}... + b{right}...(s[xpart b,xpart r],s[ypart r,ypart b]){r-b}...cycle enddef; + +vardef interpath(expr a,p,q) = + for t=0 upto length p-1: a[point t of p, point t of q] + ..controls a[postcontrol t of p, postcontrol t of q] + and a[precontrol t+1 of p, precontrol t+1 of q] .. endfor + if cycle p: cycle + else: a[point infinity of p, point infinity of q] fi enddef; + +vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false + tx_:=true_x; fx_:=false_x; + forever: x_:=.5[tx_,fx_]; exitif abs(tx_-fx_)<=tolerance; + if @#(x_): tx_ else: fx_ fi :=x_; endfor + x_ enddef; % now x_ is near where @# changes from true to false +newinternal tolerance, tx_,fx_,x_; tolerance:=.01; + +vardef buildcycle(text ll) = + save ta_, tb_, k_, i_, pp_; path pp_[]; + k_=0; + for q=ll: pp_[incr k_]=q; endfor + i_=k_; + for i=1 upto k_: + (ta_[i], length pp_[i_]-tb_[i_]) = + pp_[i] intersectiontimes reverse pp_[i_]; + if ta_[i]<0: + errmessage("Paths "& decimal i &" and "& decimal i_ &" don't intersect"); + fi + i_ := i; + endfor + for i=1 upto k_: subpath (ta_[i],tb_[i]) of pp_[i] .. endfor + cycle +enddef; + + + +%% units of measure + +mm=2.83464; pt=0.99626; dd=1.06601; bp:=1; +cm=28.34645; pc=11.95517; cc=12.79213; in:=72; + +vardef magstep primary m = mexp(46.67432m) enddef; + + + +%% macros for drawing and filling + +def drawoptions(text t) = + def _op_ = t enddef +enddef; + +linejoin:=rounded; % parameters that effect drawing +linecap:=rounded; +miterlimit:=10; + +drawoptions(); + +pen currentpen; +picture currentpicture; + +def fill expr c = addto currentpicture contour c _op_ enddef; +def draw expr p = + addto currentpicture + if picture p: + also p + else: + doublepath p withpen currentpen + fi + _op_ +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 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; +def unfilldraw expr c = filldraw c withcolor background enddef; +def undrawdot expr z = drawdot z withcolor background enddef; +def erase text t = + def _e_ = withcolor background hide(def _e_=enddef;) enddef; + t _e_ +enddef; +def _e_= enddef; + +def cutdraw text t = + begingroup interim linecap:=butt; draw t _e_; endgroup enddef; + +vardef image(text t) = + save currentpicture; + picture currentpicture; + currentpicture := nullpicture; + t; + currentpicture +enddef; + +def pickup secondary q = + if numeric q: numeric_pickup_ else: pen_pickup_ fi q enddef; +def numeric_pickup_ primary q = + if unknown pen_[q]: errmessage "Unknown pen"; clearpen + else: currentpen:=pen_[q]; + pen_lft:=pen_lft_[q]; + pen_rt:=pen_rt_[q]; + pen_top:=pen_top_[q]; + pen_bot:=pen_bot_[q]; + currentpen_path:=pen_path_[q] fi; 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; + path currentpen_path; enddef; +newinternal pen_lft,pen_rt,pen_top,pen_bot,pen_count_; + +vardef savepen = pen_[incr pen_count_]=currentpen; + pen_lft_[pen_count_]=pen_lft; + pen_rt_[pen_count_]=pen_rt; + pen_top_[pen_count_]=pen_top; + pen_bot_[pen_count_]=pen_bot; + pen_path_[pen_count_]=currentpen_path; + pen_count_ enddef; + +def clearpen = currentpen:=nullpen; + pen_lft:=pen_rt:=pen_top:=pen_bot:=0; + path currentpen_path; + enddef; +def clear_pen_memory = + pen_count_:=0; + numeric pen_lft_[],pen_rt_[],pen_top_[],pen_bot_[]; + pen currentpen,pen_[]; + path currentpen_path, pen_path_[]; + enddef; + +vardef lft primary x = x + if pair x: (pen_lft,0) else: pen_lft fi enddef; +vardef rt primary x = x + if pair x: (pen_rt,0) else: pen_rt fi enddef; +vardef top primary y = y + if pair y: (0,pen_top) else: pen_top fi enddef; +vardef bot primary y = y + if pair y: (0,pen_bot) else: pen_bot fi enddef; + +vardef penpos@#(expr b,d) = + (x@#r-x@#l,y@#r-y@#l)=(b,0) rotated d; + x@#=.5(x@#l+x@#r); y@#=.5(y@#l+y@#r) enddef; + +def penstroke text t = + forsuffixes e = l,r: path_.e:=t; endfor + fill path_.l -- reverse path_.r -- cycle enddef; +path path_.l,path_.r; + + + +%% High level drawing commands + +newinternal ahlength, ahangle; +ahlength := 4; % default arrowhead length 4bp +ahangle := 45; % default head angle 45 degrees + +vardef arrowhead expr p = + save q,e; path q; pair e; + e = point length p of p; + q = gobble(p shifted -e cutafter makepath(pencircle scaled 2ahlength)) + cuttings; + (q rotated .5ahangle & reverse q rotated -.5ahangle -- cycle) shifted e +enddef; + +path _apth; +def drawarrow expr p = _apth:=p; _finarr enddef; +def drawdblarrow expr p = _apth:=p; _findarr enddef; + +def _finarr text t = + draw _apth t; + filldraw arrowhead _apth t +enddef; + +def _findarr text t = + draw _apth t; + filldraw arrowhead _apth withpen currentpen t; + filldraw arrowhead reverse _apth withpen currentpen t +enddef; + + + +%% macros for labels + +newinternal bboxmargin; bboxmargin:=2bp; + +vardef bbox primary p = + llcorner p-(bboxmargin,bboxmargin) -- lrcorner p+(bboxmargin,-bboxmargin) + -- urcorner p+(bboxmargin,bboxmargin) -- ulcorner p+(-bboxmargin,bboxmargin) + -- cycle +enddef; + +string defaultfont; +newinternal defaultscale, labeloffset; +defaultfont = "cmr10"; +defaultscale := 1; +labeloffset := 3bp; + +vardef thelabel@#(expr s,z) = % Position s near z + save p; picture p; + if picture s: p=s + else: p = s infont defaultfont scaled defaultscale + fi; + p shifted (z + labeloffset*laboff@# - + (labxf@#*lrcorner p + labyf@#*ulcorner p + + (1-labxf@#-labyf@#)*llcorner p + ) + ) +enddef; + +def label = draw thelabel enddef; +newinternal dotlabeldiam; dotlabeldiam:=3bp; +vardef dotlabel@#(expr s,z) text t_ = + label@#(s,z) t_; + interim linecap:=rounded; + draw z withpen pencircle scaled dotlabeldiam t_; +enddef; +def makelabel = dotlabel enddef; + +pair laboff, laboff.lft, laboff.rt, laboff.top, laboff.bot; +pair laboff.ulft, laboff.llft, laboff.urt, laboff.lrt; +laboff =(0,0); labxf =.5; labyf =.5; +laboff.lft=(-1,0); labxf.lft=1; labyf.lft=.5; +laboff.rt =(1,0); labxf.rt =0; labyf.rt =.5; +laboff.bot=(0,-1); labxf.bot=.5; labyf.bot=1; +laboff.top=(0,1); labxf.top=.5; labyf.top=0; +laboff.ulft=(-.7,.7);labxf.ulft=1; labyf.ulft=0; +laboff.urt=(.7,.7); labxf.urt=0; labyf.urt=0; +laboff.llft=-(.7,.7);labxf.llft=1; labyf.llft=1; +laboff.lrt=(.7,-.7); labxf.lrt=0; labyf.lrt=1; + +vardef labels@#(text t) = + forsuffixes $=t: + label@#(str$,z$); endfor + enddef; +vardef dotlabels@#(text t) = + forsuffixes $=t: + dotlabel@#(str$,z$); endfor + enddef; +vardef penlabels@#(text t) = + forsuffixes $$=l,,r: forsuffixes $=t: + makelabel@#(str$.$$,z$.$$); endfor endfor + enddef; + + +def range expr x = numtok[x] enddef; +def numtok suffix x=x enddef; +tertiarydef m thru n = + m for x=m+1 step 1 until n: , numtok[x] endfor enddef; + + + +%% Overall adminstration + +string extra_beginfig, extra_endfig; +extra_beginfig = extra_endfig = "" ; + +def beginfig(expr c) = + begingroup + charcode:=c; + clearxy; clearit; clearpen; + pickup defaultpen; + drawoptions(); + scantokens extra_beginfig; +enddef; + +def endfig = + ; % added by HH + scantokens extra_endfig; + shipit ; + endgroup +enddef; + + +%% last-minute items + +vardef z@#=(x@#,y@#) enddef; + +def clearxy = save x,y enddef; +def clearit = currentpicture:=nullpicture enddef; +def shipit = shipout currentpicture enddef; + +let bye = end; outer end,bye; + +clear_pen_memory; % initialize the `savepen' mechanism +clearit; + +newinternal defaultpen; +pickup pencircle scaled .5bp; % set default line width +defaultpen := savepen; diff --git a/metapost/context/base/mpii/mp-butt.mpii b/metapost/context/base/mpii/mp-butt.mpii new file mode 100644 index 000000000..107886bb5 --- /dev/null +++ b/metapost/context/base/mpii/mp-butt.mpii @@ -0,0 +1,77 @@ +%D \module +%D [ file=mp-butt.mpii, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=buttons, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_butt : endinput ; fi ; + +boolean context_butt ; context_butt := true ; + +def predefinedbutton (expr button_type, button_size, button_linecolor, button_fillcolor) = + + begingroup ; + + save button_linewidth, p, d, l ; + + numeric button_linewidth ; button_linewidth := button_size/10 ; + + drawoptions (withpen pencircle scaled button_linewidth withcolor button_linecolor) ; + + path p ; p := unitsquare scaled button_size ; + numeric d ; d := button_size ; + numeric l ; l := button_linewidth ; + + fill p withcolor button_fillcolor ; + draw p ; + + if button_type = 101 : + draw (d-2l,2l)--(2l,.5d)--(d-2l,d-2l)--cycle ; + elseif button_type = 102 : + draw (2l,2l)--(d-2l,.5d)--(2l,d-2l)--cycle ; + elseif button_type = 103 : + for i=2l step 2l until d-2l : + draw (2l,i)--(2l ,i) ; + draw (4l,i)--(d-2l,i) ; + endfor ; + elseif button_type = 104 : + for i=2l step 2l until d-2l : + draw (2l ,i)--(d/2-l,i) ; + draw (d/2+l,i)--(d-2l ,i) ; + endfor ; + elseif button_type = 105 : + fill fullcircle scaled (.2d) shifted (.5d,.7d) ; + fill fullcircle xscaled (.6d) yscaled d shifted (.5d,0) ; + clip currentpicture to p ; + draw p ; + elseif button_type = 106 : + draw (2l,2l)--(d-2l,d-2l) ; + draw (d-2l,2l)--(2l,d-2l) ; + elseif button_type = 107 : + p := (3l,d-2l)--(d-3l,d-2l)--(.5d,4l)--cycle ; + fill p ; draw p ; + draw (.5d,2l) ; + elseif button_type = 108 : + draw (.5d,2l)--(d-2l,d-2l)--(2l,d-2l)--cycle ; + elseif button_type = 109 : + draw (.5d,d-2l)--(d-2l,2l)--(2l,2l)--cycle ; + elseif button_type = 110 : + button_linewidth := button_linewidth/2 ; + draw p enlarged (-2l,-l) ; + for i=2l step l until d-2l : + draw (3l,i)--(d-3l,i) ; + endfor ; + fi ; + + endgroup ; + +enddef ; + +let some_button = predefinedbutton diff --git a/metapost/context/base/mpii/mp-char.mpii b/metapost/context/base/mpii/mp-char.mpii new file mode 100644 index 000000000..63a71eff8 --- /dev/null +++ b/metapost/context/base/mpii/mp-char.mpii @@ -0,0 +1,1006 @@ +% to be cleaned up, namespace needed ! ! ! ! ! + +%D \module +%D [ file=mp-char.mpii, +%D version=1998.10.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=charts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 unknown context_shap : input "mp-shap.mpii" ; fi ; +if known context_flow : endinput ; fi ; + +boolean context_char ; context_char := true ; + +% kan naar elders + +current_position := 0 ; + +def save_text_position (expr p) = % beware: clip shift needed + current_position := current_position + 1 ; + savedata + "\MPposition{" & decimal current_position & "}{" + & decimal xpart p & "}{" + & decimal ypart p & "}%" ; +enddef ; + +%D settings + +grid_width := 60pt ; grid_height := 40pt ; +shape_width := 45pt ; shape_height := 30pt ; + +chart_offset := 2pt ; +color chart_background_color ; chart_background_color := white ; + +%D test mode + +boolean show_mid_points ; show_mid_points := false ; +boolean show_con_points ; show_con_points := false ; +boolean show_all_points ; show_all_points := false ; + +%D shapes + +color shape_line_color, shape_fill_color ; + +shape_line_width := 2pt ; +shape_line_color := .5white ; +shape_fill_color := .9white ; + +shape_node := 0 ; +shape_action := 24 ; +shape_procedure := 5 ; +shape_product := 12 ; +shape_decision := 14 ; +shape_archive := 19 ; +shape_loop := 35 ; +shape_wait := 6 ; +shape_subprocedure := 20 ; shape_sub_procedure := 20 ; +shape_singledocument := 32 ; shape_single_document := 32 ; +shape_multidocument := 33 ; shape_multi_document := 33 ; +shape_right := 66 ; +shape_left := 67 ; +shape_up := 68 ; +shape_down := 69 ; + +% vardef some_shape_path (expr type) == imported from mp-shap + +def show_shapes (expr n) = + + begin_chart(n,8,10) ; + show_con_points := true ; + for i=0 upto 7 : + for j=0 upto 9 : + new_shape(i+1,j+1,i*10+j); + endfor ; + endfor ; + end_chart ; + +enddef ; + +%D connections + +def new_chart = + + color connection_line_color ; + + connection_line_width := shape_line_width ; + connection_line_color := .8white ; + connection_smooth_size := 5pt ; + connection_arrow_size := 4pt ; + connection_dash_size := 3pt ; + + max_x := 6 ; + max_y := 4 ; + + numeric xypoint ; xypoint := 0 ; + + pair xypoints [] ; + + boolean xyfree [][] ; + path xypath [][] ; + numeric xysx [][] ; + numeric xysy [][] ; + color xyfill [][] ; + color xydraw [][] ; + numeric xyline [][] ; + boolean xypeep [][] ; + picture xypicture[][] ; + + numeric cpath ; cpath := 0 ; + path cpaths [] ; + numeric cline [] ; + color ccolor [] ; + boolean carrow [] ; + boolean cdash [] ; + boolean ccross [] ; + + boolean smooth ; smooth := true ; + boolean peepshape ; peepshape := false ; + boolean arrowtip ; arrowtip := true ; + boolean dashline ; dashline := false ; + boolean forcevalid ; forcevalid := false ; + boolean touchshape ; touchshape := false ; + boolean showcrossing ; showcrossing := false ; + + picture dash_pattern ; + + boolean reverse_y ; reverse_y := true ; + +enddef ; + +new_chart ; + +def y_pos (expr y) = + if reverse_y : max_y + 1 - y else : y fi +enddef ; + +def initialize_grid (expr maxx, maxy) = + begingroup ; + save i, j ; + max_x := maxx ; + max_y := maxy ; + dsp_x := 0 ; + dsp_y := 0 ; + for x=1 upto max_x : + for y=1 upto max_y : + xyfree [x][y] := true ; + xyfill [x][y] := shape_fill_color ; + xydraw [x][y] := shape_line_color ; + xyline [x][y] := shape_line_width ; + endfor ; + endfor ; + endgroup ; +enddef ; + +def scaled_to_grid = + xscaled grid_width yscaled grid_height +enddef ; + +def xy_offset (expr x, y) = + (x+.5,y+.5) +enddef ; + +def draw_shape (expr x, yy, p, sx, sy) = + begingroup ; + save y ; + y := y_pos(yy) ; + xypath [x][y] := (p xscaled sx yscaled sy) shifted xy_offset(x,y) ; + xyfree [x][y] := false ; + xysx [x][y] := sx ; + xysy [x][y] := sy ; + xyfill [x][y] := shape_fill_color ; + xydraw [x][y] := shape_line_color ; + xyline [x][y] := shape_line_width ; + xypeep [x][y] := peepshape ; + endgroup ; +enddef ; + +vardef i_point (expr x, y, p, t) = + begingroup ; + save q, ok ; + pair q ; + boolean ok ; + q := xypath[x][y] intersection_point ((p) shifted xy_offset(x,y)) ; + ok := true ; +% if xpart q < -.5 : ok := false ; q := (-.45,ypart q) fi ; +% if xpart q > .5 : ok := false ; q := ( .45,ypart q) fi ; +% if ypart q < -.5 : ok := false ; q := (xpart q,-.45) fi ; +% if ypart q > .5 : ok := false ; q := (xpart q, .45) fi ; + if not ok : + message (t & " of shape (" & decimal x & "," & decimal y & ") limited") ; + fi ; + q + endgroup +enddef ; + +vardef trimmed (expr x, y, z, t) = + if touchshape and t : xyline[x][y]/z else : epsilon fi +enddef ; + +zfactor := 1/3 ; + +vardef xy_bottom (expr x, y, z, t) = + i_point (x, y, ((0,0)--(0,-2)) shifted (zfactor*z*xysx[x][y],0), "bottom") + shifted(0,-trimmed(x,y,grid_height,t)) +enddef ; + +vardef xy_top (expr x, y, z, t) = + i_point (x, y, ((0,0)--(0,2)) shifted (zfactor*z*xysx[x][y],0), "top") + shifted(0,trimmed(x,y,grid_height,t)) +enddef ; + +vardef xy_left (expr x, y, z, t) = + i_point (x, y, ((0,0)--(-2,0)) shifted (0,zfactor*z*xysy[x][y]), "left") + shifted(-trimmed(x,y,grid_width,t),0) +enddef ; + +vardef xy_right (expr x, y, z, t) = + i_point (x, y, ((0,0)--(2,0)) shifted (0,zfactor*z*xysy[x][y]), "right") + shifted(trimmed(x,y,grid_width,t),0) +enddef ; + +def flush_shapes = + for x=1 upto max_x : + for y=1 upto max_y : + flush_shape (x, y) ; + endfor ; + endfor ; +enddef ; + +def flush_pictures = + for x=1 upto max_x : + for y=1 upto max_y : + flush_picture (x, y) ; + endfor ; + endfor ; +enddef ; + + +def draw_connection_point (expr x, y, z) = + pickup pencircle scaled if (z=0): 2 fi xyline[x][y] ; + drawdot xy_bottom(x,y,z,false) scaled_to_grid withcolor (1,0,0) ; + drawdot xy_top (x,y,z,false) scaled_to_grid withcolor (0,1,0) ; + drawdot xy_left (x,y,z,false) scaled_to_grid withcolor (0,0,1) ; + drawdot xy_right (x,y,z,false) scaled_to_grid withcolor (1,1,0) ; +enddef ; + +def flush_shape (expr x, yy) = + begingroup ; + save y ; + y := y_pos(yy) ; + if not xyfree[x][y] : + pickup pencircle scaled xyline[x][y] ; + if xypeep[x][y] : + fill (xypath[x][y] peepholed (unitsquare shifted (x,y))) + scaled_to_grid withpen pencircle scaled 0 + withcolor chart_background_color ; + else : + fill xypath[x][y] scaled_to_grid withcolor xyfill[x][y] ; + fi ; + draw xypath[x][y] scaled_to_grid withcolor xydraw[x][y] ; + if show_con_points or show_all_points : + draw_connection_point (x, y, 0) ; + fi ; + if show_all_points : + for i=-1 upto 1 : + draw_connection_point (x, y, i) ; + endfor ; + fi ; + fi ; + endgroup ; +enddef ; + +vardef points_initialized (expr xfrom, yfrom, xto, yto, n) = + if not xyfree[xfrom][yfrom] and not xyfree[xto][yto] : + xypoint := n ; true + else : + xypoint := 0 ; false + fi +enddef ; + +def collapse_points = + % remove redundant points + n := 1 ; + for i=2 upto xypoint: + if not (xypoints[i]=xypoints[n]) : + n := n + 1 ; + xypoints[n] := xypoints[i] + fi ; + endfor ; + xypoint := n ; + % make straight lines + if xypoints[2]=xypoints[xypoint-1] : + xypoints[3] := xypoints[xypoint] ; + xypoint := 3 ; + fi ; +enddef ; + +vardef smooth_connection (expr a,b) = + sx := connection_smooth_size/grid_width ; + sy := connection_smooth_size/grid_height ; + if ypart a = ypart b : + a shifted (if xpart a >= xpart b : - fi sx,0) +% a shifted (sx*xpart unitvector(b-a),0) + else : + a shifted (0,if ypart a >= ypart b : - fi sy) +% a shifted (0,sy*ypart unitvector(b-a)) + fi +enddef ; + +vardef trim_points = + begingroup + save p, a, b, d, i ; path p ; pair d ; + p := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; + if touchshape : + a := shape_line_width/grid_width ; + b := shape_line_width/grid_height ; + else : + a := epsilon ; + b := epsilon ; + fi ; + d := direction infinity of p ; + xypoints[xypoint] := xypoints[xypoint] shifted + if xpart d < 0 : (+a,0) ; + elseif xpart d > 0 : (-a,0) ; + elseif ypart d < 0 : (0,+b) ; + elseif ypart d > 0 : (0,-b) ; + else : origin ; + fi ; + d := direction 0 of p ; + xypoints[1] := xypoints[1] shifted + if xpart d < 0 : (-a,0) ; + elseif xpart d > 0 : (+a,0) ; + elseif ypart d < 0 : (0,-b) ; + elseif ypart d > 0 : (0,+b) ; + else : origin ; + fi ; + endgroup +enddef ; + +vardef trim_points = enddef ; + +vardef connection_path = + if reverse_connection : reverse fi (xypoints[1]-- + for i=2 upto xypoint-1 : + if smooth : + smooth_connection(xypoints[i],xypoints[i-1]) .. + controls xypoints[i] and xypoints[i] .. + smooth_connection(xypoints[i],xypoints[i+1]) -- + else : + xypoints[i]-- + fi + endfor + xypoints[xypoint]) +enddef ; + +% vardef connection_path = +% sx := connection_smooth_size/grid_width ; +% sy := connection_smooth_size/grid_height ; +% if reverse_connection : reverse fi +% (for i=1 upto xypoint-1 : xypoints[i] -- endfor xypoints[xypoint]) +% if smooth : cornered max(sx,sy) fi +% enddef ; +% +% primarydef p cornered c = +% if cycle p : +% ((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) +% else : +% ((point 0 of p) -- +% for i=1 upto length(p)-1 : +% (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 +% (point length(p) of p)) +% fi +% enddef ; + +def draw_connection = + if xypoint>0 : + collapse_points ; + trim_points ; + cpath := cpath + 1 ; + cpaths[cpath] := connection_path scaled_to_grid ; + cline[cpath] := connection_line_width ; + ccolor[cpath] := connection_line_color ; + carrow[cpath] := arrowtip ; + cdash[cpath] := dashline ; + ccross[cpath] := showcrossing ; + else : + message("no connection defined") ; + fi ; + reverse_connection := false ; +enddef ; + +def flush_connections = + pair ip ; + boolean crossing ; + ahlength := connection_arrow_size ; + dash_pattern := dashpattern(on connection_dash_size off connection_dash_size ) ; + for i=1 upto cpath : + if ccross[i] : + crossing := false ; + for j=1 upto i : + %if not ((point infinity of cpaths[i] = point infinity of cpaths[j]) or + % (point 0 of cpaths[i] = point 0 of cpaths[j])) : + if not (point infinity of cpaths[i] = point infinity of cpaths[j]) : + ip := cpaths[i] intersection_point cpaths[j] ; + if intersection_found : crossing := true fi ; + fi ; + endfor ; + if crossing : + pickup pencircle scaled 2cline[i] ; + %draw cpaths[i] withcolor chart_background_color ; + path cp ; cp := cpaths[i] ; + cp := cp cutbefore point .05 length cp of cp ; + cp := cp cutafter point .95 length cp of cp ; + draw cp withcolor chart_background_color ; + fi ; + fi ; + pickup pencircle scaled cline[i] ; + if carrow[i] : + if cdash[i] : + drawarrow cpaths[i] withcolor ccolor[i] dashed dash_pattern ; + else : + drawarrow cpaths[i] withcolor ccolor[i] ; + fi ; + else : + if cdash[i] : + draw cpaths[i] withcolor ccolor[i] dashed dash_pattern ; + else : + draw cpaths[i] withcolor ccolor[i] ; + fi ; + fi ; + draw_midpoint (i) ; + endfor ; +enddef ; + +def draw_midpoint (expr n) = + begingroup + save p ; + pair p ; + p := point .5*length(cpaths[n]) of cpaths[n]; + pickup pencircle scaled 2cline[n] ; + save_text_position (p) ; + if show_mid_points : + drawdot p withcolor .7white ; + fi ; + endgroup ; +enddef ; + +def flush_picture(expr x, y) = + if known xypicture[x][y]: + draw xypicture[x][y] shifted xy_offset((x+0.5)*grid_width,(max_y-y+1.5)*grid_height) ; + fi ; +enddef ; + +def chart_draw_picture(expr x, y, p) = + xypicture[x][y] := p ; +enddef ; + +boolean reverse_connection ; reverse_connection := false ; + +vardef up_on_grid (expr n) = + (xpart xypoints[n],(ypart xypoints[n]+1) div 1) +enddef ; + +vardef down_on_grid (expr n) = + (xpart xypoints[n],(ypart xypoints[n]) div 1) +enddef ; + +vardef left_on_grid (expr n) = + ((xpart xypoints[n]) div 1, ypart xypoints[n]) +enddef ; + +vardef right_on_grid (expr n) = + ((xpart xypoints[n]+1) div 1, ypart xypoints[n]) +enddef ; + +vardef x_on_grid (expr n, xfrom, xto, zfrom) = + if (xfrom=xto) and not (zfrom=0) : + if (zfrom=1) : right_on_grid(2) else : left_on_grid(2) fi + elseif xpart xypoints[1] < xpart xypoints[6] : + right_on_grid(n) + else : + left_on_grid(n) + fi +enddef ; + +vardef y_on_grid (expr n, yfrom, yto, zfrom) = + if (yfrom=yto) and not (zfrom=0) : + if (zfrom=1) : up_on_grid(2) else : down_on_grid(2) fi + elseif ypart xypoints[1] < ypart xypoints[6] : + up_on_grid(n) + else : + down_on_grid(n) + fi +enddef ; + +vardef xy_on_grid (expr n, m) = + (xpart xypoints[n], ypart xypoints[m]) +enddef ; + +vardef down_to_grid (expr a,b) = + (xpart xypoints[a], + ypart xypoints[if ypart xypoints[a]ypart xypoints[b]:a else:b fi]) +enddef ; + +vardef left_to_grid (expr a,b) = + (xpart xypoints[if xpart xypoints[a]xpart xypoints[b]:a else:b fi], + ypart xypoints[a]) +enddef ; + +% vardef boundingboxfraction(expr p, f) = +% ((boundingbox p) enlarged (-f*bbwidth(p),-f*bbheight(p))) +% enddef ; + +vardef valid_connection (expr xfrom, yfrom, xto, yto) = + begingroup ; + save ok, vc, pp ; + boolean ok ; + % check for slanted lines + ok := true ; + for i=1 upto xypoint-1 : + if not ((xpart xypoints[i]=xpart xypoints[i+1]) or + (ypart xypoints[i]=ypart xypoints[i+1])) : ok := false ; + fi ; + endfor ; + if not ok : + %message("slanted"); + false + elseif forcevalid : + %message("force"); + true + elseif (xfrom=xto) and (yfrom=yto) : + %message("self"); + false + else : + % check for crossing shapes + pair vc ; + path pp ; + + pair xyfirst, xylast ; + xyfirst := xypoints[1] ; + xylast := xypoints[xypoint] ; + trim_points ; + pp := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; + xypoints[1] := xyfirst ; + xypoints[xypoint] := xylast ; + + for i=1 upto max_x : + for j=1 upto max_y : % was bug: xfrom,yto + if not ( ( (i,j)=(xfrom,yfrom) ) or ( (i,j)=(xto,yto) ) ) : + if not xyfree[i][j] : + vc := pp intersection_point xypath[i][j] ; + if intersection_found : ok := false fi ; + fi ; + fi ; + endfor ; + endfor ; + %if not ok: message("crossing") ; fi ; + ok + fi + endgroup +enddef ; + +def connect_top_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := up_on_grid(1) ; + xypoints[5] := down_on_grid(6) ; + xypoints[3] := up_to_grid(2,5) ; + xypoints[4] := up_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + %%%% begin experiment + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + xypoints[4] := xypoints[4] shifted (dsp_x,0) ; + if dsp_y>0 : + xypoints[2] := xypoints[2] shifted (0,dsp_y) ; + xypoints[3] := xypoints[3] shifted (0,dsp_y) ; + elseif dsp_y<0 : + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + xypoints[5] := xypoints[5] shifted (0,dsp_y) ; + fi + %%%% end experiment + draw_connection ; + fi ; +enddef ; + +def connect_left_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_right(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[5] := right_on_grid(6) ; + xypoints[3] := left_to_grid(2,5) ; + xypoints[4] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_top(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[4] := up_on_grid(5) ; + xypoints[3] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[4] := down_on_grid(5) ; + xypoints[3] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_top(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[4] := up_on_grid(5) ; + xypoints[3] := right_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[4] := down_on_grid(5) ; + xypoints[3] := right_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + %%%% begin experiment + xypoints[2] := xypoints[2] shifted (dsp_x,0) ; + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + if dsp_y>0 : + xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; + xypoints[4] := xypoints[4] shifted (0,-dsp_y) ; + elseif dsp_y<0 : + xypoints[3] := xypoints[3] shifted (0,dsp_y) ; + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + fi + %%%% end experiment + draw_connection ; + fi ; +enddef ; + +def connect_left_left (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_left(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[5] := left_on_grid(6) ; + xypoints[3] := left_to_grid(2,5) ; + xypoints[4] := left_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_right(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[5] := right_on_grid(6) ; + xypoints[3] := right_to_grid(2,5) ; + xypoints[4] := right_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_top_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_top(xto,yto,zto,true) ; + xypoints[2] := up_on_grid(1) ; + xypoints[5] := up_on_grid(6) ; + xypoints[3] := up_to_grid(2,5) ; + xypoints[4] := up_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_bottom_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_bottom(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := down_on_grid(1) ; + xypoints[5] := down_on_grid(6) ; + xypoints[3] := down_to_grid(2,5) ; + xypoints[4] := down_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + %%%% begin experiment + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + xypoints[4] := xypoints[4] shifted (dsp_x,0) ; + if dsp_y<0 : + xypoints[2] := xypoints[2] shifted (0,-dsp_y) ; + xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; + elseif dsp_y>0 : + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + xypoints[5] := xypoints[5] shifted (0,dsp_y) ; + fi + %%%% end experiment + draw_connection ; + fi ; +enddef ; + +def connect_bottom_top (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_top_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_right_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_right (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_top_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_bottom_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_top_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_right_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_bottom_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_right_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def draw_test_shape (expr x, y) = + draw_shape(x,y,fullcircle, .7, .7) ; +enddef ; + +def draw_test_shapes = + for i=1 upto max_x : + for j=1 upto max_y : + draw_test_shape(i,j) ; + endfor ; + endfor ; +enddef; + +def draw_test_area = + pickup pencircle scaled .5shape_line_width ; + draw (unitsquare xscaled max_x yscaled max_y shifted (1,1)) + scaled_to_grid withcolor blue ; +enddef ; + +def show_connection (expr n, m) = + + begin_chart(100+n,6,6) ; + + draw_test_area ; + + smooth := true ; + arrowtip := true ; + dashline := true ; + + draw_test_shape(2,2) ; draw_test_shape(4,5) ; + draw_test_shape(3,3) ; draw_test_shape(5,1) ; + draw_test_shape(2,5) ; draw_test_shape(1,3) ; + draw_test_shape(6,2) ; draw_test_shape(4,6) ; + + if (m=1) : + connect_top_bottom (2,2,0) (4,5,0) ; + connect_top_bottom (3,3,0) (5,1,0) ; + connect_top_bottom (2,5,0) (1,3,0) ; + connect_top_bottom (6,2,0) (4,6,0) ; + elseif (m=2) : + connect_top_top (2,2,0) (4,5,0) ; + connect_top_top (3,3,0) (5,1,0) ; + connect_top_top (2,5,0) (1,3,0) ; + connect_top_top (6,2,0) (4,6,0) ; + elseif (m=3) : + connect_bottom_bottom (2,2,0) (4,5,0) ; + connect_bottom_bottom (3,3,0) (5,1,0) ; + connect_bottom_bottom (2,5,0) (1,3,0) ; + connect_bottom_bottom (6,2,0) (4,6,0) ; + elseif (m=4) : + connect_left_right (2,2,0) (4,5,0) ; + connect_left_right (3,3,0) (5,1,0) ; + connect_left_right (2,5,0) (1,3,0) ; + connect_left_right (6,2,0) (4,6,0) ; + elseif (m=5) : + connect_left_left (2,2,0) (4,5,0) ; + connect_left_left (3,3,0) (5,1,0) ; + connect_left_left (2,5,0) (1,3,0) ; + connect_left_left (6,2,0) (4,6,0) ; + elseif (m=6) : + connect_right_right (2,2,0) (4,5,0) ; + connect_right_right (3,3,0) (5,1,0) ; + connect_right_right (2,5,0) (1,3,0) ; + connect_right_right (6,2,0) (4,6,0) ; + elseif (m=7) : + connect_left_top (2,2,0) (4,5,0) ; + connect_left_top (3,3,0) (5,1,0) ; + connect_left_top (2,5,0) (1,3,0) ; + connect_left_top (6,2,0) (4,6,0) ; + elseif (m=8) : + connect_left_bottom (2,2,0) (4,5,0) ; + connect_left_bottom (3,3,0) (5,1,0) ; + connect_left_bottom (2,5,0) (1,3,0) ; + connect_left_bottom (6,2,0) (4,6,0) ; + elseif (m=9) : + connect_right_top (2,2,0) (4,5,0) ; + connect_right_top (3,3,0) (5,1,0) ; + connect_right_top (2,5,0) (1,3,0) ; + connect_right_top (6,2,0) (4,6,0) ; + else : + connect_right_bottom (2,2,0) (4,5,0) ; + connect_right_bottom (3,3,0) (5,1,0) ; + connect_right_bottom (2,5,0) (1,3,0) ; + connect_right_bottom (6,2,0) (4,6,0) ; + fi ; + + end_chart ; + +enddef ; + +def show_connections = + for f=1 upto 10 : + show_connection(f,f) ; + endfor ; +enddef ; + +%D charts + +def clip_chart (expr minx, miny, maxx, maxy) = + cmin_x := minx ; + cmax_x := maxx ; + cmin_y := miny ; + cmax_y := maxy ; +enddef ; + +def begin_chart (expr n, maxx, maxy) = + new_chart ; + chart_figure := n ; + chart_scale := 1 ; + if chart_figure>0: beginfig(chart_figure) ; fi ; + startsavingdata ; + initialize_grid (maxx, maxy) ; + bboxmargin := 0 ; + cmin_x := 1 ; + cmax_x := maxx ; + cmin_y := 1 ; + cmax_y := maxy ; +enddef ; + +def end_chart = + flush_shapes ; + flush_connections ; + flush_pictures ; + cmin_x := cmin_x ; + cmax_x := cmin_x+cmax_x ; + cmin_y := cmin_y-1 ; + cmax_y := cmin_y+cmax_y ; + if reverse_y : + cmin_y := y_pos(cmin_y) ; + cmax_y := y_pos(cmax_y) ; + fi ; + path p ; + p := (((cmin_x,cmin_y)--(cmax_x,cmin_y)-- + (cmax_x,cmax_y)--(cmin_x,cmax_y)--cycle)) + scaled_to_grid ; + %draw p withcolor red ; + p := p enlarged chart_offset ; + clip currentpicture to p ; + setbounds currentpicture to p ; + savedata + "\MPclippath{" & + decimal xpart llcorner p & "}{" & + decimal ypart llcorner p & "}{" & + decimal xpart urcorner p & "}{" & + decimal ypart urcorner p & "}%" ; + savedata + "\MPareapath{" & + decimal (xpart llcorner p + 2chart_offset) & "}{" & + decimal (ypart llcorner p + 2chart_offset) & "}{" & + decimal (xpart urcorner p - 2chart_offset) & "}{" & + decimal (ypart urcorner p - 2chart_offset) & "}%" ; + currentpicture := currentpicture scaled chart_scale ; + stopsavingdata ; + if chart_figure>0: endfig ; fi ; +enddef ; + +def new_shape (expr x, y, n) = + if known n : + if (x>0) and (x<=max_x) and (y>0) and (y<=max_y) : + sx := shape_width/grid_width ; + sy := shape_height/grid_height ; + draw_shape(x,y,some_shape_path(n), sx, sy) ; + else : + message ("shape outside grid ignored") ; + fi ; + else + message ("shape not known" ) ; + fi ; +enddef ; + +def begin_sub_chart = + begingroup ; + save shape_line_width , connection_line_width ; + save shape_line_color, shape_fill_color, connection_line_color ; + color shape_line_color, shape_fill_color, connection_line_color ; + save smooth, arrowtip, dashline, peepshape ; + boolean smooth, arrowtip, dashline, peepshape ; +enddef ; + +def end_sub_chart = + endgroup ; +enddef ; + +% show_shapes(100) ; +% +% show_connections ; +% +% begin_chart (1,4,5) ; +% %clip_chart(1,1,1,2) ; +% new_shape (1,1,31) ; +% new_shape (1,2,3) ; +% new_shape (4,4,5) ; +% connect_top_left (1,1,0) (4,4,0) ; +% connect_bottom_top (1,2,0) (4,4,0) ; +% connect_left_right (1,2,0) (1,1,0) ; +% end_chart ; diff --git a/metapost/context/base/mpii/mp-core.mpii b/metapost/context/base/mpii/mp-core.mpii new file mode 100644 index 000000000..33e9b386e --- /dev/null +++ b/metapost/context/base/mpii/mp-core.mpii @@ -0,0 +1,1418 @@ +if known context_core : endinput ; fi ; + +boolean context_core ; context_core := true ; + +pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; +path pxy[] ; +numeric hxy[], wxy[], dxy[], nxy[] ; + +def box_found (expr n,x,y,w,h,d) = + not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) +enddef ; + +def initialize_box_pos (expr pos,n,x,y,w,h,d) = + pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; + path pxy ; numeric hxy, wxy, dxy, nxy; + lxy := (x,y) ; + llxy := (x,y-d) ; + lrxy := (x+w,y-d) ; + urxy := (x+w,y+h) ; + ulxy := (x,y+h) ; + wxy := w ; + hxy := h ; + dxy := d ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; + nxy := n ; + freeze_box(pos) ; +enddef ; + +def freeze_box (expr pos) = + lxy[pos] := lxy ; + llxy[pos] := llxy ; + lrxy[pos] := lrxy ; + urxy[pos] := urxy ; + ulxy[pos] := ulxy ; + wxy[pos] := wxy ; + hxy[pos] := hxy ; + dxy[pos] := dxy ; + rxy[pos] := rxy ; + pxy[pos] := pxy ; + cxy[pos] := cxy ; + nxy[pos] := nxy ; +enddef ; + +def initialize_box (expr n,x,y,w,h,d) = + + numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; + +enddef ; + +def initialize_area (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + + do_initialize_area (fpos, tpos) ; + +enddef ; + +def do_initialize_area (expr fpos, tpos) = + lxy := lxy[fpos] ; + llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; + lrxy := lrxy[tpos] ; + urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; + ulxy := ulxy[fpos] ; + wxy := xpart lrxy - xpart llxy ; + hxy := hxy[fpos] ; + dxy := dxy[tpos] ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; +enddef ; + +def set_par_line_height (expr ph, pd) = + par_strut_height := + if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ; + par_strut_depth := + if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ; + par_line_height := + par_strut_height + par_strut_depth ; +enddef ; + +def initialize_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + mn,mx,my,mw,mh,md, + pn,px,py,pw,ph,pd, + rw,rl,rr,rh,ra,ri) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; + numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (ph, pd) ; + + do_initialize_area (fpos, tpos) ; + do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; + +enddef ; + +def initialize_area_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + wn,wx,wy,ww,wh,wd) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (wh, wd) ; + + numeric ffpos ; ffpos := 4 ; initialize_box_pos(ffpos,wn,wx,fy,0,wh,wd) ; + numeric ttpos ; ttpos := 5 ; initialize_box_pos(ttpos,wn,wx+ww,ty,0,wh,wd) ; + + do_initialize_area (ffpos, ttpos) ; + + numeric mpos ; mpos := 6 ; freeze_box(mpos) ; + + do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; + +enddef ; + +def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = + + pair lref, rref, pref, lhref, rhref ; + + % clip the page area to the left and right skips + + llxy[mpos] := llxy[mpos] shifted (+rl,0) ; + lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; + urxy[mpos] := urxy[mpos] shifted (-rr,0) ; + ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; + + % fixate the leftskip, rightskip and hanging indentation + + lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; + rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; + + pref := lxy[ppos] ; + + if nxy[tpos] > nxy[fpos] : + if nxy[fpos] = nxy[mpos] : + % first of multiple pages + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := down ; + elseif nxy[tpos] = nxy[mpos] : + % last of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + boxgriddirection := up ; + else : + % middle of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := up ; + fi ; + else : + % just one page + boxgriddirection := up ; + fi ; + + path txy, bxy, pxy, mxy ; + + txy := originpath ; % top + bxy := originpath ; % bottom + pxy := originpath ; % composed + + boolean lefthang, righthang, somehang ; + + % we only hang on the first of a multiple page background + + if nxy[mpos] > nxy[fpos] : + lefthang := righthang := somehang := false ; + else : + lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; + fi ; + + if lefthang : + mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; + elseif righthang : + mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; + else : + mxy := originpath ; + fi ; + + if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : + + % We have a one-liner. Watch how er use the bottom pos for + % determining the height. + + llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; + ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; + + else : + + % We have a multi-liner. For convenience we now correct the + % begin and end points for indentation. + + if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : + llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; + else : + llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; + fi ; + + if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : + lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; + else : + lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; + fi ; + + fi ; + + somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and + (ypart llxy[tpos]0 : + left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; + right_skip := rw - left_skip - ww ; + else : + left_skip := rl ; + right_skip := rr ; + fi ; + + path multipar, multipars[] ; + numeric multiref, multirefs[] ; + numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end + + numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; + + % locals .. why can't i move these outside? + +vardef _pmp_set_multipar_ (expr i) = + ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip + if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) +enddef ; + +vardef _pmp_snapped_multi_pos_ (expr p) = + if snap_multi_par_tops : + if abs(ypart p - ypart ulcorner multipar) < par_line_height : + (xpart p,ypart ulcorner multipar) + else : + p + fi + else : + p + fi +enddef ; + +vardef _pmp_estimated_par_lines_ (expr h) = + round(h/par_line_height) +enddef ; + +vardef _pmp_top_multi_par_(expr p) = + (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p))) +enddef ; + +vardef _pmp_multi_par_tsc_(expr p) = + if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi +enddef ; + +vardef _pmp_estimated_multi_par_height_ (expr n, t) = + if round(par_line_height)=0 : + 0 + else : + save ok, h ; boolean ok ; + numeric h ; h := 0 ; + ok := false ; + if (nxy[fpos]=RealPageNumber-1) : + for i := 1 upto NOfSavedTextAreas : + if (InsideSavedTextArea(i,par_start_pos)) : + ok := true ; + h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - + ypart llcorner SavedTextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ; + fi ; + endfor ; + fi ; + if ok : + for i := 1 upto n-1 : + h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; + endfor ; + else : + % already: ok := false ; + for i := 1 upto n-1 : + if (InsideTextArea(i,par_start_pos)) : + ok := true ; + h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; + fi ; + endfor ; + fi ; + h + fi +enddef ; + +vardef _pmp_left_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; + + if (par_hang_indent>0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ul_ ; _ul_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])); + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llxy[tpos])) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _ul_ + par_hang_indent, ypart lrxy[fpos]) -- + (xpart _ul_ + par_hang_indent, ypart _pa_) -- + (xpart ulcorner multipar, ypart _pa_) + else : + (xpart ulcorner multipar, ypart lrxy[fpos]) + fi +enddef ; + +vardef _pmp_right_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; + + if (par_hang_indent<0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ur_ ; _ur_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; + pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart urcorner multipar, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart _pmp_snapped_multi_pos_(urxy[fpos])) + else : + (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) + fi +enddef ; + +vardef _pmp_x_left_top_hang_ (expr i, t) = + par_hang_after := min(0,ra + _pmp_estimated_multi_par_height_(i,t)) ; + if (par_hang_indent>0) and (par_hang_after<0) : + pair _ul_ ; _ul_ := ulcorner multipar ; + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if t : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos])); + fi ; + if abs(ypart _pa_-ypart llxy[tpos])0) and (par_hang_after>0) and obey_multi_par_hang : + _ll_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])) ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + _pa_ -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + (xpart _pa_ + par_hang_indent,ypart _sa_) + else : + (xpart llcorner multipar, ypart _sa_) + fi +enddef ; + +vardef _pmp_right_bottom_hang_ (expr same_area) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if same_area : _pmp_snapped_multi_pos_(ulxy[tpos]) else : lrcorner multipar fi ; + if (par_hang_indent<0) and (par_hang_after>0) and obey_multi_par_hang : + _lr_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + _pa_ + else : + (xpart lrcorner multipar, ypart _sa_) + fi +enddef ; + +vardef _pmp_x_left_bottom_hang_ (expr i, t) = + pair _ll_, _sa_, _pa_ ; + _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; + if (par_hang_indent>0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i,t)) ; + _ll_ := ulcorner multipar ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + fi + _pa_ + else : + (xpart llcorner multipar, ypart _sa_) + fi +enddef ; + +vardef _pmp_x_right_bottom_hang_ (expr i, t) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ; + if (par_hang_indent<0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i, t)) ; + _lr_ := urcorner multipar ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + _pa_ + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + -- (xpart _pa_ + par_hang_indent,ypart _pa_) + -- (xpart _pa_ + par_hang_indent,ypart _sa_) + fi + else : + (xpart lrcorner multipar, ypart _sa_) + fi +enddef ; + +% def _pmp_test_multipar_ = +% multipar := boundingbox multipar ; +% enddef ; + + % first loop + + ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; + + if enable_multi_par_fallback and + (nxy[fpos]=RealPageNumber) and + (nxy[tpos]=RealPageNumber) and not + (InsideSomeTextArea(lxy[fpos]) and + InsideSomeTextArea(rxy[tpos])) : + + % fallback + + % multipar := + % llxy[fpos] -- + % lrxy[tpos] -- + % urxy[tpos] -- + % ulxy[fpos] -- cycle ; + % + % save_multipar (1,1,multipar) ; + + % we need to take the boundingbox because there can be + % more lines and we want a proper rectange + + multipar := + ulxy[fpos] -- + urxy[tpos] -- + lrxy[fpos] -- + llxy[tpos] -- cycle ; + + save_multipar (1,1,boundingbox(multipar)) ; + + else : + + % normal + + for i=1 upto NOfTextAreas : + + TopSkipCorrection := 0 ; + + multipar := _pmp_set_multipar_(i) ; + + % watch how we compensate for negative indentation + + if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) : + + % first one in chain + + ii := i ; + +% if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : + if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % in same area + + nn := i ; + + if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : + + TopSkipCorrection := TopSkip - StrutHeight ; + + if round(ypart ulxy[fpos] + TopSkipCorrection) = + round(ypart ulcorner TextAreas[i]) : + ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ; + urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ; + else : + TopSkipCorrection := 0 ; + fi ; + + fi ; + + if ypart llxy[fpos] = ypart llxy[tpos] : + + multipar := + llxy[fpos] -- + lrxy[tpos] -- + %urxy[tpos] -- + _pmp_snapped_multi_pos_(urxy[tpos]) -- + %ulxy[fpos] -- + _pmp_snapped_multi_pos_(ulxy[fpos]) -- + cycle ; + + save_multipar (i,1,multipar) ; + + elseif (ypart llxy[fpos] = ypart ulxy[tpos]) and + (xpart llxy[tpos] < xpart llxy[fpos]) : + + % two loners + + multipar := if obey_multi_par_hang : + + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + + else : + + llxy[fpos] -- + (xpart urcorner multipar, ypart llxy[fpos]) -- + (xpart urcorner multipar, ypart ulxy[fpos]) -- + _pmp_snapped_multi_pos_(ulxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + multipar := _pmp_set_multipar_(i) ; + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart llcorner multipar, ypart ulxy[tpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + %ulxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + %ulxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart lrcorner multipar, ypart ulxy[tpos]) -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(false) -- + _pmp_right_bottom_hang_(false) -- + _pmp_right_top_hang_(false) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(false) -- + + else : + + llcorner multipar -- + lrcorner multipar -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + +% elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : + elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % last one in chain + + nn := i ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,true) -- + _pmp_x_right_top_hang_(i,true) -- + _pmp_x_right_bottom_hang_(i,true) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + _pmp_x_left_bottom_hang_(i,true) -- + cycle ; + + else : + + multipar := + ulcorner multipar -- + urcorner multipar -- + (xpart lrcorner multipar, ypart urxy[tpos]) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + (xpart llcorner multipar, ypart llxy[tpos]) -- + cycle ; + + fi ; + + save_multipar (i,3,multipar) ; + + elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) : % and (NOfTextColumns>1)) : + + save_multipar (i,2,multipar) ; + + else : + % handled later + fi ; + + endfor ; + + % second loop + + if force_multi_par_chain or (ii > 1) : + + for i=ii+1 upto nn-1 : + + % rest of chain / todo : hang + +% hm, the second+ column in column sets now gets lost in a NOfTextColumns + + if (not check_multi_par_chain) or + ((nxy[fpos]RealPageNumber)) + : + + multipar := _pmp_set_multipar_(i) ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,false) -- + _pmp_x_right_top_hang_(i,false) -- + _pmp_x_right_bottom_hang_(i,false) -- + _pmp_x_left_bottom_hang_(i,false) -- + cycle ; + + fi ; + + save_multipar(i,2,multipar) ; + + fi ; + + endfor ; + + fi ; + + % end of normal/fallback + +fi ; + +% if span_multi_column_pars : +% endgroup ; +% fi ; + + % potential safeguard: + + % for i=1 upto nofmultipars : + % if length p <= 4 : + % multipars[i] := boundingbox(multipars[i]) ; + % fi ; + % end ; + + % quick hack for gb: + + one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; + +enddef ; + +color boxgridcolor ; boxgridcolor := .8red ; +color boxlinecolor ; boxlinecolor := .8blue ; +color boxfillcolor ; boxfillcolor := .8white ; +numeric boxgridtype ; boxgridtype := 0 ; +numeric boxlinetype ; boxlinetype := 1 ; +numeric boxfilltype ; boxfilltype := 1 ; +numeric boxdashtype ; boxdashtype := 0 ; +pair boxgriddirection ; boxgriddirection := up ; +numeric boxgridwidth ; boxgridwidth := 1pt ; +numeric boxlinewidth ; boxlinewidth := 1pt ; +numeric boxlineradius ; boxlineradius := 0pt ; +numeric boxfilloffset ; boxfilloffset := 0pt ; +numeric boxgriddistance ; boxgriddistance := .5cm ; +numeric boxgridshift ; boxgridshift := 0pt ; + +def draw_box = + draw pxy withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; + draw lxy -- rxy withcolor boxlinecolor withpen pencircle scaled boxgridwidth ; +enddef ; + +def draw_par = % 1 2 3 11 12 + do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ; + for i = pxy, txy, bxy : + if boxgridtype = 1 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; + elseif boxgridtype = 2 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,false) withcolor boxgridcolor ; + elseif boxgridtype = 3 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight) withcolor boxgridcolor ; + elseif boxgridtype = 4 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight/2) withcolor boxgridcolor ; + elseif boxgridtype = 11 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype = 12 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def do_show_par (expr p, r, c) = + if length(p) > 2 : for i=0 upto length(p) : + draw fullcircle scaled r shifted point i of p + withpen pencircle scaled .5pt withcolor c ; + endfor ; fi ; + draw p withpen pencircle scaled .5pt withcolor c ; +enddef ; + +def show_par = + if length(mxy) > 2 : + draw mxy dashed evenly + withpen pencircle scaled .5pt withcolor .5white ; + fi ; + do_show_par(txy, 4pt, .5green) ; + do_show_par(bxy, 6pt, .5blue ) ; + do_show_par(pxy, 8pt, .5red ) ; + draw pref withpen pencircle scaled 2pt ; +enddef ; + +def sort_multi_pars = + if nofmultipars>1 : + begingroup ; save _p_, _n_ ; path _p_ ; numeric _n_ ; + for i := 1 upto nofmultipars : + if multilocs[i] = 3 : + _p_ := multipars[nofmultipars] ; + multipars[nofmultipars] := multipars[i] ; + multipars[i] := _p_ ; + _n_ := multirefs[nofmultipars] ; + multirefs[nofmultipars] := multirefs[i] ; + multirefs[i] := _n_ ; + _n_ := multilocs[nofmultipars] ; + multilocs[nofmultipars] := multilocs[i] ; + multilocs[i] := _n_ ; + fi ; + endfor ; + endgroup ; + fi ; +enddef ; + + +def collapse_multi_pars = + if nofmultipars>1 : + begingroup ; save _nofmultipars_ ; numeric _nofmultipars_ ; + _nofmultipars_ := 1 ; + sort_multi_pars ; % block not in order: 1, 3, 2.... + for i:=1 upto nofmultipars-1 : + if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and + (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : +multilocs[_nofmultipars_] := multilocs[i+1] ; +multirefs[_nofmultipars_] := multirefs[i+1] ; + multipars[_nofmultipars_] := + ulcorner multipars[_nofmultipars_] -- + urcorner multipars[_nofmultipars_] -- + lrcorner multipars[i+1] -- + llcorner multipars[i+1] -- cycle ; + else : + _nofmultipars_ := _nofmultipars_ + 1 ; + multipars[_nofmultipars_] := multipars[i+1] ; + multilocs[_nofmultipars_] := multilocs[i+1] ; + multirefs[_nofmultipars_] := multirefs[i+1] ; + fi ; + endfor ; + nofmultipars := _nofmultipars_ ; + endgroup ; + fi ; +enddef ; + +% def draw_multi_pars = +% for i=1 upto nofmultipars : +% do_draw_par(multipars[i]) ; +% if boxgridtype= 1 : +% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 2 : +% draw baseline_grid (multipars[i],up,false) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 3 : +% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; +% draw baseline_grid (multipars[i],up,true ) +% shifted (0,ExHeight) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 4 : +% draw baseline_grid (multipars[i],up,true ) +% shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; +% elseif boxgridtype=11 : +% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; +% elseif boxgridtype=12 : +% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; +% fi ; +% endfor ; +% enddef ; + +def draw_multi_pars = + for i=1 upto nofmultipars : + do_draw_par(multipars[i]) ; + if boxgridtype= 1 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; + elseif boxgridtype= 2 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; % withcolor boxgridcolor ; + elseif boxgridtype= 3 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; % withcolor boxgridcolor ; + elseif boxgridtype= 4 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; + elseif boxgridtype=11 : + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype=12 : + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def show_multi_pars = + for i=1 upto nofmultipars : + do_show_par(multipars[i], 6pt, .5blue) ; + endfor ; +enddef ; + +vardef do_draw_par (expr p) = + if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : + save pp ; path pp ; + if (boxlineradius>0) and (boxlinetype=2) : + pp := p cornered boxlineradius ; + else : + pp := p ; + fi ; + if boxfilltype>0 : + if boxfilloffset>0 : + % temporary hack + begingroup ; interim linejoin := mitered ; + filldraw pp withcolor boxfillcolor withpen pencircle scaled (2*boxfilloffset) ; + endgroup ; + else : + fill pp withcolor boxfillcolor ; + fi ; + fi ; + if boxlinetype>0 : + draw pp withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; + fi ; + fi ; +enddef ; + +vardef baseline_grid (expr pxy, pdir, at_baseline) = + if (par_line_height>0) and (bbheight(pxy)>1) and (bbwidth(pxy)>1) and (boxgridwidth>0) : + save i, grid, bb ; picture grid ; pair start ; path bb ; + def _do_ (expr start) = + % 1 = normal, 2 = with background (i.e. no shine-through) + if boxdashtype = 2 : + draw start -- start shifted (bbwidth(pxy),0) + withpen pencircle scaled boxgridwidth + withcolor boxfillcolor ; + fi ; + draw start -- start shifted (bbwidth(pxy),0) + if boxdashtype > 0 : dashed evenly fi + withpen pencircle scaled boxgridwidth + withcolor boxgridcolor ; + enddef ; + grid := image + ( %fails with inlinespace + % + if pdir=up : + for i = if at_baseline : par_strut_depth else : 0 fi + step par_line_height + until max(bbheight(pxy),par_line_height) : + _do_ (llcorner pxy shifted (0,+i)) ; + endfor ; + else : + for i = if at_baseline : par_strut_height else : 0 fi + step par_line_height + until bbheight(pxy) : + _do_ (ulcorner pxy shifted (0,-i)) ; + endfor ; + fi ; + ) ; + clip grid to pxy ; + bb := boundingbox grid ; + grid := grid shifted (0,boxgridshift) ; + setbounds grid to bb ; + grid + else : + nullpicture + fi +enddef ; + +vardef graphic_grid (expr pxy, dx, dy, x, y) = + if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : + save grid ; picture grid ; + grid := image + ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy : + draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) + withpen pencircle scaled boxgridwidth ; + endfor ; + for i = ypart llcorner pxy step dy until ypart ulcorner pxy : + draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) + withpen pencircle scaled boxgridwidth ; + endfor ) shifted (x,y) ; + clip grid to pxy ; + grid + else : + nullpicture + fi +enddef ; + +def anchor_box (expr n,x,y,w,h,d) = + currentpicture := currentpicture shifted (-x,-y) ; +enddef ; + +let draw_area = draw_box ; +let anchor_area = anchor_box ; +let anchor_par = anchor_box ; + + +numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; +pair sync_xy[][] ; color sync_c[][] ; + +def ResetSyncTasks = + path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; + NOfSyncPaths := CurrentSyncClass := 0 ; + if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; + if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; + if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; + if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; + if (SyncLeftOffset = 0) and (SyncWidth = 0) : + SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; + fi ; +enddef ; + +ResetSyncTasks ; + +vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = + save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; + o shifted (leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,bottomoffset) -- + o shifted (leftoffset,bottomoffset) -- cycle +enddef ; + +def SetSyncColor(expr n, i, c) = + sync_c[n][i] := c ; +enddef ; + +def SetSyncThreshold(expr n, i, th) = + sync_th[n][i] := th ; +enddef ; + +vardef TheSyncColor(expr n, i) = + if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi +enddef ; + +vardef TheSyncThreshold(expr n, i) = + if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi +enddef ; + +vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = + ResetSyncTasks ; + if known sync_n[n] : + CurrentSyncClass := n ; + save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; + for i=1 upto sync_n[n] : + if RealPageNumber > sync_p[n][i] : + l := i ; + elseif RealPageNumber = sync_p[n][i] : + NOfSyncPaths := NOfSyncPaths + 1 ; + if not ok : + if i>1 : + if sync_t[n][i-1] = sync_t[n][i] : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i-1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + ok := true ; + fi ; + endfor ; + if (NOfSyncPaths = 0) and (l > 0) : + NOfSyncPaths := 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := l ; + fi ; + if NOfSyncPaths > 0 : + for i = 1 upto NOfSyncPaths-1 : + SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; + endfor ; + if unknown SyncThresholdMethod : + numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; + fi ; + if extendtop : + if SyncThresholdMethod = 1 : + if NOfSyncPaths>1 : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; + if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : + SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; + fi ; + fi ; + else : + for i = 1 upto NOfSyncPaths : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; + if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : + SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; + fi ; + endfor ; + fi ; + fi ; + if prestartnext : + if NOfSyncPaths>1 : + if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; + if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : + SyncPaths[NOfSyncPaths+1] := + (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + lrcorner SyncPaths[NOfSyncPaths] -- + llcorner SyncPaths[NOfSyncPaths] -- cycle ; + SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + fi ; + fi ; + fi ; + else : + if NOfSyncPaths>1 : + d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; + if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : + NOfSyncPaths := NOfSyncPaths - 1 ; + SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; + fi ; + fi ; + fi ; + if (NOfSyncPaths>1) and collapse : + save j ; numeric j ; j := 1 ; + for i = 2 upto NOfSyncPaths : + if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : + SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; + SyncTasks[j] := SyncTasks[i] ; + else : + j := j + 1 ; + SyncPaths[j] := SyncPaths[i] ; + SyncTasks[j] := SyncTasks[i] ; + fi ; + endfor ; + NOfSyncPaths := j ; + fi ; + fi ; + fi ; +enddef ; + +def SyncTask(expr n) = + if known SyncTasks[n] : SyncTasks[n] else : 0 fi +enddef ; + +def FlushSyncTasks = + for i = 1 upto NOfSyncPaths : + ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; + endfor ; +enddef ; + +def ProcessSyncTask(expr p, c) = + fill p withcolor c ; +enddef ; + +% for Jelle Huisman +% +% \setupcolors[state=start] +% \dontcomplain +% \definecolumnset[example][n=3,distance=5mm] +% \startMPextensions +% multi_column_first_page_hack := true ; +% \stopMPextensions +% \startuseMPgraphic{mpos:par:trick} +% for i=1 upto nofmultipars-1 : draw (rightboundary multipars[i]) shifted (2.5mm, 0) ; endfor ; +% \stopuseMPgraphic +% \definetextbackground[test][mp=mpos:par:trick,method=mpos:par:columnset] +% \starttext +% \definecolumnsetspan[chapter][n=3] +% \startcolumnset[example] +% \startcolumnsetspan[chapter] +% \chapter{Chapter One} +% \stopcolumnsetspan +% \starttextbackground[test] \dorecurse {3}{\input knuth } \stoptextbackground +% \stopcolumnset +% \startcolumnset[example] +% \startcolumnsetspan[chapter] +% \chapter{Chapter One} +% \stopcolumnsetspan +% \starttextbackground[test] \dorecurse {10}{\input knuth } \stoptextbackground +% \stopcolumnset +% \stoptext +% +% fast variant: +% +% \startuseMPgraphic{whatever} +% for i=1 upto NOfTextColumns-1 : +% draw (rightboundary TextColumns[i]) shifted (2.5mm,0) shifted -\MPxy\textanchor ; +% endfor ; +% setbounds currentpicture to OverlayBox ; +% \stopuseMPgraphic +% \defineoverlay[whatever][\useMPgraphic{whatever}] +% \setupbackgrounds[text][background=whatever] diff --git a/metapost/context/base/mpii/mp-figs.mpii b/metapost/context/base/mpii/mp-figs.mpii new file mode 100644 index 000000000..d4fcc2b35 --- /dev/null +++ b/metapost/context/base/mpii/mp-figs.mpii @@ -0,0 +1,47 @@ +%D \module +%D [ file=mp-figs.mpii, +%D version=2003.01.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=figures, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_figs : endinput ; fi ; + +boolean context_figs ; context_figs := true ; + +% todo: check defined + +def registerfigure(expr name,width,height) = + begingroup ; + save s ; string s ; s := cleanstring(name) ; + scantokens( s & "_width := " & decimal(width )) ; + scantokens( s & "_height := " & decimal(height)) ; + endgroup ; +enddef ; + +vardef figuresize(expr name) = + save s, p ; string s ; pair p ; + s := cleanstring(name) ; + scantokens( "p := " & "(" & s & "_width" & "," & s & "_height" & ")" ) ; + p +enddef ; + +vardef figurewidth(expr name) = + xpart figuresize(name) +enddef ; + +vardef figureheight(expr name) = + ypart figuresize(name) +enddef ; + +let figuredimensions = figuresize ; % for old times sake + +def naturalfigure(expr name) = + externalfigure name xyscaled(figuresize(name)) +enddef ; diff --git a/metapost/context/base/mpii/mp-fobg.mpii b/metapost/context/base/mpii/mp-fobg.mpii new file mode 100644 index 000000000..f8b709572 --- /dev/null +++ b/metapost/context/base/mpii/mp-fobg.mpii @@ -0,0 +1,87 @@ +%D \module +%D [ file=mp-fobg.mp, +%D version=2004.03.12, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=Formatting Objects, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_fobg : endinput ; fi ; + +boolean context_fobg ; context_fobg := true ; + +FoNone := 0 ; FoHidden := 1 ; FoDotted := 2 ; FoDashed := 3 ; FoSolid := 4 ; +FoDouble := 5 ; FoGroove := 6 ; FoRidge := 7 ; FoInset := 8 ; FoOutset := 9 ; +FoAll := 0 ; FoTop := 1 ; FoBottom := 2 ; FoLeft := 3 ; FoRight := 4 ; +FoMedium := .5pt ; FoThin := FoMedium/2 ; FoThick := FoMedium*2 ; + +color FoBackgroundColor, FoNoColor, FoLineColor[] ; FoNoColor := (-1,-1,-1) ; +numeric FoLineWidth[], FoLineStyle[] ; +boolean FoFrame, FoBackground, FoSplit ; + +FoFrame := FoBackground := FoSplit := false ; +FoBackgroundColor := white ; +FoDashFactor := .5 ; +FoDotFactor := .375 ; + +for i = FoAll upto FoRight : + FoLineColor[i] := black ; + FoLineWidth[i] := .5pt ; + FoLineStyle[i] := FoNone ; +endfor ; + +def DrawFoFrame(expr n, p) = + drawoptions(withcolor FoLineColor[n] withpen pencircle scaled FoLineWidth[n]) ; + if FoLineStyle[n] = FoNone : + % nothing + elseif FoLineStyle[n] = FoHidden : + % nothing + elseif FoLineStyle[n] = FoDotted : + draw p dashed (withdots scaled (FoDotFactor*FoLineWidth[n])) ; + elseif FoLineStyle[n] = FoDashed : + draw p dashed (evenly scaled (FoDashFactor*FoLineWidth[n])) ; + elseif FoLineStyle[n] = FoSolid : + draw p ; + elseif FoLineStyle[n] = FoDouble : + draw p enlarged FoLineWidth[n] ; draw p enlarged -FoLineWidth[n] ; + elseif FoLineStyle[n] = FoGroove : + draw p ; + draw p withpen pencircle scaled .5FoLineWidth[n] withcolor (inverted FoLineColor[n] softened .5) ; + elseif FoLineStyle[n] = FoRidge : + draw p withcolor (inverted FoLineColor[n] softened .5) ; + draw p withpen pencircle scaled .5FoLineWidth[n] ; + elseif FoLineStyle[n] = FoInset : + draw p ; draw p inset 2.5FoLineWidth[n] ; + elseif FoLineStyle[n] = FoOutset : + draw p ; draw p outset 2.5FoLineWidth[n] ; + fi ; +enddef ; + +primarydef p outset d = + ((lrcorner p -- urcorner p -- ulcorner p -- llcorner p -- cycle) + shifted (d*(-1,1)) cutbefore topboundary p) cutafter leftboundary p +enddef ; + +primarydef p inset d = + ((ulcorner p -- llcorner p -- lrcorner p -- urcorner p -- cycle) + shifted (d*(1,-1)) cutbefore bottomboundary p) cutafter rightboundary p +enddef ; + +vardef equalpaths(expr p, q) = + if length(p) = length(q) : + save ok ; boolean ok ; ok := true ; + for i = 0 upto length(p)-1 : + ok := ok and (round(point i of p) = round(point i of q)) ; + endfor ; + ok + else : + false + fi +enddef ; + +endinput ; diff --git a/metapost/context/base/mpii/mp-form.mpii b/metapost/context/base/mpii/mp-form.mpii new file mode 100644 index 000000000..d1dac32db --- /dev/null +++ b/metapost/context/base/mpii/mp-form.mpii @@ -0,0 +1,392 @@ +% Hans Hagen / October 2000 +% +% This file is mostly a copy from the file format.mp, that +% comes with MetaPost and is written by John Hobby. This file +% is meant to be compatible, but has a few more features, +% controlled by the variables: +% +% fmt_initialize when false, initialization is skipped +% fmt_precision the default accuracy (default=3) +% fmt_separator the pattern separator (default=%) +% fmt_zerocheck activate extra sci notation zero check +% +% instead of a picture, one can format a number in a for TeX +% acceptable input string + +boolean mant_font ; mant_font := true ; % signals graph not to load form + +if known context_form : endinput ; fi ; + +boolean context_form ; context_form := true ; + +if unknown fmt_metapost : boolean fmt_metapost ; fmt_metapost := true ; fi ; % == use old method +if unknown fmt_precision : numeric fmt_precision ; fmt_precision := 3 ; fi ; +if unknown fmt_initialize : boolean fmt_initialize ; fmt_initialize := true ; fi ; +if unknown fmt_separator : string fmt_separator ; fmt_separator := "%" ; fi ; +if unknown fmt_zerocheck : boolean fmt_zerocheck ; fmt_zerocheck := false ; fi ; + +% As said, all clever code is from John, the more stupid +% extensions are mine. The following string variables are +% responsible for the TeX formatting. + +% TeX specs when using TeX instead of pseudo TeX. + +string sFebraise_ ; sFebraise_ := "{" ; +string sFeeraise_ ; sFeeraise_ := "}" ; +string sFebmath_ ; sFebmath_ := "$" ; +string sFeemath_ ; sFeemath_ := "$" ; + +string sFmneg_ ; sFmneg_ := "-" ; +string sFemarker_ ; sFemarker_ := "{\times}10^" ; +string sFeneg_ ; sFeneg_ := "-" ; +string sFe_plus ; sFe_plus := "" ; % "+" + +def sFe_base = Fline_up_("1", sFemarker_) enddef ; + +% Macros for generating typeset pictures of computed numbers +% +% format(f,x) typeset generalized number x using format string f +% Mformat(f,x) like format, but x is in Mlog form (see marith.mp) +% init_numbers(s,m,x,sn,e) choose typeset style given sample sign, mantissa,... +% roundd(x,d) round numeric x to d places right of decimal point +% Fe_base what precedes the exponent for typeset powers of 10 +% Fe_plus plus sign if any for typesetting positive exponents +% Ten_to[] powers of ten for indices 0,1,2,3,4 +% +% New are: +% +% formatstr(f,x) TeX string representing x using format f +% Mformatstr(f,x) like Mformatstr, but x is in Mlog form + +% Other than the above-documented user interface, all +% externally visible names start with F and end with _. + +% Allow big numbers in token lists + +begingroup interim warningcheck := 0 ; + +%%% Load auxiliary macros. + +input string ; +input marith ; + +%%% Choosing the Layout %%% + +picture Fmneg_, Femarker_, Feneg_, Fe_base, Fe_plus ; +string Fmfont_, Fefont_ ; +numeric Fmscale_, Fescale_, Feraise_ ; + +% Argument +% +% s is a leading minus sign +% m is a 1-digit mantissa +% x is whatever follows the mantissa +% sn is a leading minus for the exponent, and +% e is a 1-digit exponent. +% +% Numbers in scientific notation are constructed by placing +% these pieces side-by-side; decimal numbers use only m +% and/or s. To get exponents with leading plus signs, assign +% to Fe_plus after calling init_numbers. To do something +% special with a unit mantissa followed by x, assign to +% Fe_base after calling init_numbers. + +vardef init_numbers(expr s, m, x, sn, e) = + Fmneg_ := s ; + for p within m : + Fmfont_ := fontpart p ; + Fmscale_ := xxpart p ; + exitif true ; + endfor + Femarker_ := x ; + Feneg_ := sn ; + for p within e : + Fefont_ := fontpart p ; + Fescale_ := xxpart p ; + Feraise_ := ypart llcorner p ; + exitif true ; + endfor + if fmt_metapost : + Fe_base := Fline_up_("1" infont Fmfont_ scaled Fmscale_, Femarker_) ; + % else : + % sFe_base := Fline_up_("1", sFemarker_) ; + fi ; + Fe_plus := nullpicture ; +enddef ; + +%%% Low-Level Typesetting %%% + +vardef Fmant_(expr x) = %%% adapted by HH %%% + if fmt_metapost : + (decimal abs x infont Fmfont_ scaled Fmscale_) + else : + (decimal abs x) + fi +enddef ; + +vardef Fexp_(expr x) = %%% adapted by HH %%% + if fmt_metapost : + (decimal x infont Fefont_ scaled Fescale_ shifted (0,Feraise_)) + else : + (decimal x) + fi +enddef ; + +vardef Fline_up_(text t_) = %%% adapted by HH %%% + if fmt_metapost : + save p_, c_ ; + picture p_ ; p_ = nullpicture ; + pair c_ ; c_ = (0,0) ; + for q_ = t_ : + addto p_ also q_ if string q_ : infont defaultfont scaled defaultscale fi + shifted c_ ; + c_ := (xpart lrcorner p_, 0) ; + endfor + p_ + else : + "" for q_ = t_ : & q_ endfor + fi +enddef ; + +vardef Fdec_o_(expr x) = %%% adapted by HH %%% + if x<0 : + Fline_up_(if fmt_metapost : Fmneg_ else : sFmneg_ fi, Fmant_(x)) + else : + Fmant_(x) + fi +enddef ; + +vardef Fsci_o_(expr x, e) = %%% adapted by HH %%% + if fmt_metapost : + Fline_up_ + (if x < 0 : Fmneg_,fi + if abs x = 1 : Fe_base else : Fmant_(x), Femarker_ fi, + if e < 0 : Feneg_ else : Fe_plus fi, + Fexp_(abs e)) + else : + Fline_up_ + (if x < 0 : sFmneg_, fi + if abs x = 1 : sFe_base else : Fmant_(x), sFemarker_ fi, + sFebraise_, + if e < 0 : sFeneg_ else : sFe_plus fi, + Fexp_(abs e), + sFeeraise_) + fi +enddef ; + +% Assume prologues=1 implies troff mode. TeX users who want +% prologues on should use some other positive value. The mpx +% file mechanism requires separate input files here. +% +% if fmt_initialize : %%% adapted by HH +% if prologues = 1 : input troffnum else : input texnum fi +% fi ; +% +% wrong assumption, so we need: + +if fmt_initialize : + input texnum ; +fi ; + +%%% Scaling and Rounding %%% + +% Find a pair p where x = xpart p*10**ypart p and either p = +% (0,0) or xpart p is between 1000 and 9999.99999. This is +% the `exponent form' of x. + +vardef Feform_(expr x) = + interim warningcheck := 0 ; + if string x : + Meform(Mlog_str x) + else : + save b, e ; + b = x ; e = 0 ; + if abs b >= 10000 : + (b/10, 1) + elseif b = 0 : + origin + else : + forever : + exitif abs b >= 1000 ; + b := b*10 ; e := e-1 ; + endfor + (b, e) + fi + fi +enddef ; + +% The marith.mp macros include a similar macro Meform that +% converts from `Mlog form' to exponent form. In case +% rounding has made the xpart of an exponent form number too +% large, fix it. + +vardef Feadj_(expr x, y) = + if abs x >= 10000 : (x/10, y+1) else : (x,y) fi +enddef ; + +% Round x to d places right of the decimal point. When d<0, +% round to the nearest multiple of 10 to the -d. + +vardef roundd(expr x, d) = + if abs d > 4 : + if d > 0 : x else : 0 fi + elseif d > 0 : + save i ; i = floor x ; + i + round(Ten_to[d]*(x-i))/Ten_to[d] + else : + round(x/Ten_to[-d])*Ten_to[-d] + fi +enddef ; + +Ten_to0 = 1 ; +Ten_to1 = 10 ; +Ten_to2 = 100 ; +Ten_to3 = 1000 ; +Ten_to4 = 10000 ; + +% Round an exponent form number p to k significant figures. + +primarydef p Fprec_ k = + Feadj_(roundd(xpart p,k-4), ypart p) +enddef ; + +% Round an exponent form number p to k digits right of the +% decimal point. + +primarydef p Fdigs_ k = + Feadj_(roundd(xpart p,k+ypart p), ypart p) +enddef ; + +%%% High-Level Routines %%% + +% The following operators convert z from exponent form and +% produce typeset output: Formsci_ generates scientific +% notation; Formdec_ generates decimal notation; and +% Formgen_ generates whatever is likely to be most compact. + +vardef Formsci_(expr z) = %%% adapted by HH %%% + if fmt_zerocheck and (z = origin) : + Fsci_o_(0,0) + else : + Fsci_o_(xpart z/1000, ypart z + 3) + fi +enddef ; + +vardef Formdec_(expr z) = + if ypart z > 0 : + Formsci_(z) + else : + Fdec_o_ + (xpart z if ypart z >= -4 : + /Ten_to[-ypart z] + else : + for i = ypart z upto -5 : /(10) endfor /10000 + fi) + fi +enddef ; + +vardef Formgen_(expr q) = + clearxy ; (x,y) = q ; + if x = 0 : Formdec_ + elseif y >= -6 : Formdec_ + else : Formsci_ + fi (q) +enddef ; + +def Fset_item_(expr s) = %%% adapted by HH %%% + if s <> "" : + if fmt_metapost : + s infont defaultfont scaled defaultscale, + else : + s, + fi + fi +enddef ; + +% For each format letter, the table below tells how to +% round and typeset a quantity z in exponent form. +% +% e scientific, p significant figures +% f decimal, p digits right of the point +% g decimal or scientific, p sig. figs. +% G decimal or scientific, p digits + +string fmt_[] ; + +fmt_[ASCII "e"] = "Formsci_(z Fprec_ p)" ; +fmt_[ASCII "f"] = "Formdec_(z Fdigs_ p)" ; +fmt_[ASCII "g"] = "Formgen_(z Fprec_ p)" ; +fmt_[ASCII "G"] = "Formgen_(z Fdigs_ p)" ; + +% The format and Mformat macros take a format string f and +% generate typeset output for a numeric quantity x. String f +% should contain a `%' followed by an optional number and one +% of the format letters defined above. The number should be +% an integer giving the precision (default 3). + +vardef isfmtseparator primary c = %%% added by HH %%% + ((c <> fmt_separator) and (c <> "%")) +enddef ; + +def initialize_form_numbers = + initialize_numbers ; % in context: do_initialize_numbers ; +enddef ; + +vardef dofmt_@#(expr f, x) = %%% adapted by HH %%% + initialize_form_numbers ; + if f = "" : + if fmt_metapost : nullpicture else : "" fi + else : + interim warningcheck := 0 ; + save k, l, s, p, z ; + pair z ; z = @#(x) ; + % the next adaption is okay + % k = 1 + cspan(f, fmt_separator <> ) ; + % but best is to support both % and fmt_separator + k = 1 + cspan(f, isfmtseparator) ; + % + l-k = cspan(substring(k,infinity) of f, isdigit) ; + p = if l > k : + scantokens substring(k,l) of f + else : + fmt_precision + fi ; + string s ; s = fmt_[ASCII substring (l,l+1) of f] ; + if unknown s : + if k <= length f : + errmessage("No valid format letter found in "&f) ; + fi + s = if fmt_metapost : "nullpicture" else : "" fi ; + fi + Fline_up_ + (Fset_item_(substring (0,k-1) of f) + if not fmt_metapost : sFebmath_, fi + scantokens s, + if not fmt_metapost : sFeemath_, fi + Fset_item_(substring (l+1,infinity) of f) + if fmt_metapost : nullpicture else : "" fi) + fi + hide (fmt_metapost := true) +enddef ; + +%%% so far %%% + +vardef format (expr f, x) = + fmt_metapost := true ; dofmt_.Feform_(f,x) +enddef ; + +vardef Mformat(expr f, x) = + fmt_metapost := true ; dofmt_.Meform (f,x) +enddef ; + +vardef formatstr (expr f, x) = + fmt_metapost := false ; dofmt_.Feform_(f,x) +enddef ; + +vardef Mformatstr(expr f, x) = + fmt_metapost := false ; dofmt_.Meform (f,x) +enddef ; + +% Restore warningcheck to previous value. + +endgroup ; diff --git a/metapost/context/base/mpii/mp-func.mpii b/metapost/context/base/mpii/mp-func.mpii new file mode 100644 index 000000000..94e400b91 --- /dev/null +++ b/metapost/context/base/mpii/mp-func.mpii @@ -0,0 +1,58 @@ +%D \module +%D [ file=mp-func.mpii, +%D version=2001.12.29, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=function hacks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D Under construction. + +if known context_func : endinput ; fi ; + +boolean context_func ; context_func := true ; + +string pathconnectors[] ; + +pathconnectors[0] := "," ; +pathconnectors[1] := "--" ; +pathconnectors[2] := ".." ; +pathconnectors[3] := "..." ; + +vardef function (expr f) (expr u, t, b, e, s) = save x ; numeric x ; + for xx := b step s until e : + hide (x := xx ;) if xx>b : scantokens(pathconnectors[f]) fi + (scantokens(u),scantokens(t)) + endfor +enddef ; + +def punkedfunction = function (1) enddef ; +def curvedfunction = function (2) enddef ; +def tightfunction = function (3) enddef ; + +vardef constructedpath (expr f) (text t) = + save ok ; boolean ok ; ok := false ; + for i=t : + if ok : scantokens(pathconnectors[f]) else : ok := true ; fi i + endfor +enddef ; + +def punkedpath = constructedpath (1) enddef ; +def curvedpath = constructedpath (2) enddef ; +def tightpath = constructedpath (3) enddef ; + +vardef constructedpairs (expr f) (text p) = + save i ; i := -1 ; + forever : exitif unknown p[incr(i)] ; + if i>0 : scantokens(pathconnectors[f]) fi p[i] + endfor +enddef ; + +def punkedpairs = constructedpairs (1) enddef ; +def curvedpairs = constructedpairs (2) enddef ; +def tightpairs = constructedpairs (3) enddef ; diff --git a/metapost/context/base/mpii/mp-grid.mpii b/metapost/context/base/mpii/mp-grid.mpii new file mode 100644 index 000000000..ea28d60af --- /dev/null +++ b/metapost/context/base/mpii/mp-grid.mpii @@ -0,0 +1,149 @@ +%D \module +%D [ file=mp-grid.mpii, +%D version=2000.07.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=grid support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D Under construction. + +if known context_grid : endinput ; fi ; + +boolean context_grid ; context_grid := true ; + +string fmt_separator ; fmt_separator := "@" ; +numeric fmt_precision ; fmt_precision := 3 ; +boolean fmt_initialize ; fmt_initialize := false ; +boolean fmt_zerocheck ; fmt_zerocheck := true ; + +if unknown fmt_loaded : input "mp-form.mpii" ; fi ; + +boolean fmt_pictures ; fmt_pictures := true ; + +def do_format = if fmt_pictures : format else : formatstr fi enddef ; +def do_mformat = if fmt_pictures : Mformat else : Mformatstr fi enddef ; + +numeric grid_eps ; grid_eps = eps ; + +def hlingrid (expr Min, Max, Step, Length, Width) text t = + image ( for i=Min step Step until Max+grid_eps : + draw (origin--(Width,0)) shifted (0,i*(Length/Max)) t ; + endfor ; ) ; +enddef ; + +def vlingrid (expr Min, Max, Step, Length, Height) text t = + image ( for i=Min step Step until Max+grid_eps : + draw (origin--(0,Height)) shifted (i*(Length/Max),0) t ; + endfor ; ) ; +enddef ; + +def hloggrid (expr Min, Max, Step, Length, Width) text t = + image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw (origin--(Width,0)) shifted (0,Length*log(i)) t ; + endfor ; ) ; +enddef ; + +def vloggrid (expr Min, Max, Step, Length, Height) text t = + image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw (origin--(0,Height)) shifted (Length*log(i),0) t ; + endfor ; ) ; +enddef ; + +vardef hlintext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=Min step Step until Max+grid_eps : + draw textext@#(do_format(Format,i)) shifted (0,i*(Length/Max)) t ; + endfor ; ) +enddef ; + +vardef vlintext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=Min step Step until Max+grid_eps : + draw textext@#(do_format(Format,i)) shifted (i*(Length/Max),0) t ; + endfor ; ) +enddef ; + +vardef hlogtext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw textext@#(do_format(Format,i)) shifted (0,Length*log(i)) t ; + endfor ; ) +enddef ; + +vardef vlogtext@#(expr Min, Max, Step, Length, Format) text t = + image ( do_initialize_numbers ; + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw textext@#(do_format(Format,i)) shifted (Length*log(i),0) t ; + endfor ; ) +enddef ; + +vardef hlinlabel@#(expr Min, Max, Step, Length) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw thelabel@#(decimal i,(0,i*(Length/Max))) t ; + endfor ; ) +enddef ; + +vardef vlinlabel@#(expr Min, Max, Step, Length) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw thelabel@#(decimal i,(i*(Length/Max),0)) t ; + endfor ; ) +enddef ; + +boolean numbers_initialized ; numbers_initialized := false ; + +def do_initialize_numbers = + if not numbers_initialized : + init_numbers ( textext.raw("$-$") , + textext.raw("$1$") , + textext.raw("${\times}10$") , + textext.raw("${}^-$") , + textext.raw("${}^2$") ) ; + if unknown _trial_run_ : + numbers_initialized := true ; + else : + % no reset, otherwise textexts get out of sync + % slows down graphics a bit but not much + fi ; + fi ; +enddef ; + +def initialize_numbers = + numbers_initialized := false ; do_initialize_numbers ; +enddef ; + +vardef linlog(expr xy) = ( xpart xy, log(ypart xy)) enddef ; +vardef loglin(expr xy) = (log(xpart xy), ypart xy) enddef ; +vardef loglog(expr xy) = (log(xpart xy), log(ypart xy)) enddef ; +vardef linlin(expr xy) = ( (xpart xy), (ypart xy)) enddef ; + +vardef loglinpath primary p = processpath (p) (loglin) enddef ; +vardef linlogpath primary p = processpath (p) (linlog) enddef ; +vardef loglogpath primary p = processpath (p) (loglog) enddef ; +vardef linlinpath primary p = processpath (p) (linlin) enddef ; + +def processpath (expr p) (text pp) = + if path p : + for i=0 upto length(p)-1 : + (pp(point i of p)) .. controls + (pp(postcontrol i of p)) and + (pp(precontrol (i+1) of p)) .. + endfor + if cycle p : + cycle + else : + (pp(point length(p) of p)) + fi + elseif pair p : + (pp(p)) + else : + p + fi +enddef ; diff --git a/metapost/context/base/mpii/mp-grph.mpii b/metapost/context/base/mpii/mp-grph.mpii new file mode 100644 index 000000000..782942946 --- /dev/null +++ b/metapost/context/base/mpii/mp-grph.mpii @@ -0,0 +1,310 @@ +%D \module +%D [ file=mp-grph.mpii, +%D version=2000.12.14, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=graphic text support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D Under construction. + +if known context_grph : endinput ; fi ; + +boolean context_grph ; context_grph := true ; + +string CRLF ; CRLF := char 10 & char 13 ; + +picture _currentpicture_ ; + +numeric _fig_nesting_ ; _fig_nesting_ := 0 ; + +def beginfig (expr c) = + _fig_nesting_ := _fig_nesting_ + 1 ; + if _fig_nesting_ = 1 : + begingroup + charcode := c ; + resetfig ; + scantokens extra_beginfig ; + fi ; +enddef ; + +def endfig = + ; % safeguard + if _fig_nesting_ = 1 : + scantokens extra_endfig; + shipit ; + endgroup ; + fi ; + _fig_nesting_ := _fig_nesting_ - 1 ; +enddef; + + +def resetfig = + clearxy ; + clearit ; + clearpen ; + pickup defaultpen ; + interim linecap := linecap ; + interim linejoin := linejoin ; + interim miterlimit := miterlimit ; + save _background_ ; color _background_ ; _background_ := background ; + save background ; color background ; background := _background_ ; + drawoptions () ; +enddef ; + +def protectgraphicmacros = + save showtext ; + save beginfig ; let beginfig = begingraphictextfig ; + save endfig ; let endfig = endgraphictextfig ; + save end ; let end = relax ; + interim prologues := prologues ; + resetfig ; % resets currentpicture +enddef ; + +numeric currentgraphictext ; currentgraphictext := 0 ; +string graphictextformat ; graphictextformat := "plain" ; +string graphictextstring ; graphictextstring := "" ; +string graphictextfile ; graphictextfile := "dummy.mpo" ; + +def data_mpo_file = job_name & "-mpgraph.mpo" enddef ; +def data_mpy_file = job_name & "-mpgraph.mpy" enddef ; + +if unknown mplib : + + def savegraphictext (expr str) = + if (graphictextstring<>"") : + write graphictextstring to data_mpo_file ; + graphictextstring := "" ; + fi ; + write str to data_mpo_file ; + let erasegraphictextfile = relax ; + enddef ; + + def erasegraphictextfile = + write EOF to data_mpo_file ; + let erasegraphictextfile = relax ; + enddef ; + + extra_beginfig := extra_beginfig & " erasegraphictextfile ;" ; + +fi ; + +def begingraphictextfig (expr n) = + foundpicture := n ; scratchpicture := nullpicture ; +enddef ; + +def endgraphictextfig = + if foundpicture = currentgraphictext : + expandafter endinput + else : + scratchpicture := nullpicture ; + fi ; +enddef ; + +def loadfigure primary filename = + doloadfigure (filename) +enddef ; + +def doloadfigure (expr filename) text figureattributes = + begingroup ; + save figurenumber, figurepicture, number, fixedplace ; + numeric figurenumber ; figurenumber := 0 ; + boolean figureshift ; figureshift := true ; + picture figurepicture ; figurepicture := currentpicture ; + def number primary n = hide(figurenumber := n) enddef ; + def fixedplace = hide(figureshift := false) enddef ; + protectgraphicmacros ; + % defaults + interim linecap := rounded ; + interim linejoin := rounded ; + interim miterlimit := 10 ; + % + currentpicture := nullpicture ; + draw fullcircle figureattributes ; % expand number + currentpicture := nullpicture ; + def beginfig (expr n) = + currentpicture := nullpicture ; + if (figurenumber=n) or (figurenumber=0) : + let endfig = endinput ; + fi ; + enddef ; + let endfig = relax ; + readfile(filename) ; + if figureshift : + currentpicture := currentpicture shifted -llcorner currentpicture ; + fi ; + addto figurepicture also currentpicture figureattributes ; + currentpicture := figurepicture ; + endgroup ; +enddef ; + +def graphictext primary t = + dographictext(t) +enddef ; + +def dographictext (expr t) = + begingroup ; + save figurepicture ; picture figurepicture ; + figurepicture := currentpicture ; currentpicture := nullpicture ; + if graphictextformat<>"" : + graphictextstring := + "% format=" & graphictextformat & CRLF & graphictextstring ; + graphictextformat := "" ; + fi ; + currentgraphictext := currentgraphictext + 1 ; + if unknown mplib : + savegraphictext ("\startTEXpage[scale=10000]" & t & "\stopTEXpage") ; + fi ; + dofinishgraphictext +enddef ; + +def redographictext primary t = + regraphictext(t) +enddef ; + +def regraphictext (expr t) = + begingroup ; + save figurepicture ; picture figurepicture ; + figurepicture := currentpicture ; currentpicture := nullpicture ; + save currentgraphictext ; numeric currentgraphictext ; + currentgraphictext := t ; + dofinishgraphictext +enddef ; + +%D Believe it or not, but it took me half a day to uncover +%D the following neccessity: +%D +%D \starttypen +%D save withfillcolor, withdrawcolor ; +%D \stoptypen +%D +%D When we have more than one graphictext, these will be +%D defined after the first graphic. For some obscure reason, +%D this means that in the next graphic they will be called, but +%D afterwards the data and boolean are not set. Don't ask me +%D why. + +def dofinishgraphictext text x_op_x = + protectgraphicmacros ; % resets currentpicture + interim linecap := butt ; % normally rounded + interim linejoin := mitered ; % normally rounded + interim miterlimit := 10 ; % todo + let normalwithshade = withshade ; + save foundpicture, scratchpicture, str ; + save fill, draw, withshade, reversefill, outlinefill ; + save withfillcolor, withdrawcolor ; % quite important + numeric foundpicture ; picture scratchpicture ; string str ; + def draw expr p = + % the first, naive implementation was: + % addto scratchpicture doublepath p withpen currentpen ; + % but it is better to turn lines into fills + addto scratchpicture contour boundingbox + image (addto currentpicture doublepath p withpen currentpen) ; + enddef ; + def fill expr p = + addto scratchpicture contour p withpen currentpen ; + enddef ; + def f_op_f = enddef ; boolean f_color ; f_color := false ; + def d_op_d = enddef ; boolean d_color ; d_color := false ; + def s_op_s = enddef ; boolean s_color ; s_color := false ; + boolean reverse_fill ; reverse_fill := false ; + boolean outline_fill ; outline_fill := false ; + def reversefill = + hide(reverse_fill := true ) + enddef ; + def outlinefill = + hide(outline_fill := true ) + enddef ; + def withshade primary c = + hide(def s_op_s = normalwithshade c enddef ; s_color := true ) + enddef ; + def withfillcolor primary c = + hide(def f_op_f = withcolor c enddef ; f_color := true ) + enddef ; + def withdrawcolor primary c = + hide(def d_op_d = withcolor c enddef ; d_color := true ) + enddef ; + scratchpicture := nullpicture ; + addto scratchpicture doublepath origin x_op_x ; % pre-roll + for i within scratchpicture : % Below here is a dirty tricky test! + if (urcorner dashpart i) = origin : outline_fill := false ; fi ; + endfor ; + scratchpicture := nullpicture ; + readfile(data_mpy_file) ; + scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ; + if not d_color and not f_color : d_color := true ; fi + if s_color : d_color := false ; f_color := false ; fi ; + currentpicture := figurepicture ; + if d_color and not reverse_fill : + for i within scratchpicture : + if f_color and outline_fill : + addto currentpicture doublepath pathpart i _op_ x_op_x f_op_f + dashed nullpicture ; + fi ; + if filled i : + addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; + fi ; + endfor ; + fi ; + if f_color : + for i within scratchpicture : + if filled i : + addto currentpicture contour pathpart i _op_ x_op_x f_op_f + withpen pencircle scaled 0 ; + fi ; + endfor ; + fi ; + if d_color and reverse_fill : + for i within scratchpicture : + if filled i : + addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; + fi ; + endfor ; + fi ; + if s_color : + for i within scratchpicture : + if filled i : + addto currentpicture contour pathpart i _op_ x_op_x s_op_s ; + fi ; + endfor ; + else : + for i within scratchpicture : + if stroked i : + addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; + fi ; + endfor ; + fi ; + endgroup ; +enddef ; + +def resetgraphictextdirective = + graphictextstring := "" ; +enddef ; + +def graphictextdirective text t = + graphictextstring := graphictextstring & t & CRLF ; +enddef ; + +% example +% +% % graphictextformat := "context" ; +% % graphictextformat := "plain" ; +% +% beginfig (1) ; +% graphictext +% "\vbox{\hsize10cm \input tufte }" +% scaled 8 +% withdrawcolor blue +% withfillcolor red +% withpen pencircle scaled 2pt ; +% endfig ; +% +% beginfig(1) ; +% loadfigure "gracht.mp" rotated 20 ; +% loadfigure "koe.mp" number 1 scaled 2 ; +% endfig ; diff --git a/metapost/context/base/mpii/mp-page.mpii b/metapost/context/base/mpii/mp-page.mpii new file mode 100644 index 000000000..456ee61cc --- /dev/null +++ b/metapost/context/base/mpii/mp-page.mpii @@ -0,0 +1,659 @@ +%D \module +%D [ file=mp-page.mpii, +%D version=1999.03.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=page enhancements, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module is rather preliminary and subjected to +%D changes. + +if known context_page : endinput ; fi ; + +boolean context_page ; context_page := true ; + +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 ; + +def SaveTextAreas = + path SavedTextAreas [] ; + path SavedTextColumns[] ; + numeric NOfSavedTextAreas ; + numeric NOfSavedTextColumns ; + for i=1 upto NOfTextAreas : + SavedTextAreas[i] := TextAreas[i] ; + endfor ; + for i=1 upto NOfTextColumns : + SavedTextColumns[i] := TextColumns[i] ; + endfor ; + NOfSavedTextAreas := NOfTextAreas ; + NOfSavedTextColumns := NOfTextColumns ; +enddef ; + +def ResetTextAreas = + path TextAreas[], TextColumns[] ; + numeric NOfTextAreas ; NOfTextAreas := 0 ; + numeric NOfTextColumns ; NOfTextColumns := 0 ; + numeric nofmultipars ; nofmultipars := 0 ; + TextAreas[0] := TextColumns[0] := origin -- cycle ; +enddef ; + +ResetTextAreas ; SaveTextAreas ; ; + +def RegisterTextArea (expr x, y, w, h, d) = + begingroup ; save p ; path p ; + p := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; + if NOfTextAreas>0 : + % if needed, concatenate areas + if (round(llcorner TextAreas[NOfTextAreas]) = round(ulcorner p)) and + (round(lrcorner TextAreas[NOfTextAreas]) = round(urcorner p)) : + p := ulcorner TextAreas[NOfTextAreas] -- + urcorner TextAreas[NOfTextAreas] -- + lrcorner p -- + llcorner p -- + cycle ; + else : + NOfTextAreas := NOfTextAreas + 1 ; + fi ; + else : + NOfTextAreas := NOfTextAreas + 1 ; + fi ; + TextAreas[NOfTextAreas] := p ; + if NOfTextColumns>0 : + if (round(xpart llcorner TextColumns[NOfTextColumns]) = round(xpart ulcorner p)) and + (round(xpart lrcorner TextColumns[NOfTextColumns]) = round(xpart urcorner p)) : + p := ulcorner TextColumns[NOfTextColumns] -- + urcorner TextColumns[NOfTextColumns] -- + lrcorner p -- + llcorner p -- + cycle ; + else : + NOfTextColumns := NOfTextColumns + 1 ; + fi ; + else : + NOfTextColumns := NOfTextColumns + 1 ; + fi ; + TextColumns[NOfTextColumns] := p ; + endgroup ; +enddef ; + +%D We store a local area in slot zero. + +def RegisterLocalTextArea (expr x, y, w, h, d) = + TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; +enddef ; + +def ResetLocalTextArea = + TextAreas[0] := TextColumns[0] := origin -- cycle ; +enddef ; + +ResetLocalTextArea ; + +vardef InsideTextArea (expr _i_, _xy_) = + ( (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and + (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and + (round(ypart _xy_) >= round(ypart llcorner TextAreas[_i_])) and + (round(ypart _xy_) <= round(ypart urcorner TextAreas[_i_])) ) +enddef ; + +vardef InsideSavedTextArea (expr _i_, _xy_) = + ( (round(xpart _xy_) >= round(xpart llcorner SavedTextAreas[_i_])) and + (round(xpart _xy_) <= round(xpart lrcorner SavedTextAreas[_i_])) and + (round(ypart _xy_) >= round(ypart llcorner SavedTextAreas[_i_])) and + (round(ypart _xy_) <= round(ypart urcorner SavedTextAreas[_i_])) ) +enddef ; + +vardef InsideSomeTextArea (expr _xy_) = + save ok ; boolean ok ; ok := false ; + for i := 1 upto NOfTextAreas : + if InsideTextArea(i,_xy_) : ok := true ; fi ; + exitif ok ; + endfor ; + ok +enddef ; + +vardef InsideSomeSavedTextArea (expr _xy_) = + save ok ; boolean ok ; ok := false ; + for i := 1 upto NOfSavedTextAreas : + if InsideSavedTextArea(i,_xy_) : ok := true ; fi ; + exitif ok ; + endfor ; + ok +enddef ; + +vardef TextAreaX (expr x) = + numeric _TextAreaX_ ; _TextAreaX_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) : + _TextAreaX_ := xpart llcorner TextAreas[i] ; + fi ; + endfor ; + _TextAreaX_ +enddef ; + +vardef TextAreaY (expr y) = + numeric _TextAreaY_ ; _TextAreaY_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(y) >= round(ypart llcorner TextAreas[NOfTextAreas])) and + (round(y) <= round(ypart ulcorner TextAreas[NOfTextAreas])) : + _TextAreaY_ := ypart llcorner TextAreas[NOfTextAreas] ; + fi ; + endfor ; + _TextAreaY_ +enddef ; + +vardef TextAreaXY (expr x, y) = + pair _TextAreaXY_ ; _TextAreaXY_ := origin ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) and + (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaXY_ := llconer TextAreas[i] ; + fi ; + endfor ; + _TextAreaXY_ +enddef ; + +vardef TextAreaW (expr x) = + numeric _TextAreaW_ ; _TextAreaW_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) : + _TextAreaW_ := bbwidth(TextAreas[i]) ; + fi ; + endfor ; + _TextAreaW_ +enddef ; + +vardef TextAreaH (expr y) = + numeric _TextAreaH_ ; _TextAreaH_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaH_ := bbheight(TextAreas[i]) ; + fi ; + endfor ; + _TextAreaH_ +enddef ; + +vardef TextAreaWH (expr x, y) = + pair _TextAreaWH_ ; _TextAreaWH_ := origin ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) and + (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaWH_ := (bbwidth(TextAreas[i]),bbheight(TextAreas[i])) ; + fi ; + endfor ; + _TextAreaWH_ +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 ; + +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 [][] ; path Page ; +numeric HorPos ; numeric Hstep [] ; numeric Hsize [] ; +numeric VerPos ; numeric Vstep [] ; numeric Vsize [] ; + +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 ; + +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[] ; + + Vsize[Top] = TopHeight ; + Vsize[TopSeparator] = TopDistance ; + Vsize[Header] = HeaderHeight ; + Vsize[HeaderSeparator] = HeaderDistance ; + Vsize[Text] = TextHeight ; + Vsize[FooterSeparator] = FooterDistance ; + Vsize[Footer] = FooterHeight ; + Vsize[BottomSeparator] = BottomDistance ; + Vsize[Bottom] = BottomHeight ; + + Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; + Vstep[TopSeparator] = PaperHeight-TopSpace ; + Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; + Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; + Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; + Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; + Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; + Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; + Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; + + Hsize[LeftEdge] = LeftEdgeWidth ; + Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; + Hsize[LeftMargin] = LeftMarginWidth ; + Hsize[LeftMarginSeparator] = LeftMarginDistance ; + Hsize[Text] = MakeupWidth ; + Hsize[RightMarginSeparator] = RightMarginDistance ; + Hsize[RightMargin] = RightMarginWidth ; + Hsize[RightEdgeSeparator] = RightEdgeDistance ; + Hsize[RightEdge] = RightEdgeWidth ; + + Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; + Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; + Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; + Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; + Hstep[Text] = BackSpace ; + Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; + Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; + Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; + Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; + + for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; + Area[VerPos][HorPos] := Area[HorPos][VerPos] ; + Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; + Location[VerPos][HorPos] := Location[HorPos][VerPos] ; + Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ; + Field[VerPos][HorPos] := Field[HorPos][VerPos] ; + endfor ; + endfor ; + + Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; + +enddef ; + +def BoundPageAreas = + + % pickup pencircle scaled 0pt ; + + bboxmargin := 0 ; setbounds currentpicture to Page ; + +enddef ; + +def StartPage = + + begingroup ; + + if PageStateAvailable : + LoadPageState ; + SwapPageState ; + fi ; + + SetPageAreas ; + BoundPageAreas ; + +enddef ; + +def StopPage = + + BoundPageAreas ; + + endgroup ; + +enddef ; + +def OverlayBox = + (unitsquare xyscaled (OverlayWidth,OverlayHeight)) +enddef ; + +% handy + +def innerenlarged = + hide(LoadPageState) + if OnRightPage : leftenlarged else : rightenlarged fi +enddef ; + +def outerenlarged = + hide(LoadPageState) + if OnRightPage : rightenlarged else : leftenlarged fi +enddef ; + +% obsolete + +def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ; +def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ; +def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ; +def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ; + +def Enlarged (expr p, d) = + (llEnlarged (p,d) -- + lrEnlarged (p,d) -- + urEnlarged (p,d) -- + ulEnlarged (p,d) -- cycle) +enddef ; + +% New: + +def position_anchor_bar(expr p_b_self, p_e_self, y_b_self, y_e_self, h_b_self, d_e_self, + distance, linewidth, linecolor) = + StartPage ; + path p ; p := + if p_b_self=p_e_self : + (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) -- + (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ; + elseif RealPageNumber=p_b_self : + (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) -- + (llcorner Field[Text][Text]) ; + elseif RealPageNumber=p_e_self : + (ulcorner Field[Text][Text]) -- + (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ; + else : + (ulcorner Field[Text][Text]) -- + (llcorner Field[Text][Text]) ; + fi ; + p := p shifted (-llcorner Field[Text][Text]-(distance,0)) ; + interim linecap := butt ; + draw p + withpen pencircle scaled linewidth + withcolor linecolor ; + StopPage ; +enddef ; + +% Crop stuff + +vardef crop_marks_lines (expr box, length, offset, nx, ny) = + save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ; + p := image ( + x := if nx = 0 : 1 else : nx - 1 fi ; + y := if ny = 0 : 1 else : ny - 1 fi ; + w := bbwidth (box) / x ; + h := bbheight(box) / y ; + for i=0 upto y : + draw ((llcorner box) -- (llcorner box) shifted (-length,0)) shifted (-offset,i*h) ; + draw ((lrcorner box) -- (lrcorner box) shifted ( length,0)) shifted ( offset,i*h) ; + endfor ; + for i=0 upto x : + draw ((llcorner box) -- (llcorner box) shifted (0,-length)) shifted (i*w,-offset) ; + draw ((ulcorner box) -- (ulcorner box) shifted (0, length)) shifted (i*w, offset) ; + endfor ; + ) ; + setbounds p to box ; + p +enddef ; + +vardef crop_marks_cmyk = + save p ; picture p ; p := image ( + fill ulcircle scaled 12.5 withcolor (1,0,0,0) ; + fill urcircle scaled 12.5 withcolor (0,1,0,0) ; + fill lrcircle scaled 12.5 withcolor (0,0,1,0) ; + fill llcircle scaled 12.5 withcolor (0,0,0,1) ; + draw (-10,0) -- (10,0) ; + draw (0,-10) -- (0,10) ; + draw fullcircle scaled 12.5 ; + ) ; + setbounds p to fullsquare scaled 20 ; + p +enddef ; + +vardef crop_marks_gray = + save p ; picture p ; p := image ( + fill ulcircle scaled 12.5 withcolor (0.00) ; + fill urcircle scaled 12.5 withcolor (0.25) ; + fill lrcircle scaled 12.5 withcolor (0.50) ; + fill llcircle scaled 12.5 withcolor (0.75) ; + draw (-10,0) -- (10,0) ; + draw (0,-10) -- (0,10) ; + draw (-6,0) -- (6,0) withcolor white ; + draw (0,-6) -- (0,6) withcolor white ; + draw fullcircle scaled 12.5 ; + ) ; + setbounds p to fullsquare scaled 20 ; + p +enddef ; + +vardef crop_marks_cmykrgb = + save p ; picture p ; p := image ( + fill ulcircle scaled 15 withcolor (1,0,0) ; + fill urcircle scaled 15 withcolor (0,1,0) ; + fill lrcircle scaled 15 withcolor (0,0,1) ; + fill llcircle scaled 15 withcolor (.5,.5,.5) ; + fill ulcircle scaled 10 withcolor (1,0,0,0) ; + fill urcircle scaled 10 withcolor (0,1,0,0) ; + fill lrcircle scaled 10 withcolor (0,0,1,0) ; + fill llcircle scaled 10 withcolor (0,0,0,1) ; + draw (-10,0) -- (10,0) ; + draw (0,-10) -- (0,10) ; + draw fullcircle scaled 10 ; + draw fullcircle scaled 15 ; + ) ; + setbounds p to fullsquare scaled 20 ; + p +enddef ; + +vardef crop_color(expr c, h, w, dx, dy, ts) = + image ( + save p ; path p ; + for i=1 upto 6 : + p := fullsquare + xscaled w + yscaled h + shifted (dx,dy-i*h) ; + fill p + withcolor (crop_colors[i]*c) ; + draw textext("\format{'@0.2f'," & decimal crop_colors[i] & "}") + scaled ts + shifted center p withcolor white ; + endfor ; + ) +enddef ; + +vardef crop_gray(expr c, h, w, dx, dy, ts) = + image ( + save p ; path p ; + for i=.05 step .05 until 1 : + p := fullsquare + xscaled w + yscaled h + shifted (20*(i-1)*w+dx,dy) ; + fill p + withcolor (i*c) ; + draw textext("\format{'@0.2f'," & decimal i & "}") + scaled ts + shifted center p withcolor white ; + endfor ; + ) +enddef ; + +% draw crop_marks_cmyk shifted llcorner more ; +% draw crop_marks_cmyk shifted lrcorner more ; +% draw crop_marks_cmyk shifted ulcorner more ; +% draw crop_marks_cmyk shifted urcorner more ; + +def page_marks_add_color(expr width, height, length, offset) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + numeric crop_colors[] ; + crop_colors[1] := 1 ; + crop_colors[2] := 0.95 ; + crop_colors[3] := 0.75 ; + crop_colors[4] := 0.50 ; + crop_colors[5] := 0.25 ; + crop_colors[6] := 0.05 ; + + numeric h ; h := height / 20 ; + numeric w ; w := width / 20 ; + numeric d ; d := offset + length/2 ; + + draw crop_color((1,0,0,0),h,length,xpart ulcorner page - d, 10h,length/20) ; + draw crop_color((0,1,0,0),h,length,xpart ulcorner page - d,3.5h,length/20) ; + draw crop_color((0,0,1,0),h,length,xpart ulcorner page - d, -3h,length/20) ; + + draw crop_color((0,1,1,0),h,length,xpart urcorner page + d, 10h,length/20) ; + draw crop_color((1,0,1,0),h,length,xpart urcorner page + d,3.5h,length/20) ; + draw crop_color((1,1,0,0),h,length,xpart urcorner page + d, -3h,length/20) ; + + draw crop_gray((0,0,0,1),length, w,-xpart llcorner page,-ypart llcorner page + d ,w/20) ; + draw crop_gray((1,0,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d + 1length/3,w/20) ; + draw crop_gray((0,1,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 0length/3,w/20) ; + draw crop_gray((0,0,1,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 1length/3,w/20) ; + + setbounds currentpicture to page ; + +enddef ; + +def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + draw crop_marks_gray shifted center(topboundary more) shifted (0, offset+length); + draw crop_marks_cmyk shifted center(bottomboundary more) shifted (0,-offset-length); + + setbounds currentpicture to page ; + +enddef ; + +def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + draw crop_marks_lines(page,length,offset,nx,ny) ; + + setbounds currentpicture to page ; + +enddef ; + +def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + for s=llcorner more, lrcorner more, ulcorner more, urcorner more : + draw textext(decimal n) shifted s ; + endfor ; + + setbounds currentpicture to page ; + +enddef ; diff --git a/metapost/context/base/mpii/mp-shap.mpii b/metapost/context/base/mpii/mp-shap.mpii new file mode 100644 index 000000000..17d21314c --- /dev/null +++ b/metapost/context/base/mpii/mp-shap.mpii @@ -0,0 +1,206 @@ +%D \module +%D [ file=mp-shap.mpii, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=shapes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_shap : endinput ; fi ; + +boolean context_shap ; context_shap := true ; + +path predefined_shapes[] ; + +begingroup ; + +save xradius, yradius, xxradius, yyradius ; +save ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; + +numeric xradius, yradius, xxradius, yyradius ; +pair ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; + +xradius := .15 ; +yradius := .15 ; +xxradius := .10 ; +yyradius := .10 ; + +ll := llcorner (unitsquare shifted (-.5,-.5)) ; +lr := lrcorner (unitsquare shifted (-.5,-.5)) ; +ur := urcorner (unitsquare shifted (-.5,-.5)) ; +ul := ulcorner (unitsquare shifted (-.5,-.5)) ; + +llx := ll shifted (xradius,0) ; +lly := ll shifted (0,yradius) ; + +lrx := lr shifted (-xradius,0) ; +lry := lr shifted (0,yradius) ; + +urx := ur shifted (-xradius,0) ; +ury := ur shifted (0,-yradius) ; + +ulx := ul shifted (xradius,0) ; +uly := ul shifted (0,-yradius) ; + +llxx := ll shifted (xxradius,0) ; +llyy := ll shifted (0,yyradius) ; + +lrxx := lr shifted (-xxradius,0) ; +lryy := lr shifted (0,yyradius) ; + +urxx := ur shifted (-xxradius,0) ; +uryy := ur shifted (0,-yyradius) ; + +ulxx := ul shifted (xxradius,0) ; +ulyy := ul shifted (0,-yyradius) ; + +lc := ll shifted (0,.5) ; +rc := lr shifted (0,.5) ; +tc := ul shifted (.5,0) ; +bc := ll shifted (.5,0) ; + +predefined_shapes[ 0] := (origin--cycle) ; +predefined_shapes[ 5] := (llx--lrx{right}...rc...{left}urx--ulx{left}...lc...{right}cycle) ; +predefined_shapes[ 6] := (ll--lrx{right}...rc...{left}urx--ul--cycle) ; +predefined_shapes[ 7] := (ll--lrx{right}...rc...{left}urx--ul--cycle) rotatedaround(origin,180) ; +predefined_shapes[ 8] := (lr--ury{up}...tc...{down}uly--ll--cycle) ; +predefined_shapes[ 9] := (lr--ury{up}...tc...{down}uly--ll--cycle) rotatedaround(origin,180) ; +predefined_shapes[10] := (ll--lr--ur--ul--ll--ur--ul--ll--cycle) ; +predefined_shapes[11] := (ll--lr--ur--ul--ll--lr--ul--ll--cycle) ; +predefined_shapes[12] := (ll--lrx--ur--ulx--cycle) ; +predefined_shapes[13] := (llx--lr--urx--ul--cycle) ; +predefined_shapes[14] := (lly--bc--lry--ury--tc--uly--cycle) ; +predefined_shapes[15] := (llx--lrx--rc--urx--ulx--lc--cycle) ; +predefined_shapes[16] := (ll--lrx--rc--urx--ul--cycle) ; +predefined_shapes[17] := (ll--lrx--rc--urx--ul--cycle) rotatedaround(origin,180) ; +predefined_shapes[18] := (lr--ury--tc--uly--ll--cycle) ; +predefined_shapes[19] := (lr--ury--tc--uly--ll--cycle) rotatedaround(origin,180) ; +predefined_shapes[20] := (ll--lr--ur--ul--ll--llxx--ulxx--ul--ll--lr--ur--urxx--lrxx--cycle) ; +predefined_shapes[21] := (ul--ll--lr--ur--ul--ulyy--uryy--ur--ul--ll--lr--lryy--llyy--cycle) ; +predefined_shapes[22] := (ll--lrx--lry--ur--ulx--uly--cycle) ; +predefined_shapes[23] := (llx--lr--ury--urx--ul--lly--cycle) ; +predefined_shapes[24] := (ll--lr--ur--ul--cycle) ; +predefined_shapes[25] := (llx--lrx--lry--ury--urx--ulx--uly--lly--cycle) ; +predefined_shapes[26] := (ll--lrx--lry--ur--ul--cycle) ; +predefined_shapes[27] := (ll--lr--ury--urx--ul--cycle) rotatedaround(origin,180) ; +predefined_shapes[28] := (ll--lr--ury--urx--ul--cycle) ; +predefined_shapes[29] := (ll--lrx--lry--ur--ul--cycle) rotatedaround(origin,180) ; +predefined_shapes[30] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) rotated 45; +predefined_shapes[31] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; +predefined_shapes[32] := (ll{right}...{right}lry--ur--ul--ll--cycle) ; +predefined_shapes[33] := (ll{right}...{right}lry--ur--ul--ll--cycle--ul--ulx--ulx shifted(0,yyradius)--ur shifted(yyradius,yyradius)--lry shifted(yyradius,yyradius)--lry shifted(0,yyradius)--ur--ul--cycle ) ; +predefined_shapes[34] := (uly..tc..ury & ury..tc shifted (0,-2yradius)..uly & uly--lly & lly..bc..lry & lry--ury & ury..tc shifted (0,-2yradius)..uly & cycle ) ; +predefined_shapes[35] := (bc{right}...rc{up}...tc{left}...lc{down}...cycle) ; +predefined_shapes[36] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) ; +predefined_shapes[37] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) rotatedaround(origin,180) ; +predefined_shapes[38] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) ; +predefined_shapes[39] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) rotatedaround(origin,180) ; +predefined_shapes[40] := (ll--lr--ur--ul--ll--ur--ul--ll--lr--ul--ll--cycle) ; +predefined_shapes[41] := (ll--lr--ur--ul--ll--lr--rc--lc--ll--bc--tc--ul--ll & cycle) ; +predefined_shapes[42] := (ll--lr--origin shifted (+epsilon,0)--ur--ul--origin shifted (-epsilon,0)--cycle) ; +predefined_shapes[43] := (ll--ul--origin shifted (0,+epsilon)--ur--lr--origin shifted (0,-epsilon)--cycle) ; +predefined_shapes[45] := (bc--rc--tc--lc--cycle) ; +predefined_shapes[46] := (ll--ul--rc--cycle) ; +predefined_shapes[47] := (ll--ul--rc--cycle) rotatedaround(origin,180) ; +predefined_shapes[48] := (ul--ur--bc--cycle) rotatedaround(origin,180) ; +predefined_shapes[49] := (ul--ur--bc--cycle) ; +predefined_shapes[56] := (ll--lry--ury--ul--cycle) ; +predefined_shapes[57] := (ll--lry--ury--ul--cycle) rotatedaround(origin,180) ; +predefined_shapes[58] := (ll--ulx--urx--lr--cycle) ; +predefined_shapes[59] := (ll--ulx--urx--lr--cycle) rotatedaround(origin,180); +predefined_shapes[66] := (rc--origin shifted ( epsilon,0) --cycle & rc--origin--cycle ) ; +predefined_shapes[67] := (lc--origin shifted (-epsilon,0) --cycle & lc--origin--cycle ) ; +predefined_shapes[68] := (tc--origin shifted (0, epsilon) --cycle & tc--origin--cycle ) ; +predefined_shapes[69] := (bc--origin shifted (0,-epsilon) --cycle & bc--origin--cycle ) ; +predefined_shapes[75] := (lly--lry--ury--uly--cycle) rotatedaround(origin,180) ; +predefined_shapes[76] := (ll--lr--ur--uly--cycle) rotatedaround(origin,180) ; +predefined_shapes[77] := (ll--lr--ury--ul--cycle) rotatedaround(origin,180) ; +predefined_shapes[78] := (lly--lr--ur--ul--cycle) rotatedaround(origin,180) ; +predefined_shapes[79] := (ll--lry--ur--ul--cycle) rotatedaround(origin,180) ; + +numeric predefined_shapes_xradius ; predefined_shapes_xradius := xradius ; +numeric predefined_shapes_yradius ; predefined_shapes_yradius := yradius ; +numeric predefined_shapes_xxradius ; predefined_shapes_xxradius := xxradius ; +numeric predefined_shapes_yyradius ; predefined_shapes_yyradius := yyradius ; + +endgroup ; + +vardef some_shape_path (expr type) = + if known predefined_shapes[type] : predefined_shapes[type] else : predefined_shapes[0] fi +enddef ; + +def some_shape (expr shape_type, shape_width, shape_height, shape_linewidth, shape_linecolor, shape_fillcolor) = + begingroup ; + save p ; path p ; + p := some_shape_path (shape_type) xscaled shape_width yscaled shape_height ; + pickup pencircle scaled shape_linewidth ; + fill p withcolor shape_fillcolor ; + draw p withcolor shape_linecolor ; + endgroup ; +enddef ; + +vardef drawpredefinedshape (expr t, p, lw, lc, fc) = + save pp ; + if t>1 : % normal shape + path pp ; + pp := some_shape_path(t) xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + fill pp withcolor fc ; + draw pp withpen pencircle scaled lw withcolor lc ; + elseif t=1 : % background only + path pp ; + pp := fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + fill pp withcolor fc ; + else : % dimensions only + picture pp ; pp := nullpicture ; + setbounds pp to fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + draw pp ; + fi ; +enddef ; + +vardef drawpredefinedline (expr t, p, lw, lc) = + if (t>0) and (length(p)>1) : + saveoptions ; + drawoptions(withpen pencircle scaled lw withcolor lc) ; + draw p ; + if t = 1 : + draw arrowheadonpath(p,1) ; + elseif t = 2 : + draw arrowheadonpath(reverse p,1) ; + elseif t = 3 : + for $ = p,reverse p : + draw arrowheadonpath($,1) ; + endfor ; + elseif t = 11 : + draw arrowheadonpath(p,1/2) ; + elseif t = 12 : + draw arrowheadonpath(reverse p,1/2) ; + elseif t = 13 : + for $=p,reverse p : + draw arrowheadonpath($,1) ; + endfor ; + for $=p,reverse p : + draw arrowheadonpath($,3/4) ; + endfor ; + elseif t = 21 : + for $=1/5,1/2,4/5 : + draw arrowheadonpath(p,$) ; + endfor ; + elseif t = 22 : + for $=1/5,1/2,4/5 : + draw arrowheadonpath(reverse p,$) ; + endfor ; + elseif t = 23 : + for $=p,reverse p : + draw arrowheadonpath($,1/4) ; + endfor ; + fi ; + fi ; +enddef ; + +let drawshape = drawpredefinedshape ; +let drawline = drawpredefinedline ; diff --git a/metapost/context/base/mpii/mp-spec.mpii b/metapost/context/base/mpii/mp-spec.mpii new file mode 100644 index 000000000..19d81f312 --- /dev/null +++ b/metapost/context/base/mpii/mp-spec.mpii @@ -0,0 +1,782 @@ +%D \module +%D [ file=mp-spec.mpii, +%D version=1999.6.26, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=special extensions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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. + +% Spot colors are not handled by mptopdf ! + +% let graycolor = numeric ; +% let greycolor = numeric ; +% let withanycolor = withcolor ; + +% rgbcolor red ; red := (1,0,0) ; +% rgbcolor green ; green := (0,1,0) ; +% rgbcolor blue ; blue := (0,0,1) ; +% cmykcolor cyan ; cyan := (1,0,0,0) ; +% cmykcolor magenta ; magenta := (0,1,0,0) ; +% cmykcolor yellow ; yellow := (0,0,1,0) ; +% graycolor black ; black := 0 ; % (0) ; +% graycolor white ; white := 1 ; % (1) ; + +% primarydef p withcolor c = +% p withanycolor (c) +% enddef ; + +% fill fullcircle scaled 10cm withcolor cyan ; +% fill fullcircle scaled 7cm withcolor red ; +% fill fullcircle scaled 4cm withcolor white ; + +% (r,g,b) => cmyk : r=123 g= 1 b=hash +% => spot : r=123 g= 2 b=hash +% => transparent rgb : r=123 g= 3 b=hash +% => transparent cmyk : r=123 g= 4 b=hash +% => transparent spot : r=123 g= 5 b=hash +% => rest : r=123 g=n>10 b=whatever + +%D This module is rather preliminary and subjected to +%D changes. Here we closely cooperates with the \METAPOST\ +%D to \PDF\ converter module built in \CONTEXT\ and provides +%D for instance shading. More information can be found in +%D type {supp-mpe.tex}. + +if known context_spec : endinput ; fi ; + +boolean context_spec ; context_spec := true ; + +numeric _special_counter_ ; _special_counter_ := 0 ; +numeric _color_counter_ ; _color_counter_ := 11 ; % < 10 reserved +numeric _special_signal_ ; _special_signal_ := 123 ; + +numeric _special_div_ ; _special_div_ := 1000 ; + +%D When set to \type {true}, shading will be supported. Some +%D day I will also write an additional directive. + +boolean _inline_specials_ ; _inline_specials_ := false ; + +%D Because we want to output only those specials that are +%D actually used in a figure, we need a bit complicated +%D bookkeeping and collection of specials. At the cost of some +%D obscurity, we now have rather efficient resources. + +string _global_specials_ ; _global_specials_ := "" ; +string _local_specials_ ; _local_specials_ := "" ; + +% vardef add_special_signal = % write the version number +% if (length _global_specials_>0) or (length _local_specials_ >0) : +% special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; +% fi ; +% enddef ; +% +% After some reported problems at the \CONTEXT\ mailing list, +% Taco's came up with: + +% TH: \quotation {Ok, got it. There is a bug in mp-spec.mp (inside metafun). +% Because of a wrapping number, it fails to recognize the fact that there +% are embedded specials at all.} The corrected definition is: + +vardef add_special_signal = % write the version number + if (length _global_specials_ <> 0) or (length _local_specials_ <> 0) : + special ("%%MetaPostSpecials: 2.0 " & decimal _special_signal_ & " " & decimal _special_div_) ; + fi ; +enddef ; + +% \quotation {It now tests for \quote {not equal to zero} instead of +% \quote {larger than zero}: because of all the included files, the +% string \type {_local_specials_} becomes longer than the maximum number +% \quote {length} can return, so it returns -32768 instead, and that is +% of course less than zero.} + +vardef add_extra_specials = + scantokens _global_specials_ ; + scantokens _local_specials_ ; +enddef ; + +vardef reset_extra_specials = + % only local ones + _local_specials_ := "" ; +enddef ; + +boolean insidefigure ; insidefigure := false ; + +% todo: alleen als special gebruikt flush + +extra_beginfig := + " insidefigure := true ; " & + " reset_extra_specials ; " & + extra_beginfig & + " ; " ; + +extra_endfig := + " ; " & + " add_special_signal ; " & + extra_endfig & + " add_extra_specials ; " & + " reset_extra_specials ; " & + " insidefigure := false ; " ; + +def set_extra_special (expr s) = + if insidefigure : + _local_specials_ := _local_specials_ & s ; + else : + _global_specials_ := _global_specials_ & s ; + fi +enddef ; + +def flush_special (expr typ, siz, dat) = + _special_counter_ := _special_counter_ + 1 ; + if _inline_specials_ : + set_extra_special + ( "special " + & "(" & ditto + & dat & " " + & decimal _special_counter_ & " " + & decimal typ & " " + & decimal siz + & " special" + & ditto & ");" ) ; + else : + set_extra_special + ( "special " + & "(" & ditto + & "%%MetaPostSpecial: " + & decimal siz & " " + & dat & " " + & decimal _special_counter_ & " " + & decimal typ + & ditto & ");" ) ; + fi ; +enddef ; + +%D The next hack is needed in case you use a version of +%D \METAPOST\ that does not provide you the means to configure +%D the buffer size. Patrick Gundlach suggested to use arrays +%D in this case. + +boolean bufferhack ; bufferhack := false ; % true ; + +if bufferhack : + + string _global_specials_[] ; numeric _nof_global_specials_ ; + string _local_specials_[] ; numeric _nof_local_specials_ ; + + _nof_global_specials_ := _nof_local_specials_ := 0 ; + + vardef add_special_signal = % write the version number + if (_nof_global_specials_>0) or (_nof_local_specials_>0) : + special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; + fi ; + enddef ; + + vardef add_extra_specials = + for i=1 upto _nof_global_specials_ : + scantokens _global_specials_[i] ; + endfor; + for i=1 upto _nof_local_specials_ : + scantokens _local_specials_[i] ; + endfor; + enddef ; + + vardef reset_extra_specials = + string _local_specials_[] ; _nof_local_specials_ := 0 ; + enddef ; + + def set_extra_special (expr s) = + if insidefigure : + _local_specials_[incr(_nof_local_specials_)] := s ; + else : + _global_specials_[incr(_nof_global_specials_)] := s ; + fi + enddef ; + +fi ; + +%D So far for this hack. + +%D Shade allocation. + +newinternal shadefactor ; shadefactor := 1 ; + +pair shadeoffset ; shadeoffset := origin ; + +% vardef define_linear_shade (expr a, b, ca, cb) = +% flush_special(30, 15, "0 1 " & decimal shadefactor & " " & +% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & +% dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; +% _special_counter_ +% enddef ; + +% vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = +% flush_special(31, 17, "0 1 " & decimal shadefactor & " " & +% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & +% dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; +% _special_counter_ +% enddef ; + +% these tests are not yet robust for new gray/cmyk features; +% +% - we need to get rid of cmykcolor() and + +vardef _is_cmyk_(expr c) = + (redpart c = _special_signal_/_special_div_) and (greenpart c = 1/_special_div_) +enddef ; +vardef _is_spot_(expr c) = + (redpart c = _special_signal_/_special_div_) and (greenpart c = 2/_special_div_) +enddef ; +vardef _is_gray_(expr c) = + (redpart c = greenpart c) and (greenpart c = bluepart c) +enddef ; + +numeric mp_shade_version ; mp_shade_version := 2 ; % more colors, needs new backend + +vardef define_linear_shade (expr a, b, ca, cb) = + save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; + save gray_a, gray_b ; boolean gray_a, gray_b ; + cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; + cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; + if (mp_shade_version > 1) and cmyk_a and cmyk_b : + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and cmyk_a and gray_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and gray_a and cmyk_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : + flush_special(34, 17, "0 1 " & decimal shadefactor & " " & + spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + else : + flush_special(30, 15, "0 1 " & decimal shadefactor & " " & + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; + fi ; + _special_counter_ +enddef ; + +vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = + save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; + save gray_a, gray_b ; boolean gray_a, gray_b ; + cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; + cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; + if (mp_shade_version > 1) and cmyk_a and cmyk_b : + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and cmyk_a and gray_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and gray_a and cmyk_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : + flush_special(35, 19, "0 1 " & decimal shadefactor & " " & + spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + else : + flush_special(31, 17, "0 1 " & decimal shadefactor & " " & + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + fi ; + _special_counter_ +enddef ; + +%D A few predefined shading macros. + +boolean trace_shades ; trace_shades := false ; + +% if (n=1) : a := llcorner p ; b := urcorner p ; +% elseif (n=2) : a := llcorner p ; b := ulcorner p ; +% elseif (n=3) : a := lrcorner p ; b := ulcorner p ; +% else : a := llcorner p ; b := lrcorner p ; +% fi ; + +def set_linear_vector (suffix a,b)(expr p,n) = + if (n=1) : a := llcorner p ; + b := urcorner p ; + elseif (n=2) : a := lrcorner p ; + b := ulcorner p ; + elseif (n=3) : a := urcorner p ; + b := llcorner p ; + elseif (n=4) : a := ulcorner p ; + b := lrcorner p ; + elseif (n=5) : a := .5[ulcorner p,llcorner p] ; + b := .5[urcorner p,lrcorner p] ; + elseif (n=6) : a := .5[llcorner p,lrcorner p] ; + b := .5[ulcorner p,urcorner p] ; + elseif (n=7) : a := .5[lrcorner p,urcorner p] ; + b := .5[llcorner p,ulcorner p] ; + elseif (n=8) : a := .5[urcorner p,ulcorner p] ; + b := .5[lrcorner p,llcorner p] ; + else : a := .5[ulcorner p,llcorner p] ; + b := .5[urcorner p,lrcorner p] ; + fi ; +enddef ; + +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 ; + elseif (n=4) : ab := ulcorner p ; + else : ab := center p ; r := .5r ; + fi ; +enddef ; + +def linear_shade (expr p, n, ca, cb) = + begingroup ; + save a, b, sh ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + fill p withshade define_linear_shade (a,b,ca,cb) ; + if trace_shades : + drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +def circular_shade (expr p, n, ca, cb) = + begingroup ; + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ + (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ; + if trace_shades : + drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +vardef predefined_linear_shade (expr p, n, ca, cb) = + save a, b, sh ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + define_linear_shade (a,b,ca,cb) +enddef ; + +vardef predefined_circular_shade (expr p, n, ca, cb) = + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + define_circular_shade(ab,ab,0,r,ca,cb) +enddef ; + +%D Since a \type {fill p withshade s} syntax looks better +%D than some macro, we implement a new primary. + +primarydef p withshade sc = % == p withcolor shadecolor(sh) + hide (_color_counter_ := _color_counter_ + 1) + p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) +enddef ; + +vardef shadecolor(expr sc) = + hide (_color_counter_ := _color_counter_ + 1) + (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) +enddef ; + +%D Figure inclusion. + +%numeric cef ; cef := 0 ; + +def externalfigure primary filename = + doexternalfigure (filename) +enddef ; + +def doexternalfigure (expr filename) text transformation = + begingroup ; save p, t ; picture p ; transform t ; + p := nullpicture ; t := identity transformation ; + flush_special(10, 9, + dddecimal (xxpart t, yxpart t, xypart t) & " " & + dddecimal (yypart t, xpart t, ypart t) & " " & filename) ; + addto p contour unitsquare scaled 0 ; + setbounds p to unitsquare transformed t ; + _color_counter_ := _color_counter_ + 1 ; + draw p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; + endgroup ; +enddef ; + +%D Experimental: + +%numeric currenthyperlink ; currenthyperlink := 0 ; + +def hyperlink primary t = dohyperlink(t) enddef ; +def hyperpath primary t = dohyperpath(t) enddef ; + +def dohyperlink (expr destination) text transformation = + begingroup ; save somepath ; path somepath ; + somepath := fullsquare transformation ; + dohyperpath(destination) somepath ; + endgroup ; +enddef ; + +def dohyperpath (expr destination) expr somepath = + begingroup ; + flush_special(20, 7, + ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " & + ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ; + _color_counter_ := _color_counter_ + 1 ; + fill boundingbox unitsquare scaled 0 withcolor + (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; + endgroup ; +enddef ; + +% \setupinteraction[state=start] +% \setupcolors [state=start] +% +% Hello There! \blank +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 4cm withcolor red ; +% hyperpath "nextpage" boundingbox currentpicture ; +% draw origin withcolor blue ; +% \stopMPcode +% +% \blank Does it work or not? +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 4cm withcolor red ; +% hyperpath "nextpage" fullcircle scaled 4cm ; +% draw origin withcolor blue ; +% draw fullcircle scaled 4cm shifted (1cm,1cm); +% \stopMPcode +% +% \blank Does it work or not? \page Hello There! \blank +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ; +% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ; +% draw fullcircle scaled 1cm ; +% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ; +% draw origin withcolor blue ; +% \stopMPcode +% +% \blank Does it work or not? + +_cmyk_counter_ := 0 ; + +extra_endfig := " ; resetcmykcolors ; " & extra_endfig ; + +def resetcmykcolors = + numeric cmykcolorhash[][][][] ; +enddef ; + +resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true + +string cmykcolorpattern[] ; % needed for transparancies + +vardef cmyk(expr c,m,y,k) = + if cmykcolors : + save ok ; boolean ok ; + if unknown cmykcolorhash[c][m][y][k] : + ok := false ; % not yet defined + elseif cmykcolorhash[c][m][y][k] = -1 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : +% save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; + save s ; string s ; s := ddddecimal (c,m,y,k) ; + _cmyk_counter_ := _cmyk_counter_ + 1 ; + cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; + cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; + flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; + _local_specials_ := _local_specials_ & + " cmykcolorhash[" & decimal c & "][" & decimal m & + "][" & decimal y & "][" & decimal k & "] := -1 ; " ; + fi ; + (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) + else : + (1-c-k,1-m-k,1-y-k) + fi +enddef ; + +% newcolor truecyan, truemagenta, trueyellow ; +% +% truecyan = (1,0,0,0) ; +% truemagenta = (0,1,0,0) ; +% trueyellow = (0,0,1,0) ; + +%D Spot colors + +_spotcolor_counter_ := 0 ; +_spotcolor_number_ := 0 ; + +extra_endfig := " ; resetspotcolors ; " & extra_endfig ; + +def resetspotcolors = + numeric spotcolorhash[][] ; +enddef ; + +resetspotcolors ; boolean spotcolors ; spotcolors := false ; % true + +string spotcolorpattern[] ; % needed for transparancies + +vardef spotcolor(expr p, s) = + multitonecolor(p, 1, "", decimal s) +enddef ; + +vardef multitonecolor(expr n, f, d, p) = % name fractions names factors + if spotcolors : + save ok, pc_tag ; boolean ok ; string pc_tag ; + pc_tag := "_pct_" & n ; + if not unstringed(pc_tag) : + _spotcolor_number_ := _spotcolor_number_ + 1 ; + setunstringed(pc_tag,_spotcolor_number_) ; + fi ; + pp := getunstringed(pc_tag) ; + pc_tag := "_pct_"& decimal f & "_" & if d = "" : n else : d fi & "_" & p ; % check for d empty + if not unstringed(pc_tag) : + _spotcolor_number_ := _spotcolor_number_ + 1 ; + setunstringed(pc_tag,_spotcolor_number_) ; + fi ; + ps := getunstringed(pc_tag) ; + if unknown spotcolorhash[pp][ps] : + ok := false ; % not yet defined + elseif spotcolorhash[pp][ps] = -1 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : + save ss ; string ss ; ss := n & " " & decimal f & " " & if d = "" : n else : d fi & " " & p ; + _spotcolor_counter_ := _spotcolor_counter_ + 1 ; + spotcolorpattern[_spotcolor_counter_/_special_div_] := ss ; + spotcolorhash[pp][ps] := _spotcolor_counter_ ; + flush_special(2, 7, decimal _spotcolor_counter_ & " " & ss) ; + _local_specials_ := _local_specials_ & + "spotcolorhash["&decimal pp&"]["&decimal ps&"]:=-1;" ; + fi ; + (_special_signal_/_special_div_,2/_special_div_,spotcolorhash[pp][ps]/_special_div_) + else : + .5white + fi +enddef ; + +%D Transparency + +normaltransparent := 1 ; multiplytransparent := 2 ; +screentransparent := 3 ; overlaytransparent := 4 ; +softlighttransparent := 5 ; hardlighttransparent := 6 ; +colordodgetransparent := 7 ; colorburntransparent := 8 ; +darkentransparent := 9 ; lightentransparent := 10 ; +differencetransparent := 11 ; exclusiontransparent := 12 ; + +% nottransparent := 0 ; +% compatibletransparent := 99 ; + +% fill fullcircle scaled 10cm withcolor transparant(8,.3,red) ; + +vardef transparent(expr n, t, c) = + save s, ss, nn, cc, is_cmyk, is_spot, ok ; + string s, ss ; numeric nn ; color cc ; boolean is_cmyk, is_spot, ok ; + % transparancy type + if string n : + if expandafter known scantokens(n&"transparent") : + nn := scantokens(n&"transparent") ; + else : + nn := 0 ; + fi + else : % nn := min(n,13) + nn := if n<13 : n else : nn := 0 fi ; + fi ; + % we need to expand the color (can be cmyk(..) or predefined) + cc := c ; % expand color + % check for cmyk special + is_cmyk := (redpart cc = _special_signal_/_special_div_) + and (greenpart cc = 1/_special_div_) ; + is_spot := (redpart cc = _special_signal_/_special_div_) + and (greenpart cc = 2/_special_div_) ; + % build special string, fetch cmyk components + s := decimal nn & " " & decimal t & " " & + if is_cmyk : cmykcolorpattern[bluepart cc] + elseif is_spot : spotcolorpattern[bluepart cc] + else : dddecimal cc fi ; + % check if this one is already used + ss := cleanstring("tr_" & s) ; + % we now have rather unique names, i.e. a color spec of .234 becomes + % tr..._234.... and metapost gives a number overflow (parse error) + % for variables like tr_12345678 which may result from many decimal + % positions (imo mp bug) + ss := asciistring(ss) ; + % efficiency hack + if expandafter unknown scantokens(ss) : + ok := false ; % not yet defined + elseif scantokens(ss) < 0 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : + if is_spot : + flush_special(5, 8, s) ; + elseif is_cmyk : + flush_special(4, 8, s) ; + else : + flush_special(3, 7, s) ; + fi ; + scantokens(ss) := _special_counter_ ; + _local_specials_ := _local_specials_ & "scantokens(" & ditto & ss & ditto & ") := -1 ;" ; + fi ; + % go ahead + if is_spot : + (_special_signal_/_special_div_,5/_special_div_,scantokens(ss)/_special_div_) + elseif is_cmyk : + (_special_signal_/_special_div_,4/_special_div_,scantokens(ss)/_special_div_) + else : + (_special_signal_/_special_div_,3/_special_div_,scantokens(ss)/_special_div_) + fi +enddef ; + +%D This function returns true of false, dependent on transparency. + +vardef is_transparent(text t) = + begingroup ; save transparent ; save _c_, _b_ ; + vardef transparent(expr nn, tt, cc) = _b_ := true ; cc enddef ; + boolean _b_ ; _b_ := false ; + color _c_ ; _c_ := t ; _b_ + endgroup +enddef ; + +% boolean _b_ ; better namespacing +% color _c_ ; +% vardef _transparent_(expr nn, tt, cc) = _b_ := true ; cc enddef ; +% vardef is_transparent(text t) = +% begingroup ; +% save transparent ; +% transparent := _transparent_ ; +% _b_ := false ; +% _c_ := t ; _b_ +% endgroup +% enddef ; + +%D This function returns the not transparent color. + +vardef not_transparent(text t) = + begingroup ; save transparent ; + vardef transparent(expr nn, tt, cc) = cc enddef ; + t endgroup +enddef ; + +%D Basic position tracking: + +def register (expr label, width, height, offset) = + begingroup ; + flush_special(50, 7, + ddecimal offset & " " & + decimal width & " " & + decimal height & " " & label) ; + endgroup ; +enddef ; + +%D We cannot scale cmyk colors directly since this spoils +%D the trigger signal (such colors are no real colors). + +vardef scaledcmyk(expr c,m,y,k,sf) = + cmyk(sf*c,sf*m,sf*y,sf*k) +enddef ; + +vardef scaledcmykasrgb(expr c,m,y,k,sf) = + (sf*(1-c-k,1-m-k,1-y-k)) +enddef ; + +vardef scaledrgbascmyk(expr c,m,y,k,sf) = + scaledcmyk(1-c,1-m,1-y,0,sf) +enddef ; + +vardef scaledrgb(expr r,g,b,sf) = + (sf*(r,g,b)) +enddef ; + +vardef scaledgray(expr s,sf) = + (sf*(s,s,s)) +enddef ; + +% spotcolor is already scaled + +% just an exercise (due to a question by Chof on the context mailing list); scaling of +% 'special' colors is not possible and the next solution is incomplete (spot colors, +% transparency, etc); watch the the tricky chained macro construction + +% vardef normalgray(expr s ) = (s,s,s) enddef ; +% vardef normalrgb (expr r,g,b ) = (r,g,b) enddef ; +% vardef normalcmyk(expr c,m,y,k) = if cmykcolors : save ok ; boolean ok ; if unknown cmykcolorhash[c][m][y][k] : ok := false ; elseif cmykcolorhash[c][m][y][k] = -1 : ok := false ; else : ok := true ; fi ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; _cmyk_counter_ := _cmyk_counter_ + 1 ; cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" & decimal c & "][" & decimal m & "][" & decimal y & "][" & decimal k & "] := -1 ; " ; fi ; (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) else : (1-c-k,1-m-k,1-y-k) fi enddef ; + +% vardef gray(expr s) = normalgray(s ) enddef ; +% vardef rgb (expr r,g,b) = normalrgb (r,g,b ) enddef ; +% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; + +% numeric _scaled_color_t_ ; +% color _scaled_color_c_ ; + +% def withscaledcolor = +% hide ( +% _scaled_color_t_ := 0 ; % direct +% def gray(expr s) = +% hide ( +% _gray_s_ := s ; +% _scaled_color_t_ := 1; % gray +% ) +% 0 +% enddef ; +% def rgb (expr r,g,b) = +% hide ( +% _rgb_r_ := r ; _rgb_g_ := g ; _rgb_b_ := b ; +% _scaled_color_t_ := 2 ; % rgb +% ) +% 0 +% enddef ; +% def cmyk (expr c,m,y,k) = +% hide ( +% _cmyk_c_ := c ; _cmyk_m_ := m ; _cmyk_y_ := y ; _cmyk_k_ := k ; +% _scaled_color_t_ := 3 ; % cmyk +% ) +% 0 +% enddef ; ) +% dowithscaledcolor +% enddef ; + +% def dowithscaledcolor expr t = +% hide ( +% if color t : _scaled_color_c_ := t fi ; +% vardef gray(expr s) = normalgray(s) enddef ; +% vardef rgb (expr r,g,b) = normalrgb (r,g,b) enddef ; +% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; +% ) +% enddef ; + +% def by expr s = +% if _scaled_color_t_ = 0 : +% withcolor s*_scaled_color_c_ +% elseif _scaled_color_t_ = 1 : +% withcolor gray(s*_gray_s_) +% elseif _scaled_color_t_ = 2 : +% withcolor rgb (s*_rgb_r_, s*_rgb_g_, s*_rgb_b_) +% elseif _scaled_color_t_ = 3 : +% withcolor cmyk(s*_cmyk_c_, s*_cmyk_m_, s*_cmyk_y_, s*_cmyk_k_) +% fi +% enddef ; + +% fill fullcircle scaled 10cm withscaledcolor cmyk(0,0,1,0) by .5 ; +% fill fullcircle scaled 8cm withscaledcolor rgb (0,0,1) by .5 ; +% fill fullcircle scaled 6cm withscaledcolor gray(1) by .5 ; +% fill fullcircle scaled 4cm withscaledcolor (0,1,0) by .5 ; diff --git a/metapost/context/base/mpii/mp-step.mpii b/metapost/context/base/mpii/mp-step.mpii new file mode 100644 index 000000000..e05f00b6e --- /dev/null +++ b/metapost/context/base/mpii/mp-step.mpii @@ -0,0 +1,317 @@ +%D \module +%D [ file=mp-step.mpii, +%D version=2001.05.22, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=steps, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_step : endinput ; fi ; + +boolean context_step ; context_step := true ; + +%D In the associated \TEX\ module \type {m-steps}, we describe +%D three methods. The first method uses a different kind of +%D code than the other two. The method we decided to use, +%D is based on positional information (paths) provided by +%D \CONTEXT. + +def initialize_step_variables = + save line_method, line_h_offset, line_v_offset ; + numeric line_method ; line_method := 1 ; + numeric line_h_offset ; line_h_offset := 3pt ; + numeric line_v_offset ; line_v_offset := 3pt ; +enddef ; + +def begin_step_chart = + initialize_step_variables ; + save steps, texts, t, b, tb, nofcells ; + picture cells[][], texts[][][], lines[][][] ; + numeric t, b ; t := 1 ; b := 2 ; + numeric nofcells ; nofcells := 0 ; +enddef ; + +def analyze_step_chart = + numeric n[], l[][], r[][] ; pair p[] ; + n[t] := n[b] := 0 ; numeric tb ; + for i=1 upto nofcells : for nn = t, b : + if bbwidth(cells[nn][i])>0 : n[nn] := n[nn] + 1 ; fi ; + l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ; + endfor ; endfor ; + % count left and right points + for i=1 upto nofcells-1 : for j=i upto nofcells-1 : for nn = t, b : + if bbwidth(texts[nn][i][j])>0 : + l[nn][i] := l[nn][i] + 1 ; + r[nn][j+1] := r[nn][j+1] + 1 ; + fi ; + endfor ; endfor ; endfor ; + % calculate left and right points + vardef do (expr nn, mm, ii, ss) = + if (l[nn][ii] + r[nn][ii]) > 1 : ss else : .5 fi + [ ulcorner cells[mm][ii], urcorner cells[mm][ii] ] + enddef ; + % combined rows + tb := if n[t]>0 : t else : b fi ; +enddef ; + +vardef get_step_chart_top_line (expr i, j) = + if bbwidth(cells[tb][i])>0 : + if bbwidth(texts[t][i][j])>0 : + if bbwidth(cells[tb][j+1])>0 : + p[1] := top do(t, tb, i, .6) ; + p[3] := top do(t, tb, j+1, .4) ; + p[2] := .5[p[1],p[3]] ; + if line_method = 1 : + p[2] := p[2] shifted (0, ypart + (llcorner texts[t][i][j] - ulcorner cells[tb][j+1])) ; + elseif line_method = 2 : + p[2] := center texts[t][i][j] ; + else : + % nothing + fi ; + p[1] := p[1] shifted (0,+line_v_offset) ; + p[2] := p[2] shifted (0,-line_v_offset) ; + p[3] := p[3] shifted (0,+line_v_offset) ; + (p[1] {up} ... p[2] ... {down} p[3]) + else : + origin + fi + else : + origin + fi + else : + origin + fi +enddef ; + +vardef get_step_chart_bot_line (expr i, j) = + if bbwidth(cells[b][i])>0 : + if bbwidth(texts[b][i][j])>0 : + if bbwidth(cells[b][j+1])>0 : + p[1] := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ; + p[3] := (bot do(b, b, j+1, .4)) shifted (0,-bbheight(cells[b][j+1])) ; + p[2] := .5[p[1],p[3]] ; + if line_method = 1 : + p[2] := p[2] shifted (0, -ypart + (llcorner cells[b][j+1] - ulcorner texts[b][i][j])) ; + elseif line_method = 2 : + p[2] := center texts[b][i][j] ; + fi ; + p[1] := p[1] shifted (0,-line_v_offset) ; + p[2] := p[2] shifted (0,+line_v_offset) ; + p[3] := p[3] shifted (0,-line_v_offset) ; + (p[1] {down} ... p[2] ... {up} p[3]) + else : + origin + fi + else : + origin + fi + else : + origin + fi +enddef ; + +def end_step_chart = + for i=1 upto nofcells : for nn = t, b : + if bbwidth(cells[nn][i]) >0 : draw cells[nn][i] ; fi ; + endfor ; endfor ; + for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b : + if known lines[nn][i][j] : + if bbwidth(lines[nn][i][j])>0 : draw lines[nn][i][j] ; fi ; + fi ; + endfor ; endfor ; endfor ; + for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b : + if bbwidth(texts[nn][i][j])>0 : draw texts[nn][i][j] ; fi ; + endfor ; endfor ; endfor ; +enddef ; + +%D Step tables. + +def begin_step_table = + initialize_step_variables ; + picture cells[], texts[], lines[] ; + numeric nofcells ; nofcells := 0 ; +enddef ; + +def end_step_table = + for i=1 upto nofcells : if known cells[i] : if bbwidth(cells[i])>0 : + draw cells[i] ; + fi ; fi ; endfor ; + for i=1 upto nofcells : if known lines[i] : if bbwidth(lines[i])>0 : + draw lines[i] ; + fi ; fi ; endfor ; + for i=1 upto nofcells : if known texts[i] : if bbwidth(texts[i])>0 : + draw texts[i] ; + fi ; fi ; endfor ; +enddef ; + +vardef get_step_table_line (expr i) = + pair prev, self, next ; + if known texts[i] : + self := lft .5[llcorner texts[i], ulcorner texts[i] ] ; + prev := rt if known texts[i-1] : .3 else : .5 fi [lrcorner cells[i] , urcorner cells[i] ] ; + next := rt if known texts[i+1] : .7 else : .5 fi [lrcorner cells[i+1], urcorner cells[i+1]] ; + self := self shifted (-line_h_offset,0) ; + prev := prev shifted (+line_h_offset,0) ; + next := next shifted (+line_h_offset,0) ; + prev {right} ... self ... {left} next + else : + origin + fi +enddef ; + +%D The older method let \METAPOST\ do the typesetting. The +%D macros needed for that are included here for educational +%D purposes. +%D +%D \starttypen +%D def initialize_step_variables = +%D save line_color, line_width, arrow_alternative, +%D text_fill_color, text_line_color, text_line_width, text_offset, +%D cell_fill_color, cell_line_color, cell_line_width, cell_offset, +%D line_h_offset, line_v_offset ; +%D color line_color ; line_color := .4white ; +%D numeric line_width ; line_width := 1.5pt ; +%D color text_fill_color ; text_fill_color := white ; +%D color text_line_color ; text_line_color := red ; +%D numeric text_line_width ; text_line_width := 1pt ; +%D numeric text_offset ; text_offset := 2pt ; +%D color cell_fill_color ; cell_fill_color := white ; +%D color cell_line_color ; cell_line_color := blue ; +%D numeric cell_line_width ; cell_line_width := 1pt ; +%D numeric cell_offset ; cell_offset := 2pt ; +%D numeric line_alternative ; line_alternative := 1 ; +%D numeric line_h_offset ; line_h_offset := 3pt ; +%D numeric line_v_offset ; line_v_offset := 3pt ; +%D enddef ; +%D +%D def begin_step_chart = +%D begingroup ; +%D initialize_step_variables ; +%D save steps, texts, t, b ; +%D picture cells[][] ; numeric nofcells ; nofcells := 0 ; +%D picture texts[][][] ; numeric noftexts ; noftexts := 0 ; +%D numeric t, b ; t := 1 ; b := 2 ; +%D enddef ; +%D \stoptypen +%D +%D We use a couple of macros to store the content. In the +%D second (third) alternative we will directly fill the +%D cells. +%D +%D \starttypen +%D def set_step_chart_cells (expr one, two) = +%D nofcells := nofcells + 1 ; noftexts := 0 ; +%D cells[t][nofcells] := textext.rt(one) ; +%D cells[b][nofcells] := textext.rt(two) ; +%D enddef ; +%D +%D def set_step_chart_texts (expr one, two) = +%D noftexts := noftexts + 1 ; +%D texts[t][nofcells][noftexts] := textext.rt(one) ; +%D texts[b][nofcells][noftexts] := textext.rt(two) ; +%D enddef ; +%D \stoptypen +%D +%D If you compare the building macro with the later +%D alternative, you will notice that here we explicitly +%D have to calculate the distances and positions. +%D +%D \starttypen +%D def end_step_chart = +%D numeric dx ; dx := 0 ; path p ; +%D numeric n[] ; n[t] := n[b] := 0 ; +%D numeric stepsvdistance[] ; +%D vardef bbwidth (expr p) = (xpart (lrcorner p - llcorner p)) enddef ; +%D vardef bbheight (expr p) = (ypart (urcorner p - lrcorner p)) enddef ; +%D stepsvdistance[t] := stepsvdistance[b] := 0 ; +%D for i=1 upto nofcells : +%D % find largest bbox +%D p := boundingbox steps +%D [if bbwidth(cells[t][i])>bbwidth(cells[b][i]): t else: b fi][i] ; +%D % assign largest bbox +%D for nn = t, b : +%D if bbwidth(cells[nn][i])>0 : +%D setbounds cells[nn][i] to p enlarged cell_offset ; +%D n[nn] := n[nn] + 1 ; +%D fi ; +%D endfor ; +%D % determine height +%D if n[t]>0 : +%D stepsvdistance[t] := bbheight(cells[t][1]) + intertextdistance ; +%D fi ; +%D % add to row +%D for nn = t, b : +%D cells[nn][i] := cells[nn][i] shifted (dx,stepsvdistance[nn]) ; +%D if bbwidth(cells[nn][i])>0 : +%D dowithpath (boundingbox cells[nn][i], +%D cell_line_width, cell_line_color, cell_background_color) ; +%D fi ; +%D endfor ; +%D % calculate position +%D dx := dx + interstepdistance + bbwidth(cells[b][i]) ; +%D endfor ; +%D boolean stacked ; stacked := false ; +%D numeric l[][], r[][], l[][], r[][] ; +%D pair pa, pb, pc ; path p[] ; +%D for i=1 upto nofcells : +%D l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ; +%D endfor ; +%D % count left and right points +%D for i=1 upto nofcells : for j=1 upto nofcells : for nn = t, b : +%D if known texts[nn][i][j] : if bbwidth(texts[nn][i][j])>0 : +%D l[nn][i] := l[nn][i] + 1 ; +%D r[nn][j+i] := r[nn][j+i] + 1 ; +%D stacked := (stacked or (j>1)) ; +%D setbounds texts[nn][i][j] to boundingbox texts[nn][i][j] enlarged cell_offset ; +%D fi fi ; +%D endfor ; endfor ; endfor ; +%D % calculate left and right points +%D vardef do (expr nn, mm, ii, ss) = +%D if (l[nn][ii] > 0) and (r[nn][ii] > 0) : ss else : .5 fi +%D [ ulcorner cells[mm][ii],urcorner cells[mm][ii] ] +%D enddef ; +%D % draw arrow from left to right point +%D def dodo (expr nn, ii, jj, dd) = +%D drawarrow p[nn] +%D withpen pencircle scaled arrow_line_width +%D withcolor arrow_line_color ; +%D transform tr ; tr := identity +%D shifted point .5 along p[nn] +%D shifted -center texts[nn][ii][jj] +%D if not stacked : shifted (0,dd) fi ; +%D dowithpath ((boundingbox texts[nn][ii][jj]) transformed tr, +%D text_line_width, text_line_color, text_fill_color) ; +%D enddef ; +%D % draw top and bottom text boxes +%D for i=1 upto nofcells : for j=1 upto nofcells : +%D pickup pencircle scaled arrow_line_width ; +%D if known texts[t][i][j] : if bbwidth(texts[t][i][j]) > 0 : +%D pa := top do(t, if n[t]>0 : t else : b fi, i, .6) ; +%D pb := top do(t, if n[t]>0 : t else : b fi, j+i, .4) ; +%D pc := .5[pa,pb] shifted (0,+step_arrow_depth) ; +%D p[t] := pa {up} .. if not stacked : pc .. fi {down} pb ; +%D dodo(t, i, j, +intertextdistance) ; +%D fi fi ; +%D if known texts[b][i][j] : if bbwidth(texts[b][i][j]) > 0 : +%D pa := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ; +%D pb := (bot do(b, b, j+i, .4)) shifted (0,-bbheight(cells[b][j+i])) ; +%D pc := .5[pa,pb] shifted (0,-step_arrow_depth) ; +%D p[b] := pa {down} .. if not stacked : pc .. fi {up} pb ; +%D dodo(b, i, j, -intertextdistance) ; +%D fi fi ; +%D endfor ; endfor ; +%D endgroup ; +%D enddef ; +%D \stoptypen +%D +%D If you compare both methods, you will notice that the +%D first method is the cleanest, but not the most efficient +%D (since it needs \TEX\ runs within \METAPOST\ runs within +%D \TEX\ runs). diff --git a/metapost/context/base/mpii/mp-text.mpii b/metapost/context/base/mpii/mp-text.mpii new file mode 100644 index 000000000..5f96f6788 --- /dev/null +++ b/metapost/context/base/mpii/mp-text.mpii @@ -0,0 +1,275 @@ +%D \module +%D [ file=mp-text.mpii, +%D version=2000.07.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=text support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D Under construction. + +if known context_text : endinput ; fi ; + +boolean context_text ; context_text := true ; + +if unknown noftexpictures : + numeric noftexpictures ; noftexpictures := 0 ; +fi ; + +if unknown texpictures[1] : + picture texpictures[] ; +fi ; + +numeric textextoffset ; textextoffset := 0 ; + +% vardef textext@#(expr txt) = +% interim labeloffset := textextoffset ; +% noftexpictures := noftexpictures + 1 ; +% if string txt : +% write "% figure " & decimal charcode & " : " & +% "texpictures[" & decimal noftexpictures & "] := btex " & +% txt & " etex ;" to jobname & ".mpt" ; +% if unknown texpictures[noftexpictures] : +% thelabel@#("unknown",origin) +% else : +% thelabel@#(texpictures[noftexpictures],origin) +% fi +% else : +% thelabel@#(txt,origin) +% fi +% enddef ; + +boolean hobbiestextext ; hobbiestextext := false ; +% string textextstring ; textextstring := "" ; + +% def resettextextdirective = +% textextstring := "" ; +% enddef ; + +% def textextdirective text t = +% textextstring := textextstring & t ; +% enddef ; + +vardef textext@#(expr txt) = + save _s_ ; string _s_ ; + interim labeloffset := textextoffset ; + noftexpictures := noftexpictures + 1 ; + if string txt : + if hobbiestextext : % the tex.mp method as fallback (see tex.mp) + write _s_ & "btex " & txt & " etex" to "mptextmp.mp" ; + write EOF to "mptextmp.mp" ; + scantokens "input mptextmp" + else : + write "% figure " & decimal charcode & " : " & + "texpictures[" & decimal noftexpictures & "] := btex " & + txt & " etex ;" to jobname & ".mpt" ; + if unknown texpictures[noftexpictures] : + thelabel@#("unknown",origin) + else : + thelabel@#(texpictures[noftexpictures],origin) + fi + fi + else : + thelabel@#(txt,origin) + fi +enddef ; + +string laboff_ ; laboff_ := "" ; +string laboff_c ; laboff_c := "" ; +string laboff_l ; laboff_l := ".lft" ; +string laboff_r ; laboff_r := ".rt" ; +string laboff_b ; laboff_b := ".bot" ; +string laboff_t ; laboff_t := ".top" ; + +string laboff_lt ; laboff_lt := ".ulft" ; +string laboff_rt ; laboff_rt := ".urt" ; % bugged, conflict with r +string laboff_lb ; laboff_lb := ".llft" ; +string laboff_rb ; laboff_rb := ".lrt" ; +string laboff_tl ; laboff_tl := ".ulft" ; +string laboff_tr ; laboff_tr := ".urt" ; +string laboff_bl ; laboff_bl := ".llft" ; +string laboff_br ; laboff_br := ".lrt" ; + +vardef textextstr(expr s, a) = + save ss ; string ss ; + ss := "laboff_" & a ; + ss := scantokens ss ; + ss := "textext" & ss & "(" & ditto & s & ditto & ")" ; + scantokens ss +enddef ; + +pair laboff.origin ; laboff.origin = (0,0) ; % (infinity,infinity) ; +pair laboff.raw ; laboff.raw = (0,0) ; % (infinity,infinity) ; + +laboff.origin = (0,0) ; labxf.origin := 0 ; labyf.origin := 0 ; +laboff.raw = (0,0) ; labxf.raw := 0 ; labyf.raw := 0 ; + +vardef installlabel@# (expr type, x, y, offset) = + numeric labtype@# ; labtype@# := type ; + pair laboff @# ; laboff @# := offset ; + numeric labxf @# ; labxf @# := x ; + numeric labyf @# ; labyf @# := y ; +enddef ; + +vardef thelabel@#(expr s, z) = + save p ; picture p ; + p = s if not picture s : infont defaultfont scaled defaultscale fi ; +% wrong, see myway textext +% if laboff@#<>laboff.origin : + (p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))) +% else : +% (p shifted z) +% fi +enddef; + +def build_parshape (expr p, offset_or_path, dx, dy, + baselineskip, strutheight, strutdepth, topskip) = + + if unknown trace_parshape : + boolean trace_parshape ; trace_parshape := false ; + fi ; + + begingroup ; + + save q, l, r, line, tt, bb, + n, hsize, vsize, vvsize, voffset, hoffset, width, indent, + ll, lll, rr, rrr, cp, cq, t, b ; + + path q, l, r, line, tt, bb ; + numeric n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ; + pair ll, lll, rr, rrr, cp, cq, t, b ; + + n := 0 ; cp := center p ; + + if path offset_or_path : + q := offset_or_path ; cq := center q ; + voffset := dy ; + hoffset := dx ; + else : + q := p ; cq := center q ; + hoffset := offset_or_path + dx ; + voffset := offset_or_path + dy ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + q := p shifted - cp ; + + startsavingdata ; + + savedata "\global\parvoffset " & decimal voffset&"bp " ; + savedata "\global\parhoffset " & decimal hoffset&"bp " ; + savedata "\global\parwidth " & decimal hsize&"bp " ; + savedata "\global\parheight " & decimal vsize&"bp " ; + + if not path offset_or_path : + q := q xscaled ((hsize-2hoffset)/hsize) + yscaled ((vsize-2voffset)/vsize) ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + t := (ulcorner q -- urcorner q) intersection_point q ; + b := (llcorner q -- lrcorner q) intersection_point q ; + + if xpart directionpoint t of q < 0 : + q := reverse q ; + fi ; + + l := q cutbefore t ; + l := l if xpart point 0 of q < 0 : & q fi cutafter b ; + + r := q cutbefore b ; + r := r if xpart point 0 of q > 0 : & q fi cutafter t ; + +% tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ; +% bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ; +% +% l := l cutbefore (l intersection_point tt) ; +% l := l cutafter (l intersection_point bb) ; +% r := r cutbefore (r intersection_point bb) ; +% r := r cutafter (r intersection_point tt) ; + + if trace_parshape : + drawarrow p withpen pencircle scaled 2pt withcolor red ; + drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ; + drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ; + fi ; + + vardef found_point (expr lin, pat, sig) = + pair a, b ; + a := pat intersection_point (lin shifted (0,strutheight)) ; + if intersection_found : + a := a shifted (0,-strutheight) ; + else : + a := pat intersection_point lin ; + fi ; + b := pat intersection_point (lin shifted (0,-strutdepth)) ; + if intersection_found : + if sig : + if xpart b > xpart a : a := b shifted (0,strutdepth) fi ; + else : + if xpart b < xpart a : a := b shifted (0,strutdepth) fi ; + fi ; + fi ; + a + enddef ; + + if (strutheight+strutdepth " & if numeric s : decimal s else : s fi) +% enddef ; +% vardef mpversionlt(expr s) = +% scantokens (mpversion & " < " & if numeric s : decimal s else : s fi) +% enddef ; +% vardef mpversioneq(expr s) = +% scantokens (mpversion & " = " & if numeric s : decimal s else : s fi) +% enddef ; + +%D More interesting: +%D +%D \starttyping +%D fill fullcircle scaled 4cm withcolor if mpversiongt("0.6") : red else : green fi ; +%D fill fullcircle scaled 2cm withcolor if mpversionlt(0.6) : blue else : white fi ; +%D fill fullcircle scaled 1cm withcolor if mpversioncmp(0.6,">=") : yellow else : black fi ; +%D \stoptyping + +vardef mpversioncmp(expr s, c) = + scantokens (mpversion & c & if numeric s : decimal s else : s fi) +enddef ; + +vardef mpversionlt (expr s) = mpversioncmp(s, "<") enddef ; +vardef mpversioneq (expr s) = mpversioncmp(s, "=") enddef ; +vardef mpversiongt (expr s) = mpversioncmp(s, ">") enddef ; + +%D We always want \EPS\ conforming output, so we say: + +prologues := 1 ; +warningcheck := 0 ; +mpprocset := 1 ; + +%D Namespace handling: + +% let exclamationmark = ! ; +% let questionmark = ? ; +% +% def unprotect = +% let ! = relax ; +% let ? = relax ; +% enddef ; +% +% def protect = +% let ! = exclamationmark ; +% let ? = questionmark ; +% enddef ; +% +% unprotect ; +% +% mp!some!module = 10 ; show mp!some!module ; show somemodule ; +% +% protect ; + +string space ; space := char 32 ; +string CRLF ; CRLF := char 10 & char 13 ; + +vardef ddecimal primary p = + decimal xpart p & " " & decimal ypart p +enddef ; + +%D Plain compatibility: + +string plain_compatibility_data ; plain_compatibility_data := "" ; + +def startplaincompatibility = + begingroup ; + scantokens plain_compatibility_data ; +enddef ; + +def stopplaincompatibility = + endgroup ; +enddef ; + +% is now built in +% +% extra_endfig := extra_endfig +% & "special " +% & "(" +% & ditto +% & "%%HiResBoundingBox: " +% & ditto +% & "&ddecimal llcorner currentpicture" +% & "&space" +% & "&ddecimal urcorner currentpicture" +% & ");"; + +%D More neutral: + +let triplet = rgbcolor ; +let quadruplet = cmykcolor ; + +%D Crap (experimental, not used): + +def forcemultipass = + % extra_endfig := extra_endfig & "special(" & ditto & "%%MetaPostOption: multipass" & ditto & ");" ; +enddef ; + +%D Colors: + +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_ ; + forsuffixes i=v : + _p_ := image(draw origin withcolor c ;) ; % intercept pre and postscripts + if (colormodel _p_ = cmykcolormodel) : + cmykcolor i ; + elseif (colormodel _p_ = rgbcolormodel) : + rgbcolor i ; + else : + greycolor i ; + fi ; + endfor ; +enddef ; + +%D Also handy (when we flush colors): + +vardef dddecimal primary 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 +enddef ; + +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 ; + +%D We have standardized data file names: + +def job_name = + jobname +enddef ; + +def data_mpd_file = + job_name & "-mp.mpd" +enddef ; + +%D Because \METAPOST\ has a hard coded limit of 4~datafiles, +%D we need some trickery when we have multiple files. + +if unknown collapse_data : + boolean collapse_data ; + collapse_data := false ; +fi ; + +boolean savingdata ; savingdata := false ; +boolean savingdatadone ; savingdatadone := false ; + +def savedata expr txt = + write if collapse_data : + txt + else : + if savingdata : txt else : "\MPdata{" & decimal charcode & "}{" & txt & "}" fi & "%" + fi to data_mpd_file ; +enddef ; + +def startsavingdata = + 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 ; +enddef ; + +def finishsavingdata = + if savingdatadone : + write EOF to data_mpd_file ; + savingdatadone := false ; + fi ; +enddef ; + +%D Instead of a keystroke eating save and allocation +%D sequence, you can use the \citeer {new} alternatives to +%D save and allocate in one command. + +def newcolor text v = forsuffixes i=v : save i ; color i ; endfor ; enddef ; +def newnumeric text v = forsuffixes i=v : save i ; numeric i ; endfor ; enddef ; +def newboolean text v = forsuffixes i=v : save i ; boolean i ; endfor ; enddef ; +def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; enddef ; +def newpath text v = forsuffixes i=v : save i ; path i ; endfor ; enddef ; +def newpicture text v = forsuffixes i=v : save i ; picture i ; endfor ; enddef ; +def newstring text v = forsuffixes i=v : save i ; string i ; endfor ; enddef ; +def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; enddef ; + +%D Sometimes we don't want parts of the graphics add to the +%D bounding box. One way of doing this is to save the bounding +%D box, draw the graphics that may not count, and restore the +%D bounding box. +%D +%D \starttyping +%D push_boundingbox currentpicture; +%D pop_boundingbox currentpicture; +%D \stoptyping +%D +%D The bounding box can be called with: +%D +%D \starttyping +%D boundingbox currentpicture +%D inner_boundingbox currentpicture +%D outer_boundingbox currentpicture +%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 \starttyping +%D set_outer_boundingbox currentpicture; +%D \stoptyping +%D +%D Its counterpart is: +%D +%D \starttyping +%D set_inner_boundingbox p +%D \stoptyping + +path mfun_boundingbox_stack ; +numeric mfun_boundingbox_stack_depth ; + +mfun_boundingbox_stack_depth := 0 ; + +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 +enddef; + +vardef innerboundingbox primary p = + top rt llcorner p -- + top lft lrcorner p -- + bot lft urcorner p -- + bot rt ulcorner p -- cycle +enddef; + +vardef outerboundingbox primary p = + bot lft llcorner p -- + bot rt lrcorner p -- + top rt urcorner p -- + top lft ulcorner p -- cycle +enddef; + +def inner_boundingbox = innerboundingbox enddef ; +def outer_boundingbox = outerboundingbox enddef ; + +vardef set_inner_boundingbox text q = % obsolete + setbounds q to innerboundingbox q; +enddef; + +vardef set_outer_boundingbox text q = % obsolete + setbounds q to outerboundingbox q; +enddef; + +%D Some missing functions can be implemented rather straightforward (thanks to +%D Taco and others): + +pi := 3.14159265358979323846 ; radian := 180/pi ; % 2pi*radian = 360 ; + +% let +++ = ++ ; + +numeric Pi ; Pi := pi ; % for some old compatibility reasons i guess + +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 ; + +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 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 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 ; + +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 +%D first macro divides the sides into n equal parts. The +%D first argument specifies the way the lines are drawn, while +%D the second argument identifier the way the shape is to be +%D drawn. +%D +%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 \stoptyping +%D +%D The a (or angle) alternative supports arbitrary angles and +%D is therefore more versatile. +%D +%D \starttyping +%D stripe_path_a +%D (withpen pencircle scaled 2 withcolor red) +%D (draw) +%D fullcircle xscaled 100 yscaled 40 withcolor blue; +%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 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; +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) +enddef; + +def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text = + 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) +enddef; + +def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text = + draw image(s_draw s_path s_text) anglestriped(3,0,0) s_spec ; +enddef ; + +%D A few normalizing macros: +%D +%D \starttypen +%D xscale_currentpicture ( width ) +%D yscale_currentpicture ( height ) +%D xyscale_currentpicture ( width, height ) +%D scale_currentpicture ( width, height ) +%D \stoptypen + +% def xscale_currentpicture(expr the_width) = +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_width/natural_width) ; +% enddef; +% +% def yscale_currentpicture(expr the_height ) = +% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_height/natural_height) ; +% enddef; +% +% def xyscale_currentpicture(expr the_width, the_height) = +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; +% currentpicture := currentpicture +% xscaled (the_width/natural_width) +% yscaled (the_height/natural_height) ; +% enddef; +% +% def scale_currentpicture(expr the_width, the_height) = +% xscale_currentpicture(the_width) ; +% yscale_currentpicture(the_height) ; +% enddef; + +% nog eens uitbreiden zodat path en pic worden afgehandeld. + +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_width/natural_width) ; + +primarydef p xsized w = + (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) +enddef ; + +primarydef p xysized s = + begingroup + save wh, w, h ; pair wh ; numeric w, h ; + wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; + p + if (w>0) and (h>0) : + if xpart wh > 0 : xscaled (xpart wh/w) fi + if ypart wh > 0 : yscaled (ypart wh/h) fi + fi + endgroup +enddef ; + +let sized = xysized ; + +def xscale_currentpicture(expr w) = % obsolete + currentpicture := currentpicture xsized w ; +enddef; + +def yscale_currentpicture(expr h) = % obsolete + currentpicture := currentpicture ysized h ; +enddef; + +def xyscale_currentpicture(expr w, h) = % obsolete + currentpicture := currentpicture xysized (w,h) ; +enddef; + +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 +%D is located in the first quadrant. Now guess what kind of +%D path fullsquare and unitcircle do return. + +path fullsquare, unitcircle ; + +fullsquare := unitsquare shifted - center unitsquare ; +unitcircle := fullcircle shifted urcorner fullcircle ; + +%D Some more paths: + +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 ; + +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 ; + +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 ; + +path unitdiamond, fulldiamond ; + +unitdiamond := (.5,0) -- (1,.5) -- (.5,1) -- (0,.5) -- cycle ; +fulldiamond := unitdiamond shifted - center unitdiamond ; + +%D More robust: + +% let normalscaled = scaled ; +% let normalxscaled = xscaled ; +% let normalyscaled = yscaled ; +% +% def scaled expr s = normalscaled (s) enddef ; +% def xscaled expr s = normalxscaled (s) enddef ; +% def yscaled expr s = normalyscaled (s) enddef ; + +%D Shorter + +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 Some personal code that might move to another module + +def set_grid(expr w, h, nx, ny) = + 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 ; +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 +enddef ; + +%D usage: \type{innerpath peepholed outerpath}. +%D +%D beginfig(1); +%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ; +%D fill (fullsquare scaled 200) withcolor red ; +%D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ; +%D fill p peepholed bbox p ; +%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 + else : + llcorner q -- lrcorner q -- urcorner q -- ulcorner q -- + reverse p -- ulcorner q -- cycle + fi + fi + endgroup +enddef ; + +boolean intersection_found ; + +secondarydef p intersection_point q = + begingroup + save x_, y_ ; + (x_,y_) = p intersectiontimes q ; + if x_<0 : + intersection_found := false ; + center p % origin + else : + intersection_found := true ; + .5[point x_ of p, point y_ of q] + fi + 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 +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 +enddef ; + +%D Some colors. + +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 ; + +%D Well, this is the dangerous and naive version: + +def drawfill text 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 ; + mfun_do_drawfill +enddef ; + +def mfun_do_drawfill text t = + draw _c_ t ; + fill _c_ t ; +enddef; + +def undrawfill expr c = + drawfill c withcolor background % rather useless +enddef ; + +%D Moved from mp-char.mp + +vardef paired primary d = + if pair d : d else : (d,d) fi +enddef ; + +vardef tripled primary d = + if color d : d else : (d,d,d) fi +enddef ; + +% maybe secondaries: + +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 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 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 = ( + if pair p : + 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 + fi +) enddef ; + +%D Also handy (math ladders): + +vardef laddered primary p = % was expr + point 0 of p + for i=1 upto length(p) : + -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p) + endfor +enddef ; + +%D Saves typing: + +% vardef bottomboundary primary p = (llcorner p -- lrcorner p) enddef ; +% vardef rightboundary primary p = (lrcorner p -- urcorner p) 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 ; + +%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 ; + +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 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 = ( + 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 : + p + uniformdeviate s + fi +) enddef ; + +%D Not perfect (alternative for interpath) + +vardef interpolated(expr s, p, q) = + 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 paralleled d = ( + p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p) +) 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 +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 +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 +enddef ; + +%D Rather fundamental. + +% not yet ok + +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 ; +vardef rightpath expr p = leftrightpath(p,false) enddef ; + +%D Drawoptions + +def saveoptions = + save _op_ ; def _op_ = enddef ; +enddef ; + +%D Tracing. (not yet in lexer) + +let normaldraw = draw ; +let normalfill = fill ; + +% bugged in mplib so ... + +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 ; +def drawlabeloptions (text t) = def _lab_opt_ = t enddef ; enddef ; +def draworiginoptions (text t) = def _ori_opt_ = t enddef ; enddef ; +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) ; +enddef ; + +resetdrawoptions ; + +%D Path. + +def drawpath expr p = + normaldraw p _pth_opt_ +enddef ; + +%D Arrow. + +vardef drawarrowpath expr p = + 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_ 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) +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 +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_ +enddef ; + +%D PathPoints. + +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 mfun_draw_points text t = + for _i_=0 upto length(_c_) : + normaldraw point _i_ of _c_ _pnt_opt_ t ; + endfor ; +enddef; + +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 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 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_ +enddef ; + +%D Origin. + +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 ; +enddef; + +%D Axis. + +numeric tickstep ; tickstep := 5mm ; +numeric ticklength ; ticklength := 2mm ; + +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 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 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 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 ; +enddef ; + +%D Tracing. + +def visualizeddraw expr c = + 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 +enddef ; + +def do_visualizeddraw text t = + 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_ ; +enddef ; + +def visualizepaths = + let fill = visualizedfill ; + let draw = visualizeddraw ; +enddef ; + +def naturalizepaths = + 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 +extra_beginfig := extra_beginfig & " miterlimit := 10 ; " ; % restores +extra_beginfig := extra_beginfig & " linejoin := rounded ; " ; % restores +extra_beginfig := extra_beginfig & " linecap := rounded ; " ; % restores + +%D Normally, arrowheads don't scale well. So we provide a +%D hack. + +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)) ; +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) +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 arrowpath _apth t ; % arrowpath added + fill arrowhead _apth t ; + draw arrowhead _apth 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) +enddef ; + +def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ; +def leftarrow (expr pat,tim,len) = pointarrow(pat,tim,len,+len) enddef ; +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 \starttyping +%D drawdot point .5 along somepath ; +%D drawdot point 3cm on somepath ; +%D \stoptyping +%D +%D The number denotes a percentage (fraction). + +primarydef pct along pat = % also negative + (arctime (pct * (arclength pat)) of pat) of pat +enddef ; + +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 + +% tertiarydef pat cutends len = +% begingroup ; save tap ; path tap ; +% tap := pat cutbefore (point len on pat) ; +% (tap cutafter (point -len on tap)) +% endgroup +% 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 +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 ; + +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 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) ; +enddef ; + +vardef freedotlabel (expr str, loc, ori) = + interim linecap := rounded ; + draw loc withpen pencircle scaled freedotlabelsize ; + draw thefreelabel(str,loc,ori) ; +enddef ; + +%D \starttyping +%D drawarrow anglebetween(line_a,line_b,somelabel) ; +%D \stoptyping + +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 ; +% 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 := ((common--pointa) rotatedaround (pointa,-where*90)) +% intersectionpoint +% ((common--pointb) rotatedaround (pointb, where*90)) ; +% 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 ; + +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 +enddef ; + +% Stack + +picture mfun_current_picture_stack[] ; +numeric mfun_current_picture_depth ; + +mfun_current_picture_depth := 0 ; + +def pushcurrentpicture = + 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 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) ; + +% vardef colorcircle (expr size, red, green, blue) = +% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; +% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; +% +% radius := 5cm ; pickup pencircle scaled (radius/25) ; +% +% r := g := b := fullcircle scaled radius shifted (0,radius/4) ; +% +% r := r rotatedaround (origin, 15) ; +% g := g rotatedaround (origin,135) ; +% b := b rotatedaround (origin,255) ; +% +% r := r rotatedaround(center r,-90) ; +% g := g rotatedaround(center g, 90) ; +% +% gg := buildcycle(buildcycle(reverse r,b),g) ; +% cc := buildcycle(buildcycle(b,reverse g),r) ; +% +% rr := gg rotatedaround(origin,120) ; +% bb := gg rotatedaround(origin,240) ; +% +% yy := cc rotatedaround(origin,120) ; +% mm := cc rotatedaround(origin,240) ; +% +% pushcurrentpicture ; +% +% fill fullcircle scaled radius withcolor white ; +% +% fill rr withcolor red ; fill cc withcolor white-red ; +% fill gg withcolor green ; fill mm withcolor white-green ; +% fill bb withcolor blue ; fill yy withcolor white-blue ; +% +% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; +% +% currentpicture := currentpicture xsized size ; +% +% popcurrentpicture ; +% enddef ; + +% vardef colorcircle (expr size, red, green, blue) = +% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; +% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; +% +% radius := 5cm ; pickup pencircle scaled (radius/25) ; +% +% transform t ; t := identity rotatedaround(origin,120) ; +% +% r := fullcircle scaled radius +% shifted (0,radius/4) rotatedaround(origin,15) ; +% +% g := r transformed t ; b := g transformed t ; +% +% r := r rotatedaround(center r,-90) ; +% g := g rotatedaround(center g, 90) ; +% +% gg := buildcycle(buildcycle(reverse r,b),g) ; +% cc := buildcycle(buildcycle(b,reverse g),r) ; +% +% rr := gg transformed t ; bb := rr transformed t ; +% yy := cc transformed t ; mm := yy transformed t ; +% +% pushcurrentpicture ; +% +% fill fullcircle scaled radius withcolor white ; +% +% fill rr withcolor red ; fill cc withcolor white-red ; +% fill gg withcolor green ; fill mm withcolor white-green ; +% fill bb withcolor blue ; fill yy withcolor white-blue ; +% +% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; +% +% currentpicture := currentpicture xsized size ; +% +% popcurrentpicture ; +% enddef ; + +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) ; + + transform t ; t := identity rotatedaround(origin,120) ; + + r := fullcircle rotated 90 scaled radius shifted (0,radius/4) rotatedaround(origin,135) ; + + 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 ; + + w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ; + + 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 ; + + for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ; + + currentpicture := currentpicture xsized size ; + + 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)) +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 ; + ) + fi +enddef ; + +vardef inverted primary p = + p uncolored white +enddef ; + +% primarydef p softened c = +% if color p : +% tripled(c) * p +% else : +% image +% (save cc ; color cc ; cc := tripled(c) ; +% 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 +% 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 +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 ; + ) + fi +enddef ; + +% yes or no: "text" infont "cmr12" at 24pt ; + +% let normalinfont = infont ; +% +% numeric lastfontsize ; lastfontsize = fontsize defaultfont ; +% +% def infont primary name = % no vardef, no expr +% hide(lastfontsize := fontsize name) % no ; +% normalinfont name +% enddef ; +% +% def scaledat expr size = +% scaled (size/lastfontsize) +% enddef ; +% +% let at = scaledat ; + +% like decimal + +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 +enddef ; + +% primarydef p enlonged len = +% begingroup +% save al ; al := arclength(p) ; +% if al > 0 : +% if pair p : +% point 1 of ((origin -- p) stretched ((al+len)/al)) +% else : +% p stretched ((al+len)/al) +% fi +% else : +% p +% fi +% endgroup +% enddef ; + +primarydef p enlonged len = + begingroup + if pair p : + save q ; path q ; q := origin -- p ; + save al ; al := arclength(q) ; + if al > 0 : + point 1 of (q stretched ((al+len)/al)) + else : + p + fi + else : + save al ; al := arclength(p) ; + if al > 0 : + p stretched ((al+len)/al) + else : + p + fi + fi + endgroup +enddef ; + +% path p ; p := (0,0) -- (10cm,5cm) ; +% drawarrow p withcolor red ; +% drawarrow p shortened 1cm withcolor green ; + +primarydef p shortened d = + reverse ( ( reverse (p enlonged -d) ) enlonged -d ) +enddef ; + +% yes or no, untested -) + +def xshifted expr dx = shifted(dx,0) enddef ; +def yshifted expr dy = shifted(0,dy) enddef ; + +% also handy + +% right: str = readfrom ("abc" & ".def" ) ; +% wrong: str = readfrom "abc" & ".def" ; + +% Every 62th read fails so we need to try again! + +% def readfile (expr name) = +% if (readfrom (name) <> EOF) : +% scantokens("input " & name & ";") ; +% elseif (readfrom (name) <> EOF) : +% scantokens("input " & name & ";") ; +% fi ; +% closefrom (name) ; +% enddef ; +% +% this sometimes fails on the elseif, so : +% + +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 ; +enddef ; + +% permits redefinition of end in macro + +inner end ; + +% this will be redone (when needed) using scripts and backend handling + +let normalwithcolor = withcolor ; + +def remapcolors = + def withcolor primary c = normalwithcolor remappedcolor(c) enddef ; +enddef ; + +def normalcolors = + let withcolor = normalwithcolor ; +enddef ; + +def resetcolormap = + color color_map[][][] ; + normalcolors ; +enddef ; + +resetcolormap ; + +% color_map_resolution := 1000 ; +% +% def r_color primary c = round(color_map_resolution*redpart c) enddef ; +% def g_color primary c = round(color_map_resolution*greenpart c) enddef ; +% def b_color primary c = round(color_map_resolution*bluepart c) enddef ; + +def r_color primary c = redpart c enddef ; +def g_color primary c = greenpart c enddef ; +def b_color primary c = bluepart c enddef ; + +def remapcolor(expr old, new) = + color_map[redpart old][greenpart old][bluepart old] := new ; +enddef ; + +def remappedcolor(expr c) = + 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 ; +% def redraw suffix c = do_repath (2) (c) enddef ; +% def recolor suffix c = do_repath (0) (c) enddef ; +% +% color refillbackground ; refillbackground := (1,1,1) ; +% +% def do_repath (expr mode) (suffix c) text t = % can it be stroked and filled at the same time ? +% begingroup ; +% if mode=0 : save withcolor ; remapcolors ; fi ; +% save _c_, _cc_, _f_, _b_ ; picture _c_, _cc_ ; color _f_ ; path _b_ ; +% _c_ := c ; _b_ := boundingbox c ; c := nullpicture ; +% for i within _c_ : +% _f_ := (redpart i, greenpart i, bluepart i) ; +% if bounded i : +% setbounds c to pathpart i ; +% elseif clipped i : +% clip c to pathpart i ; +% elseif stroked i : +% addto c doublepath pathpart i +% dashed dashpart i withpen penpart i +% withcolor _f_ % (redpart i, greenpart i, bluepart i) +% if mode=2 : t fi ; +% elseif filled i : +% addto c contour pathpart i +% withcolor _f_ +% if (mode=1) and (_f_<>refillbackground) : t fi ; +% else : +% addto c also i ; +% fi ; +% endfor ; +% setbounds c to _b_ ; +% endgroup ; +% 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 ; + +% primarydef p recolored t = repathed(0,p) t enddef ; +% primarydef p refilled t = repathed(1,p) t enddef ; +% primarydef p redrawn t = repathed(2,p) t enddef ; +% primarydef p retexted t = repathed(3,p) t enddef ; +% primarydef p untexted t = repathed(4,p) t enddef ; + +color refillbackground ; refillbackground := (1,1,1) ; + +% vardef repathed (expr mode, p) text t = +% begingroup ; +% if mode=0 : save withcolor ; remapcolors ; fi ; +% save _p_, _pp_, _f_, _b_, _t_ ; +% picture _p_, _pp_ ; 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 : +% addto _p_ doublepath pathpart i +% dashed dashpart i withpen penpart i +% withcolor _f_ % (redpart i, greenpart i, bluepart i) +% if mode=2 : t fi ; +% elseif filled i : +% addto _p_ contour pathpart i +% withcolor _f_ +% if (mode=1) and (_f_<>refillbackground) : t 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 ; + +def restroke suffix p = p := repathed (21,p) enddef ; % keep attributes +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 ; + fi ; + endfor ; + setbounds _p_ to _b_ ; + _p_ + endgroup +enddef ; + +% After a question of Denis on how to erase a z variable, Jacko +% suggested to assign whatever to x and y. So a clearz +% variable can be defined as: +% +% vardef clearz@# = +% x@# := whatever ; +% y@# := whatever ; +% enddef ; +% +% but Jacko suggested a redefinition of clearxy: +% +% def clearxy text s = +% clearxy_index_:=0; +% for $:=s: +% clearxy_index_:=clearxy_index_+1; endfor; +% if clearxy_index_=0: +% save x,y; +% else: +% forsuffixes $:=s: x$:=whatever; y$:=whatever; endfor; +% fi +% 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 +enddef ; + +% so now we can say: clearxy ; as well as clearxy 1, 2, 3 ; + +% show x0 ; z0 = (10,10) ; +% show x0 ; x0 := whatever ; y0 := whatever ; +% show x0 ; z0 = (20,20) ; +% show x0 ; clearxy 0 ; +% 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) +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) +enddef ; + +% cmyk color support + +vardef cmyk(expr c,m,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 +% 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 +% 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 +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 ; + fi ; + fi ; +enddef ; + +% result from metafont discussion list (denisr/boguslawj) + +def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ; +def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ; + +let == = = ; + +% added + +picture oddly ; % evenly already defined + +evenly := dashpattern(on 3 off 3) ; +oddly := dashpattern(off 3 on 3) ; + +% not perfect, but useful since it removes redundant points. + +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 ; + _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 + else : + p + fi +enddef ; + +vardef simplified expr p = ( + reverse mfun_straightened(+1,mfun_straightened(+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) -- +% (4cm,1cm) -- (4cm,2cm) -- (4cm,2.5cm) -- (4cm,3cm) -- +% (3cm,3cm) -- (2cm,3cm) -- (1cm,3cm) -- (-1cm,3cm) -- +% .5[(-1cm,3cm),(1cm,1cm)] -- (1cm,1cm) -- cycle ; +% +% p := unitcircle scaled 4cm ; +% +% drawpath p ; drawpoints p ; drawpointlabels p ; +% p := p shifted (4cm,0) ; p := straightened p ; +% drawpath p ; drawpoints p ; drawpointlabels p ; +% p := p shifted (4cm,0) ; p := straightened p ; +% drawpath p ; drawpoints p ; drawpointlabels p ; + +% new + +path originpath ; originpath := origin -- cycle ; + +vardef unitvector primary z = + if abs z = abs origin : z else : z/abs z fi +enddef; + +% also new + +% 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 +enddef ; + +% handy + +def withgray primary g = + withcolor (g,g,g) +enddef ; + +% for metafun + +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 := .850(1,1,1) fi ; + +% an improved plain mp macro + +vardef center primary p = + 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 +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 + 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 ; +enddef ; + +% makes a (line) into an infinite one (handy for calculating +% intersection points + +vardef infinite expr 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) +enddef ; + +% obscure macros: create var from string and replace - and : +% (needed for process color id's) .. will go away + +string mfun_clean_ascii[] ; + +def register_dirty_chars(expr str) = + for i = 0 upto length(str)-1 : + 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 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 ; +enddef ; + +vardef getunstringed (expr s) = + scantokens(cleanstring(s)) +enddef ; + +vardef unstringed (expr s) = + 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) = % 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 ; + endfor ; + for x=MinX upto MaxX: + label.bot(textext("\infofont " & decimal x), (x*DeltaX,-size)) ; + endfor ; + for y=MinY upto MaxY: + label.lft(textext("\infofont " & decimal y), (-size,y*DeltaY)) ; + endfor ; + endgroup +enddef; + +% new, handy for: +% +% \startuseMPgraphic{map}{n} +% \includeMPgraphic{map:germany} ; +% c_phantom (\MPvar{n}<1) ( +% fill map_germany withcolor \MPcolor{lightgray} ; +% draw map_germany withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% \includeMPgraphic{map:austria} ; +% c_phantom (\MPvar{n}<2) ( +% fill map_austria withcolor \MPcolor{lightgray} ; +% draw map_austria withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% c_phantom (\MPvar{n}<3) ( +% \includeMPgraphic{map:swiss} ; +% fill map_swiss withcolor \MPcolor{lightgray} ; +% draw map_swiss withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% c_phantom (\MPvar{n}<4) ( +% \includeMPgraphic{map:luxembourg} ; +% fill map_luxembourg withcolor \MPcolor{lightgray} ; +% draw map_luxembourg withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% \stopuseMPgraphic +% +% \useMPgraphic{map}{n=3} + +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 ; +enddef ; + +%D Handy: + +def break = + exitif true fi ; +enddef ; + +%D New too: + +primarydef p xstretched w = ( + p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi +) enddef ; + +primarydef p ystretched h = ( + p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi +) enddef ; + +primarydef p 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 +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 ; + 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/mpii/mp-txts.mpii b/metapost/context/base/mpii/mp-txts.mpii new file mode 100644 index 000000000..d3597488f --- /dev/null +++ b/metapost/context/base/mpii/mp-txts.mpii @@ -0,0 +1,66 @@ +%D \module +%D [ file=mp-txts.mpii, +%D version=2006.06.08, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=more text support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%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_txts : endinput ; fi ; + +boolean context_txts ; context_txts := true ; + +%D The real code: + +string txtfile ; txtfile := "" ; +string txtfont ; txtfont := defaultfont ; +string txtpref ; txtpref := "00001::::" ; +numeric txtnext ; txtnext := 0 ; +numeric txtdepth ; txtdepth := 0 ; + +vardef nexttxt = + txtnext := txtnext + 1 ; + txtnext +enddef ; + +picture savedtxts[] ; +numeric depthtxts[] ; + +vardef zerofilled(expr fd) = + if fd<10: "0000" else : + if fd<100: "000" else : + if fd<1000: "00" else : + if fd<10000: "0" else : + fi fi fi fi & decimal fd +enddef; + +vardef savetxt(expr n,w,h,d) text t = + depthtxts[n] := d ; + savedtxts[n] := ((txtpref & zerofilled(n)) infont txtfont) xysized(w,h+d) t +enddef ; + +vardef sometxt(expr n) = + if known savedtxts[n] : + txtdepth := depthtxts[n] ; savedtxts[n] + else : + txtdepth := 0 ; nullpicture + fi +enddef ; + +def loadtxts = + if txtfile <> "" : + readfile(txtfile) ; + fi ; +enddef ; + +def StartTexts = + loadtxts ; +enddef ; + +def StopTexts = +enddef ; diff --git a/metapost/context/base/mpiv/metafun.mpiv b/metapost/context/base/mpiv/metafun.mpiv new file mode 100644 index 000000000..b1d4f32e7 --- /dev/null +++ b/metapost/context/base/mpiv/metafun.mpiv @@ -0,0 +1,58 @@ +%D \module +%D [ file=metafun.mp, +%D version=2000.07.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=format generation file, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D First we input John Hobby's metapost plain file. However, because we want to +%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 +input "mp-grph.mpiv" ; % todo: namespace and cleanup +input "mp-grid.mpiv" ; % todo: namespace and cleanup +input "mp-form.mpiv" ; % under (re)construction +input "mp-figs.mpiv" ; % obsolete, needs checking +input "mp-func.mpiv" ; % under construction +% "mp-text.mpiv" ; % loaded on demand +% "mp-char.mpiv" ; % loaded on demand +% "mp-step.mpiv" ; % loaded on demand +% "mp-chem.mpiv" ; % loaded on demand + +string metafunversion ; metafunversion = + "metafun iv" & " " & + decimal year & "-" & + decimal month & "-" & + decimal day & " " & + if ((time div 60) < 10) : "0" & fi + decimal (time div 60) & ":" & + if ((time-(time div 60)*60) < 10) : "0" & fi + decimal (time-(time div 60)*60) ; + +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 ; + +% dump ; % obsolete in mplib diff --git a/metapost/context/base/mpiv/mp-abck.mpiv b/metapost/context/base/mpiv/mp-abck.mpiv new file mode 100644 index 000000000..abd7d8848 --- /dev/null +++ b/metapost/context/base/mpiv/mp-abck.mpiv @@ -0,0 +1,269 @@ +%D \module +%D [ file=mp-abck.mpiv, +%D version=2012.02.19, % was mp-core: 1999.08.01, anchoring +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=anchored background macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +if known context_abck : endinput ; fi ; + +boolean context_abck ; context_abck := true ; + +path multiregs[], % region used for multipar (tracing only) + multipars[], % effective area (shape) + multibox ; % main boundingbox (of main region) + +string multikind[] ; % region state: single | first | middle | last (new method) + +numeric multilocs[], % 1=begin 2=between 3=end (old method) + nofmultipars ; % number of calculated areas + +numeric par_strut_height, + par_strut_depth, + par_line_height ; + +nofmultipars := 0 ; +par_strut_height := 0 ; +par_strut_depth := 0 ; +par_line_height := 0 ; + +def boxgridoptions = withcolor .8red enddef ; +def boxlineoptions = withcolor .8blue enddef ; +def boxfilloptions = withcolor .8white enddef ; + +numeric boxgridtype ; boxgridtype := 0 ; +numeric boxlinetype ; boxlinetype := 1 ; +numeric boxfilltype ; boxfilltype := 1 ; +numeric boxdashtype ; boxdashtype := 0 ; +pair boxgriddirection ; boxgriddirection := up ; +numeric boxgridwidth ; boxgridwidth := 1pt ; +numeric boxlinewidth ; boxlinewidth := 1pt ; +numeric boxlineradius ; boxlineradius := 0 ; +numeric boxlineoffset ; boxlineoffset := 0 ; +numeric boxfilloffset ; boxfilloffset := 0 ; +numeric boxgriddistance ; boxgriddistance := .5cm ; +numeric boxgridshift ; boxgridshift := 0 ; + +def abck_show_path(expr p, r, c) = + draw p withpen pencircle scaled .5pt withcolor c ; + if length(p) > 2 : + begingroup ; save _c_ ; path _c_ ; _c_ := fullcircle scaled r ; + for i=0 upto length(p) if cycle p : -1 fi : + fill _c_ shifted point i of p withcolor white ; + draw _c_ shifted point i of p withpen pencircle scaled .5pt withcolor c ; + endfor ; + fi ; +enddef ; + +vardef abck_draw_path(expr p) = + if (length p > 2) and (bbwidth(p) > 1) and (bbheight(p) > 1) : + save pp ; path pp ; + pp := p if (boxlineradius>0) and (boxlinetype=2) : cornered boxlineradius fi ; + if boxfilltype > 0 : + if boxfilloffset > 0 : + interim linejoin := mitered ; + filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ; + else : + fill pp boxfilloptions ; + fi ; + fi ; + if boxlinetype > 0 : + draw pp boxlineoptions withpen pencircle scaled boxlinewidth ; + fi ; + fi ; +enddef ; + +def abck_grid_line(expr start, width) = + % 1 = normal, 2 = with background (i.e. no shine-through) + if boxdashtype = 2 : + draw start -- start shifted (width,0) + withpen pencircle scaled boxgridwidth + boxfilloptions ; + fi ; + draw start -- start shifted (width,0) + if boxdashtype > 0 : + dashed evenly + fi + withpen pencircle scaled boxgridwidth + boxgridoptions ; +enddef ; + +vardef abck_baseline_grid(expr pxy, pdir, at_baseline) = + save width ; width := bbwidth(pxy) ; + save height ; height := bbheight(pxy) ; + if (par_line_height > 0) and (height > 1) and (width > 1) and (boxgridwidth > 0) : + save i, grid, bb ; picture grid ; pair start ; path bb ; + grid := image ( % fails with inlinespace + if pdir = up : + for i = if at_baseline : par_strut_depth else : 0 fi step par_line_height until max(height,par_line_height) : + abck_grid_line(llcorner pxy shifted (0,+i),width) ; + endfor ; + else : + for i = if at_baseline : par_strut_height else : 0 fi step par_line_height until height : + abck_grid_line(ulcorner pxy shifted (0,-i),width) ; + endfor ; + fi ; + ) ; + clip grid to pxy ; + bb := boundingbox grid ; + grid := grid shifted (0,boxgridshift) ; + setbounds grid to bb ; + grid + else : + nullpicture + fi +enddef ; + +vardef abck_graphic_grid(expr pxy, dx, dy, x, y) = + if (bbheight(pxy) > dy) and (bbwidth(pxy) > dx) and (boxgridwidth > 0) : + save grid ; picture grid ; + grid := image ( + for i = xpart llcorner pxy step dx until xpart lrcorner pxy : + draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) withpen pencircle scaled boxgridwidth ; + endfor ; + for i = ypart llcorner pxy step dy until ypart ulcorner pxy : + draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) withpen pencircle scaled boxgridwidth ; + endfor + ) shifted (x,y) ; + clip grid to pxy ; + grid + else : + nullpicture + fi +enddef ; + +def draw_multi_pars = + for i=1 upto nofmultipars : + abck_draw_path(multipars[i]) ; + if boxgridtype = 1 : + draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ; + elseif boxgridtype = 2 : + draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,false) ; + elseif boxgridtype = 3 : + draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ; + draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; + elseif boxgridtype = 4 : + draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; + elseif boxgridtype = 11 : + draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype = 12 : + draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def show_multi_pars = + for i=1 upto nofmultipars : + abck_show_path(multipars[i], 6pt, .5blue) ; + endfor ; +enddef ; + +def show_multi_kind = + for i=1 upto nofmultipars : + fill multipars[i] + withcolor + if multikind[i] = "single" : yellow + elseif multikind[i] = "first" : red + elseif multikind[i] = "middle" : green + elseif multikind[i] = "last" : blue + fi + withtransparency (1,.5) + ; + endfor ; +enddef ; + +def multi_side_draw_options = enddef ; + +def draw_multi_side = + begingroup ; save p ; picture p ; + for i=1 upto nofmultipars : + p := image ( fill leftboundary multipars[i] + shifted (-boxlineoffset,0) + rightenlarged boxlinewidth boxlineoptions ; + ) ; + setbounds p to multipars[i] ; + draw p ; + endfor ; + endgroup ; +enddef ; + +def draw_multi_side_path text t = + begingroup ; save p ; picture p ; + for i=1 upto nofmultipars : + p := image ( draw leftboundary multipars[i] + shifted (-boxlineoffset,0) + withpen pensquare scaled boxlinewidth boxlineoptions t ; + ) ; + setbounds p to multipars[i] ; + draw p ; + endfor ; + endgroup ; +enddef ; + +% some extras + +path posboxes[], + posregions[] ; + +numeric multipages[], + nofposboxes ; + +nofposboxes := 0 ; + +% For the moment we keep these as they can be in use but they will +% disappear. + +pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; +path pxy[] ; +numeric hxy[], wxy[], dxy[], nxy[] ; + +def box_found (expr n,x,y,w,h,d) = + not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) +enddef ; + +def initialize_box_pos (expr pos,n,x,y,w,h,d) = + pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; + path pxy ; numeric hxy, wxy, dxy, nxy; + lxy := (x,y) ; + llxy := (x,y-d) ; + lrxy := (x+w,y-d) ; + urxy := (x+w,y+h) ; + ulxy := (x,y+h) ; + wxy := w ; + hxy := h ; + dxy := d ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; + nxy := n ; + freeze_box(pos) ; +enddef ; + +def freeze_box (expr pos) = + lxy[pos] := lxy ; + llxy[pos] := llxy ; + lrxy[pos] := lrxy ; + urxy[pos] := urxy ; + ulxy[pos] := ulxy ; + wxy[pos] := wxy ; + hxy[pos] := hxy ; + dxy[pos] := dxy ; + rxy[pos] := rxy ; + pxy[pos] := pxy ; + cxy[pos] := cxy ; + nxy[pos] := nxy ; +enddef ; + +def initialize_box (expr n,x,y,w,h,d) = + numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; +enddef ; + +def anchor_box (expr n,x,y,w,h,d) = + currentpicture := currentpicture shifted (-x,-y) ; +enddef ; diff --git a/metapost/context/base/mpiv/mp-apos.mpiv b/metapost/context/base/mpiv/mp-apos.mpiv new file mode 100644 index 000000000..7b7737754 --- /dev/null +++ b/metapost/context/base/mpiv/mp-apos.mpiv @@ -0,0 +1,102 @@ +%D \module +%D [ file=mp-apos.mpiv, +%D version=2012.02.19, % was mp-core: 1999.08.01, anchoring +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=anchored background macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +if known context_apos : endinput ; fi ; + +boolean context_apos ; context_apos := true ; + +path posboxes[], + posregions[] ; + +numeric multipages[], + nofposboxes ; + +nofposboxes := 0 ; + +def boxlineoptions = withcolor .8blue enddef ; +def boxfilloptions = withcolor .8white enddef ; + +def connect_positions = + if nofposboxes = 2 : + pickup pencircle scaled boxlinewidth ; + path pa ; pa := posboxes[1] enlarged boxlineoffset ; + path pb ; pb := posboxes[2] enlarged boxlineoffset ; + if pospages[1] = pospages[2] : + draw posboxes[1] boxlineoptions ; + path pc ; pc := center pa {up} .. {down} center pb ; + pair cc ; cc := (pc intersection_point pa) ; + if intersection_found : + pc := pc cutbefore cc ; + cc := (pc intersection_point pb) ; + if intersection_found : + pc := pc cutafter cc ; + drawarrow pc boxlineoptions ; + drawarrow reverse pc boxlineoptions ; + fi ; + fi ; + elseif pospages[1] == RealPageNumber : + draw posboxes[1] boxlineoptions ; + path pc ; pc := center pa {up} ... {right} urcorner (posregions[1] enlarged (20pt,20pt)) ; + pair cc ; cc := (pc intersection_point pa) ; + if intersection_found : + pc := pc cutbefore cc ; + drawarrow pc boxlineoptions ; + fi ; + elseif pospages[2] == RealPageNumber : + draw posboxes[2] boxlineoptions ; + path pc ; pc := ulcorner (posregions[2] enlarged (20pt,20pt)) {right} ... {down} center pb ; + pair cc ; cc := (pc intersection_point pb) ; + if intersection_found : + pc := pc cutafter cc ; + drawarrow pc boxlineoptions ; + fi ; + fi ; + fi ; +enddef ; + +% anch-bar: + +def anch_sidebars_draw (expr p_b_self, p_e_self, y_b_self, y_e_self, h_b_self, d_e_self, + x, y, w, h, alternative, distance, linewidth, linecolor, topoffset, bottomoffset) = + % beware, we anchor at (x,y) + begingroup ; + if alternative = 1 : + interim linecap := rounded ; + else : + interim linecap := butt ; + fi ; + save a, b ; pair a, b ; + if p_b_self = p_e_self : + a := (-distance,y_b_self+h_b_self-y) ; + b := (-distance,y_e_self-d_e_self-y) ; + elseif RealPageNumber = p_b_self : + a := (-distance,y_b_self+h_b_self-y) ; + b := (-distance,0) ; + elseif RealPageNumber = p_e_self : + a := (-distance,h) ; + b := (-distance,y_e_self-d_e_self-y) ; + else : + a := (-distance,h) ; + b := (-distance,0) ; + fi ; + a := (xpart a, min(ypart a + topoffset, h)) ; + b := (xpart b, max(ypart b - bottomoffset,0)) ; + draw + a -- b + if alternative = 1 : + dashed (withdots scaled (linewidth/2)) + fi + withpen pencircle scaled linewidth + withcolor linecolor ; + endgroup ; +enddef ; diff --git a/metapost/context/base/mpiv/mp-asnc.mpiv b/metapost/context/base/mpiv/mp-asnc.mpiv new file mode 100644 index 000000000..2626e4d58 --- /dev/null +++ b/metapost/context/base/mpiv/mp-asnc.mpiv @@ -0,0 +1,177 @@ +%D \module +%D [ file=mp-asnc.mpiv, +%D version=2012.02.19, % was mp-core: 1999.08.01, anchoring +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=anchored background macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +if known context_asnc : endinput ; fi ; + +boolean context_av ; context_asnc := true ; + +% will be replaced + +numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; +pair sync_xy[][] ; color sync_c[][] ; + +def ResetSyncTasks = + path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; + NOfSyncPaths := CurrentSyncClass := 0 ; + if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; + if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; + if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; + if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; + if (SyncLeftOffset = 0) and (SyncWidth = 0) : + SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; + fi ; +enddef ; + +ResetSyncTasks ; + +vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = + save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; + o shifted (leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,bottomoffset) -- + o shifted (leftoffset,bottomoffset) -- cycle +enddef ; + +def SetSyncColor(expr n, i, c) = + sync_c[n][i] := c ; +enddef ; + +def SetSyncThreshold(expr n, i, th) = + sync_th[n][i] := th ; +enddef ; + +vardef TheSyncColor(expr n, i) = + if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi +enddef ; + +vardef TheSyncThreshold(expr n, i) = + if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi +enddef ; + +vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = + ResetSyncTasks ; + if known sync_n[n] : + CurrentSyncClass := n ; + save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; + for i=1 upto sync_n[n] : + if RealPageNumber > sync_p[n][i] : + l := i ; + elseif RealPageNumber = sync_p[n][i] : + NOfSyncPaths := NOfSyncPaths + 1 ; + if not ok : + if i>1 : + if sync_t[n][i-1] = sync_t[n][i] : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i-1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + ok := true ; + fi ; + endfor ; + if (NOfSyncPaths = 0) and (l > 0) : + NOfSyncPaths := 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := l ; + fi ; + if NOfSyncPaths > 0 : + for i = 1 upto NOfSyncPaths-1 : + SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; + endfor ; + if unknown SyncThresholdMethod : + numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; + fi ; + if extendtop : + if SyncThresholdMethod = 1 : + if NOfSyncPaths>1 : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; + if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : + SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; + fi ; + fi ; + else : + for i = 1 upto NOfSyncPaths : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; + if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : + SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; + fi ; + endfor ; + fi ; + fi ; + if prestartnext : + if NOfSyncPaths>1 : + if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; + if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : + SyncPaths[NOfSyncPaths+1] := + (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + lrcorner SyncPaths[NOfSyncPaths] -- + llcorner SyncPaths[NOfSyncPaths] -- cycle ; + SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + fi ; + fi ; + fi ; + else : + if NOfSyncPaths>1 : + d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; + if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : + NOfSyncPaths := NOfSyncPaths - 1 ; + SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; + fi ; + fi ; + fi ; + if (NOfSyncPaths>1) and collapse : + save j ; numeric j ; j := 1 ; + for i = 2 upto NOfSyncPaths : + if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : + SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; + SyncTasks[j] := SyncTasks[i] ; + else : + j := j + 1 ; + SyncPaths[j] := SyncPaths[i] ; + SyncTasks[j] := SyncTasks[i] ; + fi ; + endfor ; + NOfSyncPaths := j ; + fi ; + fi ; + fi ; +enddef ; + +def SyncTask(expr n) = + if known SyncTasks[n] : SyncTasks[n] else : 0 fi +enddef ; + +def FlushSyncTasks = + for i = 1 upto NOfSyncPaths : + ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; + endfor ; +enddef ; + +def ProcessSyncTask(expr p, c) = + fill p withcolor c ; +enddef ; diff --git a/metapost/context/base/mpiv/mp-back.mpiv b/metapost/context/base/mpiv/mp-back.mpiv new file mode 100644 index 000000000..f588adea9 --- /dev/null +++ b/metapost/context/base/mpiv/mp-back.mpiv @@ -0,0 +1,205 @@ +%D \module +%D [ file=mp-back.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=backgrounds, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_back : endinput ; fi ; + +boolean context_back ; context_back := true ; + +def some_hash ( expr hash_width , + hash_height , + hash_linewidth , + hash_linecolor , + hash_angle , + hash_gap ) = + + stripe_gap := hash_gap ; + stripe_angle := hash_angle ; + drawoptions (withpen pencircle scaled hash_linewidth + withcolor hash_linecolor) ; + path p ; p := unitsquare xscaled hash_width yscaled hash_height ; + stripe_path_a () (draw) p ; % next we move it all to quadrant 1 + currentpicture := currentpicture shifted urcorner currentpicture ; + +enddef ; + +def some_double_back (expr back_type , + back_width , + back_height , + back_delta , + back_linewidth , + back_linecolor , + back_fillcolor , + back_topcolor , + back_bottomcolor , + back_leftcolor , + back_rightcolor ) = + + numeric ww ; ww := back_width ; + numeric hh ; hh := back_height ; + numeric dd ; dd := back_delta ; + + color back_nillcolor ; back_nillcolor := back_topcolor ; + + path p ; p := fullsquare xscaled ww yscaled hh ; + path q ; q := fullsquare xscaled (ww-2dd) yscaled (hh-2dd) ; + path r ; r := llcorner p -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p -- cycle ; + path s ; s := r xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path t ; t := llcorner p -- + lrcorner p -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) -- + llcorner p -- cycle ; + path u ; u := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path v ; v := llcorner p shifted ( 3dd,0) -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) .. + llcorner p shifted (0, 3dd) .. controls llcorner p .. cycle ; % {down} .. cycle ; + path w ; w := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path a ; a := llcorner p -- ulcorner p -- + ulcorner q -- llcorner q -- cycle ; + path b ; b := llcorner p -- lrcorner p -- + lrcorner q -- llcorner q -- cycle ; + path c ; c := lrcorner p -- urcorner p -- + urcorner q -- lrcorner q -- cycle ; + path d ; d := ulcorner p -- urcorner p -- + urcorner q -- ulcorner q -- cycle ; + path e ; e := llcorner p -- lrcorner p -- + urcorner p -- urcorner q -- + lrcorner q -- llcorner q -- cycle ; + path f ; f := llcorner p -- ulcorner p -- + urcorner p -- urcorner q -- + ulcorner q -- llcorner q -- cycle ; + + linecap := butt ; pickup pencircle scaled back_linewidth ; + + if back_type=1 : + + fill p withcolor back_fillcolor ; + fill a withcolor back_leftcolor ; + fill b withcolor back_bottomcolor ; + fill c withcolor back_rightcolor ; + fill d withcolor back_topcolor ; + draw a withcolor back_linecolor ; + draw d withcolor back_linecolor ; + draw b withcolor back_linecolor ; + draw c withcolor back_linecolor ; + + elseif back_type=2 : + + fill p withcolor back_fillcolor ; + fill e withcolor back_bottomcolor ; + fill f withcolor back_topcolor ; + draw e withcolor back_linecolor ; + draw f withcolor back_linecolor ; + + elseif back_type=3 : + + fill v withcolor back_nillcolor ; + fill w withcolor back_fillcolor ; + draw v withcolor back_linecolor ; + draw w withcolor back_linecolor ; + + elseif back_type=4 : + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=5 : + + t := t rotatedaround(center t,180) ; + u := u rotatedaround(center u,180) ; + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=6 : + + r := r rotatedaround(center r,180) ; + s := s rotatedaround(center s,180) ; + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + + elseif back_type=7 : + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + +fi ; + +enddef ; + +endinput ; + +beginfig (1) ; + +some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, .7white, .6white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +endfig ; + +end . diff --git a/metapost/context/base/mpiv/mp-bare.mpiv b/metapost/context/base/mpiv/mp-bare.mpiv new file mode 100644 index 000000000..c6194b1ee --- /dev/null +++ b/metapost/context/base/mpiv/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/mpiv/mp-base.mpiv b/metapost/context/base/mpiv/mp-base.mpiv new file mode 100644 index 000000000..28eb57fb8 --- /dev/null +++ b/metapost/context/base/mpiv/mp-base.mpiv @@ -0,0 +1,956 @@ +% This is a reformatted copy of the plain.mp file. We use a copy +% because (1) we want to make sure that there are no unresolved +% dependencies, and (2) we may patch this file eventually. + +% This file gives the macros for plain MetaPost It contains all the +% features of plain METAFONT except those specific to font-making. +% There are also a number of macros for labeling figures, etc. + +% For practical reasons I have moved some new code here (and might +% remove some code as well). After all, there is no development in +% this format. + +string base_name, base_version ; + +base_name := "plain" ; +base_version := "1.004 for metafun iv" ; + +message "loading metafun, including plain.mp version " & base_version ; + +delimiters () ; % this makes parentheses behave like parentheses + +def upto = step 1 until enddef ; +def downto = step -1 until enddef ; + +def exitunless expr c = + exitif not c +enddef ; + +let relax = \ ; % ignore the word relax, as in TeX +let \\ = \ ; % double relaxation is like single + +def [[ = [ [ enddef ; +def ]] = ] ] enddef ; + +def -- = + {curl 1} .. {curl 1} +enddef ; + +def --- = + .. tension infinity .. +enddef ; + +def ... = + .. tension atleast 1 .. +enddef ; + +def gobble primary g = +enddef ; + +primarydef g gobbled gg = +enddef ; + +def hide(text t) = + exitif numeric begingroup t ; endgroup ; +enddef ; + +def ??? = + hide ( + interim showstopping := 1 ; + showdependencies + ) +enddef ; + +def stop expr s = + message s ; + gobble readstring +enddef ; + +warningcheck :=1 ; +tracinglostchars :=1 ; + +def interact = % sets up to make "show" commands stop + hide ( + showstopping := 1 ; + tracingonline := 1 ; + ) +enddef ; + +def loggingall = % puts tracing info into the log + tracingcommands := 3 ; + tracingtitles := 1 ; + tracingequations := 1 ; + tracingcapsules := 1 ; + tracingspecs := 2 ; + tracingchoices := 1 ; + tracinglostchars := 1 ; + tracingstats := 1 ; + tracingoutput := 1 ; + tracingmacros := 1 ; + tracingrestores := 1 ; +enddef ; + +def tracingall = % turns on every form of tracing + tracingonline := 1 ; + showstopping := 1 ; + loggingall ; +enddef ; + +def tracingnone = % turns off every form of tracing + tracingcommands := 0 ; + tracingtitles := 0 ; + tracingequations := 0 ; + tracingcapsules := 0 ; + tracingspecs := 0 ; + tracingchoices := 0 ; + tracinglostchars := 0 ; + tracingstats := 0 ; + tracingoutput := 0 ; + tracingmacros := 0 ; + tracingrestores := 0 ; +enddef ; + +%% dash patterns + +vardef dashpattern(text t) = + save on, off, w ; + let on = _on_ ; + let off = _off_ ; + w = 0 ; + nullpicture t +enddef ; + +tertiarydef p _on_ d = + begingroup save pic ; + picture pic; + pic = p ; + addto pic doublepath (w,w) .. (w+d,w) ; + w := w + d ; + pic shifted (0,d) + endgroup +enddef ; + +tertiarydef p _off_ d = + begingroup w := w + d ; + p shifted (0,d) + endgroup +enddef ; + +%% basic constants and mathematical macros + +% numeric constants + +newinternal eps, epsilon, infinity, _ ; + +eps := .00049 ; % this is a pretty small positive number +epsilon := 1/256/256 ; % but this is the smallest +infinity := 4095.99998 ; % and this is the largest +_ := -1 ; % internal constant to make macros unreadable but shorter + +% linejoin and linecap types + +newinternal mitered, rounded, beveled, butt, squared ; + +mitered := 0 ; rounded := 1 ; beveled := 2 ; +butt := 0 ; rounded := 1 ; squared := 2 ; + +% pair constants + +pair right, left, up, down, origin; + +origin = (0,0) ; +up = -down = (0,1) ; +right = -left = (1,0) ; + +% path constants + +path quartercircle, halfcircle, fullcircle, unitsquare ; + +fullcircle = makepath pencircle ; +halfcircle = subpath (0,4) of fullcircle ; +quartercircle = subpath (0,2) of fullcircle ; +unitsquare = (0,0) -- (1,0) -- (1,1) -- (0,1) -- cycle ; + +% transform constants + +transform identity ; + +for z=origin,right,up : + z transformed identity = z ; +endfor + +% color constants (all in rgb color space) + +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 ; % obsolete + +let graypart = greypart ; +let greycolor = numeric ; +let graycolor = numeric ; + +% color part (will be overloaded) + +def colorpart primary t = + if colormodel t=7: + (cyanpart t, magentapart t, yellowpart t, blackpart t) + elseif colormodel t = 5 : + (redpart t, greenpart t, bluepart t) + elseif colormodel t = 3 : + (greypart t) + elseif colormodel t = 1 : + false + elseif defaultcolormodel = 7 : + (0,0,0,1) + elseif defaultcolormodel = 5 : + black + elseif defaultcolormodel = 3 : + 0 + else : + false + fi +enddef ; + +% picture constants + +picture blankpicture, evenly, withdots ; + +blankpicture = nullpicture ; % display blankpicture... +evenly = dashpattern(on 3 off 3) ; % dashed evenly +withdots = dashpattern(off 2.5 on 0 off 2.5) ; % dashed withdots + +% string constants + +string ditto, EOF ; + +ditto = char 34 ; % ASCII double-quote mark +EOF = char 0 ; % end-of-file for readfrom and write..to + +% pen constants + +pen pensquare, penrazor, penspeck ; + +pensquare = makepen(unitsquare shifted -(.5,.5)) ; +penrazor = makepen((-.5,0) -- (.5,0) -- cycle) ; +penspeck = pensquare scaled eps ; + +% nullary operators + +vardef whatever = + save ? ; + ? +enddef ; + +% unary operators + +let abs = length ; + +vardef round primary u = + if numeric u : + floor(u+.5) + elseif pair u : + (round xpart u, round ypart u) + else : + u + fi +enddef ; + +vardef ceiling primary x = + -floor(-x) +enddef ; + +vardef byte primary s = + if string s : + ASCII + fi s +enddef ; + +vardef dir primary d = + right rotated d +enddef ; + +vardef unitvector primary z = + z/abs z +enddef ; + +vardef inverse primary T = + transform T_ ; + T_ transformed T = identity ; + T_ +enddef ; + +vardef counterclockwise primary c = + if turningnumber c <= 0 : + reverse + fi c +enddef ; + +vardef tensepath expr r = + for k=0 upto length r - 1 : + point k of r --- + endfor + if cycle r : + cycle + else : + point infinity of r + fi +enddef ; + +vardef center primary p = + .5[llcorner p, urcorner p] +enddef ; + +% binary operators + +primarydef x mod y = + (x-y*floor(x/y)) +enddef ; + +primarydef x div y = + floor(x/y) +enddef ; + +primarydef w dotprod z = + (xpart w * xpart z + ypart w * ypart z) +enddef ; + +primarydef x**y = + if y = 2 : + x*x + else : + takepower y of x + fi +enddef ; + +def takepower expr y of x = + if x>0 : + mexp(y*mlog x) + elseif (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 ; + +% 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 ; + +vardef directionpoint expr z of p = + a_ := directiontime z of p ; + if a_ < 0 : + errmessage("The direction doesn't occur") ; + fi + point a_ of p +enddef ; + +secondarydef p intersectionpoint q = + begingroup + save x_, y_ ; + (x_,y_) = p intersectiontimes q ; + if x_ < 0 : + errmessage("The paths don't intersect") ; + origin + else : + .5[point x_ of p, point y_ of q] + fi + endgroup +enddef ; + +tertiarydef p softjoin q = + begingroup + c_ := fullcircle scaled 2join_radius shifted point 0 of q ; + a_ := ypart(c_ intersectiontimes p) ; + b_ := ypart(c_ intersectiontimes q) ; + if a_ < 0 : + point 0 of p{direction 0 of p} + else : + subpath(0,a_) of p + fi + ... + if b_ < 0 : + {direction infinity of q} point infinity of q + else : + subpath(b_,infinity) of q + fi + endgroup +enddef ; + +newinternal join_radius, a_, b_ ; path c_ ; + +path cuttings ; % what got cut off + +tertiarydef a cutbefore b = % tries to cut as little as possible + begingroup + save t ; + (t, whatever) = a intersectiontimes b ; + if t < 0 : + cuttings := point 0 of a ; + a + else : + cuttings := subpath (0,t) of a ; + subpath (t,length a) of a + fi + endgroup +enddef ; + +tertiarydef a cutafter b = + reverse (reverse a cutbefore b) + hide(cuttings := reverse cuttings) +enddef ; + +% special operators + +vardef incr suffix $ = $:=$+1; $ enddef ; +vardef decr suffix $ = $:=$-1; $ enddef ; + +def reflectedabout(expr w,z) = % reflects about the line w..z + transformed + begingroup + transform T_ ; + w transformed T_ = w ; + z transformed T_ = z ; + xxpart T_ = -yypart T_ ; + xypart T_ = yxpart T_ ; % T_ is a reflection + T_ + endgroup +enddef ; + +def rotatedaround(expr z, d) = % rotates d degrees around z + shifted -z rotated d shifted z +enddef ; + +let rotatedabout = rotatedaround ; % for roundabout people + +vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings + save u_ ; + setu_ u ; + for uu = t : + if uu < u_ : + u_ := uu ; + fi + endfor + u_ +enddef ; + +vardef max(expr u)(text t) = % t is a list of numerics, pairs, or strings + save u_ ; + setu_ u ; + for uu = t : + if uu > u_ : + u_ := uu ; + fi + endfor + u_ +enddef ; + +def setu_ primary u = + if pair u : + pair u_ + elseif string u : + string u_ + fi ; + u_=u +enddef ; + +def flex(text t) = % t is a list of pairs + hide ( + n_ := 0 ; + for z=t : + z_[incr n_] := z ; + endfor + dz_ := z_[n_]-z_1 + ) + z_1 for k=2 upto n_-1 : + ... z_[k]{dz_} + endfor ... z_[n_] +enddef ; + +newinternal n_; pair z_[],dz_; + +def superellipse(expr r,t,l,b,s) = + r { up } ... (s[xpart t,xpart r],s[ypart r,ypart t]) { t-r } ... + t { left } ... (s[xpart t,xpart l],s[ypart l,ypart t]) { l-t } ... + l { down } ... (s[xpart b,xpart l],s[ypart l,ypart b]) { b-l } ... + b { right } ... (s[xpart b,xpart r],s[ypart r,ypart b]) { r-b } ... cycle enddef ; + +vardef interpath(expr a,p,q) = + for t=0 upto length p-1 : + a[point t of p, point t of q] .. controls a[postcontrol t of p, postcontrol t of q] and a[precontrol t+1 of p, precontrol t+1 of q] .. + endfor + if cycle p : + cycle + else : + a[point infinity of p, point infinity of q] + fi +enddef ; + +vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false + tx_:=true_x; fx_:=false_x; + forever : + x_ := .5[tx_,fx_] ; + exitif abs(tx_-fx_) <= tolerance ; + if @#(x_) : + tx_ + else : + fx_ + fi := x_ ; + endfor + x_ % now x_ is near where @# changes from true to false +enddef ; + +newinternal tolerance, tx_, fx_, x_ ; + +tolerance := .01 ; + +vardef buildcycle(text ll) = + save ta_, tb_, k_, i_, pp_ ; path pp_[] ; + k_ = 0 ; + for q=ll : + pp_[incr k_] = q ; + endfor + i_ = k_ ; + for i=1 upto k_ : + (ta_[i], length pp_[i_]-tb_[i_]) = pp_[i] intersectiontimes reverse pp_[i_] ; + if ta_[i]<0 : + errmessage("Paths "& decimal i &" and "& decimal i_ &" don't intersect") ; + fi + i_ := i; + endfor + for i=1 upto k_ : + subpath (ta_[i],tb_[i]) of pp_[i] .. + endfor + cycle +enddef ; + +%% units of measure + +mm := 2.83464 ; +pt := 0.99626 ; +dd := 1.06601 ; +bp := 1 ; +cm := 28.34645 ; +pc := 11.95517 ; +cc := 12.79213 ; +in := 72 ; + +vardef magstep primary m = % obsolete + mexp(46.67432m) +enddef ; + +%% macros for drawing and filling + +def drawoptions(text t) = + def _op_ = t enddef +enddef ; + +% parameters that effect drawing + +linejoin := rounded ; +linecap := rounded ; +miterlimit := 10 ; + +drawoptions() ; + +pen currentpen ; +picture currentpicture ; + +def fill expr c = + addto currentpicture contour c _op_ +enddef ; + +def draw expr p = + addto currentpicture + if picture p : + also p + else : + doublepath p withpen currentpen + fi + _op_ +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 ; +% +% 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 ; +def undraw expr p = draw p withcolor background enddef ; +def unfilldraw expr c = filldraw c withcolor background enddef ; +def undrawdot expr z = drawdot z withcolor background enddef ; + +def erase text t = + def _e_ = + withcolor background hide(def _e_ = enddef ;) + enddef ; + t _e_ +enddef ; + +def _e_ = enddef ; + +def cutdraw text t = + begingroup + interim linecap := butt ; + draw t _e_ ; + endgroup +enddef ; + +vardef image(text t) = + save currentpicture ; + picture currentpicture ; + currentpicture := nullpicture ; + t ; + currentpicture +enddef ; + +def pickup secondary q = + if numeric q : + numeric_pickup_ + else : + pen_pickup_ + fi q +enddef ; + +def numeric_pickup_ primary q = + if unknown pen_[q] : + errmessage "Unknown pen" ; + clearpen + else : + currentpen := pen_ [q] ; + pen_lft := pen_lft_[q] ; + pen_rt := pen_rt_ [q] ; + pen_top := pen_top_[q] ; + pen_bot := pen_bot_[q] ; + currentpen_path := pen_path_[q] + fi ; +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 ; + path currentpen_path ; +enddef ; + +newinternal pen_lft, pen_rt, pen_top, pen_bot, pen_count_ ; + +vardef savepen = + pen_[incr pen_count_] = currentpen ; + pen_lft_ [pen_count_] = pen_lft ; + pen_rt_ [pen_count_] = pen_rt ; + pen_top_ [pen_count_] = pen_top ; + pen_bot_ [pen_count_] = pen_bot ; + pen_path_[pen_count_] = currentpen_path ; + pen_count_ +enddef ; + +def clearpen = + currentpen := nullpen; + pen_lft := pen_rt := pen_top := pen_bot := 0 ; + path currentpen_path ; +enddef ; + +def clear_pen_memory = + pen_count_ := 0 ; + numeric pen_lft_[], pen_rt_[], pen_top_[], pen_bot_[] ; + pen currentpen, pen_[]; + path currentpen_path, pen_path_[] ; +enddef ; + +vardef lft primary x = x + if pair x: (pen_lft,0) else: pen_lft fi enddef ; +vardef rt primary x = x + if pair x: (pen_rt,0) else: pen_rt fi enddef ; +vardef top primary y = y + if pair y: (0,pen_top) else: pen_top fi enddef ; +vardef bot primary y = y + if pair y: (0,pen_bot) else: pen_bot fi enddef ; + +vardef penpos@#(expr b,d) = + (x@#r-x@#l,y@#r-y@#l) = (b,0) rotated d ; + x@# = .5(x@#l+x@#r) ; + y@# = .5(y@#l+y@#r) ; % ; added HH +enddef ; + +path path_.l, path_.r ; + +def penstroke text t = + forsuffixes e = l, r : + path_.e := t ; + endfor + fill path_.l -- reverse path_.r -- cycle +enddef ; + +%% High level drawing commands + +newinternal ahlength, ahangle ; + +ahlength := 4 ; % default arrowhead length 4bp +ahangle := 45 ; % default head angle 45 degrees + +vardef arrowhead expr p = + save q, e ; path q ; pair e ; + e = point length p of p ; + q = gobble(p shifted -e cutafter makepath(pencircle scaled 2ahlength)) cuttings ; + (q rotated .5ahangle & reverse q rotated -.5ahangle -- cycle) shifted e +enddef ; + +path _apth ; + +def drawarrow expr p = _apth := p ; _finarr enddef ; +def drawdblarrow expr p = _apth := p ; _findarr enddef ; + +def _finarr text t = + draw _apth t ; + filldraw arrowhead _apth t +enddef ; + +def _findarr text t = % this had fill in 0.63 (potential incompatibility) + draw _apth t ; + filldraw arrowhead _apth withpen currentpen t ; + filldraw arrowhead reverse _apth withpen currentpen t ; % ; added HH +enddef ; + +%% macros for labels + +newinternal bboxmargin ; + +bboxmargin := 2bp ; % this can bite you + +vardef bbox primary p = + llcorner p - ( bboxmargin, bboxmargin) -- + lrcorner p + ( bboxmargin,-bboxmargin) -- + urcorner p + ( bboxmargin, bboxmargin) -- + ulcorner p + (-bboxmargin, bboxmargin) -- cycle +enddef ; + +string defaultfont ; newinternal defaultscale, labeloffset ; + +defaultfont := "cmr10" ; +defaultscale := 1 ; +labeloffset := 3bp ; + +vardef thelabel@#(expr s,z) = % Position s near z + save p ; picture p ; + if picture s : + p = s + else : + p = s infont defaultfont scaled defaultscale + fi ; + p shifted (z + labeloffset*laboff@# - ( labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p) ) +enddef ; + +def label = + draw thelabel +enddef ; + +newinternal dotlabeldiam ; + +dotlabeldiam := 3bp ; + +vardef dotlabel@#(expr s,z) text t_ = + label@#(s,z) t_ ; + % label@#(s,z) ; + interim linecap := rounded ; + draw z withpen pencircle scaled dotlabeldiam t_ ; +enddef ; + +def makelabel = + dotlabel +enddef ; + +% this will be overloaded + +pair laboff, laboff.lft, laboff.rt, laboff.top, laboff.bot ; +pair laboff.ulft, laboff.llft, laboff.urt, laboff.lrt ; + +laboff = (0,0) ; labxf = .5 ; labyf = .5 ; +laboff.lft = (-1,0) ; labxf.lft = 1 ; labyf.lft = .5 ; +laboff.rt = (1,0) ; labxf.rt = 0 ; labyf.rt = .5 ; +laboff.bot = (0,-1) ; labxf.bot = .5 ; labyf.bot = 1 ; +laboff.top = (0,1) ; labxf.top = .5 ; labyf.top = 0 ; +laboff.ulft = (-.7,.7) ; labxf.ulft = 1 ; labyf.ulft = 0 ; +laboff.urt = (.7,.7) ; labxf.urt = 0 ; labyf.urt = 0 ; +laboff.llft = -(.7,.7) ; labxf.llft = 1 ; labyf.llft = 1 ; +laboff.lrt = (.7,-.7) ; labxf.lrt = 0 ; labyf.lrt = 1 ; + +vardef labels@#(text t) = + forsuffixes $=t : + label@#(str$,z$) ; + endfor +enddef ; + +% till lhere + +vardef dotlabels@#(text t) = + forsuffixes $=t: + dotlabel@#(str$,z$) ; + endfor +enddef ; + +vardef penlabels@#(text t) = + forsuffixes $$=l,,r : + forsuffixes $=t : + makelabel@#(str$.$$,z$.$$) ; + endfor + endfor +enddef ; + +% range 4 thru 10 + +def range expr x = + _numtok_[x] +enddef ; + +def _numtok_ suffix x = + x +enddef ; + +tertiarydef m thru n = + m for x=m+1 step 1 until n : + , _numtok_[x] + endfor +enddef ; + +%% Overall administration + +string extra_beginfig, extra_endfig ; + +extra_beginfig := "" ; +extra_endfig := "" ; + +def beginfig(expr c) = + begingroup + charcode := c ; + clearxy ; + clearit ; + clearpen ; + pickup defaultpen ; + drawoptions() ; + scantokens extra_beginfig ; +enddef ; + +def endfig = + ; % added by HH + scantokens extra_endfig ; + shipit ; + endgroup +enddef ; + +%% last-minute items + +vardef z@# = + (x@#,y@#) +enddef ; + +def clearxy = + save x, y +enddef ; + +def clearit = + currentpicture := nullpicture +enddef ; + +def shipit = + shipout currentpicture +enddef ; + +let bye = end ; +outer end, bye ; + +clear_pen_memory ; % initialize the savepen mechanism +clearit ; + +% set default line width + +newinternal defaultpen ; + +pickup pencircle scaled .5bp ; + +defaultpen := savepen ; diff --git a/metapost/context/base/mpiv/mp-butt.mpiv b/metapost/context/base/mpiv/mp-butt.mpiv new file mode 100644 index 000000000..6f5b90a7e --- /dev/null +++ b/metapost/context/base/mpiv/mp-butt.mpiv @@ -0,0 +1,77 @@ +%D \module +%D [ file=mp-butt.mpiv, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=buttons, +%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_butt : endinput ; fi ; + +boolean context_butt ; context_butt := true ; + +def predefinedbutton (expr button_type, button_size, button_linecolor, button_fillcolor) = + + begingroup ; + + save button_linewidth, p, d, l ; + + numeric button_linewidth ; button_linewidth := button_size/10 ; + + drawoptions (withpen pencircle scaled button_linewidth withcolor button_linecolor) ; + + path p ; p := unitsquare scaled button_size ; + numeric d ; d := button_size ; + numeric l ; l := button_linewidth ; + + fill p withcolor button_fillcolor ; + draw p ; + + if button_type = 101 : + draw (d-2l,2l)--(2l,.5d)--(d-2l,d-2l)--cycle ; + elseif button_type = 102 : + draw (2l,2l)--(d-2l,.5d)--(2l,d-2l)--cycle ; + elseif button_type = 103 : + for i=2l step 2l until d-2l : + draw (2l,i)--(2l ,i) ; + draw (4l,i)--(d-2l,i) ; + endfor ; + elseif button_type = 104 : + for i=2l step 2l until d-2l : + draw (2l ,i)--(d/2-l,i) ; + draw (d/2+l,i)--(d-2l ,i) ; + endfor ; + elseif button_type = 105 : + fill fullcircle scaled (.2d) shifted (.5d,.7d) ; + fill fullcircle xscaled (.6d) yscaled d shifted (.5d,0) ; + clip currentpicture to p ; + draw p ; + elseif button_type = 106 : + draw (2l,2l)--(d-2l,d-2l) ; + draw (d-2l,2l)--(2l,d-2l) ; + elseif button_type = 107 : + p := (3l,d-2l)--(d-3l,d-2l)--(.5d,4l)--cycle ; + fill p ; draw p ; + draw (.5d,2l) ; + elseif button_type = 108 : + draw (.5d,2l)--(d-2l,d-2l)--(2l,d-2l)--cycle ; + elseif button_type = 109 : + draw (.5d,d-2l)--(d-2l,2l)--(2l,2l)--cycle ; + elseif button_type = 110 : + button_linewidth := button_linewidth/2 ; + draw p enlarged (-2l,-l) ; + for i=2l step l until d-2l : + draw (3l,i)--(d-3l,i) ; + endfor ; + fi ; + + endgroup ; + +enddef ; + +let some_button = predefinedbutton diff --git a/metapost/context/base/mpiv/mp-char.mpiv b/metapost/context/base/mpiv/mp-char.mpiv new file mode 100644 index 000000000..f604accd8 --- /dev/null +++ b/metapost/context/base/mpiv/mp-char.mpiv @@ -0,0 +1,1116 @@ +%D \module +%D [ file=mp-char.mpiv, +%D version=2011.10.1, % 1998.10.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=charts, +%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. + +%D This is ancient code .. but I see no need to rewrite it. This is +%D already a partial rewrite but more could be delegated to \LUA\ +%D when used in \CONTEXT\ but it does not pay off now to look into +%D that. + +%D For historic reason we first build and then flush but we could +%D as well flush directly which would save us caching. + +if unknown context_shap : input "mp-shap.mpiv" ; fi ; +if known context_flow : endinput ; fi ; + +boolean context_flow ; context_flow := true ; + +%D settings + +numeric flow_grid_width ; flow_grid_width := 60pt ; +numeric flow_shape_width ; flow_shape_width := 45pt ; +numeric flow_grid_height ; flow_grid_height := 40pt ; +numeric flow_shape_height ; flow_shape_height := 30pt ; +numeric flow_chart_offset ; flow_chart_offset := 2pt ; +color flow_chart_background_color ; flow_chart_background_color := white ; +boolean flow_show_mid_points ; flow_show_mid_points := false ; +boolean flow_show_con_points ; flow_show_con_points := false ; +boolean flow_show_all_points ; flow_show_all_points := false ; +numeric flow_shape_line_width ; flow_shape_line_width := 2pt ; +color flow_shape_line_color ; flow_shape_line_color := .5white ; +color flow_shape_fill_color ; flow_shape_fill_color := .9white ; +color flow_connection_line_color ; flow_connection_line_color := .2white ; + +numeric flow_connection_line_width ; flow_connection_line_width := flow_shape_line_width ; + +numeric flow_connection_smooth_size ; flow_connection_smooth_size := 5pt ; +numeric flow_connection_arrow_size ; flow_connection_arrow_size := 4pt ; +numeric flow_connection_dash_size ; flow_connection_dash_size := 3pt ; + +numeric flow_max_x ; flow_max_x := 6 ; +numeric flow_max_y ; flow_max_y := 4 ; + +boolean flow_smooth ; flow_smooth := true ; +boolean flow_peepshape ; flow_peepshape := false ; +boolean flow_arrowtip ; flow_arrowtip := true ; +boolean flow_dashline ; flow_dashline := false ; +boolean flow_forcevalid ; flow_forcevalid := false ; +boolean flow_touchshape ; flow_touchshape := false ; +boolean flow_showcrossing ; flow_showcrossing := false ; +boolean flow_reverse_y ; flow_reverse_y := true ; + +picture flow_dash_pattern ; flow_dash_pattern := nullpicture ; + +numeric flow_shape_node ; flow_shape_node := 0 ; +numeric flow_shape_action ; flow_shape_action := 24 ; +numeric flow_shape_procedure ; flow_shape_procedure := 5 ; +numeric flow_shape_product ; flow_shape_product := 12 ; +numeric flow_shape_decision ; flow_shape_decision := 14 ; +numeric flow_shape_archive ; flow_shape_archive := 19 ; +numeric flow_shape_loop ; flow_shape_loop := 35 ; +numeric flow_shape_wait ; flow_shape_wait := 6 ; +numeric flow_shape_subprocedure ; flow_shape_subprocedure := 20 ; +numeric flow_shape_singledocument ; flow_shape_singledocument := 32 ; +numeric flow_shape_multidocument ; flow_shape_multidocument := 33 ; +numeric flow_shape_right ; flow_shape_right := 66 ; +numeric flow_shape_left ; flow_shape_left := 67 ; +numeric flow_shape_up ; flow_shape_up := 68 ; +numeric flow_shape_down ; flow_shape_down := 69 ; + +numeric flow_label_offset ; flow_label_offset := 0 ; +numeric flow_exit_offset ; flow_exit_offset := 0 ; +numeric flow_comment_offset ; flow_comment_offset := 0 ; + +% vardef some_shape_path (expr type) == imported from mp-shap + +def flow_show_shapes(expr n) = + flow_begin_chart(n,8,10) ; + flow_show_con_points := true ; + for i=0 upto 7 : + for j=0 upto 9 : + flow_new_shape(i+1,j+1,i*10+j); + endfor ; + endfor ; + flow_end_chart ; +enddef ; + +%D connections + +def flow_new_chart = + + flow_grid_width := 60pt ; + flow_shape_width := 45pt ; + flow_grid_height := 40pt ; + flow_shape_height := 30pt ; + flow_chart_offset := 2pt ; + flow_chart_background_color := white ; + flow_show_mid_points := false ; + flow_show_con_points := false ; + flow_show_all_points := false ; + flow_shape_line_width := 2pt ; + flow_shape_line_color := .5white ; + flow_shape_fill_color := .9white ; + flow_connection_line_color := .2white ; + flow_connection_line_width := flow_shape_line_width ; + flow_connection_smooth_size := 5pt ; + flow_connection_arrow_size := 4pt ; + flow_connection_dash_size := 3pt ; + flow_label_offset := 0 ; + flow_exit_offset := 0 ; + flow_comment_offset := 0 ; + + flow_max_x := 6 ; + flow_max_y := 4 ; + + flow_smooth := true ; + flow_peepshape := false ; + flow_arrowtip := true ; + flow_dashline := false ; + flow_forcevalid := false ; + flow_touchshape := false ; + flow_showcrossing := false ; + flow_reverse_y := true ; + + flow_dash_pattern := nullpicture ; + + numeric flow_xypoint ; flow_xypoint := 0 ; + numeric flow_cpath ; flow_cpath := 0 ; + + pair flow_xypoints [] ; + boolean flow_xyfree [][] ; + path flow_xypath [][] ; + numeric flow_xysx [][] ; + numeric flow_xysy [][] ; + color flow_xyfill [][] ; + color flow_xydraw [][] ; + numeric flow_xyline [][] ; + boolean flow_xypeep [][] ; + picture flow_xytext [][] ; + picture flow_xylabel [][] ; + picture flow_xyexit [][] ; + picture flow_xycomment [][] ; + path flow_cpaths [] ; + numeric flow_cline [] ; + color flow_ccolor [] ; + boolean flow_carrow [] ; + boolean flow_cdash [] ; + boolean flow_ccross [] ; + picture flow_tpicture [][] ; + picture flow_bpicture [][] ; + picture flow_lpicture [][] ; + picture flow_rpicture [][] ; + path flow_connections[][][] ; + + predefined_shapes[61] := (fullcircle scaled (1.5*predefined_shapes_yradius) xscaled (flow_grid_height/flow_grid_width)) ; + predefined_shapes[62] := (fullcircle scaled (2.0*predefined_shapes_yradius) xscaled (flow_grid_height/flow_grid_width)) ; + +enddef ; + +flow_new_chart ; + +def flow_y_pos(expr y) = +% if flow_reverse_y : + flow_max_y + 1 - y +% else : +% y +% fi +enddef ; + +def flow_initialize_grid(expr maxx, maxy) = + flow_max_x := maxx ; + flow_max_y := maxy ; + flow_dsp_x := 0 ; + flow_dsp_y := 0 ; + for x=1 upto flow_max_x : + for y=1 upto flow_max_y : + flow_xyfree[x][y] := true ; + flow_xyfill[x][y] := flow_shape_fill_color ; + flow_xydraw[x][y] := flow_shape_line_color ; + flow_xyline[x][y] := flow_shape_line_width ; + endfor ; + endfor ; +enddef ; + +def flow_scaled_to_grid = + xscaled flow_grid_width yscaled flow_grid_height +enddef ; + +def flow_xy_offset(expr x, y) = + (x+.5,y+.5) +enddef ; + +def flow_draw_shape(expr x, yy, p, sx, sy) = + begingroup ; + save y ; numeric y ; + y := flow_y_pos(yy) ; + flow_xypath [x][y] := (p xscaled sx yscaled sy) shifted flow_xy_offset(x,y) ; + flow_xyfree [x][y] := false ; + flow_xysx [x][y] := sx ; + flow_xysy [x][y] := sy ; + flow_xyfill [x][y] := flow_shape_fill_color ; + flow_xydraw [x][y] := flow_shape_line_color ; + flow_xyline [x][y] := flow_shape_line_width ; + flow_xypeep [x][y] := flow_peepshape ; + endgroup ; +enddef ; + +vardef flow_i_point (expr x, y, p, t) = + begingroup ; + save q, ok ; pair q ; boolean ok ; + q := flow_xypath[x][y] intersection_point ((p) shifted flow_xy_offset(x,y)) ; + ok := true ; + if not ok : + message (t & " of shape (" & decimal x & "," & decimal y & ") limited") ; + fi ; + q + endgroup +enddef ; + +vardef flow_trimmed (expr x, y, z, t) = + if flow_touchshape and t : + flow_xyline[x][y]/z + else : + epsilon + fi +enddef ; + +numeric flow_zfactor ; flow_zfactor := 1/3 ; + +vardef flow_xy_bottom (expr x, y, z, t) = + flow_i_point(x, y, ((0,0)--(0,-2)) shifted (flow_zfactor*z*flow_xysx[x][y],0), "bottom") + shifted(0,-flow_trimmed(x,y,flow_grid_height,t)) +enddef ; + +vardef flow_xy_top (expr x, y, z, t) = + flow_i_point (x, y, ((0,0)--(0,2)) shifted (flow_zfactor*z*flow_xysx[x][y],0), "top") + shifted(0,flow_trimmed(x,y,flow_grid_height,t)) +enddef ; + +vardef flow_xy_left (expr x, y, z, t) = + flow_i_point (x, y, ((0,0)--(-2,0)) shifted (0,flow_zfactor*z*flow_xysy[x][y]), "left") + shifted(-flow_trimmed(x,y,flow_grid_width,t),0) +enddef ; + +vardef flow_xy_right (expr x, y, z, t) = + flow_i_point (x, y, ((0,0)--(2,0)) shifted (0,flow_zfactor*z*flow_xysy[x][y]), "right") + shifted(flow_trimmed(x,y,flow_grid_width,t),0) +enddef ; + +def flow_flush_shapes = + for x=1 upto flow_max_x : + for y=1 upto flow_max_y : + flow_flush_shape(x, y) ; + endfor ; + endfor ; +enddef ; + +def flow_flush_pictures = + for x=1 upto flow_max_x : + for y=1 upto flow_max_y : + flow_flush_picture(x, y) ; + endfor ; + endfor ; +enddef ; + +def flow_draw_connection_point(expr x, y, z) = + pickup pencircle scaled if (z=0): 2 fi flow_xyline[x][y] ; + drawdot flow_xy_bottom(x,y,z,false) flow_scaled_to_grid withcolor (1,0,0) ; + drawdot flow_xy_top (x,y,z,false) flow_scaled_to_grid withcolor (0,1,0) ; + drawdot flow_xy_left (x,y,z,false) flow_scaled_to_grid withcolor (0,0,1) ; + drawdot flow_xy_right (x,y,z,false) flow_scaled_to_grid withcolor (1,1,0) ; +enddef ; + +def flow_flush_shape(expr x, yy) = + begingroup ; + save y ; numeric y ; + y := flow_y_pos(yy) ; + if not flow_xyfree[x][y] : + pickup pencircle scaled flow_xyline[x][y] ; + if flow_xypeep[x][y] : + fill (flow_xypath[x][y] peepholed (unitsquare shifted (x,y))) + flow_scaled_to_grid withpen pencircle scaled 0 + withcolor flow_chart_background_color ; + else : + fill flow_xypath[x][y] flow_scaled_to_grid withcolor flow_xyfill[x][y] ; + fi ; + draw flow_xypath[x][y] flow_scaled_to_grid withcolor flow_xydraw[x][y] ; + if flow_show_con_points or flow_show_all_points : + flow_draw_connection_point(x, y, 0) ; + fi ; + if flow_show_all_points : + for i=-1 upto 1 : + flow_draw_connection_point(x, y, i) ; + endfor ; + fi ; + fi ; + endgroup ; +enddef ; + +vardef flow_points_initialized(expr xfrom, yfrom, xto, yto, n) = + if unknown flow_xyfree[xfrom][yfrom] or unknown flow_xyfree[xto][yto] : + flow_xypoint := 0 ; false + elseif not flow_xyfree[xfrom][yfrom] and not flow_xyfree[xto][yto] : + flow_xypoint := n ; true + else : + flow_xypoint := 0 ; false + fi +enddef ; + +def flow_collapse_points = % this can become a core macro + begingroup ; + % remove redundant points + save n ; numeric n ; + n := 1 ; + for i=2 upto flow_xypoint : + if not (flow_xypoints[i] = flow_xypoints[n]) : + n := n + 1 ; + flow_xypoints[n] := flow_xypoints[i] + fi ; + endfor ; + flow_xypoint := n ; + % make straight lines + if flow_xypoints[2] = flow_xypoints[flow_xypoint-1] : + flow_xypoints[3] := flow_xypoints[flow_xypoint] ; + flow_xypoint := 3 ; + fi ; + endgroup ; +enddef ; + +vardef flow_smooth_connection(expr a,b) = + if ypart a = ypart b : + a shifted ( if xpart a >= xpart b : - fi (flow_connection_smooth_size/flow_grid_width ),0) + else : + a shifted (0,if ypart a >= ypart b : - fi (flow_connection_smooth_size/flow_grid_height) ) + fi +enddef ; + +vardef flow_trim_points = + begingroup + save p, a, b, d, i ; numeric a, b ; path p ; pair d ; + p := for i=1 upto flow_xypoint-1 : flow_xypoints[i]-- endfor flow_xypoints[flow_xypoint] ; + if flow_touchshape : + a := flow_shape_line_width/flow_grid_width ; + b := flow_shape_line_width/flow_grid_height ; + else : + a := epsilon ; + b := epsilon ; + fi ; + d := direction infinity of p ; + flow_xypoints[flow_xypoint] := flow_xypoints[flow_xypoint] shifted + if xpart d < 0 : (+a,0) ; + elseif xpart d > 0 : (-a,0) ; + elseif ypart d < 0 : (0,+b) ; + elseif ypart d > 0 : (0,-b) ; + else : origin ; + fi ; + d := direction 0 of p ; + flow_xypoints[1] := flow_xypoints[1] shifted + if xpart d < 0 : (-a,0) ; + elseif xpart d > 0 : (+a,0) ; + elseif ypart d < 0 : (0,-b) ; + elseif ypart d > 0 : (0,+b) ; + else : origin ; + fi ; + endgroup +enddef ; + +vardef flow_trim_points = enddef ; + +vardef flow_connection_path = + if flow_reverse_connection : reverse fi (flow_xypoints[1] -- + for i=2 upto flow_xypoint-1 : + if flow_smooth : + flow_smooth_connection(flow_xypoints[i],flow_xypoints[i-1]) .. + controls flow_xypoints[i] and flow_xypoints[i] .. + flow_smooth_connection(flow_xypoints[i],flow_xypoints[i+1]) -- + else : + flow_xypoints[i] -- + fi + endfor + flow_xypoints[flow_xypoint]) +enddef ; + +def flow_draw_connection(expr i,xfrom,yfrom,xto,yto) = % 'i' is a comment reference + if flow_xypoint > 0 : + flow_collapse_points ; + flow_trim_points ; + flow_cpath := flow_cpath + 1 ; % maybe also store as x,y + flow_cpaths[flow_cpath] := flow_connection_path flow_scaled_to_grid ; + flow_cline[flow_cpath] := flow_connection_line_width ; + flow_ccolor[flow_cpath] := flow_connection_line_color ; + flow_carrow[flow_cpath] := flow_arrowtip ; + flow_cdash[flow_cpath] := flow_dashline ; + flow_ccross[flow_cpath] := flow_showcrossing ; + if flow_reverse_connection : + flow_connections[xto] [yto] [i] := flow_cpaths[flow_cpath] ; + else : + flow_connections[xfrom][yfrom][i] := flow_cpaths[flow_cpath] ; + fi ; + else : + message("no connection defined") ; + fi ; + flow_reverse_connection := false ; +enddef ; + +def flow_flush_connections = % protect locals + begingroup ; + save ip, crossing, cp ; numeric ip ; boolean crossing ; path cp ; + ahlength := flow_connection_arrow_size ; + flow_dash_pattern := dashpattern(on flow_connection_dash_size off flow_connection_dash_size) ; + for i=1 upto flow_cpath : + if flow_ccross[i] : + crossing := false ; + for j=1 upto i : + if not (point infinity of flow_cpaths[i] = point infinity of flow_cpaths[j]) : + ip := flow_cpaths[i] intersection_point flow_cpaths[j] ; + if intersection_found : crossing := true fi ; + fi ; + endfor ; + if crossing : + pickup pencircle scaled 2flow_cline[i] ; + cp := flow_cpaths[i] ; + cp := cp cutbefore point .05 length cp of cp ; + cp := cp cutafter point .95 length cp of cp ; + draw cp withcolor flow_chart_background_color ; + fi ; + fi ; + pickup pencircle scaled flow_cline[i] ; + if flow_carrow[i] : + if flow_cdash[i] : + drawarrow flow_cpaths[i] withcolor flow_ccolor[i] dashed flow_dash_pattern ; + else : + drawarrow flow_cpaths[i] withcolor flow_ccolor[i] ; + fi ; + else : + if flow_cdash[i] : + draw flow_cpaths[i] withcolor flow_ccolor[i] dashed flow_dash_pattern ; + else : + draw flow_cpaths[i] withcolor flow_ccolor[i] ; + fi ; + fi ; + flow_draw_midpoint(i) ; + endfor ; + endgroup ; +enddef ; + +def flow_draw_midpoint (expr n) = + begingroup + save p ; pair p ; + p := point .5*length(flow_cpaths[n]) of flow_cpaths[n]; + pickup pencircle scaled 2flow_cline[n] ; + if flow_show_mid_points : + drawdot p withcolor .7white ; + fi ; + endgroup ; +enddef ; + +def flow_flush_picture(expr x, yy) = + begingroup ; + save y ; numeric y ; + y := flow_y_pos(yy) ; % maybe move this to the makers + if known flow_xytext[x][y] : + draw flow_xytext[x][y] ; + fi ; + if known flow_xylabel[x][y] : + draw flow_xylabel[x][y] ; + fi ; + if known flow_xyexit[x][y] : + draw flow_xyexit[x][y] ; + fi ; + if known flow_xycomment[x][y] : + draw flow_xycomment[x][y] ; + fi ; + endgroup ; +enddef ; + +vardef flow_offset(expr x, y) = + flow_xy_offset((x+0.5)*flow_grid_width,(flow_max_y-y+1.5)*flow_grid_height) + shifted (-flow_xyline[x][y]/4,-flow_xyline[x][y]/4) % terrible hack (some compensation) +enddef ; + +def flow_chart_draw_text(expr x, y, p) = + if known flow_xytext[x][y] : + addto flow_xytext[x][y] also + else : + flow_xytext[x][y] := + fi + p shifted flow_offset(x,y) ; +enddef ; + +def flow_chart_draw_label (expr x, y, loc, txt) = + begingroup ; + save p, s ; path p ; picture s ; + p := fullsquare xscaled flow_grid_width yscaled flow_grid_height ; + p := p shifted flow_offset(x,y) ; + s := txt ; + setbounds s to boundingbox s enlarged flow_label_offset ; + if known flow_xylabel[x][y] : + addto flow_xylabel[x][y] also + else : + flow_xylabel[x][y] := + fi + if loc = "tr" : anchored.llft(s,0.5[ulcorner p,urcorner p]) ; + elseif loc = "t" : anchored.bot (s,0.5[ulcorner p,urcorner p]) ; + elseif loc = "tl" : anchored.lrt (s,0.5[ulcorner p,urcorner p]) ; + elseif loc = "br" : anchored.ulft(s,0.5[llcorner p,lrcorner p]) ; + elseif loc = "b" : anchored.top (s,0.5[llcorner p,lrcorner p]) ; + elseif loc = "bl" : anchored.urt (s,0.5[llcorner p,lrcorner p]) ; + elseif loc = "lb" : anchored.urt (s,0.5[ulcorner p,llcorner p]) ; + elseif loc = "l" : anchored.rt (s,0.5[ulcorner p,llcorner p]) ; + elseif loc = "lt" : anchored.lrt (s,0.5[ulcorner p,llcorner p]) ; + elseif loc = "rb" : anchored.ulft(s,0.5[urcorner p,lrcorner p]) ; + elseif loc = "r" : anchored.lft (s,0.5[urcorner p,lrcorner p]) ; + elseif loc = "rt" : anchored.llft(s,0.5[urcorner p,lrcorner p]) ; + else : anchored (s,center p) ; + fi ; + endgroup ; +enddef ; + +def flow_chart_draw_exit (expr x, y, loc, txt) = + begingroup ; + save p, s ; path p ; picture s ; + p := fullsquare xscaled flow_grid_width yscaled flow_grid_height ; + p := p shifted flow_offset(x,y) ; + s := txt ; + setbounds s to boundingbox s enlarged flow_exit_offset ; + if known flow_xyexit[x][y] : + addto flow_xyexit[x][y] also + else : + flow_xyexit[x][y] := + fi + if loc = "t" : anchored.top(s,0.5[ulcorner p,urcorner p]) ; + elseif loc = "b" : anchored.bot(s,0.5[llcorner p,lrcorner p]) ; + elseif loc = "l" : anchored.lft(s,0.5[ulcorner p,llcorner p]) ; + elseif loc = "r" : anchored.rt (s,0.5[urcorner p,lrcorner p]) ; + else : anchored (s,center p) ; + fi ; + endgroup ; +enddef ; + +def flow_chart_draw_comment (expr x, y, i, loc, len, txt) = % per connection + begingroup ; + if known flow_connections[x][y][i] : + save p, q, s ; path p, q ; picture s ; + p := fullsquare xscaled flow_shape_width yscaled flow_shape_height ; + p := p shifted flow_offset(x,y) ; + q := flow_connections[x][y][i] ; % already relocated + s := txt ; + setbounds s to boundingbox s enlarged flow_comment_offset ; + if known flow_xycomment[x][y] : + addto flow_xycomment[x][y] also + else : + flow_xycomment[x][y] := + fi + if loc = "tr" : anchored.llft(s,if len = 0 : 0.5[ulcorner p,urcorner p] else : point len along q fi) ; + elseif loc = "t" : anchored.bot (s,if len = 0 : 0.5[ulcorner p,urcorner p] else : point len along q fi) ; + elseif loc = "tl" : anchored.lrt (s,if len = 0 : 0.5[ulcorner p,urcorner p] else : point len along q fi) ; + elseif loc = "br" : anchored.ulft(s,if len = 0 : 0.5[llcorner p,lrcorner p] else : point len along q fi) ; + elseif loc = "b" : anchored.top (s,if len = 0 : 0.5[llcorner p,lrcorner p] else : point len along q fi) ; + elseif loc = "bl" : anchored.urt (s,if len = 0 : 0.5[llcorner p,lrcorner p] else : point len along q fi) ; + elseif loc = "lb" : anchored.urt (s,if len = 0 : 0.5[ulcorner p,llcorner p] else : point len along q fi) ; + elseif loc = "l" : anchored.rt (s,if len = 0 : 0.5[ulcorner p,llcorner p] else : point len along q fi) ; + elseif loc = "lt" : anchored.lrt (s,if len = 0 : 0.5[ulcorner p,llcorner p] else : point len along q fi) ; + elseif loc = "rb" : anchored.ulft(s,if len = 0 : 0.5[urcorner p,lrcorner p] else : point len along q fi) ; + elseif loc = "r" : anchored.lft (s,if len = 0 : 0.5[urcorner p,lrcorner p] else : point len along q fi) ; + elseif loc = "rt" : anchored.llft(s,if len = 0 : 0.5[urcorner p,lrcorner p] else : point len along q fi) ; + elseif loc = "tr:*" : anchored.llft(s,point 0 of q) ; + elseif loc = "t:*" : anchored.bot (s,point 0 of q) ; + elseif loc = "tl:*" : anchored.lrt (s,point 0 of q) ; + elseif loc = "br:*" : anchored.ulft(s,point 0 of q) ; + elseif loc = "b:*" : anchored.top (s,point 0 of q) ; + elseif loc = "bl:*" : anchored.urt (s,point 0 of q) ; + elseif loc = "lb:*" : anchored.urt (s,point 0 of q) ; + elseif loc = "l:*" : anchored.rt (s,point 0 of q) ; + elseif loc = "lt:*" : anchored.lrt (s,point 0 of q) ; + elseif loc = "rb:*" : anchored.ulft(s,point 0 of q) ; + elseif loc = "r:*" : anchored.lft (s,point 0 of q) ; + elseif loc = "rt:*" : anchored.llft(s,point 0 of q) ; + else : anchored (s,point 0 of q) ; + fi ; + fi ; + endgroup ; +enddef ; + +boolean flow_reverse_connection ; flow_reverse_connection := false ; + +vardef flow_up_on_grid (expr n) = + (xpart flow_xypoints[n],(ypart flow_xypoints[n]+1) div 1) +enddef ; + +vardef flow_down_on_grid (expr n) = + (xpart flow_xypoints[n],(ypart flow_xypoints[n]) div 1) +enddef ; + +vardef flow_left_on_grid (expr n) = + ((xpart flow_xypoints[n]) div 1, ypart flow_xypoints[n]) +enddef ; + +vardef flow_right_on_grid (expr n) = + ((xpart flow_xypoints[n]+1) div 1, ypart flow_xypoints[n]) +enddef ; + +vardef flow_x_on_grid (expr n, xfrom, xto, zfrom) = + if (xfrom = xto) and not (zfrom = 0) : + if (zfrom=1) : flow_right_on_grid(2) else : flow_left_on_grid(2) fi + elseif xpart flow_xypoints[1] < xpart flow_xypoints[6] : + flow_right_on_grid(n) + else : + flow_left_on_grid(n) + fi +enddef ; + +vardef flow_y_on_grid (expr n, yfrom, yto, zfrom) = + if (yfrom = yto) and not (zfrom = 0) : + if (zfrom = 1) : flow_up_on_grid(2) else : flow_down_on_grid(2) fi + elseif ypart flow_xypoints[1] < ypart flow_xypoints[6] : + flow_up_on_grid(n) + else : + flow_down_on_grid(n) + fi +enddef ; + +vardef flow_xy_on_grid (expr n, m) = + (xpart flow_xypoints[n], ypart flow_xypoints[m]) +enddef ; + +vardef flow_down_to_grid (expr a,b) = + (xpart flow_xypoints[a], ypart flow_xypoints[if ypart flow_xypoints[a]ypart flow_xypoints[b] : a else : b fi]) +enddef ; + +vardef flow_left_to_grid (expr a,b) = + (xpart flow_xypoints[if xpart flow_xypoints[a]xpart flow_xypoints[b] : a else : b fi], ypart flow_xypoints[a]) +enddef ; + +vardef flow_valid_connection (expr xfrom, yfrom, xto, yto) = + begingroup ; + save ok, vc, pp ; boolean ok ; pair vc ; path pp ; + save flow_xyfirst, flow_xylast ; pair flow_xyfirst, flow_xylast ; + % check for slanted lines + ok := true ; + for i=1 upto flow_xypoint-1 : + if not ((xpart flow_xypoints[i]=xpart flow_xypoints[i+1]) or (ypart flow_xypoints[i]=ypart flow_xypoints[i+1])) : + ok := false ; + fi ; + endfor ; + if not ok : + % message("slanted"); + false + elseif flow_forcevalid : + % message("force"); + true + elseif (xfrom=xto) and (yfrom=yto) : + % message("self"); + false + else : + % check for crossing shapes + flow_xyfirst := flow_xypoints[1] ; + flow_xylast := flow_xypoints[flow_xypoint] ; + flow_trim_points ; + pp := for i=1 upto flow_xypoint-1 : flow_xypoints[i]-- endfor flow_xypoints[flow_xypoint] ; + flow_xypoints[1] := flow_xyfirst ; + flow_xypoints[flow_xypoint] := flow_xylast ; + for i=1 upto flow_max_x : + for j=1 upto flow_max_y : % was bug: xfrom,yto + if not ( ( (i,j)=(xfrom,yfrom) ) or ( (i,j)=(xto,yto) ) ) : + if not flow_xyfree[i][j] : + vc := pp intersection_point flow_xypath[i][j] ; + if intersection_found : + ok := false + fi ; + fi ; + fi ; + endfor ; + endfor ; + % if not ok: message("crossing") ; fi ; + ok + fi + endgroup +enddef ; + +def flow_connect_top_bottom (expr n) (expr xfrom, yyfrom, zfrom) (expr xto, yyto, zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,6) : + flow_xypoints[1] := flow_xy_top(xfrom,yfrom,zfrom,true) ; + flow_xypoints[6] := flow_xy_bottom(xto,yto,zto,true) ; + flow_xypoints[2] := flow_up_on_grid(1) ; + flow_xypoints[5] := flow_down_on_grid(6) ; + flow_xypoints[3] := flow_up_to_grid(2,5) ; + flow_xypoints[4] := flow_up_to_grid(2,5) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_x_on_grid(2,xfrom,xto,zfrom) ; + flow_xypoints[4] := flow_xy_on_grid(3,5) ; + fi ; + %%%% begin experiment + flow_xypoints[3] := flow_xypoints[3] shifted (flow_dsp_x,0) ; + flow_xypoints[4] := flow_xypoints[4] shifted (flow_dsp_x,0) ; + if flow_dsp_y>0 : + flow_xypoints[2] := flow_xypoints[2] shifted (0,flow_dsp_y) ; + flow_xypoints[3] := flow_xypoints[3] shifted (0,flow_dsp_y) ; + elseif flow_dsp_y<0 : + flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; + flow_xypoints[5] := flow_xypoints[5] shifted (0,flow_dsp_y) ; + fi + %%%% end experiment + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_left_right (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,6) : + flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; + flow_xypoints[6] := flow_xy_right(xto,yto,zto,true) ; + flow_xypoints[2] := flow_left_on_grid(1) ; + flow_xypoints[5] := flow_right_on_grid(6) ; + flow_xypoints[3] := flow_left_to_grid(2,5) ; + flow_xypoints[4] := flow_left_to_grid(2,5) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_y_on_grid(2,yfrom,yto,zfrom) ; + flow_xypoints[4] := flow_xy_on_grid(5,3) ; + fi ; + %%%% begin experiment + if flow_dsp_y <> 0 : + flow_xypoints[3] := flow_xypoints[3] shifted (0,-flow_dsp_y) ; + flow_xypoints[4] := flow_xypoints[4] shifted (0,-flow_dsp_y) ; + fi ; + %%%% end experiment + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_left_top (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,5) : + flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; + flow_xypoints[5] := flow_xy_top(xto,yto,zto,true) ; + flow_xypoints[2] := flow_left_on_grid(1) ; + flow_xypoints[4] := flow_up_on_grid(5) ; + flow_xypoints[3] := flow_left_to_grid(2,5) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_xy_on_grid(2,4) ; + fi ; + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_left_bottom (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,5) : + flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; + flow_xypoints[5] := flow_xy_bottom(xto,yto,zto,true) ; + flow_xypoints[2] := flow_left_on_grid(1) ; + flow_xypoints[4] := flow_down_on_grid(5) ; + flow_xypoints[3] := flow_left_to_grid(2,5) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_xy_on_grid(2,4) ; + fi ; + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_right_top (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,5) : + flow_xypoints[1] := flow_xy_right(xfrom,yfrom,zfrom,true) ; + flow_xypoints[5] := flow_xy_top(xto,yto,zto,true) ; + flow_xypoints[2] := flow_right_on_grid(1) ; + flow_xypoints[4] := flow_up_on_grid(5) ; + flow_xypoints[3] := flow_right_to_grid(2,5) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_xy_on_grid(2,4) ; + fi ; + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_right_bottom (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,5) : + flow_xypoints[1] := flow_xy_right(xfrom,yfrom,zfrom,true) ; + flow_xypoints[5] := flow_xy_bottom(xto,yto,zto,true) ; + flow_xypoints[2] := flow_right_on_grid(1) ; + flow_xypoints[4] := flow_down_on_grid(5) ; + flow_xypoints[3] := flow_right_to_grid(2,5) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_xy_on_grid(2,4) ; + fi ; + %%%% begin experiment + flow_xypoints[2] := flow_xypoints[2] shifted (flow_dsp_x,0) ; + flow_xypoints[3] := flow_xypoints[3] shifted (flow_dsp_x,0) ; + if flow_dsp_y>0 : + flow_xypoints[3] := flow_xypoints[3] shifted (0,-flow_dsp_y) ; + flow_xypoints[4] := flow_xypoints[4] shifted (0,-flow_dsp_y) ; + elseif flow_dsp_y<0 : + flow_xypoints[3] := flow_xypoints[3] shifted (0,flow_dsp_y) ; + flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; + fi + %%%% end experiment + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_left_left (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,6) : + flow_xypoints[1] := flow_xy_left(xfrom,yfrom,zfrom,true) ; + flow_xypoints[6] := flow_xy_left(xto,yto,zto,true) ; + flow_xypoints[2] := flow_left_on_grid(1) ; + flow_xypoints[5] := flow_left_on_grid(6) ; + flow_xypoints[3] := flow_left_to_grid(2,5) ; + flow_xypoints[4] := flow_left_to_grid(5,2) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_y_on_grid(2,yfrom,yto,zfrom) ; + flow_xypoints[4] := flow_xy_on_grid(5,3) ; + fi ; + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_right_right (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,6) : + flow_xypoints[1] := flow_xy_right(xfrom,yfrom,zfrom,true) ; + flow_xypoints[6] := flow_xy_right(xto,yto,zto,true) ; + flow_xypoints[2] := flow_right_on_grid(1) ; + flow_xypoints[5] := flow_right_on_grid(6) ; + flow_xypoints[3] := flow_right_to_grid(2,5) ; + flow_xypoints[4] := flow_right_to_grid(5,2) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_y_on_grid(2,yfrom,yto,zfrom) ; + flow_xypoints[4] := flow_xy_on_grid(5,3) ; + fi ; + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_top_top (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,6) : + flow_xypoints[1] := flow_xy_top(xfrom,yfrom,zfrom,true) ; + flow_xypoints[6] := flow_xy_top(xto,yto,zto,true) ; + flow_xypoints[2] := flow_up_on_grid(1) ; + flow_xypoints[5] := flow_up_on_grid(6) ; + flow_xypoints[3] := flow_up_to_grid(2,5) ; + flow_xypoints[4] := flow_up_to_grid(5,2) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_x_on_grid(2,xfrom,xto,zfrom) ; + flow_xypoints[4] := flow_xy_on_grid(3,5) ; + fi ; + %%%% begin experiment (todo: not value but just + and ) + if flow_dsp_y <> 0 : + flow_xypoints[2] := flow_xypoints[2] shifted (0,flow_dsp_y) ; + flow_xypoints[3] := flow_xypoints[3] shifted (0,flow_dsp_y) ; + flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; + flow_xypoints[5] := flow_xypoints[5] shifted (0,flow_dsp_y) ; + fi ; + %%%% end experiment + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_bottom_bottom (expr n) (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := flow_y_pos(yyfrom) ; + yto := flow_y_pos(yyto) ; + if flow_points_initialized(xfrom,yfrom,xto,yto,6) : + flow_xypoints[1] := flow_xy_bottom(xfrom,yfrom,zfrom,true) ; + flow_xypoints[6] := flow_xy_bottom(xto,yto,zto,true) ; + flow_xypoints[2] := flow_down_on_grid(1) ; + flow_xypoints[5] := flow_down_on_grid(6) ; + flow_xypoints[3] := flow_down_to_grid(2,5) ; + flow_xypoints[4] := flow_down_to_grid(5,2) ; + if not flow_valid_connection(xfrom,yfrom,xto,yto) : + flow_xypoints[3] := flow_x_on_grid(2,xfrom,xto,zfrom) ; + flow_xypoints[4] := flow_xy_on_grid(3,5) ; + fi ; + %%%% begin experiment + flow_xypoints[3] := flow_xypoints[3] shifted (flow_dsp_x,0) ; + flow_xypoints[4] := flow_xypoints[4] shifted (flow_dsp_x,0) ; + if flow_dsp_y<0 : + flow_xypoints[2] := flow_xypoints[2] shifted (0,-flow_dsp_y) ; + flow_xypoints[3] := flow_xypoints[3] shifted (0,-flow_dsp_y) ; + elseif flow_dsp_y>0 : + flow_xypoints[4] := flow_xypoints[4] shifted (0,flow_dsp_y) ; + flow_xypoints[5] := flow_xypoints[5] shifted (0,flow_dsp_y) ; + fi + %%%% end experiment + flow_draw_connection(n,xfrom,yyfrom,xto,yyto) ; + fi ; +enddef ; + +def flow_connect_bottom_top (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + flow_reverse_connection := true ; + flow_connect_top_bottom (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def flow_connect_right_left (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + flow_reverse_connection := true ; + flow_connect_left_right (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def flow_connect_top_left (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + flow_reverse_connection := true ; + flow_connect_left_top (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def flow_connect_bottom_left (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + flow_reverse_connection := true ; + flow_connect_left_bottom (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def flow_connect_top_right (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + flow_reverse_connection := true ; + flow_connect_right_top (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def flow_connect_bottom_right (expr n) (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + flow_reverse_connection := true ; + flow_connect_right_bottom (n) (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def flow_draw_test_shape(expr x, y) = + flow_draw_shape(x,y,fullcircle, .7, .7) ; +enddef ; + +def flow_draw_test_shapes = + for i=1 upto flow_max_x : + for j=1 upto flow_max_y : + flow_draw_test_shape(i,j) ; + endfor ; + endfor ; +enddef; + +def flow_draw_test_area = + pickup pencircle scaled .5flow_shape_line_width ; + draw (unitsquare xscaled flow_max_x yscaled flow_max_y shifted (1,1)) flow_scaled_to_grid withcolor blue ; +enddef ; + +def flow_show_connection(expr n, m) = + + flow_begin_chart(100+n,6,6) ; + + flow_draw_test_area ; + + flow_smooth := true ; + flow_arrowtip := true ; + flow_dashline := true ; + + flow_draw_test_shape(2,2) ; flow_draw_test_shape(4,5) ; + flow_draw_test_shape(3,3) ; flow_draw_test_shape(5,1) ; + flow_draw_test_shape(2,5) ; flow_draw_test_shape(1,3) ; + flow_draw_test_shape(6,2) ; flow_draw_test_shape(4,6) ; + + if (m=1) : + flow_connect_top_bottom (0) (2,2,0) (4,5,0) ; + flow_connect_top_bottom (0) (3,3,0) (5,1,0) ; + flow_connect_top_bottom (0) (2,5,0) (1,3,0) ; + flow_connect_top_bottom (0) (6,2,0) (4,6,0) ; + elseif (m=2) : + flow_connect_top_top (0) (2,2,0) (4,5,0) ; + flow_connect_top_top (0) (3,3,0) (5,1,0) ; + flow_connect_top_top (0) (2,5,0) (1,3,0) ; + flow_connect_top_top (0) (6,2,0) (4,6,0) ; + elseif (m=3) : + flow_connect_bottom_bottom (0) (2,2,0) (4,5,0) ; + flow_connect_bottom_bottom (0) (3,3,0) (5,1,0) ; + flow_connect_bottom_bottom (0) (2,5,0) (1,3,0) ; + flow_connect_bottom_bottom (0) (6,2,0) (4,6,0) ; + elseif (m=4) : + flow_connect_left_right (0) (2,2,0) (4,5,0) ; + flow_connect_left_right (0) (3,3,0) (5,1,0) ; + flow_connect_left_right (0) (2,5,0) (1,3,0) ; + flow_connect_left_right (0) (6,2,0) (4,6,0) ; + elseif (m=5) : + flow_connect_left_left (0) (2,2,0) (4,5,0) ; + flow_connect_left_left (0) (3,3,0) (5,1,0) ; + flow_connect_left_left (0) (2,5,0) (1,3,0) ; + flow_connect_left_left (0) (6,2,0) (4,6,0) ; + elseif (m=6) : + flow_connect_right_right (0) (2,2,0) (4,5,0) ; + flow_connect_right_right (0) (3,3,0) (5,1,0) ; + flow_connect_right_right (0) (2,5,0) (1,3,0) ; + flow_connect_right_right (0) (6,2,0) (4,6,0) ; + elseif (m=7) : + flow_connect_left_top (0) (2,2,0) (4,5,0) ; + flow_connect_left_top (0) (3,3,0) (5,1,0) ; + flow_connect_left_top (0) (2,5,0) (1,3,0) ; + flow_connect_left_top (0) (6,2,0) (4,6,0) ; + elseif (m=8) : + flow_connect_left_bottom (0) (2,2,0) (4,5,0) ; + flow_connect_left_bottom (0) (3,3,0) (5,1,0) ; + flow_connect_left_bottom (0) (2,5,0) (1,3,0) ; + flow_connect_left_bottom (0) (6,2,0) (4,6,0) ; + elseif (m=9) : + flow_connect_right_top (0) (2,2,0) (4,5,0) ; + flow_connect_right_top (0) (3,3,0) (5,1,0) ; + flow_connect_right_top (0) (2,5,0) (1,3,0) ; + flow_connect_right_top (0) (6,2,0) (4,6,0) ; + else : + flow_connect_right_bottom (0) (2,2,0) (4,5,0) ; + flow_connect_right_bottom (0) (3,3,0) (5,1,0) ; + flow_connect_right_bottom (0) (2,5,0) (1,3,0) ; + flow_connect_right_bottom (0) (6,2,0) (4,6,0) ; + fi ; + + flow_end_chart ; + +enddef ; + +def flow_show_connections = + for f=1 upto 10 : + flow_show_connection(f,f) ; + endfor ; +enddef ; + +%D charts + +def flow_clip_chart(expr minx, miny, maxx, maxy) = + flow_cmin_x := minx ; + flow_cmax_x := maxx ; + flow_cmin_y := miny ; + flow_cmax_y := maxy ; +enddef ; + +def flow_begin_chart(expr n, maxx, maxy) = + flow_new_chart ; + flow_chart_figure := n ; + flow_chart_scale := 1 ; + if flow_chart_figure>0: + beginfig(flow_chart_figure) ; + fi ; + flow_initialize_grid (maxx, maxy) ; + bboxmargin := 0 ; + flow_cmin_x := 1 ; + flow_cmax_x := maxx ; + flow_cmin_y := 1 ; + flow_cmax_y := maxy ; +enddef ; + +def flow_end_chart = + begingroup ; + save p ; path p ; + flow_flush_shapes ; + flow_flush_connections ; + flow_flush_pictures ; + flow_cmin_x := flow_cmin_x ; + flow_cmax_x := flow_cmin_x+flow_cmax_x ; + flow_cmin_y := flow_cmin_y-1 ; + flow_cmax_y := flow_cmin_y+flow_cmax_y ; + if flow_reverse_y : + flow_cmin_y := flow_y_pos(flow_cmin_y) ; + flow_cmax_y := flow_y_pos(flow_cmax_y) ; + fi ; + p := (((flow_cmin_x,flow_cmin_y)--(flow_cmax_x,flow_cmin_y)-- + (flow_cmax_x,flow_cmax_y)--(flow_cmin_x,flow_cmax_y)--cycle)) + flow_scaled_to_grid ; + %draw p withcolor red ; + p := p enlarged flow_chart_offset ; + clip currentpicture to p ; + setbounds currentpicture to p ; + endgroup ; + currentpicture := currentpicture scaled flow_chart_scale ; + if flow_chart_figure>0: + endfig ; + fi ; +enddef ; + +def flow_new_shape(expr x, y, n) = + if known n : + if (x>0) and (x<=flow_max_x) and (y>0) and (y<=flow_max_y) : + flow_draw_shape(x,y,some_shape_path(n), flow_shape_width/flow_grid_width, flow_shape_height/flow_grid_height) ; + else : + message ("shape outside grid ignored") ; + fi ; + else : + message ("shape not known" ) ; + fi ; +enddef ; + +def flow_begin_sub_chart = + begingroup ; + save flow_shape_line_width, flow_connection_line_width ; + save flow_shape_line_color, flow_shape_fill_color, flow_connection_line_color ; + color flow_shape_line_color, flow_shape_fill_color, flow_connection_line_color ; + save flow_smooth, flow_arrowtip, flow_dashline, flow_peepshape ; + boolean flow_smooth, flow_arrowtip, flow_dashline, flow_peepshape ; +enddef ; + +def flow_end_sub_chart = + endgroup ; +enddef ; + diff --git a/metapost/context/base/mpiv/mp-chem.mpiv b/metapost/context/base/mpiv/mp-chem.mpiv new file mode 100644 index 000000000..b861d3f12 --- /dev/null +++ b/metapost/context/base/mpiv/mp-chem.mpiv @@ -0,0 +1,1731 @@ +%D \module +%D [ file=mp-chem.mpiv, +%D version=2009.05.13, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=chemicals, +%D author=Hans Hagen \& Alan Braslau, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D This module is incomplete and experimental. Okay, it's not that bad but we do need +%D some disclaimer. + +% either consistent setting or not + +if known context_chem : endinput ; fi ; + +boolean context_chem ; context_chem := true ; + +numeric + chem_num[], % scratch + 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_center_offset, chem_dbl_offset, + chem_bb_angle, chem_axis_rulethickness, + chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b, + chem_setting_rotation, chem_emwidth, chem_b_length, + chem_front_b[] ; + +boolean + chem_setting_axis, + chem_doing_pb, chem_bd_wedge, + chem_star[], chem_front[], chem_stacked[], chem_tetra[] ; + +string + chem_previous ; + +path + chem_path[], % scratch + chem_b_path[], chem_c_path[], + chem_r_path[], chem_r_path.lft[], chem_r_path.rt[] ; + +pair + chem_origin, chem_mirror, + chem_pair[], % scratch + chem_sb_pair, chem_sb_pair.m, chem_sb_pair.p, chem_sb_pair.b ; + +picture + chem_pic, % scratch + % The use of dashpattern is found to dot the starting point with chem_sb_dash.m... + %chem_sb_dash, chem_sb_dash.m, chem_sb_dash.p, chem_sb_dash.b, + chem_axis_color ; + +transform + chem_t ; % scratch + +color lightblue ; lightblue := (173/255,216/255,230/255) ; + +% debugging + +boolean chem_trace_nesting ; chem_trace_nesting := false ; +boolean chem_trace_text ; chem_trace_text := false ; +boolean chem_trace_boundingbox ; chem_trace_boundingbox := false ; + +chem_axis_color := image(draw origin withcolor lightblue) ; +chem_setting_axis := false ; +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 := .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 := 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_bd_wedge := true ; % according to IUPAC 2005 + +def chem_reset = + chem_rotation := 0 ; + chem_mirror := origin ; + chem_adjacent := 0 ; + chem_substituent := 0 ; + chem_substituent.lft := 0 ; + chem_substituent.rt := 0 ; + chem_stack_n := 0 ; + chem_doing_pb := false ; + chem_origin := origin ; + chem_previous := "one" ; + pair chem_mark_pair[] ; +enddef ; + +chem_reset ; + +newinternal numeric + one, carbon, alkyl, newmanstagger, newmaneclipsed, + three, four, five, six, seven, eight, nine, + fivefront, sixfront, chair, boat ; + +vardef chem_init_some (suffix $) (expr e) = + if not known chem_star[$] : chem_star[$] := false ; fi + if not known chem_front[$] : chem_front[$] := false ; fi + if not known chem_stacked[$] : chem_stacked[$] := false ; fi + if not known chem_tetra[$] : chem_tetra[$] := false ; fi + + % We define all paths as closed, so that they may be indexed mod length. + if path(e) : + chem_b_path[$] := e if not cycle(e) : -- cycle fi ; + chem_num0 := length(chem_b_path[$]) ; + else : % polygon + chem_num0 := e ; + chem_num1 := 360/chem_num0 ; + chem_b_path[$] := + ( + for i=0 upto chem_num0-1 : + dir(if chem_star[$] : -i else : (.5-i) fi *chem_num1) -- + endfor + cycle + ) + if chem_front[$] : + rotated (chem_num1-90) + fi + if not chem_star[$] : + scaled (.5/(sind .5chem_num1)) + % carbon-carbon benzene bond length + scaled (1.4/1.54) + fi ; + fi ; + + if chem_front[$] and (not known chem_front_b[$]) : + chem_front_b[$] := floor(.5(length chem_b_path[$])) + 1 ; + fi + + chem_num2 := 0 ; + chem_c_path[$] := + reverse(fullcircle) rotated angle(point 0 of chem_b_path[$]) + if not chem_star[$] : + hide (for i=0 upto chem_num0-1: + if abs(point i+.5 of chem_b_path[$]) < + abs(point chem_num2+.5 of chem_b_path[$]) : + chem_num2 := i ; + fi + endfor) + scaled (2*(abs(point chem_num2+.5 of chem_b_path[$]) - 2chem_dbl_offset)) + fi ; + + chem_r_path[$] := + if chem_star[$] : + chem_b_path[$] + else : + ( + for i=0 upto chem_num0-1 : + (unitvector point i of chem_b_path[$]) + shifted point i of chem_b_path[$] -- + endfor + cycle + ) + fi ; + + chem_r_path.lft[$] := + ( + for i=0 upto chem_num0-1 : + if chem_front[$] : + up + scaled .5 + shifted point i of chem_b_path[$] + elseif chem_star[$] : + point i of chem_b_path[$] + else : + point i+1 of chem_b_path[$] + rotatedabout(point i of chem_b_path[$],180) + fi -- + endfor + cycle + ) ; + chem_r_path.rt[$] := + ( + for i=0 upto chem_num0-1 : + if chem_front[$] : + down + scaled .5 + shifted point i of chem_b_path[$] + elseif chem_star[$] : + point i+2 of chem_b_path[$] + else : + point i-1 of chem_b_path[$] + rotatedabout(point i of chem_b_path[$],180) + fi -- + endfor + cycle + ) ; + +enddef ; + +% The following is used only once: +def chem_init_all = +begingroup + save a, b, c, d, e ; numeric a, b, c, d, e ; + save lft, rt ; path lft, rt ; + + % tetrahedrial angle + a := 2angle(1,sqrt 2) ; + + % solve for chair + 2b = 180 - .5a ; + 4c = 180 - .5a ; + d + e = 360 - 2a ; + d = 5e ; % this is the one tunable parameter which fixes the perspective. + z2 = z1 shifted dir(90+a+d) ; + z3 = z2 shifted dir(270-a) ; + z4 = z3 shifted dir(90+a) ; + z6 = z1 shifted dir(90+a) ; + z5 = z6 shifted dir(270-a) ; + z4 = z1 xyscaled (-1,-1) ; + z5 = z2 xyscaled (-1,-1) ; + + save indx ; numeric indx ; indx = 2 ; % starting value doesn't matter, really. + % polygons + three := incr indx ; % 3 (these numbers don't matter - they are just indices) + four := incr indx ; % 4 + five := incr indx ; % 5 + six := incr indx ; % 6 + seven := incr indx ; % 7 + eight := incr indx ; % 8 + nine := incr indx ; % 9 + + chem_init_some(three,3) ; + chem_init_some(four, 4) ; + chem_init_some(five, 5) ; + chem_init_some(six, 6) ; + chem_init_some(seven,7) ; + chem_init_some(eight,8) ; + chem_init_some(nine, 9) ; + + % star-form + one := incr indx ; % 10 + carbon := incr indx ; % 11 + alkyl := incr indx ; % 12 + newmanstagger := incr indx ; % 13 + newmaneclipsed := incr indx ; % 14 + + chem_star[one] := true ; + chem_star[carbon] := true ; chem_tetra[carbon] := true ; + chem_star[alkyl] := true ; chem_tetra[alkyl] := true ; + chem_star[newmanstagger] := true ; chem_tetra[newmanstagger] := true ; + chem_star[newmaneclipsed] := true ; chem_tetra[newmaneclipsed] := true ; + chem_stacked[newmanstagger] := true ; + chem_stacked[newmaneclipsed] := true ; + chem_init_some(one, 8) ; + chem_init_some(carbon, dir(0)--dir(360-a)--dir(180-.5a+b)--dir(180-.5a)) ; + chem_init_some(alkyl, dir(0)--dir(360-a)--dir(360-a-90)--dir(90)) ; + chem_init_some(newmanstagger, dir(30)--dir(270)--dir(150)--dir(330)--dir(210)--dir(90)) ; + chem_init_some(newmaneclipsed, dir(30)--dir(270)--dir(150)--dir(0)--dir(240)--dir(120)) ; + + % front views + fivefront := incr indx ; % 15 + sixfront := incr indx ; % 16 + chair := incr indx ; % 17 + boat := incr indx ; % 18 + + chem_front[fivefront] := true ; chem_front_b[fivefront] := 3 ; + chem_front[sixfront] := true ; chem_front_b[sixfront] := 3 ; + chem_init_some(fivefront,5) ; + chem_init_some(sixfront, 6) ; + % chair + chem_front[chair] := true ; chem_front_b[chair] := 4 ; + chem_init_some(chair, z1--z2--z3--z4--z5--z6) ; + lft := dir(90-a)--down--dir(90+a+d)--down--dir(90+a)--down ; + rt := up--dir(270+a)--up--dir(270-a)--up--dir(90+e) ; + chem_r_path.lft[chair] := + for i=0 upto 5 : point i of lft shifted point i of chem_b_path[chair] -- endfor + cycle ; + chem_r_path.rt[chair] := + for i=0 upto 5 : point i of rt shifted point i of chem_b_path[chair] -- endfor + cycle ; + % boat + chem_front[boat] := true ; chem_front_b[boat] := 4 ; + chem_init_some(boat, + for i=1 upto 4 : point i-1 of chem_b_path[sixfront] -- endfor + point 2 of chem_b_path[sixfront] yscaled .5 -- + point 1 of chem_b_path[sixfront] yscaled .5 + ) ; + lft := dir(30+.5a)--dir(330+.5a)--dir(210-.5a)--dir(150-.5a)--dir(120)--dir(60) ; + rt := dir(30-.5a)--dir(330-.5a)--dir(210+.5a)--dir(150+.5a)--dir(120+a)--dir(60-a) ; + chem_r_path.lft[boat] := + for i=0 upto 5 : point i of lft shifted point i of chem_b_path[boat] -- endfor + cycle ; + chem_r_path.rt[boat] := + for i=0 upto 5 : point i of rt shifted point i of chem_b_path[boat] -- endfor + cycle ; +endgroup +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, bond, scale, offset, axis, rulethickness, axiscolor) = + save chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b ; + + 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 + if numeric r : + chem_setting_r := r ; + fi + if numeric t : + chem_setting_t := t ; + fi + if numeric b : + chem_setting_b := -b ; + fi + chem_setting_rotation := rotation ; + chem_setting_offset := offset ; + chem_setting_axis := if boolean axis : axis else : (axis<>0) fi ; + chem_axis_rulethickness := .75*(rulethickness) ; % axis 50% thinner than frame and bonds. + chem_axis_color := image(draw origin withcolor axiscolor) ; % so we handle all color models + + chem_reset ; +enddef ; + +% \stopchemical + +vardef chem_stop_structure = + % Make sure that all of the saved stack has been restored... (this was a gotcha!) + forever : + exitif chem_stack_n=0 ; + chem_restore ; + endfor + + currentpicture := (currentpicture shifted -chem_origin) rotated chem_setting_rotation ; + + save l, r, b, t ; + l := min(xpart llcorner currentpicture, xpart lrcorner currentpicture) ; + r := max(xpart llcorner currentpicture, xpart lrcorner currentpicture) ; + b := min(ypart llcorner currentpicture, ypart ulcorner currentpicture) ; + t := max(ypart llcorner currentpicture, ypart ulcorner currentpicture) ; + + if unknown chem_setting_l : chem_setting_l := l ; fi + if unknown chem_setting_r : chem_setting_r := r ; fi + if unknown chem_setting_b : chem_setting_b := b ; fi + if unknown chem_setting_t : chem_setting_t := t ; fi + + if chem_setting_axis : % put it behind the picture + chem_pic := currentpicture ; currentpicture := nullpicture ; + chem_num0 := .5chem_b_length ; + chem_num1 := .2chem_num0 ; + % draw the axes to the bounding box of the entire structure, + % not necessarily the bounding box of the final figure + draw (l,0) -- (r,0) + withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; + draw (0,b) -- (0,t) + withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; + for i = 0 step chem_num0 until r : + draw (i,-chem_num1) -- (i,chem_num1) + withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; + endfor + for i = 0 step -chem_num0 until l : + draw (i,-chem_num1) -- (i,chem_num1) + withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; + endfor + for i = 0 step chem_num0 until t : + draw (-chem_num1,i) -- (chem_num1,i) + withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; + endfor + for i = 0 step -chem_num0 until b : + draw (-chem_num1,i) -- (chem_num1,i) + withpen pencircle scaled chem_axis_rulethickness withcolor colorpart(chem_axis_color) ; + endfor + addto currentpicture also chem_pic ; + fi ; + if chem_trace_boundingbox : + fill boundingbox currentpicture withcolor blue withtransparency(1,.25) ; + fi ; + setbounds currentpicture to + ((chem_setting_l,chem_setting_b) -- (chem_setting_r,chem_setting_b) -- + (chem_setting_r,chem_setting_t) -- (chem_setting_l,chem_setting_t) -- cycle) ; + if chem_trace_boundingbox : + fill boundingbox currentpicture withcolor red withtransparency(1,.25) ; + fi ; +enddef ; + +% \chemical + +vardef chem_start_component = enddef ; +vardef chem_stop_component = enddef ; + +vardef chem_pb = % PB : + if chem_trace_nesting : + draw boundingbox currentpicture + withpen pencircle scaled 1mm withcolor colorpart(chem_axis_color) ; + draw origin withpen pencircle scaled 2mm withcolor colorpart(chem_axis_color) ; + fi ; + chem_doing_pb := true ; +enddef ; + +vardef chem_pe = % PE + if chem_trace_nesting : + draw boundingbox currentpicture withpen pencircle scaled .5mm withcolor red ; + draw origin withpen pencircle scaled 1mm withcolor red ; + fi ; + currentpicture := currentpicture shifted -chem_origin ; + if chem_trace_nesting : + draw origin withpen pencircle scaled .5mm withcolor green ; + fi ; + chem_origin := origin ; + chem_doing_pb := false ; +enddef ; + +vardef chem_do (expr pos) = + if (unknown chem_doing_pb) or (not chem_doing_pb) : + pos + else : + chem_doing_pb := false ; + currentpicture := currentpicture shifted -pos ; + chem_origin := chem_origin shifted -pos ; + origin % nullpicture + fi +enddef ; + + +picture chem_stack_p[] ; +pair chem_stack_origin[], chem_stack_mirror[] ; +numeric chem_stack_rotation[] ; +string chem_stack_previous[] ; + +vardef chem_save = % SAVE + chem_stack_p [incr chem_stack_n] := currentpicture ; + chem_stack_origin [ chem_stack_n] := chem_origin ; chem_origin := origin ; + chem_stack_rotation[ chem_stack_n] := chem_rotation ; + chem_stack_mirror [ chem_stack_n] := chem_mirror ; + chem_stack_previous[ chem_stack_n] := chem_previous ; + currentpicture := nullpicture ; +enddef ; + +vardef chem_restore = % RESTORE + if chem_stack_n>0 : + currentpicture := currentpicture shifted -chem_origin ; + addto chem_stack_p [chem_stack_n] also currentpicture ; + currentpicture := chem_stack_p [chem_stack_n] ; + chem_stack_p[chem_stack_n] := nullpicture ; + chem_origin := chem_stack_origin [chem_stack_n] ; + chem_rotation := chem_stack_rotation[chem_stack_n] ; + chem_mirror := chem_stack_mirror [chem_stack_n] ; + chem_previous := chem_stack_previous[chem_stack_n] ; + chem_stack_n := chem_stack_n - 1 ; + fi ; +enddef ; + +% chem_adj and chem_sub are to be followed by chem_set(n) which does all the work... + +vardef chem_adj (suffix $) (expr d, s) = % ADJ + % scale s is ignored (for now?) + if not chem_front[$] : + chem_substituent := 0 ; + chem_substituent.lft := 0 ; + chem_substituent.rt := 0 ; + chem_adjacent := d ; + fi +enddef ; + +vardef chem_lsub (suffix $) (expr d, s) = % LSUB + chem_sub.lft($,d,s) ; +enddef ; + +vardef chem_rsub (suffix $) (expr d, s) = % RSUB + chem_sub.rt ($,d,s) ; +enddef ; + +vardef chem_sub@# (suffix $) (expr d, s) = % SUB + % scale s is ignored (for now?) + chem_adjacent := 0 ; + chem_substituent := 0 ; + chem_substituent.lft := 0 ; + chem_substituent.rt := 0 ; + % then : + chem_substituent@# := d ; +enddef ; + +def chem_transformed (suffix $) = % not vardef! + scaled chem_b_length + if not chem_front[$] : + if chem_mirror<>origin : reflectedabout(origin,chem_mirror) fi + rotated chem_rotation + fi +enddef ; + +vardef chem_draw (expr what, r, c) (text extra) = + draw what + withpen pencircle scaled r + withcolor c %\MPcolor{c} + extra ; +enddef ; + +vardef chem_fill (expr what, r, c) (text extra) = + fill what + withpen pencircle scaled r + withcolor c %\MPcolor{c} + extra ; +enddef ; + +vardef chem_drawarrow (expr what, r, c) (text extra) = + drawarrow what + withpen pencircle scaled r + withcolor c %\MPcolor{c} + extra ; +enddef ; + +vardef chem_set (suffix $) = + forsuffixes P = scantokens chem_previous : + + % 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 ; + elseif (chem_adjacent<>0) and (chem_front[P] or chem_front[$]) : + % not allowed for FRONT + chem_adjacent := 0 ; + elseif chem_adjacent<>0 : + chem_substituent := 0 ; + chem_substituent.lft := 0 ; + chem_substituent.rt := 0 ; + % move to the bond midpoint of the first structure + chem_pair0 := center ( + if chem_star[P] : + origin -- point (chem_adjacent-1) + else : + subpath (chem_adjacent-1,chem_adjacent) + fi + of chem_b_path[P] + ) chem_transformed(P) ; + % find the closest opposite bond of the second structure + chem_pair1 := chem_pair0 rotated if chem_star[P] : 90 else : 180 fi ; + chem_num0 := abs(chem_pair1) ; + chem_num1 := if chem_tetra[$] : 1 else : length chem_b_path[$] fi ; + % only consider even indices (cardinal points) for ONE + chem_num2 := if chem_star[$] and not chem_tetra[$] : 2 else : 1 fi ; + for i=0 step chem_num2 until chem_num1 : + chem_pair2 := ( + ( + unitvector + center ( + if chem_star[$] : + origin -- point i + else : + subpath (i,i+1) + fi + of chem_b_path[$]) + ) + scaled chem_num0 + ) chem_transformed($) ; + if i=0 : + chem_pair3 := chem_pair2 ; + chem_num3 := 0 ; + elseif (abs(chem_pair1 shifted -chem_pair2)) < (abs(chem_pair1 shifted -chem_pair3)) : + chem_pair3 := chem_pair2 ; + chem_num3 := i ; + fi + endfor + if chem_star[$] : + chem_pair4 := chem_pair0 shifted + -((point (chem_adjacent-1) of chem_b_path[P]) chem_transformed(P)) ; + fi + % adjust the bond angles + 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] : + (point chem_num3 + else : + center(subpath (chem_num3,chem_num3+1) + fi + of chem_b_path[$]) + chem_transformed($) ; + fi + if not chem_star[P] : + chem_pair4 := chem_pair4 shifted -chem_pair0 ; + fi + currentpicture := currentpicture shifted chem_pair4 ; + chem_origin := chem_origin shifted chem_pair4 ; + chem_adjacent := 0 ; + fi ; + + % Insure that only one, if any, will be nonzero + if ((chem_substituent <> 0) and (chem_substituent.lft <> 0)) or + ((chem_substituent <> 0) and (chem_substituent.rt <> 0)) or + ((chem_substituent.lft <> 0) and (chem_substituent.rt <> 0)) : + chem_substituent := 0 ; + chem_substituent.lft := 0 ; + chem_substituent.rt := 0 ; + fi + if (chem_substituent <> 0) or (chem_substituent.lft <> 0) or (chem_substituent.rt <> 0) : + % move origin to radical endpoint of the first structure + if chem_substituent.lft > 0 : + chem_pair0 := point chem_substituent.lft-1 of chem_r_path.lft[P] ; + chem_substituent := chem_substituent.lft ; + chem_substituent.lft := 0 ; + elseif chem_substituent.rt > 0 : + chem_pair0 := point chem_substituent.rt-1 of chem_r_path.rt[P] ; + chem_substituent := chem_substituent.rt ; + chem_substituent.rt := 0 ; + else : + chem_pair0 := point chem_substituent-1 of chem_r_path[P] ; + fi + chem_pair1 := chem_pair0 if not chem_star[P] : + shifted -(point chem_substituent-1 of chem_b_path[P]) fi ; + chem_t := identity chem_transformed(P) ; + chem_pair0 := chem_pair0 transformed chem_t ; % radical + chem_pair1 := chem_pair1 transformed chem_t ; % recentered (see below) + currentpicture := currentpicture shifted -chem_pair0 ; + chem_origin := chem_origin shifted -chem_pair0 ; + if (not (chem_star[P] and chem_star[$])) or chem_tetra[P] or chem_tetra[$] : + if chem_tetra[P] and chem_tetra[$] and ((chem_substituent=1) or (chem_substituent=2)): + chem_rotation := (chem_rotation + 180) mod 360 ; % trans-alkane + chem_pair2 := (point .5 of chem_b_path[$]) ; % bisector, not chem_transformed + if chem_mirror=origin : + chem_mirror := chem_pair2 ; + else : + chem_num0 := angle(chem_mirror)-angle(chem_pair2) ; + if (chem_num0>0) and (chem_num0> 180) : + chem_num0 := 360 - chem_num0 ; + elseif (chem_num0<0) and (chem_num0<-180) : + chem_num0 := -360 - chem_num0 ; + fi + chem_rotation := (chem_rotation + 2chem_num0) mod 360 ; + chem_mirror := origin ; + fi + fi + chem_t := identity chem_transformed($) ; + chem_pair1 := chem_pair1 rotated 180 ; % opposite direction of radical bond + % find the closest node + chem_num0 := abs(chem_pair1) ; % distance + % search to find the nearest node of $; only consider 1 and 2 for CARBON,ALKYL + chem_num1 := if chem_tetra[$] : 1 else : length chem_b_path[$] fi ; + % only consider even indices (cardinal points) for ONE + chem_num2 := if chem_star[$] and not chem_tetra[$] : 2 else : 1 fi ; + for i=0 step chem_num2 until chem_num1 : + chem_pair2 := (unitvector(point i of chem_b_path[$]) scaled chem_num0) + transformed chem_t ; + if i=0 : + chem_pair3 := chem_pair2 ; + chem_num3 := 0 ; + elseif (abs(chem_pair1 shifted -chem_pair2)) < + (abs(chem_pair1 shifted -chem_pair3)) : + chem_pair3 := chem_pair2 ; + chem_num3 := i ; + fi + endfor + if not chem_front[$] : % adjust rotation + 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 ; + if not chem_star[$] : + 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 ; + endfor + chem_previous := str $ ; +enddef ; + +% line (f_rom, t_o, r_ule, c_olor) + +vardef chem_b@# (suffix $) (expr f, t, r, c) = % B + if chem_star[$] : + chem_r@#($,f,t,r,c) ; + elseif length(str @#)>0 : + chem_sb@#($,f,t,r,c) ; + else : + chem_draw( + (subpath (f-1,t) of chem_b_path[$]) chem_transformed($), + r,c,) ; + fi +enddef ; + +vardef chem_sb@# (suffix $) (expr f, t, r, c) = % SB + if chem_star[$] : + chem_sr@#($,f,t,r,c) ; + else : + %chem_draw( + % (subpath (f-1,t) of chem_b_path[$]) chem_transformed($), + % r,c,dashed chem_sb_dash@# scaled chem_b_length) ; + 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, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_sd@# (suffix $) (expr f, t, r, c) = % SD + if chem_star[$] : + chem_rd@#($,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, + r,c,dashed evenly) ; + endfor + fi +enddef ; + +vardef chem_r_fragment@# (suffix $) (expr i) = + ( + if chem_star[$] : + origin + else : + point i-1 of chem_b_path[$] + fi -- + point i-1 of chem_r_path@#[$] + ) % no ; +enddef ; + +vardef chem_r@# (suffix $) (expr f, t, r, c) = % R + if length(str @#)>0 : + chem_sr@#($,f,t,r,c) ; + else : + chem_sr.b($,f,t,r,c) ; + fi +enddef ; + +vardef chem_er@# (suffix $) (expr f, t, r, c) = % ER + if length(str @#)>0: + chem_dr@#($,f,t,r,c) ; + else : + chem_dr.b($,f,t,r,c) ; + fi +enddef ; + +vardef chem_dr@# (suffix $) (expr f, t, r, c) = % DR + if not chem_front[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := (subpath chem_sb_pair@# of chem_r_fragment($,i)) ; + chem_draw( + (chem_path0 paralleled chem_dbl_offset) transformed chem_t, + r,c,) ; + chem_draw( + (chem_path0 paralleled -chem_dbl_offset) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_lr@# (suffix $) (expr f, t, r, c) = % LR + if length(str @#)>0 : + chem_lsr@#($,f,t,r,c) ; + else : + chem_lsr.b($,f,t,r,c) ; + fi +enddef ; + +vardef chem_rr@# (suffix $) (expr f, t, r, c) = % RR + if length(str @#)>0 : + chem_rsr@#($,f,t,r,c) ; + else : + chem_rsr.b($,f,t,r,c) ; + fi +enddef ; + +vardef chem_eb@# (suffix $) (expr f, t, r, c) = % EB + if not chem_star[$] : + %chem_draw( + % ((subpath (f-1,t) of chem_b_path[$]) paralleled -2chem_dbl_offset) + % chem_transformed($), + % r,c,dashed chem_sb_dash scaled chem_b_length) ; + for i=f upto t : + chem_t := identity chem_transformed($) ; + chem_draw( + ((subpath (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$]) + paralleled -2chem_dbl_offset) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_ad@# (suffix $) (expr f, t, r, c) = % AD + 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 + 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 + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + ((point i-1 of chem_r_path[$]) scaled (xpart chem_sb_pair)) transformed chem_t, + chem_dot_factor*r,c,) ; + endfor + fi +enddef ; + +vardef chem_ed@# (suffix $) (expr f, t, r, c) = % ED + chem_t := identity chem_transformed($) ; + for i=f upto t : + if chem_star[$] : + chem_path0 := subpath chem_sb_pair of chem_r_fragment($,i) ; + chem_draw( + (point 0 of (chem_path0 paralleled -chem_dbl_offset)) transformed chem_t, + chem_dot_factor*r,c,) ; + chem_draw( + (point 0 of (chem_path0 paralleled chem_dbl_offset)) transformed chem_t, + chem_dot_factor*r,c,) ; + else : + chem_draw( + ((subpath (chem_sb_pair shifted (i-1,i-1)) of chem_b_path[$]) + paralleled -2chem_dbl_offset) transformed chem_t, + r,c,dashed evenly) ; + fi + endfor +enddef ; + +vardef chem_ep@# (suffix $) (expr f, t, r, c) = % EP + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair of chem_r_fragment($,i) ; + chem_draw( + (point 0 of (chem_path0 paralleled -chem_dbl_offset) -- + point 0 of (chem_path0 paralleled chem_dbl_offset)) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_et@# (suffix $) (expr f, t, r, c) = % ET + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair of chem_r_fragment($,i) ; + chem_draw( + (point 0 of (chem_path0 paralleled -2chem_dbl_offset)) transformed chem_t, + chem_dot_factor*r,c,) ; + chem_draw( + (point 0 of chem_path0) transformed chem_t, + chem_dot_factor*r,c,) ; + chem_draw( + (point 0 of (chem_path0 paralleled 2chem_dbl_offset)) transformed chem_t, + chem_dot_factor*r,c,) ; + endfor + fi +enddef ; + +vardef chem_db@# (suffix $) (expr f, t, r, c) = % DB + if chem_star[$] : + chem_dr@#($,f,t,r,c) ; + elseif not chem_front[$] : + chem_t := identity chem_transformed($) ; + %chem_draw( + % ((subpath (f-1,t) of chem_b_path[$]) paralleled -chem_dbl_offset) + % transformed chem_t, + % r,c,dashed chem_sb_dash@# scaled chem_b_length) ; + %chem_draw( + % ((subpath (f-1,t) of chem_b_path[$]) paralleled chem_dbl_offset) + % transformed chem_t, + % r,c,dashed chem_sb_dash@# scaled chem_b_length) ; + for i=f upto t : + chem_path0 := subpath (chem_sb_pair@# shifted (i-1,i-1)) of chem_b_path[$] ; + chem_draw( + (chem_path0 paralleled -chem_dbl_offset) transformed chem_t, + r,c,) ; + chem_draw( + (chem_path0 paralleled chem_dbl_offset) transformed chem_t, + r,c,) ; + % todo : this should be cut-off where it overlaps a neighboring standard bond. + endfor + fi +enddef ; + +vardef chem_tb@# (suffix $) (expr f, t, r, c) = % TB + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_draw( + (chem_path0 paralleled -2chem_dbl_offset) transformed chem_t, + r,c,) ; + chem_draw( + chem_path0 transformed chem_t, + r,c,) ; + chem_draw( + (chem_path0 paralleled 2chem_dbl_offset) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_sr@# (suffix $) (expr f, t, r, c) = % SR + chem_t := identity chem_transformed($) ; + if chem_stacked[$] : + chem_num0 := length chem_b_path[$] ; chem_num1 := floor(.5chem_num0) ; + for i=f upto t : + chem_draw( + (subpath (if i>chem_num1: .5,ypart fi chem_sb_pair@#) of chem_r_fragment($,i)) + transformed chem_t, + r,c,) ; + endfor + else : + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment($,i)) + transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_rd@# (suffix $) (expr f, t, r, c) = % RD + chem_t := identity chem_transformed($) ; + if chem_stacked[$] : + chem_num0 := length chem_b_path[$] ; chem_num1 := floor(.5chem_num0) ; + for i=f upto t : + chem_draw( + (subpath (if i>chem_num1: .5,ypart fi chem_sb_pair@#) of chem_r_fragment($,i)) + transformed chem_t, + r,c,dashed evenly) ; + endfor + else : + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment($,i)) + transformed chem_t, + r,c,dashed evenly) ; + endfor + fi +enddef ; + +vardef chem_rh@# (suffix $) (expr f, t, r, c) = % RH + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment($,i)) + transformed chem_t, + chem_dot_factor*r,c,dashed withdots scaled ((.5chem_b_length/3)/5bp)) ; + % not symmetric - needs to be tweaked... + endfor +enddef ; + +vardef chem_lrh@# (suffix $) (expr f, t, r, c) = % LRH + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment.lft($,i)) + transformed chem_t, + chem_dot_factor*r,c,dashed withdots scaled ((.5chem_b_length/3)/5bp)) ; + % not symmetric - needs to be tweaked... + endfor +enddef ; + +vardef chem_rrh@# (suffix $) (expr f, t, r, c) = % RRH + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment.rt($,i)) + transformed chem_t, + chem_dot_factor*r,c,dashed withdots scaled ((.5chem_b_length/3)/5bp)) ; + % not symmetric - needs to be tweaked... + endfor +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 ; + +vardef chem_bb@# (suffix $) (expr f, t, r, c) = % BB + if chem_star[$] : + chem_rb@#($,f,t,r,c) ; + elseif chem_front[$] : + chem_t := identity chem_transformed($) ; + chem_draw( + (subpath (f-1,t) of chem_b_path[$]) transformed chem_t, + r,c,) ; + chem_num0 := length chem_b_path[$] ; % total number of bonds + chem_num1 := chem_front_b[$] ; % number of bonds to be made bold + % bold bonds within f and t + chem_num2 := if f<0 :((f+1) mod chem_num0) + chem_num0 else : ((f-1) mod chem_num0) + 1 fi ; + chem_num3 := if t<0 :((t+1) mod chem_num0) + chem_num0 else : ((t-1) mod chem_num0) + 1 fi ; + if chem_num31) : + chem_path0 := subpath (if chem_num2>2 : chem_num2-1 else : 1 fi, + if chem_num3=chem_num1 : + chem_fill( + (point chem_num1 of chem_b_path[$] -- + point chem_num1-1 of chem_b_path[$] shifted (0,-chem_dbl_offset) -- + point chem_num1-1 of chem_b_path[$] shifted (0, chem_dbl_offset) -- + cycle) transformed chem_t, + r,c,) ; + fi + fi + fi +enddef ; + +vardef chem_rb@# (suffix $) (expr f, t, r, c) = % RB + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_fill( + (point 0 of chem_path0 -- + point 1 of chem_path0 + rotatedaround(point 0 of chem_path0, -chem_bb_angle) -- + point 1 of chem_path0 + rotatedaround(point 0 of chem_path0, chem_bb_angle) -- + cycle) transformed chem_t, + r,c,) ; + endfor +enddef ; + +vardef chem_lrb@# (suffix $) (expr f, t, r, c) = % LRB + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.lft($,i) ; + chem_fill( + (point 0 of chem_path0 -- + point 1 of chem_path0 + rotatedaround(point 0 of chem_path0, -chem_bb_angle) -- + point 1 of chem_path0 + rotatedaround(point 0 of chem_path0, chem_bb_angle) -- + cycle) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_rrb@# (suffix $) (expr f, t, r, c) = % RRB + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.rt($,i) ; + chem_fill( + (point 0 of chem_path0 -- + point 1 of chem_path0 + rotatedaround(point 0 of chem_path0, -chem_bb_angle) -- + point 1 of chem_path0 + rotatedaround(point 0 of chem_path0, chem_bb_angle) -- + cycle) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_lsr@# (suffix $) (expr f, t, r, c) = % LSR + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment.lft($,i)) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_rsr@# (suffix $) (expr f, t, r, c) = % RSR + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment.rt($,i)) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_lrd@# (suffix $) (expr f, t, r, c) = % LRD + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment.lft($,i)) transformed chem_t, + r,c,dashed evenly) ; + endfor + fi +enddef ; + +vardef chem_rrd@# (suffix $) (expr f, t, r, c) = % RRD + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of chem_r_fragment.rt($,i)) transformed chem_t, + r,c,dashed evenly) ; + endfor + fi +enddef ; + +vardef chem_s@# (suffix $) (expr f, t, r, c) = % S + if length(str @#)>0 : + chem_ss@#($,f,t,r,c) ; + else : + chem_ss.b($,f,t,r,c) ; + fi +enddef ; + +vardef chem_ss@# (suffix $) (expr f, t, r, c) = % SS + if not (chem_star[$] or chem_front[$]) : + chem_draw( + subpath chem_sb_pair@# of (point f-2 of chem_b_path[$] -- point t of chem_b_path[$]) + chem_transformed($), + r,c,) ; + fi +enddef ; + +vardef chem_mid@# (suffix $) (expr f, t, r, c) = % MID + if length(str @#)>0 : + chem_mids@#($,f,t,r,c) ; + else : + chem_mids.b($,f,t,r,c) ; + fi +enddef ; + +vardef chem_mids@# (suffix $) (expr f, t, r, c) = % MIDS + if not (chem_star[$] or chem_front[$]) : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_draw( + (subpath chem_sb_pair@# of (origin -- point i-1 of chem_b_path[$])) + transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_cd (suffix $) (expr r, c) = % CD + chem_draw( + chem_c_path[$] chem_transformed($), + r,c,dashed evenly) ; +enddef ; + +vardef chem_c (suffix $) (expr r, c) = % C + chem_draw( + chem_c_path[$] chem_transformed($), + r,c,) ; +enddef ; + +vardef chem_ccd (suffix $) (expr f, t, r, c) = % CCD + chem_num0 := ypart((origin--center(subpath (f-2,f-1) of chem_b_path[$])) + intersectiontimes chem_c_path[$]) ; + chem_num1 := ypart((origin--center(subpath (t-1,t) of chem_b_path[$])) + intersectiontimes chem_c_path[$]) ; + if chem_num1>chem_num0 : + chem_num0 := chem_num0 + length chem_c_path[$] ; + fi + chem_draw( + subpath (chem_num1,chem_num0) of chem_c_path[$] chem_transformed($), + r,c,dashed evenly) ; +enddef ; + +vardef chem_cc (suffix $) (expr f, t, r, c) = % CC + chem_num0 := ypart((origin--center(subpath (f-2,f-1) of chem_b_path[$])) + intersectiontimes chem_c_path[$]) ; + chem_num1 := ypart((origin--center(subpath (t-1,t) of chem_b_path[$])) + intersectiontimes chem_c_path[$]) ; + if chem_num1>chem_num0 : + chem_num0 := chem_num0 + length chem_c_path[$] ; + fi + chem_draw( + subpath (chem_num1,chem_num0) of chem_c_path[$] chem_transformed($), + r,c,) ; +enddef ; + +vardef chem_ldb@# (suffix $) (expr f, t, r, c) = % LD + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_draw( + chem_path0 transformed chem_t, + r,c,) ; + chem_draw( + (chem_path0 paralleled 2chem_dbl_offset) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_rdb@# (suffix $) (expr f, t, r, c) = % LD + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_draw( + chem_path0 transformed chem_t, + r,c,) ; + chem_draw( + (chem_path0 paralleled -2chem_dbl_offset) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_ldd@# (suffix $) (expr f, t, r, c) = % LDD + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_draw( + chem_path0 transformed chem_t, + r,c,) ; + chem_draw( + (chem_path0 paralleled 2chem_dbl_offset) transformed chem_t, + r,c,dashed evenly) ; + endfor + fi +enddef ; + +vardef chem_rdd@# (suffix $) (expr f, t, r, c) = % RDD + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_draw( + chem_path0 transformed chem_t, + r,c,) ; + chem_draw( + (chem_path0 paralleled -2chem_dbl_offset) transformed chem_t, + r,c,dashed evenly) ; + endfor + fi +enddef ; + +vardef chem_oe@# (suffix $) (expr f, t, r, c) = % OE + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; + chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; + chem_draw( + ( point 0 of chem_path0 -- + .2[point 0 of chem_path0, point infinity of chem_path0].. + .3[point 0 of chem_path1, point infinity of chem_path1].. + .4[point 0 of chem_path0, point infinity of chem_path0].. + .5[point 0 of chem_path2, point infinity of chem_path2].. + .6[point 0 of chem_path0, point infinity of chem_path0].. + .7[point 0 of chem_path1, point infinity of chem_path1].. + .8[point 0 of chem_path0, point infinity of chem_path0]-- + point infinity of chem_path0) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_bw@# (suffix $) (expr f, t, r, c) = % BW + if chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; + chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; + chem_draw( + ( point 0 of chem_path0.. + .1[point 0 of chem_path1, point infinity of chem_path1].. + .2[point 0 of chem_path0, point infinity of chem_path0].. + .3[point 0 of chem_path2, point infinity of chem_path2].. + .4[point 0 of chem_path0, point infinity of chem_path0].. + .5[point 0 of chem_path1, point infinity of chem_path1].. + .6[point 0 of chem_path0, point infinity of chem_path0].. + .7[point 0 of chem_path2, point infinity of chem_path2].. + .8[point 0 of chem_path0, point infinity of chem_path0].. + .9[point 0 of chem_path1, point infinity of chem_path1].. + point infinity of chem_path0) transformed chem_t, + r,c,) ; + endfor + fi +enddef ; + +vardef chem_bd@# (suffix $) (expr f, t, r, c) = % BD + if chem_star[$] : chem_rbd#@($,f,t,r,c) ; fi +enddef ; + +vardef chem_rbd@# (suffix $) (expr f, t, r, c) = % RBD + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment($,i) ; + if chem_bd_wedge : + chem_path1 := chem_path0 rotated -chem_bb_angle ; + chem_path2 := chem_path0 rotated chem_bb_angle ; + else : + chem_path1 := chem_path0 paralleled -chem_dbl_offset ; + chem_path2 := chem_path0 paralleled chem_dbl_offset ; + fi + for j=0 upto 3 : + chem_draw( + (point (j/3) of chem_path1 -- point (j/3) of chem_path2) transformed chem_t, + 2r,c,) ; + endfor + endfor +enddef ; + +vardef chem_lrbd@# (suffix $) (expr f, t, r, c) = % LRBD + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.lft($,i) ; + if chem_bd_wedge : + chem_path1 := chem_path0 rotated -chem_bb_angle ; + chem_path2 := chem_path0 rotated chem_bb_angle ; + else : + chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; + chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; + fi + for j=0 upto 3 : + chem_draw( + (point (j/3) of chem_path1 -- point (j/3) of chem_path2) transformed chem_t, + 2r,c,) ; + endfor + endfor + fi +enddef ; + +vardef chem_rrbd@# (suffix $) (expr f, t, r, c) = % RRBD + if not chem_star[$] : + chem_t := identity chem_transformed($) ; + for i=f upto t : + chem_path0 := subpath chem_sb_pair@# of chem_r_fragment.rt($,i) ; + if chem_bd_wedge : + chem_path1 := chem_path0 rotated -chem_bb_angle ; + chem_path2 := chem_path0 rotated chem_bb_angle ; + else : + chem_path1 := chem_path0 paralleled -.5chem_dbl_offset ; + chem_path2 := chem_path0 paralleled .5chem_dbl_offset ; + fi + for j=0 upto 3 : + chem_draw( + (point (j/3) of chem_path1 -- point (j/3) of chem_path2) transformed chem_t, + 2r,c,) ; + endfor + endfor + fi +enddef ; + +% text, number (no alignment on number); + +vardef chem_z@#(suffix $) (expr p) (text t) = % Z + draw chem_text@# + (t,chem_do( + if p=0 : + origin + else : + (point p-1 of chem_b_path[$]) chem_transformed($) + fi + )) ; +enddef ; + +vardef chem_cz@#(suffix $) (expr p) (text t) = chem_z@#($,p,t) ; enddef ; % CZ ? + +vardef chem_midz@#(suffix $) (expr p) (text t) = % MIDZ + if not (chem_star[$] or chem_front[$]) : + draw chem_text@# + (t,chem_do( + (xpart chem_sb_pair, 0) scaled (xpart point 0 of chem_b_path[$]) + chem_transformed($) + )) ; + fi +enddef ; + +vardef chem_rz@#(suffix $) (expr p) (text t) = % RZ + draw chem_text@# + (t, chem_do((point p-1 of chem_r_path[$]) chem_transformed($))) ; +enddef ; + +vardef chem_lrz@#(suffix $) (expr p) (text t) = % LRZ + if not chem_star[$] : + draw chem_text@# + (t, + chem_do((point p-1 of chem_r_path.lft[$]) chem_transformed($))) ; + fi +enddef ; + +vardef chem_rrz@#(suffix $) (expr p) (text t) = % RRZ + if not chem_star[$] : + draw chem_text@# + (t, chem_do((point p-1 of chem_r_path.rt[$]) chem_transformed($))) ; + fi +enddef ; + +vardef chem_zn@#(suffix $) (expr p) (text t) = % ZN + chem_zt($,p,t) ; +enddef ; + +vardef chem_zt@#(suffix $) (expr p) (text t) = % ZT + draw chem_text@#(t,chem_do ((point p-1 of chem_b_path[$]) chem_transformed($) + scaled chem_text_min)) ; +enddef ; + +vardef chem_zln@#(suffix $) (expr p) (text t) = % ZLN + chem_zlt($,p,t) ; +enddef ; + +vardef chem_zlt@#(suffix $) (expr p) (text t) = % ZLT + draw chem_text@#(t, chem_do((point p-1.5 of chem_b_path[$]) chem_transformed($) + scaled chem_text_min)) ; +enddef ; + +vardef chem_zrn@#(suffix $) (expr p) (text t) = % ZRN + chem_zrt($,p,t) ; +enddef ; + +vardef chem_zrt@#(suffix $) (expr p) (text t) = % ZRT + draw chem_text@#(t, chem_do((point p-0.5 of chem_b_path[$]) chem_transformed($) + scaled chem_text_min)) ; +enddef ; + +vardef chem_crz@#(suffix $) (expr p) (text t) = % CRZ ???? + if chem_star[$] : + draw chem_text@#(t, chem_do((point p-1 of chem_b_path[$] enlonged chem_center_offset) + chem_transformed($))) ; + fi +enddef ; + +vardef chem_rn@#(suffix $) (expr i, t) = % RN + chem_rt($,i,t) ; +enddef ; + +vardef chem_rt@#(suffix $) (expr p) (text t) = % RT + draw chem_text@#(t, chem_do((center chem_r_fragment($,p)) chem_transformed($))) ; +enddef ; + +vardef chem_lrn@#(suffix $) (expr i, t) = % LRN + chem_lrt($,i,t) ; +enddef ; + +vardef chem_lrt@#(suffix $) (expr p) (text t) = % LRT + draw chem_text@#(t, chem_do((center chem_r_fragment.lft($,p)) chem_transformed($))) ; +enddef ; + +vardef chem_rrn@# (suffix $) (expr i, t) = % RRN + chem_rrt($,i,t) ; +enddef ; + +vardef chem_rrt@#(suffix $) (expr p) (text t) = % RRT + draw chem_text@#(t, chem_do((center chem_r_fragment.rt($,p)) chem_transformed($))) ; +enddef ; + +vardef chem_symbol(expr t) = draw textext(t) ; enddef ; + +vardef chem_align@#(expr pic) = + pic + if (mfun_labtype@# >= 10) : + shifted (0,ypart center pic) + fi + shifted (-(mfun_labxf@#*lrcorner pic + mfun_labyf@#*ulcorner pic + (1-mfun_labxf@#-mfun_labyf@#)*llcorner pic)) +enddef ; + +vardef chem_text@#(expr txt, z) = + chem_pic := textext(txt) ; + if length(str @#)=0 : + chem_pic := chem_align(chem_pic) ; + elseif (str @#) = "auto" : + if z<>origin : + chem_num0 := abs(angle(z rotated chem_setting_rotation)) ; + if chem_num0<=60 : + chem_pic := chem_align.rt (chem_pic) xshifted chem_text_offset ; + elseif chem_num0>=120 : + chem_pic := chem_align.lft(chem_pic) xshifted -chem_text_offset ; + else : + chem_pic := chem_align (chem_pic) ; + fi + else : + chem_pic := chem_align (chem_pic) ; + fi + else : + chem_pic := chem_align@#(chem_pic) shifted (chem_text_offset*mfun_laboff@#) ; + fi + chem_pic := (chem_pic rotated -chem_setting_rotation) shifted z ; + + if chem_trace_text : + draw z withpen pencircle scaled 2pt withcolor red ; + draw boundingbox chem_pic withpen pencircle scaled 1pt withcolor red ; + fi + + chem_pic +enddef ; + +% transform + +% rotations and reflections + +vardef chem_rot (suffix $) (expr d, s) = % ROT + if not chem_front[$] : + if d=0 : + 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[$]) - + angle(point d+chem_num0-1 of chem_b_path[$])) ; + chem_rotation := (chem_rotation + s*chem_num1) zmod 360 ; + fi + fi +enddef ; + +vardef chem_mir (suffix $) (expr d, s) = % MIR + % We take the scale factor s to multiply the rotation, but only ONCE. + % For example: CARBON,.5MIR12 will give a rotation by 104° + if not chem_front[$] : + if d=0 : % inversion + if chem_mirror=origin : + chem_rotation := (chem_rotation + 180*s) zmod 360 ; + else : + chem_mirror := chem_mirror rotated 90 ; + fi + else : + chem_pair0 := (point d-1 of chem_b_path[$]) scaled s ; % not chem_transformed + if chem_mirror=origin : + chem_mirror := chem_pair0 ; + else : + chem_num0 := angle(chem_mirror)-angle(chem_pair0) ; + if (chem_num0>0) and (chem_num0> 180) : + chem_num0 := 360 - chem_num0 ; + elseif (chem_num0<0) and (chem_num0<-180) : + chem_num0 := -360 - chem_num0 ; + fi + chem_num0 := chem_num0 * s ; + chem_rotation := (chem_rotation + 2chem_num0) zmod 360 ; + chem_mirror := origin ; + fi + fi + fi +enddef ; + +% translations + +vardef chem_dir (suffix $) (expr d, s) = % DIR (same as MOV(d-1)MOV(d+1)) + if not chem_front[$] : + if d=0 : + currentpicture := currentpicture shifted -chem_origin ; + chem_origin := origin ; + else : + chem_pair0 := + (((point d-2 of chem_b_path[$]) shifted (point d of chem_b_path[$])) scaled s) + chem_transformed($) ; + currentpicture := currentpicture shifted -chem_pair0 ; + chem_origin := chem_origin shifted -chem_pair0 ; + fi + fi +enddef ; + +vardef chem_mov (suffix $) (expr d, s) = % MOV + if d=0 : + currentpicture := currentpicture shifted -chem_origin ; + chem_origin := origin ; + else : + chem_pair0 := ((point d-1 of chem_b_path[$]) scaled s) chem_transformed($) ; + currentpicture := currentpicture shifted -chem_pair0 ; + chem_origin := chem_origin shifted -chem_pair0 ; + fi ; +enddef ; + +vardef chem_mark (suffix $) (expr d, s) = % MARK + % scale s is ignored + if d<>0 : + chem_mark_pair[d] := -chem_origin ; + fi +enddef ; + +vardef chem_marked (expr d) = + if d=0 : + chem_origin + elseif known chem_mark_pair[d] : + chem_mark_pair[d] shifted chem_origin + else : + origin + fi +enddef ; + +vardef chem_number@#(suffix $) (expr p) (text t) = chem_label@#($,p,t) enddef ; % NUMBER +vardef chem_label@# (suffix $) (expr p) (text t) = % LABEL + draw chem_text@#(t,chem_do(chem_marked(p))) ; +enddef ; + +vardef chem_move (suffix $) (expr d, s) = % MOVE + chem_pair0 := chem_marked(d) scaled s ; + currentpicture := currentpicture shifted -chem_pair0 ; + chem_origin := chem_origin shifted -chem_pair0 ; +enddef ; + +vardef chem_diff (suffix $) (expr d, s) = % DIFF + chem_pair0 := (chem_marked(d) shifted -chem_origin) scaled s ; + currentpicture := currentpicture shifted -chem_pair0 ; + chem_origin := chem_origin shifted -chem_pair0 ; +enddef ; + +vardef chem_line (suffix $) (expr f, t, r, c) = % LINE + draw if f=t : origin else : chem_marked(f) fi -- chem_marked(t) + % no chem_transformed + withpen pencircle scaled r + withcolor c %\MPcolor{c} +enddef ; + +vardef chem_dash (suffix $) (expr f, t, r, c) = % DASH + draw if f=t : origin else : chem_marked(f) fi -- chem_marked(t) + % no chem_transformed + withpen pencircle scaled r + withcolor c %\MPcolor{c} + dashed evenly ; +enddef ; + +vardef chem_arrow (suffix $) (expr f, t, r, c) = % ARROW + drawarrow if f=t : origin else : chem_marked(f) fi -- chem_marked(t) + % no chem_transformed + withpen pencircle scaled r + withcolor c %\MPcolor{c} +enddef ; + + +vardef chem_rm (suffix $) (expr d, s) = % RM + if (not chem_front[$]) and (d<>0) : + chem_pair0 := ((point d-1 of chem_r_path[$]) scaled s) chem_transformed($) ; + currentpicture := currentpicture shifted -chem_pair0 ; + chem_origin := chem_origin shifted -chem_pair0 ; + fi ; +enddef ; + +vardef chem_off (suffix $) (expr d, s) = % OFF + if d=0 : + currentpicture := currentpicture shifted -chem_origin ; + chem_origin := origin ; + else : + chem_pair0 := (unitvector(point d-1 of chem_b_path[one])) scaled chem_setting_offset*s ; + % not chem_transformed + currentpicture := currentpicture shifted -chem_pair0 ; + chem_origin := chem_origin shifted -chem_pair0 ; + fi ; +enddef ; diff --git a/metapost/context/base/mpiv/mp-core.mpiv b/metapost/context/base/mpiv/mp-core.mpiv new file mode 100644 index 000000000..9b7182908 --- /dev/null +++ b/metapost/context/base/mpiv/mp-core.mpiv @@ -0,0 +1,1561 @@ +%D \module +%D [ file=mp-core.mpiv, +%D version=1999.08.01, % anchoring +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=background macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +if known context_core : endinput ; fi ; + +boolean context_core ; context_core := true ; + +%D Copied to here .. not used any more. + +if unknown NOfTextColumns : numeric NOfTextColumns ; NOfTextColumns := 1 ; fi ; +if unknown NOfTextAreas : numeric NOfTextAreas ; NOfTextAreas := 1 ; fi ; + +def SaveTextAreas = + path SavedTextAreas [] ; + path SavedTextColumns[] ; + numeric NOfSavedTextAreas ; + numeric NOfSavedTextColumns ; + for i=1 upto NOfTextAreas : + SavedTextAreas[i] := TextAreas[i] ; + endfor ; + for i=1 upto NOfTextColumns : + SavedTextColumns[i] := TextColumns[i] ; + endfor ; + NOfSavedTextAreas := NOfTextAreas ; + NOfSavedTextColumns := NOfTextColumns ; +enddef ; + +def ResetTextAreas = + path TextAreas[], TextColumns[], PlainTextArea, RegionTextArea ; + numeric NOfTextAreas ; NOfTextAreas := 0 ; + numeric NOfTextColumns ; NOfTextColumns := 0 ; + numeric nofmultipars ; nofmultipars := 0 ; + TextAreas[0] := TextColumns[0] := origin -- cycle ; +enddef ; + +ResetTextAreas ; SaveTextAreas ; ; + +def RegisterTextArea (expr x, y, w, h, d) = + begingroup ; + save p ; path p ; + p := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; + if NOfTextAreas>0 : + % if needed, concatenate areas + if (round(llcorner TextAreas[NOfTextAreas]) = round(ulcorner p)) and + (round(lrcorner TextAreas[NOfTextAreas]) = round(urcorner p)) : + p := + ulcorner TextAreas[NOfTextAreas] -- + urcorner TextAreas[NOfTextAreas] -- + lrcorner p -- + llcorner p -- cycle ; + else : + NOfTextAreas := NOfTextAreas + 1 ; + fi ; + else : + NOfTextAreas := NOfTextAreas + 1 ; + fi ; + TextAreas[NOfTextAreas] := p ; + if NOfTextColumns>0 : + if (round(xpart llcorner TextColumns[NOfTextColumns]) = round(xpart ulcorner p)) and + (round(xpart lrcorner TextColumns[NOfTextColumns]) = round(xpart urcorner p)) : + p := + ulcorner TextColumns[NOfTextColumns] -- + urcorner TextColumns[NOfTextColumns] -- + lrcorner p -- + llcorner p -- cycle ; + else : + NOfTextColumns := NOfTextColumns + 1 ; + fi ; + else : + NOfTextColumns := NOfTextColumns + 1 ; + fi ; + TextColumns[NOfTextColumns] := p ; + endgroup ; +enddef ; + +%D We store a local area in slot zero. + +def RegisterPlainTextArea(expr x,y,w,h,d) = + PlainTextArea := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; +enddef ; + +def RegisterRegionTextArea(expr x,y,w,h,d) = + RegionTextArea := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; + % RegionTextArea := RegionTextArea enlarged 2mm ; +enddef ; + +def RegisterLocalTextArea (expr x, y, w, h, d) = + TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; +enddef ; + +def ResetLocalTextArea = + TextAreas[0] := TextColumns[0] := origin -- cycle ; +enddef ; + +ResetLocalTextArea ; + +vardef InsideTextArea (expr _i_, _xy_) = + (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and + (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and + (round(ypart _xy_) >= round(ypart llcorner TextAreas[_i_])) and + (round(ypart _xy_) <= round(ypart urcorner TextAreas[_i_])) +enddef ; + +vardef InsideSavedTextArea (expr _i_, _xy_) = + (round(xpart _xy_) >= round(xpart llcorner SavedTextAreas[_i_])) and + (round(xpart _xy_) <= round(xpart lrcorner SavedTextAreas[_i_])) and + (round(ypart _xy_) >= round(ypart llcorner SavedTextAreas[_i_])) and + (round(ypart _xy_) <= round(ypart urcorner SavedTextAreas[_i_])) +enddef ; + +vardef InsideSomeTextArea (expr _xy_) = + save ok ; boolean ok ; ok := false ; + for i := 1 upto NOfTextAreas : + if InsideTextArea(i,_xy_) : + ok := true ; % we can move the exit here + fi ; + exitif ok ; + endfor ; + ok +enddef ; + +vardef InsideSomeSavedTextArea (expr _xy_) = + save ok ; boolean ok ; ok := false ; + for i := 1 upto NOfSavedTextAreas : + if InsideSavedTextArea(i,_xy_) : + ok := true ; + fi ; + exitif ok ; + endfor ; + ok +enddef ; + +vardef TextAreaX (expr x) = + numeric _TextAreaX_ ; _TextAreaX_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) : + _TextAreaX_ := xpart llcorner TextAreas[i] ; + fi ; + endfor ; + _TextAreaX_ +enddef ; + +vardef TextAreaY (expr y) = + numeric _TextAreaY_ ; _TextAreaY_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(y) >= round(ypart llcorner TextAreas[NOfTextAreas])) and + (round(y) <= round(ypart ulcorner TextAreas[NOfTextAreas])) : + _TextAreaY_ := ypart llcorner TextAreas[NOfTextAreas] ; + fi ; + endfor ; + _TextAreaY_ +enddef ; + +vardef TextAreaXY (expr x, y) = + pair _TextAreaXY_ ; _TextAreaXY_ := origin ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) and + (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaXY_ := llconer TextAreas[i] ; + fi ; + endfor ; + _TextAreaXY_ +enddef ; + +vardef TextAreaW (expr x) = + numeric _TextAreaW_ ; _TextAreaW_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) : + _TextAreaW_ := bbwidth(TextAreas[i]) ; + fi ; + endfor ; + _TextAreaW_ +enddef ; + +vardef TextAreaH (expr y) = + numeric _TextAreaH_ ; _TextAreaH_ := 0 ; + for i := 1 upto NOfTextAreas : + if (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaH_ := bbheight(TextAreas[i]) ; + fi ; + endfor ; + _TextAreaH_ +enddef ; + +vardef TextAreaWH (expr x, y) = + pair _TextAreaWH_ ; _TextAreaWH_ := origin ; + for i := 1 upto NOfTextAreas : + if (round(x) >= round(xpart llcorner TextAreas[i])) and + (round(x) <= round(xpart lrcorner TextAreas[i])) and + (round(y) >= round(ypart llcorner TextAreas[i])) and + (round(y) <= round(ypart ulcorner TextAreas[i])) : + _TextAreaWH_ := (bbwidth(TextAreas[i]),bbheight(TextAreas[i])) ; + fi ; + endfor ; + _TextAreaWH_ +enddef ; + +%D Till here. + +pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; +path pxy[] ; +numeric hxy[], wxy[], dxy[], nxy[] ; + +def box_found (expr n,x,y,w,h,d) = + not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) +enddef ; + +def initialize_box_pos (expr pos,n,x,y,w,h,d) = + pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; + path pxy ; numeric hxy, wxy, dxy, nxy; + lxy := (x,y) ; + llxy := (x,y-d) ; + lrxy := (x+w,y-d) ; + urxy := (x+w,y+h) ; + ulxy := (x,y+h) ; + wxy := w ; + hxy := h ; + dxy := d ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; + nxy := n ; + freeze_box(pos) ; +enddef ; + +def freeze_box (expr pos) = + lxy[pos] := lxy ; + llxy[pos] := llxy ; + lrxy[pos] := lrxy ; + urxy[pos] := urxy ; + ulxy[pos] := ulxy ; + wxy[pos] := wxy ; + hxy[pos] := hxy ; + dxy[pos] := dxy ; + rxy[pos] := rxy ; + pxy[pos] := pxy ; + cxy[pos] := cxy ; + nxy[pos] := nxy ; +enddef ; + +def initialize_box (expr n,x,y,w,h,d) = + numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; +enddef ; + +def initialize_area (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td) = + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + do_initialize_area (fpos, tpos) ; +enddef ; + +def do_initialize_area (expr fpos, tpos) = + lxy := lxy[fpos] ; + llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; + lrxy := lrxy[tpos] ; + urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; + ulxy := ulxy[fpos] ; + wxy := xpart lrxy - xpart llxy ; + hxy := hxy[fpos] ; + dxy := dxy[tpos] ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; +enddef ; + +def set_par_line_height (expr ph, pd) = + par_strut_height := if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ; + par_strut_depth := if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ; + par_line_height := par_strut_height + par_strut_depth ; +enddef ; + +def initialize_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + mn,mx,my,mw,mh,md, + pn,px,py,pw,ph,pd, + rw,rl,rr,rh,ra,ri) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; + numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (ph, pd) ; + + do_initialize_area (fpos, tpos) ; + do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; + +enddef ; + +def initialize_area_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + wn,wx,wy,ww,wh,wd) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (wh, wd) ; + + numeric ffpos ; ffpos := 4 ; initialize_box_pos(ffpos,wn,wx,fy,0,wh,wd) ; + numeric ttpos ; ttpos := 5 ; initialize_box_pos(ttpos,wn,wx+ww,ty,0,wh,wd) ; + + do_initialize_area (ffpos, ttpos) ; + + numeric mpos ; mpos := 6 ; freeze_box(mpos) ; + + do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; + +enddef ; + +def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = + + pair lref, rref, pref, lhref, rhref ; + + % clip the page area to the left and right skips + + llxy[mpos] := llxy[mpos] shifted (+rl,0) ; + lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; + urxy[mpos] := urxy[mpos] shifted (-rr,0) ; + ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; + + % fixate the leftskip, rightskip and hanging indentation + + lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; + rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; + + pref := lxy[ppos] ; + + if nxy[tpos] > nxy[fpos] : + if nxy[fpos] = nxy[mpos] : + % first of multiple pages + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := down ; + elseif nxy[tpos] = nxy[mpos] : + % last of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + boxgriddirection := up ; + else : + % middle of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := up ; + fi ; + else : + % just one page + boxgriddirection := up ; + fi ; + + path txy, bxy, pxy, mxy ; + + txy := originpath ; % top + bxy := originpath ; % bottom + pxy := originpath ; % composed + + boolean lefthang, righthang, somehang ; + + % we only hang on the first of a multiple page background + + if nxy[mpos] > nxy[fpos] : + lefthang := righthang := somehang := false ; + else : + lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; + fi ; + + if lefthang : + mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; + elseif righthang : + mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; + else : + mxy := originpath ; + fi ; + + if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : + + % We have a one-liner. Watch how er use the bottom pos for + % determining the height. + + llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; + ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; + + else : + + % We have a multi-liner. For convenience we now correct the + % begin and end points for indentation. + + if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : + llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; + else : + llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; + fi ; + + if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : + lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; + else : + lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; + fi ; + + fi ; + + somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and + (ypart llxy[tpos]0 : + left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; + right_skip := rw - left_skip - ww ; + else : + left_skip := rl ; + right_skip := rr ; + fi ; + + path multipar, multipars[] ; + numeric multiref, multirefs[] ; + numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end + + numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; + + % locals .. why can't i move these outside? + + vardef _pmp_set_multipar_ (expr i) = + ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip + if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) + enddef ; + + vardef _pmp_snapped_multi_pos_ (expr p) = + if snap_multi_par_tops : + if abs(ypart p - ypart ulcorner multipar) < par_line_height : + (xpart p,ypart ulcorner multipar) + else : + p + fi + else : + p + fi + enddef ; + + vardef _pmp_estimated_par_lines_ (expr h) = + round(h/par_line_height) + enddef ; + + vardef _pmp_top_multi_par_(expr p) = + (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p))) + enddef ; + + vardef _pmp_multi_par_tsc_(expr p) = + if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi + enddef ; + + vardef _pmp_estimated_multi_par_height_ (expr n, t) = + if round(par_line_height)=0 : + 0 + else : + save ok, h ; boolean ok ; + numeric h ; h := 0 ; + ok := false ; + if (nxy[fpos]=RealPageNumber-1) : + for i := 1 upto NOfSavedTextAreas : + if (InsideSavedTextArea(i,par_start_pos)) : + ok := true ; + h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner SavedTextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ; + fi ; + endfor ; + fi ; + if ok : + for i := 1 upto n-1 : + h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; + endfor ; + else : + % already: ok := false ; + for i := 1 upto n-1 : + if (InsideTextArea(i,par_start_pos)) : + ok := true ; + h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; + fi ; + endfor ; + fi ; + h + fi + enddef ; + + vardef _pmp_left_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; + + if (par_hang_indent>0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ul_ ; _ul_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])); + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llxy[tpos])) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _ul_ + par_hang_indent, ypart lrxy[fpos]) -- + (xpart _ul_ + par_hang_indent, ypart _pa_) -- + (xpart ulcorner multipar, ypart _pa_) + else : + (xpart ulcorner multipar, ypart lrxy[fpos]) + fi + enddef ; + + vardef _pmp_right_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ; + + if (par_hang_indent<0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ur_ ; _ur_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; + pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart urcorner multipar, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart _pmp_snapped_multi_pos_(urxy[fpos])) + else : + (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) + fi + enddef ; + + vardef _pmp_x_left_top_hang_ (expr i, t) = + par_hang_after := min(0,ra + _pmp_estimated_multi_par_height_(i,t)) ; + if (par_hang_indent>0) and (par_hang_after<0) : + pair _ul_ ; _ul_ := ulcorner multipar ; + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if t : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos])); + fi ; + if abs(ypart _pa_-ypart llxy[tpos])0) and (par_hang_after>0) and obey_multi_par_hang : + _ll_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])) ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + _pa_ -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + (xpart _pa_ + par_hang_indent,ypart _sa_) + else : + (xpart llcorner multipar, ypart _sa_) + fi + enddef ; + + vardef _pmp_right_bottom_hang_ (expr same_area) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if same_area : _pmp_snapped_multi_pos_(ulxy[tpos]) else : lrcorner multipar fi ; + if (par_hang_indent<0) and (par_hang_after>0) and obey_multi_par_hang : + _lr_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + _pa_ + else : + (xpart lrcorner multipar, ypart _sa_) + fi + enddef ; + + vardef _pmp_x_left_bottom_hang_ (expr i, t) = + pair _ll_, _sa_, _pa_ ; + _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; + if (par_hang_indent>0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i,t)) ; + _ll_ := ulcorner multipar ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + fi + _pa_ + else : + (xpart llcorner multipar, ypart _sa_) + fi + enddef ; + + vardef _pmp_x_right_bottom_hang_ (expr i, t) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ; + if (par_hang_indent<0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i, t)) ; + _lr_ := urcorner multipar ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + _pa_ + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + -- (xpart _pa_ + par_hang_indent,ypart _pa_) + -- (xpart _pa_ + par_hang_indent,ypart _sa_) + fi + else : + (xpart lrcorner multipar, ypart _sa_) + fi + enddef ; + + % def _pmp_test_multipar_ = + % multipar := boundingbox multipar ; + % enddef ; + + % first loop + + ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; + + if enable_multi_par_fallback and (nxy[fpos]=RealPageNumber) + and (nxy[tpos]=RealPageNumber) and not (InsideSomeTextArea(lxy[fpos]) and InsideSomeTextArea(rxy[tpos])) : + + % fallback + + % multipar := + % llxy[fpos] -- + % lrxy[tpos] -- + % urxy[tpos] -- + % ulxy[fpos] -- cycle ; + % + % save_multipar (1,1,multipar) ; + + % we need to take the boundingbox because there can be + % more lines and we want a proper rectange + + multipar := + ulxy[fpos] -- + urxy[tpos] -- + lrxy[fpos] -- + llxy[tpos] -- cycle ; + + save_multipar (1,1,boundingbox(multipar)) ; + + else : + + % normal + + for i=1 upto NOfTextAreas : + + TopSkipCorrection := 0 ; + + multipar := _pmp_set_multipar_(i) ; + + % watch how we compensate for negative indentation + + if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) : + + % first one in chain + + ii := i ; + + if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % in same area + + nn := i ; + + if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : + + TopSkipCorrection := TopSkip - StrutHeight ; + + if round(ypart ulxy[fpos] + TopSkipCorrection) = round(ypart ulcorner TextAreas[i]) : + ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ; + urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ; + else : + TopSkipCorrection := 0 ; + fi ; + + fi ; + + if ypart llxy[fpos] = ypart llxy[tpos] : + + multipar := + llxy[fpos] -- + lrxy[tpos] -- + _pmp_snapped_multi_pos_(urxy[tpos]) -- + _pmp_snapped_multi_pos_(ulxy[fpos]) -- + cycle ; + + save_multipar (i,1,multipar) ; + + elseif (ypart llxy[fpos] = ypart ulxy[tpos]) and (xpart llxy[tpos] < xpart llxy[fpos]) : + + % two loners + + multipar := if obey_multi_par_hang : + + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + + else : + + llxy[fpos] -- + (xpart urcorner multipar, ypart llxy[fpos]) -- + (xpart urcorner multipar, ypart ulxy[fpos]) -- + _pmp_snapped_multi_pos_(ulxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + multipar := _pmp_set_multipar_(i) ; + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart llcorner multipar, ypart ulxy[tpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart lrcorner multipar, ypart ulxy[tpos]) -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(false) -- + _pmp_right_bottom_hang_(false) -- + _pmp_right_top_hang_(false) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(false) -- + + else : + + llcorner multipar -- + lrcorner multipar -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + + elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % last one in chain + + nn := i ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,true) -- + _pmp_x_right_top_hang_(i,true) -- + _pmp_x_right_bottom_hang_(i,true) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + _pmp_x_left_bottom_hang_(i,true) -- + cycle ; + + else : + + multipar := + ulcorner multipar -- + urcorner multipar -- + (xpart lrcorner multipar, ypart urxy[tpos]) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + (xpart llcorner multipar, ypart llxy[tpos]) -- + cycle ; + + fi ; + + save_multipar (i,3,multipar) ; + + elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) and (NOfTextColumns>1)) : + + save_multipar (i,2,multipar) ; + + else : + % handled later + fi ; + + endfor ; + + + % second loop + + if force_multi_par_chain or (ii > 1) : + + for i=ii+1 upto nn-1 : + + % rest of chain / todo : hang + + % hm, the second+ column in column sets now gets lost in a NOfTextColumns + + if (not check_multi_par_chain) or ((nxy[fpos]RealPageNumber)) : + + multipar := _pmp_set_multipar_(i) ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,false) -- + _pmp_x_right_top_hang_(i,false) -- + _pmp_x_right_bottom_hang_(i,false) -- + _pmp_x_left_bottom_hang_(i,false) -- + cycle ; + + fi ; + + save_multipar(i,2,multipar) ; + + fi ; + + endfor ; + + fi ; + + % end of normal/fallback + + fi ; + + if span_multi_column_pars : + endgroup ; + fi ; + + % potential safeguard: + + % for i=1 upto nofmultipars : + % if length p <= 4 : + % multipars[i] := boundingbox(multipars[i]) ; + % fi ; + % end ; + + % quick hack for gb: + + one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; + +enddef ; + +def boxgridoptions = withcolor .8red enddef ; +def boxlineoptions = withcolor .8blue enddef ; +def boxfilloptions = withcolor .8white enddef ; + +numeric boxgridtype ; boxgridtype := 0 ; +numeric boxlinetype ; boxlinetype := 1 ; +numeric boxfilltype ; boxfilltype := 1 ; +numeric boxdashtype ; boxdashtype := 0 ; +pair boxgriddirection ; boxgriddirection := up ; +numeric boxgridwidth ; boxgridwidth := 1pt ; +numeric boxlinewidth ; boxlinewidth := 1pt ; +numeric boxlineradius ; boxlineradius := 0pt ; +numeric boxfilloffset ; boxfilloffset := 0pt ; +numeric boxgriddistance ; boxgriddistance := .5cm ; +numeric boxgridshift ; boxgridshift := 0pt ; + +def draw_box = + draw pxy boxlineoptions withpen pencircle scaled boxlinewidth ; + draw lxy -- rxy boxlineoptions withpen pencircle scaled boxgridwidth ; +enddef ; + +def draw_par = % 1 2 3 11 12 + do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ; + for i = pxy, txy, bxy : + if boxgridtype = 1 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) boxgridoptions ; + elseif boxgridtype = 2 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,false) boxgridoptions ; + elseif boxgridtype = 3 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) boxgridoptions ; + draw baseline_grid (i,boxgriddirection,true ) shifted (0,ExHeight) boxgridoptions ; + elseif boxgridtype = 4 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) shifted (0,ExHeight/2) boxgridoptions ; + elseif boxgridtype = 11 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype = 12 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def do_show_par (expr p, r, c) = + if length(p) > 2 : + for i=0 upto length(p) : + draw fullcircle scaled r shifted point i of p withpen pencircle scaled .5pt withcolor c ; + endfor ; + fi ; + draw p withpen pencircle scaled .5pt withcolor c ; +enddef ; + +def show_par = + if length(mxy) > 2 : + draw mxy dashed evenly withpen pencircle scaled .5pt withcolor .5white ; + fi ; + do_show_par(txy, 4pt, .5green) ; + do_show_par(bxy, 6pt, .5blue ) ; + do_show_par(pxy, 8pt, .5red ) ; + draw pref withpen pencircle scaled 2pt ; +enddef ; + +def sort_multi_pars = + if nofmultipars>1 : + begingroup ; + save _p_, _n_ ; path _p_ ; numeric _n_ ; + for i := 1 upto nofmultipars : + if multilocs[i] = 3 : + _p_ := multipars[nofmultipars] ; + multipars[nofmultipars] := multipars[i] ; + multipars[i] := _p_ ; + _n_ := multirefs[nofmultipars] ; + multirefs[nofmultipars] := multirefs[i] ; + multirefs[i] := _n_ ; + _n_ := multilocs[nofmultipars] ; + multilocs[nofmultipars] := multilocs[i] ; + multilocs[i] := _n_ ; + fi ; + endfor ; + endgroup ; + fi ; +enddef ; + +def collapse_multi_pars = + if nofmultipars>1 : + begingroup ; + save _nofmultipars_ ; numeric _nofmultipars_ ; + _nofmultipars_ := 1 ; + sort_multi_pars ; % block not in order: 1, 3, 2.... + for i:=1 upto nofmultipars-1 : + if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and + (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : + multilocs[_nofmultipars_] := multilocs[i+1] ; + multirefs[_nofmultipars_] := multirefs[i+1] ; + multipars[_nofmultipars_] := + ulcorner multipars[_nofmultipars_] -- + urcorner multipars[_nofmultipars_] -- + lrcorner multipars[i+1] -- + llcorner multipars[i+1] -- cycle ; + else : + _nofmultipars_ := _nofmultipars_ + 1 ; + multipars[_nofmultipars_] := multipars[i+1] ; + multilocs[_nofmultipars_] := multilocs[i+1] ; + multirefs[_nofmultipars_] := multirefs[i+1] ; + fi ; + endfor ; + nofmultipars := _nofmultipars_ ; + endgroup ; + fi ; +enddef ; + +def draw_multi_pars = + for i=1 upto nofmultipars : + do_draw_par(multipars[i]) ; + if boxgridtype= 1 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; + elseif boxgridtype= 2 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; + elseif boxgridtype= 3 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; + elseif boxgridtype= 4 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; + elseif boxgridtype=11 : + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype=12 : + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def show_multi_pars = + for i=1 upto nofmultipars : + do_show_par(multipars[i], 6pt, .5blue) ; + endfor ; +enddef ; + +vardef do_draw_par (expr p) = + if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : + save pp ; path pp ; + if (boxlineradius>0) and (boxlinetype=2) : + pp := p cornered boxlineradius ; + else : + pp := p ; + fi ; + if boxfilltype>0 : + if boxfilloffset>0 : + % temporary hack + begingroup ; + interim linejoin := mitered ; + filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ; + endgroup ; + else : + fill pp boxfilloptions ; + fi ; + fi ; + if boxlinetype>0 : + draw pp boxlineoptions withpen pencircle scaled boxlinewidth ; + fi ; + fi ; +enddef ; + +vardef baseline_grid (expr pxy, pdir, at_baseline) = + save width ; width := bbwidth(pxy) ; + save height ; height := bbheight(pxy) ; + if (par_line_height>0) and (height>1) and (width>1) and (boxgridwidth>0) : + save i, grid, bb ; picture grid ; pair start ; path bb ; + def _do_ (expr start) = + % 1 = normal, 2 = with background (i.e. no shine-through) + if boxdashtype = 2 : + draw start -- start shifted (width,0) + withpen pencircle scaled boxgridwidth + boxfilloptions ; + fi ; + draw start -- start shifted (width,0) + if boxdashtype > 0 : + dashed evenly + fi + withpen pencircle scaled boxgridwidth + boxgridoptions ; + enddef ; + grid := image ( % fails with inlinespace + if pdir=up : + for i = if at_baseline : par_strut_depth else : 0 fi step par_line_height until max(height,par_line_height) : + _do_ (llcorner pxy shifted (0,+i)) ; + endfor ; + else : + for i = if at_baseline : par_strut_height else : 0 fi step par_line_height until height : + _do_ (ulcorner pxy shifted (0,-i)) ; + endfor ; + fi ; + ) ; + clip grid to pxy ; + bb := boundingbox grid ; + grid := grid shifted (0,boxgridshift) ; + setbounds grid to bb ; + grid + else : + nullpicture + fi +enddef ; + +vardef graphic_grid (expr pxy, dx, dy, x, y) = + if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : + save grid ; picture grid ; + grid := image ( + for i = xpart llcorner pxy step dx until xpart lrcorner pxy : + draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) withpen pencircle scaled boxgridwidth ; + endfor ; + for i = ypart llcorner pxy step dy until ypart ulcorner pxy : + draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) withpen pencircle scaled boxgridwidth ; + endfor + ) shifted (x,y) ; + clip grid to pxy ; + grid + else : + nullpicture + fi +enddef ; + +def anchor_box (expr n,x,y,w,h,d) = + currentpicture := currentpicture shifted (-x,-y) ; +enddef ; + +let draw_area = draw_box ; +let anchor_area = anchor_box ; +let anchor_par = anchor_box ; + +numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; +pair sync_xy[][] ; color sync_c[][] ; + +def ResetSyncTasks = + path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; + NOfSyncPaths := CurrentSyncClass := 0 ; + if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; + if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; + if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; + if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; + if (SyncLeftOffset = 0) and (SyncWidth = 0) : + SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; + fi ; +enddef ; + +ResetSyncTasks ; + +vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = + save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; + o shifted (leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,bottomoffset) -- + o shifted (leftoffset,bottomoffset) -- cycle +enddef ; + +def SetSyncColor(expr n, i, c) = + sync_c[n][i] := c ; +enddef ; + +def SetSyncThreshold(expr n, i, th) = + sync_th[n][i] := th ; +enddef ; + +vardef TheSyncColor(expr n, i) = + if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi +enddef ; + +vardef TheSyncThreshold(expr n, i) = + if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi +enddef ; + +vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = + ResetSyncTasks ; + if known sync_n[n] : + CurrentSyncClass := n ; + save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; + for i=1 upto sync_n[n] : + if RealPageNumber > sync_p[n][i] : + l := i ; + elseif RealPageNumber = sync_p[n][i] : + NOfSyncPaths := NOfSyncPaths + 1 ; + if not ok : + if i>1 : + if sync_t[n][i-1] = sync_t[n][i] : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i-1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + ok := true ; + fi ; + endfor ; + if (NOfSyncPaths = 0) and (l > 0) : + NOfSyncPaths := 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := l ; + fi ; + if NOfSyncPaths > 0 : + for i = 1 upto NOfSyncPaths-1 : + SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; + endfor ; + if unknown SyncThresholdMethod : + numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; + fi ; + if extendtop : + if SyncThresholdMethod = 1 : + if NOfSyncPaths>1 : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; + if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : + SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; + fi ; + fi ; + else : + for i = 1 upto NOfSyncPaths : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; + if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : + SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; + fi ; + endfor ; + fi ; + fi ; + if prestartnext : + if NOfSyncPaths>1 : + if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; + if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : + SyncPaths[NOfSyncPaths+1] := + (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + lrcorner SyncPaths[NOfSyncPaths] -- + llcorner SyncPaths[NOfSyncPaths] -- cycle ; + SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + fi ; + fi ; + fi ; + else : + if NOfSyncPaths>1 : + d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; + if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : + NOfSyncPaths := NOfSyncPaths - 1 ; + SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; + fi ; + fi ; + fi ; + if (NOfSyncPaths>1) and collapse : + save j ; numeric j ; j := 1 ; + for i = 2 upto NOfSyncPaths : + if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : + SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; + SyncTasks[j] := SyncTasks[i] ; + else : + j := j + 1 ; + SyncPaths[j] := SyncPaths[i] ; + SyncTasks[j] := SyncTasks[i] ; + fi ; + endfor ; + NOfSyncPaths := j ; + fi ; + fi ; + fi ; +enddef ; + +def SyncTask(expr n) = + if known SyncTasks[n] : SyncTasks[n] else : 0 fi +enddef ; + +def FlushSyncTasks = + for i = 1 upto NOfSyncPaths : + ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; + endfor ; +enddef ; + +def ProcessSyncTask(expr p, c) = + fill p withcolor c ; +enddef ; diff --git a/metapost/context/base/mpiv/mp-cows.mpiv b/metapost/context/base/mpiv/mp-cows.mpiv new file mode 100644 index 000000000..3ad1a98f5 --- /dev/null +++ b/metapost/context/base/mpiv/mp-cows.mpiv @@ -0,0 +1,156 @@ +%D \module +%D [ file=mp-cows.mpiv, +%D version=2015.05.27, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=the cow, +%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_cows : endinput ; fi ; + +boolean context_cows ; context_cows := true ; + +picture cow ; cow := image ( + fill (245.449005,600.340027)..controls (242.781006,599.398010) and (239.621002,596.020020)..(237.671997,594.070007) + ..controls (236.738007,584.421997) and (244.578003,583.629028)..(250.199005,577.440979) + ..controls (258.769989,573.698975) and (251.210999,567.718994)..(256.179993,557.421997) + ..controls (257.039001,550.940979) and (257.898010,543.890991)..(255.309006,539.781006) + ..controls (249.479996,538.921997) and (247.968994,540.218994)..(246.891006,531.429993) + ..controls (246.309006,526.968994) and (231.770004,529.059021)..(229.031006,538.270020) + ..controls (227.089996,544.968994) and (221.328003,546.698975)..(217.800995,543.171997) + ..controls (213.770004,538.059021) and (215.781006,531.218994)..(217.800995,527.468994) + ..controls (224.929993,517.320007) and (212.039001,511.421997)..(205.128998,516.737976) + ..controls (199.729996,508.679993) and (211.391006,500.039001)..(207.429993,494.500000) + ..controls (205.781006,493.988007) and (204.770004,489.171997)..(185.468994,500.539001) + ..controls (180.358994,504.140991) and (167.828003,500.761993)..(168.770004,520.629028) + ..controls (168.770004,525.820007) and (165.602005,543.531006)..(162.141006,555.909973) + ..controls (159.410004,561.237976) and (156.738007,559.078003)..(156.891006,553.898010) + ..controls (157.179993,547.851990) and (162.940994,531.218994)..(155.520004,540.218994) + ..controls (153.578003,539.210999) and (156.891006,523.578003)..(156.891006,521.640991) + ..controls (162.000000,517.031006) and (157.391006,513.578003)..(154.729996,512.281006) + ..controls (151.270004,518.328003) and (149.621002,518.039001)..(147.171997,514.440979) + ..controls (141.699005,514.078003) and (144.578003,528.190979)..(140.261993,528.620972) + ..controls (137.020004,527.762024) and (139.179993,520.059021)..(138.238007,518.762024) + ..controls (132.979996,524.737976) and (130.897995,529.270020)..(127.012001,521.640991) + ..controls (126.140999,521.640991) and (122.109001,519.190979)..(120.960999,526.539001) + ..controls (117.648003,552.737976) and (107.058998,558.359009)..(93.820297,565.129028) + ..controls (92.019501,565.629028) and (84.238297,566.710999)..(79.339798,568.148010) + ..controls (73.511703,560.879028) and (58.320301,565.629028)..(56.230499,570.309021) + ..controls (54.789101,572.690979) and (54.648399,575.210999)..(54.789101,576.500000) + ..controls (52.339802,580.101990) and (55.871101,582.698975)..(59.621101,583.059021) + ..controls (62.859402,587.159973) and (68.539101,594.940979)..(71.281303,601.559021) + ..controls (72.289101,603.070007) and (74.949203,609.340027)..(78.191399,609.551025) + ..controls (74.949203,612.940979) and (74.300797,622.512024)..(82.660202,617.328003) + ..controls (87.121101,624.020020) and (92.089798,624.309021)..(95.761703,615.820007) + ..controls (102.890999,615.379028) and (102.308998,608.690979)..(115.780998,605.520020) + ..controls (122.762001,602.859009) and (132.770004,604.578003)..(140.261993,603.718994) + ..controls (136.218994,596.879028) and (127.441002,566.859009)..(132.979996,559.801025) + ..controls (140.761993,564.698975) and (141.839996,605.379028)..(157.031006,595.659973) + ..controls (160.559006,593.929993) and (159.910004,590.039001)..(164.089996,590.179993) + ..controls (170.421997,587.448975) and (169.128998,600.770020)..(172.511993,600.770020) + ..controls (176.468994,599.762024) and (183.020004,599.039001)..(186.979996,599.539001) + ..controls (197.710999,600.770020) and (206.929993,604.078003)..(223.921997,602.500000) + ..controls (231.121002,601.781006) and (238.250000,601.059021)..(245.449005,600.340027) + --cycle; + fill (305.281006,560.948975)..controls (304.628998,560.948975) and (299.949005,561.237976)..(299.378998,561.237976) + ..controls (302.398010,550.440979) and (303.980011,536.468994)..(304.199005,525.309021) + ..controls (303.699005,521.351990) and (299.808990,517.460999)..(299.378998,525.671997) + ..controls (295.851990,530.859009) and (296.421997,540.070007)..(293.398010,540.289001) + ..controls (287.351990,539.640991) and (285.339996,513.218994)..(280.011993,509.328003) + ..controls (276.261993,512.281006) and (280.730011,524.020020)..(275.539001,524.737976) + ..controls (270.500000,524.020020) and (264.308990,526.679993)..(266.691010,534.460999) + ..controls (270.289001,543.020020) and (268.339996,554.762024)..(266.539001,561.601990) + ..controls (262.371002,578.590027) and (264.019989,587.090027)..(271.578003,596.090027) + --(267.480011,604.512024)..controls (275.398010,608.262024) and (285.621002,604.578003)..(290.019989,602.210999) + ..controls (294.621002,600.262024) and (300.238007,595.940979)..(301.101990,587.379028) + ..controls (303.339996,578.879028) and (304.421997,569.737976)..(305.281006,560.948975) + --cycle; + pickup pencircle scaled 2.000000bp; + draw (84.378899,618.551025)..controls (88.339798,624.379028) and (92.589798,622.940979)..(96.339798,615.671997) + ..controls (101.230003,615.601990) and (102.460999,612.429993)..(104.980003,610.781006) + ..controls (122.621002,598.390991) and (147.460999,607.179993)..(167.897995,601.921997) + ..controls (180.940994,598.539001) and (190.871002,599.762024)..(200.089996,602.059021) + ..controls (220.320007,607.250000) and (246.102005,596.159973)..(263.738007,603.859009) + ..controls (274.750000,608.620972) and (284.761993,605.659973)..(292.968994,600.909973) + ..controls (297.578003,597.960999) and (299.589996,596.090027)..(300.960999,591.262024) + ..controls (306.289001,572.539001) and (306.289001,551.020020)..(309.531006,530.570007) + ..controls (309.531006,528.840027) and (312.191010,526.101990)..(312.480011,522.070007) + ..controls (315.789001,511.339996) and (316.078003,510.121002)..(317.160004,502.199005) + ..controls (317.160004,501.339996) and (326.519989,488.449005)..(325.011993,479.019989) + ..controls (323.929993,481.250000) and (323.859009,482.828003)..(321.621002,481.679993) + ..controls (320.328003,479.300995) and (320.898010,473.898010)..(322.558990,471.738007) + ..controls (320.828003,470.808990) and (318.460999,473.468994)..(317.519989,475.199005) + ..controls (318.171997,473.039001) and (317.808990,470.808990)..(316.730011,469.300995) + ..controls (315.859009,472.250000) and (316.578003,473.179993)..(315.359009,473.898010) + ..controls (313.988007,472.898010) and (314.210999,469.300995)..(314.281006,466.199005) + ..controls (313.488007,468.070007) and (311.468994,472.460999)..(312.550995,476.421997) + ..controls (312.480011,484.199005) and (308.808990,489.101990)..(310.320007,499.101990) + ..controls (310.101990,504.429993) and (307.300995,521.059021)..(304.558990,524.301025) + ..controls (303.121002,526.250000) and (306.359009,510.769989)..(306.359009,506.160004) + ..controls (306.648010,500.898010) and (307.078003,468.718994)..(306.429993,463.101990) + ..controls (306.429993,459.218994) and (306.218994,453.960999)..(307.078003,452.160004) + ..controls (308.738007,450.789001) and (309.378998,450.500000)..(309.601990,447.980011) + ..controls (309.238007,446.621002) and (308.738007,446.039001)..(307.730011,445.539001) + ..controls (306.070007,444.601990) and (307.371002,441.789001)..(306.070007,439.851990) + ..controls (304.488007,438.769989) and (304.128998,441.859009)..(303.339996,441.859009) + ..controls (302.691010,441.000000) and (303.050995,437.980011)..(302.468994,436.179993) + ..controls (299.660004,433.800995) and (292.179993,432.500000)..(289.148010,434.660004) + ..controls (289.730011,440.640991) and (291.738007,441.578003)..(295.628998,446.621002) + ..controls (298.660004,452.589996) and (297.000000,460.941010)..(296.929993,468.140991) + ..controls (295.488007,480.378998) and (289.218994,487.300995)..(289.441010,496.441010) + ..controls (287.859009,495.718994) and (286.421997,494.570007)..(284.261993,494.859009) + ..controls (283.390991,489.460999) and (286.421997,484.558990)..(284.828003,480.820007) + ..controls (281.949005,471.960999) and (277.058990,446.621002)..(279.000000,437.761993) + ..controls (280.011993,434.738007) and (278.210999,433.148010)..(277.058990,433.941010) + ..controls (276.769989,433.941010) and (276.550995,433.941010)..(276.410004,433.941010) + ..controls (276.410004,433.941010) and (276.550995,431.421997)..(275.691010,430.921997) + ..controls (274.101990,430.339996) and (273.671997,431.710999)..(272.660004,432.140991) + ..controls (271.218994,430.851990) and (272.519989,429.480011)..(271.148010,428.039001) + ..controls (267.191010,428.039001) and (261.359009,425.378998)..(257.980011,428.261993) + ..controls (257.328003,434.160004) and (263.300995,436.679993)..(266.468994,440.710999) + ..controls (268.628998,446.621002) and (271.078003,462.890991)..(267.769989,474.621002) + ..controls (267.769989,475.558990) and (264.378998,485.281006)..(261.429993,488.660004) + ..controls (258.699005,487.660004) and (257.328003,485.500000)..(253.218994,486.289001) + ..controls (252.578003,484.339996) and (253.300995,482.328003)..(252.218994,480.101990) + ..controls (251.858994,479.519989) and (249.339996,478.578003)..(249.190994,481.390991) + ..controls (248.979996,483.050995) and (248.897995,486.359009)..(248.261993,486.718994) + ..controls (243.647995,486.718994) and (233.710999,487.078003)..(231.770004,493.921997) + ..controls (219.891006,492.339996) and (215.929993,491.261993)..(206.570007,493.421997) + ..controls (196.628998,489.671997) and (183.238007,506.160004)..(174.531006,502.199005) + ..controls (172.511993,496.148010) and (173.089996,485.640991)..(171.647995,481.390991) + ..controls (169.339996,474.769989) and (171.141006,467.140991)..(171.141006,456.410004) + ..controls (170.570007,455.398010) and (169.852005,454.460999)..(168.479996,454.460999) + ..controls (168.479996,453.101990) and (169.339996,450.859009)..(168.621002,449.421997) + ..controls (167.179993,447.621002) and (165.891006,451.800995)..(165.020004,444.601990) + ..controls (163.147995,443.738007) and (157.750000,442.218994)..(155.589996,445.179993) + ..controls (155.878998,448.988007) and (158.328003,451.300995)..(160.128998,453.378998) + ..controls (161.421997,456.910004) and (160.988007,458.281006)..(160.699005,461.808990) + ..controls (160.988007,464.980011) and (161.710999,468.578003)..(161.858994,470.089996) + ..controls (161.858994,473.039001) and (162.500000,479.300995)..(161.141006,481.179993) + --(159.410004,482.691010)..controls (157.179993,487.218994) and (158.328003,494.640991)..(157.608994,500.261993) + ..controls (155.809006,500.691010) and (155.809006,500.980011)..(154.011993,498.308990) + ..controls (154.011993,494.421997) and (153.500000,486.359009)..(152.352005,483.839996) + ..controls (149.690994,479.808990) and (150.839996,459.648010)..(151.421997,448.558990) + ..controls (151.781006,446.468994) and (149.690994,447.699005)..(149.761993,444.738007) + ..controls (150.050995,442.800995) and (147.891006,443.589996)..(146.089996,444.601990) + ..controls (145.147995,445.179993) and (146.589996,439.781006)..(145.371002,439.558990) + ..controls (142.339996,438.839996) and (136.871002,438.191010)..(135.218994,440.710999) + ..controls (134.570007,444.601990) and (137.878998,448.058990)..(140.621002,451.011993) + ..controls (143.141006,455.828003) and (140.897995,465.699005)..(140.468994,476.281006) + --(138.891006,478.218994)..controls (134.858994,483.191010) and (139.608994,496.941010)..(136.511993,506.230011) + ..controls (120.019997,514.870972) and (122.109001,519.190979)..(118.730003,537.620972) + ..controls (115.128998,557.640991) and (93.378899,567.648010)..(79.058601,567.648010) + ..controls (73.441399,563.039001) and (66.238297,563.620972)..(58.539101,567.648010) + ..controls (55.660198,569.229980) and (54.429699,573.190979)..(54.500000,576.500000) + ..controls (52.628899,580.750000) and (55.218800,582.190979)..(59.621101,583.487976) + ..controls (62.710899,587.809021) and (68.621101,594.648010)..(69.191399,597.737976) + ..controls (70.339798,601.921997) and (75.531303,608.109009)..(77.761703,609.770020) + ..controls (75.820297,613.012024) and (74.808601,615.171997)..(77.109398,618.551025) + ..controls (79.558601,620.140991) and (81.789101,616.609009)..(84.378899,618.551025) + --cycle; +) ; diff --git a/metapost/context/base/mpiv/mp-crop.mpiv b/metapost/context/base/mpiv/mp-crop.mpiv new file mode 100644 index 000000000..00bcdcb44 --- /dev/null +++ b/metapost/context/base/mpiv/mp-crop.mpiv @@ -0,0 +1,194 @@ +%D \module +%D [ file=mp-crop.mpiv, +%D version=2011.06.23, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=Cropmarks, +%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_crop : endinput ; fi ; + +boolean context_crop ; context_crop := true ; + +vardef crop_marks_lines (expr box, len, offset, nx, ny) = + save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ; + p := image ( + x := if nx = 0 : 1 else : nx - 1 fi ; + y := if ny = 0 : 1 else : ny - 1 fi ; + w := bbwidth (box) / x ; + h := bbheight(box) / y ; + for i=0 upto y : + draw ((llcorner box) -- (llcorner box) shifted (-len,0)) shifted (-offset,i*h) ; + draw ((lrcorner box) -- (lrcorner box) shifted ( len,0)) shifted ( offset,i*h) ; + endfor ; + for i=0 upto x : + draw ((llcorner box) -- (llcorner box) shifted (0,-len)) shifted (i*w,-offset) ; + draw ((ulcorner box) -- (ulcorner box) shifted (0, len)) shifted (i*w, offset) ; + endfor ; + ) ; + setbounds p to box ; + p +enddef ; + +vardef crop_marks_cmyk = + save p ; picture p ; p := image ( + fill ulcircle scaled 12.5 withcolor (1,0,0,0) ; + fill urcircle scaled 12.5 withcolor (0,1,0,0) ; + fill lrcircle scaled 12.5 withcolor (0,0,1,0) ; + fill llcircle scaled 12.5 withcolor (0,0,0,1) ; + draw (-10,0) -- (10,0) ; + draw (0,-10) -- (0,10) ; + draw fullcircle scaled 12.5 ; + ) ; + setbounds p to fullsquare scaled 20 ; + p +enddef ; + +vardef crop_marks_gray = + save p ; picture p ; p := image ( + fill ulcircle scaled 12.5 withcolor (0.00) ; + fill urcircle scaled 12.5 withcolor (0.25) ; + fill lrcircle scaled 12.5 withcolor (0.50) ; + fill llcircle scaled 12.5 withcolor (0.75) ; + draw (-10,0) -- (10,0) ; + draw (0,-10) -- (0,10) ; + draw (-6,0) -- (6,0) withcolor white ; + draw (0,-6) -- (0,6) withcolor white ; + draw fullcircle scaled 12.5 ; + ) ; + setbounds p to fullsquare scaled 20 ; + p +enddef ; + +vardef crop_marks_cmykrgb = + save p ; picture p ; p := image ( + fill ulcircle scaled 15 withcolor (1,0,0) ; + fill urcircle scaled 15 withcolor (0,1,0) ; + fill lrcircle scaled 15 withcolor (0,0,1) ; + fill llcircle scaled 15 withcolor (.5,.5,.5) ; + fill ulcircle scaled 10 withcolor (1,0,0,0) ; + fill urcircle scaled 10 withcolor (0,1,0,0) ; + fill lrcircle scaled 10 withcolor (0,0,1,0) ; + fill llcircle scaled 10 withcolor (0,0,0,1) ; + draw (-10,0) -- (10,0) ; + draw (0,-10) -- (0,10) ; + draw fullcircle scaled 10 ; + draw fullcircle scaled 15 ; + ) ; + setbounds p to fullsquare scaled 20 ; + p +enddef ; + +vardef crop_color(expr c, h, w, dx, dy, ts) = + image ( + save p ; path p ; + for i=1 upto 6 : + p := fullsquare + xscaled w + yscaled h + shifted (dx,dy-i*h) ; + fill p + withcolor (crop_colors[i]*c) ; + draw textext("\format{'@0.2f'," & decimal crop_colors[i] & "}") + scaled ts + shifted center p withcolor white ; + endfor ; + ) +enddef ; + +vardef crop_gray(expr c, h, w, dx, dy, ts) = + image ( + save p ; path p ; + for i=.05 step .05 until 1 : + p := fullsquare + xscaled w + yscaled h + shifted (20*(i-1)*w+dx,dy) ; + fill p + withcolor (i*c) ; + draw textext("\format{'@0.2f'," & decimal i & "}") + scaled ts + shifted center p withcolor white ; + endfor ; + ) +enddef ; + +% draw crop_marks_cmyk shifted llcorner more ; +% draw crop_marks_cmyk shifted lrcorner more ; +% draw crop_marks_cmyk shifted ulcorner more ; +% draw crop_marks_cmyk shifted urcorner more ; + +def page_marks_add_color(expr width, height, length, offset) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + numeric crop_colors[] ; + crop_colors[1] := 1 ; + crop_colors[2] := 0.95 ; + crop_colors[3] := 0.75 ; + crop_colors[4] := 0.50 ; + crop_colors[5] := 0.25 ; + crop_colors[6] := 0.05 ; + + numeric h ; h := height / 20 ; + numeric w ; w := width / 20 ; + numeric d ; d := offset + length/2 ; + + draw crop_color((1,0,0,0),h,length,xpart ulcorner page - d, 10h,length/20) ; + draw crop_color((0,1,0,0),h,length,xpart ulcorner page - d,3.5h,length/20) ; + draw crop_color((0,0,1,0),h,length,xpart ulcorner page - d, -3h,length/20) ; + + draw crop_color((0,1,1,0),h,length,xpart urcorner page + d, 10h,length/20) ; + draw crop_color((1,0,1,0),h,length,xpart urcorner page + d,3.5h,length/20) ; + draw crop_color((1,1,0,0),h,length,xpart urcorner page + d, -3h,length/20) ; + + draw crop_gray((0,0,0,1),length, w,-xpart llcorner page,-ypart llcorner page + d ,w/20) ; + draw crop_gray((1,0,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d + 1length/3,w/20) ; + draw crop_gray((0,1,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 0length/3,w/20) ; + draw crop_gray((0,0,1,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 1length/3,w/20) ; + + setbounds currentpicture to page ; + +enddef ; + +def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + draw crop_marks_gray shifted center(topboundary more) shifted (0, offset+length); + draw crop_marks_cmyk shifted center(bottomboundary more) shifted (0,-offset-length); + + setbounds currentpicture to page ; + +enddef ; + +def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + draw crop_marks_lines(page,length,offset,nx,ny) ; + + setbounds currentpicture to page ; + +enddef ; + +def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace + + path page ; page := fullsquare xscaled width yscaled height ; + path more ; more := page enlarged (offset+length/2,offset+length/2) ; + + for s=llcorner more, lrcorner more, ulcorner more, urcorner more : + draw textext(decimal n) shifted s ; + endfor ; + + setbounds currentpicture to page ; + +enddef ; diff --git a/metapost/context/base/mpiv/mp-figs.mpiv b/metapost/context/base/mpiv/mp-figs.mpiv new file mode 100644 index 000000000..aac7c5ad2 --- /dev/null +++ b/metapost/context/base/mpiv/mp-figs.mpiv @@ -0,0 +1,47 @@ +%D \module +%D [ file=mp-figs.mpiv, +%D version=2003.01.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=figures, +%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_figs : endinput ; fi ; + +boolean context_figs ; context_figs := true ; + +% todo: check defined + +def registerfigure(expr name,width,height) = + begingroup ; + save s ; string s ; s := cleanstring(name) ; + scantokens( s & "_width := " & decimal(width )) ; + scantokens( s & "_height := " & decimal(height)) ; + endgroup ; +enddef ; + +vardef figuresize(expr name) = + save s, p ; string s ; pair p ; + s := cleanstring(name) ; + scantokens( "p := " & "(" & s & "_width" & "," & s & "_height" & ")" ) ; + p +enddef ; + +vardef figurewidth(expr name) = + xpart figuresize(name) +enddef ; + +vardef figureheight(expr name) = + ypart figuresize(name) +enddef ; + +let figuredimensions = figuresize ; % for old times sake + +def naturalfigure(expr name) = + externalfigure name xyscaled(figuresize(name)) +enddef ; diff --git a/metapost/context/base/mpiv/mp-fobg.mpiv b/metapost/context/base/mpiv/mp-fobg.mpiv new file mode 100644 index 000000000..f8b709572 --- /dev/null +++ b/metapost/context/base/mpiv/mp-fobg.mpiv @@ -0,0 +1,87 @@ +%D \module +%D [ file=mp-fobg.mp, +%D version=2004.03.12, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=Formatting Objects, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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_fobg : endinput ; fi ; + +boolean context_fobg ; context_fobg := true ; + +FoNone := 0 ; FoHidden := 1 ; FoDotted := 2 ; FoDashed := 3 ; FoSolid := 4 ; +FoDouble := 5 ; FoGroove := 6 ; FoRidge := 7 ; FoInset := 8 ; FoOutset := 9 ; +FoAll := 0 ; FoTop := 1 ; FoBottom := 2 ; FoLeft := 3 ; FoRight := 4 ; +FoMedium := .5pt ; FoThin := FoMedium/2 ; FoThick := FoMedium*2 ; + +color FoBackgroundColor, FoNoColor, FoLineColor[] ; FoNoColor := (-1,-1,-1) ; +numeric FoLineWidth[], FoLineStyle[] ; +boolean FoFrame, FoBackground, FoSplit ; + +FoFrame := FoBackground := FoSplit := false ; +FoBackgroundColor := white ; +FoDashFactor := .5 ; +FoDotFactor := .375 ; + +for i = FoAll upto FoRight : + FoLineColor[i] := black ; + FoLineWidth[i] := .5pt ; + FoLineStyle[i] := FoNone ; +endfor ; + +def DrawFoFrame(expr n, p) = + drawoptions(withcolor FoLineColor[n] withpen pencircle scaled FoLineWidth[n]) ; + if FoLineStyle[n] = FoNone : + % nothing + elseif FoLineStyle[n] = FoHidden : + % nothing + elseif FoLineStyle[n] = FoDotted : + draw p dashed (withdots scaled (FoDotFactor*FoLineWidth[n])) ; + elseif FoLineStyle[n] = FoDashed : + draw p dashed (evenly scaled (FoDashFactor*FoLineWidth[n])) ; + elseif FoLineStyle[n] = FoSolid : + draw p ; + elseif FoLineStyle[n] = FoDouble : + draw p enlarged FoLineWidth[n] ; draw p enlarged -FoLineWidth[n] ; + elseif FoLineStyle[n] = FoGroove : + draw p ; + draw p withpen pencircle scaled .5FoLineWidth[n] withcolor (inverted FoLineColor[n] softened .5) ; + elseif FoLineStyle[n] = FoRidge : + draw p withcolor (inverted FoLineColor[n] softened .5) ; + draw p withpen pencircle scaled .5FoLineWidth[n] ; + elseif FoLineStyle[n] = FoInset : + draw p ; draw p inset 2.5FoLineWidth[n] ; + elseif FoLineStyle[n] = FoOutset : + draw p ; draw p outset 2.5FoLineWidth[n] ; + fi ; +enddef ; + +primarydef p outset d = + ((lrcorner p -- urcorner p -- ulcorner p -- llcorner p -- cycle) + shifted (d*(-1,1)) cutbefore topboundary p) cutafter leftboundary p +enddef ; + +primarydef p inset d = + ((ulcorner p -- llcorner p -- lrcorner p -- urcorner p -- cycle) + shifted (d*(1,-1)) cutbefore bottomboundary p) cutafter rightboundary p +enddef ; + +vardef equalpaths(expr p, q) = + if length(p) = length(q) : + save ok ; boolean ok ; ok := true ; + for i = 0 upto length(p)-1 : + ok := ok and (round(point i of p) = round(point i of q)) ; + endfor ; + ok + else : + false + fi +enddef ; + +endinput ; diff --git a/metapost/context/base/mpiv/mp-form.mpiv b/metapost/context/base/mpiv/mp-form.mpiv new file mode 100644 index 000000000..88b15e097 --- /dev/null +++ b/metapost/context/base/mpiv/mp-form.mpiv @@ -0,0 +1,30 @@ +%D \module +%D [ file=mp-form.mpiv, +%D version=2011.10.14, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=form support, +%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. + +% The graph package will be replaced by our own variant using +% MetaPost 2 features and textext. + +if known context_form : endinput ; fi ; + +boolean context_form ; context_form := true ; + +string Fmfont_ ; Fmfont_ := "crap" ; + +% The following function accept a number or string that can be +% converted to a number by \LUA. The first argument is a format +% where @ can be used instead of %. The number is typeset in math +% mode and @3e is converted into @.3e. + +vardef mfun_format_number(expr fmt, i) = + "\ctxlua{metapost.formatnumber('" & fmt & "'," & if string i : i else : decimal i fi & ")}" +enddef ; diff --git a/metapost/context/base/mpiv/mp-func.mpiv b/metapost/context/base/mpiv/mp-func.mpiv new file mode 100644 index 000000000..b1b9d6d5d --- /dev/null +++ b/metapost/context/base/mpiv/mp-func.mpiv @@ -0,0 +1,87 @@ +%D \module +%D [ file=mp-func.mpiv, +%D version=2001.12.29, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=function hacks, +%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. + +%D Under construction. + +if known context_func : endinput ; fi ; + +boolean context_func ; context_func := true ; + +string mfun_pathconnectors[] ; + +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(c) + fi + (scantokens(u),scantokens(t)) + endfor +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(c) + else : + ok := true ; + fi + i + endfor +enddef ; + +def constructedpath = mfun_constructedpath enddef ; % let doesn't work here +def straightpath = mfun_constructedpath (1) enddef ; +def curvedpath = mfun_constructedpath (2) 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(c) + fi + p[i] + endfor +enddef ; + +def constructedpairs = mfun_constructedpairs enddef ; % let doesn't work here +def straightpairs = mfun_constructedpairs (1) enddef ; +def curvedpairs = mfun_constructedpairs (2) 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/mpiv/mp-grap.mpiv b/metapost/context/base/mpiv/mp-grap.mpiv new file mode 100644 index 000000000..4fd8ee5bd --- /dev/null +++ b/metapost/context/base/mpiv/mp-grap.mpiv @@ -0,0 +1,1706 @@ +%D \module +%D [ file=mp-grap.mpiv, +%D version=2012.10.16, % 2008.09.08 and earlier, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=graph packagesupport, +%D author=Hans Hagen \& Alan Braslau, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +if known context_grap : endinput ; fi ; + +boolean context_grap ; context_grap := true ; + +% Below is a modified graph.mp + +show numbersystem, numberprecision ; + +%if epsilon/4 = 0 : +if numbersystem <> "double" : + errmessage "The graph macros require the double precision number system." ; + endinput ; +fi + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% $Id : graph.mp,v 1.2 2004/09/19 21 :47 :10 karl Exp $ +% Public domain. + +% Macros for drawing graphs + +% begingraph(width,height) begin a new graph +% setcoords(xtype,ytype) sets up a new coordinate system (log,-linear..) +% setrange(lo,hi) set coord ranges (numeric and string args OK) +% gdraw [with...] draw a line in current coord system +% gfill [with...] fill a region using current coord system +% gdrawarrow .., gdrawdblarrow.. like gdraw, but with 1 or 2 arrowheads +% augment(loc) append given coordinates to a polygonal path +% glabel(pic,loc) place label pic near graph coords or time loc +% gdotlabel(pic,loc) same with dot +% OUT loc value for labels relative to whole graph +% gdata(file,s,text) read coords from file ; evaluate t w/ tokens s[] +% auto. default x or y tick locations (for interation) +% tick.(fmt,u) draw centered tick from given side at u w/ format +% itick.(fmt,u) draw inward tick from given side at u w/ format +% otick.(fmt,u) draw outward tick at coord u ; label format fmt +% grid.(fmt,u) draw grid line at u with given side labeled +% autogrid([itick|.. bot|..],..) iterate over auto.x, auto.y, drawing tick/grids +% frame.[bot|top..] draw frame (or one side of the frame) +% graph_frame_needed := false ; after begingraph, not to draw a frame at all +% graph_background := color ; fill color for frame, if defined +% endgraph end of graph--the result is a picture + +% option `plot ' draws picture at each path knot, turns off pen +% graph_template. template paths for tick marks and grid lines +% graph_margin_fraction.low, +% graph_margin_fraction.high fractions determining margins when no setrange +% graph_log_marks[], graph_lin_marks, graph_exp_marks loop text strings used by auto. +% graph_minimum_number_of_marks, graph_log_minimum numeric parameters used by auto. +% Autoform is the format string used by autogrid +% Autoform_X, Autoform_Y if defined, are used instead + +% Other than the above-documented user interface, all externally visible names +% are of the form X_., Y_., or Z_., or they start +% with `graph_' + +% 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 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 + else: mexp(x) fi +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 + else: 10**x fi +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 : + save e, m ; e=floor(x/mlogten)-3; m := mexp(x-e*mlogten) ; + if abs m<1000 : m := m*10 ; e := e-1 ; elseif abs m>=10000 : m := m/10 ; e := e+1 ; fi + (m, e) + fi +enddef ; + +% Modified from above. + +vardef graph_Feform(expr x) = + interim warningcheck :=0 ; + if x=0 : origin + else : + save e, m ; e=floor(if x<0 : -mlog(-x) else : mlog(x) fi/mlogten)-3; m := x/(10**e) ; + if abs m<1000 : m := m*10 ; e := e-1 ; elseif abs m>=10000 : m := m/10 ; e := e+1 ; fi + (m, e) + fi +enddef ; + +vardef graph_error(expr x,s) = + interim showstopping :=0 ; + show x ; errmessage s ; +enddef ; + +%%%%%%%%%%%%%%%%%%%%%%%% Data structures, begingraph %%%%%%%%%%%%%%%%%%%%%%%% + +vardef Z_@# = (X_@#,Y_@#) enddef ; % used in place of plain.mp's z convention + +def graph_suffix(suffix $) = % convert from x or y to X_ or Y_ + if str$="x" : X_ else : Y_ fi +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 ; + +def begingraph(expr w, h) = + begingroup + save X_, Y_ ; + X_.graph_coordinate_type = + Y_.graph_coordinate_type = linear ; % coordinate system for each axis + Z_.graph_dimensions = (w,h) ; % dimensions of graph not counting axes etc. + %also, Z_.low, Z_.high user-specified coordinate ranges in units used in graph_current_graph + + save graph_finished_graph ; + picture graph_finished_graph ; % the finished part of the graph + graph_finished_graph = nullpicture ; + save graph_current_graph ; + picture graph_current_graph ; % what has been drawn in current coords + graph_current_graph = nullpicture ; + save graph_current_bb ; + picture graph_current_bb ; % picture whose bbox is graph_current_graph's w/ linewidths 0 + graph_current_bb = nullpicture ; + save graph_last_drawn ; + picture graph_last_drawn ; % result of last gdraw or gfill + graph_last_drawn = nullpicture ; + save graph_last_path ; + path graph_last_path ; % last gdraw or gfill path in data coordinates. + save graph_plot_picture ; + picture graph_plot_picture ; % a picture from the `plot' option known when plot allowed + save graph_foreground ; + color graph_foreground ; % drawing color, if set. + save graph_label ; + picture graph_label[] ; % labels to place around the whole graph when it is done + save graph_autogrid_needed ; + boolean graph_autogrid_needed ; % whether autogrid is needed + graph_autogrid_needed = true ; + save graph_frame_needed ; + boolean graph_frame_needed ; % whether frame needs to be drawn + graph_frame_needed = true ; + save graph_number_of_arrowheads ; % number of arrowheads for next gdraw + graph_number_of_arrowheads = 0 ; + + if known graph_background : % new feature! + fill origin--(w,0)--(w,h)--(0,h)--cycle withcolor graph_background ; + fi +enddef ; + +% Additional variables not explained above : +% graph_modified_lower, graph_modified_higher pairs giving bounds used in auto +% graph_exponent, graph_comma variables and macros used in auto +% graph_modified_bias +% an offset to graph_modified_lower and graph_modified_higher to ease computing exponents +% Some additional variables function as constants. Most can be modified by the +% user to alter the behavior of these macros. +% Not very modifiable : log, linear, +% graph_frame_pair_a, graph_frame_pair_b, graph_margin_pair +% 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 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 : +% log means internal graph coords = mlog(user graph coords) +% -log means internal graph coords = -mlog(user graph coords) +% linear means internal graph coords = (user graph coords) +% -linear means internal graph coords = -(user graph coords) + + +vardef graph_set_default_bounds = % Set default Z_.low, Z_.high + forsuffixes $=low,high : + (if known X_$ : whatever else : X_$ fi, if known Y_$ : whatever else : Y_$ fi) + = graph_margin_fraction$[llcorner graph_current_bb,urcorner graph_current_bb] + + 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. + +vardef graph_remap(suffix $,$$,$$$) = + save p_ ; + graph_set_default_bounds ; + pair p_, $ ; $=-Z_.low; + p_ = (max(X_.high-X_.low,.9), max(Y_.high-Y_.low,.9)) ; + transform $$, $$$ ; + forsuffixes #=$$,$$$ : xpart#=ypart#=xypart#=yxpart#=0 ; endfor + (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 : + false + elseif colormodel q=3 : + (greypart q) + elseif colormodel q=5 : + (redpart q, greenpart q, bluepart q) + elseif colormodel q=7 : + (cyanpart q, magentapart q, yellowpart q, blackpart q) + fi +enddef ; + +% Add picture component q to picture @# and change part p to tp, +% where p is something from q that needs coordinate transformation. +% The type of p is pair or path. +% 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 : +% path p ; p=pathpart q; +% addto @# doublepath tp graph_with_pen_and_color(q) dashed dashpart q ; +% elseif filled q : +% path p ; p=pathpart q; +% addto @# contour tp graph_with_pen_and_color(q) ; +% else : +% interim truecorners :=0 ; +% pair p ; p=llcorner q; +% if urcorner q<>p : p := p + graph_coordinate_multiplication(o-p,urcorner q-p) ; fi +% 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 ; + picture tp_clipped ; tp_clipped := nullpicture; + if stroked q : + path p ; p=pathpart q; + addto tp_clipped doublepath tp graph_with_pen_and_color(q) dashed dashpart q ; + %draw bbox tp_clipped withcolor red ; + elseif filled q : + path p ; p=pathpart q; + addto tp_clipped contour tp graph_with_pen_and_color(q) ; + %draw bbox tp_clipped withcolor green ; + else : + if (urcorner q<>llcorner q) : do_clip := false ; fi % Do not clip the axis labels; + interim truecorners := 0 ; + pair p ; p=llcorner q; + if urcorner q<>p : p := p + graph_coordinate_multiplication(o-p,urcorner q-p) ; fi + addto tp_clipped also q shifted ((tp)-llcorner q) ; + %draw bbox tp_clipped withcolor if do_clip : cyan else : blue fi ; + fi + if do_clip : + clip tp_clipped to origin--(xpart Z_.graph_dimensions,0)--Z_.graph_dimensions-- + (0,ypart Z_.graph_dimensions)--cycle ; + fi + addto @# also tp_clipped ; +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 : + save s, S, T ; + graph_remap(s, S, T) ; + for q within graph_current_graph : + graph_picture_conversion.graph_finished_graph(q,-s,p shifted s transformed S transformed T) ; + endfor + graph_current_graph := graph_current_bb := nullpicture ; + fi + graph_clear_bounds.X_ ; graph_clear_bounds.Y_; + 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; + string r_[]s ; + for x_= + for p_=t : if pair p_ : xpart p_, ypart fi p_, endfor : + r_[incr r_] if string x_ : s fi = x_ ; + if r_>2 : + graph_set_bounds if r_=3 : X_ else : Y_ fi (r_[r_-2] if unknown r_[r_-2] : s fi, x_) ; + fi + exitif r_=4 ; + 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 : + @#low = if unknown l : + whatever + else : + if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l + fi ; + @#high = if unknown h : + whatever + else : + if abs @#graph_coordinate_type=log : graph_mlog fi if string h : scantokens fi h + fi ; + else : + -@#high = if unknown l : + whatever + else : + if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l + fi ; + -@#low = if unknown h : + whatever + else : + if abs @#graph_coordinate_type=log : graph_mlog fi if string h : scantokens fi h + fi ; + 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 : + save r_ ; path r_; + r_ := graph_pair_adjust(point 0 of p, tx, ty) + if path p : + for t=1 upto length p : + if c : -- + else : ..controls graph_pair_adjust(postcontrol(t-1) of p, tx, ty) + and graph_pair_adjust(precontrol t of p, tx, ty) .. + fi + graph_pair_adjust(point t of p, tx, ty) + endfor + if cycle p : &cycle fi + fi ; + 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 ; + +% Convert path p from user graph coords to internal graph coords. + +vardef graph_convert_user_path_to_internal primary p = + interim warningcheck :=0 ; + 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 ; + if 0 for x_=t_ : +1 if pair x_ : +1 fi endfor <= 1 : + t_ + else : + n_0 = n_1 = 0 ; + point 0 of graph_convert_user_path_to_internal ( + for x_= + for y_=t_ : if pair y_ : xpart y_, ypart fi y_, endfor + 0, 0 : + if known x_ : if string x_ : scantokens fi x_ + else : hide(n_[n_] :=whatever) 0 + fi + exitif incr n_=2 ; + ,endfor) + (n_0,n_1) + 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 ' 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 := graph_loptok s_ ; + n_ = if @#1="%" : 0 else : 1 fi ; + forever : + @#[incr n_] := graph_loptok s_ ; + exitif @#[n_]="" ; + endfor + @#1<>"" + else : false + 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 ; % not used? + for i=1 upto largestmantissa : + exitunless graph_read_line$(f) ; + c + endfor + if graph_close_file : + closefrom f ; + 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 ; + gdata(f, s, if i>1 :--fi + if s2="" : ( i, scantokens s1) + else : (scantokens s1, scantokens s2) fi + ) +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 : + graph_error(begingroup @# endgroup, "Cannot augment--not a path") ; + else : + def graph_comma= hide(def graph_comma=,enddef) enddef ; + if known @# : @# :=@#-- else : @#= fi + (for p=t : + graph_comma if string p : scantokens fi p + endfor) ; + 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 ; + else : + save x,y ; + z = llcorner graph_current_bb ; + if unknown xpart p : xpart p= else : x := fi 0 ; + if unknown ypart p : ypart p= else : y := fi 0 ; + addto graph_current_bb doublepath (p+z) ; + fi + graph_current_bb := image(fill llcorner graph_current_bb..urcorner graph_current_bb--cycle) ; +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 ; + path graph_last_path ; + 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. + +def graph_draw expr p = + if string p : hide(graph_last_path := graph_readpath(p) ;) + graph_convert_user_path_to_internal graph_last_path + elseif path p or pair p : + hide(graph_last_path := p ;) + graph_convert_user_path_to_internal p + else : graph_error(p,"gdraw argument should be a data file or a path") + origin + fi + withpen currentpen graph_withlist _op_ +enddef ; + +% 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 + elseif cycle p : hide(graph_last_path := p ;) + graph_convert_user_path_to_internal p + else : graph_error(p,"gfill argument should be a data file or a cyclic path") + origin..cycle + fi graph_withlist _op_ +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 = + hide( + def graph_errorbar_text = t enddef ; + save pic ; picture pic ; pic := image(draw origin _op_ options ;) ; + if color colorpart pic : graph_foreground := colorpart pic ; fi + ) + 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 ;) ; + +vardef graph_errorbars(text t) = + if known graph_last_path : + save n, p, q ; path p ; pair q ; + save pic ; picture pic[] ; pic0 := nullpicture ; + pic1 := if known graph_xbar_picture : graph_xbar_picture + elseif known graph_errorbar_picture : graph_errorbar_picture rotated 90 + else : nullpicture fi ; + pic2 := if known graph_ybar_picture : graph_ybar_picture + elseif known graph_errorbar_picture : graph_errorbar_picture + else : nullpicture fi ; + if length pic1>0 : + pic1 := pic1 scaled graph_shapesize ; + setbounds pic1 to origin..cycle ; + fi + if length pic2>0 : + pic2 := pic2 scaled graph_shapesize ; + setbounds pic2 to origin..cycle ; + fi + for i=0 upto length graph_last_path : + clearxy ; z = point i of graph_last_path ; + n := 1 ; + for $=t : + if known $ : + q := if path $ : if length $>i : point i of $ else : origin fi + elseif pair $ : $ elseif numeric $ : ($,$) else : origin fi ; + if q<>origin : + p := graph_convert_user_path_to_internal (( + if n=1 : + (-xpart q,0)--(ypart q,0) + else : + (0,-xpart q)--(0,ypart q) + fi ) shifted z) ; + addto pic0 doublepath p ; + if length pic[n]>0 : + if ypart q<>0 : + addto pic0 also pic[n] shifted point 1 of p ; + fi + if xpart q<>0 : + addto pic0 also pic[n] rotated 180 shifted point 0 of p ; + fi + fi + fi + fi + exitif incr n>3 ; + endfor + endfor + if length pic0>0 : + save bg, fg ; color bg, fg ; + bg := if known graph_background : graph_background else : background fi ; + fg := if known graph_foreground : graph_foreground else : black fi ; + addto graph_current_graph also pic0 withpen currentpen scaled 2 _op_ withcolor bg ; + addto graph_current_graph also pic0 withpen currentpen scaled .5 _op_ withcolor fg ; + fi + fi +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 + hide (graph_plot_picture := image( + if bounded p : for q within p : graph_addto_currentpicture q endfor % Save memory + else : graph_addto_currentpicture p + fi graph_setbounds origin..cycle)) + fi +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; + +% 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 ; + 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 ; + fi + graph_errorbars(graph_errorbar_text) ; + if length graph_plot_picture>0 : + for i=0 upto length p if cycle p : -1 fi : + addto graph_current_graph also graph_plot_picture shifted point i of p ; + endfor + picture graph_plot_picture ; + fi + if graph_number_of_arrowheads>0 : + graph_draw_arrowhead(p, graph_with_pen_and_color(graph_last_drawn)) ; + 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 ; + fi +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(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) = + if p<>q : (q - 100pt*unitvector(q-p)) -- fi + q +enddef ; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Drawing labels %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Argument c is a drawing command that needs an additional argument p that gives +% a location in internal graph coords. Draw in graph_current_graph enclosed in a setbounds +% 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) ; + graph_unknown_pair_bbox(p) ; + addto graph_current_graph also + 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) + else : graph_stash_label + 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 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; + +vardef itick@#(expr f,u) text w = graph_tick_label(@#,@,false,f,u,w) ; enddef; + +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 $, 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) +enddef ; + +% Generate label positioning arguments appropriate for label suffix $ and +% coordinate u. + +def graph_generate_label_position(suffix $)(expr u) = + 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 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 = 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 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 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); + +%%%%%%%%%%%%%%%%%%%%%%%%%% Automatic grid selection %%%%%%%%%%%%%%%%%%%%%%%%%% + +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 + +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 +% type of grid spacing to use. Bounds are returned in variables local to +% begingraph..endgraph : pairs graph_modified_lower and graph_modified_higher +% are upper and lower bounds in +% `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 ; + graph_set_default_bounds ; + if @#graph_coordinate_type>0 : (l,h) else : -(h,l) fi = (@#low, @#high) ; + 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 >= 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. + +def graph_scan_marks(expr k, l, h)(text t) = + for m=scantokens graph_log_marks[k] : + exitif m>h ; + if m>=l : t fi + endfor +enddef ; + +% 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, + if e= graph_minimum_number_of_marks ; + endfor + k +enddef ; + +% 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 graph_exp_marks : + @# = e ; + exitif floor(ypart graph_modified_higher/e) - + floor(graph_modified_exponent_ypart(graph_modified_lower)/e) + >= graph_minimum_number_of_marks ; + numeric @# ; + endfor + known @# +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 = 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 graph_lin_marks : + d = n*x ; + exitif 0 graph_generate_numbers(d,+1)>=m ; + numeric d ; + endfor + fi + 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 ; + e+3 = if graph_modified_lower=graph_modified_bias : ypart graph_modified_higher + elseif graph_modified_higher=graph_modified_bias : ypart graph_modified_lower + else : max(ypart graph_modified_lower, ypart graph_modified_higher) fi ; + forsuffixes $=graph_modified_lower, graph_modified_higher : + $ := (xpart $ for i=ypart $ upto e+2 : /(10) endfor, e) ; + endfor + 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 + elseif e>=0 : + if abs m=.1 : x else : decimal m & "e" & decimal e fi + fi +enddef ; + +def auto suffix $ = + hide(def graph_comma= hide(def graph_comma=,enddef) enddef) + if graph_bounds.graph_suffix($)=log : + if graph_select_exponent_mark.graph_exponent : + graph_generate_exponents(graph_exponent, + graph_comma graph_factor_and_exponent_to_string(1,e)) + else : + graph_scan_mark(graph_select_mark, graph_modified_lower, graph_modified_higher, + graph_comma graph_factor_and_exponent_to_string(m,e)) + fi + else : + hide(graph_exponent :=graph_match_exponents) + graph_generate_numbers(graph_tick_mark_spacing, + graph_comma graph_factor_and_exponent_to_string(m,graph_exponent)) + fi +enddef ; + +string Autoform ; Autoform = "%g"; + +%vardef autogrid(suffix tx, ty) text w = +% graph_autogrid_needed :=false ; +% if str tx<>"" : for x=auto.x : tx(Autoform,x) w ; endfor fi +% if str ty<>"" : for y=auto.y : ty(Autoform,y) w ; endfor fi +%enddef ; + +% We redefine autogrid, adding the possibility of differing X and Y +% formats. + +% string Autoform_X ; Autoform_X := "@.0e" ; +% string Autoform_Y ; Autoform_Y := "@.0e" ; + +vardef autogrid(suffix tx, ty) text w = + graph_autogrid_needed := false ; + if str tx <> "" : + for x=auto.x : + tx ( + if string Autoform_X : + if Autoform_X <> "" : + Autoform_X + else : + Autoform + fi + else : + Autoform + fi, + x + ) w ; + endfor + fi + if str ty <> "" : + for y=auto.y : + ty ( + if string Autoform_Y : + if Autoform_Y <> "" : + Autoform_Y + else : + Autoform + fi + else : + Autoform + fi, + y + ) w ; + endfor + fi +enddef ; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% endgraph %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +def endgraph = + if graph_autogrid_needed : autogrid(otick.bot, otick.lft) ; fi + if graph_frame_needed : frame ; fi + setcoords(linear,linear) ; + interim truecorners :=1 ; + for b=bbox graph_finished_graph : + setbounds graph_finished_graph to b ; + for i=0 step .5 until 3.5 : + if known graph_label[i] : + addto graph_finished_graph also graph_label[i] shifted point i of b ; + fi + endfor + endfor + graph_finished_graph + endgroup +enddef ; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% We format in luatex (using \mathematics{}) ... +% we could pass via variables and save escaping as that is inefficient + +if unknown context_mlib : + + 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 ; + + 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 format (expr f, x) = textext(strfmt(f,x)) enddef ; + vardef formatted(expr f, x) = textext(varfmt(f,x)) enddef ; + +fi ; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% A couple of extensions : + +% Define a function plotsymbol() returning a picture : 10 different shapes, +% unfilled outline, interior filled with different shades of the background. +% This allows overlapping points on a plot to be more distinguishable. + +vardef graph_shapesize = (.33BodyFontSize) enddef ; + +path graph_shape[] ; % (internal) symbol path + +graph_shape[0] := (0,0) ; % point +graph_shape[1] := fullcircle ; % circle +graph_shape[2] := (up -- down) scaled .5 ; % vertical bar + +for i = 3 upto 9 : % polygons + graph_shape[i] := + for j = 0 upto i-1 : + (up scaled .5) rotated (360j/i) -- + endfor cycle ; +endfor + +graph_shape[12] := graph_shape[2] rotated +90 ; % horizontal line +graph_shape[22] := graph_shape[2] rotated +45 ; % backslash +graph_shape[32] := graph_shape[2] rotated -45 ; % slash +graph_shape[13] := graph_shape[3] rotated 180 ; % down triangle +graph_shape[23] := graph_shape[3] rotated -90 ; % right triangle +graph_shape[33] := graph_shape[3] rotated +90 ; % left triangle +graph_shape[14] := graph_shape[4] rotated +45 ; % square +graph_shape[15] := graph_shape[5] rotated 180 ; % down pentagon +graph_shape[16] := graph_shape[6] rotated +90 ; % turned hexagon +graph_shape[17] := graph_shape[7] rotated 180 ; +graph_shape[18] := graph_shape[8] rotated +22.5 ; + +numeric l ; + +for j = 5 upto 9 : + l := length(graph_shape[j]) ; + pair p[] ; + for i = 0 upto l : + p[i] = whatever [point i of graph_shape[j], + point (i+2 mod l) of graph_shape[j]] ; + p[i] = whatever [point (i+1 mod l) of graph_shape[j], + point (i+l-1 mod l) of graph_shape[j]] ; + endfor + graph_shape[20+j] := for i = 0 upto l : point i of graph_shape[j]--p[i]--endfor cycle ; +endfor + +path s ; s := graph_shape[4] ; +path q ; q := s scaled .25 ; +numeric l ; l := length(s) ; + +pair p[] ; + +graph_shape[24] := for i = 0 upto l-1 : + hide( + p[i] = whatever [point i of s, point (i+1 mod l) of s] ; + p[i] = whatever [point i of q, point (i-1+l mod l) of q] ; + p[i+l] = whatever [point i of s, point (i+1 mod l) of s] ; + p[i+l] = whatever [point i+1 of q, point (i+2 mod l) of q] ; + ) + point i of q -- p[i] -- p[i+l] -- +endfor cycle ; + +graph_shape[34] := graph_shape[24] rotated 45 ; + +% usage : gdraw p plot plotsymbol( 1,1) ; % a filled circle +% usage : gdraw p plot plotsymbol(14,0) ; % a square +% usage : gdraw p plot plotsymbol( 4,.5) ; % a 50% filled diamond + +def stars(expr f) = plotsymbol(25,f) enddef ; % a 5-point star +def points(expr f) = plotsymbol( 0,f) enddef ; +def circles(expr f) = plotsymbol( 1,f) enddef ; +def crosses(expr f) = plotsymbol(34,f) enddef ; +def squares(expr f) = plotsymbol(14,f) enddef ; +def diamonds(expr f) = plotsymbol( 4,f) enddef ; % a turned square +def uptriangles(expr f) = plotsymbol( 3,f) enddef ; +def downtriangles(expr f) = plotsymbol(13,f) enddef ; +def lefttriangles(expr f) = plotsymbol(33,f) enddef ; +def righttriangles(expr f) = plotsymbol(23,f) enddef ; + +% f (fill) is color, numeric or boolean, otherwise background. +def plotsymbol(expr n, f) text t = + if known graph_shape[n] : + image( + save bg, fg ; color bg, fg ; + bg := if known graph_background : graph_background else : background fi ; + save pic ; picture pic ; pic := image(draw origin _op_ t ;) ; + if color colorpart pic : graph_foreground := colorpart pic ; fi + fg := if known graph_foreground : graph_foreground else : black fi ; + save p ; path p ; p = graph_shape[n] scaled graph_shapesize ; + draw p withcolor bg withpen currentpen scaled 2 ; % halo + currentpen := currentpen scaled .5 ; + if cycle p : + fill p withcolor + if known f : + if color f : + f + elseif numeric f : + f[bg,fg] + elseif boolean f and f : + fg + else + bg + fi + else : + bg + fi ; + fi + draw p _op_ t ; + ) + else : + nullpicture + fi + t +enddef ; + +% standard resistance color code: rainbow sequence (from /usr/share/X11/rgb.txt) +color resistance_color[] ; string resistance_name[] ; +resistance_color0 = (0,0,0) ; resistance_name0 = "black" ; +resistance_color1 = (165/255,42/255,42/255) ; resistance_name1 = "brown" ; +resistance_color2 = (1,0,0) ; resistance_name2 = "red" ; +resistance_color3 = (1,165/255,0) ; resistance_name3 = "orange" ; +resistance_color4 = (1,1,0) ; resistance_name4 = "yellow" ; +resistance_color5 = (0,1,0) ; resistance_name5 = "green" ; +resistance_color6 = (0,0,1) ; resistance_name6 = "blue" ; +resistance_color7 = (148/255,0,211/255) ; resistance_name7 = "darkviolet" ; +resistance_color8 = (190/255,190/255,190/255) ; resistance_name8 = "gray" ; +resistance_color9 = (1,1,1) ; resistance_name9 = "white" ; + +%def rainbow(expr f) = +% ((abs(5f) mod 5) + 2 - floor((abs(5f) mod 5) + 2)) +% [resistance_color[ floor((abs(5f) mod 5) + 2)], +% resistance_color[ceiling((abs(5f) mod 5) + 2)]] +%enddef ; +def rainbow(expr f) = + hide(numeric n_ ; n_ = (abs(5f) mod 5) + 2 ;) + (n_-floor(n_))[resistance_color[floor n_],resistance_color[ceiling n_]] +enddef ; + +% The following extensions are not specific to graph and could be moved to metafun... + +% sort a path. Efficient en memory use, not so efficient in sorting long paths... + +vardef sortpath (suffix $) (text t) = % t can be "xpart", "ypart", "length", "angle", ... + if path $ : + if length $ > 0 : + save n, k ; n := length $ ; + for i=0 upto n : + k := i ; + for j=i+1 upto n : + if t (point j of $) < t (point k of $) : + k := j ; + fi + endfor + if k>i : + $ := if i>0 : subpath (0,i-1) of $ -- fi + point k of $ -- + subpath (i,k-1) of $ + if k0 : .. fi + (point i of $) + endfor ) + fi +enddef ; + +% return a path of a function func(x) with abscissa running from f to t over n intervals + +def makefunctionpath (expr f, t, n) (text func) = + (for x=f step ((t-f)/(abs n)) until t : + if x<>f : -- fi + (x, func) + endfor ) +enddef ; + +% shift a path, point by point +% +% example : +% +% p1 := addtopath(p0,(.1normaldeviate,.1normaldeviate)) ; + +vardef addtopath (suffix p) (text t) = + if path p : + (for i=0 upto length p : + if i>0 : -- fi + hide(clearxy ; z = point i of p ;) z shifted t + endfor) + fi +enddef ; + +% return a new path of a function func(z) using the same abscissa as an existing path + +vardef functionpath (suffix p) (text func) = + (for i=0 upto length p : + if i>0 : .. fi + (hide(x := xpart(point i of p))x,func) %(hide(clearxy ; z = point i of p)x,func) + endfor ) +enddef ; + +% least-squares "fit" to a polynomial +% +% example : +% +% path p[] ; +% numeric a[] ; a0 := 1 ; a1 := .1 ; a2 := .01 ; a3 := .001 ; a4 := 0.0001 ; +% p0 := makefunctionpath(0,5,10,polynomial_function(a,4,x)) ; +% p1 := addtopath(p0,(0,.001normaldeviate)) ; +% gdraw p0 ; +% gdraw p1 plot plotsymbol(1,.5) ; +% +% numeric b[] ; +% polynomial_fit(p1, b, 4, 1) ; +% gdraw functionpath(p1,polynomial_function(b,4,x)) ; +% +% numeric c[] ; +% linear_fit(p1, c, 1) ; +% gdraw functionpath(p1,linear_function(c,x)) dashed evenly ; + +% a polynomial function : +% +% y = a0 + a1 * x + a2 * x^2 + ... + a[n] * x^n + +vardef polynomial_function (suffix $) (expr n, x) = + (for j=0 upto n : + $[j]*(x**j) endfor) % no ; +enddef ; + +% find the determinant of a (n+1)*(n+1) matrix ; indices run from 0 to n + +vardef det (suffix $) (expr n) = + hide( + numeric determinant ; determinant := 1 ; + save jj ; numeric jj ; + for k=0 upto n : + if $[k][k]=0 : + jj := -1 ; + for j=0 upto n : + if $[k][j]<>0 : + jj := j ; + exitif true ; + fi + endfor + if jj<0 : + determinant := 0 ; + exitif true ; + fi + for j=k upto n : % interchange the columns + temp := $[j][jj] ; + $[j][jj] := $[j][k] ; + $[j][k] := temp ; + endfor + determinant = -determinant ; + fi + exitif determinant=0 ; + determinant := determinant * $[k][k] ; + if k0 : /(abs t) fi ; + elseif pair t : + if t<>origin : + w := 1/(abs t) ; + fi + elseif path t : + if length t>= i: + if point i of t<>origin : + w := 1/(abs point i of t) ; + fi + else : + w := 0 ; + fi ; + fi + fi + x1 := w ; + for j=0 upto 2n : + sumx[j] := sumx[j] + x1 ; + x1 := x1 * x ; + endfor + y1 := y * w ; + for j=0 upto n : + sumy[j] := sumy[j] + y1 ; + y1 := y1 * x ; + endfor + fit_chi_squared := fit_chi_squared + y*y*w ; + endfor + % construct matrices and calculate the polynomial coefficients + save m ; numeric m[][] ; + for j=0 upto n : + for k=0 upto n : + m[j][k] := sumx[j+k] ; + endfor + endfor + save delta ; numeric delta ; + delta := det(m,n) ; % this destroys the matrix m[][], which is OK + if delta = 0 : + fit_chi_squared := 0 ; + for j=0 upto n : + $[j] := 0 ; + endfor + else : + for i=0 upto n : + for j=0 upto n : + for k=0 upto n : + m[j][k] := sumx[j+k] ; + endfor + m[j][i] := sumy[j] ; + endfor + $[i] := det(m,n) / delta ; % matrix m[][] gets destroyed... + endfor + for j=0 upto n : + fit_chi_squared := fit_chi_squared - 2sumy[j]*$[j] ; + for k=0 upto n : + fit_chi_squared := fit_chi_squared + $[j]*$[k]*sumx[j+k] ; + endfor + endfor + % normalize by the number of degrees of freedom + fit_chi_squared := fit_chi_squared / (length(p) - n) ; % length(p)+1-(n+1) + fi + fi +enddef ; + +% y = a0 + a1 * x +% +% of course a line is just a polynomial of order 1 + +vardef linear_function (suffix $) (expr x) = polynomial_function($,1,x) enddef ; +vardef linear_fit (suffix p, $) (text t) = polynomial_fit(p, $, 1, t) ; enddef ; + +% and a constant is polynomial of order 0 + +vardef constant_function (suffix $) (expr x) = polynomial_function($,0,x) enddef ; +vardef constant_fit (suffix p, $) (text t) = polynomial_fit(p, $, 0, t) ; enddef ; + +% y = a1 * exp(a0*x) +% +% exp and ln defined in metafun + +vardef exponential_function (suffix $) (expr x) = $1*exp($0*x) enddef ; + +% since we take a log, this only works for positive ordinates + +vardef exponential_fit (suffix p, $) (text t) = + save a ; numeric a[] ; + save q ; path q[] ; % fit to the log of the ordinate + for i=0 upto length p : + clearxy ; z = point i of p ; + if y>0 : + augment.q0(x,ln(y)) ; + augment.q1( + if known t : + if numeric t : (0,ln(t)) + elseif pair t : (xpart t,ln(ypart t)) + elseif path t : + if length t>=i : + hide(z1 = point i of t;) + (x1,ln(y1)) + else : + origin + fi + fi + else : + (0,1) + fi ) ; + fi + endfor + linear_fit(q0,a,q1) ; + save e ; e := exp(sqrt(fit_chi_squared)) ; + fit_chi_squared := e * e ; + $0 := a1 ; + $1 := exp(a0) ; +enddef ; + +% y = a1 * x**a0 + +vardef power_law_function (suffix $) (expr x) = $1*(x**$0) enddef ; + +% since we take logs, this only works for positive abscissae and ordinates + +vardef power_law_fit (suffix p, $) (text t) = + save a ; numeric a[] ; + save q ; path q[] ; % fit to the logs of the abscissae and ordinates + for i=0 upto length p : + clearxy ; z = point i of p ; + if (x>0) and (y>0) : + augment.q0(ln(x),ln(y)) ; + augment.q1( + if known t : + if numeric t : (0,ln(t)) + elseif pair t : (ln(xpart t),ln(ypart t)) + elseif path t : + if length t>=i : + hide(z1 = point i of t) + (ln(x1),ln(y1)) + else : + origin + fi + fi + else : + (0,1) + fi ) ; + fi + endfor + linear_fit(q0,a,q1) ; + save e ; e := exp(sqrt(fit_chi_squared)) ; + fit_chi_squared := e * e ; + $0 := a1 ; + $1 := exp(a0) ; +enddef ; + +% gaussian : y = a2 * exp(-ln(2)*((x-a0)/a1)^2) +% +% a1 is the hwhm ; sigma := a1/sqrt(2ln(2)) or a1/1.17741 + +newinternal lntwo ; lntwo := ln(2) ; % brrr, why not inline it + +vardef gaussian_function (suffix $) (expr x) = + if $1 = 0 : + if x = $0 : $2 else : 0 fi + else : + $2 * exp(-lntwo*(((x-$0)/$1)**2)) + fi + if known $3 : + + $3 + fi +enddef ; + +% since we take a log, this only works for positive ordinates + +vardef gaussian_fit (suffix p, $) (text t) = + save a ; numeric a[] ; + save q ; path q[] ; % fit to the log of the ordinate + for i=0 upto length p : + clearxy ; z = point i of p ; + if y>0 : + augment.q0(x,ln(y)) ; + augment.q1( + if known t : + if numeric t : (0,ln(t)) + elseif pair t : (xpart t,ln(ypart t)) + elseif path t : + if length t>=i : + hide(z1 = point i of t) + (x1,ln(y1)) + else : + origin + fi + fi + else : + (0,1) + fi ) ; + fi + endfor + polynomial_fit(q0,a,2,q1) ; + save e ; e := exp(sqrt(fit_chi_squared)) ; + fit_chi_squared := e * e ; + $1 := sqrt(-lntwo/a2) ; + $0 := -.5a1/a2 ; + $2 := exp(a0-.25*a1*a1/a2) ; + $3 := 0 ; % polynomial_fit will NOT work with a non-zero background! +enddef ; + +% lorentzian: y = a2 / (1 + ((x - a0)/a1)^2) + +vardef lorentzian_function (suffix $) (expr x) = + if $1 = 0 : + if x = $0 : $2 else : 0 fi + else : + $2 / (1 + ((x - $0)/$1)**2) + fi + if known $3 : + + $3 + fi +enddef ; + +vardef lorentzian_fit (suffix p, $) (text t) = + save a ; numeric a[] ; + save q ; path q ; % fit to the inverse of the ordinate + for i=0 upto length p : + if ypart(point i of p)<>0 : + augment.q(xpart(point i of p), 1/ypart(point i of p)) ; + fi + endfor + polynomial_fit(q,a,2,if t <> 0 : 1/(t) else : 0 fi) ; + fit_chi_squared := 1/fit_chi_squared ; + $0 := -.5a1/a2 ; + $2 := 1/(a0-.25a1*a1/a2) ; + $1 := sqrt((a0-.25a1*a1/a2)/a2) ; + $3 := 0 ; % polynomial_fit will NOT work with a non-zero background! +enddef ; diff --git a/metapost/context/base/mpiv/mp-grid.mpiv b/metapost/context/base/mpiv/mp-grid.mpiv new file mode 100644 index 000000000..b9243b1b9 --- /dev/null +++ b/metapost/context/base/mpiv/mp-grid.mpiv @@ -0,0 +1,142 @@ +%D \module +%D [ file=mp-grid.mpiv, +%D version=2000.07.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=grid support, +%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. + +%D Under construction. + +if known context_grid : endinput ; fi ; + +boolean context_grid ; context_grid := true ; + +string fmt_separator ; fmt_separator := "@" ; +numeric fmt_precision ; fmt_precision := 3 ; +boolean fmt_initialize ; fmt_initialize := false ; +boolean fmt_zerocheck ; fmt_zerocheck := true ; + +if unknown fmt_loaded : input "mp-form.mpiv" ; fi ; + +boolean fmt_pictures ; fmt_pictures := true ; + +def do_format = if fmt_pictures : format else : formatstr fi enddef ; +def do_mformat = if fmt_pictures : Mformat else : Mformatstr fi enddef ; + +numeric grid_eps ; grid_eps = eps ; + +def hlingrid (expr Min, Max, Step, Length, Width) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw (origin--(Width,0)) shifted (0,i*(Length/Max)) t ; + endfor ; + ) ; +enddef ; + +def vlingrid (expr Min, Max, Step, Length, Height) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw (origin--(0,Height)) shifted (i*(Length/Max),0) t ; + endfor ; + ) ; +enddef ; + +def hloggrid (expr Min, Max, Step, Length, Width) text t = + image ( + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw (origin--(Width,0)) shifted (0,Length*log(i)) t ; + endfor ; + ) ; +enddef ; + +def vloggrid (expr Min, Max, Step, Length, Height) text t = + image ( + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw (origin--(0,Height)) shifted (Length*log(i),0) t ; + endfor ; + ) ; +enddef ; + +vardef hlintext@#(expr Min, Max, Step, Length, Format) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw textext@#(mfun_format_number(Format,i)) shifted (0,i*(Length/Max)) t ; + endfor ; + ) +enddef ; + +vardef vlintext@#(expr Min, Max, Step, Length, Format) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw textext@#(mfun_format_number(Format,i)) shifted (i*(Length/Max),0) t ; + endfor ; + ) +enddef ; + +vardef hlogtext@#(expr Min, Max, Step, Length, Format) text t = + image ( + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw textext@#(mfun_format_number(Format,i)) shifted (0,Length*log(i)) t ; + endfor ; + ) +enddef ; + +vardef vlogtext@#(expr Min, Max, Step, Length, Format) text t = + image ( + for i=max(Min,1) step Step until min(Max,10)+grid_eps : + draw textext@#(mfun_format_number(Format,i)) shifted (Length*log(i),0) t ; + endfor ; + ) +enddef ; + +vardef hlinlabel@#(expr Min, Max, Step, Length) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw thelabel@#(decimal i,(0,i*(Length/Max))) t ; + endfor ; + ) +enddef ; + +vardef vlinlabel@#(expr Min, Max, Step, Length) text t = + image ( + for i=Min step Step until Max+grid_eps : + draw thelabel@#(decimal i,(i*(Length/Max),0)) t ; + endfor ; + ) +enddef ; + +vardef linlog(expr xy) = ( xpart xy, log(ypart xy)) enddef ; +vardef loglin(expr xy) = (log(xpart xy), ypart xy) enddef ; +vardef loglog(expr xy) = (log(xpart xy), log(ypart xy)) enddef ; +vardef linlin(expr xy) = ( (xpart xy), (ypart xy)) enddef ; + +vardef loglinpath primary p = processpath (p) (loglin) enddef ; +vardef linlogpath primary p = processpath (p) (linlog) enddef ; +vardef loglogpath primary p = processpath (p) (loglog) enddef ; +vardef linlinpath primary p = processpath (p) (linlin) enddef ; + +vardef processpath (expr p) (text pp) = + if path p : + for i=0 upto length(p)-1 : + pp(point i of p) .. controls + pp(postcontrol i of p) and + pp(precontrol (i+1) of p) .. + endfor + if cycle p : + cycle + else : + pp(point length(p) of p) + fi + elseif pair p : + pp(p) + else : + p + fi +enddef ; + diff --git a/metapost/context/base/mpiv/mp-grph.mpiv b/metapost/context/base/mpiv/mp-grph.mpiv new file mode 100644 index 000000000..5938b9f02 --- /dev/null +++ b/metapost/context/base/mpiv/mp-grph.mpiv @@ -0,0 +1,348 @@ +%D \module +%D [ file=mp-grph.mpiv, +%D version=2000.12.14, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=graphic text support, +%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. + +%D Under construction. + +if known context_grph : endinput ; fi ; + +boolean context_grph ; context_grph := true ; + +picture _currentpicture_ ; + +numeric _fig_nesting_ ; _fig_nesting_ := 0 ; + +def beginfig (expr c) = + _fig_nesting_ := _fig_nesting_ + 1 ; + if _fig_nesting_ = 1 : + begingroup + charcode := c ; + resetfig ; + scantokens extra_beginfig ; + fi ; +enddef ; + +def endfig = + ; % safeguard + if _fig_nesting_ = 1 : + scantokens extra_endfig ; + shipit ; + endgroup ; + fi ; + _fig_nesting_ := _fig_nesting_ - 1 ; +enddef; + +def resetfig = + clearxy ; + clearit ; + clearpen ; + pickup defaultpen ; + interim linecap := linecap ; + interim linejoin := linejoin ; + interim miterlimit := miterlimit ; + save _background_ ; color _background_ ; _background_ := background ; + save background ; color background ; background := _background_ ; + drawoptions () ; +enddef ; + +def protectgraphicmacros = + save showtext ; + save beginfig ; let beginfig = begingraphictextfig ; + save endfig ; let endfig = endgraphictextfig ; + save end ; let end = relax ; + interim prologues := prologues ; + resetfig ; % resets currentpicture +enddef ; + +numeric currentgraphictext ; currentgraphictext := 0 ; + +def data_mpo_file = job_name & "-mpgraph.mpo" enddef ; +def data_mpy_file = job_name & "-mpgraph.mpy" enddef ; + +def begingraphictextfig (expr n) = + foundpicture := n ; + scratchpicture := nullpicture ; +enddef ; + +def endgraphictextfig = + if foundpicture = currentgraphictext : + expandafter endinput + else : + scratchpicture := nullpicture ; + fi ; +enddef ; + +def loadfigure primary filename = + doloadfigure (filename) +enddef ; + +def doloadfigure (expr filename) text figureattributes = + begingroup ; + save figurenumber, figurepicture, number, fixedplace ; + numeric figurenumber ; figurenumber := 0 ; + boolean figureshift ; figureshift := true ; + picture figurepicture ; figurepicture := currentpicture ; + def number primary n = hide(figurenumber := n) enddef ; + def fixedplace = hide(figureshift := false) enddef ; + protectgraphicmacros ; + % defaults + interim linecap := rounded ; + interim linejoin := rounded ; + interim miterlimit := 10 ; + % + currentpicture := nullpicture ; + draw fullcircle figureattributes ; % expand number + currentpicture := nullpicture ; + def beginfig (expr n) = + currentpicture := nullpicture ; + if (figurenumber=n) or (figurenumber=0) : + let endfig = endinput ; + fi ; + enddef ; + let endfig = relax ; + readfile(filename) ; + if figureshift : + currentpicture := currentpicture shifted -llcorner currentpicture ; + fi ; + addto figurepicture also currentpicture figureattributes ; + currentpicture := figurepicture ; + endgroup ; +enddef ; + +% shared between old and new + +boolean mfun_gt_color_fill ; +boolean mfun_gt_color_draw ; +boolean mfun_gt_shade_fill ; +boolean mfun_gt_reverse_fill ; +boolean mfun_gt_outline_fill ; +picture mfun_gt_picture ; + +% this is the old version: + +def old_graphictext primary t = + hide ( + if mfun_trial_run : + let mfun_graphic_text = mfun_no_graphic_text ; + else : + let mfun_graphic_text = mfun_do_graphic_text ; + fi + ) + mfun_graphic_text(t) +enddef ; + +def mfun_do_graphic_text (expr t) = + % withprescript "gt_stage=final" + begingroup ; + save figurepicture ; picture figurepicture ; + figurepicture := currentpicture ; currentpicture := nullpicture ; + currentgraphictext := currentgraphictext + 1 ; + mfun_finish_graphic_text % picks up directives +enddef ; + +def mfun_no_graphic_text (expr t) text rest = + currentgraphictext := currentgraphictext + 1 ; + draw unitsquare + withprescript "gt_stage=trial" + withprescript "gt_index=" & decimal currentgraphictext + withpostscript t +enddef ; + +def mfun_finish_graphic_text text rest = + protectgraphicmacros ; % resets currentpicture + interim linecap := butt ; % normally rounded + interim linejoin := mitered ; % normally rounded + interim miterlimit := 10 ; % todo + let normalwithshade = withshade ; + save foundpicture, scratchpicture, str ; + save fill, draw, withshade, reversefill, outlinefill ; + save withfillcolor, withdrawcolor ; % quite important + numeric foundpicture ; picture scratchpicture ; string str ; + def draw expr p = + % the first, naive implementation was: + % addto scratchpicture doublepath p withpen currentpen ; + % but it is better to turn lines into fills + addto scratchpicture contour boundingbox + image (addto currentpicture doublepath p withpen currentpen) ; + enddef ; + def fill expr p = + addto scratchpicture contour p withpen currentpen ; + enddef ; + def mfun_gt_fill = enddef ; boolean mfun_gt_color_fill ; mfun_gt_color_fill := false ; + def mfun_gt_draw = enddef ; boolean mfun_gt_color_draw ; mfun_gt_color_draw := false ; + def mfun_gt_shade = enddef ; boolean mfun_gt_shade_fill ; mfun_gt_shade_fill := false ; + boolean mfun_gt_reverse_fill ; mfun_gt_reverse_fill := false ; + boolean mfun_gt_outline_fill ; mfun_gt_outline_fill := false ; + def reversefill = + hide(mfun_gt_reverse_fill := true ) + enddef ; + def outlinefill = + hide(mfun_gt_outline_fill := true ) + enddef ; + def withshade primary c = + hide(def mfun_gt_shade = normalwithshade c enddef ; mfun_gt_shade_fill := true ) + enddef ; + def withfillcolor primary c = + hide(def mfun_gt_fill = withcolor c enddef ; mfun_gt_color_fill := true ) + enddef ; + def withdrawcolor primary c = + hide(def mfun_gt_draw = withcolor c enddef ; mfun_gt_color_draw := true ) + enddef ; + scratchpicture := nullpicture ; + addto scratchpicture doublepath origin rest ; % pre-roll + for i within scratchpicture : % Below here is a dirty tricky test! + if (urcorner dashpart i) = origin : + mfun_gt_outline_fill := false ; + fi ; + endfor ; + scratchpicture := nullpicture ; + readfile(data_mpy_file) ; + scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ; + if not mfun_gt_color_draw and not mfun_gt_color_fill : + mfun_gt_color_draw := true ; + fi + if mfun_gt_shade_fill : + mfun_gt_color_draw := false ; + mfun_gt_color_fill := false ; + fi ; + currentpicture := figurepicture ; + if mfun_gt_shade_fill : + for i within scratchpicture : + if filled i : + addto currentpicture contour pathpart i _op_ rest mfun_gt_shade ; + fi ; + endfor ; + else : + if mfun_gt_color_draw and not mfun_gt_reverse_fill : + for i within scratchpicture : + if mfun_gt_color_fill and mfun_gt_outline_fill : + addto currentpicture doublepath pathpart i _op_ rest mfun_gt_fill dashed nullpicture ; + fi ; + if filled i : + addto currentpicture doublepath pathpart i _op_ rest mfun_gt_draw ; + fi ; + endfor ; + fi ; + if mfun_gt_color_fill : + for i within scratchpicture : + if filled i : + addto currentpicture contour pathpart i _op_ rest mfun_gt_fill withpen pencircle scaled 0 ; + fi ; + endfor ; + fi ; + if mfun_gt_color_draw and mfun_gt_reverse_fill : + for i within scratchpicture : + if filled i : + addto currentpicture doublepath pathpart i _op_ rest mfun_gt_draw ; + fi ; + endfor ; + fi ; + for i within scratchpicture : + if stroked i : + addto currentpicture doublepath pathpart i _op_ rest mfun_gt_draw ; + fi ; + endfor ; + fi ; + endgroup ; +enddef ; + +% and this is the new one: + +% boolean mfun_gt_color_fill ; +% boolean mfun_gt_color_draw ; +% boolean mfun_gt_shade_fill ; +% boolean mfun_gt_reverse_fill ; +% picture mfun_gt_picture ; + +def mfun_gt_default = % somewhat compatible + scaled 11.5 + withpen pencircle scaled .1 +enddef ; + +def new_graphictext primary t = % use outlinetext instead + begingroup ; + mfun_graphic_text_indeed(t) +enddef ; + +def mfun_graphic_text_indeed(expr t) text rest = + interim linecap := butt ; % normally rounded + interim linejoin := mitered ; % normally rounded + % interim miterlimit := 10 ; % todo + % + let normalwithshade = withshade ; + % + save reversefill, outlinefill, withshade, withfillcolor, withdrawcolor ; + % + def mfun_gt_fill = enddef ; + def mfun_gt_draw = enddef ; + def mfun_gt_shade = enddef ; + % + mfun_gt_color_fill := false ; + mfun_gt_color_draw := false ; + mfun_gt_shade_fill := false ; + mfun_gt_reverse_fill := false ; + % + def reversefill = hide(mfun_gt_reverse_fill := true) enddef ; + def outlinefill = enddef ; + def withshade primary c = hide(mfun_gt_shade_fill := true; def mfun_gt_shade = normalwithshade c enddef ;) enddef ; + def withfillcolor primary c = hide(mfun_gt_color_fill := true; def mfun_gt_fill = withcolor c enddef ;) enddef ; + def withdrawcolor primary c = hide(mfun_gt_color_draw := true; def mfun_gt_draw = withcolor c enddef ;) enddef ; + % + mfun_gt_picture := nullpicture ; + addto mfun_gt_picture doublepath origin rest ; % preroll + mfun_gt_picture := nullpicture ; + % + def reversefill = enddef ; + def outlinefill = enddef ; + def withshade primary c = enddef ; + def withfillcolor primary c = enddef ; + def withdrawcolor primary c = enddef ; + % + if mfun_gt_shade_fill : + draw outlinetext.f(t)(mfun_gt_shade) rest; + elseif mfun_gt_color_fill and mfun_gt_color_draw : + if mfun_gt_reverse_fill : + draw outlinetext.r(t)(mfun_gt_default mfun_gt_fill rest)(mfun_gt_default mfun_gt_draw rest) ; + else : + draw outlinetext.b(t)(mfun_gt_default mfun_gt_draw rest)(mfun_gt_default mfun_gt_fill rest); + fi ; + elseif mfun_gt_color_fill : + draw outlinetext.f(t)(mfun_gt_default mfun_gt_fill rest) ; + elseif mfun_gt_color_draw : + draw outlinetext.d(t)(mfun_gt_default mfun_gt_draw rest) ; + else : + draw outlinetext.d(t)(mfun_gt_default rest) ; + fi ; + % + endgroup ; +enddef ; + +let graphictext = old_graphictext ; +%%% graphictext = new_graphictext ; % more than 10 times faster + +% example +% +% beginfig (1) ; +% graphictext +% "\vbox{\hsize10cm \input tufte }" +% scaled 8 +% withdrawcolor blue +% withfillcolor red +% withpen pencircle scaled 2pt ; +% endfig ; +% +% beginfig(1) ; +% loadfigure "gracht.mp" rotated 20 ; +% loadfigure "koe.mp" number 1 scaled 2 ; +% endfig ; +% +% end diff --git a/metapost/context/base/mpiv/mp-idea.mpiv b/metapost/context/base/mpiv/mp-idea.mpiv new file mode 100644 index 000000000..462d97553 --- /dev/null +++ b/metapost/context/base/mpiv/mp-idea.mpiv @@ -0,0 +1,30 @@ +% redpart (1,1,0,0) crashes + +% let normalredpart = redpart ; +% let normalgreenpart = greenpart ; +% let normalbluepart = bluepart ; +% let normalcyanpart = cyanpart ; +% let normalmagentapart = magentapart ; +% let normalyellowpart = yellowpart ; +% let normalblackpart = blackpart ; + +% vardef redpart expr p = if cmykcolor p : 1 - normalcyanpart p elseif rgbcolor p : normalredpart p else : p fi enddef ; +% vardef greenpart expr p = if cmykcolor p : 1 - normalmagentapart p elseif rgbcolor p : normalgreenpart p else : p fi enddef ; +% vardef bluepart expr p = if cmykcolor p : 1 - normalyellowpart p elseif rgbcolor p : normalbluepart p else : p fi enddef ; +% vardef cyanpart expr p = if cmykcolor p : normalcyanpart p elseif rgbcolor p : 1 - normalredpart p else : p fi enddef ; +% vardef magentapart expr p = if cmykcolor p : normalmagentapart p elseif rgbcolor p : 1 - normalgreenpart p else : p fi enddef ; +% vardef yellowpart expr p = if cmykcolor p : normalyellowpart p elseif rgbcolor p : 1 - normalbluepart p else : p fi enddef ; +% vardef blackpart expr p = if cmykcolor p : normalblackpart p elseif rgbcolor p : 0 else : p fi enddef ; + +vardef rcomponent expr p = if rgbcolor p : redpart p elseif cmykcolor p : 1 - cyanpart p else : p fi enddef ; +vardef gcomponent expr p = if rgbcolor p : greenpart p elseif cmykcolor p : 1 - magentapart p else : p fi enddef ; +vardef bcomponent expr p = if rgbcolor p : bluepart p elseif cmykcolor p : 1 - yellowpart p else : p fi enddef ; +vardef ccomponent expr p = if cmykcolor p : cyanpart p elseif rgbcolor p : 1 - redpart p else : p fi enddef ; +vardef mcomponent expr p = if cmykcolor p : magentapart p elseif rgbcolor p : 1 - greenpart p else : p fi enddef ; +vardef ycomponent expr p = if cmykcolor p : yellowpart p elseif rgbcolor p : 1 - bluepart p else : p fi enddef ; +vardef bcomponent expr p = if cmykcolor p : blackpart p elseif rgbcolor p : 0 else : p fi enddef ; + +vardef somecolor = (1,1,0,0) enddef ; + +fill OverlayBox withcolor (rcomponent somecolor,gcomponent somecolor,bcomponent somecolor) ; +fill OverlayBox withcolor (ccomponent somecolor,mcomponent somecolor,ycomponent somecolor,bcomponent somecolor) ; diff --git a/metapost/context/base/mpiv/mp-luas.mpiv b/metapost/context/base/mpiv/mp-luas.mpiv new file mode 100644 index 000000000..c30798247 --- /dev/null +++ b/metapost/context/base/mpiv/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/mpiv/mp-mlib.mpiv b/metapost/context/base/mpiv/mp-mlib.mpiv new file mode 100644 index 000000000..326342b70 --- /dev/null +++ b/metapost/context/base/mpiv/mp-mlib.mpiv @@ -0,0 +1,1462 @@ +%D \module +%D [ file=mp-mlib.mpiv, +%D version=2008.03.21, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=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 unknown mplib : endinput ; fi ; +if known context_mlib : endinput ; fi ; + +boolean context_mlib ; context_mlib := true ; + +%D Color and transparency +%D +%D Separable: + +newinternal normaltransparent ; normaltransparent := 1 ; +newinternal multiplytransparent ; multiplytransparent := 2 ; +newinternal screentransparent ; screentransparent := 3 ; +newinternal overlaytransparent ; overlaytransparent := 4 ; +newinternal softlighttransparent ; softlighttransparent := 5 ; +newinternal hardlighttransparent ; hardlighttransparent := 6 ; +newinternal colordodgetransparent ; colordodgetransparent := 7 ; +newinternal colorburntransparent ; colorburntransparent := 8 ; +newinternal darkentransparent ; darkentransparent := 9 ; +newinternal lightentransparent ; lightentransparent := 10 ; +newinternal differencetransparent ; differencetransparent := 11 ; +newinternal exclusiontransparent ; exclusiontransparent := 12 ; + +%D Nonseparable: + +newinternal huetransparent ; huetransparent := 13 ; +newinternal saturationtransparent ; saturationtransparent := 14 ; +newinternal colortransparent ; colortransparent := 15 ; +newinternal luminositytransparent ; luminositytransparent := 16 ; + +vardef transparency_alternative_to_number(expr name) = + if string name : + if expandafter known scantokens(name & "transparent") : + scantokens(name & "transparent") + else : + 0 + fi + elseif name < 17 : + name + else : + 0 + fi +enddef ; + +def namedcolor (expr n) = + 1 + withprescript "sp_type=named" + 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=" & colordecimals v +enddef ; + +def multitonecolor(expr name)(text t) = + 1 + withprescript "sp_type=multitone" + withprescript "sp_name=" & name + withprescript "sp_value=" & colordecimalslist(t) +enddef ; + +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(a) + withprescript "tr_transparency=" & decimal t + withcolor c +enddef ; + +% 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 + (c,m,y,k) +enddef ; + +% Texts (todo: better strut ratio, now .7 hardcoded, should be passed) + +newinternal textextoffset ; textextoffset := 0 ; + +%%%%%%% mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ; % we can consider using colors (less hash space) +color mfun_tt_b ; +numeric mfun_tt_n ; mfun_tt_n := 0 ; +picture mfun_tt_p ; mfun_tt_p := nullpicture ; +picture mfun_tt_o ; mfun_tt_o := nullpicture ; +picture mfun_tt_c ; mfun_tt_c := nullpicture ; + +if unknown mfun_trial_run : + boolean mfun_trial_run ; + mfun_trial_run := false ; +else : + % already defined before the format is loaded +fi ; + +if unknown mfun_first_run : + boolean mfun_first_run ; + mfun_first_run := true ; +else : + % already defined before the format is loaded +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_endfig := "mfun_flush_tex_texts ;" & extra_endfig ; +extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ; + +% We collect and flush them all, as we can also have temporary textexts +% that gets never really flushed but are used for calculations. So, we +% 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. + +% see mp-keep.mpiv for older code + +% vardef rawtextext(expr s) = % todo: avoid currentpicture +% if s = "" : +% 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 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] +% 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 ; + +boolean mfun_onetime_textext ; mfun_onetime_textext := false ; + +vardef rawtextext(expr s) = % todo: avoid currentpicture + if s = "" : + mfun_onetime_textext := false ; + 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 s ; + if not mfun_onetime_textext : + addto mfun_tt_p also mfun_tt_c + withprescript "tx_global=yes" ; + fi ; + else : + mfun_tt_b := lua.mp.tt_dimensions(mfun_tt_n) ; + addto mfun_tt_c doublepath unitsquare + 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" ; + fi ; + mfun_onetime_textext := false ; + mfun_tt_c + fi +enddef ; + +% More text + +defaultfont := "Mono" ; +defaultscale := 1 ; + +extra_beginfig := extra_beginfig & "defaultscale:=1;" ; + +vardef fontsize expr name = + save size ; numeric size ; + size := bbwidth(textext("\MPfontsizehskip{" & name & "}")) ; + if size = 0 : + 12pt + else : + size + fi +enddef ; + +pair mfun_laboff ; mfun_laboff := (0,0) ; +pair mfun_laboff.lft ; mfun_laboff.lft := (-1,0) ; +pair mfun_laboff.rt ; mfun_laboff.rt := (1,0) ; +pair mfun_laboff.bot ; mfun_laboff.bot := (0,-1) ; +pair mfun_laboff.top ; mfun_laboff.top := (0,1) ; +pair mfun_laboff.ulft ; mfun_laboff.ulft := (-.7,.7) ; +pair mfun_laboff.urt ; mfun_laboff.urt := (.7,.7) ; +pair mfun_laboff.llft ; mfun_laboff.llft := -(.7,.7) ; +pair mfun_laboff.lrt ; mfun_laboff.lrt := (.7,-.7) ; + +pair mfun_laboff.d ; mfun_laboff.d := mfun_laboff ; +pair mfun_laboff.dlft ; mfun_laboff.dlft := mfun_laboff.lft ; +pair mfun_laboff.drt ; mfun_laboff.drt := mfun_laboff.rt ; +pair mfun_laboff.origin ; mfun_laboff.origin := origin ; +pair mfun_laboff.raw ; mfun_laboff.raw := origin ; + +pair mfun_laboff.l ; mfun_laboff.l := mfun_laboff.lft ; +pair mfun_laboff.r ; mfun_laboff.r := mfun_laboff.rt ; +pair mfun_laboff.b ; mfun_laboff.b := mfun_laboff.bot ; +pair mfun_laboff.t ; mfun_laboff.t := mfun_laboff.top ; +pair mfun_laboff.l_t ; mfun_laboff.l_t := mfun_laboff.ulft ; +pair mfun_laboff.r_t ; mfun_laboff.r_t := mfun_laboff.urt ; +pair mfun_laboff.l_b ; mfun_laboff.l_b := mfun_laboff.llft ; +pair mfun_laboff.r_b ; mfun_laboff.r_b := mfun_laboff.lrt ; +pair mfun_laboff.t_l ; mfun_laboff.t_l := mfun_laboff.ulft ; +pair mfun_laboff.t_r ; mfun_laboff.t_r := mfun_laboff.urt ; +pair mfun_laboff.b_l ; mfun_laboff.b_l := mfun_laboff.llft ; +pair mfun_laboff.b_r ; mfun_laboff.b_r := mfun_laboff.lrt ; + +mfun_labxf := 0.5 ; +mfun_labxf.lft := mfun_labxf.l := 1 ; +mfun_labxf.rt := mfun_labxf.r := 0 ; +mfun_labxf.bot := mfun_labxf.b := 0.5 ; +mfun_labxf.top := mfun_labxf.t := 0.5 ; +mfun_labxf.ulft := mfun_labxf.l_t := mfun_labxf.t_l := 1 ; +mfun_labxf.urt := mfun_labxf.r_t := mfun_labxf.t_r := 0 ; +mfun_labxf.llft := mfun_labxf.l_b := mfun_labxf.b_l := 1 ; +mfun_labxf.lrt := mfun_labxf.r_b := mfun_labxf.b_r := 0 ; + +mfun_labxf.d := mfun_labxf ; +mfun_labxf.dlft := mfun_labxf.lft ; +mfun_labxf.drt := mfun_labxf.rt ; +mfun_labxf.origin := 0 ; +mfun_labxf.raw := 0 ; + +mfun_labyf := 0.5 ; +mfun_labyf.lft := mfun_labyf.l := 0.5 ; +mfun_labyf.rt := mfun_labyf.r := 0.5 ; +mfun_labyf.bot := mfun_labyf.b := 1 ; +mfun_labyf.top := mfun_labyf.t := 0 ; +mfun_labyf.ulft := mfun_labyf.l_t := mfun_labyf.t_l := 0 ; +mfun_labyf.urt := mfun_labyf.r_t := mfun_labyf.t_r := 0 ; +mfun_labyf.llft := mfun_labyf.l_b := mfun_labyf.b_l := 1 ; +mfun_labyf.lrt := mfun_labyf.r_b := mfun_labyf.b_r := 1 ; + +mfun_labyf.d := mfun_labyf ; +mfun_labyf.dlft := mfun_labyf.lft ; +mfun_labyf.drt := mfun_labyf.rt ; +mfun_labyf.origin := 0 ; +mfun_labyf.raw := 0 ; + +mfun_labtype := 0 ; +mfun_labtype.lft := mfun_labtype.l := 1 ; +mfun_labtype.rt := mfun_labtype.r := 2 ; +mfun_labtype.bot := mfun_labtype.b := 3 ; +mfun_labtype.top := mfun_labtype.t := 4 ; +mfun_labtype.ulft := mfun_labtype.l_t := mfun_labtype.t_l := 5 ; +mfun_labtype.urt := mfun_labtype.r_t := mfun_labtype.t_r := 6 ; +mfun_labtype.llft := mfun_labtype.l_b := mfun_labtype.b_l := 7 ; +mfun_labtype.lrt := mfun_labtype.r_b := mfun_labtype.b_r := 8 ; +mfun_labtype.d := 10 ; +mfun_labtype.dlft := 11 ; +mfun_labtype.drt := 12 ; +mfun_labtype.origin := 0 ; +mfun_labtype.raw := 0 ; + +% installlabel.foo ( 0, 1, 1, (.5,-1) ) ; + +vardef installlabel@# (expr type, x, y, offset) = + numeric labtype@# ; labtype@# := type ; + pair laboff @# ; laboff @# := offset ; + numeric labxf @# ; labxf @# := x ; + numeric labyf @# ; labyf @# := y ; +enddef ; + +% we save the plain variant + +vardef plain_thelabel@#(expr p,z) = + if string p : + plain_thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z) + else : + p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) + fi +enddef; + +def plain_label = % takes two arguments, contrary to textext that takes one + normaldraw plain_thelabel +enddef ; + +let mfun_label = label ; +let mfun_thelabel = thelabel ; + +def useplainlabels = % somehow let doesn't work for all code + def label = plain_label enddef ; + def thelabel = plain_thelabel enddef ; +enddef ; + +def usemetafunlabels = + let label = mfun_label ; + let thelabel = mfun_thelabel ; +enddef ; + +vardef dotlabel@#(expr s,z) text t_ = + label@#(s,z) t_ ; + interim linecap := rounded ; + normaldraw z withpen pencircle scaled dotlabeldiam t_ ; +enddef ; + +plain_compatibility_data := plain_compatibility_data & "save label, thelabel ;" & "useplainlabels ;" ; + +% next comes own own: + +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) : + shifted (0,ypart center p) + fi + shifted (z + textextoffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p)) + fi +enddef ; + +vardef textext@#(expr p) = % no draw here + thetextext@#(p,origin) +enddef ; + +vardef onetimetextext@#(expr p) = % no draw here + mfun_onetime_textext := true ; + thetextext@#(p,origin) +enddef ; + +vardef thelabel@#(expr p,z) = + if string p : + thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z) + else : + p shifted (z + labeloffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p)) + fi +enddef; + +def label = % takes two arguments, contrary to textext that takes one + normaldraw thelabel +enddef ; + +vardef anchored@#(expr p, z) = % beware: no "+ mfun_laboff@#" here (never!) + p + if (mfun_labtype@# >= 10) : + shifted (0,ypart center p) + fi + shifted (z + (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p)) +enddef ; + +let normalinfont = infont ; + +primarydef s infont name = % nasty hack + if name = "" : + textext(s) + else : + textext("\definedfont[" & name & "]" & s) + fi +enddef ; + +% Helper + +string mfun_prescript_separator ; mfun_prescript_separator := char(13) ; + +% Shades + +% 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 + +% fill fullcircle scaled 10cm +% withshademethod "circular" +% withshadevector (5cm,1cm) +% withshadecenter (.1,.5) +% withshadedomain (.2,.6) +% withshadefactor 1.2 +% withshadecolors (red,green) +% ; + +path mfun_shade_path ; +numeric mfun_shade_step ; mfun_shade_step := 0 ; + +def withshadestep = + hide(mfun_shade_step := mfun_shade_step + 1 ;) + mfun_withshadestep +enddef ; + +def mfun_withshadestep (text t) = + withprescript "sh_step=" & decimal mfun_shade_step + t +enddef ; + +primarydef p withshademethod m = + hide( + mfun_shade_path := p ; + mfun_shade_step := 1 ; + ) + 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 withshadedirection expr a = + withprescript "sh_center_a=" & ddecimal (point xpart a of boundingbox(mfun_shade_path)) + withprescript "sh_center_b=" & ddecimal (point ypart a of boundingbox(mfun_shade_path)) +enddef ; + +pair shadedup ; shadedup := (0.5,2.5) ; +pair shadeddown ; shadeddown := (2.5,0.5) ; +pair shadedleft ; shadedleft := (1.5,3.5) ; +pair shadedright ; shadedright := (3.5,1.5) ; + +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 withshadebound (expr a) = +% if mfun_shade_step > 0 : +% withprescript "sh_bound_" & decimal mfun_shade_step & "=" & decimal a +% fi +% enddef ; + +def withshadefraction expr a = + if mfun_shade_step > 0 : + withprescript "sh_fraction_" & decimal mfun_shade_step & "=" & decimal a + fi +enddef ; + +def withshadecolors (expr a, b) = + if mfun_shade_step > 0 : + withprescript "sh_color=into" + withprescript "sh_color_a_" & decimal mfun_shade_step & "=" & colordecimals a + withprescript "sh_color_b_" & decimal mfun_shade_step & "=" & colordecimals b + else : + withprescript "sh_color=into" + withprescript "sh_color_a=" & colordecimals a + withprescript "sh_color_b=" & colordecimals b + fi +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 ; + elseif (n=2) : a := lrcorner p ; b := ulcorner p ; + elseif (n=3) : a := urcorner p ; b := llcorner p ; + elseif (n=4) : a := ulcorner p ; b := lrcorner p ; + elseif (n=5) : a := .5[ulcorner p,llcorner p] ; b := .5[urcorner p,lrcorner p] ; + elseif (n=6) : a := .5[llcorner p,lrcorner p] ; b := .5[ulcorner p,urcorner p] ; + elseif (n=7) : a := .5[lrcorner p,urcorner p] ; b := .5[llcorner p,ulcorner p] ; + elseif (n=8) : a := .5[urcorner p,ulcorner p] ; b := .5[lrcorner p,llcorner p] ; + else : a := .5[ulcorner p,llcorner p] ; b := .5[urcorner p,lrcorner p] ; + fi ; +enddef ; + +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 ; + elseif (n=4) : ab := ulcorner p ; + else : ab := center p ; r := .5r ; + fi ; +enddef ; + +def circular_shade (expr p, n, ca, cb) = + begingroup ; + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + fill p withcircularshade(ab,ab,0,r,ca,cb) ; + if trace_shades : + drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +def linear_shade (expr p, n, ca, cb) = + begingroup ; + save a, b ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + fill p withlinearshade(a,b,ca,cb) ; + if trace_shades : + drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +string mfun_defined_cs_pre[] ; numeric mfun_defined_cs ; mfun_defined_cs := 0 ; + +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=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 ; + +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=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 ; + +% 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 ; +% set_linear_vector(a,b)(p,n) ; +% define_linear_shade (a,b,ca,cb) +% enddef ; +% +% vardef predefined_circular_shade (expr p, n, ca, cb) = +% save ab, r ; pair ab ; numeric r ; +% r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; +% set_circular_vector(ab,r)(p,n) ; +% define_circular_shade(ab,ab,0,r,ca,cb) +% enddef ; + +% Layers + +def onlayer primary name = + withprescript "la_name=" & name +enddef ; + +% Figures + +% def externalfigure primary filename = +% doexternalfigure (filename) +% enddef ; +% +% def doexternalfigure (expr filename) text transformation = +% if true : % a bit incompatible esp scaled 1cm now scaled the natural size +% draw rawtextext("\externalfigure[" & filename & "]") transformation ; +% else : +% draw unitsquare transformation withprescript "fg_name=" & filename ; +% fi ; +% enddef ; + +def withmask primary filename = + withprescript "fg_mask=" & filename +enddef ; + +def externalfigure primary filename = + if false : + rawtextext("\externalfigure[" & filename & "]") + else : + image ( + addto currentpicture doublepath unitsquare + withprescript "fg_name=" & filename ; + ) +% unitsquare +% withpen pencircle scaled 0 +% withprescript "fg_name=" & filename + fi +enddef ; + +def figure primary filename = + rawtextext("\externalfigure[" & filename & "]") +enddef ; + +% Positions + +def register (expr tag, width, height, offset) = +% draw image ( + addto currentpicture doublepath unitsquare xscaled width yscaled height shifted offset + withprescript "ps_label=" & tag ; +% ) ; % no transformations +enddef ; + +% outlines (todo: pass around less arguments) + +numeric currentoutlinetext ; currentoutlinetext := 0 ; + +vardef mfun_do_outline_text_flush (expr kind, n, x, y) (text t) = + if kind = "f" : + mfun_do_outline_text_f (n, x, y) (t) + elseif kind = "d" : + mfun_do_outline_text_d (n, x, y) (t) + elseif kind = "b" : + mfun_do_outline_text_b (n, x, y) (t) + elseif kind = "r" : + mfun_do_outline_text_r (n, x, y) (t) + elseif kind = "p" : + mfun_do_outline_text_p (n, x, y) (t) + else : + mfun_do_outline_text_n (n, x, y) (t) + fi ; +enddef ; + +numeric mfun_do_outline_n ; mfun_do_outline_n := 0 ; + +vardef mfun_do_outline_text_f (expr n, x, y) (text t) = + mfun_do_outline_n := 0 ; + for i=t : + mfun_do_outline_n := mfun_do_outline_n + 1 ; + if mfun_do_outline_n = n : + fill i shifted(x,y) mfun_do_outline_options_f + else : + nofill i shifted(x,y) + fi ; + endfor ; +enddef ; + +vardef mfun_do_outline_text_d (expr n, x, y) (text t) = + for i=t : + draw i shifted(x,y) mfun_do_outline_options_d ; + endfor ; +enddef ; + +vardef mfun_do_outline_text_p (expr n, x, y) (text t) = + for i=t : + draw i shifted(x,y) ; + endfor ; +enddef ; + +vardef mfun_do_outline_text_b (expr n, x, y) (text t) = + mfun_do_outline_n := 0 ; + for i=t : + mfun_do_outline_n := mfun_do_outline_n + 1 ; + if mfun_do_outline_n = n : + fill i shifted(x,y) mfun_do_outline_options_f + else : + nofill i shifted(x,y) + fi ; + endfor ; + for i=t : + draw i shifted(x,y) mfun_do_outline_options_d ; + endfor ; +enddef ; + +vardef mfun_do_outline_text_r (expr n, x, y) (text t) = + mfun_do_outline_n := 0 ; + for i=t : + draw i shifted(x,y) mfun_do_outline_options_d ; + endfor ; + for i=t : + mfun_do_outline_n := mfun_do_outline_n + 1 ; + if mfun_do_outline_n = n : + fill i shifted(x,y) mfun_do_outline_options_f + else : + nofill i shifted(x,y) + fi ; + endfor ; +enddef ; + +vardef mfun_do_outline_text_n (expr n, x, y) (text t) = + mfun_do_outline_n := 0 ; + for i=t : + mfun_do_outline_n := mfun_do_outline_n + 1 ; + if mfun_do_outline_n = n : fill else : nofill fi i shifted(x,y) ; + endfor ; +enddef ; + +vardef mfun_do_outline_text_set_f (text f) text r = + def mfun_do_outline_options_f = f enddef ; + def mfun_do_outline_options_r = r enddef ; +enddef ; + +vardef mfun_do_outline_text_set_d (text d) text r = + def mfun_do_outline_options_d = d enddef ; + def mfun_do_outline_options_r = r enddef ; +enddef ; + +vardef mfun_do_outline_text_set_b (text f) (text d) text r = + def mfun_do_outline_options_f = f enddef ; + def mfun_do_outline_options_d = d enddef ; + def mfun_do_outline_options_r = r enddef ; +enddef ; + +vardef mfun_do_outline_text_set_r (text d) (text f) text r = + def mfun_do_outline_options_d = d enddef ; + def mfun_do_outline_options_f = f enddef ; + def mfun_do_outline_options_r = r enddef ; +enddef ; + +vardef mfun_do_outline_text_set_n text r = + def mfun_do_outline_options_r = r enddef ; +enddef ; + +vardef mfun_do_outline_text_set_p = +enddef ; + +def mfun_do_outline_options_d = enddef ; +def mfun_do_outline_options_f = enddef ; +def mfun_do_outline_options_r = enddef ; + +vardef outlinetext@# (expr t) text rest = + save kind ; string kind ; kind := str @# ; + currentoutlinetext := currentoutlinetext + 1 ; + image ( normaldraw image ( + if mfun_trial_run : + % lua.mp.report("set outline text",currentoutlinetext); + normaldraw unitsquare + withprescript "ot_stage=trial" + withprescript "ot_index=" & decimal currentoutlinetext + withprescript "ot_kind=" & kind + withpostscript t ; + else : + % lua.mp.report("get outline text",currentoutlinetext); + if kind = "f" : + mfun_do_outline_text_set_f rest ; + elseif kind = "d" : + mfun_do_outline_text_set_d rest ; + elseif kind = "b" : + mfun_do_outline_text_set_b rest ; + elseif kind = "r" : + mfun_do_outline_text_set_r rest ; + elseif kind = "p" : + mfun_do_outline_text_set_p ; + else : + mfun_do_outline_text_set_n rest ; + fi ; + lua.mp.get_outline_text(currentoutlinetext) ; + fi ; + ) mfun_do_outline_options_r ; ) +enddef ; + +% A few helpers: + +numeric mfun_c_b_llx, mfun_c_b_h, mfun_c_b_w, mfun_c_b_l ; + +vardef checkedbounds(expr llx,lly,urx,ury) = + mfun_c_b_llx := min(xpart llcorner currentpicture,llx) ; + mfun_c_b_urx := max(xpart urcorner currentpicture,urx) ; + mfun_c_b_lly := min(ypart llcorner currentpicture,lly) ; + mfun_c_b_ury := max(ypart urcorner currentpicture,ury) ; + (mfun_c_b_llx,mfun_c_b_lly) -- + (mfun_c_b_urx,mfun_c_b_lly) -- + (mfun_c_b_urx,mfun_c_b_ury) -- + (mfun_c_b_llx,mfun_c_b_ury) -- cycle +enddef ; + +vardef checkbounds(expr llx,lly,urx,ury) = + setbounds currentpicture to checkedbounds(llx,lly,urx,ury) ; +enddef ; + +vardef strut(expr ht,dp) = + setbounds currentpicture to checkedbounds(0,0,ht,dp) ; +enddef ; + +vardef rule(expr wd,ht,dp) = + image (fill (0,-dp)--(wd,-dp)--(wd,ht)--(0,ht)--cycle) +enddef ; + + +% Housekeeping + +extra_beginfig := extra_beginfig & "currentgraphictext := 0 ; " ; +extra_beginfig := extra_beginfig & "currentoutlinetext := 0 ; " ; +extra_endfig := extra_endfig & "finishsavingdata ; " ; +extra_endfig := extra_endfig & "mfun_reset_tex_texts ; " ; + +% Bonus + +vardef verbatim(expr s) = + ditto & "\detokenize{" & s & "}" & ditto +enddef ; + +% New + +def bitmapimage(expr xresolution, yresolution, data) = + image ( + addto currentpicture doublepath unitsquare + withprescript "bm_xresolution=" & decimal xresolution + withprescript "bm_yresolution=" & decimal yresolution + withpostscript data ; + ) +enddef ; + +% Experimental: +% +% property p ; p = properties(withcolor (1,1,0,0)) ; +% fill fullcircle scaled 20cm withproperties p ; + +let property = picture ; + +vardef properties(text t) = + image(draw unitcircle t) +enddef ; + +if metapostversion < 1.770 : + + def withproperties expr p = + if colormodel p = 3 : + withcolor greypart p + elseif colormodel p = 5 : + withcolor (redpart p,greenpart p,bluepart p) + elseif colormodel p = 7 : + withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p) + fi + enddef ; + +else : + + def withproperties expr p = + if colormodel p = 3 : + withcolor greypart p + elseif colormodel p = 5 : + withcolor (redpart p,greenpart p,bluepart p) + elseif colormodel p = 7 : + withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p) + fi + withprescript prescriptpart p + withpostscript postscriptpart p + enddef ; + +fi ; + +% Experimental: + +primarydef t asgroup s = % s = isolated|knockout + begingroup + save grouppicture, wrappedpicture, groupbounds ; + picture grouppicture, wrappedpicture ; path groupbounds ; + grouppicture := if picture t : t else : image(draw t) fi ; + groupbounds := boundingbox grouppicture ; + wrappedpicture:= nullpicture ; + addto wrappedpicture contour groupbounds + withprescript "gr_state=start" + withprescript "gr_type=" & s + withprescript "gr_llx=" & decimal xpart llcorner groupbounds + withprescript "gr_lly=" & decimal ypart llcorner groupbounds + withprescript "gr_urx=" & decimal xpart urcorner groupbounds + withprescript "gr_ury=" & decimal ypart urcorner groupbounds ; + addto wrappedpicture also grouppicture ; + addto wrappedpicture contour groupbounds + withprescript "gr_state=stop" ; + wrappedpicture + endgroup +enddef ; + +% Also experimental ... needs to be made better ... so it can change! + +string mfun_auto_align[] ; + +mfun_auto_align[0] := "rt" ; +mfun_auto_align[1] := "urt" ; +mfun_auto_align[2] := "top" ; +mfun_auto_align[3] := "ulft" ; +mfun_auto_align[4] := "lft" ; +mfun_auto_align[5] := "llft" ; +mfun_auto_align[6] := "bot" ; +mfun_auto_align[7] := "lrt" ; +mfun_auto_align[8] := "rt" ; + +def autoalign(expr n) = + scantokens mfun_auto_align[round((n mod 360)/45)] +enddef ; + +% draw textext.autoalign(60) ("\strut oeps 1") ; +% draw textext.autoalign(160)("\strut oeps 2") ; +% draw textext.autoalign(260)("\strut oeps 3") ; +% draw textext.autoalign(360)("\strut oeps 4") ; + +% new +% +% passvariable("version","1.0") ; +% passvariable("number",123) ; +% passvariable("string","whatever") ; +% passvariable("point",(1,2)) ; +% passvariable("triplet",(1,2,3)) ; +% passvariable("quad",(1,2,3,4)) ; +% 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) & " " & + decimal xpart (precontrol i of p) & " " & + decimal ypart (precontrol i of p) & " " & + decimal xpart (postcontrol i of p) & " " & + decimal ypart (postcontrol i of p) +enddef ; + +vardef mfun_transform_to_string(expr t) = + decimal xxpart t & " " & % rx + decimal xypart t & " " & % sx + decimal yxpart t & " " & % sy + decimal yypart t & " " & % ry + decimal xpart t & " " & % tx + decimal ypart t % ty +enddef ; + +vardef mfun_numeric_to_string(expr n) = + decimal n +enddef ; + +vardef mfun_pair_to_string(expr p) = + decimal xpart p & " " & + decimal ypart p +enddef ; + +vardef mfun_rgbcolor_to_string(expr c) = + decimal redpart c & " " & + decimal greenpart c & " " & + decimal bluepart c +enddef ; + +vardef mfun_cmykcolor_to_string(expr c) = + decimal cyanpart c & " " & + decimal magentapart c & " " & + decimal yellowpart 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 ; + +vardef mfun_boolean_to_string(expr b) = + if b : "true" else : "false" fi +enddef ; + +% def passvariable(expr key, value) = +% special +% if numeric value : "1:" & key & "=" & mfun_numeric_to_string(value) +% elseif pair value : "4:" & key & "=" & mfun_pair_to_string(value) +% elseif rgbcolor value : "5:" & key & "=" & mfun_rgbcolor_to_string(value) +% elseif cmykcolor value : "6:" & key & "=" & mfun_cmykcolor_to_string(value) +% elseif boolean value : "3:" & key & "=" & mfun_boolean_to_string(value) +% elseif path value : "7:" & key & "=" & mfun_path_to_string(value) +% elseif transform value : "8:" & key & "=" & mfun_transform_to_string(value) +% else : "2:" & key & "=" & value +% fi ; +% enddef ; + +vardef tostring(expr value) = + if numeric value : mfun_numeric_to_string(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) + else : value + fi +enddef ; + +vardef mfun_tagged_string(expr value) = + if numeric value : "1:" & mfun_numeric_to_string(value) + elseif pair value : "4:" & mfun_pair_to_string(value) + elseif rgbcolor value : "5:" & mfun_rgbcolor_to_string(value) + elseif cmykcolor value : "6:" & mfun_cmykcolor_to_string(value) + elseif boolean value : "3:" & mfun_boolean_to_string(value) + elseif path value : "7:" & mfun_path_to_string(value) + elseif transform value : "8:" & mfun_transform_to_string(value) + else : "2:" & value + fi +enddef ; + +% amore flexible variant for passing data to context + +vardef mfun_point_to_lua(expr p,i) = + "{" & + decimal xpart (point i of p) & "," & + decimal ypart (point i of p) & "," & + decimal xpart (precontrol i of p) & "," & + decimal ypart (precontrol i of p) & "," & + decimal xpart (postcontrol i of p) & "," & + decimal ypart (postcontrol i of p) + & "}" +enddef ; + +vardef mfun_transform_to_lua(expr t) = + "{" & + decimal xxpart t & "," & % rx + decimal xypart t & "," & % sx + decimal yxpart t & "," & % sy + decimal yypart t & "," & % ry + decimal xpart t & "," & % tx + decimal ypart t % ty + & "}" +enddef ; + +vardef mfun_numeric_to_lua(expr n) = + decimal n +enddef ; + +vardef mfun_pair_to_lua(expr p) = + "{" & + decimal xpart p & "," & + decimal ypart p + & "}" +enddef ; + +vardef mfun_rgbcolor_to_lua(expr c) = + "{" & + decimal redpart c & "," & + decimal greenpart c & "," & + decimal bluepart c + & "}" +enddef ; + +vardef mfun_cmykcolor_to_lua(expr c) = + "{" & + decimal cyanpart c & "," & + decimal magentapart c & "," & + decimal yellowpart c & "," & + decimal blackpart c + & "}" +enddef ; + +vardef mfun_path_to_lua(expr p) = + "{" & + mfun_point_to_lua(p,0) for i=1 upto length(p) : & "," & mfun_point_to_lua(p,i) endfor + & "}" +enddef ; + +vardef mfun_boolean_to_lua(expr b) = + if b : "true" else : "false" fi +enddef ; + +vardef mfun_string_to_lua(expr s) = + "[==[" & s & "]==]" +enddef ; + +def mfun_to_lua(expr key)(expr value)(text t) = + special "metapost.variables['" & key & "']=" & t(value) ; +enddef ; + +def mfun_array_to_lua(expr key)(suffix value)(expr first, last, stp)(text t) = + special + "metapost.variables['" & key & "']={" + for i=first step stp until last : + & "[" & decimal i & "]=" & t(value[i]) & "," + endfor + & "}" ; +enddef ; + +def passvariable(expr key, value) = + if numeric value : mfun_to_lua(key,value,mfun_numeric_to_lua) + elseif pair value : mfun_to_lua(key,value,mfun_pair_to_lua) + elseif string value : mfun_to_lua(key,value,mfun_string_to_lua) + elseif boolean value : mfun_to_lua(key,value,mfun_boolean_to_lua) + elseif path value : mfun_to_lua(key,value,mfun_path_to_lua) + elseif rgbcolor value : mfun_to_lua(key,value,mfun_rgbcolor_to_lua) + elseif cmykcolor value : mfun_to_lua(key,value,mfun_cmykcolor_to_lua) + elseif transform value : mfun_to_lua(key,value,mfun_transform_to_lua) + fi ; +enddef ; + +def passarrayvariable(expr key)(suffix values)(expr first, last, stp) = + if numeric values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_numeric_to_lua) + elseif pair values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_pair_to_lua) + elseif string values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_string_to_lua) + elseif boolean values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_boolean_to_lua) + elseif path values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_path_to_lua) + elseif rgbcolor values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_rgbcolor_to_lua) + elseif cmykcolor values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_cmykcolor_to_lua) + elseif transform values[first] : mfun_array_to_lua(key,values,first,last,stp,mfun_transform_to_lua) + fi ; +enddef ; + +def startpassingvariable(expr k) = + begingroup ; + save stoppassingvariable, startarray, stoparray, starthash, stophash, index, key, value, slot, entry ; + let stoppassingvariable = mfun_stop_lua_variable ; + let startarray = mfun_start_lua_array ; + let stoparray = mfun_stop_lua_array ; + let starthash = mfun_start_lua_hash ; + let stophash = mfun_stop_lua_hash ; + let index = mfun_lua_index ; + let key = mfun_lua_key ; + let value = mfun_lua_value ; + let slot = mfun_lua_slot ; + let entry = mfun_lua_entry ; + save s ; string s ; + s := "metapost.variables['" & k & "']=" +enddef ; + +def mfun_stop_lua_variable = + ; + special substring(0,length(s)-1) of s ; + endgroup ; +enddef ; + +% currently there is no difference between array and hash + +def mfun_start_lua_array = + & "{" +enddef ; + +def mfun_stop_lua_array = + & "}," +enddef ; + +def mfun_start_lua_hash = + & "{" +enddef ; + +def mfun_stop_lua_hash = + & "}," +enddef ; + +def mfun_lua_key(expr k) = + & "['" & k & "']=" +enddef ; + +def mfun_lua_index(expr k) = + & "[" & decimal k & "]=" +enddef ; + +def mfun_lua_value(expr v) = + if numeric v : & mfun_numeric_to_lua(v) & "," + elseif pair v : & mfun_pair_to_lua(v) & "," + elseif string v : & mfun_string_to_lua(v) & "," + elseif boolean v : & mfun_boolean_to_lua(v) & "," + elseif path v : & mfun_path_to_lua(v) & "," + elseif rgbcolor v : & mfun_rgbcolor_to_lua(v) & "," + elseif cmykcolor v : & mfun_cmykcolor_to_lua(v) & "," + elseif transform v : & mfun_transform_to_lua(v) & "," + fi +enddef ; + +def mfun_lua_entry(expr k, v) = + mfun_lua_key(k) + mfun_lua_value(v) +enddef ; + +def mfun_lua_slot(expr k, v) = + mfun_lua_index(k) + mfun_lua_value(v) +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) = + 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) = "\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 fillup text t = draw t withpostscript "both" enddef ; % we use draw because we need the proper boundingbox +def eofillup text t = draw t withpostscript "eoboth" enddef ; % we use draw because we need the proper boundingbox +def eofill text t = fill t withpostscript "evenodd" enddef ; +def nofill text t = fill t withpostscript "collect" enddef ; +%%% 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/mpiv/mp-page.mpiv b/metapost/context/base/mpiv/mp-page.mpiv new file mode 100644 index 000000000..2e4a2b437 --- /dev/null +++ b/metapost/context/base/mpiv/mp-page.mpiv @@ -0,0 +1,695 @@ +%D \module +%D [ file=mp-page.mpiv, +%D version=1999.03.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=page enhancements, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D 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 ; + +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 ; + +def SwapPageState = + mfun_swapped := true ; % eventually this will go ! +enddef ; + +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 ; + +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 ; +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 + +numeric HorPos ; HorPos := 0 ; +numeric VerPos ; VerPos := 0 ; + +% 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[] ; +% +% 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 SetPageAreas = +% +% numeric Vsize[], Hsize[], Vstep[], Hstep[] ; +% +% Vsize[Top] = TopHeight ; +% Vsize[TopSeparator] = TopDistance ; +% Vsize[Header] = HeaderHeight ; +% Vsize[HeaderSeparator] = HeaderDistance ; +% Vsize[Text] = TextHeight ; +% Vsize[FooterSeparator] = FooterDistance ; +% Vsize[Footer] = FooterHeight ; +% Vsize[BottomSeparator] = BottomDistance ; +% Vsize[Bottom] = BottomHeight ; +% +% Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; +% Vstep[TopSeparator] = PaperHeight-TopSpace ; +% Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; +% Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; +% Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; +% Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; +% Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; +% Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; +% Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; +% +% Hsize[LeftEdge] = LeftEdgeWidth ; +% Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; +% Hsize[LeftMargin] = LeftMarginWidth ; +% Hsize[LeftMarginSeparator] = LeftMarginDistance ; +% Hsize[Text] = MakeupWidth ; +% Hsize[RightMarginSeparator] = RightMarginDistance ; +% Hsize[RightMargin] = RightMarginWidth ; +% Hsize[RightEdgeSeparator] = RightEdgeDistance ; +% Hsize[RightEdge] = RightEdgeWidth ; +% +% Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; +% Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; +% Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; +% Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; +% Hstep[Text] = BackSpace ; +% Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; +% Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; +% Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; +% Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; +% +% for VerPos=Top step 10 until Bottom: +% for HorPos=LeftEdge step 1 until RightEdge: +% Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; +% Area[VerPos][HorPos] := Area[HorPos][VerPos] ; +% Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; +% Location[VerPos][HorPos] := Location[HorPos][VerPos] ; +% Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ; +% Field[VerPos][HorPos] := Field[HorPos][VerPos] ; +% endfor ; +% endfor ; +% +% Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; +% +% enddef ; +% +% def BoundPageAreas = +% % pickup pencircle scaled 0pt ; +% bboxmargin := 0 ; setbounds currentpicture to Page ; +% enddef ; +% +% def StartPage = +% begingroup ; +% if PageStateAvailable : +% LoadPageState ; +% SwapPageState ; +% fi ; +% SetPageAreas ; +% BoundPageAreas ; +% enddef ; +% +% def StopPage = +% BoundPageAreas ; +% endgroup ; +% enddef ; + +% Because metapost > 1.50 has dynamic memory management and is less +% efficient than before we now delay calculations ... (on a document +% with 150 pages the time spent in mp was close to 5 seconds which was +% only due to initialising the page related areas, something that was +% hardly noticeable before. At least now we're back to half a second +% for such a case. + +def SetPageVsize = + numeric Vsize[] ; + Vsize[Top] = TopHeight ; + Vsize[TopSeparator] = TopDistance ; + Vsize[Header] = HeaderHeight ; + Vsize[HeaderSeparator] = HeaderDistance ; + Vsize[Text] = TextHeight ; + Vsize[FooterSeparator] = FooterDistance ; + Vsize[Footer] = FooterHeight ; + Vsize[BottomSeparator] = BottomDistance ; + Vsize[Bottom] = BottomHeight ; +enddef ; + +def SetPageHsize = + numeric Hsize[] ; + Hsize[LeftEdge] = LeftEdgeWidth ; + Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; + Hsize[LeftMargin] = LeftMarginWidth ; + Hsize[LeftMarginSeparator] = LeftMarginDistance ; + Hsize[Text] = MakeupWidth ; + Hsize[RightMarginSeparator] = RightMarginDistance ; + Hsize[RightMargin] = RightMarginWidth ; + Hsize[RightEdgeSeparator] = RightEdgeDistance ; + Hsize[RightEdge] = RightEdgeWidth ; +enddef ; + +def SetPageVstep = + numeric Vstep[] ; + Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; + Vstep[TopSeparator] = PaperHeight-TopSpace ; + Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; + Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; + Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; + Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; + Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; + Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; + Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; +enddef ; + +def SetPageHstep = + numeric Hstep[] ; + Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; + Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; + Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; + Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; + Hstep[Text] = BackSpace ; + Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; + Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; + Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; + Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; +enddef ; + +def SetPageArea = + path Area[][] ; + for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; + Area[VerPos][HorPos] := Area[HorPos][VerPos] ; + endfor ; + endfor ; +enddef ; + +def SetPageLocation = + pair Location[][] ; + for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; + Location[VerPos][HorPos] := Location[HorPos][VerPos] ; + endfor ; + endfor ; +enddef ; + +def SetPageField = + path Field[][] ; + for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Field[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] shifted (Hstep[HorPos],Vstep[VerPos]) ; + Field[VerPos][HorPos] := Field[HorPos][VerPos] ; + endfor ; + endfor ; +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 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 ; + +% 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 = + 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 ; + +let SetPageAreas = SetPageVariables ; % compatiblity + +def BoundPageAreas = + % pickup pencircle scaled 0pt ; + bboxmargin := 0 ; setbounds currentpicture to Page ; +enddef ; + +def StartPage = + begingroup ; + if mfun_first_run : + if PageStateAvailable : + LoadPageState ; + SwapPageState ; + fi ; + SetPageVariables ; + fi ; + BoundPageAreas ; +enddef ; + +def StopPage = + BoundPageAreas ; + endgroup ; +enddef ; + +% cover pages + +def BoundCoverAreas = + % todo: add cropmarks + bboxmargin := 0 ; setbounds currentpicture to CoverPage enlarged PaperBleed ; +enddef ; + +let SetCoverAreas = SetPageVariables ; % compatiblity + +def StartCover = + begingroup ; + if mfun_first_run : + if PageStateAvailable : + LoadPageState ; + % SwapPageState ; + fi ; + SetPageVariables ; % was SetPageAreas ; + SetCoverAreas ; + fi ; + BoundCoverAreas ; +enddef ; + +def StopCover = + BoundCoverAreas ; + endgroup ; +enddef ; + +% overlays: + +def OverlayBox = + (unitsquare xyscaled (OverlayWidth,OverlayHeight)) +enddef ; + +% handy + +def innerenlarged = + hide(LoadPageState) + if OnRightPage : leftenlarged else : rightenlarged fi +enddef ; + +def outerenlarged = + hide(LoadPageState) + if OnRightPage : rightenlarged else : leftenlarged fi +enddef ; + +% obsolete + +def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ; +def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ; +def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ; +def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ; + +def Enlarged (expr p, d) = + (llEnlarged (p,d) -- + lrEnlarged (p,d) -- + urEnlarged (p,d) -- + ulEnlarged (p,d) -- cycle) +enddef ; + +% for the moment we put these here: + +string RuleDirection ; RuleDirection := "" ; +string RuleOption ; RuleOption := "" ; +numeric RuleWidth ; RuleWidth := 0 ; +numeric RuleHeight ; RuleHeight := 0 ; +numeric RuleDepth ; RuleDepth := 0 ; +numeric RuleThickness ; RuleThickness := 0 ; +numeric RuleFactor ; RuleFactor := 0 ; +numeric RuleOffset ; RuleOffset := 0 ; + def RuleColor = (.5white) enddef ; + +def FakeWord(expr RuleWidth, RuleHeight, RuleDepth, RuleThickness) (text RuleColor) = + fill unitsquare + xscaled RuleWidth + yscaled (RuleDepth-RuleThickness/2) + withcolor RuleColor ; + fill unitsquare + xscaled RuleWidth + yscaled (RuleHeight-RuleDepth-RuleThickness/2) + shifted (0,RuleDepth+RuleThickness) + withcolor RuleColor ; +enddef ; + +def FakeRule(expr RuleWidth, RuleHeight, RuleDepth, RuleThickness) (text RuleColor) = + fill unitsquare + xscaled RuleWidth + yscaled RuleHeight + withcolor RuleColor ; +enddef ; diff --git a/metapost/context/base/mpiv/mp-shap.mpiv b/metapost/context/base/mpiv/mp-shap.mpiv new file mode 100644 index 000000000..713656510 --- /dev/null +++ b/metapost/context/base/mpiv/mp-shap.mpiv @@ -0,0 +1,218 @@ +%D \module +%D [ file=mp-shap.mpiv, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=shapes, +%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_shap : endinput ; fi ; + +boolean context_shap ; context_shap := true ; + +path predefined_shapes[] ; + +def start_predefined_shape_definition = + + begingroup ; + + save xradius, yradius, xxradius, yyradius ; + save ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; + + numeric xradius, yradius, xxradius, yyradius ; + pair ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ; + + xradius := .15 ; + yradius := .15 ; + xxradius := .10 ; + yyradius := .10 ; + + ll := llcorner (unitsquare shifted (-.5,-.5)) ; + lr := lrcorner (unitsquare shifted (-.5,-.5)) ; + ur := urcorner (unitsquare shifted (-.5,-.5)) ; + ul := ulcorner (unitsquare shifted (-.5,-.5)) ; + + llx := ll shifted (xradius,0) ; + lly := ll shifted (0,yradius) ; + + lrx := lr shifted (-xradius,0) ; + lry := lr shifted (0,yradius) ; + + urx := ur shifted (-xradius,0) ; + ury := ur shifted (0,-yradius) ; + + ulx := ul shifted (xradius,0) ; + uly := ul shifted (0,-yradius) ; + + llxx := ll shifted (xxradius,0) ; + llyy := ll shifted (0,yyradius) ; + + lrxx := lr shifted (-xxradius,0) ; + lryy := lr shifted (0,yyradius) ; + + urxx := ur shifted (-xxradius,0) ; + uryy := ur shifted (0,-yyradius) ; + + ulxx := ul shifted (xxradius,0) ; + ulyy := ul shifted (0,-yyradius) ; + + lc := ll shifted (0,.5) ; + rc := lr shifted (0,.5) ; + tc := ul shifted (.5,0) ; + bc := ll shifted (.5,0) ; + +enddef ; + +def stop_predefined_shape_definition = + + endgroup ; + +enddef ; + +start_predefined_shape_definition ; + + predefined_shapes[ 0] := (origin--cycle) ; + predefined_shapes[ 5] := (llx--lrx{right}...rc...{left}urx--ulx{left}...lc...{right}cycle) ; + predefined_shapes[ 6] := (ll--lrx{right}...rc...{left}urx--ul--cycle) ; + predefined_shapes[ 7] := (ll--lrx{right}...rc...{left}urx--ul--cycle) rotatedaround(origin,180) ; + predefined_shapes[ 8] := (lr--ury{up}...tc...{down}uly--ll--cycle) ; + predefined_shapes[ 9] := (lr--ury{up}...tc...{down}uly--ll--cycle) rotatedaround(origin,180) ; + predefined_shapes[10] := (ll--lr--ur--ul--ll--ur--ul--ll--cycle) ; + predefined_shapes[11] := (ll--lr--ur--ul--ll--lr--ul--ll--cycle) ; + predefined_shapes[12] := (ll--lrx--ur--ulx--cycle) ; + predefined_shapes[13] := (llx--lr--urx--ul--cycle) ; + predefined_shapes[14] := (lly--bc--lry--ury--tc--uly--cycle) ; + predefined_shapes[15] := (llx--lrx--rc--urx--ulx--lc--cycle) ; + predefined_shapes[16] := (ll--lrx--rc--urx--ul--cycle) ; + predefined_shapes[17] := (ll--lrx--rc--urx--ul--cycle) rotatedaround(origin,180) ; + predefined_shapes[18] := (lr--ury--tc--uly--ll--cycle) ; + predefined_shapes[19] := (lr--ury--tc--uly--ll--cycle) rotatedaround(origin,180) ; + predefined_shapes[20] := (ll--lr--ur--ul--ll--llxx--ulxx--ul--ll--lr--ur--urxx--lrxx--cycle) ; + predefined_shapes[21] := (ul--ll--lr--ur--ul--ulyy--uryy--ur--ul--ll--lr--lryy--llyy--cycle) ; + predefined_shapes[22] := (ll--lrx--lry--ur--ulx--uly--cycle) ; + predefined_shapes[23] := (llx--lr--ury--urx--ul--lly--cycle) ; + predefined_shapes[24] := (ll--lr--ur--ul--cycle) ; + predefined_shapes[25] := (llx--lrx--lry--ury--urx--ulx--uly--lly--cycle) ; + predefined_shapes[26] := (ll--lrx--lry--ur--ul--cycle) ; + predefined_shapes[27] := (ll--lr--ury--urx--ul--cycle) rotatedaround(origin,180) ; + predefined_shapes[28] := (ll--lr--ury--urx--ul--cycle) ; + predefined_shapes[29] := (ll--lrx--lry--ur--ul--cycle) rotatedaround(origin,180) ; + predefined_shapes[30] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) rotated 45; + predefined_shapes[31] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; + predefined_shapes[32] := (ll{right}...{right}lry--ur--ul--ll--cycle) ; + predefined_shapes[33] := (ll{right}...{right}lry--ur--ul--ll--cycle--ul--ulx--ulx shifted(0,yyradius)--ur shifted(yyradius,yyradius)--lry shifted(yyradius,yyradius)--lry shifted(0,yyradius)--ur--ul--cycle ) ; + predefined_shapes[34] := (uly..tc..ury & ury..tc shifted (0,-2yradius)..uly & uly--lly & lly..bc..lry & lry--ury & ury..tc shifted (0,-2yradius)..uly & cycle ) ; + predefined_shapes[35] := (bc{right}...rc{up}...tc{left}...lc{down}...cycle) ; + predefined_shapes[36] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) ; + predefined_shapes[37] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) rotatedaround(origin,180) ; + predefined_shapes[38] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) ; + predefined_shapes[39] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) rotatedaround(origin,180) ; + predefined_shapes[40] := (ll--lr--ur--ul--ll--ur--ul--ll--lr--ul--ll--cycle) ; + predefined_shapes[41] := (ll--lr--ur--ul--ll--lr--rc--lc--ll--bc--tc--ul--ll & cycle) ; + predefined_shapes[42] := (ll--lr--origin shifted (+epsilon,0)--ur--ul--origin shifted (-epsilon,0)--cycle) ; + predefined_shapes[43] := (ll--ul--origin shifted (0,+epsilon)--ur--lr--origin shifted (0,-epsilon)--cycle) ; + predefined_shapes[45] := (bc--rc--tc--lc--cycle) ; + predefined_shapes[46] := (ll--ul--rc--cycle) ; + predefined_shapes[47] := (ll--ul--rc--cycle) rotatedaround(origin,180) ; + predefined_shapes[48] := (ul--ur--bc--cycle) rotatedaround(origin,180) ; + predefined_shapes[49] := (ul--ur--bc--cycle) ; + predefined_shapes[56] := (ll--lry--ury--ul--cycle) ; + predefined_shapes[57] := (ll--lry--ury--ul--cycle) rotatedaround(origin,180) ; + predefined_shapes[58] := (ll--ulx--urx--lr--cycle) ; + predefined_shapes[59] := (ll--ulx--urx--lr--cycle) rotatedaround(origin,180); + predefined_shapes[66] := (rc--origin shifted ( epsilon,0) --cycle & rc--origin--cycle ) ; + predefined_shapes[67] := (lc--origin shifted (-epsilon,0) --cycle & lc--origin--cycle ) ; + predefined_shapes[68] := (tc--origin shifted (0, epsilon) --cycle & tc--origin--cycle ) ; + predefined_shapes[69] := (bc--origin shifted (0,-epsilon) --cycle & bc--origin--cycle ) ; + predefined_shapes[75] := (lly--lry--ury--uly--cycle) rotatedaround(origin,180) ; + predefined_shapes[76] := (ll--lr--ur--uly--cycle) rotatedaround(origin,180) ; + predefined_shapes[77] := (ll--lr--ury--ul--cycle) rotatedaround(origin,180) ; + predefined_shapes[78] := (lly--lr--ur--ul--cycle) rotatedaround(origin,180) ; + predefined_shapes[79] := (ll--lry--ur--ul--cycle) rotatedaround(origin,180) ; + + numeric predefined_shapes_xradius ; predefined_shapes_xradius := xradius ; + numeric predefined_shapes_yradius ; predefined_shapes_yradius := yradius ; + numeric predefined_shapes_xxradius ; predefined_shapes_xxradius := xxradius ; + numeric predefined_shapes_yyradius ; predefined_shapes_yyradius := yyradius ; + +stop_predefined_shape_definition ; + +vardef some_shape_path (expr type) = + if known predefined_shapes[type] : predefined_shapes[type] else : predefined_shapes[0] fi +enddef ; + +def some_shape (expr shape_type, shape_width, shape_height, shape_linewidth, shape_linecolor, shape_fillcolor) = + begingroup ; + save p ; path p ; + p := some_shape_path (shape_type) xscaled shape_width yscaled shape_height ; + pickup pencircle scaled shape_linewidth ; + fill p withcolor shape_fillcolor ; + draw p withcolor shape_linecolor ; + endgroup ; +enddef ; + +vardef drawpredefinedshape (expr t, p, lw, lc, fc) = + save pp ; + if t>1 : % normal shape + path pp ; + pp := some_shape_path(t) xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + fill pp withcolor fc ; + draw pp withpen pencircle scaled lw withcolor lc ; + elseif t=1 : % background only + path pp ; + pp := fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + fill pp withcolor fc ; + else : % dimensions only + picture pp ; pp := nullpicture ; + setbounds pp to fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ; + draw pp ; + fi ; +enddef ; + +vardef drawpredefinedline (expr t, p, lw, lc) = + if (t>0) and (length(p)>1) : + saveoptions ; + drawoptions(withpen pencircle scaled lw withcolor lc) ; + draw p ; + if t = 1 : + draw arrowheadonpath(p,1) ; + elseif t = 2 : + draw arrowheadonpath(reverse p,1) ; + elseif t = 3 : + for $ = p,reverse p : + draw arrowheadonpath($,1) ; + endfor ; + elseif t = 11 : + draw arrowheadonpath(p,1/2) ; + elseif t = 12 : + draw arrowheadonpath(reverse p,1/2) ; + elseif t = 13 : + for $=p,reverse p : + draw arrowheadonpath($,1) ; + endfor ; + for $=p,reverse p : + draw arrowheadonpath($,3/4) ; + endfor ; + elseif t = 21 : + for $=1/5,1/2,4/5 : + draw arrowheadonpath(p,$) ; + endfor ; + elseif t = 22 : + for $=1/5,1/2,4/5 : + draw arrowheadonpath(reverse p,$) ; + endfor ; + elseif t = 23 : + for $=p,reverse p : + draw arrowheadonpath($,1/4) ; + endfor ; + fi ; + fi ; +enddef ; + +let drawshape = drawpredefinedshape ; +let drawline = drawpredefinedline ; diff --git a/metapost/context/base/mpiv/mp-step.mpiv b/metapost/context/base/mpiv/mp-step.mpiv new file mode 100644 index 000000000..f7a7ba5de --- /dev/null +++ b/metapost/context/base/mpiv/mp-step.mpiv @@ -0,0 +1,376 @@ +%D \module +%D [ file=mp-cell.mpiv, % mp-step.mpiv, +%D version=2010.10.07, % 2001.05.22, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=steps, +%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. + +% step prefixes .. no save needed + +if known context_cell : endinput ; fi ; + +boolean context_cell ; context_cell := true ; + +def initialize_step_variables = + save + text_fill_color, text_line_color, text_line_width, text_offset, + cell_fill_color, cell_line_color, cell_line_width, cell_offset, + line_line_color, line_line_width, line_alternative, + line_distance, cell_distance_y, cell_distance_x, + nofcells, chart_vertical ; + + color text_line_color ; text_line_color := red ; + color cell_line_color ; cell_line_color := blue ; + color line_line_color ; line_line_color := green ; + + color text_fill_color ; text_fill_color := white ; + color cell_fill_color ; cell_fill_color := white ; + + numeric text_line_width ; text_line_width := 2pt ; + numeric cell_line_width ; cell_line_width := 2pt ; + numeric line_line_width ; line_line_width := 2pt ; + + numeric text_offset ; text_offset := 4pt ; + numeric cell_offset ; cell_offset := 4pt ; + + numeric line_distance ; line_distance := 10pt ; % between line and text + numeric line_offset ; line_offset := 4pt ; % between center and start of line + numeric line_height ; line_height := 20pt ; + + numeric cell_distance_y ; cell_distance_y := 20pt ; + numeric cell_distance_x ; cell_distance_x := 20pt ; + + numeric text_distance_set ; text_distance_set := 4pt ; + + boolean chart_vertical ; chart_vertical := false ; + + numeric nofcells ; nofcells := 0 ; + +enddef ; + +def step_cells (expr t, b) = + nofcells := nofcells + 1 ; + cells_t[nofcells] := textext.d(t) ; + cells_b[nofcells] := textext.d(b) ; + texts_t[nofcells] := nullpicture ; + texts_m[nofcells] := nullpicture ; + texts_b[nofcells] := nullpicture ; +enddef ; + +def step_texts (expr t, b) = + texts_t[nofcells] := textext.d(t) ; + texts_m[nofcells] := textext.d(m) ; + texts_b[nofcells] := textext.d(b) ; +enddef ; + +def step_begin_cell = + nofcells := nofcells + 1 ; + cells_t[nofcells] := nullpicture ; + cells_b[nofcells] := nullpicture ; + texts_t[nofcells] := nullpicture ; + texts_m[nofcells] := nullpicture ; + texts_b[nofcells] := nullpicture ; +enddef ; + +def step_end_cell = +enddef ; + +def step_cell_top (expr t) = cells_t[nofcells] := textext.d(t) ; enddef ; +def step_cell_bot (expr b) = cells_b[nofcells] := textext.d(b) ; enddef ; +def step_text_top (expr t) = texts_t[nofcells] := textext.d(t) ; enddef ; +def step_text_mid (expr m) = texts_m[nofcells] := textext.d(m) ; enddef ; +def step_text_bot (expr b) = texts_b[nofcells] := textext.d(b) ; enddef ; + +def step_begin_chart = + begingroup ; + initialize_step_variables ; + save nofcells ; numeric nofcells ; nofcells := 0 ; + save cells_t, cells_m, cells_b ; picture cells_t[], cells_m[], cells_b[] ; + save texts_t, texts_m, texts_b ; picture texts_t[], texts_m[], texts_b[] ; +enddef ; + +def step_end_chart = + % we could combine some loops but this is cleaner + save dx, delta ; numeric dx, delta ; + save p ; path p ; + save one_row_only ; boolean one_row_only ; + save cell_t, next_t, text_t ; picture cell_t, next_t, text_t ; + save cell_m, next_m, text_m ; picture cell_m, next_m, text_m ; + save cell_b, next_b, text_b ; picture cell_b, next_b, text_b ; + save height_t, width_t, max_height_t, max_width_t ; numeric height_t, width_t, max_height_t, max_width_t ; + save height_m, width_m, max_height_m, max_width_m ; numeric height_m, width_m, max_height_m, max_width_m ; + save height_b, width_b, max_height_b, max_width_b ; numeric height_b, width_b, max_height_b, max_width_b ; + % check rows + one_row_only := true ; + for i=1 upto nofcells : + if bbwidth(cells_b[i]) > 0 : + one_row_only := false ; + fi ; + endfor ; + % swap and rotate + if chart_vertical : + if one_row_only : + % deal with mid_texts + max_width_t := max_width_m := max_width_b := 0 ; + for i=1 upto nofcells : + width_t := bbwidth(texts_t[i]) ; + width_m := bbwidth(texts_m[i]) ; + width_b := bbwidth(texts_b[i]) ; + if width_t > max_width_t : max_width_t := width_t fi ; + if width_m > max_width_m : max_width_m := width_m fi ; + if width_b > max_width_b : max_width_b := width_b fi ; + endfor ; + if max_width_m > 0 : + for i=1 upto nofcells : + text_t := texts_t[i] ; width_t := bbwidth(text_t) ; + text_m := texts_m[i] ; width_m := bbwidth(text_m) ; + text_b := texts_b[i] ; width_b := bbwidth(text_b) ; + if width_t < max_width_t : + setbounds text_t to boundingbox text_t leftenlarged (max_width_t - width_t) ; + fi ; + if width_m < max_width_m : + setbounds text_m to boundingbox text_m leftenlarged ((max_width_m - width_m)/2) ; + setbounds text_m to boundingbox text_m rightenlarged ((max_width_m - width_m)/2) ; + fi ; + if width_b < max_width_b : + setbounds text_b to boundingbox text_b rightenlarged (max_width_b - width_b) ; + fi ; + text_t := text_t shifted (- xpart llcorner text_t, 0) ; + text_m := text_m shifted (- xpart llcorner text_m, 0) ; + text_b := text_b shifted (- xpart llcorner text_b, 0) ; + texts_t[i] := image ( + draw text_t ; + draw text_m shifted (max_width_t + text_distance_set,0) ; + draw text_b shifted (max_width_t + max_width_m + 2*text_distance_set,0) ; + ) rotated 90 ; + texts_m[i] := texts_b[i] := nullpicture ; + cells_t[i] := cells_t[i] rotated 90 ; + endfor ; + else : + for i=1 upto nofcells : + cells_t[i] := cells_t[i] rotated 90 ; + texts_t[i] := texts_t[i] rotated 90 ; + texts_b[i] := texts_b[i] rotated 90 ; + endfor ; + fi ; + else : + for i=1 upto nofcells : + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + cells_t[i] := cell_b rotated 90 ; + cells_b[i] := cell_t rotated 90 ; + text_t := texts_t[i] ; + text_b := texts_b[i] ; + texts_t[i] := text_b rotated 90 ; + texts_b[i] := text_t rotated 90 ; + endfor ; + fi ; + fi ; + % align horizontal + for i=1 upto nofcells : + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + width_t := bbwidth(cell_t) ; + width_b := bbwidth(cell_b) ; + if (width_t = 0) and (width_b = 0) : + % skip + elseif (width_t > 0) and (width_t < width_b) : + delta := (width_b-width_t)/2 ; + setbounds cell_t to boundingbox cell_t leftenlarged delta rightenlarged delta ; + cells_t[i] := cell_t ; + elseif (width_b > 0) and (width_t > width_b) : + delta := (width_t-width_b)/2 ; + setbounds cell_b to boundingbox cell_b leftenlarged delta rightenlarged delta ; + cells_b[i] := cell_b ; + fi ; + endfor ; + % analyze vertical + max_height_t := 0 ; + max_height_b := 0 ; + for i=1 upto nofcells : + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + height_t := bbheight(cell_t) ; + height_b := bbheight(cell_b) ; + if height_t > 0 : + setbounds cell_t to boundingbox cell_t enlarged cell_offset ; + height_t := height_t + 2 * cell_offset ; + cells_t[i] := cell_t ; + fi ; + if height_b > 0 : + setbounds cell_b to boundingbox cell_b enlarged cell_offset ; + height_b := height_b + 2 * cell_offset ; + cells_b[i] := cell_b ; + fi ; + if height_t > max_height_t : + max_height_t := height_t ; + fi + if height_b > max_height_b : + max_height_b := height_b ; + fi ; + endfor ; + % align vertical + for i=1 upto nofcells : + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + height_t := bbheight(cell_t) ; + height_b := bbheight(cell_b) ; + if height_t > 0 : + delta := (max_height_t-height_t)/2 ; + setbounds cell_t to boundingbox cell_t topenlarged delta bottomenlarged delta ; + fi ; + if height_b > 0 : + delta := (max_height_b-height_b)/2 ; + setbounds cell_b to boundingbox cell_b topenlarged delta bottomenlarged delta ; + fi ; + cells_t[i] := cell_t ; + cells_b[i] := cell_b ; + endfor ; + % position + dx := 0 ; + for i=1 upto nofcells : + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + cell_t := cell_t shifted -llcorner cell_t ; + cell_b := cell_b shifted -llcorner cell_b ; + cell_t := cell_t shifted (dx, 0) ; + cell_b := cell_b shifted (dx,-cell_distance_y-max_height_b) ; + cells_t[i] := cell_t ; + cells_b[i] := cell_b ; + width_t := bbwidth(cell_t) ; + width_b := bbwidth(cell_b) ; + if width_t > 0 : + dx := dx + cell_distance_x + width_t ; + elseif width_b > 0 : + dx := dx + cell_distance_x + width_b ; + fi ; + endfor ; + % flush + for i=1 upto nofcells : + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + width_t := bbwidth(cell_t) ; + width_b := bbwidth(cell_b) ; + if width_t > 0 : + fill boundingbox cell_t withcolor cell_fill_color ; + draw boundingbox cell_t withpen pencircle scaled cell_line_width withcolor cell_line_color ; + draw cell_t ; + fi ; + if width_b > 0 : + fill boundingbox cell_b withcolor cell_fill_color ; + draw boundingbox cell_b withpen pencircle scaled cell_line_width withcolor cell_line_color ; + draw cell_b ; + fi ; + endfor ; + % + def midtopboundary expr p = 0.5[ulcorner boundingbox p, urcorner boundingbox p] enddef ; + def midbottomboundary expr p = 0.5[llcorner boundingbox p, lrcorner boundingbox p] enddef ; + % draw top and bottom text boxes + for i=1 upto nofcells-1 : + text_t := texts_t[i] ; + text_b := texts_b[i] ; + if bbwidth(text_t) > 0 : + setbounds text_t to boundingbox text_t enlarged text_offset ; + texts_t[i] := text_t ; + fi ; + if bbwidth(text_b) > 0 : + setbounds text_b to boundingbox text_b enlarged text_offset ; + texts_b[i] := text_b ; + fi ; + endfor ; + % arrows + for i=1 upto nofcells-1 : + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + next_t := cells_t[i+1] ; + next_b := cells_b[i+1] ; + pair t_a, t_b, t_c, b_a, b_b, b_c ; + t_a := midtopboundary cell_t ; + t_b := midtopboundary next_t ; + t_c := (xpart 0.5[t_a,t_b], ypart t_a+line_height+line_distance) ; + if one_row_only : + b_a := midbottomboundary cell_t ; + b_b := midbottomboundary next_t ; + else : + b_a := midbottomboundary cell_b ; + b_b := midbottomboundary next_b ; + fi ; + b_c := (xpart 0.5[b_a,b_b], ypart b_a-line_height-line_distance) ; + texts_t[i] := thelabel.top(texts_t[i],t_c) ; + texts_b[i] := thelabel.bot(texts_b[i],b_c) ; + endfor ; + % + for i=1 upto nofcells-1 : % todo arrows when empty text + cell_t := cells_t[i] ; + cell_b := cells_b[i] ; + next_t := cells_t[i+1] ; + next_b := cells_b[i+1] ; + text_t := texts_t[i] ; + text_b := texts_b[i] ; + if bbwidth(text_t) > 0 : + if bbwidth(cell_t) > 0 : + drawarrow midtopboundary cell_t + shifted (if i > 1 : line_offset else : 0 fi, cell_line_width) {up} .. + midbottomboundary text_t shifted (0,-line_distance) .. + {down} midtopboundary next_t shifted(if i < nofcells - 1 : -line_offset else : 0 fi,cell_line_width) + withpen pencircle scaled line_line_width + withcolor line_line_color ; + else : + fi ; + fi ; + if bbwidth(text_b) > 0 : + if one_row_only : + cell_b := cell_t ; + next_b := next_t ; + fi ; + if bbwidth(cell_b) > 0 : + drawarrow midbottomboundary cell_b + shifted (if i > 1 : line_offset else : 0 fi, -cell_line_width) {down} .. + midtopboundary text_b shifted (0, line_distance) .. + {up} midbottomboundary next_b shifted (if i < nofcells - 1 : -line_offset else : 0 fi,-cell_line_width) + withpen pencircle scaled line_line_width + withcolor line_line_color ; + else : + fi ; + fi ; + endfor ; + % draw top and bottom text boxes + for i=1 upto nofcells-1 : + text_t := texts_t[i] ; + text_b := texts_b[i] ; + if bbwidth(text_t) > 0 : + fill boundingbox text_t withcolor text_fill_color ; + draw boundingbox text_t withpen pencircle scaled text_line_width withcolor text_line_color ; + draw text_t ; + fi ; + if bbwidth(text_b) > 0 : + fill boundingbox text_b withcolor text_fill_color ; + draw boundingbox text_b withpen pencircle scaled text_line_width withcolor text_line_color ; + draw text_b ; + fi ; + endfor ; + if chart_vertical : + % rotate back + currentpicture := currentpicture rotated -90 ; + fi ; + endgroup ; +enddef ; + +% start_begin_step ; +% step_cells ("\strut test 0", "\strut test 0") ; +% step_cells ("\strut test 1", "\vbox{\hsize3cm \strut oeps 1\crlf oeps 1}") ; +% step_texts ("\strut 1", "\strut 1") ; +% step_cells ("\strut test 2", "\strut oeps 2 oeps 2") ; +% step_cells ("\strut test X", "\strut test X") ; +% step_texts ("\strut 2", "\strut 2") ; +% step_cells ("\strut test 3", "\strut oeps 3 oeps 3") ; +% step_texts ("\strut 3", "\strut 3") ; +% step_cells ("\strut test 4", "\strut oeps 4 oeps 4") ; +% step_texts ("\strut 4", "\strut 4") ; +% stop_end_chart ; diff --git a/metapost/context/base/mpiv/mp-symb.mpiv b/metapost/context/base/mpiv/mp-symb.mpiv new file mode 100644 index 000000000..a84c84e82 --- /dev/null +++ b/metapost/context/base/mpiv/mp-symb.mpiv @@ -0,0 +1,351 @@ +%D \module +%D [ file=mp-symb.mp, +%D version=very old, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=navigation symbol macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Instead of these symbols, you can use the \type {contnav} +%D font by Taco Hoekwater that is derived form this file. + +u := 3; +h := 5u; +wt := 5u; +wb := .25wt; +o := .1u; +pw := .5u; + +drawoptions (withpen pencircle scaled pw); + +path lefttriangle, righttriangle, sublefttriangle, subrighttriangle; + +pair s ; s = (2wb,0) ; + +x1t = x2t = 0; +x3t = wt; +y3t = .5h; +z1t-z2t = (z3t-z2t) rotated 60; + +z4t = (z2t--z3t) intersectionpoint ((z1t--z2t) shifted s) ; +z5t = (z3t--z1t) intersectionpoint ((z1t--z2t) shifted s) ; + +righttriangle = z1t--z2t--z3t--cycle; +lefttriangle = righttriangle rotatedaround((0,.5h), 180) shifted (wt,0); + +subrighttriangle = z4t--((z2t--z3t--z1t) shifted s)--z5t ; +sublefttriangle = subrighttriangle rotatedaround((0,.5h), 180) shifted (wt,0); + +path sidebar; + +x1b = x4b = 0; +x2b = x3b = wb; +y1b = y2b = y1t; +y3b = y4b = y2t; + +sidebar = z1b--z2b--z3b--z4b--cycle; + +path midbar, onebar, twobar; + +hh = abs(y1t-y2t); + +%midbar := unitsquare scaled 2hh/3; +midbar := unitsquare scaled hh; +onebar := unitsquare xscaled (hh/3) yscaled hh; +twobar := onebar; + +def prepareglyph = + drawoptions (withpen pencircle scaled .5u); +enddef; + +def finishglyph = + set_outer_boundingbox currentpicture; + bboxmargin := o; + setbounds currentpicture to bbox currentpicture; +% draw boundingbox currentpicture withcolor red withpen pencircle scaled 1; +enddef; + +beginfig (1); + prepareglyph; + fill lefttriangle; + draw lefttriangle; % draw gets the bbox right, filldraw doesn't + finishglyph; +endfig; + +beginfig (2); + prepareglyph; + fill righttriangle; + draw righttriangle; + finishglyph; +endfig; + +beginfig (3); + prepareglyph; + fill sidebar; + draw sidebar; + fill lefttriangle shifted (.5s); + draw lefttriangle shifted (.5s); + finishglyph; +endfig; + +beginfig (4); + prepareglyph; + fill righttriangle; + draw righttriangle; + fill sidebar shifted (wt,0); + draw sidebar shifted (wt,0); + finishglyph; +endfig; + +beginfig (5); + prepareglyph; + fill lefttriangle; + draw lefttriangle; + fill lefttriangle shifted s; + draw lefttriangle shifted s; + finishglyph; +endfig; + +beginfig (6); + prepareglyph; + fill righttriangle; + draw righttriangle; + fill righttriangle shifted s; + draw righttriangle shifted s; + finishglyph; +endfig; + +beginfig (7); + prepareglyph; + fill midbar; + draw midbar; + finishglyph; +endfig; + +beginfig (8); + prepareglyph; + fill onebar; + draw onebar; + finishglyph; +endfig; + +beginfig (9); + prepareglyph; + fill twobar; + draw twobar; + fill twobar shifted (pw+hh/2,0); + draw twobar shifted (pw+hh/2,0); + finishglyph; +endfig; + +beginfig(101); + prepareglyph; + draw lefttriangle; + finishglyph; +endfig; + +beginfig(102); + prepareglyph; + draw righttriangle; + finishglyph; +endfig; + +beginfig(103); + prepareglyph; + draw sidebar; + draw lefttriangle shifted (.5s); + finishglyph; +endfig; + +beginfig(104); + prepareglyph; + draw righttriangle; + draw sidebar shifted (wt,0); + finishglyph; +endfig; + +beginfig(105); + prepareglyph; + draw lefttriangle; + draw lefttriangle shifted s; + finishglyph; +endfig; + +beginfig(106); + prepareglyph; + draw righttriangle; + draw righttriangle shifted s; + finishglyph; +endfig; + +beginfig(107); + prepareglyph; + draw midbar; + finishglyph; +endfig; + +beginfig(108); + prepareglyph; + draw onebar; + finishglyph; +endfig; + +beginfig(109); + prepareglyph; + draw twobar; + draw twobar shifted (pw+hh/2,0); + finishglyph; +endfig; + +beginfig(201); + prepareglyph; + draw lefttriangle; + finishglyph; +endfig; + +beginfig(202); + prepareglyph; + draw righttriangle; + finishglyph; +endfig; + +beginfig(203); + prepareglyph; + draw sidebar; + draw lefttriangle shifted (.5s); + finishglyph; +endfig; + +beginfig(204); + prepareglyph; + draw righttriangle; + draw sidebar shifted (wt,0); + finishglyph; +endfig; + +beginfig(205); + prepareglyph; + draw sublefttriangle shifted s; + draw lefttriangle shifted s; + finishglyph; +endfig; + +beginfig(206); + prepareglyph; + draw subrighttriangle; + draw righttriangle; + finishglyph; +endfig; + +beginfig(207); + prepareglyph; + draw midbar; + finishglyph; +endfig; + +beginfig(208); + prepareglyph; + draw onebar; + finishglyph; +endfig; + +beginfig(209); + prepareglyph; + draw twobar; + draw twobar shifted (pw+hh/2,0); + finishglyph; +endfig; + + +beginfig(999); + +picture collection [] ; + +prepareglyph ; +draw lefttriangle ; +finishglyph ; +collection[201] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw righttriangle ; +finishglyph ; +collection[202] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw sidebar ; +draw lefttriangle shifted (.5s) ; +finishglyph ; +collection[203] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw righttriangle ; +draw sidebar shifted (wt,0) ; +finishglyph ; +collection[204] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw sublefttriangle shifted s ; +draw lefttriangle shifted s ; +finishglyph ; +collection[205] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw subrighttriangle ; +draw righttriangle ; +finishglyph ; +collection[206] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw midbar ; +finishglyph ; +collection[207] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw onebar ; +finishglyph ; +collection[208] := currentpicture ; +currentpicture := nullpicture ; + +prepareglyph ; +draw twobar ; +draw twobar shifted (pw+hh/2,0) ; +finishglyph ; +collection[209] := currentpicture ; +currentpicture := nullpicture ; + +for i=201 upto 209 : + collection[i] := collection[i] shifted - center collection[i] ; +endfor ; + +addto currentpicture also collection[205] shifted ( 0, 0) + withcolor (.3,.4,.5) ; +addto currentpicture also collection[202] shifted ( 0,1.5h) + withcolor (.5,.6,.7) ; +addto currentpicture also collection[201] shifted (1.5h, 0) + withcolor (.6,.7,.8) ; +addto currentpicture also collection[206] shifted (1.5h,1.5h) + withcolor (.4,.5,.6) ; + +collection[210] := currentpicture ; +currentpicture := nullpicture ; + +bboxmargin := .25u; + +fill bbox collection[210] withcolor .95(1,1,0); +addto currentpicture also collection[210] ; + +endfig ; + +end diff --git a/metapost/context/base/mpiv/mp-text.mpiv b/metapost/context/base/mpiv/mp-text.mpiv new file mode 100644 index 000000000..b68e8412a --- /dev/null +++ b/metapost/context/base/mpiv/mp-text.mpiv @@ -0,0 +1,163 @@ +%D \module +%D [ file=mp-text.mpiv, +%D version=2000.07.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=text support, +%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. + +%D This one is only used in metafun so it will become a module. + +if known context_text : endinput ; fi ; + +boolean context_text ; context_text := true ; + +def build_parshape (expr p, offset_or_path, dx, dy, baselineskip, strutheight, strutdepth, topskip) = + + if unknown trace_parshape : + boolean trace_parshape ; trace_parshape := false ; + fi ; + + begingroup ; + + save + q, l, r, line, tt, bb, + n, hsize, vsize, vvsize, voffset, hoffset, width, indent, + ll, lll, rr, rrr, cp, cq, t, b ; + + path + q, l, r, line, tt, bb ; + numeric + n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ; + pair + ll, lll, rr, rrr, cp, cq, t, b ; + + n := 0 ; + cp := center p ; + + if path offset_or_path : + q := offset_or_path ; + cq := center q ; + voffset := dy ; + hoffset := dx ; + else : + q := p ; + cq := center q ; + hoffset := offset_or_path + dx ; + voffset := offset_or_path + dy ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + q := p shifted - cp ; + + startsavingdata ; + + savedata "\global\parvoffset " & decimal voffset&"bp " ; + savedata "\global\parhoffset " & decimal hoffset&"bp " ; + savedata "\global\parwidth " & decimal hsize&"bp " ; + savedata "\global\parheight " & decimal vsize&"bp " ; + + if not path offset_or_path : + q := q xscaled ((hsize-2hoffset)/hsize) yscaled ((vsize-2voffset)/vsize) ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + t := (ulcorner q -- urcorner q) intersection_point q ; + b := (llcorner q -- lrcorner q) intersection_point q ; + + if xpart directionpoint t of q < 0 : + q := reverse q ; + fi ; + + l := q cutbefore t ; + l := l if xpart point 0 of q < 0 : & q fi cutafter b ; + + r := q cutbefore b ; + r := r if xpart point 0 of q > 0 : & q fi cutafter t ; + + % tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ; + % bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ; + + % l := l cutbefore (l intersection_point tt) ; + % l := l cutafter (l intersection_point bb) ; + % r := r cutbefore (r intersection_point bb) ; + % r := r cutafter (r intersection_point tt) ; + + if trace_parshape : + drawarrow p withpen pencircle scaled 2pt withcolor red ; + drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ; + drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ; + fi ; + + vardef found_point (expr lin, pat, sig) = + pair a, b ; + a := pat intersection_point (lin shifted (0,strutheight)) ; + if intersection_found : + a := a shifted (0,-strutheight) ; + else : + a := pat intersection_point lin ; + fi ; + b := pat intersection_point (lin shifted (0,-strutdepth)) ; + if intersection_found : + if sig : + if xpart b > xpart a : a := b shifted (0,strutdepth) fi ; + else : + if xpart b < xpart a : a := b shifted (0,strutdepth) fi ; + fi ; + fi ; + a + enddef ; + + if (strutheight+strutdepth +pi := 3.14159265358979323846264338327950288419716939937510 ; % 50 digits +radian := 180/pi ; % 2pi*radian = 360 ; + +% let +++ = ++ ; + +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 ; + +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 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 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 ; + +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 = + 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 +%D first macro divides the sides into n equal parts. The +%D first argument specifies the way the lines are drawn, while +%D the second argument identifier the way the shape is to be +%D drawn. +%D +%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 \stoptyping +%D +%D The a (or angle) alternative supports arbitrary angles and +%D is therefore more versatile. +%D +%D \starttyping +%D stripe_path_a +%D (withpen pencircle scaled 2 withcolor red) +%D (draw) +%D fullcircle xscaled 100 yscaled 40 withcolor blue; +%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 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; +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) +enddef; + +def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text = + 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) +enddef; + +def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text = + draw image(s_draw s_path s_text) anglestriped(3,0,0) s_spec ; +enddef ; + +%D A few normalizing macros: + +primarydef p xsized w = + (p if (bbwidth (p)>0) and (w>0) : scaled (w/bbwidth (p)) fi) +enddef ; + +primarydef p ysized h = + (p if (bbheight(p)>0) and (h>0) : scaled (h/bbheight(p)) fi) +enddef ; + +primarydef p xysized s = + begingroup + save wh, w, h ; pair wh ; numeric w, h ; + wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; + p + if (w>0) and (h>0) : + if xpart wh > 0 : xscaled (xpart wh/w) fi + if ypart wh > 0 : yscaled (ypart wh/h) fi + fi + endgroup +enddef ; + +let sized = xysized ; + +def xscale_currentpicture(expr w) = % obsolete + currentpicture := currentpicture xsized w ; +enddef; + +def yscale_currentpicture(expr h) = % obsolete + currentpicture := currentpicture ysized h ; +enddef; + +def xyscale_currentpicture(expr w, h) = % obsolete + currentpicture := currentpicture xysized (w,h) ; +enddef; + +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 +%D is located in the first quadrant. Now guess what kind of +%D path fullsquare and unitcircle do return. + +path fullsquare, unitcircle ; + +fullsquare := unitsquare shifted - center unitsquare ; +unitcircle := fullcircle shifted urcorner fullcircle ; + +%D Some more paths: + +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 ; + +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 ; + +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 ; + +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 ; +fulldiamond := unitdiamond shifted - center unitdiamond ; + +%D More robust: + +% let normalscaled = scaled ; +% let normalxscaled = xscaled ; +% let normalyscaled = yscaled ; +% +% def scaled expr s = normalscaled (s) enddef ; +% def xscaled expr s = normalxscaled (s) enddef ; +% def yscaled expr s = normalyscaled (s) enddef ; + +%D Shorter + +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 Some personal code that might move to another module + +def set_grid(expr w, h, nx, ny) = + 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 ; +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 +enddef ; + +%D usage: \type{innerpath peepholed outerpath}. +%D +%D beginfig(1); +%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ; +%D fill (fullsquare scaled 200) withcolor red ; +%D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ; +%D fill p peepholed bbox p ; +%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 + else : + llcorner q -- lrcorner q -- urcorner q -- ulcorner q -- + reverse p -- ulcorner q -- cycle + fi + fi + endgroup +enddef ; + +boolean intersection_found ; + +secondarydef p intersection_point q = + begingroup + save x_, y_ ; + (x_,y_) = p intersectiontimes q ; + if x_<0 : + intersection_found := false ; + center p % origin + else : + intersection_found := true ; + .5[point x_ of p, point y_ of q] + fi + 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 +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 +enddef ; + +%D Some colors. + +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 ; + +vardef complementary expr c = ( + if cmykcolor c : (1,1,1,1) - + elseif rgbcolor c : (1,1,1) - + elseif pair c : (1,1) - + elseif numeric c : 1 - + fi c +) enddef ; + +vardef complemented expr c = + save m ; + if cmykcolor c : m := max(cyanpart c, magentapart c, yellowpart c, blackpart c) ; + ( (m,m,m,m) - + elseif rgbcolor c : m := max(redpart c, greenpart c, bluepart c) ; + ( (m,m,m) - + elseif pair c : m := max(xpart c, ypart c) ; + ( (m,m) - + elseif numeric c : ( m - + fi c ) +enddef ; + +%D Well, this is the dangerous and naive version: + +def drawfill text 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 ; + mfun_do_drawfill +enddef ; + +def mfun_do_drawfill text t = + draw _c_ t ; + fill _c_ t ; +enddef; + +def undrawfill expr c = + drawfill c withcolor background % rather useless +enddef ; + +%D Moved from mp-char.mp + +vardef paired primary d = + if pair d : d else : (d,d) fi +enddef ; + +vardef tripled primary d = + if color d : d else : (d,d,d) fi +enddef ; + +% maybe secondaries: + +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 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 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 as stepper: + +vardef rotation(expr i, n) = + if (n == 0) : 0 else : i * 360 / n fi +enddef ; + +%D Handy for testing/debugging: + +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 + 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 + fi +) enddef ; + +%D Also handy (math ladders): + +vardef laddered primary p = % was expr + point 0 of p + for i=1 upto length(p) : + -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p) + endfor +enddef ; + +%D Saves typing: + +% vardef bottomboundary primary p = (llcorner p -- lrcorner p) enddef ; +% vardef rightboundary primary p = (lrcorner p -- urcorner p) 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 ; + +%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 ; + +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 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 = ( + 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 : + p + uniformdeviate s + fi +) enddef ; + +%D Not perfect (alternative for interpath) + +vardef interpolated(expr s, p, q) = + 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 paralleled d = ( + p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p) +) 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 +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 +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 +enddef ; + +%D Rather fundamental. + +% not yet ok + +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 ; +vardef rightpath expr p = leftrightpath(p,false) enddef ; + +%D Drawoptions + +def saveoptions = + save _op_ ; def _op_ = enddef ; +enddef ; + +%D Tracing. (not yet in lexer) + +let normaldraw = draw ; +let normalfill = fill ; + +% bugged in mplib so ... + +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 ; +def drawlabeloptions (text t) = def _lab_opt_ = t enddef ; enddef ; +def draworiginoptions (text t) = def _ori_opt_ = t enddef ; enddef ; +def drawboundoptions (text t) = def _bnd_opt_ = t enddef ; enddef ; +def drawpathoptions (text t) = def _pth_opt_ = t enddef ; enddef ; + +numeric drawoptionsfactor ; drawoptionsfactor := pt ; + +def resetdrawoptions = + drawlineoptions (withpen pencircle scaled 1.0 drawoptionsfactor withcolor .5white) ; + drawpointoptions (withpen pencircle scaled 4.0 drawoptionsfactor withcolor black) ; + drawcontroloptions(withpen pencircle scaled 2.5 drawoptionsfactor withcolor black) ; + drawlabeloptions () ; + draworiginoptions (withpen pencircle scaled 1.0 drawoptionsfactor withcolor .5white) ; + drawboundoptions (dashed evenly _ori_opt_) ; + drawpathoptions (withpen pencircle scaled 5.0 drawoptionsfactor withcolor .8white) ; +enddef ; + +resetdrawoptions ; + +%D Path. + +def drawpath expr p = + normaldraw p _pth_opt_ +enddef ; + +%D Arrow. + +newinternal ahvariant ; ahvariant := 0 ; +newinternal ahdimple ; ahdimple := 1/5 ; + +vardef arrowhead expr p = + save q, e, r ; + pair e ; e = point length p of p ; + path q ; q = gobble(p shifted -e cutafter makepath(pencircle scaled (2ahlength))) cuttings ; + if ahvariant > 0: + path r ; r = gobble(p shifted -e cutafter makepath(pencircle scaled ((1-ahdimple)*2ahlength))) cuttings ; + fi + (q rotated (ahangle/2) & reverse q rotated -(ahangle/2) + if ahvariant = 1 : + -- point 0 of r -- + elseif ahvariant = 2 : + ... point 0 of r ... + else : + -- + fi + cycle + ) shifted e +enddef ; + +vardef drawarrowpath expr p = + save autoarrows ; boolean autoarrows ; autoarrows := true ; + drawarrow p _pth_opt_ +enddef ; + +def midarrowhead expr 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) + (ahlength/2)) 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_ +enddef ; + +%D PathPoints. + +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 mfun_draw_points text t = + for _i_=0 upto length(_c_) : + normaldraw point _i_ of _c_ _pnt_opt_ t ; + endfor ; +enddef; + +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 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 ; +numeric pointlabelscale ; pointlabelscale := 0 ; +string pointlabelfont ; pointlabelfont := "" ; + +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_) ; + begingroup ; + if pointlabelscale > 0 : + save defaultscale ; numeric defaultscale ; + defaultscale := pointlabelscale ; + fi ; + if pointlabelfont <> "" : + save defaultfont ; string defaultfont ; + defaultfont := pointlabelfont ; + fi ; + _u_ := 10 * drawoptionsfactor * defaultscale * _u_ ; + normaldraw thelabel ( decimal _i_, _p_ shifted if cycle _c_ and (_i_=0) : - fi _u_ ) _lab_opt_ t ; + endgroup ; + endfor ; +enddef; + +%D Bounding box. + +def drawboundingbox expr p = + normaldraw boundingbox p _bnd_opt_ +enddef ; + +%D Origin. + +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 ; +enddef; + +%D Axis. + +numeric tickstep ; tickstep := 5mm ; +numeric ticklength ; ticklength := 2mm ; + +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 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 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 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 ; +enddef ; + +def drawpathonly expr p = + drawpath p ; + drawcontrollines p ; + drawcontrolpoints p ; + drawpoints p ; + drawpointlabels p ; +enddef ; + +%D Tracing. + +def visualizeddraw expr c = + 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 +enddef ; + +def do_visualizeddraw text t = + 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_ ; +enddef ; + +def detaileddraw expr c = + if picture c : normaldraw c else : path _c_ ; _c_ := c ; do_detaileddraw fi +enddef ; + +def do_detaileddraw text t = + drawpath _c_ t ; + drawcontrollines _c_ ; + drawcontrolpoints _c_ ; + drawpoints _c_ ; + % % for labels we need an third run (as the second will mark the numbers); i could preroll them + % % but then the hash needs to handle that as well (as now we keep numbering) + % drawpointlabels _c_ ; +enddef ; + +def visualizepaths = + let fill = visualizedfill ; + let draw = visualizeddraw ; +enddef ; + +def detailpaths = + let draw = detaileddraw ; +enddef ; + +def naturalizepaths = + 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 +extra_beginfig := extra_beginfig & " miterlimit := 10 ; " ; % restores +extra_beginfig := extra_beginfig & " linejoin := rounded ; " ; % restores +extra_beginfig := extra_beginfig & " linecap := rounded ; " ; % restores + +%D Normally, arrowheads don't scale well. So we provide a +%D hack. + +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)) ; +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) +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 (if ahvariant > 0 : (1-ahdimple)* fi 2ahlength*cosd(ahangle/2)) + 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 arrowpath _apth t ; % arrowpath added +% fill arrowhead _apth t ; +% draw arrowhead _apth 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; + +def _finarr text t = + if autoarrows : set_ahlength (t) fi ; + draw arrowpath _apth t ; % arrowpath added + fillup arrowhead _apth t ; +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) +enddef ; + +def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ; +def leftarrow (expr pat,tim,len) = pointarrow(pat,tim,len,+len) enddef ; +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 \starttyping +%D drawdot point .5 along somepath ; +%D drawdot point 3cm on somepath ; +%D \stoptyping +%D +%D The number denotes a percentage (fraction). + +primarydef pct along pat = % also negative + (arctime (pct * (arclength pat)) of pat) of pat +enddef ; + +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 + +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 +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 ; + +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 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) ; +enddef ; + +vardef freedotlabel (expr str, loc, ori) = + interim linecap := rounded ; + draw loc withpen pencircle scaled freedotlabelsize ; + draw thefreelabel(str,loc,ori) ; +enddef ; + +%D \starttyping +%D drawarrow anglebetween(line_a,line_b,somelabel) ; +%D \stoptyping + +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 ; + 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 mfun_current_picture_stack[] ; +numeric mfun_current_picture_depth ; + +mfun_current_picture_depth := 0 ; + +def pushcurrentpicture = + 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 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) ; + +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) ; + + transform t ; t := identity rotatedaround(origin,120) ; + + r := fullcircle rotated 90 scaled radius shifted (0,radius/4) rotatedaround(origin,135) ; + + 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 ; + + w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ; + + 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 ; + + for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ; + + currentpicture := currentpicture xsized size ; + + 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)) +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 ; + ) + fi +enddef ; + +vardef inverted primary p = + p uncolored white +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 +enddef ; + +vardef grayed primary p = + if rgbcolor p : + tripled(.30redpart p+.59greenpart p+.11bluepart p) + 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 + 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 + 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 ; + ) + else : + p + fi +enddef ; + +let greyed = grayed ; + +vardef hsvtorgb(expr h,s,v) = + save H, S, V, x ; + H = h mod 360 ; + S = if s < 0 : 0 elseif s > 1 : 1 else: s fi ; + V = if v < 0 : 0 elseif v > 1 : 1 else: v fi ; + x = 1 - abs(H mod 120 - 60)/60 ; + V * ( (1-S) * (1,1,1) + S * + if H < 60 : (1,x,0) + elseif H < 120 : (x,1,0) + elseif H < 180 : (0,1,x) + elseif H < 240 : (0,x,1) + elseif H < 300 : (x,0,1) + else : (1,0,x) + fi ) +enddef ; + +% yes or no: "text" infont "cmr12" at 24pt ; + +% let normalinfont = infont ; +% +% numeric lastfontsize ; lastfontsize = fontsize defaultfont ; +% +% def infont primary name = % no vardef, no expr +% hide(lastfontsize := fontsize name) % no ; +% normalinfont name +% enddef ; +% +% def scaledat expr size = +% scaled (size/lastfontsize) +% enddef ; +% +% let at = scaledat ; + +% like decimal + +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 +enddef ; + +primarydef p enlonged len = + begingroup + if pair p : + save q ; path q ; q := origin -- p ; + save al ; al := arclength(q) ; + if al > 0 : + point 1 of (q stretched ((al+len)/al)) + else : + p + fi + else : + save al ; al := arclength(p) ; + if al > 0 : + p stretched ((al+len)/al) + else : + p + fi + fi + endgroup +enddef ; + +% path p ; p := (0,0) -- (10cm,5cm) ; +% drawarrow p withcolor red ; +% drawarrow p shortened 1cm withcolor green ; + +primarydef p shortened d = + reverse ( ( reverse (p enlonged -d) ) enlonged -d ) +enddef ; + +% yes or no, untested -) + +def xshifted expr dx = shifted(dx,0) enddef ; +def yshifted expr dy = shifted(0,dy) enddef ; + +% also handy + +% right: str = readfrom ("abc" & ".def" ) ; +% wrong: str = readfrom "abc" & ".def" ; + +% Every 62th read fails so we need to try again! + +% def readfile (expr name) = +% if (readfrom (name) <> EOF) : +% scantokens("input " & name & ";") ; +% elseif (readfrom (name) <> EOF) : +% scantokens("input " & name & ";") ; +% fi ; +% closefrom (name) ; +% enddef ; +% +% this sometimes fails on the elseif, so : +% + +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 ; +enddef ; + +% permits redefinition of end in macro + +inner end ; + +% this will be redone (when needed) using scripts and backend handling + +let normalwithcolor = withcolor ; + +def remapcolors = + def withcolor primary c = normalwithcolor remappedcolor(c) enddef ; +enddef ; + +def normalcolors = + let withcolor = normalwithcolor ; +enddef ; + +def resetcolormap = + color color_map[][][] ; + normalcolors ; +enddef ; + +resetcolormap ; + +def r_color primary c = redpart c enddef ; +def g_color primary c = greenpart c enddef ; +def b_color primary c = bluepart c enddef ; + +def remapcolor(expr old, new) = + color_map[redpart old][greenpart old][bluepart old] := new ; +enddef ; + +def remappedcolor(expr c) = + if known color_map[redpart c][greenpart c][bluepart c] : + color_map[redpart c][greenpart c][bluepart c] + else : + c + fi +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 ; + +% primarydef p recolored t = repathed(0,p) t enddef ; +% primarydef p refilled t = repathed(1,p) t enddef ; +% primarydef p redrawn t = repathed(2,p) t enddef ; +% primarydef p retexted t = repathed(3,p) t enddef ; +% primarydef p untexted t = repathed(4,p) t enddef ; + +color refillbackground ; refillbackground := (1,1,1) ; + +def restroke suffix p = p := repathed (21,p) enddef ; % keep attributes +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 ; + fi ; + endfor ; + setbounds _p_ to _b_ ; + _p_ + endgroup +enddef ; + +% After a question of Denis on how to erase a z variable, Jacko +% suggested to assign whatever to x and y. So a clearz +% variable can be defined as: +% +% vardef clearz@# = +% x@# := whatever ; +% y@# := whatever ; +% enddef ; +% +% but Jacko suggested a redefinition of clearxy: +% +% def clearxy text s = +% clearxy_index_:=0; +% for $:=s: +% clearxy_index_:=clearxy_index_+1; endfor; +% if clearxy_index_=0: +% save x,y; +% else: +% forsuffixes $:=s: x$:=whatever; y$:=whatever; endfor; +% fi +% 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 +enddef ; + +% so now we can say: clearxy ; as well as clearxy 1, 2, 3 ; + +% show x0 ; z0 = (10,10) ; +% show x0 ; x0 := whatever ; y0 := whatever ; +% show x0 ; z0 = (20,20) ; +% show x0 ; clearxy 0 ; +% 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) +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) +enddef ; + +% cmyk color support + +% vardef cmyk(expr c,m,y,k) = % elsewhere +% (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 +% 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 +% 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 +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 ; + fi ; + fi ; +enddef ; + +% result from metafont discussion list (denisr/boguslawj) + +def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ; +def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ; + +let == = = ; + +% added + +picture oddly ; % evenly already defined + +evenly := dashpattern(on 3 off 3) ; +oddly := dashpattern(off 3 on 3) ; + +% not perfect, but useful since it removes redundant points. + +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 ; + _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 + else : + p + fi +enddef ; + +vardef simplified expr p = ( + reverse mfun_straightened(+1,mfun_straightened(+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) -- +% (4cm,1cm) -- (4cm,2cm) -- (4cm,2.5cm) -- (4cm,3cm) -- +% (3cm,3cm) -- (2cm,3cm) -- (1cm,3cm) -- (-1cm,3cm) -- +% .5[(-1cm,3cm),(1cm,1cm)] -- (1cm,1cm) -- cycle ; +% +% p := unitcircle scaled 4cm ; +% +% drawpath p ; drawpoints p ; drawpointlabels p ; +% p := p shifted (4cm,0) ; p := straightened p ; +% drawpath p ; drawpoints p ; drawpointlabels p ; +% p := p shifted (4cm,0) ; p := straightened p ; +% drawpath p ; drawpoints p ; drawpointlabels p ; + +% new + +path originpath ; originpath := origin -- cycle ; + +vardef unitvector primary z = + if abs z = abs origin : z else : z/abs z fi +enddef; + +% also new + +% 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 +enddef ; + +% handy + +def withgray primary g = + withcolor g +enddef ; + +% for metafun + +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 := .850(1,1,1) fi ; + +% an improved plain mp macro + +vardef center primary p = + 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 +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 + 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 ; +enddef ; + +% makes a (line) into an infinite one (handy for calculating +% intersection points + +vardef infinite expr 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) +enddef ; + +% obscure macros: create var from string and replace - and : +% (needed for process color id's) .. will go away + +string mfun_clean_ascii[] ; + +def register_dirty_chars(expr str) = + for i = 0 upto length(str)-1 : + 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 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 ; +enddef ; + +vardef getunstringed (expr s) = + scantokens(cleanstring(s)) +enddef ; + +vardef unstringed (expr s) = + 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) = % 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 ; + endfor ; + for x=MinX upto MaxX: + label.bot(textext("\infofont " & decimal x), (x*DeltaX,-size)) ; + endfor ; + for y=MinY upto MaxY: + label.lft(textext("\infofont " & decimal y), (-size,y*DeltaY)) ; + endfor ; + endgroup +enddef; + +% new, handy for: +% +% \startuseMPgraphic{map}{n} +% \includeMPgraphic{map:germany} ; +% c_phantom (\MPvar{n}<1) ( +% fill map_germany withcolor \MPcolor{lightgray} ; +% draw map_germany withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% \includeMPgraphic{map:austria} ; +% c_phantom (\MPvar{n}<2) ( +% fill map_austria withcolor \MPcolor{lightgray} ; +% draw map_austria withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% c_phantom (\MPvar{n}<3) ( +% \includeMPgraphic{map:swiss} ; +% fill map_swiss withcolor \MPcolor{lightgray} ; +% draw map_swiss withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% c_phantom (\MPvar{n}<4) ( +% \includeMPgraphic{map:luxembourg} ; +% fill map_luxembourg withcolor \MPcolor{lightgray} ; +% draw map_luxembourg withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ; +% ) ; +% \stopuseMPgraphic +% +% \useMPgraphic{map}{n=3} + +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 ; +enddef ; + +%D Handy: + +def break = + exitif true ; % fi +enddef ; + +%D New too: + +primarydef p xstretched w = ( + p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi +) enddef ; + +primarydef p ystretched h = ( + p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi +) enddef ; + +%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) ; +% 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 ; + 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 ; + +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 (charscale > 0) and (charscale <> 1) : + currentpicture := currentpicture scaled charscale ; + fi ; fi ; + endfig ; +enddef ; + +%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 ; + +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/fonts/bidi-symbols.mp b/metapost/context/fonts/bidi-symbols.mp deleted file mode 100644 index abe48b951..000000000 --- a/metapost/context/fonts/bidi-symbols.mp +++ /dev/null @@ -1,73 +0,0 @@ -%D \module -%D [ file=bidi-symbols.mp, -%D version=2013.09.06, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=demo font, -%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. - -passvariable("fontname","bidi-symbols") ; -passvariable("fontversion","1.009") ; - -numeric font_bidi_dp ; font_bidi_dp := -6 ; -numeric font_bidi_wd ; font_bidi_wd := -12 ; - -% beginfig(1) ; % lre -% charcode := 8234 ; charwd := 0 ; charht := 0 ; chardp := 0 ; -% drawarrow (0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp) withcolor red ; -% currentpicture := currentpicture scaled charscale ; -% setbounds currentpicture to boundingbox nullpicture ; -% endfig ; -% -% beginfig(2) ; % rle -% charcode := 8235 ; charwd := 0 ; charht := 0 ; chardp := 0 ; -% drawarrow (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp) withcolor green ; -% currentpicture := currentpicture scaled charscale ; -% setbounds currentpicture to boundingbox nullpicture ; -% endfig ; -% -% beginfig(3) ; % pdf -% charcode := 8236 ; charwd := 0 ; charht := 0 ; chardp := 0 ; -% draw (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd/2,font_bidi_dp) -- (font_bidi_wd/2,font_bidi_dp) withcolor blue ; -% currentpicture := currentpicture scaled charscale ; -% setbounds currentpicture to boundingbox nullpicture ; -% endfig ; -% -% beginfig(4) ; % lro -% charcode := 8237 ; charwd := 0 ; charht := 0 ; chardp := 0 ; -% drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp)) withcolor red ; -% currentpicture := currentpicture scaled charscale ; -% setbounds currentpicture to boundingbox nullpicture ; -% endfig ; -% -% beginfig(5) ; % rlo -% charcode := 8238 ; charwd := 0 ; charht := 0 ; chardp := 0 ; -% drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp)) withcolor green ; -% currentpicture := currentpicture scaled charscale ; -% setbounds currentpicture to boundingbox nullpicture ; -% endfig ; - -beginglyph(8234,0,0,0) ; % lre - drawarrow (0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp) withcolor red ; -endglyph ; - -beginglyph(8235,0,0,0) ; % rle - drawarrow (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp) withcolor green ; -endglyph ; - -beginglyph(8236,0,0,0) ; % pdf - draw (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd/2,font_bidi_dp) -- (font_bidi_wd/2,font_bidi_dp) withcolor blue ; -endglyph ; - -beginglyph(8237,0,0,0) ; % lro - drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp)) withcolor red ; -endglyph ; - -beginglyph(8238,0,0,0) ; % rlo - drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp)) withcolor green ; -endglyph ; diff --git a/metapost/context/fonts/bidi-symbols.tex b/metapost/context/fonts/bidi-symbols.tex deleted file mode 100644 index ba659ccb7..000000000 --- a/metapost/context/fonts/bidi-symbols.tex +++ /dev/null @@ -1,33 +0,0 @@ -\nopdfcompression - -% At the ConTeXt 2013 meeting Taco suggested to add ActualText entries to the -% shapes. It took us a bit of experimenting and the current implementation of -% this is quite okay, but beware: some viewers will add a space when copying -% such characters. - -\starttext - - \definemetafont[bidi-symbols][bidi-symbols.mp] - - \startbuffer - xxx{\demo\char"202A}\relax xxx\quad % lre - xxx{\demo\char"202B}\relax xxx\quad % rle - xxx{\demo\char"202C}\relax xxx\quad % pdf - xxx{\demo\char"202D}\relax xxx\quad % lro - xxx{\demo\char"202E}\relax xxx\quad % rlo - \stopbuffer - - \definefont[demo][demo@bidi-symbols] - - \getbuffer \blank - - \definefont[demo][demo@bidi-symbols at \the\dimexpr3\exheight] - - \getbuffer \blank - - \definefont[demo][demo@bidi-symbols at \the\dimexpr4\exheight] - - \getbuffer \blank - -\stoptext - diff --git a/metapost/context/fonts/demo-symbols.mp b/metapost/context/fonts/demo-symbols.mp deleted file mode 100644 index 822854c94..000000000 --- a/metapost/context/fonts/demo-symbols.mp +++ /dev/null @@ -1,21 +0,0 @@ -%D \module -%D [ file=demo-symbols.mp, -%D version=2013.09.06, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=demo font, -%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. - -passvariable("fontname","demo-symbols") ; -passvariable("fontversion","1.005") ; - -beginglyph(9754,2,4,0) ; % high voltage - interim ahlength := 1 ; - drawarrow (1,4) -- (0,2) -- (2,3) -- (1,0) withcolor darkred ; -endglyph ; - diff --git a/metapost/context/fonts/demo-symbols.tex b/metapost/context/fonts/demo-symbols.tex deleted file mode 100644 index e9af4a027..000000000 --- a/metapost/context/fonts/demo-symbols.tex +++ /dev/null @@ -1,21 +0,0 @@ -\starttext - - \definemetafont[demo-symbols][demo-symbols.mp] - - \startbuffer - watch this: {\demo\char"261A} \quad \ruledhbox{\demo\char"261A} - \stopbuffer - - \definefont[demo][demo@demo-symbols] - - \getbuffer \blank - - \definefont[demo][demo@demo-symbols at \the\dimexpr3\exheight] - - \getbuffer \blank - - \definefont[demo][demo@demo-symbols at \the\dimexpr4\exheight] - - \getbuffer \blank - -\stoptext diff --git a/metapost/context/fonts/mpiv/bidi-symbols.mp b/metapost/context/fonts/mpiv/bidi-symbols.mp new file mode 100644 index 000000000..abe48b951 --- /dev/null +++ b/metapost/context/fonts/mpiv/bidi-symbols.mp @@ -0,0 +1,73 @@ +%D \module +%D [ file=bidi-symbols.mp, +%D version=2013.09.06, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=demo font, +%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. + +passvariable("fontname","bidi-symbols") ; +passvariable("fontversion","1.009") ; + +numeric font_bidi_dp ; font_bidi_dp := -6 ; +numeric font_bidi_wd ; font_bidi_wd := -12 ; + +% beginfig(1) ; % lre +% charcode := 8234 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow (0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp) withcolor red ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(2) ; % rle +% charcode := 8235 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp) withcolor green ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(3) ; % pdf +% charcode := 8236 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% draw (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd/2,font_bidi_dp) -- (font_bidi_wd/2,font_bidi_dp) withcolor blue ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(4) ; % lro +% charcode := 8237 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp)) withcolor red ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(5) ; % rlo +% charcode := 8238 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp)) withcolor green ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; + +beginglyph(8234,0,0,0) ; % lre + drawarrow (0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp) withcolor red ; +endglyph ; + +beginglyph(8235,0,0,0) ; % rle + drawarrow (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp) withcolor green ; +endglyph ; + +beginglyph(8236,0,0,0) ; % pdf + draw (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd/2,font_bidi_dp) -- (font_bidi_wd/2,font_bidi_dp) withcolor blue ; +endglyph ; + +beginglyph(8237,0,0,0) ; % lro + drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp)) withcolor red ; +endglyph ; + +beginglyph(8238,0,0,0) ; % rlo + drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp)) withcolor green ; +endglyph ; diff --git a/metapost/context/fonts/mpiv/bidi-symbols.tex b/metapost/context/fonts/mpiv/bidi-symbols.tex new file mode 100644 index 000000000..ba659ccb7 --- /dev/null +++ b/metapost/context/fonts/mpiv/bidi-symbols.tex @@ -0,0 +1,33 @@ +\nopdfcompression + +% At the ConTeXt 2013 meeting Taco suggested to add ActualText entries to the +% shapes. It took us a bit of experimenting and the current implementation of +% this is quite okay, but beware: some viewers will add a space when copying +% such characters. + +\starttext + + \definemetafont[bidi-symbols][bidi-symbols.mp] + + \startbuffer + xxx{\demo\char"202A}\relax xxx\quad % lre + xxx{\demo\char"202B}\relax xxx\quad % rle + xxx{\demo\char"202C}\relax xxx\quad % pdf + xxx{\demo\char"202D}\relax xxx\quad % lro + xxx{\demo\char"202E}\relax xxx\quad % rlo + \stopbuffer + + \definefont[demo][demo@bidi-symbols] + + \getbuffer \blank + + \definefont[demo][demo@bidi-symbols at \the\dimexpr3\exheight] + + \getbuffer \blank + + \definefont[demo][demo@bidi-symbols at \the\dimexpr4\exheight] + + \getbuffer \blank + +\stoptext + diff --git a/metapost/context/fonts/mpiv/demo-symbols.mp b/metapost/context/fonts/mpiv/demo-symbols.mp new file mode 100644 index 000000000..822854c94 --- /dev/null +++ b/metapost/context/fonts/mpiv/demo-symbols.mp @@ -0,0 +1,21 @@ +%D \module +%D [ file=demo-symbols.mp, +%D version=2013.09.06, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=demo font, +%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. + +passvariable("fontname","demo-symbols") ; +passvariable("fontversion","1.005") ; + +beginglyph(9754,2,4,0) ; % high voltage + interim ahlength := 1 ; + drawarrow (1,4) -- (0,2) -- (2,3) -- (1,0) withcolor darkred ; +endglyph ; + diff --git a/metapost/context/fonts/mpiv/demo-symbols.tex b/metapost/context/fonts/mpiv/demo-symbols.tex new file mode 100644 index 000000000..e9af4a027 --- /dev/null +++ b/metapost/context/fonts/mpiv/demo-symbols.tex @@ -0,0 +1,21 @@ +\starttext + + \definemetafont[demo-symbols][demo-symbols.mp] + + \startbuffer + watch this: {\demo\char"261A} \quad \ruledhbox{\demo\char"261A} + \stopbuffer + + \definefont[demo][demo@demo-symbols] + + \getbuffer \blank + + \definefont[demo][demo@demo-symbols at \the\dimexpr3\exheight] + + \getbuffer \blank + + \definefont[demo][demo@demo-symbols at \the\dimexpr4\exheight] + + \getbuffer \blank + +\stoptext diff --git a/metapost/context/fonts/mpiv/punkfont-bold.mp b/metapost/context/fonts/mpiv/punkfont-bold.mp new file mode 100644 index 000000000..1c62963f9 --- /dev/null +++ b/metapost/context/fonts/mpiv/punkfont-bold.mp @@ -0,0 +1,4 @@ +boolean bold_punk ; bold_punk := true ; + +input "punkfont-definitions.mp" ; +input "punkfont-characters.mp" ; diff --git a/metapost/context/fonts/mpiv/punkfont-boldslanted.mp b/metapost/context/fonts/mpiv/punkfont-boldslanted.mp new file mode 100644 index 000000000..3e5fa1561 --- /dev/null +++ b/metapost/context/fonts/mpiv/punkfont-boldslanted.mp @@ -0,0 +1,5 @@ +boolean bold_punk ; bold_punk := true ; +boolean slanted_punk ; slanted_punk := true ; + +input "punkfont-definitions.mp" ; +input "punkfont-characters.mp" ; diff --git a/metapost/context/fonts/mpiv/punkfont-characters.mp b/metapost/context/fonts/mpiv/punkfont-characters.mp new file mode 100644 index 000000000..da0015b02 --- /dev/null +++ b/metapost/context/fonts/mpiv/punkfont-characters.mp @@ -0,0 +1,726 @@ +initialize_punk_upper ; + +beginpunkchar("A",13,1,2); +z1=pp(1.5u,0); z2=(.5w,1.1h); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % left and right diagonals +z4=pp .3[z1,z2]; z5=pp .3[z3,z2]; pd z4; pd z5; draw z4--z5; % crossbar +endchar; + +beginpunkchar("B",12,1,1); +z1=pp(2u,0); z2=pp(2u,.6h); z3=pp(2u,h); pd z1; pd z3; draw z1--z3; % stem +z1.5=pp(w-u,.5y2); z2.5=pp(w-u,.5[y2,y3]); draw z2--z2.5--z3; % upper lobe +draw flex(z2,z1.5,z1); % lower lobe +endchar; + +beginpunkchar("C",13,1,2); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=(.6w,0); z5=(w-2u,.2h); +pd z1; pd z5; draw z1..z2..z3..z4..z5; % arc +endchar; + +beginpunkchar("D",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6h); +pd z1; pd z2; draw flex(z1,z3,z2); % lobe +draw z1--z2; % stem +endchar; + +beginpunkchar("E",12,.5,1); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2.5u,h); z4=pp(w-2u,0); +pd z3; pd z4; draw z4--z1--z2--z3; % stem and arms +z5=pp(2u,.6h); z6=pp(w-3u,.6h); pd z5; pd z6; draw z5--z6; % crossbar +endchar; + +beginpunkchar("F",12,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,h); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +z5=pp(2u,.6h); z6=pp(w-3u,.6h); z4=pp .5[z5,z6]-(0,.1h); +pd z5; pd z6; draw flex (z5,z4,z6); % crossbar +endchar; + +beginpunkchar("G",13,.5,.5); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=pp(.6w,0); z5=(w-2u,0); +pd z1; draw z1..z2..z3..z4---z5; % arc +z6=pp(.5[u,x5],.4h); pd z6; pd z5; draw z6--(pp(x5,y6))--z5; % spur +endchar; + +beginpunkchar("H",14,1,.5); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +z5=pp(2u,.6h); z6=pp(w-2u,.6h); +pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw flex(z3,z6,z4); % stems +pd z5; draw z5--z6; % crossbar +endchar; + +beginpunkchar("I",5,1,2); +z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); +pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem +endchar; + +beginpunkchar("J",9,1,2); +z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); +pd z1; pd z3; draw z1--z2--z3; % arc +endchar; + +beginpunkchar("K",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(2u,1/3h); z4=pp(w-1.5u,h); +pd z1; pd z2; draw z1--z2; % stem +pd z3; pd z4; draw z3--z4; % upper diagonal +z6=pp(w-u,0); z5=1/3[z3,z4]; +pd z6; draw flex(z5,.8[z1,2/3[z5,z6] ],z6);% lower diagonal +endchar; + +beginpunkchar("L",11,1,2); +z1=pp(2u,h); z2=pp(2u,0); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +endchar; + +beginpunkchar("M",17,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(.5w,0); z4=pp(w-2u,h); z5=pp(w-2u,0); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % stems and diagonals +endchar; + +beginpunkchar("N",13,.75,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +pd z1; pd z4; draw z1--z2--z3--z4; % stems and diagonals +endchar; + +beginpunkchar("O",12,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{left}..z2..z3..z4..z1; % bowl +endchar; + +beginpunkchar("P",13,1,2); +z1=pp(2u,0); z2=pp(2u,1.1h); z3=pp(2u,.5h); z4=pp(w,.6[y3,y2]); +pd z1; pd z3; draw z1--z2--z4--z3; % stem and bowl +endchar; + +beginpunkchar("Q",14,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl +z5=pp(.4w,.2h); z6=pp(w-u,-.1h); z7=pp(.5[x5,x6],-.2h); +pd z5; pd z6; draw z5--z7--z6; % tail +endchar; + +beginpunkchar("R",16,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6[y2,y4]); z4=pp(2u,.5h); z5=pp(w-1.5u,0); +pd z1; pd z2; pd z5; draw z1--flex(z2,z3,z4)--z5; % stem, bowl, and diagonal +endchar; + +beginpunkchar("S",11,.3,1); +z1=pp(w-2u,.9h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.6[z6,z2]; +z5=pp(w-u,.35h); z6=pp(.5w,u); z7=pp(u,.2h); +pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % stroke +endchar; + +beginpunkchar("T",13,.75,2); +z1=pp(u,h); z2=pp(w-u,h); z3=pp(.5w,0); +pd z1; pd z2; pd z3; draw z1--z2; % arms +draw .5[z1,z2]--z3; % stem +endchar; + +beginpunkchar("U",13,.3,2); +z1=pp(2u,h); z2=pp(2u,.2h); z3=pp(.5w,0); z4=pp(w-2u,.2h); z5=pp(w-2u,h); +pd z1; pd z5; draw z1---z2...z3{z4-z2}...z4---z5; % stroke +endchar; + +beginpunkchar("V",13,1,2); +z1=pp(1.5u,h); z2=pp(.5w,0); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar("W",18,1,2); +z1=pp(1.5u,h); z2=pp(.5[x1,x3],0); z3=pp(.5w,.8h); z4=pp(.5[x3,x5],0); +z5=pp(w-1.5u,h); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % diagonals +endchar; + +beginpunkchar("X",13,1,1); +z1=pp(1.5u,h); z2=pp(w-1.5u,0); z3=pp(1.5u,0); z4=pp(w-2.5u,h); +pd z1; pd z2; draw z1--z2; % main diagonal +pd z3; pd z4; draw z3--z4; % cross diagonal +endchar; + +beginpunkchar("Y",13,1,2); +z1=pp(1.5u,h); z2=pp(w-1.5u,h); z3=pp(.5w,.5h); z4=pp(.5w,0); +pd z1; pd z2; pd z4; draw z1--z3--z4; % stem and left diagonal +draw z2--z3; % right diagonal +endchar; + +beginpunkchar("Z",11,1,2); +z1=pp(1.5u,h); z2=pp(w-2.5u,h); z3=pp(1.5u,0); z4=pp(w-1.5u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % diagonals +endchar; + +beginpunkchar(198,16,1,2); % \AE +z1=pp(1.5u,0); z2=pp(.6w,h); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % left diagonal and upper arm +z4=pp .3[z1,z2]; z5=pp(.6w,0); z6=pp(w-2u,.3h); +pd z4; pd z6; draw z4--z6; % crossbar +z7=pp(w-u,0); pd z2; pd z7; draw z2--z5--z7; % stem and lower arm +endchar; + +beginpunkchar(338,18,1,2); % \OE +z1=pp(.5w,h); z2=pp(u,.4h); z3=pp(.5w,0); +pd z1; draw z1..z2..{right}z3; % bowl +z4=pp(w-1.5u,h); z5=pp(w-2u,.4h); z6=pp(w-u,0); +pd z4; pd z6; draw z4--z1--z3--z6; % arms and stem +pd z5; draw z5--.4[z3,z1]; % crossbar +endchar; + +beginpunkchar(216,14,1,1); % \O +z1=pp(.5w,h); z2=pp(u,.5h); z3=pp(.5w,0); z4=pp(w-u,.5h); +z5=pp(w-2u,1.1h); z6=pp(2u,-.1h); +pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % bowl and diagonal +endchar; + +beginpunkchar(915,11,1,2); % $\Gamma$ +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +endchar; + +beginpunkchar(916,15,1,2); % $\Delta$ +z1=pp(u,0); z2=pp(.5w,h); z3=pp(w-u,0); +pd z1; draw z1--z2..tension 5..z3..tension 5..z1; % triangle +endchar; + +beginpunkchar(920,15,.5,2); % $\Theta$ +z1=pp(.5w,h); z2=pp(u,.6h); z3=pp(.5w,0); z4=pp(w-u,.6h); +pd z1; draw z1..tension.8..z2..z3..z4..tension.8..z1; % bowl +z5=pp(x2+2u,.4h); z6=pp(x4-2u,.4h); pd z5; pd z6; draw z5--z6; % bar +endchar; + +beginpunkchar(923,12,1,2); % $\Lambda$ +z1=pp(u,0); z2=pp(.5w,h); z3=pp(w-u,0); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(926,12,1,1); % $\Xi$ +z1=pp(u,h); z2=pp(w-u,h); pd z1; pd z2; draw z1--z2; % upper arm +z3=pp(2u,.55h); z4=pp(w-2u,.55h); pd z3; pd z4; draw z3--z4; % bar +z5=pp(u,0); z6=pp(w-u,0); pd z5; pd z6; draw z5--z6; % lower arm +endchar; + +beginpunkchar(928,13,1,.5); % $\Pi$ +z1=pp(1.5u,0); z2=pp(1.5u,h); z3=pp(w-1.5u,h); z4=pp(w-1.5u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % stems and bar +endchar; + +beginpunkchar(931,13,1,1); % $\Sigma$ +z1=pp(w-u,h); z2=pp(u,h); z3=pp(.5w-u,.5h); z4=pp(u,0); z5=pp(w-u,0); +pd z1; pd z5; draw z1--z2{.5[z4,z5]-z2}..z3--z4--z5; % arms and diagonals +endchar; + +beginpunkchar(933,15,1,.5); % $\Upsilon$ +z1=pp(u,.8h); z2=pp(.3w,h); z3=pp(.5w,.5h); z4=pp(.5w,0); +pd z1; pd z4; draw z1..z2..tension2..z3---z4; % left arc and stem +z5=pp(w-u,.8h); z6=pp(.7w,h); +pd z5; draw z5..z6..tension2..{z4-z3}z3; % right arc +endchar; + +beginpunkchar(934,13,1,2); % $\Phi$ +z1=pp(.5w,h); z2=pp(.5w,0); pd z1; pd z2; draw z1--z2; % stem +z3=pp(.5w,2/3h); z4=pp(u,.5h); z5=pp(.5w,1/4h); z6=pp(w-u,.5h); +pd z3; draw z3..z4..z5..z6..z3; % bowl +endchar; + +beginpunkchar(936,14,1,1); % $\Psi$ +z1=pp(.5w,h); z2=pp(.5w,0); pd z1; pd z2; draw z1--z2; % stem +z3=pp(u,.8h); z4=pp(.5w,.2h); z5=pp(w-u,.8h); +pd z3; pd z5; draw z3{.4[z1,z2]-z3}..z4{right}..{z5-.4[z1,z2]}z5; % stroke +endchar; + +beginpunkchar(937,13,1,2); % $\Omega$ +z1=pp(u,0); z2=pp(1/3w,0); z3=pp(u,2/3h); z4=pp(.5w,h); +z5=pp(w-u,2/3h); z6=pp(2/3w,0); z7=pp(w-u,0); +pd z1; pd z7; draw z1--z2{up}..z3..z4..z5..{down}z6--z7; % bowl and arms +endchar; + +beginpunkchar(".",5,1,2); +pd pp(.5w,0); % dot +endchar; + +beginpunkchar(",",5,.5,.5); +z1=pp(.5w,0); z2=pp(w-u,-.1h); z3=pp(.5w,-.3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(":",5,1,.5); +pd pp(.5w,0); pd pp(.5w,.4h); % dots +endchar; + +beginpunkchar(";",5,.5,.5); +z1=pp(.5w,0); z2=pp(w-u,-.1h); z3=pp(.5w,-.3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +pd pp(.5w,.4h); % dot +endchar; + +beginpunkchar("!",5,.5,.5); +pd pp(.5w,0); % dot +z1=pp(.5w,1.05h); z2=pp(.5w,.3h); pd z1; pd z2; draw z1--z2; % stem +endchar; + +beginpunkchar(161,5,.5,.5); % spanish inverted ! +pd pp(.5w,.9h); % dot +z1=pp(.5w,-.1h); z2=pp(.5w,.6h); pd z1; pd z2; draw z1--z2; % stem +endchar; + +beginpunkchar("?",9,1,.5); +z1=pp(1.5u,.8h); z2=pp(.5w,h); z3=pp(w-u,.8h); z4=pp(.5w,.3h); +pd z1; pd z4; draw z1..z2..z3..{down}z4; % arc and stem +pd pp(.5w,0); % dot +endchar; + +beginpunkchar(191,9,1,.5); % spanish inverted ? +z1=pp(1.5u,.1h); z2=pp(.5w,-.1h); z3=pp(w-u,.1h); z4=pp(.5w,.6h); +pd z1; pd z4; draw z1..z2..z3..{up}z4; % arc and stem +pd pp(.5w,.9h); % dot +endchar; + +beginpunkchar("&",14,.5,.5); +z1=pp(w-2u,h); z2=pp(u,h); z3=pp(3u,0); z5=pp(w-u,.6h); z6=pp(w-2u,0); +pd z1; pd z5; draw z1--z2--z3--z5; % arms and stem +draw z1--.5[z2,z3]; pd z6; draw z6--.6[z3,z5]; % diagonals +endchar; + +beginpunkchar("$",12,.5,.5); +z1=pp(w-1.5u,.7h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.5[z3,z5]; +z5=pp(w-u,.3h); z6=pp(.5w,0); z7=pp(u,.3h); +pd z1; pd z7; draw z1..z2..z3..z4..z5..z6..z7; % stroke +z8=z2+(0,.1h); pd z8; draw z8--z6; % stem +endchar; + +beginpunkchar("%",18,.5,.5); +z1=pp(3.5u,1.1h); z2=pp(u,.8h); z3=pp(3.5u,.5h); z4=pp(6u,.8h); +z5=pp(w-3.5u,.5h); z6=pp(w-6u,.2h); z7=pp(w-3.5u,-.1h); z8=pp(w-u,.2h); +pd z1; draw z1..z2..z3..z4..z1; % upper bowl +pd z5; draw z5..z6..z7..z8..z5; % lower bowl +z9=pp(w-3u,1.1h); z0=pp(3u,-.1h); pd z0; draw z9--z0; % diagonal +draw z1{z5-z1}..z9; % link +endchar; + +beginpunkchar("@",18,1,.5); +z1=pp(2u,0); z2=pp(1/3w,.7h); z3=pp(w-6u,0); +z4=pp(w,.3h); z5=pp(1/3w,h); z6=pp(u,.5h); z7=.7[z2,z3]; +pd z1; pd z7; draw z1--z2--z3{right}..z4..z5..z6..z7; % diagonals and stroke +endchar; + +beginpunkchar("-",7,.5,.5); +z1=pp(u,.4h); z2=pp(w-u,.5h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar(8211,9,.5,.5); % -- +z1=pp(0,.5h); z2=pp(w,.4h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar(8212,18,.5,.5); % --- +z1=pp(0,.5h); z2=pp(w,.4h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar("+",9,.5,1); +z1=pp(0,.5h); z2=pp(w,.5h); pd z1; pd z2; draw z1--z2; % bar +z3=pp(.5w,.1h); z4=pp(.5w,.9h); pd z3; pd z4; draw z3--z4; % stem +endchar; + +beginpunkchar("*",13,.5,1); +z0=pp(.5w,1.1h); z1=pp(u,.9h); z2=pp(2u,.3h); z3=pp(w-u,.3h); z4=pp(w-u,.9h); +pd z0; draw z0--z2..1/3[.5[z2,z4],z0]..z4--z1--z3--z0; % star +endchar; + +beginpunkchar(39,5,.5,1.5); % ' apostrofe HH/TH (to be checked) +z1=pp(w/2,h); z2=pp(w/2+u,.85h); z3=pp(w/2,2/3h); +pd z1; pd z3; draw z1..z2..z3; % stroke +endchar; + +beginpunkchar(34,9,1,1.5); % " HH/TH (to be checked) +z1=pp(1.5u,h); z2=pp(1.5u,.6h); z3=pp(w-1.5u,h); z4=pp(w-1.5u,.6h); +pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw z3--z4; +endchar; + +beginpunkchar(8216,5,.3,.5); % ` +z1=pp(w-1.5u,h); z2=pp(u,.85h); z3=pp(w-u,2/3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(8217,5,.3,.5); % ' +z1=pp(1.5u,h); z2=pp(w-u,.85h); z3=pp(u,2/3h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(8220,9,.3,.5); % `` quotedblleft +z1=pp(.5w+.5u,h); z2=pp(w-u,.6h); z3=pp(u,.95h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar(8221,9,.3,.5); % '' quotedblright +z1=pp(.5w-.5u,h); z2=pp(u,.6h); z3=pp(w-u,.95h); +pd z1; pd z3; draw z1--z2--z3; % stroke +endchar; + +beginpunkchar("(",7,.5,.5); +z1=pp(w-u,h); z2=pp(u,.5h); z3=pp(w-u,0); +pd z1; pd z3; draw z1..z2..z3; % stroke +endchar; + +beginpunkchar(")",7,.5,.5); +z1=pp(u,h); z2=pp(w-u,.5h); z3=pp(u,0); pd z1; pd z3; draw z1..z2..z3; % stroke +endchar; + +beginpunkchar("[",8,.5,.5); +z1=pp(w-u,h); z2=pp(.5w,h); z3=pp(.5w,0); z4=pp(w-u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % bars and stem +endchar; + +beginpunkchar("]",8,.5,.5); +z1=pp(u,h); z2=pp(.5w,h); z3=pp(.5w,0); z4=pp(u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % bars and stem +endchar; + +beginpunkchar("<",9,.5,.5); +z1=pp(w-u,.9h); z2=pp(u,.5h); z3=pp(w-u,.1h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(">",9,.5,.5); +z1=pp(u,.9h); z2=pp(w-u,.5h); z3=pp(u,.1h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar("{",10,.5,.5); % HH/TH +z1=pp(w-2u,h); z3=pp(2u,.5h); z5=pp(w-2u,0); +z2=pp(w-4u,.6h); z4=(w-4u,.4h); +pd z1; pd z3; pd z5; draw z1{left}..z2--z3 & z3--z4..{right}z5; +endchar; + +beginpunkchar("}",10,.5,.5); % HH/TH +z1=pp(2u,h); z3=pp(w-2u,.5h); z5=pp(2u,0); +z2=pp(4u,.6h); z4=(4u,.4h); +pd z1; pd z3; pd z5; draw z1{right}..z2--z3 & z3--z4..{left}z5; +endchar; + +beginpunkchar("=",9,.5,.5); +z5=pp(u,2/3h); z6=pp(w-u,2/3h); pd z5; pd z6; draw z5--z6; % upper bar +z7=pp(u,1/3h); z8=pp(w-u,1/3h); pd z7; pd z8; draw z7--z8; % lower bar +endchar; + +beginpunkchar("#",15,.5,.5); +z1=pp(.5w,h); z2=pp(3u,0); z3=pp(w-3u,h); z4=pp(.5w,0); +pd z2; pd z3; draw z3--z1--z2; draw z3--z4--z2; % diagonals (linked) +z5=pp(u,2/3h); z6=pp(w-u,2/3h); pd z5; pd z6; draw z5--z6; % upper bar +z7=pp(u,1/3h); z8=pp(w-u,1/3h); pd z7; pd z8; draw z7--z8; % lower bar +endchar; + +beginpunkchar("/",9,1,1); +z1=pp(1.5u,-.05h); z2=pp(w-1.5u,1.05h); pd z1; pd z2; draw z1--z2; % diagonal +endchar; + +beginpunkchar("\",9,1,1); % HH/TH +z1=pp(1.5u,1.05h); z2=pp(w-1.5u,-.05h); pd z1; pd z2; draw z1--z2; % reverse diagonal +endchar; + + +beginpunkchar("0",9,.5,1); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl +endchar; + +beginpunkchar("1",9,.3,1); +z1=pp(2u,.7h); z2=pp(.6w,h); z3=pp(.6w,0); +pd z1; pd z3; draw z1--z2--z3; % serif and stem +endchar; + +beginpunkchar("2",9,1,1); +z1=pp(2u,.7h); z2=pp(.5w,h); z3=pp(w-u,.6h); z4=pp(u,0); z5=pp(w-2u,0); +pd z1; pd z5; draw z1..z2..z3..z4--z5; % stroke +endchar; + +beginpunkchar("3",9,.5,.5); +z1=pp(2u,.7h); z2=pp(.5w,h); z3=pp(w-u,.5[y2,y4]); +z4=pp(.5w-u,.55h); z5=pp(w-u,.5[y4,y6]); z6=pp(.5w,0); z7=pp(1.5u,.2h); +pd z1; pd z7; draw z1..z2..z3..z4&z4..z5..z6..z7; % arcs +endchar; + +beginpunkchar("4",9,1,1); +z1=pp(w-u,.3h); z2=pp(u,.3h); z3=pp(2/3w,h); z4=pp(2/3w,0); +pd z1; pd z4; draw z1--z2--z3--z4; % stem and diagonals +endchar; + +beginpunkchar("5",9,.5,.5); +z1=pp(w-2u,h); z2=pp(2u,h); z3=pp(u,.7h); z4=pp(w-u,.5[y3,y5]); +z5=pp(.5w,0); z6=pp(u,.2h); +pd z1; pd z6; draw z1--z2--z3..z4..z5..z6; % stroke +endchar; + +beginpunkchar("6",9,1,1); +z1=pp(2/3w,h); z2=pp(u,.3h); z3=pp(.5w,0); z4=pp(w-u,.3h); z5=pp(.6w,.6h); +z6=pp z2; pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % stroke +endchar; + +beginpunkchar("7",9,.5,1); +z1=pp(2u,h); z2=pp(w-.5u,h); z3=pp(.4w,0); +pd z1; pd z3; draw z1--z2&z2..z3{down}; % stroke +endchar; + +beginpunkchar("8",9,.5,.5); +z1=pp(.5w,h); z2=pp(u,.5[y1,y3]); z3=pp(.5w,.6h); z4=pp(w-u,.5[y3,y5]); +z5=pp(.5w,0); z6=pp(u,.5[y5,y3]); z7=pp(w-u,.5[y1,y3]); +pd z1; draw z1{curl 8}..z2..z3..z4..z5..z6..z3..z7..z1; % stroke +endchar; + +beginpunkchar("9",9,1,1); +z1=pp(1/3w,0); z2=pp(w-u,.7h); z3=pp(.5w,h); z4=pp(u,.7h); z5=pp(.5w,.4h); +pd z1; pd z5; draw z1..z2..z3..z4..z5; % stroke +endchar; + +beginpunkchar(96,9,1,1); % \`{} grave +z1=pp(2.5u,h); z2=pp(.6w,.8h); pd z1; pd z2; draw z1--z2; % diagonal +endchar; + +beginpunkchar(180,9,1,1); % \'{} acute +z1=pp(w-2.5u,h); z2=pp(.4w,.8h); pd z1; pd z2; draw z1--z2; % diagonal +endchar; + +beginpunkchar(710,13,1,1); % \^{} circumflex +z1=pp(2.5u,.8h); z2=pp(.5w,h); z3=(w-2.5u,.8h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(711,13,1,1); % \v{} caron +z1=pp(2.5u,.9h); z2=pp(.5w,.7h); z3=pp(w-2.5u,.9h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar(728,11,1,1); % \u{} breve +z1=pp(2u,h); z2=pp(.5w,.75h); z3=pp(w-2u,h); +pd z1; pd z3; draw flex(z1,z2,z3); % stroke +endchar; + +beginpunkchar(175,12,1,1); % \={} macron +z1=pp(u,.8h); z2=pp(w-u,.8h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar(729,5,1,1); % \.{} +pd pp(.5w,.9h); % dot +endchar; + +beginpunkchar(168,13,1,1); % \"{} diaeresis +pd pp(1/5w,.9h); pd pp(4/5w,.9h); % dots +endchar; + +beginpunkchar(732,13,1,1); % \~{} tilde +z1=pp(u,.75h); z2=pp(w-u,.9h); pd z1; pd z2; draw z1{up}..{up}z2; % stroke +endchar; + +beginpunkchar(733,13,1,1); % \H{} hungarumlaut +z1=pp(4u,h); z2=pp(2.5u,.7h); z3=pp(w-2u,h); z4=pp(w-3.5u,.7h); +pd z1; pd z3; draw z1--z2--z4--z3; % diagonals (linked) +endchar; + +beginpunkchar(730,13,0,0); % Scandinavian loop, for \AA\ and \aa (ring) +z0=(.5w,.66h); % point $z^2$ of lowercase A +z1=(.5w,.9h); draw z0{z0-(1.5u,0)}..z1..{(w-1.5u,0)-z0}z0; % loop +endchar; + +beginpunkchar(184,13,.5,.5); % Cedilla, for \c c +z1=(.6w,0); z2=pp(.6w,-.1h); z3=pp(2.5u,-.1h); +pd z3; draw z1--z2--z3; % stroke +endchar; + +initialize_punk_lower ; + +beginpunkchar(305,5,1,2); % dotless I +z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); +pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem +endchar; + +beginpunkchar(567,9,1,2); % dotless J +z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); +pd z1; pd z3; draw z1--z2--z3; % arc +endchar; + +beginpunkchar(223,18,.3,1); % German SS +z1=pp(.5w-u,.9h); z2=pp(1/3w,h); z3=pp(u,.7h); z4=.6[z6,z2]; +z5=pp(.5w,.35h); z6=pp(1/3w,u); z7=pp(u,.2h); +pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % left stroke +for i=1 upto 7: z[i+10]=pp(z[i] shifted (.5w-u,0)); endfor +pd z11; pd z17; draw z11--z12...z13..z14..z15...z16--z17; % right stroke +endchar; + +beginpunkchar("a",13,1,2); +z1=pp(1.5u,0); z2=(.5w,1.1h); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % left and right diagonals +z4=pp .3[z1,z2]; z5=pp .3[z3,z2]; pd z4; pd z5; draw z4--z5; % crossbar +endchar; + +beginpunkchar("b",12,1,1); +z1=pp(2u,0); z2=pp(2u,.6h); z3=pp(2u,h); pd z1; pd z3; draw z1--z3; % stem +z1.5=pp(w-u,.5y2); z2.5=pp(w-u,.5[y2,y3]); draw z2--z2.5--z3; % upper lobe +draw flex(z2,z1.5,z1); % lower lobe +endchar; + +beginpunkchar("c",13,1,2); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=(.6w,0); z5=(w-2u,.2h); +pd z1; pd z5; draw z1..z2..z3..z4..z5; % arc +endchar; + +beginpunkchar("d",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6h); +pd z1; pd z2; draw flex(z1,z3,z2); % lobe +draw z1--z2; % stem +endchar; + +beginpunkchar("e",12,.5,1); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2.5u,h); z4=pp(w-2u,0); +pd z3; pd z4; draw z4--z1--z2--z3; % stem and arms +z5=pp(2u,.6h); z6=pp(w-3u,.6h); pd z5; pd z6; draw z5--z6; % crossbar +endchar; + +beginpunkchar("f",12,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,h); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +z5=pp(2u,.6h); z6=pp(w-3u,.6h); z4=pp .5[z5,z6]-(0,.1h); +pd z5; pd z6; draw flex (z5,z4,z6); % crossbar +endchar; + +beginpunkchar("g",13,.5,.5); +z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=pp(.6w,0); z5=(w-2u,0); +pd z1; draw z1..z2..z3..z4---z5; % arc +z6=pp(.5[u,x5],.4h); pd z6; pd z5; draw z6--(pp(x5,y6))--z5; % spur +endchar; + +beginpunkchar("h",14,1,.5); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +z5=pp(2u,.6h); z6=pp(w-2u,.6h); +pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw flex(z3,z6,z4); % stems +pd z5; draw z5--z6; % crossbar +endchar; + +beginpunkchar("i",5,1,2); +z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); +pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem +endchar; + +beginpunkchar("j",9,1,2); +z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); +pd z1; pd z3; draw z1--z2--z3; % arc +endchar; + +beginpunkchar("k",14,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(2u,1/3h); z4=pp(w-1.5u,h); +pd z1; pd z2; draw z1--z2; % stem +pd z3; pd z4; draw z3--z4; % upper diagonal +z6=pp(w-u,0); z5=1/3[z3,z4]; +pd z6; draw flex(z5,.8[z1,2/3[z5,z6] ],z6);% lower diagonal +endchar; + +beginpunkchar("l",11,1,2); +z1=pp(2u,h); z2=pp(2u,0); z3=pp(w-1.5u,0); +pd z1; pd z3; draw z1--z2--z3; % stem and arm +endchar; + +beginpunkchar("m",17,.5,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(.5w,0); z4=pp(w-2u,h); z5=pp(w-2u,0); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % stems and diagonals +endchar; + +beginpunkchar("n",13,.75,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); +pd z1; pd z4; draw z1--z2--z3--z4; % stems and diagonals +endchar; + +beginpunkchar("o",12,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{left}..z2..z3..z4..z1; % bowl +endchar; + +beginpunkchar("p",13,1,2); +z1=pp(2u,0); z2=pp(2u,1.1h); z3=pp(2u,.5h); z4=pp(w,.6[y3,y2]); +pd z1; pd z3; draw z1--z2--z4--z3; % stem and bowl +endchar; + +beginpunkchar("q",14,.5,2); +z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); +pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl +z5=pp(.4w,.2h); z6=pp(w-u,-.1h); z7=pp(.5[x5,x6],-.2h); +pd z5; pd z6; draw z5--z7--z6; % tail +endchar; + +beginpunkchar("r",16,1,2); +z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6[y2,y4]); z4=pp(2u,.5h); z5=pp(w-1.5u,0); +pd z1; pd z2; pd z5; draw z1--flex(z2,z3,z4)--z5; % stem, bowl, and diagonal +endchar; + +beginpunkchar("s",11,.3,1); +z1=pp(w-2u,.9h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.6[z6,z2]; +z5=pp(w-u,.35h); z6=pp(.5w,u); z7=pp(u,.2h); +pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % stroke +endchar; + +beginpunkchar("t",13,.75,2); +z1=pp(u,h); z2=pp(w-u,h); z3=pp(.5w,0); +pd z1; pd z2; pd z3; draw z1--z2; % arms +draw .5[z1,z2]--z3; % stem +endchar; + +beginpunkchar("u",13,.3,2); +z1=pp(2u,h); z2=pp(2u,.2h); z3=pp(.5w,0); z4=pp(w-2u,.2h); z5=pp(w-2u,h); +pd z1; pd z5; draw z1---z2...z3{z4-z2}...z4---z5; % stroke +endchar; + +beginpunkchar("v",13,1,2); +z1=pp(1.5u,h); z2=pp(.5w,0); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % diagonals +endchar; + +beginpunkchar("w",18,1,2); +z1=pp(1.5u,h); z2=pp(.5[x1,x3],0); z3=pp(.5w,.8h); z4=pp(.5[x3,x5],0); +z5=pp(w-1.5u,h); +pd z1; pd z5; draw z1--z2--z3--z4--z5; % diagonals +endchar; + +beginpunkchar("x",13,1,1); +z1=pp(1.5u,h); z2=pp(w-1.5u,0); z3=pp(1.5u,0); z4=pp(w-2.5u,h); +pd z1; pd z2; draw z1--z2; % main diagonal +pd z3; pd z4; draw z3--z4; % cross diagonal +endchar; + +beginpunkchar("y",13,1,2); +z1=pp(1.5u,h); z2=pp(w-1.5u,h); z3=pp(.5w,.5h); z4=pp(.5w,0); +pd z1; pd z2; pd z4; draw z1--z3--z4; % stem and left diagonal +draw z2--z3; % right diagonal +endchar; + +beginpunkchar("z",11,1,2); +z1=pp(1.5u,h); z2=pp(w-2.5u,h); z3=pp(1.5u,0); z4=pp(w-1.5u,0); +pd z1; pd z4; draw z1--z2--z3--z4; % diagonals +endchar; + +beginpunkchar(230,16,1,2); % \ae +z1=pp(1.5u,0); z2=pp(.6w,h); z3=pp(w-1.5u,h); +pd z1; pd z3; draw z1--z2--z3; % left diagonal and upper arm +z4=pp .3[z1,z2]; z5=pp(.6w,0); z6=pp(w-2u,.3h); +pd z4; pd z6; draw z4--z6; % crossbar +z7=pp(w-u,0); pd z2; pd z7; draw z2--z5--z7; % stem and lower arm +endchar; + +beginpunkchar(339,18,1,2); % \oe +z1=pp(.5w,h); z2=pp(u,.4h); z3=pp(.5w,0); +pd z1; draw z1..z2..{right}z3; % bowl +z4=pp(w-1.5u,h); z5=pp(w-2u,.4h); z6=pp(w-u,0); +pd z4; pd z6; draw z4--z1--z3--z6; % arms and stem +pd z5; draw z5--.4[z3,z1]; % crossbar +endchar; + +beginpunkchar(248,14,1,1); % \o +z1=pp(.5w,h); z2=pp(u,.5h); z3=pp(.5w,0); z4=pp(w-u,.5h); +z5=pp(w-2u,1.1h); z6=pp(2u,-.1h); +pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % bowl and diagonal +endchar; + +revert_punk_lower; + +beginpunkchar("_",12,.5,.5); % _ +z1=pp(0,-.2h); z2=pp(w,-.2h); pd z1; pd z2; draw z1--z2; % bar +endchar; + +beginpunkchar("^",12,1,.5); % +z1=pp(.5w,h); z2=pp(1.5u,.6h); z3=pp(w-1.5u,.6h); +pd z2; pd z3; draw z2--z1--z3; +endchar; diff --git a/metapost/context/fonts/mpiv/punkfont-definitions.mp b/metapost/context/fonts/mpiv/punkfont-definitions.mp new file mode 100644 index 000000000..2901a9d03 --- /dev/null +++ b/metapost/context/fonts/mpiv/punkfont-definitions.mp @@ -0,0 +1,115 @@ +% Remark: +% +% This file is a merge of the original punk files by Donald Knuth, who +% added this comment: +% +% Font inspired by Gerard and Marjan Unger's lectures, Feb 1985 +% +% The regular punk files are part of TeXLive and in metafont format. All +% errors introduced are ours. We also changed the encoding to unicode. In +% due time we might add a few more more characters. We still need to +% improve some of the metrics which involves a bit of trial and error. The +% font just covers basic latin shapes but in ConTeXt MkIV we add virtual +% composed shapes. There is a module m-punk.tex that implements this. This +% derivate is also used in mk.tex (mk.pdf) which is one of our tests for +% LuaTeX. We published an article on it in the MAPS (NTG magazine). +% +% 2008, Taco Hoekwater & Hans Hagen + +if unknown punk_font_loaded : + + if unknown scale_factor : + scale_factor := 1 ; + fi ; + + boolean punk_font_loaded ; + + punk_font_loaded := true ; + warningcheck := 0 ; + proofing := 0 ; + designsize := 10pt#; + font_identifier := "Punk Nova" ; % dedicated to Don Knuth and Hermann Zapf + + ht# := 7pt# ; % height of characters + u# := 1/4pt# ; % unit width + dev# := .3pt# ; % standard deviation of punk points + + if known bold_punk : + s# := 1.2pt# ; % extra sidebar + px# := 1pt# ; % horizontal thickness of pen + py# := .8pt# ; % vertical thickness of pen + dot# := 1.7pt# ; % diameter of dots + else : + s# := 0 ; % extra sidebar, ok + px# := .6pt# ; % horizontal thickness of pen + py# := .5pt# ; % vertical thickness of pen + dot# := 1.3pt# ; % diameter of dots + fi ; + + pt := .1pt ; + mag := scale_factor * 10 ; + bp_per_pixel := bpppix_ * mag ; + + define_pixels(u,dev) ; + define_blacker_pixels(px,py,dot) ; + define_whole_pixels(s) ; + xoffset := s ; + + pickup pencircle xscaled px yscaled py ; + punk_pen := savepen ; + pickup pencircle scaled dot ; + path dot_pen_path ; + dot_pen_path := tensepath makepath currentpen ; + + defaultcolormodel := 1 ; + + if known slanted_punk : + dot_pen_path := dot_pen_path slanted -0.25 ; + extra_endchar := extra_endchar & "currentpicture := currentpicture slanted 0.25 ;" ; + fi ; + + + def beginpunkchar(expr c,n,h,v) = % code $c$; width is $n$ units + hdev := h * dev ; % modify horizontal amounts of deviation + vdev := v * dev ; % modify vertical amounts of deviation + beginchar(c,n*u#,ht#,0) ; + italcorr 0 ; + % italcorr ht#*slant; + pickup punk_pen + enddef ; + + def ^ = + transformed currenttransform + enddef ; + + def makebox(text rule) = + for y=0, h : % horizontals + rule((-s,y)^,(w-s,y)^) ; + endfor + for x=-s, 0, w-2s, w-s : % verticals + rule((x,0)^,(x,h)^) ; + endfor + enddef ; + + rulepen := pensquare ; + + vardef pp expr z = + z + (hdev * normaldeviate, vdev * normaldeviate) + enddef; + + def pd expr z = % {\bf drawdot} + addto currentpicture contour dot_pen_path shifted z.t_ % withpen penspeck + enddef; + + def initialize_punk_upper = + ht# := 7pt# ; dev# := .3pt# ; + enddef ; + def initialize_punk_lower = + sht# := ht#; sdev := dev; + ht# := .6ht# ; dev := .7dev ; + enddef ; + def revert_punk_lower = + ht# := sht#; dev := sdev; + enddef ; + +fi ; diff --git a/metapost/context/fonts/mpiv/punkfont-slanted.mp b/metapost/context/fonts/mpiv/punkfont-slanted.mp new file mode 100644 index 000000000..5c1ff46b2 --- /dev/null +++ b/metapost/context/fonts/mpiv/punkfont-slanted.mp @@ -0,0 +1,4 @@ +boolean slanted_punk ; slanted_punk := true ; + +input "punkfont-definitions.mp" ; +input "punkfont-characters.mp" ; diff --git a/metapost/context/fonts/mpiv/punkfont.mp b/metapost/context/fonts/mpiv/punkfont.mp new file mode 100644 index 000000000..2a03aae81 --- /dev/null +++ b/metapost/context/fonts/mpiv/punkfont.mp @@ -0,0 +1,2 @@ +input "punkfont-definitions.mp" ; +input "punkfont-characters.mp" ; diff --git a/metapost/context/fonts/punkfont-bold.mp b/metapost/context/fonts/punkfont-bold.mp deleted file mode 100644 index 1c62963f9..000000000 --- a/metapost/context/fonts/punkfont-bold.mp +++ /dev/null @@ -1,4 +0,0 @@ -boolean bold_punk ; bold_punk := true ; - -input "punkfont-definitions.mp" ; -input "punkfont-characters.mp" ; diff --git a/metapost/context/fonts/punkfont-boldslanted.mp b/metapost/context/fonts/punkfont-boldslanted.mp deleted file mode 100644 index 3e5fa1561..000000000 --- a/metapost/context/fonts/punkfont-boldslanted.mp +++ /dev/null @@ -1,5 +0,0 @@ -boolean bold_punk ; bold_punk := true ; -boolean slanted_punk ; slanted_punk := true ; - -input "punkfont-definitions.mp" ; -input "punkfont-characters.mp" ; diff --git a/metapost/context/fonts/punkfont-characters.mp b/metapost/context/fonts/punkfont-characters.mp deleted file mode 100644 index da0015b02..000000000 --- a/metapost/context/fonts/punkfont-characters.mp +++ /dev/null @@ -1,726 +0,0 @@ -initialize_punk_upper ; - -beginpunkchar("A",13,1,2); -z1=pp(1.5u,0); z2=(.5w,1.1h); z3=pp(w-1.5u,0); -pd z1; pd z3; draw z1--z2--z3; % left and right diagonals -z4=pp .3[z1,z2]; z5=pp .3[z3,z2]; pd z4; pd z5; draw z4--z5; % crossbar -endchar; - -beginpunkchar("B",12,1,1); -z1=pp(2u,0); z2=pp(2u,.6h); z3=pp(2u,h); pd z1; pd z3; draw z1--z3; % stem -z1.5=pp(w-u,.5y2); z2.5=pp(w-u,.5[y2,y3]); draw z2--z2.5--z3; % upper lobe -draw flex(z2,z1.5,z1); % lower lobe -endchar; - -beginpunkchar("C",13,1,2); -z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=(.6w,0); z5=(w-2u,.2h); -pd z1; pd z5; draw z1..z2..z3..z4..z5; % arc -endchar; - -beginpunkchar("D",14,1,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6h); -pd z1; pd z2; draw flex(z1,z3,z2); % lobe -draw z1--z2; % stem -endchar; - -beginpunkchar("E",12,.5,1); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2.5u,h); z4=pp(w-2u,0); -pd z3; pd z4; draw z4--z1--z2--z3; % stem and arms -z5=pp(2u,.6h); z6=pp(w-3u,.6h); pd z5; pd z6; draw z5--z6; % crossbar -endchar; - -beginpunkchar("F",12,.5,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,h); -pd z1; pd z3; draw z1--z2--z3; % stem and arm -z5=pp(2u,.6h); z6=pp(w-3u,.6h); z4=pp .5[z5,z6]-(0,.1h); -pd z5; pd z6; draw flex (z5,z4,z6); % crossbar -endchar; - -beginpunkchar("G",13,.5,.5); -z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=pp(.6w,0); z5=(w-2u,0); -pd z1; draw z1..z2..z3..z4---z5; % arc -z6=pp(.5[u,x5],.4h); pd z6; pd z5; draw z6--(pp(x5,y6))--z5; % spur -endchar; - -beginpunkchar("H",14,1,.5); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); -z5=pp(2u,.6h); z6=pp(w-2u,.6h); -pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw flex(z3,z6,z4); % stems -pd z5; draw z5--z6; % crossbar -endchar; - -beginpunkchar("I",5,1,2); -z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); -pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem -endchar; - -beginpunkchar("J",9,1,2); -z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); -pd z1; pd z3; draw z1--z2--z3; % arc -endchar; - -beginpunkchar("K",14,1,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(2u,1/3h); z4=pp(w-1.5u,h); -pd z1; pd z2; draw z1--z2; % stem -pd z3; pd z4; draw z3--z4; % upper diagonal -z6=pp(w-u,0); z5=1/3[z3,z4]; -pd z6; draw flex(z5,.8[z1,2/3[z5,z6] ],z6);% lower diagonal -endchar; - -beginpunkchar("L",11,1,2); -z1=pp(2u,h); z2=pp(2u,0); z3=pp(w-1.5u,0); -pd z1; pd z3; draw z1--z2--z3; % stem and arm -endchar; - -beginpunkchar("M",17,.5,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(.5w,0); z4=pp(w-2u,h); z5=pp(w-2u,0); -pd z1; pd z5; draw z1--z2--z3--z4--z5; % stems and diagonals -endchar; - -beginpunkchar("N",13,.75,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); -pd z1; pd z4; draw z1--z2--z3--z4; % stems and diagonals -endchar; - -beginpunkchar("O",12,.5,2); -z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); -pd z1; draw z1{left}..z2..z3..z4..z1; % bowl -endchar; - -beginpunkchar("P",13,1,2); -z1=pp(2u,0); z2=pp(2u,1.1h); z3=pp(2u,.5h); z4=pp(w,.6[y3,y2]); -pd z1; pd z3; draw z1--z2--z4--z3; % stem and bowl -endchar; - -beginpunkchar("Q",14,.5,2); -z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); -pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl -z5=pp(.4w,.2h); z6=pp(w-u,-.1h); z7=pp(.5[x5,x6],-.2h); -pd z5; pd z6; draw z5--z7--z6; % tail -endchar; - -beginpunkchar("R",16,1,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6[y2,y4]); z4=pp(2u,.5h); z5=pp(w-1.5u,0); -pd z1; pd z2; pd z5; draw z1--flex(z2,z3,z4)--z5; % stem, bowl, and diagonal -endchar; - -beginpunkchar("S",11,.3,1); -z1=pp(w-2u,.9h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.6[z6,z2]; -z5=pp(w-u,.35h); z6=pp(.5w,u); z7=pp(u,.2h); -pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % stroke -endchar; - -beginpunkchar("T",13,.75,2); -z1=pp(u,h); z2=pp(w-u,h); z3=pp(.5w,0); -pd z1; pd z2; pd z3; draw z1--z2; % arms -draw .5[z1,z2]--z3; % stem -endchar; - -beginpunkchar("U",13,.3,2); -z1=pp(2u,h); z2=pp(2u,.2h); z3=pp(.5w,0); z4=pp(w-2u,.2h); z5=pp(w-2u,h); -pd z1; pd z5; draw z1---z2...z3{z4-z2}...z4---z5; % stroke -endchar; - -beginpunkchar("V",13,1,2); -z1=pp(1.5u,h); z2=pp(.5w,0); z3=pp(w-1.5u,h); -pd z1; pd z3; draw z1--z2--z3; % diagonals -endchar; - -beginpunkchar("W",18,1,2); -z1=pp(1.5u,h); z2=pp(.5[x1,x3],0); z3=pp(.5w,.8h); z4=pp(.5[x3,x5],0); -z5=pp(w-1.5u,h); -pd z1; pd z5; draw z1--z2--z3--z4--z5; % diagonals -endchar; - -beginpunkchar("X",13,1,1); -z1=pp(1.5u,h); z2=pp(w-1.5u,0); z3=pp(1.5u,0); z4=pp(w-2.5u,h); -pd z1; pd z2; draw z1--z2; % main diagonal -pd z3; pd z4; draw z3--z4; % cross diagonal -endchar; - -beginpunkchar("Y",13,1,2); -z1=pp(1.5u,h); z2=pp(w-1.5u,h); z3=pp(.5w,.5h); z4=pp(.5w,0); -pd z1; pd z2; pd z4; draw z1--z3--z4; % stem and left diagonal -draw z2--z3; % right diagonal -endchar; - -beginpunkchar("Z",11,1,2); -z1=pp(1.5u,h); z2=pp(w-2.5u,h); z3=pp(1.5u,0); z4=pp(w-1.5u,0); -pd z1; pd z4; draw z1--z2--z3--z4; % diagonals -endchar; - -beginpunkchar(198,16,1,2); % \AE -z1=pp(1.5u,0); z2=pp(.6w,h); z3=pp(w-1.5u,h); -pd z1; pd z3; draw z1--z2--z3; % left diagonal and upper arm -z4=pp .3[z1,z2]; z5=pp(.6w,0); z6=pp(w-2u,.3h); -pd z4; pd z6; draw z4--z6; % crossbar -z7=pp(w-u,0); pd z2; pd z7; draw z2--z5--z7; % stem and lower arm -endchar; - -beginpunkchar(338,18,1,2); % \OE -z1=pp(.5w,h); z2=pp(u,.4h); z3=pp(.5w,0); -pd z1; draw z1..z2..{right}z3; % bowl -z4=pp(w-1.5u,h); z5=pp(w-2u,.4h); z6=pp(w-u,0); -pd z4; pd z6; draw z4--z1--z3--z6; % arms and stem -pd z5; draw z5--.4[z3,z1]; % crossbar -endchar; - -beginpunkchar(216,14,1,1); % \O -z1=pp(.5w,h); z2=pp(u,.5h); z3=pp(.5w,0); z4=pp(w-u,.5h); -z5=pp(w-2u,1.1h); z6=pp(2u,-.1h); -pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % bowl and diagonal -endchar; - -beginpunkchar(915,11,1,2); % $\Gamma$ -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-1.5u,h); -pd z1; pd z3; draw z1--z2--z3; % stem and arm -endchar; - -beginpunkchar(916,15,1,2); % $\Delta$ -z1=pp(u,0); z2=pp(.5w,h); z3=pp(w-u,0); -pd z1; draw z1--z2..tension 5..z3..tension 5..z1; % triangle -endchar; - -beginpunkchar(920,15,.5,2); % $\Theta$ -z1=pp(.5w,h); z2=pp(u,.6h); z3=pp(.5w,0); z4=pp(w-u,.6h); -pd z1; draw z1..tension.8..z2..z3..z4..tension.8..z1; % bowl -z5=pp(x2+2u,.4h); z6=pp(x4-2u,.4h); pd z5; pd z6; draw z5--z6; % bar -endchar; - -beginpunkchar(923,12,1,2); % $\Lambda$ -z1=pp(u,0); z2=pp(.5w,h); z3=pp(w-u,0); -pd z1; pd z3; draw z1--z2--z3; % diagonals -endchar; - -beginpunkchar(926,12,1,1); % $\Xi$ -z1=pp(u,h); z2=pp(w-u,h); pd z1; pd z2; draw z1--z2; % upper arm -z3=pp(2u,.55h); z4=pp(w-2u,.55h); pd z3; pd z4; draw z3--z4; % bar -z5=pp(u,0); z6=pp(w-u,0); pd z5; pd z6; draw z5--z6; % lower arm -endchar; - -beginpunkchar(928,13,1,.5); % $\Pi$ -z1=pp(1.5u,0); z2=pp(1.5u,h); z3=pp(w-1.5u,h); z4=pp(w-1.5u,0); -pd z1; pd z4; draw z1--z2--z3--z4; % stems and bar -endchar; - -beginpunkchar(931,13,1,1); % $\Sigma$ -z1=pp(w-u,h); z2=pp(u,h); z3=pp(.5w-u,.5h); z4=pp(u,0); z5=pp(w-u,0); -pd z1; pd z5; draw z1--z2{.5[z4,z5]-z2}..z3--z4--z5; % arms and diagonals -endchar; - -beginpunkchar(933,15,1,.5); % $\Upsilon$ -z1=pp(u,.8h); z2=pp(.3w,h); z3=pp(.5w,.5h); z4=pp(.5w,0); -pd z1; pd z4; draw z1..z2..tension2..z3---z4; % left arc and stem -z5=pp(w-u,.8h); z6=pp(.7w,h); -pd z5; draw z5..z6..tension2..{z4-z3}z3; % right arc -endchar; - -beginpunkchar(934,13,1,2); % $\Phi$ -z1=pp(.5w,h); z2=pp(.5w,0); pd z1; pd z2; draw z1--z2; % stem -z3=pp(.5w,2/3h); z4=pp(u,.5h); z5=pp(.5w,1/4h); z6=pp(w-u,.5h); -pd z3; draw z3..z4..z5..z6..z3; % bowl -endchar; - -beginpunkchar(936,14,1,1); % $\Psi$ -z1=pp(.5w,h); z2=pp(.5w,0); pd z1; pd z2; draw z1--z2; % stem -z3=pp(u,.8h); z4=pp(.5w,.2h); z5=pp(w-u,.8h); -pd z3; pd z5; draw z3{.4[z1,z2]-z3}..z4{right}..{z5-.4[z1,z2]}z5; % stroke -endchar; - -beginpunkchar(937,13,1,2); % $\Omega$ -z1=pp(u,0); z2=pp(1/3w,0); z3=pp(u,2/3h); z4=pp(.5w,h); -z5=pp(w-u,2/3h); z6=pp(2/3w,0); z7=pp(w-u,0); -pd z1; pd z7; draw z1--z2{up}..z3..z4..z5..{down}z6--z7; % bowl and arms -endchar; - -beginpunkchar(".",5,1,2); -pd pp(.5w,0); % dot -endchar; - -beginpunkchar(",",5,.5,.5); -z1=pp(.5w,0); z2=pp(w-u,-.1h); z3=pp(.5w,-.3h); -pd z1; pd z3; draw z1--z2--z3; % stroke -endchar; - -beginpunkchar(":",5,1,.5); -pd pp(.5w,0); pd pp(.5w,.4h); % dots -endchar; - -beginpunkchar(";",5,.5,.5); -z1=pp(.5w,0); z2=pp(w-u,-.1h); z3=pp(.5w,-.3h); -pd z1; pd z3; draw z1--z2--z3; % stroke -pd pp(.5w,.4h); % dot -endchar; - -beginpunkchar("!",5,.5,.5); -pd pp(.5w,0); % dot -z1=pp(.5w,1.05h); z2=pp(.5w,.3h); pd z1; pd z2; draw z1--z2; % stem -endchar; - -beginpunkchar(161,5,.5,.5); % spanish inverted ! -pd pp(.5w,.9h); % dot -z1=pp(.5w,-.1h); z2=pp(.5w,.6h); pd z1; pd z2; draw z1--z2; % stem -endchar; - -beginpunkchar("?",9,1,.5); -z1=pp(1.5u,.8h); z2=pp(.5w,h); z3=pp(w-u,.8h); z4=pp(.5w,.3h); -pd z1; pd z4; draw z1..z2..z3..{down}z4; % arc and stem -pd pp(.5w,0); % dot -endchar; - -beginpunkchar(191,9,1,.5); % spanish inverted ? -z1=pp(1.5u,.1h); z2=pp(.5w,-.1h); z3=pp(w-u,.1h); z4=pp(.5w,.6h); -pd z1; pd z4; draw z1..z2..z3..{up}z4; % arc and stem -pd pp(.5w,.9h); % dot -endchar; - -beginpunkchar("&",14,.5,.5); -z1=pp(w-2u,h); z2=pp(u,h); z3=pp(3u,0); z5=pp(w-u,.6h); z6=pp(w-2u,0); -pd z1; pd z5; draw z1--z2--z3--z5; % arms and stem -draw z1--.5[z2,z3]; pd z6; draw z6--.6[z3,z5]; % diagonals -endchar; - -beginpunkchar("$",12,.5,.5); -z1=pp(w-1.5u,.7h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.5[z3,z5]; -z5=pp(w-u,.3h); z6=pp(.5w,0); z7=pp(u,.3h); -pd z1; pd z7; draw z1..z2..z3..z4..z5..z6..z7; % stroke -z8=z2+(0,.1h); pd z8; draw z8--z6; % stem -endchar; - -beginpunkchar("%",18,.5,.5); -z1=pp(3.5u,1.1h); z2=pp(u,.8h); z3=pp(3.5u,.5h); z4=pp(6u,.8h); -z5=pp(w-3.5u,.5h); z6=pp(w-6u,.2h); z7=pp(w-3.5u,-.1h); z8=pp(w-u,.2h); -pd z1; draw z1..z2..z3..z4..z1; % upper bowl -pd z5; draw z5..z6..z7..z8..z5; % lower bowl -z9=pp(w-3u,1.1h); z0=pp(3u,-.1h); pd z0; draw z9--z0; % diagonal -draw z1{z5-z1}..z9; % link -endchar; - -beginpunkchar("@",18,1,.5); -z1=pp(2u,0); z2=pp(1/3w,.7h); z3=pp(w-6u,0); -z4=pp(w,.3h); z5=pp(1/3w,h); z6=pp(u,.5h); z7=.7[z2,z3]; -pd z1; pd z7; draw z1--z2--z3{right}..z4..z5..z6..z7; % diagonals and stroke -endchar; - -beginpunkchar("-",7,.5,.5); -z1=pp(u,.4h); z2=pp(w-u,.5h); pd z1; pd z2; draw z1--z2; % bar -endchar; - -beginpunkchar(8211,9,.5,.5); % -- -z1=pp(0,.5h); z2=pp(w,.4h); pd z1; pd z2; draw z1--z2; % bar -endchar; - -beginpunkchar(8212,18,.5,.5); % --- -z1=pp(0,.5h); z2=pp(w,.4h); pd z1; pd z2; draw z1--z2; % bar -endchar; - -beginpunkchar("+",9,.5,1); -z1=pp(0,.5h); z2=pp(w,.5h); pd z1; pd z2; draw z1--z2; % bar -z3=pp(.5w,.1h); z4=pp(.5w,.9h); pd z3; pd z4; draw z3--z4; % stem -endchar; - -beginpunkchar("*",13,.5,1); -z0=pp(.5w,1.1h); z1=pp(u,.9h); z2=pp(2u,.3h); z3=pp(w-u,.3h); z4=pp(w-u,.9h); -pd z0; draw z0--z2..1/3[.5[z2,z4],z0]..z4--z1--z3--z0; % star -endchar; - -beginpunkchar(39,5,.5,1.5); % ' apostrofe HH/TH (to be checked) -z1=pp(w/2,h); z2=pp(w/2+u,.85h); z3=pp(w/2,2/3h); -pd z1; pd z3; draw z1..z2..z3; % stroke -endchar; - -beginpunkchar(34,9,1,1.5); % " HH/TH (to be checked) -z1=pp(1.5u,h); z2=pp(1.5u,.6h); z3=pp(w-1.5u,h); z4=pp(w-1.5u,.6h); -pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw z3--z4; -endchar; - -beginpunkchar(8216,5,.3,.5); % ` -z1=pp(w-1.5u,h); z2=pp(u,.85h); z3=pp(w-u,2/3h); -pd z1; pd z3; draw z1--z2--z3; % stroke -endchar; - -beginpunkchar(8217,5,.3,.5); % ' -z1=pp(1.5u,h); z2=pp(w-u,.85h); z3=pp(u,2/3h); -pd z1; pd z3; draw z1--z2--z3; % stroke -endchar; - -beginpunkchar(8220,9,.3,.5); % `` quotedblleft -z1=pp(.5w+.5u,h); z2=pp(w-u,.6h); z3=pp(u,.95h); -pd z1; pd z3; draw z1--z2--z3; % stroke -endchar; - -beginpunkchar(8221,9,.3,.5); % '' quotedblright -z1=pp(.5w-.5u,h); z2=pp(u,.6h); z3=pp(w-u,.95h); -pd z1; pd z3; draw z1--z2--z3; % stroke -endchar; - -beginpunkchar("(",7,.5,.5); -z1=pp(w-u,h); z2=pp(u,.5h); z3=pp(w-u,0); -pd z1; pd z3; draw z1..z2..z3; % stroke -endchar; - -beginpunkchar(")",7,.5,.5); -z1=pp(u,h); z2=pp(w-u,.5h); z3=pp(u,0); pd z1; pd z3; draw z1..z2..z3; % stroke -endchar; - -beginpunkchar("[",8,.5,.5); -z1=pp(w-u,h); z2=pp(.5w,h); z3=pp(.5w,0); z4=pp(w-u,0); -pd z1; pd z4; draw z1--z2--z3--z4; % bars and stem -endchar; - -beginpunkchar("]",8,.5,.5); -z1=pp(u,h); z2=pp(.5w,h); z3=pp(.5w,0); z4=pp(u,0); -pd z1; pd z4; draw z1--z2--z3--z4; % bars and stem -endchar; - -beginpunkchar("<",9,.5,.5); -z1=pp(w-u,.9h); z2=pp(u,.5h); z3=pp(w-u,.1h); -pd z1; pd z3; draw z1--z2--z3; % diagonals -endchar; - -beginpunkchar(">",9,.5,.5); -z1=pp(u,.9h); z2=pp(w-u,.5h); z3=pp(u,.1h); -pd z1; pd z3; draw z1--z2--z3; % diagonals -endchar; - -beginpunkchar("{",10,.5,.5); % HH/TH -z1=pp(w-2u,h); z3=pp(2u,.5h); z5=pp(w-2u,0); -z2=pp(w-4u,.6h); z4=(w-4u,.4h); -pd z1; pd z3; pd z5; draw z1{left}..z2--z3 & z3--z4..{right}z5; -endchar; - -beginpunkchar("}",10,.5,.5); % HH/TH -z1=pp(2u,h); z3=pp(w-2u,.5h); z5=pp(2u,0); -z2=pp(4u,.6h); z4=(4u,.4h); -pd z1; pd z3; pd z5; draw z1{right}..z2--z3 & z3--z4..{left}z5; -endchar; - -beginpunkchar("=",9,.5,.5); -z5=pp(u,2/3h); z6=pp(w-u,2/3h); pd z5; pd z6; draw z5--z6; % upper bar -z7=pp(u,1/3h); z8=pp(w-u,1/3h); pd z7; pd z8; draw z7--z8; % lower bar -endchar; - -beginpunkchar("#",15,.5,.5); -z1=pp(.5w,h); z2=pp(3u,0); z3=pp(w-3u,h); z4=pp(.5w,0); -pd z2; pd z3; draw z3--z1--z2; draw z3--z4--z2; % diagonals (linked) -z5=pp(u,2/3h); z6=pp(w-u,2/3h); pd z5; pd z6; draw z5--z6; % upper bar -z7=pp(u,1/3h); z8=pp(w-u,1/3h); pd z7; pd z8; draw z7--z8; % lower bar -endchar; - -beginpunkchar("/",9,1,1); -z1=pp(1.5u,-.05h); z2=pp(w-1.5u,1.05h); pd z1; pd z2; draw z1--z2; % diagonal -endchar; - -beginpunkchar("\",9,1,1); % HH/TH -z1=pp(1.5u,1.05h); z2=pp(w-1.5u,-.05h); pd z1; pd z2; draw z1--z2; % reverse diagonal -endchar; - - -beginpunkchar("0",9,.5,1); -z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); -pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl -endchar; - -beginpunkchar("1",9,.3,1); -z1=pp(2u,.7h); z2=pp(.6w,h); z3=pp(.6w,0); -pd z1; pd z3; draw z1--z2--z3; % serif and stem -endchar; - -beginpunkchar("2",9,1,1); -z1=pp(2u,.7h); z2=pp(.5w,h); z3=pp(w-u,.6h); z4=pp(u,0); z5=pp(w-2u,0); -pd z1; pd z5; draw z1..z2..z3..z4--z5; % stroke -endchar; - -beginpunkchar("3",9,.5,.5); -z1=pp(2u,.7h); z2=pp(.5w,h); z3=pp(w-u,.5[y2,y4]); -z4=pp(.5w-u,.55h); z5=pp(w-u,.5[y4,y6]); z6=pp(.5w,0); z7=pp(1.5u,.2h); -pd z1; pd z7; draw z1..z2..z3..z4&z4..z5..z6..z7; % arcs -endchar; - -beginpunkchar("4",9,1,1); -z1=pp(w-u,.3h); z2=pp(u,.3h); z3=pp(2/3w,h); z4=pp(2/3w,0); -pd z1; pd z4; draw z1--z2--z3--z4; % stem and diagonals -endchar; - -beginpunkchar("5",9,.5,.5); -z1=pp(w-2u,h); z2=pp(2u,h); z3=pp(u,.7h); z4=pp(w-u,.5[y3,y5]); -z5=pp(.5w,0); z6=pp(u,.2h); -pd z1; pd z6; draw z1--z2--z3..z4..z5..z6; % stroke -endchar; - -beginpunkchar("6",9,1,1); -z1=pp(2/3w,h); z2=pp(u,.3h); z3=pp(.5w,0); z4=pp(w-u,.3h); z5=pp(.6w,.6h); -z6=pp z2; pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % stroke -endchar; - -beginpunkchar("7",9,.5,1); -z1=pp(2u,h); z2=pp(w-.5u,h); z3=pp(.4w,0); -pd z1; pd z3; draw z1--z2&z2..z3{down}; % stroke -endchar; - -beginpunkchar("8",9,.5,.5); -z1=pp(.5w,h); z2=pp(u,.5[y1,y3]); z3=pp(.5w,.6h); z4=pp(w-u,.5[y3,y5]); -z5=pp(.5w,0); z6=pp(u,.5[y5,y3]); z7=pp(w-u,.5[y1,y3]); -pd z1; draw z1{curl 8}..z2..z3..z4..z5..z6..z3..z7..z1; % stroke -endchar; - -beginpunkchar("9",9,1,1); -z1=pp(1/3w,0); z2=pp(w-u,.7h); z3=pp(.5w,h); z4=pp(u,.7h); z5=pp(.5w,.4h); -pd z1; pd z5; draw z1..z2..z3..z4..z5; % stroke -endchar; - -beginpunkchar(96,9,1,1); % \`{} grave -z1=pp(2.5u,h); z2=pp(.6w,.8h); pd z1; pd z2; draw z1--z2; % diagonal -endchar; - -beginpunkchar(180,9,1,1); % \'{} acute -z1=pp(w-2.5u,h); z2=pp(.4w,.8h); pd z1; pd z2; draw z1--z2; % diagonal -endchar; - -beginpunkchar(710,13,1,1); % \^{} circumflex -z1=pp(2.5u,.8h); z2=pp(.5w,h); z3=(w-2.5u,.8h); -pd z1; pd z3; draw z1--z2--z3; % diagonals -endchar; - -beginpunkchar(711,13,1,1); % \v{} caron -z1=pp(2.5u,.9h); z2=pp(.5w,.7h); z3=pp(w-2.5u,.9h); -pd z1; pd z3; draw z1--z2--z3; % diagonals -endchar; - -beginpunkchar(728,11,1,1); % \u{} breve -z1=pp(2u,h); z2=pp(.5w,.75h); z3=pp(w-2u,h); -pd z1; pd z3; draw flex(z1,z2,z3); % stroke -endchar; - -beginpunkchar(175,12,1,1); % \={} macron -z1=pp(u,.8h); z2=pp(w-u,.8h); pd z1; pd z2; draw z1--z2; % bar -endchar; - -beginpunkchar(729,5,1,1); % \.{} -pd pp(.5w,.9h); % dot -endchar; - -beginpunkchar(168,13,1,1); % \"{} diaeresis -pd pp(1/5w,.9h); pd pp(4/5w,.9h); % dots -endchar; - -beginpunkchar(732,13,1,1); % \~{} tilde -z1=pp(u,.75h); z2=pp(w-u,.9h); pd z1; pd z2; draw z1{up}..{up}z2; % stroke -endchar; - -beginpunkchar(733,13,1,1); % \H{} hungarumlaut -z1=pp(4u,h); z2=pp(2.5u,.7h); z3=pp(w-2u,h); z4=pp(w-3.5u,.7h); -pd z1; pd z3; draw z1--z2--z4--z3; % diagonals (linked) -endchar; - -beginpunkchar(730,13,0,0); % Scandinavian loop, for \AA\ and \aa (ring) -z0=(.5w,.66h); % point $z^2$ of lowercase A -z1=(.5w,.9h); draw z0{z0-(1.5u,0)}..z1..{(w-1.5u,0)-z0}z0; % loop -endchar; - -beginpunkchar(184,13,.5,.5); % Cedilla, for \c c -z1=(.6w,0); z2=pp(.6w,-.1h); z3=pp(2.5u,-.1h); -pd z3; draw z1--z2--z3; % stroke -endchar; - -initialize_punk_lower ; - -beginpunkchar(305,5,1,2); % dotless I -z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); -pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem -endchar; - -beginpunkchar(567,9,1,2); % dotless J -z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); -pd z1; pd z3; draw z1--z2--z3; % arc -endchar; - -beginpunkchar(223,18,.3,1); % German SS -z1=pp(.5w-u,.9h); z2=pp(1/3w,h); z3=pp(u,.7h); z4=.6[z6,z2]; -z5=pp(.5w,.35h); z6=pp(1/3w,u); z7=pp(u,.2h); -pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % left stroke -for i=1 upto 7: z[i+10]=pp(z[i] shifted (.5w-u,0)); endfor -pd z11; pd z17; draw z11--z12...z13..z14..z15...z16--z17; % right stroke -endchar; - -beginpunkchar("a",13,1,2); -z1=pp(1.5u,0); z2=(.5w,1.1h); z3=pp(w-1.5u,0); -pd z1; pd z3; draw z1--z2--z3; % left and right diagonals -z4=pp .3[z1,z2]; z5=pp .3[z3,z2]; pd z4; pd z5; draw z4--z5; % crossbar -endchar; - -beginpunkchar("b",12,1,1); -z1=pp(2u,0); z2=pp(2u,.6h); z3=pp(2u,h); pd z1; pd z3; draw z1--z3; % stem -z1.5=pp(w-u,.5y2); z2.5=pp(w-u,.5[y2,y3]); draw z2--z2.5--z3; % upper lobe -draw flex(z2,z1.5,z1); % lower lobe -endchar; - -beginpunkchar("c",13,1,2); -z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=(.6w,0); z5=(w-2u,.2h); -pd z1; pd z5; draw z1..z2..z3..z4..z5; % arc -endchar; - -beginpunkchar("d",14,1,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6h); -pd z1; pd z2; draw flex(z1,z3,z2); % lobe -draw z1--z2; % stem -endchar; - -beginpunkchar("e",12,.5,1); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2.5u,h); z4=pp(w-2u,0); -pd z3; pd z4; draw z4--z1--z2--z3; % stem and arms -z5=pp(2u,.6h); z6=pp(w-3u,.6h); pd z5; pd z6; draw z5--z6; % crossbar -endchar; - -beginpunkchar("f",12,.5,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,h); -pd z1; pd z3; draw z1--z2--z3; % stem and arm -z5=pp(2u,.6h); z6=pp(w-3u,.6h); z4=pp .5[z5,z6]-(0,.1h); -pd z5; pd z6; draw flex (z5,z4,z6); % crossbar -endchar; - -beginpunkchar("g",13,.5,.5); -z1=pp(w-2u,.8h); z2=pp(.6w,h); z3=pp(u,.5h); z4=pp(.6w,0); z5=(w-2u,0); -pd z1; draw z1..z2..z3..z4---z5; % arc -z6=pp(.5[u,x5],.4h); pd z6; pd z5; draw z6--(pp(x5,y6))--z5; % spur -endchar; - -beginpunkchar("h",14,1,.5); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); -z5=pp(2u,.6h); z6=pp(w-2u,.6h); -pd z1; pd z2; pd z3; pd z4; draw z1--z2; draw flex(z3,z6,z4); % stems -pd z5; draw z5--z6; % crossbar -endchar; - -beginpunkchar("i",5,1,2); -z1=pp(.5w,0); z2=(.5w,1/3h); z3=(.5w,2/3h); z4=(.5w,h); -pd z1; pd z4; draw flex(z1,z2,z3,z4); % stem -endchar; - -beginpunkchar("j",9,1,2); -z1=pp(w-2u,h); z2=pp(w-2u,-.1h); z3=pp(u,0); -pd z1; pd z3; draw z1--z2--z3; % arc -endchar; - -beginpunkchar("k",14,1,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(2u,1/3h); z4=pp(w-1.5u,h); -pd z1; pd z2; draw z1--z2; % stem -pd z3; pd z4; draw z3--z4; % upper diagonal -z6=pp(w-u,0); z5=1/3[z3,z4]; -pd z6; draw flex(z5,.8[z1,2/3[z5,z6] ],z6);% lower diagonal -endchar; - -beginpunkchar("l",11,1,2); -z1=pp(2u,h); z2=pp(2u,0); z3=pp(w-1.5u,0); -pd z1; pd z3; draw z1--z2--z3; % stem and arm -endchar; - -beginpunkchar("m",17,.5,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(.5w,0); z4=pp(w-2u,h); z5=pp(w-2u,0); -pd z1; pd z5; draw z1--z2--z3--z4--z5; % stems and diagonals -endchar; - -beginpunkchar("n",13,.75,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-2u,0); z4=pp(w-2u,h); -pd z1; pd z4; draw z1--z2--z3--z4; % stems and diagonals -endchar; - -beginpunkchar("o",12,.5,2); -z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); -pd z1; draw z1{left}..z2..z3..z4..z1; % bowl -endchar; - -beginpunkchar("p",13,1,2); -z1=pp(2u,0); z2=pp(2u,1.1h); z3=pp(2u,.5h); z4=pp(w,.6[y3,y2]); -pd z1; pd z3; draw z1--z2--z4--z3; % stem and bowl -endchar; - -beginpunkchar("q",14,.5,2); -z1=pp(.5w,h); z2=pp(u,.55h); z3=pp(.5w,0); z4=pp(w-u,.55h); -pd z1; draw z1{curl 2}..z2..z3..z4..z1; % bowl -z5=pp(.4w,.2h); z6=pp(w-u,-.1h); z7=pp(.5[x5,x6],-.2h); -pd z5; pd z6; draw z5--z7--z6; % tail -endchar; - -beginpunkchar("r",16,1,2); -z1=pp(2u,0); z2=pp(2u,h); z3=pp(w-u,.6[y2,y4]); z4=pp(2u,.5h); z5=pp(w-1.5u,0); -pd z1; pd z2; pd z5; draw z1--flex(z2,z3,z4)--z5; % stem, bowl, and diagonal -endchar; - -beginpunkchar("s",11,.3,1); -z1=pp(w-2u,.9h); z2=pp(.5w,h); z3=pp(u,.7h); z4=.6[z6,z2]; -z5=pp(w-u,.35h); z6=pp(.5w,u); z7=pp(u,.2h); -pd z1; pd z7; draw z1--z2...z3..z4..z5...z6--z7; % stroke -endchar; - -beginpunkchar("t",13,.75,2); -z1=pp(u,h); z2=pp(w-u,h); z3=pp(.5w,0); -pd z1; pd z2; pd z3; draw z1--z2; % arms -draw .5[z1,z2]--z3; % stem -endchar; - -beginpunkchar("u",13,.3,2); -z1=pp(2u,h); z2=pp(2u,.2h); z3=pp(.5w,0); z4=pp(w-2u,.2h); z5=pp(w-2u,h); -pd z1; pd z5; draw z1---z2...z3{z4-z2}...z4---z5; % stroke -endchar; - -beginpunkchar("v",13,1,2); -z1=pp(1.5u,h); z2=pp(.5w,0); z3=pp(w-1.5u,h); -pd z1; pd z3; draw z1--z2--z3; % diagonals -endchar; - -beginpunkchar("w",18,1,2); -z1=pp(1.5u,h); z2=pp(.5[x1,x3],0); z3=pp(.5w,.8h); z4=pp(.5[x3,x5],0); -z5=pp(w-1.5u,h); -pd z1; pd z5; draw z1--z2--z3--z4--z5; % diagonals -endchar; - -beginpunkchar("x",13,1,1); -z1=pp(1.5u,h); z2=pp(w-1.5u,0); z3=pp(1.5u,0); z4=pp(w-2.5u,h); -pd z1; pd z2; draw z1--z2; % main diagonal -pd z3; pd z4; draw z3--z4; % cross diagonal -endchar; - -beginpunkchar("y",13,1,2); -z1=pp(1.5u,h); z2=pp(w-1.5u,h); z3=pp(.5w,.5h); z4=pp(.5w,0); -pd z1; pd z2; pd z4; draw z1--z3--z4; % stem and left diagonal -draw z2--z3; % right diagonal -endchar; - -beginpunkchar("z",11,1,2); -z1=pp(1.5u,h); z2=pp(w-2.5u,h); z3=pp(1.5u,0); z4=pp(w-1.5u,0); -pd z1; pd z4; draw z1--z2--z3--z4; % diagonals -endchar; - -beginpunkchar(230,16,1,2); % \ae -z1=pp(1.5u,0); z2=pp(.6w,h); z3=pp(w-1.5u,h); -pd z1; pd z3; draw z1--z2--z3; % left diagonal and upper arm -z4=pp .3[z1,z2]; z5=pp(.6w,0); z6=pp(w-2u,.3h); -pd z4; pd z6; draw z4--z6; % crossbar -z7=pp(w-u,0); pd z2; pd z7; draw z2--z5--z7; % stem and lower arm -endchar; - -beginpunkchar(339,18,1,2); % \oe -z1=pp(.5w,h); z2=pp(u,.4h); z3=pp(.5w,0); -pd z1; draw z1..z2..{right}z3; % bowl -z4=pp(w-1.5u,h); z5=pp(w-2u,.4h); z6=pp(w-u,0); -pd z4; pd z6; draw z4--z1--z3--z6; % arms and stem -pd z5; draw z5--.4[z3,z1]; % crossbar -endchar; - -beginpunkchar(248,14,1,1); % \o -z1=pp(.5w,h); z2=pp(u,.5h); z3=pp(.5w,0); z4=pp(w-u,.5h); -z5=pp(w-2u,1.1h); z6=pp(2u,-.1h); -pd z1; pd z6; draw z1..z2..z3..z4..z5--z6; % bowl and diagonal -endchar; - -revert_punk_lower; - -beginpunkchar("_",12,.5,.5); % _ -z1=pp(0,-.2h); z2=pp(w,-.2h); pd z1; pd z2; draw z1--z2; % bar -endchar; - -beginpunkchar("^",12,1,.5); % -z1=pp(.5w,h); z2=pp(1.5u,.6h); z3=pp(w-1.5u,.6h); -pd z2; pd z3; draw z2--z1--z3; -endchar; diff --git a/metapost/context/fonts/punkfont-definitions.mp b/metapost/context/fonts/punkfont-definitions.mp deleted file mode 100644 index 2901a9d03..000000000 --- a/metapost/context/fonts/punkfont-definitions.mp +++ /dev/null @@ -1,115 +0,0 @@ -% Remark: -% -% This file is a merge of the original punk files by Donald Knuth, who -% added this comment: -% -% Font inspired by Gerard and Marjan Unger's lectures, Feb 1985 -% -% The regular punk files are part of TeXLive and in metafont format. All -% errors introduced are ours. We also changed the encoding to unicode. In -% due time we might add a few more more characters. We still need to -% improve some of the metrics which involves a bit of trial and error. The -% font just covers basic latin shapes but in ConTeXt MkIV we add virtual -% composed shapes. There is a module m-punk.tex that implements this. This -% derivate is also used in mk.tex (mk.pdf) which is one of our tests for -% LuaTeX. We published an article on it in the MAPS (NTG magazine). -% -% 2008, Taco Hoekwater & Hans Hagen - -if unknown punk_font_loaded : - - if unknown scale_factor : - scale_factor := 1 ; - fi ; - - boolean punk_font_loaded ; - - punk_font_loaded := true ; - warningcheck := 0 ; - proofing := 0 ; - designsize := 10pt#; - font_identifier := "Punk Nova" ; % dedicated to Don Knuth and Hermann Zapf - - ht# := 7pt# ; % height of characters - u# := 1/4pt# ; % unit width - dev# := .3pt# ; % standard deviation of punk points - - if known bold_punk : - s# := 1.2pt# ; % extra sidebar - px# := 1pt# ; % horizontal thickness of pen - py# := .8pt# ; % vertical thickness of pen - dot# := 1.7pt# ; % diameter of dots - else : - s# := 0 ; % extra sidebar, ok - px# := .6pt# ; % horizontal thickness of pen - py# := .5pt# ; % vertical thickness of pen - dot# := 1.3pt# ; % diameter of dots - fi ; - - pt := .1pt ; - mag := scale_factor * 10 ; - bp_per_pixel := bpppix_ * mag ; - - define_pixels(u,dev) ; - define_blacker_pixels(px,py,dot) ; - define_whole_pixels(s) ; - xoffset := s ; - - pickup pencircle xscaled px yscaled py ; - punk_pen := savepen ; - pickup pencircle scaled dot ; - path dot_pen_path ; - dot_pen_path := tensepath makepath currentpen ; - - defaultcolormodel := 1 ; - - if known slanted_punk : - dot_pen_path := dot_pen_path slanted -0.25 ; - extra_endchar := extra_endchar & "currentpicture := currentpicture slanted 0.25 ;" ; - fi ; - - - def beginpunkchar(expr c,n,h,v) = % code $c$; width is $n$ units - hdev := h * dev ; % modify horizontal amounts of deviation - vdev := v * dev ; % modify vertical amounts of deviation - beginchar(c,n*u#,ht#,0) ; - italcorr 0 ; - % italcorr ht#*slant; - pickup punk_pen - enddef ; - - def ^ = - transformed currenttransform - enddef ; - - def makebox(text rule) = - for y=0, h : % horizontals - rule((-s,y)^,(w-s,y)^) ; - endfor - for x=-s, 0, w-2s, w-s : % verticals - rule((x,0)^,(x,h)^) ; - endfor - enddef ; - - rulepen := pensquare ; - - vardef pp expr z = - z + (hdev * normaldeviate, vdev * normaldeviate) - enddef; - - def pd expr z = % {\bf drawdot} - addto currentpicture contour dot_pen_path shifted z.t_ % withpen penspeck - enddef; - - def initialize_punk_upper = - ht# := 7pt# ; dev# := .3pt# ; - enddef ; - def initialize_punk_lower = - sht# := ht#; sdev := dev; - ht# := .6ht# ; dev := .7dev ; - enddef ; - def revert_punk_lower = - ht# := sht#; dev := sdev; - enddef ; - -fi ; diff --git a/metapost/context/fonts/punkfont-slanted.mp b/metapost/context/fonts/punkfont-slanted.mp deleted file mode 100644 index 5c1ff46b2..000000000 --- a/metapost/context/fonts/punkfont-slanted.mp +++ /dev/null @@ -1,4 +0,0 @@ -boolean slanted_punk ; slanted_punk := true ; - -input "punkfont-definitions.mp" ; -input "punkfont-characters.mp" ; diff --git a/metapost/context/fonts/punkfont.mp b/metapost/context/fonts/punkfont.mp deleted file mode 100644 index 2a03aae81..000000000 --- a/metapost/context/fonts/punkfont.mp +++ /dev/null @@ -1,2 +0,0 @@ -input "punkfont-definitions.mp" ; -input "punkfont-characters.mp" ; -- cgit v1.2.3