texlive[71467] Master/texmf-dist: luamplib (10jun24)

commits+karl at tug.org commits+karl at tug.org
Mon Jun 10 22:22:58 CEST 2024


Revision: 71467
          https://tug.org/svn/texlive?view=revision&revision=71467
Author:   karl
Date:     2024-06-10 22:22:58 +0200 (Mon, 10 Jun 2024)
Log Message:
-----------
luamplib (10jun24)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS
    trunk/Master/texmf-dist/doc/luatex/luamplib/luamplib.pdf
    trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex
    trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex
    trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx
    trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
    trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS	2024-06-10 20:22:38 UTC (rev 71466)
+++ trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS	2024-06-10 20:22:58 UTC (rev 71467)
@@ -1,5 +1,11 @@
                        History of the luamplib package
 
+2024/06/10 2.32.0
+   * \mppattern{<name>} ... \endmppattern defines a tiling pattern which can be
+   used with 'withpattern' operator to fill a closed path by replicating the tile
+   horizontally and vertically.  \begin{mppattern} ... \end{mppattern} is exactly
+   the same as \mppattern ... \endmppattern.  See luamplib manual for details.
+
 2024/05/30 2.31.2
    * support vertical writing mode in mpliboutlinetext (presently luatexko
    package only, and except horizontal mode inside vertical mode)

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/luamplib.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex	2024-06-10 20:22:38 UTC (rev 71466)
+++ trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex	2024-06-10 20:22:58 UTC (rev 71467)
@@ -244,6 +244,41 @@
     )
     scaled 4;
 \endmpfig
+\par\leavevmode
+\mppattern{mypatt}
+  \mpfig
+    picture q;
+    q := btex Q etex;
+    fill bbox q withcolor .8[red,white];
+    draw q withcolor .8red;
+  \endmpfig
+\endmppattern
+\mpfig
+  fill fullcircle scaled 100 withpostscript "collect";
+  draw unitsquare shifted - center unitsquare scaled 45
+    withpattern "mypatt"
+    withpostscript "evenodd"
+    ;
+\endmpfig
+\begin{mppattern}{pattuncolored}
+  [
+    colored = false,
+    matrix = "0.7071 0.7071 -0.7071 0.7071",
+  ]
+  \tiny\TeX
+\end{mppattern}\relax
+\mpfig
+  picture tex; tex := mpliboutlinetext.p ("\bfseries \TeX");
+  i:=0;
+  for item within tex:
+    i:=i+1;
+    if i < length tex:
+      fill pathpart item scaled 10 withpostscript "collect";
+    else:
+      draw pathpart item scaled 10 withpattern "pattuncolored" withcolor 0.7 blue;
+    fi
+  endfor
+\endmpfig
 \tracingcommands0
 
 \vskip 2\baselineskip

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex	2024-06-10 20:22:38 UTC (rev 71466)
+++ trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex	2024-06-10 20:22:58 UTC (rev 71467)
@@ -237,6 +237,41 @@
     )
     scaled 4;
 \endmpfig
+\par\leavevmode
+\mppattern{mypatt}
+  \mpfig
+    picture q;
+    q := btex Q etex;
+    fill bbox q withcolor .8[red,white];
+    draw q withcolor .8red;
+  \endmpfig
+\endmppattern
+\mpfig
+  fill fullcircle scaled 100 withpostscript "collect";
+  draw unitsquare shifted - center unitsquare scaled 45
+    withpattern "mypatt"
+    withpostscript "evenodd"
+    ;
+\endmpfig
+\mppattern{pattuncolored}
+  [
+    colored = false,
+    matrix = "0.7071 0.7071 -0.7071 0.7071",
+  ]
+  \fiverm\TeX
+\endmppattern
+\mpfig
+  picture tex; tex := mpliboutlinetext.p ("\bf \TeX");
+  i:=0;
+  for item within tex:
+    i:=i+1;
+    if i < length tex:
+      fill pathpart item scaled 10 withpostscript "collect";
+    else:
+      draw pathpart item scaled 10 withpattern "pattuncolored" withcolor 0.7 blue;
+    fi
+  endfor
+\endmpfig
 \tracingcommands0
 
 \vskip 2\baselineskip

Modified: trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx	2024-06-10 20:22:38 UTC (rev 71466)
+++ trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx	2024-06-10 20:22:58 UTC (rev 71467)
@@ -85,7 +85,7 @@
 %<*driver>
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{luamplib.drv}%
-  [2024/05/30 v2.31.2 Interface for using the mplib library]%
+  [2024/06/10 v2.32.0 Interface for using the mplib library]%
 \documentclass{ltxdoc}
 \usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace}
 \usepackage[x11names]{xcolor}
@@ -153,7 +153,7 @@
 % \author{Hans Hagen, Taco Hoekwater, Elie Roux, Philipp Gesang and Kim Dohyun\\
 % Maintainer: LuaLaTeX Maintainers ---
 % Support: \email{lualatex-dev at tug.org}}
-% \date{2024/05/30 v2.31.2}
+% \date{2024/06/10 v2.32.0}
 %
 % \maketitle
 %
@@ -541,6 +541,81 @@
 %   \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} \ldots\ \cs{endmppattern}, \texttt{withpattern}}
+%   |\mppattern{<name>}| \ldots\ |\endmppattern| defines a tiling pattern
+%   associated with the |<name>|.
+%   MetaPost operator |withpattern|, the syntax being
+%   \textit{path} |withpattern| \textit{string}, will return a metapost picture which fills
+%   the given path with a tiling pattern of the |<name>|.
+%   \begin{verbatim}
+%     \mppattern{mypatt}           % or \begin{mppattern}{mypatt}
+%       [ xstep = 10, ystep = 12 ] % options: see below
+%       \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}
+%
+%     \mpfig
+%       fill fullcircle scaled 100 withpostscript "collect";
+%       draw unitsquare shifted - center unitsquare scaled 45
+%         withpattern "mypatt"
+%         withpostscript "evenodd" ;
+%     \endmpfig
+%   \end{verbatim}
+%   The available options are:
+%
+%   \bigskip
+%   \begin{tabular}{lll}\hline
+%     Key   & Value Type & Explanation\\\hline
+%     |xstep|    &\textit{number} & horizontal spacing between pattern cells\\
+%     |ystep|    &\textit{number} & vertical spacing between pattern cells\\
+%     |xshift|   &\textit{number} & horizontal shifting of pattern cells\\
+%     |yshift|   &\textit{number} & vertical shifting of pattern cells\\
+%     |bbox|     &\textit{string} & |llx| |lly| |urx| |ury| values separated by spaces\\
+%     |matrix|   &\textit{string} & |xx| |xy| |yx| |yy| values separated by spaces\\
+%     |resources|&\textit{string} & PDF resources if needed\\
+%     |colored|  &\textit{boolean}& |false| for uncolored pattern. default: |true|\\\hline
+%   \end{tabular}
+%   \bigskip
+%
+%   When you use special effects such as transparency in a pattern,
+%   |resources| option might be needed: for instance, |resources="/ExtGState 1 0 R"|.
+%
+%   Option |colored=false| 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{mppattern}{pattuncolored}
+%        [
+%          colored = false,
+%          matrix = "0.7071 0.7071 -0.7071 0.7071",
+%        ]
+%        \tiny\TeX
+%      \end{mppattern}
+%
+%      \begin{mplibcode}
+%        beginfig(1)
+%        picture tex; tex := mpliboutlinetext.p ("\bfseries \TeX");
+%        i:=0;
+%        for item within tex:
+%          i:=i+1;
+%          if i < length tex:
+%            fill pathpart item scaled 10
+%                 withpostscript "collect";
+%          else:
+%            draw pathpart item scaled 10
+%                 withpattern "pattuncolored"
+%                 withcolor 0.7 blue          % paints the pattern
+%                 ;
+%          fi
+%        endfor
+%        endfig;
+%      \end{mplibcode}
+%   \end{verbatim}
+%
 % \paragraph{About figure box metrics}
 %   Notice that, after each figure is processed, macro \cs{MPwidth} stores
 %   the width value of latest figure; \cs{MPheight}, the height value.
@@ -573,8 +648,8 @@
 
 luatexbase.provides_module {
   name          = "luamplib",
-  version       = "2.31.2",
-  date          = "2024/05/30",
+  version       = "2.32.0",
+  date          = "2024/06/10",
   description   = "Lua package to typeset Metapost with LuaTeX's MPLib.",
 }
 
@@ -1625,6 +1700,7 @@
 luamplib.graphictext = function (text, fakebold, fc, dc)
   local fmt = process_tex_text(text):sub(1,-2)
   local id = tonumber(fmt:match"mplibtexboxid=(%d+):")
+  emboldenfonts.width = nil
   local box = texgetbox(id)
   box.head = embolden(box, box.head, fakebold)
   local fill = graphictextcolor(fc,"fill")
@@ -2224,6 +2300,9 @@
     fi;
   ) mplib_do_outline_options_r; )
 enddef ;
+primarydef t withpattern p =
+  image( fill t withprescript "mplibpattern=" & if numeric p: decimal fi p; )
+enddef;
 ]],
   legacyverbatimtex = [[
 def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
@@ -2620,7 +2699,8 @@
     end
   end
 else
-  texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}")
+  texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}",
+  "\\special{pdf:obj @MPlibCS<<>>}","\\special{pdf:obj @MPlibPt<<>>}")
 end
 
 %    \end{macrocode}
@@ -2772,10 +2852,11 @@
 end })
 
 local function do_preobj_SH(object,prescript)
-  if object.postscript == "collect" then return end
   local shade_no
   local sh_type = prescript and prescript.sh_type
-  if sh_type then
+  if not sh_type then
+    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()
@@ -2889,6 +2970,129 @@
 
 %    \end{macrocode}
 %
+%    Patterns
+%    \begin{macrocode}
+patterns = { c_l_r_s_p_c_s_ = { } }
+function luamplib.registerpattern ( boxid, name, opts )
+  local box = texgetbox(boxid)
+  if opts.xstep == 0 then opts.xstep = nil end
+  if opts.ystep == 0 then opts.ystep = nil end
+  if opts.colored == nil then opts.colored = true end
+  local attr = {
+    "/Type/Pattern",
+    "/PatternType 1",
+    format("/PaintType %i", opts.colored and 1 or 2),
+    "/TilingType 2",
+    format("/XStep %.3f", opts.xstep or box.width/factor),
+    format("/YStep %.3f", opts.ystep or (box.height+box.depth)/factor),
+    format("/Matrix [%s %s %s]", opts.matrix or "1 0 0 1", opts.xshift or 0, opts.yshift or 0),
+  }
+  if pdfmode then
+    if opts.bbox then
+      attr[#attr+1] = format("/BBox [%s]", opts.bbox)
+    end
+    local index = tex.saveboxresource(boxid,tableconcat(attr),opts.resources,true,opts.bbox and 4 or 1)
+    patterns[name] = { id = index, colored = opts.colored }
+  else
+    local objname = "@mplibpattern"..name
+    local metric = opts.bbox and format("bbox %s",opts.bbox) or
+      format([[width \the\wd%i \space height \the\ht%i \space depth \the\dp%i]],boxid,boxid,boxid)
+    texsprint {
+      [[\ifvmode\nointerlineskip\fi]],
+      format([[\hbox to0pt{\vbox to0pt{\hsize=\wd %i\vss\noindent]], boxid), -- force horiz mode?
+      [[\special{pdf:bcontent}]],
+      [[\special{pdf:bxobj ]], objname, format(" %s}", metric),
+      format([[\box %i]], boxid),
+      [[\special{pdf:exobj <<]], tableconcat(attr), ">>}",
+      [[\special{pdf:econtent}]],
+      [[\par}\hss}]],
+    }
+    patterns[#patterns+1] = objname
+    patterns[name] = { id = #patterns, colored = opts.colored }
+  end
+end
+local function pattern_colorspace (cs, ref)
+  local on, new = update_pdfobjs(format("[/Pattern %s]", ref or format("/%s",cs)))
+  if new then
+    local key = format("MPlibCS%i",on)
+    local val = pdfmode and format("%i 0 R",on) or format("@mplibpdfobj%i",on)
+    if pdfmanagement then
+      texsprint(ccexplat,format("\\pdfmanagement_add:nnn{Page/Resources/ColorSpace}{%s}{%s}",key,val))
+    else
+      local res = format("/%s %s", key, val)
+      if is_defined"pgf at sys@addpdfresource at colorspaces@plain" then
+        texsprint(catat11, format("\\pgf at sys@addpdfresource at colorspaces@plain{%s}", res))
+      elseif pdfmode then
+        if not pdfetcs.ColorSpace_res then
+          pdfetcs.initialize_resources"ColorSpace"
+        end
+        pdfetcs.fallback_update_resources("ColorSpace", res)
+      else
+        texsprint(format("\\special{pdf:put @MPlibCS<<%s>>}", res))
+        texsprint"\\special{pdf:put @resources<</ColorSpace @MPlibCS>>}"
+      end
+    end
+    patterns.c_l_r_s_p_c_s_[cs] = on
+  end
+  return on
+end
+local function do_preobj_PAT(object, prescript)
+  local name = prescript and prescript.mplibpattern
+  if not name then return end
+  local patt = patterns[name]
+  local index = patt and patt.id or err("cannot get pattern object '%s'", name)
+  local key = format("MPlibPt%s",index)
+  if patt.colored then
+    pdf_literalcode("/Pattern cs /%s scn", key)
+  else
+    local color = prescript.mpliboverridecolor
+    if not color then
+      local t = object.color
+      color = t and #t>0 and luamplib.colorconverter(t)
+    end
+    if not color then return end
+    local csobj, cs, ref
+    if color:find" cs " or color:find"@pdf.obj" then
+      local t = color:explode()
+      if pdfmode then
+        cs = t[1]:sub(2,-1)
+        ref = format("%s 0 R", ltx.pdf.object_id(cs))
+        color = t[3]
+      else
+        cs, ref = t[2], t[2]
+        color = t[3]:match"%[(.+)%]"
+      end
+    else
+      local t = colorsplit(color)
+      cs = #t == 4 and "DeviceCMYK" or #t == 3 and "DeviceRGB" or "DeviceGray"
+      color = tableconcat(t," ")
+    end
+    csobj = patterns.c_l_r_s_p_c_s_[cs] or pattern_colorspace(cs, ref)
+    pdf_literalcode("/MPlibCS%i cs %s /%s scn", csobj, color, key)
+  end
+  if patt.done then return end
+  local val = pdfmode and format("%s 0 R",index) or patterns[index]
+  if pdfmanagement then
+    texsprint(ccexplat, format("\\pdfmanagement_add:nnn{Page/Resources/Pattern}{%s}{%s}",key,val))
+  else
+    local res = format("/%s %s", key, val)
+    if is_defined"pgf at sys@addpdfresource at patterns@plain" then
+      texsprint(catat11, format("\\pgf at sys@addpdfresource at patterns@plain{%s}", res))
+    elseif pdfmode then
+      if not pdfetcs.Pattern_res then
+        pdfetcs.initialize_resources"Pattern"
+      end
+      pdfetcs.fallback_update_resources("Pattern", res)
+    else
+      texsprint(format("\\special{pdf:put @MPlibPt<<%s>>}", res))
+      texsprint"\\special{pdf:put @resources<</Pattern @MPlibPt>>}"
+    end
+  end
+  patt.done = true
+end
+
+%    \end{macrocode}
+%
 %    Finally, flush figures by inserting PDF literals.
 %    \begin{macrocode}
 function luamplib.flush (result,flusher)
@@ -2991,6 +3195,7 @@
 %    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
@@ -3176,7 +3381,7 @@
 \else
   \NeedsTeXFormat{LaTeX2e}
   \ProvidesPackage{luamplib}
-    [2024/05/30 v2.31.2 mplib package for LuaTeX]
+    [2024/06/10 v2.32.0 mplib package for LuaTeX]
   \ifx\newluafunction\@undefined
   \input ltluatex
   \fi
@@ -3240,6 +3445,44 @@
 \def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\copy#1\hss}}}
 %    \end{macrocode}
 %
+%    Patterns
+%    \begin{macrocode}
+{\def\:{\global\let\mplibsptoken= } \: }
+\protected\def\mppattern#1{%
+  \begingroup
+  \def\mplibpatternname{#1}%
+  \mplibpatterngetnexttok
+}
+\def\mplibpatterngetnexttok{\futurelet\nexttok\mplibpatternbranch}
+\def\mplibpatternskipspace{\afterassignment\mplibpatterngetnexttok\let\nexttok= }
+\def\mplibpatternbranch{%
+  \ifx [\nexttok
+    \expandafter\mplibpatternopts
+  \else
+    \ifx\mplibsptoken\nexttok
+      \expandafter\expandafter\expandafter\mplibpatternskipspace
+    \else
+      \let\mplibpatternoptions\empty
+      \expandafter\expandafter\expandafter\mplibpatternmain
+    \fi
+  \fi
+}
+\def\mplibpatternopts[#1]{%
+  \def\mplibpatternoptions{#1}%
+  \mplibpatternmain
+}
+\def\mplibpatternmain{%
+  \setbox\mplibscratchbox\hbox\bgroup\ignorespaces
+}
+\protected\def\endmppattern{%
+  \egroup
+  \directlua{ luamplib.registerpattern(
+    \the\mplibscratchbox, '\mplibpatternname', {\mplibpatternoptions}
+  )}%
+  \endgroup
+}
+%    \end{macrocode}
+%
 %    simple way to use mplib:
 %    |\mpfig draw fullcircle scaled 10; \endmpfig|
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua	2024-06-10 20:22:38 UTC (rev 71466)
+++ trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua	2024-06-10 20:22:58 UTC (rev 71467)
@@ -11,8 +11,8 @@
 
 luatexbase.provides_module {
   name          = "luamplib",
-  version       = "2.31.2",
-  date          = "2024/05/30",
+  version       = "2.32.0",
+  date          = "2024/06/10",
   description   = "Lua package to typeset Metapost with LuaTeX's MPLib.",
 }
 
@@ -823,6 +823,7 @@
 luamplib.graphictext = function (text, fakebold, fc, dc)
   local fmt = process_tex_text(text):sub(1,-2)
   local id = tonumber(fmt:match"mplibtexboxid=(%d+):")
+  emboldenfonts.width = nil
   local box = texgetbox(id)
   box.head = embolden(box, box.head, fakebold)
   local fill = graphictextcolor(fc,"fill")
@@ -1410,6 +1411,9 @@
     fi;
   ) mplib_do_outline_options_r; )
 enddef ;
+primarydef t withpattern p =
+  image( fill t withprescript "mplibpattern=" & if numeric p: decimal fi p; )
+enddef;
 ]],
   legacyverbatimtex = [[
 def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
@@ -1756,7 +1760,8 @@
     end
   end
 else
-  texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}")
+  texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}",
+  "\\special{pdf:obj @MPlibCS<<>>}","\\special{pdf:obj @MPlibPt<<>>}")
 end
 
 local transparancy_modes = { [0] = "Normal",
@@ -1900,10 +1905,11 @@
 end })
 
 local function do_preobj_SH(object,prescript)
-  if object.postscript == "collect" then return end
   local shade_no
   local sh_type = prescript and prescript.sh_type
-  if sh_type then
+  if not sh_type then
+    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()
@@ -2015,6 +2021,125 @@
   return shade_no
 end
 
+patterns = { c_l_r_s_p_c_s_ = { } }
+function luamplib.registerpattern ( boxid, name, opts )
+  local box = texgetbox(boxid)
+  if opts.xstep == 0 then opts.xstep = nil end
+  if opts.ystep == 0 then opts.ystep = nil end
+  if opts.colored == nil then opts.colored = true end
+  local attr = {
+    "/Type/Pattern",
+    "/PatternType 1",
+    format("/PaintType %i", opts.colored and 1 or 2),
+    "/TilingType 2",
+    format("/XStep %.3f", opts.xstep or box.width/factor),
+    format("/YStep %.3f", opts.ystep or (box.height+box.depth)/factor),
+    format("/Matrix [%s %s %s]", opts.matrix or "1 0 0 1", opts.xshift or 0, opts.yshift or 0),
+  }
+  if pdfmode then
+    if opts.bbox then
+      attr[#attr+1] = format("/BBox [%s]", opts.bbox)
+    end
+    local index = tex.saveboxresource(boxid,tableconcat(attr),opts.resources,true,opts.bbox and 4 or 1)
+    patterns[name] = { id = index, colored = opts.colored }
+  else
+    local objname = "@mplibpattern"..name
+    local metric = opts.bbox and format("bbox %s",opts.bbox) or
+      format([[width \the\wd%i \space height \the\ht%i \space depth \the\dp%i]],boxid,boxid,boxid)
+    texsprint {
+      [[\ifvmode\nointerlineskip\fi]],
+      format([[\hbox to0pt{\vbox to0pt{\hsize=\wd %i\vss\noindent]], boxid), -- force horiz mode?
+      [[\special{pdf:bcontent}]],
+      [[\special{pdf:bxobj ]], objname, format(" %s}", metric),
+      format([[\box %i]], boxid),
+      [[\special{pdf:exobj <<]], tableconcat(attr), ">>}",
+      [[\special{pdf:econtent}]],
+      [[\par}\hss}]],
+    }
+    patterns[#patterns+1] = objname
+    patterns[name] = { id = #patterns, colored = opts.colored }
+  end
+end
+local function pattern_colorspace (cs, ref)
+  local on, new = update_pdfobjs(format("[/Pattern %s]", ref or format("/%s",cs)))
+  if new then
+    local key = format("MPlibCS%i",on)
+    local val = pdfmode and format("%i 0 R",on) or format("@mplibpdfobj%i",on)
+    if pdfmanagement then
+      texsprint(ccexplat,format("\\pdfmanagement_add:nnn{Page/Resources/ColorSpace}{%s}{%s}",key,val))
+    else
+      local res = format("/%s %s", key, val)
+      if is_defined"pgf at sys@addpdfresource at colorspaces@plain" then
+        texsprint(catat11, format("\\pgf at sys@addpdfresource at colorspaces@plain{%s}", res))
+      elseif pdfmode then
+        if not pdfetcs.ColorSpace_res then
+          pdfetcs.initialize_resources"ColorSpace"
+        end
+        pdfetcs.fallback_update_resources("ColorSpace", res)
+      else
+        texsprint(format("\\special{pdf:put @MPlibCS<<%s>>}", res))
+        texsprint"\\special{pdf:put @resources<</ColorSpace @MPlibCS>>}"
+      end
+    end
+    patterns.c_l_r_s_p_c_s_[cs] = on
+  end
+  return on
+end
+local function do_preobj_PAT(object, prescript)
+  local name = prescript and prescript.mplibpattern
+  if not name then return end
+  local patt = patterns[name]
+  local index = patt and patt.id or err("cannot get pattern object '%s'", name)
+  local key = format("MPlibPt%s",index)
+  if patt.colored then
+    pdf_literalcode("/Pattern cs /%s scn", key)
+  else
+    local color = prescript.mpliboverridecolor
+    if not color then
+      local t = object.color
+      color = t and #t>0 and luamplib.colorconverter(t)
+    end
+    if not color then return end
+    local csobj, cs, ref
+    if color:find" cs " or color:find"@pdf.obj" then
+      local t = color:explode()
+      if pdfmode then
+        cs = t[1]:sub(2,-1)
+        ref = format("%s 0 R", ltx.pdf.object_id(cs))
+        color = t[3]
+      else
+        cs, ref = t[2], t[2]
+        color = t[3]:match"%[(.+)%]"
+      end
+    else
+      local t = colorsplit(color)
+      cs = #t == 4 and "DeviceCMYK" or #t == 3 and "DeviceRGB" or "DeviceGray"
+      color = tableconcat(t," ")
+    end
+    csobj = patterns.c_l_r_s_p_c_s_[cs] or pattern_colorspace(cs, ref)
+    pdf_literalcode("/MPlibCS%i cs %s /%s scn", csobj, color, key)
+  end
+  if patt.done then return end
+  local val = pdfmode and format("%s 0 R",index) or patterns[index]
+  if pdfmanagement then
+    texsprint(ccexplat, format("\\pdfmanagement_add:nnn{Page/Resources/Pattern}{%s}{%s}",key,val))
+  else
+    local res = format("/%s %s", key, val)
+    if is_defined"pgf at sys@addpdfresource at patterns@plain" then
+      texsprint(catat11, format("\\pgf at sys@addpdfresource at patterns@plain{%s}", res))
+    elseif pdfmode then
+      if not pdfetcs.Pattern_res then
+        pdfetcs.initialize_resources"Pattern"
+      end
+      pdfetcs.fallback_update_resources("Pattern", res)
+    else
+      texsprint(format("\\special{pdf:put @MPlibPt<<%s>>}", res))
+      texsprint"\\special{pdf:put @resources<</Pattern @MPlibPt>>}"
+    end
+  end
+  patt.done = true
+end
+
 function luamplib.flush (result,flusher)
   if result then
     local figures = result.fig
@@ -2090,6 +2215,7 @@
                   end
                 else
                   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

Modified: trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty	2024-06-10 20:22:38 UTC (rev 71466)
+++ trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty	2024-06-10 20:22:58 UTC (rev 71467)
@@ -14,7 +14,7 @@
 \else
   \NeedsTeXFormat{LaTeX2e}
   \ProvidesPackage{luamplib}
-    [2024/05/30 v2.31.2 mplib package for LuaTeX]
+    [2024/06/10 v2.32.0 mplib package for LuaTeX]
   \ifx\newluafunction\@undefined
   \input ltluatex
   \fi
@@ -46,6 +46,40 @@
   \catcode`\&=12 \catcode`\$=12 \catcode`\%=12 \catcode`\^^M=12
 }
 \def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\copy#1\hss}}}
+{\def\:{\global\let\mplibsptoken= } \: }
+\protected\def\mppattern#1{%
+  \begingroup
+  \def\mplibpatternname{#1}%
+  \mplibpatterngetnexttok
+}
+\def\mplibpatterngetnexttok{\futurelet\nexttok\mplibpatternbranch}
+\def\mplibpatternskipspace{\afterassignment\mplibpatterngetnexttok\let\nexttok= }
+\def\mplibpatternbranch{%
+  \ifx [\nexttok
+    \expandafter\mplibpatternopts
+  \else
+    \ifx\mplibsptoken\nexttok
+      \expandafter\expandafter\expandafter\mplibpatternskipspace
+    \else
+      \let\mplibpatternoptions\empty
+      \expandafter\expandafter\expandafter\mplibpatternmain
+    \fi
+  \fi
+}
+\def\mplibpatternopts[#1]{%
+  \def\mplibpatternoptions{#1}%
+  \mplibpatternmain
+}
+\def\mplibpatternmain{%
+  \setbox\mplibscratchbox\hbox\bgroup\ignorespaces
+}
+\protected\def\endmppattern{%
+  \egroup
+  \directlua{ luamplib.registerpattern(
+    \the\mplibscratchbox, '\mplibpatternname', {\mplibpatternoptions}
+  )}%
+  \endgroup
+}
 \def\mpfiginstancename{@mpfig}
 \protected\def\mpfig{%
   \begingroup



More information about the tex-live-commits mailing list.