%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 %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} \unprotect %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 \def\@@MPG{@MPG@} %D Since we want lables to follow the document settings, we %D also set the font related variables. \ifnum\texengine=\xetexengine \startMPinitializations % scale is not yet ok defaultfont:="rm-lmtt10"; defaultscale:=\the\bodyfontsize/10pt; \stopMPinitializations \else \startMPinitializations % scale is not yet ok defaultfont:="\truefontname{Regular}"; defaultscale:=\the\bodyfontsize/10pt; \stopMPinitializations \fi %D In order to support fancy text features (like outline %D fonts), we set: \startMPextensions graphictextformat:="context"; graphictextdirective "\the\everyMPTEXgraphic"; \stopMPextensions % \startMPextensions % textextdirective "\the\everyMPTEXgraphic"; % \stopMPextensions %D A signal that we're in combines \CONTEXT||\METAFUN mode: \startMPextensions string contextversion; contextversion:="\contextversion"; \stopMPextensions %D Some safeguards: %D %D \starttyping %D \appendtoks \cleanupfeatures \to \everyMPgraphic %D \stoptyping %D %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. \newcounter\totalnofMPgraphics \def\thenofMPgraphics{\the\nofMPgraphics} % from supp-mps \appendtoks \savecurrentvalue\totalnofMPgraphics\thenofMPgraphics \to \everybye %D \macros %D {setupMPvariables} %D %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 %D \starttyping %D \setupMPvariables[meta:button][size=20pt] %D \stoptyping \def\@@meta{meta:} \def\setupMPvariables {\dodoubleempty\dosetupMPvariables} \def\dosetupMPvariables[#1][#2]% {\ifsecondargument \getrawparameters[#1:][#2]% brr, todo: [\@@meta#1:] \else \getrawparameters[\@@meta][#1]% \fi} \let\@@framed\s!unknown \def\MPvariable#1% {\csname \ifcsname\@@framed\@@meta#1\endcsname\@@framed\fi\@@meta#1% \endcsname} \let\MPvar\MPvariable \let\setMPvariables\setupMPvariables \def\MPrawvar#1#2{\csname#1:#2\endcsname} \def\presetMPvariable {\dodoubleargument\dopresetMPvariable} \def\dopresetMPvariable[#1][#2=#3]% {\doifundefined{#1:#2}{\setvalue{#1:#2}{#3}}} \def\useMPvariables {\dodoubleargument\douseMPvariables} \def\douseMPvariables[#1][#2]% {\def\@@meta{#1:}% \prepareMPvariables{#2}} %D \macros %D {startuniqueMPgraphic, uniqueMPgraphic} %D %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 %D \starttyping %D \defineoverlay[example][\uniqueMPgraphic{test}] %D %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 %D \starttyping %D \long\def\startuniqueMPgraphic#1#2\stopuniqueMPgraphic% %D {\setvalue{\@@MPG#1}% %D {\startreusableMPgraphic{\overlaystamp:#1}#2\stopreusableMPgraphic %D \reuseMPgraphic{\overlaystamp:#1}}} %D %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 {\overlaywidth:\overlayheight:\overlaydepth :\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} %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 \METAPOST. %D %D \starttyping %D \startuniqueMPgraphic{meta:hash}{gap,angle,...} %D \stoptyping %D %D The calling macro also accepts a second argument. For %D convenient use in overlay definitions, we use \type {{}} %D instead of \type {[]}. %D %D \starttyping %D \uniqueMPgraphic{meta:hash}{gap=10pt,angle=30} %D \stoptyping \long\def\handleuniqueMPgraphic#1#2#3% {\blabelgroup \def\@@meta{#1:}% \extendMPoverlaystamp{#2}% incl prepare \ifundefined{\@@MPG\overlaystamp:#1}% \enableincludeMPgraphics \startMPgraphic#3\stopMPgraphic \doifobjectssupportedelse\donothing\useMPboxfalse \ifuseMPbox \@EA\douseMPbox \else \@EA\nouseMPbox \fi {\@@MPG\overlaystamp:#1}% \fi \getvalue{\@@MPG\overlaystamp:#1}% \elabelgroup} \long\def\startuniqueMPgraphic {\blabelgroup \dodoublegroupempty\dostartuniqueMPgraphic} \long\def\dostartuniqueMPgraphic {\obeyMPlines \dodostartuniqueMPgraphic} \long\def\dodostartuniqueMPgraphic#1#2#3\stopuniqueMPgraphic% {\long\setgvalue{\@@MPG#1}{\handleuniqueMPgraphic{#1}{#2}{#3}}% \elabelgroup} \unexpanded\def\uniqueMPgraphic {\dodoublegroupempty\douniqueMPgraphic} \def\douniqueMPgraphic#1#2% {\blabelgroup \setupMPvariables[#1][#2]% \getvalue{\@@MPG#1}{}% \elabelgroup} \let\stopuniqueMPcode \relax % so that we can use it in \expanded \def\includeMPgraphic#1% {\executeifdefined{\@@MPG#1};} % ; if not found \long\def\handleuseMPgraphic#1#2#3% {\blabelgroup \def\@@meta{#1:}% \prepareMPvariables{#2}% \enableincludeMPgraphics \startMPgraphic#3\stopMPgraphic \ifMPrun \else % see mfun-004 : processing buffer \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% \placeMPgraphic \fi \deallocateMPslot\currentMPgraphic \elabelgroup} \long\def\startuseMPgraphic {\blabelgroup \dodoublegroupempty\dostartuseMPgraphic} \long\def\dostartuseMPgraphic {\obeyMPlines \dodostartuseMPgraphic} \long\def\dodostartuseMPgraphic#1#2#3\stopuseMPgraphic {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}% \elabelgroup} \long\def\startusableMPgraphic % redundant but handy {\blabelgroup \dodoublegroupempty\dostartusableMPgraphic} \long\def\dostartusableMPgraphic % redundant but handy {\obeyMPlines \dodostartusableMPgraphic} \long\def\dodostartusableMPgraphic#1#2#3\stopusableMPgraphic {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}% \elabelgroup} \long\def\handlereusableMPgraphic#1#2#3% {\blabelgroup \def\@@meta{#1:}% \prepareMPvariables{#2}% \enableincludeMPgraphics \startMPgraphic#3\stopMPgraphic \doifobjectssupportedelse\donothing\useMPboxfalse \ifuseMPbox \@EA\douseMPbox \else \@EA\nouseMPbox \fi {\@@MPG#1}% \getvalue{\@@MPG#1}% \elabelgroup} \long\def\startreusableMPgraphic {\blabelgroup \dodoublegroupempty\dostartreusableMPgraphic} \def\dostartreusableMPgraphic {\obeyMPlines \dodostartreusableMPgraphic} \long\def\dodostartreusableMPgraphic#1#2#3\stopreusableMPgraphic {\long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}{#3}}% \elabelgroup} \unexpanded\def\useMPgraphic {\dodoublegroupempty\douseMPgraphic} \def\douseMPgraphic#1#2% {\blabelgroup \setupMPvariables[#1][#2]% \getvalue{\@@MPG#1}{}% \elabelgroup} \let\reuseMPgraphic\useMPgraphic \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 \def\enableincludeMPgraphics {\let\handleuseMPgraphic \thirdofthreearguments \let\handlereusableMPgraphic\thirdofthreearguments} % todo: each code/page/buffer a var class %D \macros %D {startuniqueMPpagegraphic,uniqueMPpagegraphic} %D %D Experimental. \def\MPpageprefix{\doifoddpageelse oe:} \def\overlaypagestamp {\MPpageprefix\overlaywidth:\overlayheight:\overlaydepth :\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} \long\def\startuniqueMPpagegraphic {\blabelgroup \dodoublegroupempty\dostartuniqueMPpagegraphic} \long\def\dostartuniqueMPpagegraphic {\obeyMPlines \dodostartuniqueMPpagegraphic} \long\def\dodostartuniqueMPpagegraphic#1#2#3\stopuniqueMPpagegraphic {\long\setgvalue{\@@MPG o:#1}{\handleuniqueMPgraphic{o:#1}{#2}{#3}}% \long\setgvalue{\@@MPG e:#1}{\handleuniqueMPgraphic{e:#1}{#2}{#3}}% \elabelgroup} \unexpanded\def\uniqueMPpagegraphic {\dodoublegroupempty\douniqueMPpagegraphic} % \def\douniqueMPpagegraphic#1#2% % {\blabelgroup % \let\overlaystamp\overlaypagestamp % \setupMPvariables[#1][#2]% % \getvalue{\@@MPG\MPpageprefix#1}{}% % \elabelgroup} \def\douniqueMPpagegraphic#1#2% {\blabelgroup \let\overlaystamp\overlaypagestamp \setupMPvariables[\MPpageprefix#1][#2]% prefix is new here \getvalue{\@@MPG\MPpageprefix#1}{}% \elabelgroup} %D One way of defining a stamp is: %D %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. \def\prepareMPvariable#1% {\ifundefined{\@@framed\@@meta#1}% \doprepareMPvariable{\@@meta#1}% \else \doprepareMPvariable{\@@framed\@@meta#1}% \fi} % \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 \def\doprepareMPvariable#1% {\edef\theMPvariable{\getvalue{#1}}% \doifelsenothing\theMPvariable {\setevalue{#1}{\MPcolor{black}}} {\defconvertedcommand\ascii\theMPvariable % otherwise problems \doifcolorelse \ascii % with 2\bodyfontsize {\setevalue{#1}{\MPcolor\theMPvariable}} {% can be aux macro \setbox\scratchbox\hbox{\scratchdimen\theMPvariable sp}% \ifdim\wd\scratchbox=\zeropoint % \scratchcounter\theMPvariable % \setevalue{#1}{\the\scratchcounter}% % also accepts 0.number : \setevalue{#1}{\number\theMPvariable}% \else \scratchdimen\theMPvariable \setevalue{#1}{\the\scratchdimen}% \fi}}} %D We redefine \type {\extendMPoverlaystamp} to preprocess %D variables using \type {\prepareMPvariable}. \def\doextendMPoverlaystamp#1% {\prepareMPvariable{#1}% \edef\overlaystamp{\overlaystamp:\MPvariable{#1}}} \def\extendMPoverlaystamp#1% {\processcommalist[#1]\doextendMPoverlaystamp} \def\prepareMPvariables#1% {\processcommalist[#1]\prepareMPvariable} %D \macros %D {MPdatafile} %D %D We redefine a macro from \type {supp-mps.tex}: \def\MPdatafile {\bufferprefix mpd-\the\currentMPgraphic.mpd} %D \macros %D {MPrunfile} %D %D This one is more abstract and does not assume knowledge %D of buffer prefixes. \def\MPrunfile#1% {\bufferprefix mprun.#1} %D \macros %D {getMPdata} %D %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. \def\MPdataMPDfile{\jobname-mpgraph.mpd} \def\MPdataMPOfile{\jobname-mpgraph.mpo} \def\MPdataMPYfile{\jobname-mpgraph.mpy} \startMPextensions boolean collapse_data; collapse_data:=true; def data_mpd_file="\MPdataMPDfile"; enddef ; def data_mpo_file="\MPdataMPOfile"; enddef ; def data_mpy_file="\MPdataMPYfile"; enddef ; \stopMPextensions \def\getMPdata {\long\def\MPdata##1##2{\ifnum##1=\currentMPgraphic\relax##2\fi}% \startreadingfile % \startnointerference % no, else we need to do all data global \readlocfile\MPdataMPDfile\donothing\donothing % \stopnointerference \stopreadingfile} %D We have to enable this mechanism with: \startMPextensions \stopMPextensions %D For the moment, the next one is a private macro: \def\processMPbuffer {\dosingleempty\doprocessMPbuffer} \def\doprocessMPbuffer[#1]% {\doifelsenothing{#1} {\doprocessMPbuffer[\jobname]} {\bgroup \setnormalcatcodes \obeyMPlines %\let\par\empty % oeps, this makes dvi mode graphics hang when not found \!!toksa\emptytoks \def\copyMPbufferline{\expandafter\appendtoks\fileline\to\!!toksa}% \def\dodoprocessMPbuffer##1% {\doprocessfile\scratchread{\TEXbufferfile{##1}}\copyMPbufferline}% \processcommalist[#1]\dodoprocessMPbuffer \@EA\startMPcode\the\!!toksa\stopMPcode % more efficient \egroup}} \def\runMPbuffer {\dosingleempty\dorunMPbuffer} \def\dorunMPbuffer[#1]% processing only {{\MPruntrue\doprocessMPbuffer[#1]}} %D \macros %D {startMPenvironment, resetMPenvironment} %D %D In order to synchronize the main \TEX\ run and the runs %D local to \METAPOST, environments can be passed. \ifx\everyMPTEXgraphic\undefined \newtoks\everyMPTEXgraphic \fi %D A more general way of passing environments is: \def\startMPenvironment % second arg gobbles spaces, so that reset gives \emptytoks {\bgroup \catcode`\^^M=\@@space \dodoubleempty\dostartMPenvironment} \long\def\dostartMPenvironment[#1][#2]#3\stopMPenvironment {\egroup \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 \defconvertedargument\ascii{#3}% \expandafter\appendtoks\ascii\to\everyMPTEXgraphic} \def\resetMPenvironment {\everyMPTEXgraphic\emptytoks % = is really needed ! \startMPenvironment \global\loadfontfileoncetrue \stopMPenvironment} \resetMPenvironment \def\useMPenvironmentbuffer[#1]% {\expanded{\startMPenvironment\noexpand\readfile{\TEXbufferfile{\jobname}}{}{}}\stopMPenvironment} % \useMPenvironmentbuffer[mp] % what was this? %D This command takes \type {[reset]} as optional %D argument. %D %D \starttyping %D \startMPenvironment %D \setupbodyfont[pos,14.4pt] %D \stopMPenvironment %D %D \startMPcode %D draw btex \sl Hans Hagen etex scaled 5 ; %D \stopMPcode %D \stoptyping %D %D The \type {\resetMPenvironment} is a quick way to erase %D the token list. %D %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 %D \starttyping %D \usetypescript[palatino][texnansi] %D %D \startMPenvironment %D \usetypescript[palatino][texnansi] %D \enableregime[utf] %D \setupbodyfont[palatino] %D \stopMPenvironment %D %D \startMPpage %D draw btex aap‒noot coördinatie – één etex ; %D \stopMPpage %D \stoptyping %D We don't want spurious files, do we? %\def\initializeMPgraphics % {%\ifx\bufferprefix\empty \else % \immediate\openout\MPwrite\MPgraphicfile.mp % \immediate\write\MPwrite{end.}% % \immediate\closeout\MPwrite % }%\fi} % strange : % \def\initializeMPgraphicfile % {\bgroup % \doinitializeMPgraphicfile % \MPruntrue % \doinitializeMPgraphicfile % \egroup} % \def\doinitializeMPgraphicfile % {\immediate\openout\scratchwrite\MPgraphicfile.mp % \immediate\write\scratchwrite{end.}% % \immediate\closeout\scratchwrite} \def\initializeMPgraphicfile {\immediate\openout\scratchwrite\MPgraphicfile.mp \immediate\write\scratchwrite{end.}% \immediate\closeout\scratchwrite} \def\initializeMPgraphics {\bgroup \initializeMPgraphicfile % \ifx\bufferprefix\empty\else % \let\bufferprefix\empty % \initializeMPgraphicfile % \fi \egroup} %D Loading specific \METAPOST\ related definitions is %D accomplished by: \def\douseMPlibrary#1% {\ifundefined{\c!file\f!metapostprefix#1}% \letvalueempty{\c!file\f!metapostprefix#1}% \makeshortfilename[\truefilename{\f!metapostprefix#1}]% \startreadingfile \readsysfile{\shortfilename.\mksuffix} {\showmessage\m!metapost1{#1}} {\readsysfile{\shortfilename.tex} {\showmessage\m!metapost1{#1}} \donothing}% \stopreadingfile \fi} \def\useMPlibrary[#1]% {\processcommalist[#1]\douseMPlibrary} %D \macros %D {setMPtext, MPtext, MPstring, MPbetex} %D %D To be documented: %D %D \starttyping %D \setMPtext{identifier}{text} %D %D \MPtext {identifier} %D \MPstring{identifier} %D \MPbetex {identifier} %D \stoptyping \def\@@MPT{@MPT@} \def\forceMPTEXgraphic {\long\def\checkMPTEXgraphic##1{\global\MPTEXgraphictrue}} \def\setMPtext#1#2% todo : #1 must be made : safe {%\forceMPTEXgraphic \defconvertedargument\ascii{#2}% \dodoglobal\letvalue{\@@MPT#1}\ascii} % \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 \startMPinitializations cmykcolors:=\ifMPcmykcolors true\else false\fi; spotcolors:=\ifMPspotcolors true\else false\fi; \stopMPinitializations %D In order to communicate conveniently with the \TEX\ %D engine, we introduce some typesetting variables. % todo : backgroundoffsets \startMPextensions color OverlayColor,OverlayLineColor; \stopMPextensions \startMPinitializations OverlayWidth:=\overlaywidth; OverlayHeight:=\overlayheight; OverlayDepth:=\overlayheight; OverlayColor:=\MPcolor{\overlaycolor}; OverlayLineWidth:=\overlaylinewidth; OverlayLineColor:=\MPcolor{\overlaylinecolor}; % BaseLineSkip:=\the\baselineskip; LineHeight:=\the\baselineskip; BodyFontSize:=\the\bodyfontsize; % TopSkip:=\the\topskip; StrutHeight:=\strutheight; StrutDepth:=\strutdepth; % CurrentWidth:=\the\hsize; CurrentHeight:=\the\vsize; % EmWidth:=\the\emwidth; ExHeight:=\the\exheight; % PageNumber:=\the\pageno; RealPageNumber:=\the\realpageno; LastPageNumber:= \lastpage; \stopMPinitializations \appendtoks \disablediscretionaries \disablecompoundcharacters \to\everyMPgraphic % 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. \appendtoks \chardef\activecharactermode\zerocount \to\everyMPgraphic \appendtoks \expanded{\definecolor[currentcolor][\currentcolorname]}% \to \everyMPgraphic \appendtoks \baselineskip1\baselineskip \lineheight 1\lineheight \topskip 1\topskip \to \everyMPgraphic %D Alas, the prologue settings differ per driver. \ifx\undefined\MPprologues \def\MPprologues{0} \fi \startMPinitializations prologues:=\MPprologues; mpprocset:=1; \stopMPinitializations \appendtoks \def\MPprologues{0}% \def\MPOSTdriver{dvips}% \to \everyresetspecials %D \macros %D {PDFMPformoffset} %D %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. \def\PDFMPformoffset{\objectoffset} %D \macros %D {insertMPfile} %D %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. \newtoks\everyinsertMPfile %D First we present the reasonable fast alternative that we %D happily used for some time. %D %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 %D However, on a 1 Gig Pentium, the next alternative saves %D us 20 seconds run time for the 300 page \METAFUN\ manual: \let\insertMPfileARG\insertMPfile \def\insertMPfile#1#2% in context #2 is empty {\doifelsenothing{#2}{\doinsertMPfile{#1}}{\insertMPfileARG{#1}{#2}}} \def\includeMPasEPS#1% untested !! {\bgroup \message{[MP as EPS #1]}% \the\everyinsertMPfile \dogetEPSboundingbox{#1}\!!widtha\!!heighta\!!widthb\!!heightb \setbox\scratchbox\vbox to \!!heightb {\vfill \let \@@DriverImageType \c!mps \def \@@DriverImageFile {#1}% \edef\@@DriverImageWidth {\the\!!widthb }% \edef\@@DriverImageHeight{\the\!!heightb}% \doinsertfile}% \wd\scratchbox\!!widthb \dp\scratchbox\zeropoint \box\scratchbox \egroup} \ifx\makeMPintoPDFobject\undefined \newcount\makeMPintoPDFobject \fi \def\includeMPasPDF#1% {\bgroup \the\everyinsertMPfile \ifinobject \else \makeMPintoPDFobject\plustwo \fi % when needed \convertMPtoPDF{#1}{1}{1}% no \plusone ! \egroup} %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. \appendtoks \let\figuretypes\c!mps \runutilityfilefalse \consultutilityfilefalse \to \everyinsertMPfile %D One more: (still needed?) \startMPextensions def initialize_form_numbers = do_initialize_numbers; enddef; \stopMPextensions \startMPinitializations HSize:=\the\hsize ; VSize:=\the\vsize ; \stopMPinitializations \startMPextensions vardef ForegroundBox = unitsquare xysized(HSize,VSize) enddef ; vardef PageFraction = if \lastpage>1: (\realfolio-1)/(\lastpage-1) else: 1 fi enddef ; \stopMPextensions %D And some more. These are not really needed since we %D don't use the normal figure inclusion macros any longer. \appendtoks \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: \def\doifelseMPgraphic#1{\doifdefinedelse{\@@MPG#1}} %D \macros %D {startMPcolor} %D %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] \def\startMPcolor {\dodoubleempty\dostartMPcolor} \long\def\dostartMPcolor[#1][#2]#3\stopMPcolor % slow but sometimes handy {\startnointerference \def\handleMPgraycolor{\expanded{\defineglobalcolor[#1][s=\!MPgMPa1,#2]}}% \def\handleMPrgbcolor {\expanded{\defineglobalcolor[#1][r=\!MPgMPa1,g=\!MPgMPa2,b=\!MPgMPa3,#2]}}% \def\handleMPcmykcolor{\expanded{\defineglobalcolor[#1][c=\!MPgMPa1,m=\!MPgMPa2,y=\!MPgMPa3,k=\!MPgMPa4,#2]}}% \startMPcode#3\stopMPcode \stopnointerference} %D New: \definelayerpreset % no dx,dy - else nasty non-mp placement [mp] [\c!y=-\MPury bp, \c!x=\MPllx bp, \c!method=\v!fit] \definelayer [mp] [\c!preset=mp] %D Usage: %D %D \starttyping %D \defineproperty[one][layer][state=start] %D \defineproperty[two][layer][state=stop] %D %D \startuseMPgraphic{step-1} %D fill fullcircle scaled 10cm withcolor red ; %D \stopuseMPgraphic %D %D \startuseMPgraphic{step-2} %D fill fullcircle scaled 5cm withcolor green ; %D \stopuseMPgraphic %D %D \setlayer[mp]{\property[one]{\useMPgraphic{step-1}}} %D \setlayer[mp]{\property[two]{\useMPgraphic{step-2}}} %D %D \ruledhbox{\flushlayer[mp]} %D \stoptyping %D %D Reusing graphics is also possible (now): %D %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 %D \startuseMPgraphic{demo} %D drawpoint "1cm,1.5cm" ; %D \stopuseMPgraphic %D %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 %D Static figures are processed only when there has been %D something changed. Here is Aditya Mahajan's testcase: %D %D \startbuffer %D \startstaticMPfigure{circle} %D fill fullcircle scaled 1cm withcolor blue; %D \stopstaticMPfigure %D %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 %D \typebuffer \getbuffer \def\usestaticMPfigure[#1]% {\dodoubleempty\externalfigure[\jobname-#1.pdf]} \def\startstaticMPfigure {\begingroup \obeyMPlines \dostartstaticMPfigure} \def\dostartstaticMPfigure#1#2\stopstaticMPfigure {\startstaticMPgraphic{\jobname-#1}#2\stopstaticMPgraphic \endgroup} % 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 \prependtoks _special_div_ := 1000\ifconditional\manyMPspecials0\fi ; \to \MPextensions %D Needed (will become default): \prependtoks \resetlanguagespecifics \to \everyMPgraphic %D Goody for preventing overflows: \def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} %D Done. \protect \endinput %D Experimental: \appendtoks \ifrunMPgraphics \ifcase\systemcommandmode \or \runMPgraphicsfalse \fi \fi \to \everyjob % also: % % linecap := rounded ; % linejoin := rounded ; % drawoptions () ;