diff options
Diffstat (limited to 'Master/texmf-dist/source/luatex/luamplib/luamplib.dtx')
-rw-r--r-- | Master/texmf-dist/source/luatex/luamplib/luamplib.dtx | 537 |
1 files changed, 305 insertions, 232 deletions
diff --git a/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx b/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx index e06112e1617..625a35848c0 100644 --- a/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx +++ b/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx @@ -85,7 +85,7 @@ See source file '\inFileName' for licencing and contact information. %<*driver> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{luamplib.drv}% - [2024/07/24 v2.34.2 Interface for using the mplib library]% + [2024/08/03 v2.34.5 Interface for using the mplib library]% \documentclass{ltxdoc} \usepackage{metalogo,multicol,xspace} \usepackage[x11names]{xcolor} @@ -123,10 +123,9 @@ See source file '\inFileName' for licencing and contact information. \newcommand*\email [1] {<\href{mailto:#1}{#1}>} \newcommand \file {\nolinkurl} -\newcommand \pk {\textsf} \newcommand*\metapost {\textsc{metapost}\xspace} -\newcommand*\mplib {\textsf{mplib}\xspace} +\newcommand*\mplib {\pkg{mplib}\xspace} \begin{document} \DocInput{luamplib.dtx}% @@ -152,11 +151,11 @@ See source file '\inFileName' for licencing and contact information. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \textsf{luamplib} package} +% \title{The \pkg{luamplib} package} % \author{Hans Hagen, Taco Hoekwater, Elie Roux, Philipp Gesang and Kim Dohyun\\ % Current Maintainer: Kim Dohyun\\ % Support: \url{https://github.com/lualatex/luamplib}} -% \date{2024/07/24 v2.34.2} +% \date{2024/08/03 v2.34.5} % % \maketitle % @@ -174,9 +173,9 @@ See source file '\inFileName' for licencing and contact information. % % Using this package is easy: in Plain, type your \metapost code between the % macros \cs{mplibcode} and \cs{endmplibcode}, and in \LaTeX\ in the -% \texttt{mplibcode} environment. +% |mplibcode| environment. % -% The resulting \metapost figures are put in a \TeX\ \texttt{hbox} with dimensions +% The resulting \metapost figures are put in a \TeX\ |hbox| with dimensions % adjusted to the \metapost code. % % The code of luamplib is basically from the |luatex-mplib.lua| and |luatex-mplib.tex| files @@ -186,13 +185,13 @@ See source file '\inFileName' for licencing and contact information. % % \begin{itemize} % \item possibility to use |btex ... etex| to typeset \TeX\ code. -% |textext()| is a more versatile macro equivalent to |TEX()| from \textsf{TEX.mp}. +% |textext()| is a more versatile macro equivalent to |TEX()| from \pkg{TEX.mp}. % |TEX()| is also allowed and is a synonym of |textext()|. % The argument of % \mplib's primitive |maketext| will also be processed by the same routine. % % \item possibility to use |verbatimtex ... etex|, though it's behavior cannot -% be the same as the stand-alone \textsf{mpost}. +% be the same as the stand-alone \pkg{mpost}. % Of course you cannot include \cs{documentclass}, \cs{usepackage} etc. % When these \TeX\ commands are found in |verbatimtex ... etex|, the entire code will be % ignored. @@ -231,7 +230,7 @@ See source file '\inFileName' for licencing and contact information. % \end{mplibcode} %\end{verbatim} % -% \paragraph{\cs{mplibsetformat\{plain\char"7C metafun\}}} +% \paragraph{\cs{mplibsetformat\{plain\textbar metafun\}}} % There are (basically) two formats for \metapost: \emph{plain} and % \emph{metafun}. By default, the \emph{plain} format is used, but you can set % the format to be used by future figures at any time using @@ -267,15 +266,15 @@ See source file '\inFileName' for licencing and contact information. % it is regarded by luamplib as % a color expression of \TeX\ side. % For instance, when |withshadecolors("orange", 2/3red)| is given, the first color |"orange"| will be -% interpreted as an \textsf{xcolor}'s or \textsf{l3color}'s expression. +% interpreted as a \pkg{color}, \pkg{xcolor} or \pkg{l3color}'s expression. % -% \paragraph{\cs{mplibnumbersystem\{scaled\char"7C double\char"7C decimal\}}} +% \paragraph{\cs{mplibnumbersystem\{scaled\textbar double\textbar decimal\}}} % Users can choose |numbersystem| option. % The default value is |scaled|, which can be changed % by declaring \cs{mplibnumbersystem\{double\}} or % \cs{mplibnumbersystem\{decimal\}}. % -% \paragraph{\cs{mplibshowlog\{enable\char"7C disable\}}} +% \paragraph{\cs{mplibshowlog\{enable\textbar disable\}}} % Default: |disable|. % When \cs{mplibshowlog\{enable\}}\footnote{As for user's setting, % |enable|, |true| and |yes| are identical; @@ -283,7 +282,7 @@ See source file '\inFileName' for licencing and contact information. % the \metapost process will be printed to the |.log| file. % This is the \TeX{} side interface for |luamplib.showlog|. % -% \paragraph{\cs{mpliblegacybehavior\{enable\char"7C disable\}}} +% \paragraph{\cs{mpliblegacybehavior\{enable\textbar disable\}}} % \hypertarget{mpliblegacybehavior}{}\relax % By default, \cs{mpliblegacybehavior\{enable\}} % is already declared for backward compatibility, @@ -321,7 +320,7 @@ See source file '\inFileName' for licencing and contact information. %\end{verbatim} % % By contrast, -% when \cs{mpliblegacybehavior\{disabled\}} is declared, any +% when \cs{mpliblegacybehavior\{disable\}} is declared, any % |verbatimtex| |...| |etex| will be executed, along with |btex| |...| |etex|, % sequentially one by one. % So, some \TeX\ code in |verbatimtex ... etex| will have effects on @@ -337,7 +336,7 @@ See source file '\inFileName' for licencing and contact information. % \end{mplibcode} %\end{verbatim} % -% \paragraph{\cs{mplibtextextlabel\{enable\char"7C disable\}}} +% \paragraph{\cs{mplibtextextlabel\{enable\textbar disable\}}} % Default: |disable|. % \cs{mplibtextextlabel\{enable\}} enables % the labels typeset via |textext| instead of |infont| operator. @@ -351,7 +350,7 @@ See source file '\inFileName' for licencing and contact information. % Also take care of |char| operator in the left side argument, % as this might bring unpermitted characters into \TeX. % -% \paragraph{\cs{mplibcodeinherit\{enable\char"7C disable\}}} +% \paragraph{\cs{mplibcodeinherit\{enable\textbar disable\}}} % Default: |disable|. % \cs{mplibcodeinherit\{enable\}} enables the inheritance % of variables, constants, and macros defined by previous \metapost code chunks. @@ -393,7 +392,7 @@ See source file '\inFileName' for licencing and contact information. % \everyendmplib[instanceName]{...} %\end{verbatim} % -% \paragraph{\cs{mplibglobaltextext\{enable\char"7C disable\}}} +% \paragraph{\cs{mplibglobaltextext\{enable\textbar disable\}}} % Default: |disable|. % Formerly, to inherit |btex| |...| |etex| boxes as well as other \metapost macros, variables and constants, % it was necessary to declare \cs{mplibglobaltextext\{enable\}} in advance. @@ -414,7 +413,7 @@ See source file '\inFileName' for licencing and contact information. % \endmplibcode %\end{verbatim} % -% \paragraph{\cs{mplibverbatim\{enable\char"7C disable\}}} +% \paragraph{\cs{mplibverbatim\{enable\textbar disable\}}} % Default: |disable|. % Users can issue \cs{mplibverbatim\{enable\}}, after which % the contents of mplibcode environment will be read verbatim. As a result, @@ -426,8 +425,8 @@ See source file '\inFileName' for licencing and contact information. % \paragraph{\cs{mpdim\{...\}}} % \hypertarget{mpdim}{}\relax % Besides other \TeX\ commands, \cs{mpdim} is specially allowed -% in the mplibcode environment. This feature is inpired by \textsf{gmp} package authored by -% Enrico Gregorio. Please refer to the manual of \textsf{gmp} package for details. +% in the mplibcode environment. This feature is inpired by \pkg{gmp} package authored by +% Enrico Gregorio. Please refer to the manual of \pkg{gmp} package for details. %\begin{verbatim} % \begin{mplibcode} % beginfig(1) @@ -439,13 +438,13 @@ See source file '\inFileName' for licencing and contact information. % % \paragraph{\cs{mpcolor[...]\{...\}}} % With \cs{mpcolor} command, color names or expressions of -% \textsf{color}, \textsf{xcolor} and \textsf{l3color} module/packages can be used in the mplibcode -% enviroment (after |withcolor| operator). +% \pkg{color}, \pkg{xcolor} and \pkg{l3color} module/packages can be used in the mplibcode +% environment (after |withcolor| operator). % See the example \hyperlink{mpdim}{above}. -% The optional |[...]| means the option of \textsf{xcolor}'s \cs{color} command. -% For spot colors, \textsf{l3color} (in PDF/DVI mode), -% \textsf{colorspace}, \textsf{spotcolor} -% (in PDF mode) and \textsf{xespotcolor} (in DVI mode) packages are supported +% The optional |[...]| denotes the option of \pkg{xcolor}'s \cs{color} command. +% For spot colors, \pkg{l3color} (in PDF/DVI mode), +% \pkg{colorspace}, \pkg{spotcolor} +% (in PDF mode) and \pkg{xespotcolor} (in DVI mode) packages are supported % as well. % % \paragraph{\cs{mpfig} \ldots\ \cs{endmpfig}} @@ -532,7 +531,7 @@ See source file '\inFileName' for licencing and contact information. % % \paragraph{\texttt{mplibdimen(...)}, \texttt{mplibcolor(...)}} % These are \metapost interfaces for the \TeX\ commands -% \hyperlink{mpdim}{\cs{mpdim} \textcolor{black}{and} \cs{mpcolor}}. For example, +% \cs{mpdim} and \cs{mpcolor} (see \hyperlink{mpdim}{above}). For example, % |mplibdimen("\linewidth")| is basically the same as \cs{mpdim\{\cs{linewidth}\}}, and % |mplibcolor("red!50")| is basically the same as \cs{mpcolor\{red!50\}}. % The difference is that these \metapost operators can also be used in external |.mp| files, @@ -567,7 +566,7 @@ See source file '\inFileName' for licencing and contact information. % |fakebold|, |drawcolor| and |fillcolor| are optional; % default values are |2|, |"black"| and |"white"| respectively. % When the color expressions are given in string type, they are regarded as -% \textsf{xcolor}'s or \textsf{l3color}'s expressions. +% \pkg{color}, \pkg{xcolor} or \pkg{l3color}'s expressions. % All from |mplibgraphictext| to the end of sentence will compose an % anonymous |picture|, which can be drawn or assigned to a variable. % Incidentally, |withdrawcolor| and |withfillcolor| are synonyms of @@ -581,7 +580,7 @@ See source file '\inFileName' for licencing and contact information. % However, because the implementation is quite different from others, % there are some limitations such that you can't % apply shading (gradient colors) to the text. Again, -% in DVI mode, \textsf{unicode-math} package is needed for math formula, +% in DVI mode, \pkg{unicode-math} package is needed for math formula, % as we cannot embolden type1 fonts in DVI mode. % % \paragraph{\texttt{mplibglyph ... of ...}} @@ -612,10 +611,10 @@ See source file '\inFileName' for licencing and contact information. % will remain transparent. % % \leavevmode\llap{\textcolor{red}{☞}\kern1.2\parindent}\relax -% To apply the nonzero winding number rule to a picture containg paths, +% To apply the nonzero winding number rule to a picture containing paths, % luamplib appends |withpostscript| |"collect"| % to the paths except the last one in the picture. -% If you want the even-odd rule instead, you can, even with \emph{plain} format, +% If you want the even-odd rule instead, you can, with \emph{plain} format as well, % additionally declare |withpostscript| |"evenodd"| to the last path in the picture. % % \paragraph{\texttt{mpliboutlinetext (...)}} @@ -631,43 +630,57 @@ See source file '\inFileName' for licencing and contact information. %\end{verbatim} % After the process, |mpliboutlinepic[]| % and |mpliboutlinenum| will be preserved as global variables; -% |mpliboutlinepic[1]| \ldots{} |mpliboutlinepic[mpliboutlinenum]| +% |mpliboutlinepic[1]| |...| |mpliboutlinepic[mpliboutlinenum]| % will be an array of images each of which containing a glyph or a rule. % % \textsc{n.b.} As Unicode grapheme cluster is not considered in the array, a unit that must be % a single cluster might be separated apart. % -% \paragraph{\cs{mppattern\{...\}} \texttt{...} \cs{endmppattern}, \texttt{... withpattern ...}} +% \paragraph{\cs{mppattern\{...\} ...} \cs{endmppattern}, \texttt{... withpattern ...}} % \hypertarget{mppattern}{}\relax % \TeX\ macros % \cs{mppattern\{<name>\}} |...| \cs{endmppattern} define a tiling pattern % associated with the |<name>|. % \metapost operator |withpattern|, the syntax being -% \emph{<path>} |withpattern| \emph{<string>}, will return a \metapost picture which fills -% the given path with a tiling pattern of the |<name>| +% \emph{<path>}\,\textbar\,\emph{<textual picture>} |withpattern| \emph{<string>}, +% will return a \metapost picture which fills +% the given path or text with a tiling pattern of the |<name>| % by replicating it horizontally and vertically. +% The \emph{textual picture} here means any text typeset by \TeX, mostly the result +% of the |btex| command (though technically this is not a true textual picture) +% or the |infont| operator. +% % An example: %\begin{verbatim} -% \mppattern{mypatt} % or \begin{mppattern}{mypatt} -% [ % options: see below -% xstep = 10, ystep = 12, -% matrix = {0,1,-1,0}, % or "0 1 -1 0" -% ] -% \mpfig % or any other TeX code, -% picture q; -% q := btex Q etex; -% fill bbox q withcolor .8[red,white]; -% draw q withcolor .8red; -% \endmpfig -% \endmppattern % or \end{mppattern} +% \mppattern{mypatt} % or \begin{mppattern}{mypatt} +% [ % options: see below +% xstep = 10, +% ystep = 12, +% matrix = {0, 1, -1, 0}, % or "0 1 -1 0" +% ] +% \mpfig % or any other TeX code, +% draw (origin--(1,1)) +% scaled 10 +% withcolor 1/3[blue,white] +% ; +% draw (up--right) +% scaled 10 +% withcolor 1/3[red,white] +% ; +% \endmpfig +% \endmppattern % or \end{mppattern} % -% \mpfig -% fill fullcircle scaled 100 -% withpostscript "collect" ; -% draw unitsquare shifted - center unitsquare scaled 45 -% withpattern "mypatt" -% withpostscript "evenodd" ; -% \endmpfig +% \mpfig +% draw fullcircle scaled 90 +% withpostscript "collect" +% ; +% draw fullcircle scaled 200 +% withpattern "mypatt" +% withpen pencircle scaled 1 +% withcolor \mpcolor{red!50!blue!50} +% withpostscript "evenodd" +% ; +% \endmpfig %\end{verbatim} % % The available options are listed in Table~\ref{tab:mppatternoptions}. @@ -680,8 +693,8 @@ See source file '\inFileName' for licencing and contact information. % |ystep| &\emph{number} & vertical spacing between pattern cells\\ % |xshift| &\emph{number} & horizontal shifting of pattern cells\\ % |yshift| &\emph{number} & vertical shifting of pattern cells\\ -% |matrix| &\emph{table} or \emph{string} & |xx|, |yx|, |xy|, |yy| values\kern1pt* or MP transform code\\ % |bbox| &\emph{table} or \emph{string} & |llx|, |lly|, |urx|, |ury| values\kern1pt*\\ +% |matrix| &\emph{table} or \emph{string} & |xx|, |yx|, |xy|, |yy| values\kern1pt* or MP transform code\\ % |resources|&\emph{string} & PDF resources if needed\\ % |colored| or |coloured| &\emph{boolean}& |false| for uncolored pattern. default: |true|\\\hline % & & \small *\,in string type, numbers are separated by spaces\\ @@ -705,7 +718,7 @@ See source file '\inFileName' for licencing and contact information. % Uncolored pattern will be painted later by the color of a \metapost object. % An example: %\begin{verbatim} -% \begin{mppattern}{pattuncolored} +% \begin{mppattern}{pattnocolor} % [ % colored = false, % matrix = "slanted .3 rotated 30", @@ -725,7 +738,7 @@ See source file '\inFileName' for licencing and contact information. % if j < length mpliboutlinepic[i]: % withpostscript "collect" % else: -% withpattern "pattuncolored" +% withpattern "pattnocolor" % withpen pencircle scaled 1/2 % withcolor (i/4)[red,blue] % paints the pattern % fi; @@ -734,10 +747,26 @@ See source file '\inFileName' for licencing and contact information. % endfig; % \end{mplibcode} %\end{verbatim} +% A much simpler and efficient way to obtain a similar result +% (without colorful characters in this example) +% is to give a \emph{textual picture} as the operand of |withpattern|: +%\begin{verbatim} +% \begin{mplibcode} +% beginfig(2) +% picture pic; +% pic = mplibgraphictext "\bfseries\TeX" +% fakebold 1/2 +% fillcolor 1/3[red,blue] % paints the pattern +% drawcolor 2/3[red,blue] +% scaled 10 ; +% draw pic withpattern "pattnocolor" ; +% endfig; +% \end{mplibcode} +%\end{verbatim} % % \paragraph{\texttt{... withfademethod ...}} % This is a \metapost operator which makes the color of an object gradiently transparent. -% The syntax is \emph{<path>}\texttt{\char"7C}\emph{<picture>} |withfademethod| \emph{<string>}, +% The syntax is \emph{<path>}\texttt{\textbar}\emph{<picture>} |withfademethod| \emph{<string>}, % the latter being either |"linear"| or |"circular"|. % Though it is similar to the |withshademethod| from \emph{metafun}, % the differences are: (1) the operand of |withfademethod| can be a picture as well as a path; @@ -764,6 +793,8 @@ See source file '\inFileName' for licencing and contact information. % sets the bounding box of the fading area, default value being |(llcorner p, urcorner p)|. % Though this option is not needed in most cases, there could be cases when users want to % explicitly control the bounding box. +% Particularly, see the description \hyperlink{withgroupbbox}{below} +% on the analogous macro |withgroupbbox|. % \end{description} % An example: %\begin{verbatim} @@ -784,8 +815,8 @@ See source file '\inFileName' for licencing and contact information. % As said \hyperlink{metafunformat}{before}, % transparency group is available with \emph{plain} as well as \emph{metafun} format. % The syntax is exactly the same: -% \emph{<picture>} \char"7C\ \emph{<path>} |asgroup| -% |""| \char"7C\ |"isolated"| \char"7C\ |"knockout"| \char"7C\ |"isolated,knockout"|, +% \emph{<picture>} \textbar\ \emph{<path>} |asgroup| +% |""| \textbar\ |"isolated"| \textbar\ |"knockout"| \textbar\ |"isolated,knockout"|, % which will return a \metapost picture. % It is called \emph{Transparency Group} because the objects contained in the group are composited % to produce a single object, so that outer transparency effect, if any, @@ -813,6 +844,17 @@ See source file '\inFileName' for licencing and contact information. % a transparency group of the name to the |currentpicture|. % Contrary to the \TeX\ command just mentioned, % the position of the group is the same as the original transparency group. +% +% \item[|withgroupbbox (|\emph{pair}|,|\emph{pair}|)|] +% \hypertarget{withgroupbbox}{}\relax +% sets the bounding box of the transparency group, +% default value being |(llcorner p, urcorner p)|. +% This option might be needed especially when you draw with a thick pen +% a path that touches the boundary; +% you would probably want to append to the sentense +% `|withgroupbbox| |(bot| |lft| |llcorner| |p,| |top| |rt| |urcorner| |p)|', +% supposing that the pen was selected by the |pickup| command. +% % \end{description} % An example showing the difference between the \TeX\ and \metapost commands: %\begin{verbatim} @@ -820,7 +862,8 @@ See source file '\inFileName' for licencing and contact information. % draw image( % fill fullcircle scaled 100 shifted 25right withcolor .5[blue,white]; % fill fullcircle scaled 100 withcolor .5[red,white] ; -% ) asgroup "" withgroupname "mygroup"; +% ) asgroup "" +% withgroupname "mygroup"; % draw (left--right) scaled 10; % draw (up--down) scaled 10; % \endmpfig @@ -854,19 +897,24 @@ See source file '\inFileName' for licencing and contact information. % asgroup="", % ] % \mpfig % or any other TeX code -% draw (left--right) scaled 30 rotated 45 withpen pencircle scaled 10; -% draw (left--right) scaled 30 rotated -45 withpen pencircle scaled 10; +% pickup pencircle scaled 10; +% draw (left--right) scaled 30 rotated 45 ; +% draw (left--right) scaled 30 rotated -45 ; % \endmpfig % \endmplibgroup % or \end{mplibgroup} % % \usemplibgroup{mygrx} % % \mpfig -% usemplibgroup "mygrx" scaled 1.5 withprescript "tr_transparency=0.5"; +% usemplibgroup "mygrx" +% scaled 1.5 +% withprescript "tr_transparency=0.5" ; % \endmpfig %\end{verbatim} +% % Availabe options, much fewer than those for \cs{mppattern}, % are listed in Table~\ref{tab:mplibgroupoptions}. +% Again, the width/height/depth values of the mplibgroup will be written down into the log file. % \begin{table} % \centering % \caption{options for \cs{mplibgroup}}\label{tab:mplibgroupoptions} @@ -886,11 +934,10 @@ See source file '\inFileName' for licencing and contact information. % % When |asgroup| option, including empty string, is not given, % a normal form XObject will be generated rather than a transparency group. -% So, the individual objects, not the XObject as a whole, will be affected +% Thus the individual objects, not the XObject as a whole, will be affected % by outer transparency command. % -% As shown in the example, you can reuse the transparency group or the normal form XObject -% once defined +% As shown in the example, you can reuse the mplibgroup once defined % using the \TeX\ command \cs{usemplibgroup} or % the \metapost command |usemplibgroup|. % The behavior of these commands is the same as that described \hyperlink{usemplibgroup}{above}. @@ -981,8 +1028,8 @@ See source file '\inFileName' for licencing and contact information. luatexbase.provides_module { name = "luamplib", - version = "2.34.2", - date = "2024/07/24", + version = "2.34.5", + date = "2024/08/03", description = "Lua package to typeset Metapost with LuaTeX's MPLib.", } @@ -1039,7 +1086,7 @@ luamplib.showlog = luamplib.showlog or false % \end{macrocode} % % This module is a stripped down version of libraries that are used by -% \ConTeXt. Provide a few ``shortcuts'' expected by the imported code. +% \ConTeXt. Provide a few ``shortcuts'' expected by the code. % \begin{macrocode} local tableconcat = table.concat local tableinsert = table.insert @@ -1228,7 +1275,7 @@ end % \end{macrocode} % % As the finder function for \mplib, use the |kpse| library and -% make it behave like as if \metapost was used. And replace it with +% make it behave like as if \metapost was used. And replace |.mp| files with % cache files if needed. % See also \#74, \#97. % \begin{macrocode} @@ -1349,10 +1396,8 @@ local function luamplibload (name) find_file = luamplib.finder, % \end{macrocode} % Make use of |make_text| and |run_script|, which will co-operate -% with \LuaTeX's |tex.runtoks|. And we -% provide |numbersystem| option since v2.4. Default value ``|scaled|'' -% can be changed by declaring |\mplibnumbersystem{double}| -% or |\mplibnumbersystem{decimal}|. +% with \LuaTeX's |tex.runtoks| or other Lua functions. And we +% provide |numbersystem| option since v2.4. % See \url{https://github.com/lualatex/luamplib/issues/21}. % \begin{macrocode} make_text = luamplib.maketext, @@ -1722,10 +1767,10 @@ end % luamplib's \metapost color operators % \begin{macrocode} local function colorsplit (res) - local t, tt = { }, res:gsub("[%[%]]",""):explode() + local t, tt = { }, res:gsub("[%[%]]","",2):explode() local be = tt[1]:find"^%d" and 1 or 2 for i=be, #tt do - if tt[i]:find"^%a" then break end + if not tonumber(tt[i]) then break end t[#t+1] = tt[i] end return t @@ -1856,13 +1901,13 @@ end % % Remove trailing zeros for smaller PDF % \begin{macrocode} +local decimals = "%.%d+" local function rmzeros(str) return str:gsub("%.?0+$","") end % \end{macrocode} % % luamplib's mplibgraphictext operator % \begin{macrocode} -local running = -1073741824 local emboldenfonts = { } local function getemboldenwidth (curr, fakebold) local width = emboldenfonts.width @@ -1895,13 +1940,14 @@ local function getrulewhatsit (line, wd, ht, dp) fmt = "pdf:content "..fmt pl = node.new("whatsit","special") end - pl.data = fmt:format(line, 0, -dp, wd, ht+dp, "B") :gsub("%.%d+", rmzeros) + pl.data = fmt:format(line, 0, -dp, wd, ht+dp, "B") :gsub(decimals,rmzeros) local ss = node.new"glue" node.setglue(ss, 0, 65536, 65536, 2, 2) pl.next = ss return pl end local function getrulemetric (box, curr, bp) + local running = -1073741824 local wd,ht,dp = curr.width, curr.height, curr.depth wd = wd == running and box.width or wd ht = ht == running and box.height or ht @@ -1953,7 +1999,8 @@ local function embolden (box, curr, fakebold) head, curr = node.remove(head, curr) elseif curr.id == node.id"glyph" and curr.font > 0 then local f = curr.font - local i = emboldenfonts[f] + local key = format("%s:%s",f,fakebold) + local i = emboldenfonts[key] if not i then local ft = font.getfont(f) or font.getcopy(f) if pdfmode then @@ -1969,7 +2016,7 @@ local function embolden (box, curr, fakebold) name = format('%s;embolden=%s;',name,fakebold) _, i = fonts.constructors.readanddefine(name,ft.size) end - emboldenfonts[f] = i + emboldenfonts[key] = i end curr.font = i end @@ -1981,6 +2028,9 @@ end local function graphictextcolor (col, filldraw) if col:find"^[%d%.:]+$" then col = col:explode":" + for i=1,#col do + col[i] = format("%.3f", col[i]) + end if pdfmode then local op = #col == 4 and "k" or #col == 3 and "rg" or "g" col[#col+1] = filldraw == "fill" and op or op:upper() @@ -2604,7 +2654,13 @@ vardef mpliboutlinetext@# (expr t) text rest = ) mplib_do_outline_options_r; ) enddef ; primarydef t withpattern p = - image( fill t withprescript "mplibpattern=" & if numeric p: decimal fi p; ) + image( + if cycle t: + fill + else: + draw + fi + t withprescript "mplibpattern=" & if numeric p: decimal fi p; ) enddef; vardef mplibtransformmatrix (text e) = save t; transform t; @@ -2629,10 +2685,10 @@ primarydef p withfademethod s = fi withprescript "mplibfadetype=" & s withprescript "mplibfadebbox=" & - decimal xpart llcorner p & ":" & - decimal ypart llcorner p & ":" & - decimal xpart urcorner p & ":" & - decimal ypart urcorner p + decimal (xpart llcorner p -1/4) & ":" & + decimal (ypart llcorner p -1/4) & ":" & + decimal (xpart urcorner p +1/4) & ":" & + decimal (ypart urcorner p +1/4) enddef; def withfadeopacity (expr a,b) = withprescript "mplibfadeopacity=" & @@ -2661,13 +2717,25 @@ def withfadebbox (expr a,b) = enddef; primarydef p asgroup s = image( - fill llcorner p--lrcorner p--urcorner p--ulcorner p--cycle + draw center p + withprescript "mplibgroupbbox=" & + decimal (xpart llcorner p -1/4) & ":" & + decimal (ypart llcorner p -1/4) & ":" & + decimal (xpart urcorner p +1/4) & ":" & + decimal (ypart urcorner p +1/4) withprescript "gr_state=start" withprescript "gr_type=" & s; draw p; draw center p withprescript "gr_state=stop"; ) enddef; +def withgroupbbox (expr a,b) = + withprescript "mplibgroupbbox=" & + decimal xpart a & ":" & + decimal ypart a & ":" & + decimal xpart b & ":" & + decimal ypart b +enddef; def withgroupname expr s = withprescript "mplibgroupname=" & s enddef; @@ -2788,21 +2856,12 @@ end % % For parsing |prescript| materials. % \begin{macrocode} -local further_split_keys = { - mplibtexboxid = true, - sh_color_a = true, - sh_color_b = true, -} local function script2table(s) local t = {} for _,i in ipairs(s:explode("\13+")) do local k,v = i:match("(.-)=(.*)") -- v may contain = or empty. if k and v and k ~= "" and not t[k] then - if further_split_keys[k] or further_split_keys[k:sub(1,10)] then - t[k] = v:explode(":") - else - t[k] = v - end + t[k] = v end end return t @@ -2830,7 +2889,7 @@ end % in the argument of pdfliteral. % \begin{macrocode} local function pdf_literalcode (...) - put2output{ -2, format(...) :gsub("%.%d+", rmzeros) } + put2output{ -2, format(...) :gsub(decimals,rmzeros) } end local start_pdf_code = pdfmode and function() pdf_literalcode"q" end @@ -2845,7 +2904,7 @@ local stop_pdf_code = pdfmode % |textext(...)| or |TEX(...)|, all being the same internally. % \begin{macrocode} local function put_tex_boxes (object,prescript) - local box = prescript.mplibtexboxid + local box = prescript.mplibtexboxid:explode":" local n,tw,th = box[1],tonumber(box[2]),tonumber(box[3]) if n and tw and th then local op = object.path @@ -2970,12 +3029,20 @@ if pdfmode then end else texsprint { + "\\luamplibatfirstshipout{", "\\special{pdf:obj @MPlibTr<<>>}", "\\special{pdf:obj @MPlibSh<<>>}", "\\special{pdf:obj @MPlibCS<<>>}", - "\\special{pdf:obj @MPlibPt<<>>}", + "\\special{pdf:obj @MPlibPt<<>>}}", } pdfetcs.resadded = { } + pdfetcs.fallback_update_resources = function (name,res,obj) + texsprint{"\\special{pdf:put ", obj, " <<", res, ">>}"} + if not pdfetcs.resadded[name] then + texsprint{"\\luamplibateveryshipout{\\special{pdf:put @resources <</", name, " ", obj, ">>}}"} + pdfetcs.resadded[name] = obj + end + end end % \end{macrocode} @@ -3001,29 +3068,21 @@ local function add_extgs_resources (on, new) local tr = format("/%s %s", key, val) if is_defined(pdfetcs.pgfextgs) then texsprint { "\\csname ", pdfetcs.pgfextgs, "\\endcsname{", tr, "}" } - elseif pdfmode then - if is_defined"TRP@list" then - texsprint(catat11,{ - [[\if@filesw\immediate\write\@auxout{]], - [[\string\g@addto@macro\string\TRP@list{]], - tr, - [[}}\fi]], - }) - if not get_macro"TRP@list":find(tr) then - texsprint(catat11,[[\global\TRP@reruntrue]]) - end - else - pdfetcs.fallback_update_resources("ExtGState", tr) + elseif is_defined"TRP@list" then + texsprint(catat11,{ + [[\if@filesw\immediate\write\@auxout{]], + [[\string\g@addto@macro\string\TRP@list{]], + tr, + [[}}\fi]], + }) + if not get_macro"TRP@list":find(tr) then + texsprint(catat11,[[\global\TRP@reruntrue]]) end else - texsprint { "\\special{pdf:put @MPlibTr<<", tr, ">>}" } + pdfetcs.fallback_update_resources("ExtGState",tr,"@MPlibTr") end end end - if not pdfmode and not pdfmanagement and not is_defined(pdfetcs.pgfextgs) then - texsprint"\\special{pdf:put @resources <</ExtGState @MPlibTr>>}" - pdfetcs.resadded.ExtGState = "@MPlibTr" - end return key end local function do_preobj_TR(object,prescript) @@ -3033,9 +3092,9 @@ local function do_preobj_TR(object,prescript) local key, on, os, new local mode = prescript.tr_alternative or 1 mode = transparancy_modes[tonumber(mode)] or mode + opaq = format("%.3f", opaq) :gsub(decimals,rmzeros) for i,v in ipairs{ {mode,opaq},{"Normal",1} } do - mode, opaq = v[1], v[2] - os = format("<</BM/%s/ca %s/CA %s/AIS false>>",mode,opaq,opaq) + os = format("<</BM/%s/ca %s/CA %s/AIS false>>",v[1],v[2],v[2]) on, new = update_pdfobjs(os) key = add_extgs_resources(on,new) if i == 1 then @@ -3052,16 +3111,24 @@ end % Shading with \emph{metafun} format. % \begin{macrocode} local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,steps,fractions) + for _,v in ipairs{ca,cb} do + for i,vv in ipairs(v) do + for ii,vvv in ipairs(vv) do + v[i][ii] = tonumber(vvv) and format("%.3f",vvv) or vvv + end + end + end local fun2fmt,os = "<</FunctionType 2/Domain[%s]/C0[%s]/C1[%s]/N 1>>" if steps > 1 then local list,bounds,encode = { },{ },{ } for i=1,steps do if i < steps then - bounds[i] = fractions[i] or 1 + bounds[i] = format("%.3f", fractions[i] or 1) end encode[2*i-1] = 0 encode[2*i] = 1 os = fun2fmt:format(domain,tableconcat(ca[i],' '),tableconcat(cb[i],' ')) + :gsub(decimals,rmzeros) list[i] = format(pdfetcs.resfmt, update_pdfobjs(os)) end os = tableconcat { @@ -3070,18 +3137,19 @@ local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,st format("/Encode[%s]", tableconcat(encode,' ')), format("/Functions[%s]", tableconcat(list, ' ')), format("/Domain[%s]>>", domain), - } + } :gsub(decimals,rmzeros) else os = fun2fmt:format(domain,tableconcat(ca[1],' '),tableconcat(cb[1],' ')) + :gsub(decimals,rmzeros) end local objref = format(pdfetcs.resfmt, update_pdfobjs(os)) os = tableconcat { format("<</ShadingType %i", shtype), format("/ColorSpace %s", colorspace), format("/Function %s", objref), - format("/Coords[%s]", coordinates :gsub("%.%d+", rmzeros)), + format("/Coords[%s]", coordinates), "/Extend[true true]/AntiAlias true>>", - } + } :gsub(decimals,rmzeros) local on, new = update_pdfobjs(os) if new then local key, val = format("MPlibSh%s", on), format(pdfetcs.resfmt, on) @@ -3091,17 +3159,9 @@ local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,st } else local res = format("/%s %s", key, val) - if pdfmode then - pdfetcs.fallback_update_resources("Shading", res) - else - texsprint { "\\special{pdf:put @MPlibSh<<", res, ">>}" } - end + pdfetcs.fallback_update_resources("Shading",res,"@MPlibSh") end end - if not pdfmode and not pdfmanagement then - texsprint"\\special{pdf:put @resources <</Shading @MPlibSh>>}" - pdfetcs.resadded.Shading = "@MPlibSh" - end return on end local function color_normalize(ca,cb) @@ -3133,14 +3193,14 @@ local function do_preobj_SH(object,prescript) return else local domain = prescript.sh_domain or "0 1" - local centera = prescript.sh_center_a or "0 0"; centera = centera:explode() - local centerb = prescript.sh_center_b or "0 0"; centerb = centerb:explode() + local centera = (prescript.sh_center_a or "0 0"):explode() + local centerb = (prescript.sh_center_b or "0 0"):explode() local transform = prescript.sh_transform == "yes" local sx,sy,sr,dx,dy = 1,1,1,0,0 if transform then - local first = prescript.sh_first or "0 0"; first = first:explode() - local setx = prescript.sh_set_x or "0 0"; setx = setx:explode() - local sety = prescript.sh_set_y or "0 0"; sety = sety:explode() + local first = (prescript.sh_first or "0 0"):explode() + local setx = (prescript.sh_set_x or "0 0"):explode() + local sety = (prescript.sh_set_y or "0 0"):explode() local x,y = tonumber(setx[1]) or 0, tonumber(sety[1]) or 0 if x ~= 0 and y ~= 0 then local path = object.path @@ -3162,15 +3222,15 @@ local function do_preobj_SH(object,prescript) end end local ca, cb, colorspace, steps, fractions - ca = { prescript.sh_color_a_1 or prescript.sh_color_a or {0} } - cb = { prescript.sh_color_b_1 or prescript.sh_color_b or {1} } + ca = { (prescript.sh_color_a_1 or prescript.sh_color_a or "0"):explode":" } + cb = { (prescript.sh_color_b_1 or prescript.sh_color_b or "1"):explode":" } steps = tonumber(prescript.sh_step) or 1 if steps > 1 then fractions = { prescript.sh_fraction_1 or 0 } for i=2,steps do fractions[i] = prescript[format("sh_fraction_%i",i)] or (i/steps) - ca[i] = prescript[format("sh_color_a_%i",i)] or {0} - cb[i] = prescript[format("sh_color_b_%i",i)] or {1} + ca[i] = (prescript[format("sh_color_a_%i",i)] or "0"):explode":" + cb[i] = (prescript[format("sh_color_b_%i",i)] or "1"):explode":" end end if prescript.mplib_spotcolor then @@ -3237,7 +3297,6 @@ local function do_preobj_SH(object,prescript) else err"unknown shading type" end - pdf_literalcode("q /Pattern cs") end return shade_no end @@ -3247,7 +3306,6 @@ end % Patterns % \begin{macrocode} pdfetcs.patterns = { } -local patterns = pdfetcs.patterns local function gather_resources (optres) local t, do_pattern = { }, not optres local names = {"ExtGState","ColorSpace","Shading"} @@ -3297,7 +3355,7 @@ local function gather_resources (optres) "}}", }, catat11) t[#t+1] = texgettoks'mplibtmptoks' - elseif do_pattern then + else for _,v in ipairs(names) do local vv = pdfetcs.resadded[v] if vv then @@ -3310,9 +3368,9 @@ local function gather_resources (optres) end function luamplib.registerpattern ( boxid, name, opts ) local box = texgetbox(boxid) - local wd = format("%.3f",box.width/factor) :gsub("%.%d+", rmzeros) - local hd = format("%.3f",(box.height+box.depth)/factor) :gsub("%.%d+", rmzeros) - info("w/h/d of '%s': %s %s 0", name, wd, hd) + local wd = format("%.3f",box.width/factor) + local hd = format("%.3f",(box.height+box.depth)/factor) + info("w/h/d of pattern '%s': %s 0", name, format("%s %s",wd, hd):gsub(decimals,rmzeros)) if opts.xstep == 0 then opts.xstep = nil end if opts.ystep == 0 then opts.ystep = nil end if opts.colored == nil then @@ -3327,9 +3385,9 @@ function luamplib.registerpattern ( boxid, name, opts ) local data = format("mplibtransformmatrix(%s);",opts.matrix) process(data,"@mplibtransformmatrix") local t = luamplib.transformmatrix - opts.matrix = format("%s %s %s %s", t[1], t[2], t[3], t[4]) - opts.xshift = opts.xshift or t[5] - opts.yshift = opts.yshift or t[6] + opts.matrix = format("%f %f %f %f", t[1], t[2], t[3], t[4]) + opts.xshift = opts.xshift or format("%f",t[5]) + opts.yshift = opts.yshift or format("%f",t[6]) end local attr = { "/Type/Pattern", @@ -3342,27 +3400,32 @@ function luamplib.registerpattern ( boxid, name, opts ) } local optres = opts.resources or "" optres = optres .. gather_resources(optres) + local patterns = pdfetcs.patterns if pdfmode then if opts.bbox then attr[#attr+1] = format("/BBox[%s]", opts.bbox) end - local index = tex.saveboxresource(boxid, tableconcat(attr), optres, true, opts.bbox and 4 or 1) + attr = tableconcat(attr) :gsub(decimals,rmzeros) + local index = tex.saveboxresource(boxid, attr, optres, true, opts.bbox and 4 or 1) patterns[name] = { id = index, colored = opts.colored } else - local objname = "@mplibpattern"..name + local cnt = #patterns + 1 + local objname = "@mplibpattern" .. cnt local metric = format("bbox %s", opts.bbox or format("0 0 %s %s",wd,hd)) texsprint { - "\\ifvmode\\nointerlineskip\\fi\\vbox to0pt{\\vss\\hbox to0pt{", + "\\expandafter\\newbox\\csname luamplib.patternbox.", cnt, "\\endcsname", + "\\global\\setbox\\csname luamplib.patternbox.", cnt, "\\endcsname", + "\\hbox{\\unhbox ", boxid, "}\\luamplibatnextshipout{", "\\special{pdf:bcontent}", "\\special{pdf:bxobj ", objname, " ", metric, "}", - "\\raise\\dp ", boxid, "\\box ", boxid, + "\\raise\\dp\\csname luamplib.patternbox.", cnt, "\\endcsname", + "\\box\\csname luamplib.patternbox.", cnt, "\\endcsname", "\\special{pdf:put @resources <<", optres, ">>}", "\\special{pdf:exobj <<", tableconcat(attr), ">>}", - "\\special{pdf:econtent}", - "\\hss}}", + "\\special{pdf:econtent}}", } - patterns[#patterns+1] = objname - patterns[name] = { id = #patterns, colored = opts.colored } + patterns[cnt] = objname + patterns[name] = { id = cnt, colored = opts.colored } end end local function pattern_colorspace (cs) @@ -3377,22 +3440,17 @@ local function pattern_colorspace (cs) local res = format("/%s %s", key, val) if is_defined(pdfetcs.pgfcolorspace) then texsprint { "\\csname ", pdfetcs.pgfcolorspace, "\\endcsname{", res, "}" } - elseif pdfmode then - pdfetcs.fallback_update_resources("ColorSpace", res) else - texsprint { "\\special{pdf:put @MPlibCS<<", res, ">>}" } + pdfetcs.fallback_update_resources("ColorSpace",res,"@MPlibCS") end end end - if not pdfmode and not pdfmanagement and not is_defined(pdfetcs.pgfcolorspace) then - texsprint"\\special{pdf:put @resources <</ColorSpace @MPlibCS>>}" - pdfetcs.resadded.ColorSpace = "@MPlibCS" - end return on end local function do_preobj_PAT(object, prescript) local name = prescript and prescript.mplibpattern if not name then return end + local patterns = pdfetcs.patterns local patt = patterns[name] local index = patt and patt.id or err("cannot get pattern object '%s'", name) local key = format("MPlibPt%s",index) @@ -3432,17 +3490,11 @@ local function do_preobj_PAT(object, prescript) local res = format("/%s %s", key, val) if is_defined(pdfetcs.pgfpattern) then texsprint { "\\csname ", pdfetcs.pgfpattern, "\\endcsname{", res, "}" } - elseif pdfmode then - pdfetcs.fallback_update_resources("Pattern", res) else - texsprint { "\\special{pdf:put @MPlibPt<<", res, ">>}" } + pdfetcs.fallback_update_resources("Pattern",res,"@MPlibPt") end end end - if not pdfmode and not pdfmanagement and not is_defined(pdfetcs.pgfpattern) then - texsprint"\\special{pdf:put @resources <</Pattern @MPlibPt>>}" - pdfetcs.resadded.Pattern = "@MPlibPt" - end patt.done = true end @@ -3486,19 +3538,20 @@ local function do_preobj_FADE (object, prescript) on = sh_pdfpageresources(fd_type, "0 1", "/DeviceGray", {{opaq[1]}}, {{opaq[2]}}, coords, 1) os = format("<</PatternType 2/Shading %s>>", format(pdfetcs.resfmt, on)) on = update_pdfobjs(os) - bbox = format("0 0 %f %f", bbox[3]+dx, bbox[4]+dy) :gsub("%.%d+", rmzeros) + bbox = format("0 0 %f %f", bbox[3]+dx, bbox[4]+dy) local streamtext = format("q /Pattern cs/MPlibFd%s scn %s re f Q", on, bbox) + :gsub(decimals,rmzeros) os = format("<</Pattern<</MPlibFd%s %s>>>>", on, format(pdfetcs.resfmt, on)) on = update_pdfobjs(os) local resources = format(pdfetcs.resfmt, on) on = update_pdfobjs"<</S/Transparency/CS/DeviceGray>>" local attr = tableconcat{ "/Subtype/Form", - format("/BBox[%s]", bbox), - format("/Matrix[1 0 0 1 %s]", format("%f %f", -dx,-dy) :gsub("%.%d+", rmzeros)), - format("/Resources %s", resources), + "/BBox[", bbox, "]", + "/Matrix[1 0 0 1 ", format("%f %f", -dx,-dy), "]", + "/Resources ", resources, "/Group ", format(pdfetcs.resfmt, on), - } + } :gsub(decimals,rmzeros) on = update_pdfobjs(attr, streamtext) os = "<</SMask<</S/Luminosity/G " .. format(pdfetcs.resfmt, on) .. ">>>>" on, new = update_pdfobjs(os) @@ -3525,13 +3578,7 @@ local function do_preobj_GRP (object, prescript) for _,v in ipairs(prescript.gr_type:explode",+") do trgroup[v] = true end - local p = object.path - trgroup.bbox = { - math.min(p[1].x_coord, p[2].x_coord, p[3].x_coord, p[4].x_coord), - math.min(p[1].y_coord, p[2].y_coord, p[3].y_coord, p[4].y_coord), - math.max(p[1].x_coord, p[2].x_coord, p[3].x_coord, p[4].x_coord), - math.max(p[1].y_coord, p[2].y_coord, p[3].y_coord, p[4].y_coord), - } + trgroup.bbox = prescript.mplibgroupbbox:explode":" put2output[[\begingroup\setbox\mplibscratchbox\hbox\bgroup]] elseif grstate == "stop" then local llx,lly,urx,ury = tableunpack(trgroup.bbox) @@ -3543,7 +3590,7 @@ local function do_preobj_GRP (object, prescript) }) local grattr = format("/Group<</S/Transparency/I %s/K %s>>",trgroup.isolated,trgroup.knockout) local res = gather_resources() - local bbox = format("%f %f %f %f", llx,lly,urx,ury) :gsub("%.%d+", rmzeros) + local bbox = format("%f %f %f %f", llx,lly,urx,ury) :gsub(decimals,rmzeros) if pdfmode then put2output(tableconcat{ "\\saveboxresource type 2 attr{/Type/XObject/Subtype/Form/FormType 1", @@ -3564,10 +3611,11 @@ local function do_preobj_GRP (object, prescript) "\\special{pdf:put @resources <<", res, ">>}", "\\special{pdf:exobj <<", grattr, ">>}", "\\special{pdf:uxobj ", objname, "}\\endgroup", - "\\expandafter\\gdef\\csname luamplib.group.", trgroup.name, "\\endcsname{", - "\\mplibstarttoPDF{",llx,"}{",lly,"}{",urx,"}{",ury,"}", - "\\special{pdf:uxobj ", objname, "}\\mplibstoptoPDF}", }) + token.set_macro("luamplib.group."..trgroup.name, tableconcat{ + "\\mplibstarttoPDF{",llx,"}{",lly,"}{",urx,"}{",ury,"}", + "\\special{pdf:uxobj ", objname, "}\\mplibstoptoPDF", + }, "global") end trgroup.shifts[trgroup.name] = { llx, lly } end @@ -3575,6 +3623,7 @@ local function do_preobj_GRP (object, prescript) end function luamplib.registergroup (boxid, name, opts) local box = texgetbox(boxid) + local wd, ht, dp = node.getwhd(box) local res = (opts.resources or "") .. gather_resources() local attr = { "/Type/XObject/Subtype/Form/FormType 1" } if type(opts.matrix) == "table" then opts.matrix = tableconcat(opts.matrix," ") end @@ -3582,15 +3631,15 @@ function luamplib.registergroup (boxid, name, opts) if opts.matrix and opts.matrix:find"%a" then local data = format("mplibtransformmatrix(%s);",opts.matrix) process(data,"@mplibtransformmatrix") - opts.matrix = tableconcat(luamplib.transformmatrix, ' ') + opts.matrix = format("%f %f %f %f %f %f",tableunpack(luamplib.transformmatrix)) end local grtype = 3 if opts.bbox then - attr[#attr+1] = format("/BBox[%s]", opts.bbox :gsub("%.%d+", rmzeros)) + attr[#attr+1] = format("/BBox[%s]", opts.bbox) grtype = 2 end if opts.matrix then - attr[#attr+1] = format("/Matrix[%s]", opts.matrix :gsub("%.%d+", rmzeros)) + attr[#attr+1] = format("/Matrix[%s]", opts.matrix) grtype = opts.bbox and 4 or 1 end if opts.asgroup then @@ -3600,33 +3649,36 @@ function luamplib.registergroup (boxid, name, opts) end local trgroup = pdfetcs.tr_group trgroup.shifts[name] = { get_macro'MPllx', get_macro'MPlly' } + local whd if pdfmode then - local index = tex.saveboxresource(boxid, tableconcat(attr), res, true, grtype) - texsprint{ - "\\expandafter\\gdef\\csname luamplib.group.", name, - "\\endcsname{\\useboxresource ", index, "}", - } + attr = tableconcat(attr) :gsub(decimals,rmzeros) + local index = tex.saveboxresource(boxid, attr, res, true, grtype) + token.set_macro("luamplib.group."..name, "\\useboxresource "..index, "global") + whd = format("%.3f %.3f 0", wd/factor, (ht+dp)/factor) :gsub(decimals,rmzeros) else trgroup.cnt = (trgroup.cnt or 0) + 1 local objname = format("@mplibtrgr%s", trgroup.cnt) - local wd, ht, dp = node.getwhd(box) texsprint { - "\\ifvmode\\nointerlineskip\\fi\\vbox to0pt{\\vss\\hbox to0pt{", + "\\expandafter\\newbox\\csname luamplib.groupbox.", trgroup.cnt, "\\endcsname", + "\\global\\setbox\\csname luamplib.groupbox.", trgroup.cnt, "\\endcsname", + "\\hbox{\\unhbox ", boxid, "}\\luamplibatnextshipout{", "\\special{pdf:bcontent}", "\\special{pdf:bxobj ", objname, " width ", wd, "sp height ", ht, "sp depth ", dp, "sp}", - "\\unhbox ", boxid, + "\\unhbox\\csname luamplib.groupbox.", trgroup.cnt, "\\endcsname", "\\special{pdf:put @resources <<", res, ">>}", "\\special{pdf:exobj <<", tableconcat(attr), ">>}", - "\\special{pdf:econtent}", - "\\hss}}", - "\\expandafter\\gdef\\csname luamplib.group.", name, "\\endcsname{", + "\\special{pdf:econtent}}", + } + token.set_macro("luamplib.group."..name, tableconcat{ "\\begingroup\\setbox\\mplibscratchbox\\hbox{\\special{pdf:uxobj ", objname, "}}", "\\wd\\mplibscratchbox ", wd, "sp", "\\ht\\mplibscratchbox ", ht, "sp", "\\dp\\mplibscratchbox ", dp, "sp", - "\\box\\mplibscratchbox\\endgroup}", - } + "\\box\\mplibscratchbox\\endgroup", + }, "global") + whd = format("%.3f %.3f %.3f", wd/factor, ht/factor, dp/factor) :gsub(decimals,rmzeros) end + info("w/h/d of group '%s': %s", name, whd) end local function stop_special_effects(fade,opaq,over) @@ -3788,7 +3840,7 @@ function luamplib.flush (result,flusher) local object = objects[o] local objecttype = object.type % \end{macrocode} -% The following 8 lines are part of |btex...etex| patch. +% The following 9 lines are part of |btex...etex| patch. % Again, colors are processed at this stage. % \begin{macrocode} local prescript = object.prescript @@ -3797,6 +3849,7 @@ function luamplib.flush (result,flusher) local tr_opaq = do_preobj_TR(object,prescript) -- opacity local fading_ = do_preobj_FADE(object,prescript) -- fading local trgroup = do_preobj_GRP(object,prescript) -- transparency group + local pattern_ = do_preobj_PAT(object,prescript) -- pattern if prescript and prescript.mplibtexboxid then put_tex_boxes(object,prescript) elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then --skip @@ -3875,11 +3928,6 @@ function luamplib.flush (result,flusher) pdf_literalcode("[] 0 d") dashed = false end -% \end{macrocode} -% Added : shading and pattern -% \begin{macrocode} - local shade_no = do_preobj_SH(object,prescript) -- shading - local pattern_ = do_preobj_PAT(object,prescript) -- pattern local path = object.path local transformed, penwidth = false, 1 local open = path and path[1].left_type and path[#path].right_type @@ -3895,6 +3943,14 @@ function luamplib.flush (result,flusher) objecttype = 'fill' end end +% \end{macrocode} +% Added : shading +% \begin{macrocode} + local shade_no = do_preobj_SH(object,prescript) -- shading + if shade_no then + pdf_literalcode"q /Pattern cs" + objecttype = false + end if transformed then start_pdf_code() end @@ -3915,27 +3971,25 @@ function luamplib.flush (result,flusher) else flushnormalpath(path,open) end -% \end{macrocode} -% Shading seems to conflict with these ops -% \begin{macrocode} - if not shade_no then -- conflict with shading - if objecttype == "fill" then - pdf_literalcode(evenodd and "h f*" or "h f") - elseif objecttype == "outline" then - if both then - pdf_literalcode(evenodd and "h B*" or "h B") - else - pdf_literalcode(open and "S" or "h S") - end - elseif objecttype == "both" then + if objecttype == "fill" then + pdf_literalcode(evenodd and "h f*" or "h f") + elseif objecttype == "outline" then + if both then pdf_literalcode(evenodd and "h B*" or "h B") + else + pdf_literalcode(open and "S" or "h S") end + elseif objecttype == "both" then + pdf_literalcode(evenodd and "h B*" or "h B") end end if transformed then stop_pdf_code() end local path = object.htap +% \end{macrocode} +% How can we generate an |htap| object? Please let us know if you have succeeded. +% \begin{macrocode} if path then if transformed then start_pdf_code() @@ -3973,7 +4027,7 @@ function luamplib.flush (result,flusher) % We should beware the |q ... Q| scope. % \begin{macrocode} if shade_no then -- shading - pdf_literalcode("W n /MPlibSh%s sh Q",shade_no) + pdf_literalcode("W%s n /MPlibSh%s sh Q",evenodd and "*" or "",shade_no) end end end @@ -4044,15 +4098,34 @@ end % First we need to load some packages. % % \begin{macrocode} -\bgroup\expandafter\expandafter\expandafter\egroup -\expandafter\ifx\csname selectfont\endcsname\relax - \input ltluatex -\else +\ifcsname ProvidesPackage\endcsname +% \end{macrocode} +% We need \LaTeX\ 2024-06-01 as we use |ltx.pdf.object_id| when pdfmanagement is loaded. +% But as \pkg{fp} package does not accept an option, we do not append the date option. +% \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{luamplib} - [2024/07/24 v2.34.2 mplib package for LuaTeX] - \ifx\newluafunction\@undefined + [2024/08/03 v2.34.5 mplib package for LuaTeX] +\fi +\ifdefined\newluafunction\else \input ltluatex +\fi +% \end{macrocode} +% +% In DVI mode, a new XObject (mppattern, mplibgroup) must be encapsulated in an \cs{hbox}. +% But this should not affect typesetting. So we use Hook mechanism provided by \LaTeX\ kernel. +% In Plain, \pkg{atbegshi.sty} is loaded. +% \begin{macrocode} +\ifnum\outputmode=0 + \ifdefined\AddToHookNext + \def\luamplibatnextshipout{\AddToHookNext{shipout/background}} + \def\luamplibatfirstshipout{\AddToHook{shipout/firstpage}} + \def\luamplibateveryshipout{\AddToHook{shipout/background}} + \else + \input atbegshi.sty + \def\luamplibatnextshipout#1{\AtBeginShipoutNext{\AtBeginShipoutAddToBox{#1}}} + \let\luamplibatfirstshipout\AtBeginShipoutFirst + \def\luamplibateveryshipout#1{\AtBeginShipout{\AtBeginShipoutAddToBox{#1}}} \fi \fi % \end{macrocode} |