meta-ini.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=meta-ini,
%D        version=1999.07.10,
%D          title=\METAPOST\ Graphics,
%D       subtitle=Initialization,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

% currently the running color influences the mp graphic in
% pdftex, but this will change [i.e. become optional]; one
% problem is that pdf has no grouping with regards to the
% color

\writestatus{loading}{MetaPost Graphics / Initializations}


%D This module extends the functionality of the support module
%D \type {supp-mps}, the module that is responsible for
%D \METAPOST\ inclusion in \CONTEXT. Some basic macros will be
%D extended. Since some support is depends on \METAPOST\
%D macros. so let's first preload a few auxiliary \METAPOST\
%D files.

\maxnofMPgraphics = 4000 % metafun disables the 4K boundary

\appendtoks \flushMPgraphics \to \everygoodbye  % \everylastshipout


%D Since we want lables to follow the document settings, we
%D also set the font related variables.

    \startMPinitializations % scale is not yet ok
    \startMPinitializations % scale is not yet ok

%D In order to support fancy text features (like outline
%D fonts), we set:

    graphictextdirective "\the\everyMPTEXgraphic";

% \startMPextensions
%     textextdirective "\the\everyMPTEXgraphic";
% \stopMPextensions

%D A signal that we're in combines \CONTEXT||\METAFUN mode:

    string contextversion;

%D Some safeguards:
%D \starttyping
%D \appendtoks \cleanupfeatures \to \everyMPgraphic
%D \stoptyping
%D No, we don't want that (else we loose UTF etc).

%D Another one:

\prependtoks \MPstaticgraphictrue \to \everyoverlay
\prependtoks \MPstaticgraphictrue \to \everypagebody

%D We save the number of graphics for the sake of \TEXEXEC.


\def\thenofMPgraphics{\the\nofMPgraphics} % from supp-mps

\to \everybye

%D \macros
%D   {setupMPvariables}
%D When we build collections of \METAPOST\ graphics, like
%D background and buttons, the need for passing settings
%D arises. By (mis|)|using the local prefix that belongs to
%D \type {\framed}, we get a rather natural interface to
%D backgrounds. To prevent conflicts, we will use the \type
%D {-} in \METAPOST\ specific variables, like:
%D \starttyping
%D \setupMPvariables[meta:button][size=20pt]
%D \stoptyping



     \getrawparameters[#1:][#2]% brr, todo: [\@@meta#1:]










%D \macros
%D   {startuniqueMPgraphic, uniqueMPgraphic}
%D This macros is probably of most use to myself, since I like
%D to use graphics that adapt themselves. The next \METAPOST\
%D kind of graphic is both unique and reused when possible.
%D \starttyping
%D \defineoverlay[example][\uniqueMPgraphic{test}]
%D \startuniqueMPgraphic {test}
%D   draw unitsquare xscaled \overlaywidth yscaled \overlayheight ;
%D \stopuniqueMPgraphic
%D \stoptyping

%D For educational purposes, we show the original version
%D first. This one used a rather simple method for determining
%D the uniqueness.
%D \starttyping
%D \long\def\startuniqueMPgraphic#1#2\stopuniqueMPgraphic%
%D   {\setvalue{\@@MPG#1}%
%D      {\startreusableMPgraphic{\overlaystamp:#1}#2\stopreusableMPgraphic
%D       \reuseMPgraphic{\overlaystamp:#1}}}
%D \def\uniqueMPgraphic#1%
%D   {\getvalue{\@@MPG#1}}
%D \stoptyping

%\def\overlaystamp % watch the \MPcolor, since colors can be redefined
%  {\overlaywidth:\overlayheight:\overlaydepth
%   :\MPcolor{\overlaycolor}:\MPcolor{\overlaylinecolor}}

\def\overlaystamp % watch the \MPcolor, since colors can be redefined

%D A better approach is to let additional variables play a role
%D in determining the uniqueness. In the next macro, the
%D second, optional, argument is used to guarantee the
%D uniqueness, as well as prepare variables for passing them to
%D \starttyping
%D \startuniqueMPgraphic{meta:hash}{gap,angle,...}
%D \stoptyping
%D The calling macro also accepts a second argument. For
%D convenient use in overlay definitions, we use \type {{}}
%D instead of \type {[]}.
%D \starttyping
%D \uniqueMPgraphic{meta:hash}{gap=10pt,angle=30}
%D \stoptyping

   \extendMPoverlaystamp{#2}% incl prepare
     \fi {\@@MPG\overlaystamp:#1}%






\let\stopuniqueMPcode \relax % so that we can use it in \expanded

  {\executeifdefined{\@@MPG#1};} % ; if not found
   \ifMPrun \else % see mfun-004 : processing buffer




\long\def\startusableMPgraphic % redundant but handy

\long\def\dostartusableMPgraphic % redundant but handy


   \fi {\@@MPG#1}%







\let\stopuseMPcode      \relax % so that we can use it in \expanded
\let\stopusableMPcode   \relax % so that we can use it in \expanded
\let\stopreusableMPcode \relax % so that we can use it in \expanded
\let\stopuniqueMPcode   \relax % so that we can use it in \expanded

  {\let\handleuseMPgraphic     \thirdofthreearguments

% todo: each code/page/buffer a var class
%D \macros
%D   {startuniqueMPpagegraphic,uniqueMPpagegraphic}
%D Experimental.

\def\MPpageprefix{\doifoddpageelse oe:}




  {\long\setgvalue{\@@MPG o:#1}{\handleuniqueMPgraphic{o:#1}{#2}{#3}}%
   \long\setgvalue{\@@MPG e:#1}{\handleuniqueMPgraphic{e:#1}{#2}{#3}}%


% \def\douniqueMPpagegraphic#1#2%
%   {\blabelgroup
%    \let\overlaystamp\overlaypagestamp
%    \setupMPvariables[#1][#2]%
%    \getvalue{\@@MPG\MPpageprefix#1}{}%
%    \elabelgroup}

   \setupMPvariables[\MPpageprefix#1][#2]% prefix is new here
%D One way of defining a stamp is:
%D \starttyping
%D \def\extendMPoverlaystamp#1%
%D   {\def\docommand##1%
%D      {\edef\overlaystamp{\overlaystamp:\MPvariable{##1}}}%
%D    \processcommalist[#1]\docommand}
%D \stoptyping

%D Since we need to feed \METAPOST\ with expanded dimensions,
%D we introduce a dedicated expansion engine.


% \startlines
% \def\xxx{\lineheight}     \doprepareMPvariable{xxx} \xxx
% \def\xxx{2pt}             \doprepareMPvariable{xxx} \xxx
% \def\xxx{2}               \doprepareMPvariable{xxx} \xxx
% \def\xxx{\scratchcounter} \doprepareMPvariable{xxx} \xxx
% \def\xxx{red}             \doprepareMPvariable{xxx} \xxx
% \def\xxx{0.4}             \doprepareMPvariable{xxx} \xxx
% \stoplines

     {\defconvertedcommand\ascii\theMPvariable % otherwise problems
      \doifcolorelse \ascii                    % with 2\bodyfontsize
        {% can be aux macro
         \setbox\scratchbox\hbox{\scratchdimen\theMPvariable sp}%
         % \scratchcounter\theMPvariable
         % \setevalue{#1}{\the\scratchcounter}%
         % also accepts 0.number :

%D We redefine \type {\extendMPoverlaystamp} to preprocess
%D variables using \type {\prepareMPvariable}.




%D \macros
%D   {MPdatafile}
%D We redefine a macro from \type {supp-mps.tex}:

  {\bufferprefix mpd-\the\currentMPgraphic.mpd}

%D \macros
%D   {MPrunfile}
%D This one is more abstract and does not assume knowledge
%D of buffer prefixes.

  {\bufferprefix mprun.#1}

%D \macros
%D   {getMPdata}
%D When we collect graphics in one file, we run into
%D troubles, since \METAPOST\ has a built in limit (of 4)
%D on the number of files it can handle. It's therefore
%D better to collect all data in one file and filter it.


    boolean collapse_data; collapse_data:=true;
    def data_mpd_file="\MPdataMPDfile"; enddef ;
    def data_mpo_file="\MPdataMPOfile"; enddef ;
    def data_mpy_file="\MPdataMPYfile"; enddef ;

   % \startnointerference % no, else we need to do all data global
   % \stopnointerference

%D We have to enable this mechanism with:


%D For the moment, the next one is a private macro:


     %\let\par\empty % oeps, this makes dvi mode graphics hang when not found
      \@EA\startMPcode\the\!!toksa\stopMPcode % more efficient


\def\dorunMPbuffer[#1]% processing only

%D \macros
%D   {startMPenvironment, resetMPenvironment}
%D In order to synchronize the main \TEX\ run and the runs
%D local to \METAPOST, environments can be passed.


%D A more general way of passing environments is:

\def\startMPenvironment % second arg gobbles spaces, so that reset gives \emptytoks

   \doif{#1}\s!reset\resetMPenvironment % reset mp toks
   \doif{#1}\v!global{#3}%              % use in main doc too
   \doif{#1}+{#3}%                      % use in main doc too

  {\everyMPTEXgraphic\emptytoks % = is really needed !



% \useMPenvironmentbuffer[mp] % what was this?

%D This command takes \type {[reset]} as optional
%D argument.
%D \starttyping
%D \startMPenvironment
%D   \setupbodyfont[pos,14.4pt]
%D \stopMPenvironment
%D \startMPcode
%D   draw btex \sl Hans Hagen etex scaled 5 ;
%D \stopMPcode
%D \stoptyping
%D The \type {\resetMPenvironment} is a quick way to erase
%D the token list.
%D You should be aware of independencies. For instance, if you use a font
%D in a graphic that is not used in the main document, you need to load the
%D typescript at the outer level (either directly or by using the global
%D option).
%D \starttyping
%D \usetypescript[palatino][texnansi]
%D \startMPenvironment
%D     \usetypescript[palatino][texnansi]
%D     \enableregime[utf]
%D     \setupbodyfont[palatino]
%D \stopMPenvironment
%D \startMPpage
%D     draw btex aap‒noot coördinatie – één etex ;
%D \stopMPpage
%D \stoptyping

%D We don't want spurious files, do we?

%  {%\ifx\bufferprefix\empty \else
%     \immediate\openout\MPwrite\
%     \immediate\write\MPwrite{end.}%
%     \immediate\closeout\MPwrite
%   }%\fi}

% strange :

% \def\initializeMPgraphicfile
%   {\bgroup
%    \doinitializeMPgraphicfile
%    \MPruntrue
%    \doinitializeMPgraphicfile
%    \egroup}

% \def\doinitializeMPgraphicfile
%   {\immediate\openout\scratchwrite\
%    \immediate\write\scratchwrite{end.}%
%    \immediate\closeout\scratchwrite}


%    \ifx\bufferprefix\empty\else
%      \let\bufferprefix\empty
%      \initializeMPgraphicfile
%    \fi

%D Loading specific \METAPOST\ related definitions is
%D accomplished by:



%D \macros
%D   {setMPtext, MPtext, MPstring, MPbetex}
%D To be documented:
%D \starttyping
%D \setMPtext{identifier}{text}
%D \MPtext  {identifier}
%D \MPstring{identifier}
%D \MPbetex {identifier}
%D \stoptyping



\def\setMPtext#1#2% todo : #1 must be made : safe

% \def\MPtext       #1{\getvalue{\@@MPT#1}}
% \def\MPstring    #1{"\getvalue{\@@MPT#1}"}
% \def\MPbetex #1{btex \getvalue{\@@MPT#1} etex}

\def\MPtext       #1{\executeifdefined{\@@MPT#1}\empty}
\def\MPstring    #1{"\executeifdefined{\@@MPT#1}\empty"}
\def\MPbetex #1{btex \executeifdefined{\@@MPT#1}\empty\space etex}

%D Unfortunately \METAPOST\ does not have \CMYK\ support
%D built in, but by means of specials we can supply the
%D information needed to handle them naturaly.

\newif\ifMPcmykcolors \MPcmykcolorstrue
\newif\ifMPspotcolors \MPspotcolorstrue

  cmykcolors:=\ifMPcmykcolors true\else false\fi;
  spotcolors:=\ifMPspotcolors true\else false\fi;

%D In order to communicate conveniently with the \TEX\
%D engine, we introduce some typesetting variables.

% todo : backgroundoffsets

  color OverlayColor,OverlayLineColor;

  LastPageNumber:= \lastpage;


% New, experimental (if complaints than only in enco-ffr.mkii), well
% Mojca complained that it does not work with utf-8 and textext, see
% ** in meta-tex.


\to \everyMPgraphic

  \lineheight  1\lineheight
  \topskip     1\topskip
\to \everyMPgraphic

%D Alas, the prologue settings differ per driver.

\ifx\undefined\MPprologues \def\MPprologues{0} \fi


\to \everyresetspecials

%D \macros
%D   {PDFMPformoffset}
%D In \PDF, forms are clipped and therefore we have to take
%D precautions to get this right. Since this is related to
%D objects, we use the same offset as used there.


%D \macros
%D   {insertMPfile}
%D Bypassing the special driver and figure mechanism is not
%D that nice but saves upto 5\% time in embedding \METAPOST\
%D graphics by using the low level \PDF\ converter directly,
%D given of course that we use \PDFTEX. As a result we need to
%D fool around with the object trigger.


%D First we present the reasonable fast alternative that we
%D happily used for some time.
%D \starttyping
%D \def\insertMPfile#1#2%
%D   {\ifx\undefined\externalfigure
%D      \message{[insert file #1 here]}%
%D    \else
%D      \bgroup
%D      \the\everyinsertMPfile
%D      \externalfigure
%D        [#1]
%D        [\c!type=\c!mps,\c!object=\v!no,%
%D         \c!symbol=\v!yes,\c!reset=\v!yes,%
%D         \c!maxwidth=,\c!maxheight=,%
%D         \c!frame=\v!off,\c!background=,%
%D         #2]%
%D      \egroup
%D    \fi}
%D \stoptyping
%D However, on a 1 Gig Pentium, the next alternative saves
%D us 20 seconds run time for the 300 page \METAFUN\ manual:


\def\insertMPfile#1#2% in context #2 is empty

\def\includeMPasEPS#1% untested !!
   \message{[MP as EPS #1]}%
   \setbox\scratchbox\vbox to \!!heightb
      \let \@@DriverImageType  \c!mps
      \def \@@DriverImageFile  {#1}%
      \edef\@@DriverImageWidth {\the\!!widthb }%

\ifx\makeMPintoPDFobject\undefined \newcount\makeMPintoPDFobject \fi

   \ifinobject \else \makeMPintoPDFobject\plustwo \fi % when needed
   \convertMPtoPDF{#1}{1}{1}% no \plusone !

%D So, using a low level approach (thereby avoiding the slower
%D figure analysis macros) pays off. This kind of
%D optimizations are a bit tricky since we must make sure that
%D special resources end up in the (PDF) files. Because the
%D \METAPOST\ to \PDF\ can handle objects itself, it is not
%D that complicated.

%D We hook a couple of initializations into the graphic
%D macros.

\to \everyinsertMPfile

%D One more: (still needed?)

  def initialize_form_numbers =

  HSize:=\the\hsize ;
  VSize:=\the\vsize ;

  vardef ForegroundBox =
    unitsquare xysized(HSize,VSize)
  enddef ;
  vardef PageFraction =
    if \lastpage>1: (\realfolio-1)/(\lastpage-1) else: 1 fi
  enddef ;

%D And some more. These are not really needed since we
%D don't use the normal figure inclusion macros any longer.

  \externalfigurepostprocessors\emptytoks % safeguard
\to \everyinsertMPfile

%D We also take care of disabling fancy figure features, that
%D can terribly interfere when dealing with symbols,
%D background graphics and running (postponed) graphics.
%D You won't believe me if I tell you what funny side effects
%D can occur. One took me over a day to uncover when
%D processing the screen version of the \METAFUN\ manual.

%D For my eyes only:


%D \macros
%D   {startMPcolor}
%D The following time consuming method uses \METAPOST\ to
%D calculate a color. This enables a match between colors
%D resulting from a complex calculation (e.g. for a title
%D page) and those in the text.

% \startuseMPgraphic{somecolors}
%   color c[] ; c[1] := .7[red,green] ; c[2] := .7[blue,yellow] ;
% \stopuseMPgraphic

% \startMPcolor[shade-1][t=.2,a=1]
%   \includeMPgraphic{somecolors} ; fill fullcircle withcolor c[1] ;
% \stopMPcolor

% \startMPcolor[shade-2][t=.2,a=1]
%   \includeMPgraphic{somecolors} ; fill fullcircle withcolor c[2] ;
% \stopMPcolor

% \blackrule[width=\hsize,height=4cm,color=shade-1]
% \blackrule[width=\hsize,height=4cm,color=shade-2]


\long\def\dostartMPcolor[#1][#2]#3\stopMPcolor % slow but sometimes handy
     \def\handleMPrgbcolor {\expanded{\defineglobalcolor[#1][r=\!MPgMPa1,g=\!MPgMPa2,b=\!MPgMPa3,#2]}}%

%D New:

\definelayerpreset % no dx,dy - else nasty non-mp placement
  [\c!y=-\MPury bp,
   \c!x=\MPllx bp,


%D Usage:
%D \starttyping
%D \defineproperty[one][layer][state=start]
%D \defineproperty[two][layer][state=stop]
%D \startuseMPgraphic{step-1}
%D   fill fullcircle scaled 10cm withcolor red ;
%D \stopuseMPgraphic
%D \startuseMPgraphic{step-2}
%D   fill fullcircle scaled 5cm withcolor green ;
%D \stopuseMPgraphic
%D \setlayer[mp]{\property[one]{\useMPgraphic{step-1}}}
%D \setlayer[mp]{\property[two]{\useMPgraphic{step-2}}}
%D \ruledhbox{\flushlayer[mp]}
%D \stoptyping
%D Reusing graphics is also possible (now):
%D \starttyping
%D \startreusableMPgraphic{axis}
%D   tickstep := 1cm ; ticklength := 2mm ;
%D   drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
%D   tickstep := tickstep/2 ; ticklength := ticklength/2 ;
%D   drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
%D \stopreusableMPgraphic
%D \startuseMPgraphic{demo}
%D   drawpoint "1cm,1.5cm" ;
%D \stopuseMPgraphic
%D \definelayer[mp][preset=mp]
%D \setlayer[mp]{\reuseMPgraphic{axis}}
%D \setlayer[mp]{\useMPgraphic{demo}}
%D \ruledhbox{\flushlayer[mp]}
%D \stoptyping

%D \macros
%D   {startstaticMPfigure,useMPstaticfigure}
%D Static figures are processed only when there has been
%D something changed. Here is Aditya Mahajan's testcase:
%D \startbuffer
%D \startstaticMPfigure{circle}
%D   fill fullcircle scaled 1cm withcolor blue;
%D \stopstaticMPfigure
%D \startstaticMPfigure{axis}
%D   drawarrow (0,0)--(2cm,0) ;
%D   drawarrow (0,0)--(0,2cm) ;
%D   label.llft(textext("(0,0)") ,origin) ;
%D \stopstaticMPfigure
%D \stopbuffer
%D \typebuffer \getbuffer




% faster, but more tricky
% \def\startstaticMPfigure
%   {\doifmodeelse{*\v!first}
%      {\begingroup
%       \obeyMPlines
%       \dostartstaticMPfigure}
%      {\gobbleuntil\stopstaticMPfigure}}
% \def\dostartstaticMPfigure#1#2\stopstaticMPfigure
%   {\startMPstaticgraphic{\jobname-#1}#2\stopMPstaticgraphic
%    % dirty trick, don't register, so no second main run of texexec:
%    \global\advance\nofMPgraphics \minusone
%    \endgroup}}

%D New:

% \appendtoks \closeMPgraphicfiles \to \everystoptext

%D New:

\newconditional\manyMPspecials % when set to true, > 1000 specials can be used

\settrue \manyMPspecials % per 1/4/2006

  _special_div_ := 1000\ifconditional\manyMPspecials0\fi ;
\to \MPextensions

%D Needed (will become default):

\to \everyMPgraphic

%D Goody for preventing overflows:


%D Done.

\protect \endinput

%D Experimental:

  \ifrunMPgraphics \ifcase\systemcommandmode \or
  \fi \fi
\to \everyjob

% also:
% linecap  := rounded ;
% linejoin := rounded ;
% drawoptions () ;