diff options
author | Norbert Preining <norbert@preining.info> | 2024-07-18 03:01:14 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2024-07-18 03:01:14 +0000 |
commit | 3ce3d19f5ec8a431281019a114993df9289cb032 (patch) | |
tree | f13f90e8aedf5f170a14565745bbda1fe18f8576 /macros/luatex/generic/luamplib | |
parent | 7f670cc0d3cf52e69f647a46bb7330b774ac0a7d (diff) |
CTAN sync 202407180301
Diffstat (limited to 'macros/luatex/generic/luamplib')
-rw-r--r-- | macros/luatex/generic/luamplib/NEWS | 7 | ||||
-rw-r--r-- | macros/luatex/generic/luamplib/luamplib.dtx | 391 | ||||
-rw-r--r-- | macros/luatex/generic/luamplib/luamplib.pdf | bin | 234171 -> 239222 bytes | |||
-rw-r--r-- | macros/luatex/generic/luamplib/test-luamplib-latex.tex | 29 | ||||
-rw-r--r-- | macros/luatex/generic/luamplib/test-luamplib-plain.tex | 14 |
5 files changed, 310 insertions, 131 deletions
diff --git a/macros/luatex/generic/luamplib/NEWS b/macros/luatex/generic/luamplib/NEWS index 57324895f8..c97974fc20 100644 --- a/macros/luatex/generic/luamplib/NEWS +++ b/macros/luatex/generic/luamplib/NEWS @@ -1,8 +1,13 @@ History of the luamplib package +2024/07/17 2.34.0 + * support transparency group with metafun format + * fix regarding default value in circular fading mode + * fix regarging the scope of graphics state + 2024/07/14 2.33.1 * refactor the manual, including some minor items undocumented so far - * improve fade routine to get possibly smaller pdf file + * improve fading routine to get possibly smaller pdf file 2024/07/08 2.33.0 * provide a new metapost operator 'withfademethod' and related macros, diff --git a/macros/luatex/generic/luamplib/luamplib.dtx b/macros/luatex/generic/luamplib/luamplib.dtx index a7e44a487e..44500e957c 100644 --- a/macros/luatex/generic/luamplib/luamplib.dtx +++ b/macros/luatex/generic/luamplib/luamplib.dtx @@ -85,7 +85,7 @@ See source file '\inFileName' for licencing and contact information. %<*driver> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{luamplib.drv}% - [2024/07/14 v2.33.1 Interface for using the mplib library]% + [2024/07/17 v2.34.0 Interface for using the mplib library]% \documentclass{ltxdoc} \usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace} \usepackage[x11names]{xcolor} @@ -153,7 +153,7 @@ See source file '\inFileName' for licencing and contact information. % \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/14 v2.33.1} +% \date{2024/07/17 v2.34.0} % % \maketitle % @@ -219,14 +219,14 @@ See source file '\inFileName' for licencing and contact information. % the lua table containing metapost code % which will % be automatically inserted at the beginning and ending of each metapost code chunk. -% \begin{verbatim} +%\begin{verbatim} % \everymplib{ beginfig(0); } % \everyendmplib{ endfig; } % \begin{mplibcode} % % beginfig/endfig not needed % draw fullcircle scaled 1cm; % \end{mplibcode} -% \end{verbatim} +%\end{verbatim} % % \paragraph{\cs{mplibsetformat\{plain\char"7C metafun\}}} % There are (basically) two formats for metapost: \emph{plain} and @@ -236,15 +236,24 @@ See source file '\inFileName' for licencing and contact information. % % \textsc{n.b.} As \emph{metafun} is such a complicated format, % we cannot support all the functionalities producing special effects provided by \emph{metafun}. -% At least, however, transparency (actually opacity) and shading (gradient colors) effects +% At least, however, transparency (actually opacity), transparency group, and shading (gradient colors) % are fully supported, % and outlinetext is supported by our own alternative |mpliboutlinetext| (see below \S\,1.2). % % \leavevmode\llap{\textcolor{red}{☞}\kern1.2\parindent}\relax % Among these, transparency is so simple that you can apply it to an object, % even with the \emph{plain} format, -% just by appending |withprescript "tr_transparency=|\emph{<number>}|"|, where -% $0 \le \hbox{\emph{<number>}} \le 1$, to the sentence. +% just by appending |withprescript "tr_transparency=|\emph{<number>}|"| to the sentence. +% ($0 \le \hbox{\emph{<number>}} \le 1$) +% +% As for transparency group, the current \emph{metafun} document \S\,8.8 is not correct. +% The true syntax is: +%\begin{verbatim} +% draw <picture>|<path> asgroup <string> +%\end{verbatim} +% where \emph{<string>} should be |""| (empty), |"isolated"|, |"knockout"|, or |"isolated,knockout"|. +% Beware that currently many of the PDF rendering applications, except Adobe Acrobat Reader, +% cannot properly render the isolated or knockout effect. % % One thing worth mentioning about shading is: % when a color expression is given in string type, @@ -277,14 +286,14 @@ See source file '\inFileName' for licencing and contact information. % each figure box can be freely moved horizontally or vertically. % Also, a box number can be assigned to a figure box, allowing it to be % reused later. -% \begin{verbatim} +%\begin{verbatim} % \mplibcode % verbatimtex \moveright 3cm etex; beginfig(0); ... endfig; % verbatimtex \leavevmode etex; beginfig(1); ... endfig; % verbatimtex \leavevmode\lower 1ex etex; beginfig(2); ... endfig; % verbatimtex \endgraf\moveright 1cm etex; beginfig(3); ... endfig; % \endmplibcode -% \end{verbatim} +%\end{verbatim} % \textsc{n.b.} \cs{endgraf} should be used instead of \cs{par} inside % |verbatimtex ... etex|. % @@ -292,7 +301,7 @@ See source file '\inFileName' for licencing and contact information. % between |beginfig()| and |endfig| will be inserted % after flushing out the metapost figure. % As shown in the example below, |VerbatimTeX()| is a synonym of |verbatimtex| |...| |etex|. -% \begin{verbatim} +%\begin{verbatim} % \mplibcode % D := sqrt(2)**7; % beginfig(0); @@ -301,7 +310,7 @@ See source file '\inFileName' for licencing and contact information. % endfig; % \endmplibcode % diameter: \Dia bp. -% \end{verbatim} +%\end{verbatim} % % By contrast, % when |\mpliblegacybehavior{disabled}| is declared, any @@ -309,7 +318,7 @@ See source file '\inFileName' for licencing and contact information. % sequentially one by one. % So, some \TeX\ code in |verbatimtex ... etex| will have effects on % following |btex| |...| |etex| codes. -% \begin{verbatim} +%\begin{verbatim} % \begin{mplibcode} % beginfig(0); % draw btex ABC etex; @@ -318,7 +327,7 @@ See source file '\inFileName' for licencing and contact information. % draw btex GHI etex shifted (2cm,0); % bold face % endfig; % \end{mplibcode} -% \end{verbatim} +%\end{verbatim} % % \paragraph{\cs{mplibtextextlabel\{enable\char"7C disable\}}} % Default: |disable|. @@ -347,11 +356,11 @@ See source file '\inFileName' for licencing and contact information. % in \LaTeX{} |mplibcode| environment. % Plain \TeX\ users also can use this functionality. % The syntax for \LaTeX\ is: -% \begin{verbatim} +%\begin{verbatim} % \begin{mplibcode}[instanceName] % % some mp code % \end{mplibcode} -% \end{verbatim} +%\end{verbatim} % The behavior is as follows. % \begin{itemize} % \item All the variables and functions are shared @@ -371,10 +380,10 @@ See source file '\inFileName' for licencing and contact information. % Unnamed \cs{everymplib} affects not only those instances with no name, % but also those with name but with no corresponding \cs{everymplib}. % The syntax is: -% \begin{verbatim} +%\begin{verbatim} % \everymplib[instanceName]{...} % \everyendmplib[instanceName]{...} -% \end{verbatim} +%\end{verbatim} % % \paragraph{\cs{mplibglobaltextext\{enable\char"7C disable\}}} % Default: |disable|. @@ -382,8 +391,8 @@ See source file '\inFileName' for licencing and contact information. % it was necessary to declare \cs{mplibglobaltextext\{enable\}} in advance. % But from v2.27, this is implicitly enabled when \cs{mplibcodeinherit} % is enabled. -% This optinal command still remains mostly for backward compatibility. -% \begin{verbatim} +% This optional command still remains mostly for backward compatibility. +%\begin{verbatim} % \mplibcodeinherit{enable} % %\mplibglobaltextext{enable} % \everymplib{ beginfig(0);} \everyendmplib{ endfig;} @@ -395,7 +404,7 @@ See source file '\inFileName' for licencing and contact information. % \mplibcode % currentpicture := pic scaled 2; % \endmplibcode -% \end{verbatim} +%\end{verbatim} % % \paragraph{\cs{mplibverbatim\{enable\char"7C disable\}}} % Default: |disable|. @@ -409,14 +418,14 @@ See source file '\inFileName' for licencing and contact information. % 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. -% \begin{verbatim} +%\begin{verbatim} % \begin{mplibcode} % beginfig(1) % draw origin--(.6\mpdim{\linewidth},0) withpen pencircle scaled 4 % dashed evenly scaled 4 withcolor \mpcolor{orange}; % endfig; % \end{mplibcode} -% \end{verbatim} +%\end{verbatim} % % \paragraph{\cs{mpcolor[...]\{...\}}} % With \cs{mpcolor} command, color names or expressions of @@ -435,7 +444,7 @@ See source file '\inFileName' for licencing and contact information. % we also provide unexpandable \TeX\ macros |\mpfig ... \endmpfig| and its starred version % |\mpfig* ... \endmpfig| to save typing toil. % The former is roughly the same as follows: -% \begin{verbatim} +%\begin{verbatim} % \begin{mplibcode}[@mpfig] % beginfig(0) % token list declared by \everymplib[@mpfig] @@ -443,24 +452,24 @@ See source file '\inFileName' for licencing and contact information. % token list declared by \everyendmplib[@mpfig] % endfig; % \end{mplibcode} -% \end{verbatim} +%\end{verbatim} % and the starred version is roughly the same as follows: -% \begin{verbatim} +%\begin{verbatim} % \begin{mplibcode}[@mpfig] % ... % \end{mplibcode} -% \end{verbatim} +%\end{verbatim} % In these macros |\mpliblegacybehavior{disable}| % is forcibly declared. % Again, as both share the same instance name, metapost codes are inherited among them. % A simple example: -% \begin{verbatim} +%\begin{verbatim} % \everymplib[@mpfig]{ drawoptions(withcolor .5[red,white]); } % \mpfig* input boxes \endmpfig % \mpfig % circleit.a(btex Box 1 etex); drawboxed(a); % \endmpfig -% \end{verbatim} +%\end{verbatim} % The instance name (default: |@mpfig|) can be changed by redefining % \cs{mpfiginstancename}, after which a new mplib instance will start and % code inheritance too will begin anew. |\let\mpfiginstancename\empty| will @@ -523,10 +532,10 @@ See source file '\inFileName' for licencing and contact information. % to a MetaPost color expression, that can be used anywhere color expression is expected % as well as after the |withcolor| operator. % For instance: -% \begin{verbatim} +%\begin{verbatim} % color col; % col := mplibtexcolor "olive!50"; -% \end{verbatim} +%\end{verbatim} % But the result may vary in its color model (gray/rgb/cmyk) % according to the given \TeX\ color. (Spot colors are forced to % cmyk model, so this operator is not recommended for spot colors.) @@ -538,11 +547,11 @@ See source file '\inFileName' for licencing and contact information. % |mplibgraphictext| is a metapost operator, the effect of which is similar to that of % \ConTeXt's |graphictext| or our own |mpliboutlinetext| (see below). % However the syntax is somewhat different. -% \begin{verbatim} +%\begin{verbatim} % mplibgraphictext "Funny" % fakebold 2.3 % fontspec option % drawcolor .7blue fillcolor "red!50" % color expressions -% \end{verbatim} +%\end{verbatim} % |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 @@ -567,13 +576,13 @@ See source file '\inFileName' for licencing and contact information. % From v2.30, we provide a new metapost operator |mplibglyph|, which returns a metapost picture % containing outline paths of a glyph in opentype, truetype or type1 fonts. % When a type1 font is specified, metapost primitive |glyph| will be called. -% \begin{verbatim} +%\begin{verbatim} % mplibglyph 50 of \fontid\font % slot 50 of current font % mplibglyph "Q" of "TU/TeXGyrePagella(0)/m/n/10" % font csname % mplibglyph "Q" of "texgyrepagella-regular.otf" % raw filename % mplibglyph "Q" of "Times.ttc(2)" % subfont number % mplibglyph "Q" of "SourceHanSansK-VF.otf[Regular]" % instance name -% \end{verbatim} +%\end{verbatim} % Both arguments before and after of ``|of|'' can be either a number or a string. % Number arguments are regarded as a glyph slot (GID) and a font id number, repectively. % String argument at the left side is regarded as a glyph name in the font or a unicode character. @@ -601,12 +610,12 @@ See source file '\inFileName' for licencing and contact information. % From v2.31, a new metapost operator |mpliboutlinetext| is available, which mimicks % metafun's |outlinetext|. So the syntax is the same as metafun's. See the metafun % manual \S\,8.7 (|texdoc metafun|). A simple example: -% \begin{verbatim} +%\begin{verbatim} % draw mpliboutlinetext.b ("$\sqrt{2+\alpha}$") % (withcolor \mpcolor{red!50}) % (withpen pencircle scaled .2 withcolor red) % scaled 2 ; -% \end{verbatim} +%\end{verbatim} % After the process, |mpliboutlinepic[]| % and |mpliboutlinenum| will be preserved as global variables; % |mpliboutlinepic[1]| \ldots{} |mpliboutlinepic[mpliboutlinenum]| @@ -624,7 +633,7 @@ See source file '\inFileName' for licencing and contact information. % the given path with a tiling pattern of the |<name>| % by replicating it horizontally and vertically. % An example: -% \begin{verbatim} +%\begin{verbatim} % \mppattern{mypatt} % or \begin{mppattern}{mypatt} % [ % options: see below % xstep = 10, ystep = 12, @@ -645,7 +654,7 @@ See source file '\inFileName' for licencing and contact information. % withpattern "mypatt" % withpostscript "evenodd" ; % \endmpfig -% \end{verbatim} +%\end{verbatim} % % The available options are listed in Table~\ref{tab:mppatternoptions}. % \begin{table} @@ -681,7 +690,7 @@ See source file '\inFileName' for licencing and contact information. % Option |colored=false| (|coloured| is a synonym of |colored|) will generate an uncolored pattern which shall have no color at all. % Uncolored pattern will be painted later by the color of a metapost object. % An example: -% \begin{verbatim} +%\begin{verbatim} % \begin{mppattern}{pattuncolored} % [ % colored = false, @@ -710,7 +719,7 @@ See source file '\inFileName' for licencing and contact information. % endfor % endfig; % \end{mplibcode} -% \end{verbatim} +%\end{verbatim} % % \paragraph{\texttt{... withfademethod ...}, and related macros} % |withfademethod| is a metapost operator which makes the color of an object gradiently transparent. @@ -743,7 +752,7 @@ See source file '\inFileName' for licencing and contact information. % explicitly control the bounding box. % \end{description} % An example: -% \begin{verbatim} +%\begin{verbatim} % \mpfig % picture mill; % mill = btex \includegraphics[width=100bp]{mill} etex; @@ -754,7 +763,7 @@ See source file '\inFileName' for licencing and contact information. % withfadeopacity (1, 0) % ; % \endmpfig -% \end{verbatim} +%\end{verbatim} % % \subsection{Lua} % @@ -778,7 +787,7 @@ See source file '\inFileName' for licencing and contact information. % as documented in Lua\TeX{} manual \S\,11.2.8.4 (|texdoc luatex|). % The following will print |false|, |3.0|, |MetaPost| and % the knots and the cyclicity of the path |unitsquare|, consecutively. -% \begin{verbatim} +%\begin{verbatim} % \begin{mplibcode}[instance1] % boolean b; b = 1 > 2; % numeric n; n = 3; @@ -796,13 +805,13 @@ See source file '\inFileName' for licencing and contact information. % print(k, type(v)=='table' and table.concat(v,' ') or v) % end % } -% \end{verbatim} +%\end{verbatim} % % \paragraph{Lua function \texttt{luamplib.process\_mplibcode}} % Users can execute a MetaPost code chunk from Lua side by using this function: -% \begin{verbatim} +%\begin{verbatim} % luamplib.process_mplibcode (<string> metapost code, <string> instance name) -% \end{verbatim} +%\end{verbatim} % The second argument cannot be absent, but can be an empty string (|""|) which % means that it has no instance name. % @@ -841,8 +850,8 @@ See source file '\inFileName' for licencing and contact information. luatexbase.provides_module { name = "luamplib", - version = "2.33.1", - date = "2024/07/14", + version = "2.34.0", + date = "2024/07/17", description = "Lua package to typeset Metapost with LuaTeX's MPLib.", } @@ -1655,7 +1664,7 @@ luamplib.shadecolor = function (str) if res:find" cs " or res:find"@pdf.obj" then -- spot color shade: l3 only % \end{macrocode} % An example of spot color shading: -% \begin{verbatim} +%\begin{verbatim} % \documentclass{article} % \usepackage{luamplib} % \mplibsetformat{metafun} @@ -1701,9 +1710,9 @@ luamplib.shadecolor = function (str) % endfig; % \end{mplibcode} % \end{document} -% \end{verbatim} +%\end{verbatim} % another one: user-defined DeviceN colorspace -% \begin{verbatim} +%\begin{verbatim} % \DocumentMetadata{ } % \documentclass{article} % \usepackage{luamplib} @@ -1731,7 +1740,7 @@ luamplib.shadecolor = function (str) % ; % \endmpfig % \end{document} -% \end{verbatim} +%\end{verbatim} % \begin{macrocode} run_tex_code({ [[\color_export:nnN{]], str, [[}{backend}\mplib_@tempa]], @@ -2509,7 +2518,15 @@ vardef mplibtransformmatrix (text e) = & "}"); enddef; primarydef p withfademethod s = - p withprescript "mplibfadetype=" & s + if picture p: + image( + draw p; + draw center p withprescript "mplibfadestate=stop"; + ) + else: + p withprescript "mplibfadestate=stop" + fi + withprescript "mplibfadetype=" & s withprescript "mplibfadebbox=" & decimal xpart llcorner p & ":" & decimal ypart llcorner p & ":" & @@ -2863,6 +2880,7 @@ else "\\special{pdf:obj @MPlibCS<<>>}", "\\special{pdf:obj @MPlibPt<<>>}", } + pdfetcs.resadded = { } end % \end{macrocode} @@ -2909,23 +2927,29 @@ local function add_extgs_resources (on, new) 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) if object.postscript == "collect" then return end local opaq = prescript and prescript.tr_transparency - local on if opaq then + local key, on, os, new local mode = prescript.tr_alternative or 1 - mode = transparancy_modes[tonumber(mode)] - local os, new = format("<</BM /%s/ca %.3f/CA %.3f/AIS false>>",mode,opaq,opaq) - on, new = update_pdfobjs(os) - local key = add_extgs_resources(on,new) - start_pdf_code() - pdf_literalcode("/%s gs",key) + mode = transparancy_modes[tonumber(mode)] or mode + for i,v in ipairs{ {mode,opaq},{"Normal",1} } do + mode, opaq = v[1], v[2] + os = format("<</BM /%s/ca %.3f/CA %.3f/AIS false>>",mode,opaq,opaq) + on, new = update_pdfobjs(os) + key = add_extgs_resources(on,new) + if i == 1 then + pdf_literalcode("/%s gs",key) + else + return format("/%s gs",key) + end + end end - return on end % \end{macrocode} @@ -2981,6 +3005,7 @@ local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,st end if not pdfmode and not pdfmanagement then texsprint"\\special{pdf:put @resources <</Shading @MPlibSh>>}" + pdfetcs.resadded.Shading = "@MPlibSh" end return on end @@ -3131,6 +3156,64 @@ end % \begin{macrocode} pdfetcs.patterns = { } local patterns = pdfetcs.patterns +local function gather_resources (do_pattern, optres) + local t = { } + local names = {"ExtGState","ColorSpace","Shading"} + if do_pattern then + names[#names+1] = "Pattern" + end + if pdfmode then + if pdfmanagement then + for _,v in ipairs(names) do + local pp = get_macro(format("g__pdfdict_/g__pdf_Core/Page/Resources/%s_prop",v)) + if pp and pp:find"__prop_pair" then + t[#t+1] = format("/%s %s 0 R", v, ltx.pdf.object_id("__pdf/Page/Resources/"..v)) + end + end + else + local res = pdfetcs.getpageres() or "" + run_tex_code[[\mplibtmptoks\expandafter{\the\pdfvariable pageresources}]] + res = (res .. texgettoks'mplibtmptoks'):explode() + res = tableconcat(res," "):explode"/+" + for _,v in ipairs(res) do + if do_pattern or not v:find"Pattern" and not optres:find(v) then + t[#t+1] = "/" .. v + end + end + end + else + if pdfmanagement then + for _,v in ipairs(names) do + local pp = get_macro(format("g__pdfdict_/g__pdf_Core/Page/Resources/%s_prop",v)) + if pp and pp:find"__prop_pair" then + run_tex_code { + "\\mplibtmptoks\\expanded{{", + format("/%s \\csname pdf_object_ref:n\\endcsname{__pdf/Page/Resources/%s}",v,v), + "}}", + } + t[#t+1] = texgettoks'mplibtmptoks' + end + end + elseif is_defined(pdfetcs.pgfextgs) then + run_tex_code ({ + "\\mplibtmptoks\\expanded{{", + "\\ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs\\fi", + "\\ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces\\fi", + do_pattern and "\\ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \\fi" or "", + "}}", + }, catat11) + t[#t+1] = texgettoks'mplibtmptoks' + elseif do_pattern then + for _,v in ipairs(names) do + local vv = pdfetcs.resadded[v] + if vv then + t[#t+1] = format("/%s %s", v, vv) + end + end + end + end + return t +end function luamplib.registerpattern ( boxid, name, opts ) local box = texgetbox(boxid) local wd = format("%.3f",box.width/factor) @@ -3163,27 +3246,10 @@ function luamplib.registerpattern ( boxid, name, opts ) format("/YStep %s", opts.ystep or hd), format("/Matrix [%s %s %s]", opts.matrix or "1 0 0 1", opts.xshift or 0, opts.yshift or 0), } + local optres = opts.resources or "" + local t = gather_resources(false, optres) + optres = optres .. tableconcat(t) if pdfmode then - local optres, t = opts.resources or "", { } - if pdfmanagement then - for _,v in ipairs{"ExtGState","ColorSpace","Shading"} do - local pp = get_macro(format("g__pdfdict_/g__pdf_Core/Page/Resources/%s_prop",v)) - if pp and pp:find"__prop_pair" then - t[#t+1] = format("/%s %s 0 R", v, ltx.pdf.object_id("__pdf/Page/Resources/"..v)) - end - end - else - local res = pdfetcs.getpageres() or "" - run_tex_code[[\mplibtmptoks\expandafter{\the\pdfvariable pageresources}]] - res = (res .. texgettoks'mplibtmptoks'):explode() - res = tableconcat(res," "):explode"/+" - for _,v in ipairs(res) do - if not v:find"Pattern" and not optres:find(v) then - t[#t+1] = "/" .. v - end - end - end - optres = optres .. tableconcat(t) if opts.bbox then attr[#attr+1] = format("/BBox [%s]", opts.bbox) end @@ -3192,29 +3258,6 @@ function luamplib.registerpattern ( boxid, name, opts ) else local objname = "@mplibpattern"..name local metric = format("bbox %s", opts.bbox or format("0 0 %s %s",wd,hd)) - local optres, t = opts.resources or "", { } - if pdfmanagement then - for _,v in ipairs{"ExtGState","ColorSpace","Shading"} do - local pp = get_macro(format("g__pdfdict_/g__pdf_Core/Page/Resources/%s_prop",v)) - if pp and pp:find"__prop_pair" then - run_tex_code { - "\\mplibtmptoks\\expanded{{", - format("/%s \\csname pdf_object_ref:n\\endcsname{__pdf/Page/Resources/%s}",v,v), - "}}", - } - t[#t+1] = texgettoks'mplibtmptoks' - end - end - elseif is_defined(pdfetcs.pgfextgs) then - run_tex_code ({ - "\\mplibtmptoks\\expanded{{", - "\\ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs\\fi", - "\\ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces\\fi", - "}}", - }, catat11) - t[#t+1] = texgettoks'mplibtmptoks' - end - optres = optres .. tableconcat(t) texsprint { [[\ifvmode\nointerlineskip\fi]], format([[\hbox to0pt{\vbox to0pt{\hsize=\wd %i\vss\noindent]], boxid), -- force horiz mode? @@ -3251,6 +3294,7 @@ local function pattern_colorspace (cs) 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 @@ -3305,6 +3349,7 @@ local function do_preobj_PAT(object, prescript) 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 @@ -3313,22 +3358,29 @@ end % % Fading % \begin{macrocode} +pdfetcs.fading = { } local function do_preobj_FADE (object, prescript) - if object.postscript == "collect" then return end local fd_type = prescript and prescript.mplibfadetype - if not fd_type then return end + local fd_stop = prescript and prescript.mplibfadestate + if not fd_type then + return fd_stop -- returns "stop" (if picture) or nil + end local bbox = prescript.mplibfadebbox:explode":" - local width, height = bbox[3]-bbox[1], bbox[4]-bbox[2] - local vec = prescript.mplibfadevector - vec = vec and vec:explode":" - or fd_type == "linear" and {bbox[1], bbox[2], bbox[3], bbox[2]} -- left to right - or {width/2, height/2, width/2, height/2} -- center for both circles local dx, dy = -bbox[1], -bbox[2] - bbox = format("0 0 %f %f", bbox[3]+dx, bbox[4]+dy) + local vec = prescript.mplibfadevector; vec = vec and vec:explode":" + if not vec then + if fd_type == "linear" then + vec = {bbox[1], bbox[2], bbox[3], bbox[2]} -- left to right + else + local centerx, centery = (bbox[1]+bbox[3])/2, (bbox[2]+bbox[4])/2 + vec = {centerx, centery, centerx, centery} -- center for both circles + end + end local coords = { vec[1]+dx, vec[2]+dy, vec[3]+dx, vec[4]+dy } if fd_type == "linear" then coords = format("%f %f %f %f", tableunpack(coords)) elseif fd_type == "circular" then + local width, height = bbox[3]-bbox[1], bbox[4]-bbox[2] local radius = (prescript.mplibfaderadius or "0:"..math.sqrt(width^2+height^2)/2):explode":" tableinsert(coords, 3, radius[1]) tableinsert(coords, radius[2]) @@ -3336,6 +3388,7 @@ local function do_preobj_FADE (object, prescript) else err("unknown fading method '%s'", fd_type) end + bbox = format("0 0 %f %f", bbox[3]+dx, bbox[4]+dy) fd_type = fd_type == "linear" and 2 or 3 local opaq = (prescript.mplibfadeopacity or "1:0"):explode":" local on, os, new @@ -3360,7 +3413,76 @@ local function do_preobj_FADE (object, prescript) local key = add_extgs_resources(on,new) start_pdf_code() pdf_literalcode("/%s gs", key) - return on + if fd_stop then return "standalone" end + return "start" +end + +% \end{macrocode} +% +% Transparency Group +% \begin{macrocode} +pdfetcs.tr_group = { } +local function do_preobj_GRP (object, prescript) + local grstate = prescript and prescript.gr_state + if not grstate then return end + local trgroup = pdfetcs.tr_group + if grstate == "start" then + trgroup.isolated, trgroup.knockout = false, false + 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), + } + put2output[[\begingroup\setbox\mplibscratchbox\hbox\bgroup]] + elseif grstate == "stop" then + local llx,lly,urx,ury = tableunpack(trgroup.bbox) + local grattr = format("/Group<</S/Transparency/I %s/K %s>>",trgroup.isolated,trgroup.knockout) + local res = tableconcat(gather_resources(true)) + put2output(tableconcat{ + "\\egroup", + format("\\wd\\mplibscratchbox %fbp", urx-llx), + format("\\ht\\mplibscratchbox %fbp", ury-lly), + "\\dp\\mplibscratchbox 0pt", + }) + if pdfmode then + put2output(tableconcat{ + "\\saveboxresource type 2 attr{/Type/XObject/Subtype/Form/FormType 1", + format("/BBox[%f %f %f %f]", llx,lly,urx,ury), + grattr, "} resources{", res, "}\\mplibscratchbox", + [[\setbox\mplibscratchbox\hbox{\useboxresource\lastsavedboxresourceindex}]], + [[\wd\mplibscratchbox 0pt\ht\mplibscratchbox 0pt\dp\mplibscratchbox 0pt]], + [[\box\mplibscratchbox\endgroup]], + }) + else + trgroup.cnt = (trgroup.cnt or 0) + 1 + local objname = format("@mplibtrgr%s", trgroup.cnt) + put2output(tableconcat{ + "\\special{pdf:bxobj ", objname, " bbox ", format("%f %f %f %f", llx,lly,urx,ury), "}", + "\\unhbox\\mplibscratchbox", + "\\special{pdf:put @resources <<", res, ">>}", + "\\special{pdf:exobj <<", grattr, ">>}", + "\\special{pdf:uxobj ", objname, "}\\endgroup", + }) + end + end + return grstate +end + +local function stop_special_effects(fade,opaq,over) + if fade then -- fading + stop_pdf_code() + end + if opaq then -- opacity + pdf_literalcode(opaq) + end + if over then -- color + put2output"\\special{pdf:ec}" + end end % \end{macrocode} @@ -3488,11 +3610,11 @@ function luamplib.flush (result,flusher) % luamplib silently ignores this invalid figure for those % that do not contain |beginfig ... endfig|. (issue \#70) % Original code of ConTeXt general was: -% \begin{verbatim} +%\begin{verbatim} % -- invalid % pdf_startfigure(fignum,0,0,0,0) % pdf_stopfigure() -% \end{verbatim} +%\end{verbatim} % \begin{macrocode} else % \end{macrocode} @@ -3510,7 +3632,7 @@ function luamplib.flush (result,flusher) local object = objects[o] local objecttype = object.type % \end{macrocode} -% The following 7 lines are part of |btex...etex| patch. +% The following 8 lines are part of |btex...etex| patch. % Again, colors are processed at this stage. % \begin{macrocode} local prescript = object.prescript @@ -3518,6 +3640,7 @@ function luamplib.flush (result,flusher) local cr_over = do_preobj_CR(object,prescript) -- color 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 if prescript and prescript.mplibtexboxid then put_tex_boxes(object,prescript) elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then --skip @@ -3543,7 +3666,7 @@ function luamplib.flush (result,flusher) pdf_literalcode("%f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) stop_pdf_code() - else + elseif not trgroup and fading_ ~= "stop" then local evenodd, collect, both = false, false, false local postscript = object.postscript if not object.istext then @@ -3569,10 +3692,7 @@ function luamplib.flush (result,flusher) else % \end{macrocode} % Removed from ConTeXt general: color stuff. -% Added instead : shading stuff % \begin{macrocode} - local shade_no = do_preobj_SH(object,prescript) -- shading - local pattern_ = do_preobj_PAT(object,prescript) -- pattern local ml = object.miterlimit if ml and ml ~= miterlimit then miterlimit = ml @@ -3599,6 +3719,11 @@ 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 @@ -3688,21 +3813,29 @@ function luamplib.flush (result,flusher) end end % \end{macrocode} -% Added to ConTeXt general: post-object color and shading stuff. +% Added to ConTeXt general: post-object colors and shading stuff. +% We should beware the |q ... Q| scope. % \begin{macrocode} if shade_no then -- shading pdf_literalcode("W n /MPlibSh%s sh Q",shade_no) end end end - if fading_ then -- fading - stop_pdf_code() - end - if tr_opaq then -- opacity - stop_pdf_code() + if fading_ == "start" then + pdfetcs.fading.specialeffects = {fading_, tr_opaq, cr_over} + elseif trgroup == "start" then + pdfetcs.tr_group.specialeffects = {fading_, tr_opaq, cr_over} + elseif fading_ == "stop" then + local se = pdfetcs.fading.specialeffects + if se then stop_special_effects(se[1], se[2], se[3]) end + elseif trgroup == "stop" then + local se = pdfetcs.tr_group.specialeffects + if se then stop_special_effects(se[1], se[2], se[3]) end + else + stop_special_effects(fading_, tr_opaq, cr_over) end - if cr_over then -- color - put2output"\\special{pdf:ec}" + if fading_ or trgroup then -- extgs resetted + miterlimit, linecap, linejoin, dashed = -1, -1, -1, false end end end @@ -3761,7 +3894,7 @@ end \else \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{luamplib} - [2024/07/14 v2.33.1 mplib package for LuaTeX] + [2024/07/17 v2.34.0 mplib package for LuaTeX] \ifx\newluafunction\@undefined \input ltluatex \fi diff --git a/macros/luatex/generic/luamplib/luamplib.pdf b/macros/luatex/generic/luamplib/luamplib.pdf Binary files differindex a8bea32e1a..d59201ed00 100644 --- a/macros/luatex/generic/luamplib/luamplib.pdf +++ b/macros/luatex/generic/luamplib/luamplib.pdf diff --git a/macros/luatex/generic/luamplib/test-luamplib-latex.tex b/macros/luatex/generic/luamplib/test-luamplib-latex.tex index 50a5778870..b2f2f63cb7 100644 --- a/macros/luatex/generic/luamplib/test-luamplib-latex.tex +++ b/macros/luatex/generic/luamplib/test-luamplib-latex.tex @@ -287,7 +287,7 @@ draw mpliboutlinetext.b ("$\displaystyle\frac{1}{1-x^2}$") endfor endfor \endmpfig -\par +\par\leavevmode \mpfig picture mill; mill = btex \includegraphics[width=100bp]{mill} etex; draw mill; @@ -299,6 +299,33 @@ draw mpliboutlinetext.b ("$\displaystyle\frac{1}{1-x^2}$") withfadeopacity (1, 0) ; \endmpfig +\par +\def\test#1{% + \mpfig + fill unitsquare shifted -center unitsquare scaled 200 + withshademethod "linear" + withshadecolors (.3[red,white], .3[blue,white]) + ; + label( btex MetaPost etex scaled 3, origin) ; + draw image( + fill fullcircle scaled 100 shifted 25left + withcolor .8white + withtransparency (2,1) + ; + fill fullcircle scaled 100 shifted 25right + withcolor .8white + withtransparency (2,1) + ; + ) + asgroup "#1" + withtransparency (1,.5) + ; + currentpicture := currentpicture scaled 3/4; + \endmpfig +}% +\hbox{\test{isolated,knockout}\,\test{isolated}\vbox to\MPheight{\vss\hbox{~isolated}\vss}}% +\hbox{\test{knockout}\,\test{}}% +\hbox to\MPwidth{\hss knockout\hss}% \tracingcommands0 \vskip 2\baselineskip diff --git a/macros/luatex/generic/luamplib/test-luamplib-plain.tex b/macros/luatex/generic/luamplib/test-luamplib-plain.tex index dde6fbfb10..622932ca10 100644 --- a/macros/luatex/generic/luamplib/test-luamplib-plain.tex +++ b/macros/luatex/generic/luamplib/test-luamplib-plain.tex @@ -280,6 +280,20 @@ draw mpliboutlinetext.b ("$\overbrace{x+\cdots+x}^k$") endfor endfor \endmpfig +\mpfig +fill fullcircle scaled 125 withcolor 2/3[blue,white]; +draw image( + draw (left--right) rotated 45 scaled 50 + withpen pencircle scaled 20 + ; + draw (left--right) rotated -45 scaled 50 + withpen pencircle scaled 20 + ; + ) + asgroup "" + withprescript "tr_transparency=.3" + ; +\endmpfig \tracingcommands0 \vskip 2\baselineskip |