texlive[74880] Master/texmf-dist: l3backend (8apr25)

commits+karl at tug.org commits+karl at tug.org
Tue Apr 8 22:12:26 CEST 2025


Revision: 74880
          https://tug.org/svn/texlive?view=revision&revision=74880
Author:   karl
Date:     2025-04-08 22:12:26 +0200 (Tue, 08 Apr 2025)
Log Message:
-----------
l3backend (8apr25)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3backend/README.md
    trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf
    trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.tex
    trunk/Master/texmf-dist/dvips/l3backend/l3backend-dvips.pro
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend.ins
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.lua
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def

Added Paths:
-----------
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdfannot.dtx

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md	2025-04-08 20:12:26 UTC (rev 74880)
@@ -6,6 +6,19 @@
 
 ## [Unreleased]
 
+## [2025-03-14]
+
+### Fixed
+- Correct naming of PostScript functions in PDF area
+
+## [2025-03-10]
+
+### Added
+- Support for canvas shifts
+
+### Changed
+- Move PDF annotation functions to `pdfannot` module
+
 ## [2024-05-08]
 
 ### Changed
@@ -355,7 +368,9 @@
 - Include `l3backend` in file names
 - Moved backend code to internal for each 'parent' module
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2024-05-08...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2025-03-14...HEAD
+[2025-03-14]: https://github.com/latex3/latex3/compare/2025-03-10...2025-03-14
+[2025-03-10]: https://github.com/latex3/latex3/compare/2024-05-08...2025-03-10
 [2024-05-08]: https://github.com/latex3/latex3/compare/2024-04-11...2024-05-08
 [2024-04-11]: https://github.com/latex3/latex3/compare/2024-03-14...2024-04-11
 [2024-03-14]: https://github.com/latex3/latex3/compare/2024-02-20...2024-03-14

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3backend/README.md	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/doc/latex/l3backend/README.md	2025-04-08 20:12:26 UTC (rev 74880)
@@ -1,7 +1,7 @@
 LaTeX3 Backend Drivers
 ======================
 
-Release 2024-05-08
+Release 2025-03-14
 
 This package forms parts of `expl3`, and contains the code used to interface
 with backends (drivers) across the `expl3` codebase. The functions here are
@@ -11,6 +11,6 @@
 
 -----
 
-<p>Copyright (C) 2019-2024 The LaTeX Project <br />
+<p>Copyright (C) 2019-2025 The LaTeX Project <br />
 <a href="http://latex-project.org/">http://latex-project.org/</a> <br />
 All rights reserved.</p>

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.tex	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.tex	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 
 File: l3backend-code.tex
 
-Copyright (C) 2019,2021 The LaTeX Project
+Copyright (C) 2019,2021,2025 The LaTeX Project
 
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,6 +44,7 @@
     l3backend-draw.dtx     ,
     l3backend-graphics.dtx ,
     l3backend-pdf.dtx      ,
+    l3backend-pdfannot.dtx ,
     l3backend-opacity.dtx  ,
     l3backend-header.dtx
   }

Modified: trunk/Master/texmf-dist/dvips/l3backend/l3backend-dvips.pro
===================================================================
--- trunk/Master/texmf-dist/dvips/l3backend/l3backend-dvips.pro	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/dvips/l3backend/l3backend-dvips.pro	2025-04-08 20:12:26 UTC (rev 74880)
@@ -6,7 +6,7 @@
 %%
 %% l3backend-header.dtx  (with options: `header,dvips')
 %% 
-%% Copyright (C) 2019-2024 The LaTeX Project
+%% Copyright (C) 2019-2025 The LaTeX Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-basics.dtx
 %
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %
@@ -70,27 +70,27 @@
 %    \begin{macrocode}
 \ProvidesExplFile
 %<*dvipdfmx>
-  {l3backend-dvipdfmx.def}{2024-05-08}{}
+  {l3backend-dvipdfmx.def}{2025-03-14}{}
   {L3 backend support: dvipdfmx}
 %</dvipdfmx>
 %<*dvips>
-  {l3backend-dvips.def}{2024-05-08}{}
+  {l3backend-dvips.def}{2025-03-14}{}
   {L3 backend support: dvips}
 %</dvips>
 %<*dvisvgm>
-  {l3backend-dvisvgm.def}{2024-05-08}{}
+  {l3backend-dvisvgm.def}{2025-03-14}{}
   {L3 backend support: dvisvgm}
 %</dvisvgm>
 %<*luatex>
-  {l3backend-luatex.def}{2024-05-08}{}
+  {l3backend-luatex.def}{2025-03-14}{}
   {L3 backend support: PDF output (LuaTeX)}
 %</luatex>
 %<*pdftex>
-  {l3backend-pdftex.def}{2024-05-08}{}
+  {l3backend-pdftex.def}{2025-03-14}{}
   {L3 backend support: PDF output (pdfTeX)}
 %</pdftex>
 %<*xetex>
-  {l3backend-xetex.def}{2024-05-08}{}
+  {l3backend-xetex.def}{2025-03-14}{}
   {L3 backend support: XeTeX}
 %</xetex>
 %    \end{macrocode}
@@ -280,7 +280,16 @@
 %</pdftex>
       { \exp_not:n {#1} }
   }
-\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:e #1
+  {
+%<*luatex>
+    \tex_pdfextension:D literal
+%</luatex>
+%<*pdftex>
+    \tex_pdfliteral:D
+%</pdftex>
+      {#1}
+  }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -350,7 +359,16 @@
 %</pdftex>
         { \exp_not:n {#1} }
   }
-\cs_generate_variant:Nn \__kernel_backend_matrix:n { e }
+\cs_new_protected:Npn \__kernel_backend_matrix:e #1
+  {
+%<*luatex>
+    \tex_pdfextension:D setmatrix
+%</luatex>
+%<*pdftex>
+    \tex_pdfsetmatrix:D
+%</pdftex>
+        {#1}
+  }
 %    \end{macrocode}
 % \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-box.dtx
 %
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-color.dtx
 %
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-draw.dtx
 %
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %
@@ -115,7 +115,7 @@
 % \begin{macro}{\@@_backend_curveto:nnnnnn}
 %   Path creation operations mainly resolve directly to PostScript primitive
 %   steps, with only the need to convert to \texttt{bp}. Notice that
-%   \texttt{x}-type expansion is included here to ensure that any variable
+%   \texttt{e}-type expansion is included here to ensure that any variable
 %   values are forced to literals before any possible caching. There is
 %   no native rectangular path command (without also clipping, filling or
 %   stroking), so that task is done using a small amount of PostScript.
@@ -327,8 +327,8 @@
 % \end{macro}
 % \end{macro}
 %
-%
-% \begin{macro}{\@@_backend_cm:nnnn}
+% \begin{macro}{\@@_backend_transform:nnnn}
+% \begin{macro}{\@@_backend_shift:nn}
 %   In \texttt{dvips}, keeping the transformations in line with the engine
 %   is unfortunately not possible for scaling and rotations: even if we
 %   decompose the matrix into those operations, there is still no backend
@@ -335,13 +335,19 @@
 %   tracking (\emph{cf.}~\texttt{dvipdfmx}/\XeTeX{}). Thus we take the shortest
 %   path available and simply dump the matrix as given.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \@@_backend_transform:nnnn #1#2#3#4
   {
     \@@_backend_literal:n
       { [ #1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat }
   }
+\cs_new_protected:Npn \@@_backend_shift:nn #1#2
+  {
+    \@@_backend_literal:n
+      { [ 1 ~ 0 ~ 0 ~ 1 ~ #1 ~ #2 ] ~ concat }
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_backend_box_use:Nnnnn}
 %   Inside a picture |@beginspecial|/|@endspecial| are active, which is
@@ -369,9 +375,9 @@
     \@@_backend_literal:n { save }
     \@@_backend_literal:n { currentpoint }
     \@@_backend_literal:n { currentpoint~translate }
-    \@@_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
-    \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
-    \@@_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
+    \@@_backend_transform:nnnn { 1 } { 0 } { 0 } { -1 }
+    \@@_backend_transform:nnnn {#2} {#3} {#4} {#5}
+    \@@_backend_transform:nnnn { 1 } { 0 } { 0 } { -1 }
     \@@_backend_literal:n { neg~exch~neg~exch~translate }
     \@@_backend_literal:n { [end] }
     \hbox_overlap_right:n { \box_use:N #1 }
@@ -403,7 +409,7 @@
 %   Pass data through using a dedicated interface.
 %    \begin{macrocode}
 \cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_pdf:n
-\cs_generate_variant:Nn \@@_backend_literal:n { e }
+\cs_new_eq:NN \@@_backend_literal:e \__kernel_backend_literal_pdf:e
 %    \end{macrocode}
 % \end{macro}
 %
@@ -568,8 +574,9 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\@@_backend_cm:nnnn}
-% \begin{macro}{\@@_backend_cm_aux:nnnn}
+% \begin{macro}{\@@_backend_transform:nnnn}
+% \begin{macro}{\@@_backend_transform_aux:nnnn}
+% \begin{macro}{\@@_backend_shift:nn}
 %   Another split here between \LuaTeX{}/pdfTeX{} and \texttt{dvipdfmx}/\XeTeX{}.
 %   In the former, we have a direct method to maintain alignment: the backend
 %   can use a matrix itself. For \texttt{dvipdfmx}/\XeTeX{}, we can to decompose the
@@ -578,20 +585,30 @@
 %   \texttt{dvipdfmx}/\XeTeX{}, but as a matched pair so not suitable for the
 %   \enquote{stand alone} transformation set up here.) The specials used here
 %   are from \texttt{xdvipdfmx} originally: they are well-tested, but probably
-%   equivalent to the \texttt{pdf:} versions!
+%   equivalent to the \texttt{pdf:} versions! As working out the rotation is
+%   relatively expensive, we optimise for the case where there is only a
+%   scaling.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \@@_backend_transform:nnnn #1#2#3#4
   {
 %<*luatex|pdftex>
     \__kernel_backend_matrix:n { #1 ~ #2 ~ #3 ~ #4 }
 %</luatex|pdftex>
 %<*dvipdfmx|xetex>
-    \@@_backend_cm_decompose:nnnnN {#1} {#2} {#3} {#4}
-      \@@_backend_cm_aux:nnnn
+    \str_if_eq:nnTF { #2 ~ #3 } { 0 ~ 0 }
+      {
+        \__kernel_backend_literal:n { x:rotate~0 }
+        \__kernel_backend_literal:n { x:scale~#1~#4 }
+        \__kernel_backend_literal:n { x:rotate~0 }
+      }
+      {
+        \@@_backend_transform_decompose:nnnnN {#1} {#2} {#3} {#4}
+          \@@_backend_transform_aux:nnnn
+      }
 %</dvipdfmx|xetex>
   }
 %<*dvipdfmx|xetex>
-\cs_new_protected:Npn \@@_backend_cm_aux:nnnn #1#2#3#4
+\cs_new_protected:Npn \@@_backend_transform_aux:nnnn #1#2#3#4
   {
     \__kernel_backend_literal:e
       {
@@ -616,15 +633,26 @@
   }
 %</dvipdfmx|xetex>
 %    \end{macrocode}
+%   Much less complex for a shift: this is deliberately not tracked by the
+%   engine (we would otherwise do stuff in \TeX{}), so use the same approach
+%   for all PDF-based routes.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_shift:nn #1#2
+  {
+    \@@_backend_literal:n
+      { 1 ~ 0 ~ 0 ~ 1 ~ #1 ~ #2 ~ cm }
+  }
+%    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
-% \begin{macro}{\@@_backend_cm_decompose:nnnnN}
+% \begin{macro}{\@@_backend_transform_decompose:nnnnN}
 % \begin{macro}
 %   {
-%     \@@_backend_cm_decompose_auxi:nnnnN,
-%     \@@_backend_cm_decompose_auxii:nnnnN,
-%     \@@_backend_cm_decompose_auxiii:nnnnN,
+%     \@@_backend_transform_decompose_auxi:nnnnN,
+%     \@@_backend_transform_decompose_auxii:nnnnN,
+%     \@@_backend_transform_decompose_auxiii:nnnnN,
 %   }
 %   Internally, transformations for drawing are tracked as a matrix. Not all
 %   engines provide a way of dealing with this: if we use a raw matrix, the
@@ -675,11 +703,11 @@
 %   normally expect $B$ and $C$ to be.
 %    \begin{macrocode}
 %<*dvipdfmx|xetex>
-\cs_new_protected:Npn \@@_backend_cm_decompose:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \@@_backend_transform_decompose:nnnnN #1#2#3#4#5
   {
     \use:e
       {
-        \@@_backend_cm_decompose_auxi:nnnnN
+        \@@_backend_transform_decompose_auxi:nnnnN
           { \fp_eval:n { (#1 + #4) / 2 } }
           { \fp_eval:n { (#1 - #4) / 2 } }
           { \fp_eval:n { (#3 + #2) / 2 } }
@@ -687,11 +715,11 @@
       }
         #5
   }
-\cs_new_protected:Npn \@@_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \@@_backend_transform_decompose_auxi:nnnnN #1#2#3#4#5
   {
     \use:e
       {
-        \@@_backend_cm_decompose_auxii:nnnnN
+        \@@_backend_transform_decompose_auxii:nnnnN
           { \fp_eval:n { 2 * sqrt ( #1 * #1 + #4 * #4 ) } }
           { \fp_eval:n { 2 * sqrt ( #2 * #2 + #3 * #3 ) } }
           { \fp_eval:n { atand ( #3 , #2 ) } }
@@ -699,11 +727,11 @@
       }
         #5
   }
-\cs_new_protected:Npn \@@_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \@@_backend_transform_decompose_auxii:nnnnN #1#2#3#4#5
   {
     \use:e
       {
-        \@@_backend_cm_decompose_auxiii:nnnnN
+        \@@_backend_transform_decompose_auxiii:nnnnN
           { \fp_eval:n { ( #4 - #3 ) / 2 } }
           { \fp_eval:n { ( #1 + #2 ) / 2 } }
           { \fp_eval:n { ( #1 - #2 ) / 2 } }
@@ -711,7 +739,7 @@
       }
         #5
   }
-\cs_new_protected:Npn \@@_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \@@_backend_transform_decompose_auxiii:nnnnN #1#2#3#4#5
   {
     \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
       { #5 {#1} {#2} {#3} {#4} }
@@ -734,7 +762,7 @@
   {
     \__kernel_backend_scope_begin:
 %<*luatex|pdftex>
-    \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
+    \__kernel_backend_matrix:n { #2 ~ #3 ~ #4 ~ #5 }
 %</luatex|pdftex>
 %<*dvipdfmx|xetex>
     \__kernel_backend_literal:n
@@ -798,7 +826,7 @@
 %   collected up before being output in one go. For that we use a dedicated
 %   storage routine, which adds spaces as required. Since paths should
 %   be fully expanded there is no need to worry about the internal
-%   \texttt{x}-type expansion.
+%   \texttt{e}-type expansion.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_backend_moveto:nn #1#2
   {
@@ -1013,11 +1041,12 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\@@_backend_cm:nnnn}
+% \begin{macro}{\@@_backend_transform:nnnn}
+% \begin{macro}{\@@_backend_shift:nn}
 %   The four arguments here are floats (the affine matrix), the last
 %   two are a displacement vector.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \@@_backend_transform:nnnn #1#2#3#4
   {
     \__kernel_backend_scope:n
       {
@@ -1025,8 +1054,17 @@
           " matrix ( #1 , #2 , #3 , #4 , 0pt , 0pt ) "
       }
   }
+\cs_new_protected:Npn \@@_backend_shift:nn #1#2
+  {
+    \__kernel_backend_scope:n
+      {
+        transform =
+          " matrix ( 1 , 0 , 0 , 1 ,  #1pt , #2pt ) "
+      }
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_backend_box_use:Nnnnn}
 %   No special savings can be made here: simply displace the box inside
@@ -1036,7 +1074,7 @@
 \cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
   {
     \__kernel_backend_scope_begin:
-    \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
+    \@@_backend_transform:nnnn {#2} {#3} {#4} {#5}
     \__kernel_backend_literal_svg:n
       {
         < g~

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-graphics.dtx
 %
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %
@@ -60,23 +60,6 @@
 %<@@=graphics>
 %    \end{macrocode}
 %
-% \begin{macro}{\@@_backend_loaded:n}
-%   To deal with file load ordering. Plain users are on their own.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_loaded:n #1
-  {
-    \cs_if_exist:NTF \hook_gput_code:nnn
-      {
-        \hook_gput_code:nnn
-          { package / l3graphics / after }
-          { backend }
-          {#1}
-      }
-      {#1}
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \subsection{\texttt{dvips} backend}
 %
 %    \begin{macrocode}
@@ -85,8 +68,7 @@
 %
 % \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  { \seq_set_from_clist:Nn \l_graphics_search_ext_seq { .eps , .ps } }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq { .eps , .ps }
 %    \end{macrocode}
 % \end{variable}
 %
@@ -93,11 +75,8 @@
 % \begin{macro}{\@@_backend_getbb_eps:n, \@@_backend_getbb_ps:n}
 %   Simply use the generic function.
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  {
-    \cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
-    \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
-  }
+\cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
+\cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
 %    \end{macrocode}
 % \end{macro}
 %
@@ -122,8 +101,7 @@
 %
 % \begin{macro}{\@@_backend_get_pagecount:n}
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+\cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n
 %    \end{macrocode}
 % \end{macro}
 %
@@ -139,12 +117,8 @@
 %
 % \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn
-      \l_graphics_search_ext_seq
-      { .pdf , .eps , .ps , .png , .jpg , .jpeg  }
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .pdf , .eps , .ps , .png , .jpg , .jpeg  }
 %    \end{macrocode}
 % \end{variable}
 %
@@ -378,11 +352,8 @@
 %
 % \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn \l_graphics_search_ext_seq
-      { .pdf , .eps , .ps , .png , .jpg , .jpeg , .bmp }
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .pdf , .eps , .ps , .png , .jpg , .jpeg , .bmp }
 %    \end{macrocode}
 % \end{variable}
 %
@@ -396,11 +367,8 @@
 %   Simply use the generic functions: only for \texttt{dvipdfmx} in the
 %   extraction cases.
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  {
-    \cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
-    \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
-  }
+\cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
+\cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
 %<*dvipdfmx>
 \cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
   {
@@ -543,8 +511,7 @@
 % \begin{macro}{\@@_backend_get_pagecount:n}
 %    \begin{macrocode}
 %<*dvipdfmx>
-\@@_backend_loaded:n
-  { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+\cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n
 %</dvipdfmx>
 %    \end{macrocode}
 % \end{macro}
@@ -688,12 +655,8 @@
 %
 % \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn
-      \l_graphics_search_ext_seq
-      { .svg , .pdf , .eps , .ps , .png , .jpg , .jpeg }
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .svg , .pdf , .eps , .ps , .png , .jpg , .jpeg }
 %    \end{macrocode}
 % \end{variable}
 %
@@ -804,11 +767,8 @@
 % \begin{macro}{\@@_backend_getbb_eps:n, \@@_backend_getbb_ps:n}
 %   Simply use the generic function.
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  {
-    \cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
-    \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
-  }
+\cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
+\cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
 %    \end{macrocode}
 % \end{macro}
 %
@@ -913,8 +873,7 @@
 %
 % \begin{macro}{\@@_backend_get_pagecount:n}
 %    \begin{macrocode}
-\@@_backend_loaded:n
-  { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+\cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n
 %    \end{macrocode}
 % \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-header.dtx
 %
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-opacity.dtx
 %
-% Copyright (C) 2021-2024 The LaTeX Project
+% Copyright (C) 2021-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 %
 %% File: l3backend-pdf.dtx
 %
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-05-08}
+% \date{Released 2025-03-14}
 %
 % \maketitle
 %
@@ -66,25 +66,6 @@
 % significant contributions by Alexander Grahn, in addition to the specific
 % code referenced a various points.
 %
-% \subsection{Shared code}
-%
-% A very small number of items that belong at the backend level but which
-% are common to most backends.
-%
-%    \begin{macrocode}
-%<*!dvisvgm>
-%    \end{macrocode}
-%
-% \begin{variable}{\l_@@_internal_box}
-%    \begin{macrocode}
-\box_new:N \l_@@_internal_box
-%    \end{macrocode}
-% \end{variable}
-%
-%    \begin{macrocode}
-%</!dvisvgm>
-%    \end{macrocode}
-%
 % \subsection{\texttt{dvips} backend}
 %
 %    \begin{macrocode}
@@ -238,371 +219,8 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsubsection{Annotations}
+% \subsubsection{Destinations}
 %
-% In \texttt{dvips}, annotations have to be constructed manually. As such,
-% we need the object code above for some definitions.
-%
-% \begin{variable}{\l_@@_backend_content_box}
-%   The content of an annotation.
-%    \begin{macrocode}
-\box_new:N \l_@@_backend_content_box
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_backend_model_box}
-%   For creating model sizing for links.
-%    \begin{macrocode}
-\box_new:N \l_@@_backend_model_box
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_backend_annotation_int}
-%   Needed as objects which are not annotations could be created.
-%    \begin{macrocode}
-\int_new:N \g_@@_backend_annotation_int
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\@@_backend_annotation:nnnn}
-%   Annotations are objects, but we track them separately. Notably, they are
-%   not in the object data lists. Here, to get the coordinates of the
-%   annotation, we need to have the data collected at the PostScript level.
-%   That requires a bit of box trickery (effectively a \LaTeXe{} |picture|
-%   of zero size). Once the data is collected, use it to set up the annotation
-%   border.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4
-  {
-    \exp_args:Nf \@@_backend_annotation_aux:nnnn
-      { \dim_eval:n {#1} } {#2} {#3} {#4}
-  }
-\cs_new_protected:Npn \@@_backend_annotation_aux:nnnn #1#2#3#4
-  {
-    \box_move_down:nn {#3}
-      { \hbox:n { \__kernel_backend_postscript:n { pdf.save.ll } } }
-    \box_move_up:nn {#2}
-      {
-        \hbox:n
-          {
-            \__kernel_kern:n {#1}
-            \__kernel_backend_postscript:n { pdf.save.ur }
-            \__kernel_kern:n { -#1 }
-          }
-      }
-    \int_gincr:N \g_@@_backend_object_int
-    \int_gset_eq:NN \g_@@_backend_annotation_int \g_@@_backend_object_int
-    \@@_backend_pdfmark:e
-      {
-        /_objdef { pdf.obj \int_use:N \g_@@_backend_object_int }
-        pdf.rect
-        #4 ~
-        /ANN
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_backend_annotation_last:}
-%   Provide the last annotation we created: could get tricky of course if
-%   other packages are loaded.
-%    \begin{macrocode}
-\cs_new:Npn \@@_backend_annotation_last:
-  { { pdf.obj \int_use:N \g_@@_backend_annotation_int } }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{variable}{\g_@@_backend_link_int}
-%   To track annotations which are links.
-%    \begin{macrocode}
-\int_new:N \g_@@_backend_link_int
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_backend_link_dict_tl}
-%   To pass information to the end-of-link function.
-%    \begin{macrocode}
-\tl_new:N \g_@@_backend_link_dict_tl
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_backend_link_sf_int}
-%   Needed to save/restore space factor, which is needed to deal with the face
-%   we need a box.
-%    \begin{macrocode}
-\int_new:N \g_@@_backend_link_sf_int
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_backend_link_math_bool}
-%   Needed to save/restore math mode.
-%    \begin{macrocode}
-\bool_new:N \g_@@_backend_link_math_bool
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_backend_link_bool}
-%   Track link formation: we cannot nest at all.
-%    \begin{macrocode}
-\bool_new:N \g_@@_backend_link_bool
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_breaklink_pdfmark_tl}
-%   Swappable content for link breaking.
-%    \begin{macrocode}
-\tl_new:N \l_@@_breaklink_pdfmark_tl
-\tl_set:Nn \l_@@_breaklink_pdfmark_tl { pdfmark }
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\@@_breaklink_postscript:n}
-%   To allow dropping material unless link breaking is active.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_breaklink_postscript:n #1 { }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_breaklink_usebox:N}
-%   Swappable box unpacking or use.
-%    \begin{macrocode}
-\cs_new_eq:NN \@@_breaklink_usebox:N \box_use:N
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
-% \begin{macro}{\@@_backend_link:nw, \@@_backend_link_aux:nw}
-% \begin{macro}{\@@_backend_link_end:, \@@_backend_link_end_aux:}
-% \begin{macro}{\@@_backend_link_minima:}
-% \begin{macro}{\@@_backend_link_outerbox:n}
-% \begin{macro}{\@@_backend_link_sf_save:, \@@_backend_link_sf_restore:}
-%   Links are created like annotations but with dedicated code to allow for
-%   adjusting the size of the rectangle. In contrast to \pkg{hyperref}, we
-%   grab the link content as a box which can then unbox: this allows the same
-%   interface as for \pdfTeX{}.
-%
-%   Notice that the link setup here uses |/Action| not |/A|. That is because
-%   Distiller \emph{requires} this trigger word, rather than a \enquote{raw}
-%   PDF dictionary key (Ghostscript can handle either form).
-%
-%   Taking the idea of |evenboxes| from \pkg{hypdvips}, we implement a minimum
-%   box height and depth for link placement. This means that \enquote{underlining}
-%   with a hyperlink will generally give an even appearance. However, to ensure
-%   that the full content is always above the link border, we do not allow
-%   this to be negative (contrast \pkg{hypdvips} approach). The result should
-%   be similar to \pdfTeX{} in the vast majority of foreseeable cases.
-%
-%   The object number for a link is saved separately from the rest of the
-%   dictionary as this allows us to insert it just once, at either an
-%   unbroken link or only in the first line of a broken one. That makes the
-%   code clearer but also avoids a low-level PostScript error with the code
-%   as taken from \pkg{hypdvips}.
-%
-%   Getting the outer dimensions of the text area may be better using a two-pass
-%   approach and |\tex_savepos:D|. That plus generic mode are still to re-examine.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
-  {
-    \@@_backend_link_begin:nw
-      { #1 /Subtype /Link /Action << /S /GoTo /D ( #2 ) >> }
-  }
-\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
-  { \@@_backend_link_begin:nw {#1#2} }
-\cs_new_protected:Npn \@@_backend_link_begin:nw #1
-  {
-    \bool_if:NF \g_@@_backend_link_bool
-      { \@@_backend_link_begin_aux:nw {#1} }
-  }
-%    \end{macrocode}
-%   The definition of |pdf.link.dict| here is needed as there is code in the
-%   PostScript headers for breaking links, and that can only work with this
-%   available.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_begin_aux:nw #1
-  {
-    \bool_gset_true:N \g_@@_backend_link_bool
-    \__kernel_backend_postscript:n
-      { /pdf.link.dict ( #1 ) def }
-    \tl_gset:Nn \g_@@_backend_link_dict_tl {#1}
-    \@@_backend_link_sf_save:
-    \mode_if_math:TF
-      { \bool_gset_true:N \g_@@_backend_link_math_bool }
-      { \bool_gset_false:N \g_@@_backend_link_math_bool }
-    \hbox_set:Nw \l_@@_backend_content_box
-      \@@_backend_link_sf_restore:
-      \bool_if:NT \g_@@_backend_link_math_bool
-        { \c_math_toggle_token }
-  }
-\cs_new_protected:Npn \@@_backend_link_end:
-  {
-    \bool_if:NT \g_@@_backend_link_bool
-      { \@@_backend_link_end_aux: }
-  }
-\cs_new_protected:Npn \@@_backend_link_end_aux:
-  {
-      \bool_if:NT \g_@@_backend_link_math_bool
-        { \c_math_toggle_token }
-      \@@_backend_link_sf_save:
-    \hbox_set_end:
-    \@@_backend_link_minima:
-    \hbox_set:Nn \l_@@_backend_model_box { Gg }
-    \exp_args:Ne \@@_backend_link_outerbox:n
-      {
-        \int_if_odd:nTF { \value { page } }
-          { \oddsidemargin }
-          { \evensidemargin }
-      }
-    \box_move_down:nn { \box_dp:N \l_@@_backend_content_box }
-      { \hbox:n { \__kernel_backend_postscript:n { pdf.save.linkll } } }
-    \@@_breaklink_postscript:n { pdf.bordertracking.begin }
-    \@@_breaklink_usebox:N \l_@@_backend_content_box
-    \@@_breaklink_postscript:n { pdf.bordertracking.end }
-    \box_move_up:nn { \box_ht:N \l_@@_backend_content_box }
-      {
-        \hbox:n
-          { \__kernel_backend_postscript:n { pdf.save.linkur } }
-      }
-    \int_gincr:N \g_@@_backend_object_int
-    \int_gset_eq:NN \g_@@_backend_link_int \g_@@_backend_object_int
-    \__kernel_backend_postscript:e
-      {
-        mark
-        /_objdef { pdf.obj \int_use:N \g_@@_backend_link_int }
-        \g_@@_backend_link_dict_tl \c_space_tl
-        pdf.rect
-        /ANN ~ \l_@@_breaklink_pdfmark_tl
-      }
-    \@@_backend_link_sf_restore:
-    \bool_gset_false:N \g_@@_backend_link_bool
-  }
-\cs_new_protected:Npn \@@_backend_link_minima:
-  {
-    \hbox_set:Nn \l_@@_backend_model_box { Gg }
-    \__kernel_backend_postscript:e
-      {
-        /pdf.linkdp.pad ~
-          \dim_to_decimal:n
-            {
-              \dim_max:nn
-                {
-                    \box_dp:N \l_@@_backend_model_box
-                  - \box_dp:N \l_@@_backend_content_box
-                }
-                { 0pt }
-            } ~
-              pdf.pt.dvi ~ def
-        /pdf.linkht.pad ~
-          \dim_to_decimal:n
-            {
-              \dim_max:nn
-                {
-                    \box_ht:N \l_@@_backend_model_box
-                  - \box_ht:N \l_@@_backend_content_box
-                }
-                { 0pt }
-            } ~
-              pdf.pt.dvi ~ def
-      }
-  }
-\cs_new_protected:Npn \@@_backend_link_outerbox:n #1
-  {
-    \__kernel_backend_postscript:e
-      {
-        /pdf.outerbox
-          [
-            \dim_to_decimal:n {#1} ~
-            \dim_to_decimal:n { -\box_dp:N \l_@@_backend_model_box } ~
-            \dim_to_decimal:n { #1 + \textwidth } ~
-            \dim_to_decimal:n { \box_ht:N \l_@@_backend_model_box }
-          ]
-          [ exch { pdf.pt.dvi } forall ] def
-        /pdf.baselineskip ~
-          \dim_to_decimal:n { \tex_baselineskip:D } ~ dup ~ 0 ~ gt
-            { pdf.pt.dvi ~ def }
-            { pop ~ pop }
-          ifelse
-      }
-  }
-\cs_new_protected:Npn \@@_backend_link_sf_save:
-  {
-    \int_gset:Nn \g_@@_backend_link_sf_int
-      {
-        \mode_if_horizontal:TF
-          { \tex_spacefactor:D }
-          { 0 }
-      }
-  }
-\cs_new_protected:Npn \@@_backend_link_sf_restore:
-  {
-    \mode_if_horizontal:T
-      {
-        \int_compare:nNnT \g_@@_backend_link_sf_int > { 0 }
-          { \int_set_eq:NN \tex_spacefactor:D \g_@@_backend_link_sf_int }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%   Hooks to allow link breaking: something will be needed in format mode
-%   at some stage. At present this code is disabled as there is an open
-%   question about the name of the hook: to be resolved at the \LaTeXe{}
-%   end.
-%    \begin{macrocode}
-\use_none:n
-  {
-    \cs_if_exist:NT \@makecol at hook
-      {
-        \tl_put_right:Nn \@makecol at hook
-          {
-            \box_if_empty:NF \l_shipout_box
-              {
-                \vbox_set:Nn \l_shipout_box
-                  {
-                    \__kernel_backend_postscript:n
-                      {
-                        pdf.globaldict /pdf.brokenlink.rect ~ known
-                          { pdf.bordertracking.continue }
-                        if
-                      }
-                    \vbox_unpack_drop:N \l_shipout_box
-                    \__kernel_backend_postscript:n
-                      { pdf.bordertracking.endpage }
-                  }
-              }
-          }
-        \tl_set:Nn \l_@@_breaklink_pdfmark_tl { pdf.pdfmark }
-        \cs_set_eq:NN \@@_breaklink_postscript:n \__kernel_backend_postscript:n
-        \cs_set_eq:NN \@@_breaklink_usebox:N \hbox_unpack:N
-      }
-  }
-%    \end{macrocode}
-%
-% \begin{macro}{\@@_backend_link_last:}
-%   The same as annotations, but with a custom integer.
-%    \begin{macrocode}
-\cs_new:Npn \@@_backend_link_last:
-  { { pdf.obj \int_use:N \g_@@_backend_link_int } }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_margin:n}
-%   Convert to big points and pass to PostScript.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_margin:n #1
-  {
-    \__kernel_backend_postscript:e
-      {
-        /pdf.linkmargin { \dim_to_decimal:n {#1} ~ pdf.pt.dvi } def
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_backend_destination:nn}
 % \begin{macro}{\@@_backend_destination:nnnn, \@@_backend_destination_aux:nnnn}
 %   Here, we need to turn the zoom into a scale. We also need to know where
@@ -753,115 +371,8 @@
 %<*luatex|pdftex>
 %    \end{macrocode}
 %
-% \subsubsection{Annotations}
+% \subsubsection{Destinations}
 %
-% \begin{macro}{\@@_backend_annotation:nnnn}
-%   Simply pass the raw data through, just dealing with evaluation of dimensions.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4
-  {
-%<*luatex>
-    \tex_pdfextension:D annot ~
-%</luatex>
-%<*pdftex>
-    \tex_pdfannot:D
-%</pdftex>
-      width  ~ \dim_eval:n {#1} ~
-      height ~ \dim_eval:n {#2} ~
-      depth  ~ \dim_eval:n {#3} ~
-      {#4}
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_backend_annotation_last:}
-%   A tiny amount of extra data gets added here; we use \texttt{x}-type
-%   expansion to get the space in the right place and form. The \enquote{extra}
-%   space in the \LuaTeX{} version is \emph{required} as it is consumed in
-%   finding the end of the keyword.
-%    \begin{macrocode}
-\cs_new:Npe \@@_backend_annotation_last:
-  {
-    \exp_not:N \int_value:w
-%<*luatex>
-      \exp_not:N \tex_pdffeedback:D lastannot ~
-%</luatex>
-%<*pdftex>
-      \exp_not:N \tex_pdflastannot:D
-%</pdftex>
-      \c_space_tl 0 ~ R
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}
-%   {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
-% \begin{macro}{\@@_backend_link_begin:nnnw}
-% \begin{macro}{\@@_backend_link_end:}
-%   Links are all created using the same internals.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
-  { \@@_backend_link_begin:nnnw {#1} { goto~name } {#2} }
-\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
-  { \@@_backend_link_begin:nnnw {#1} { user } {#2} }
-\cs_new_protected:Npn \@@_backend_link_begin:nnnw #1#2#3
-  {
-%<*luatex>
-    \tex_pdfextension:D startlink ~
-%</luatex>
-%<*pdftex>
-    \tex_pdfstartlink:D
-%</pdftex>
-      attr {#1}
-      #2 {#3}
-  }
-\cs_new_protected:Npn \@@_backend_link_end:
-  {
-%<*luatex>
-    \tex_pdfextension:D endlink \scan_stop:
-%</luatex>
-%<*pdftex>
-    \tex_pdfendlink:D
-%</pdftex>
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_last:}
-%   Formatted for direct use.
-%    \begin{macrocode}
-\cs_new:Npe \@@_backend_link_last:
-  {
-    \exp_not:N \int_value:w
-%<*luatex>
-      \exp_not:N \tex_pdffeedback:D lastlink ~
-%</luatex>
-%<*pdftex>
-      \exp_not:N \tex_pdflastlink:D
-%</pdftex>
-      \c_space_tl 0 ~ R
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_margin:n}
-%   A simple task: pass the data to the primitive.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_margin:n #1
-  {
-%<*luatex>
-    \tex_pdfvariable:D linkmargin
-%</luatex>
-%<*pdftex>
-    \tex_pdflinkmargin:D
-%</pdftex>
-      \dim_eval:n {#1} \scan_stop:
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_backend_destination:nn}
 % \begin{macro}{\@@_backend_destination:nnnn}
 %   A simple task: pass the data to the primitive. The |\scan_stop:| deals
@@ -1314,97 +825,8 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsubsection{Annotations}
+% \subsubsection{Destinations}
 %
-% \begin{variable}{\g_@@_backend_annotation_int}
-%   Needed as objects which are not annotations could be created.
-%    \begin{macrocode}
-\int_new:N \g_@@_backend_annotation_int
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\@@_backend_annotation:nnnn}
-%   Simply pass the raw data through, just dealing with evaluation of dimensions.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4
-  {
-    \int_gincr:N \g_@@_backend_object_int
-    \int_gset_eq:NN \g_@@_backend_annotation_int \g_@@_backend_object_int
-    \@@_backend:e
-      {
-        ann ~ @pdf.obj \int_use:N \g_@@_backend_object_int \c_space_tl
-        width  ~ \dim_eval:n {#1} ~
-        height ~ \dim_eval:n {#2} ~
-        depth  ~ \dim_eval:n {#3} ~
-        << /Type /Annot #4 >>
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_annotation_last:}
-%    \begin{macrocode}
-\cs_new:Npn \@@_backend_annotation_last:
-  { @pdf.obj \int_use:N \g_@@_backend_annotation_int }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{variable}{\g_@@_backend_link_int}
-%   To track annotations which are links.
-%    \begin{macrocode}
-\int_new:N \g_@@_backend_link_int
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}
-%   {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
-% \begin{macro}{\@@_backend_link_begin:n}
-% \begin{macro}{\@@_backend_link_end:}
-%   All created using the same internals.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
-  { \@@_backend_link_begin:n { #1 /Subtype /Link /A << /S /GoTo /D ( #2 ) >> } }
-\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
-  { \@@_backend_link_begin:n {#1#2} }
-\cs_new_protected:Npe \@@_backend_link_begin:n #1
-  {
-    \exp_not:N \int_gincr:N \exp_not:N  \g_@@_backend_link_int
-    \@@_backend:e
-      {
-        bann ~
-        @pdf.lnk
-        \exp_not:N \int_use:N \exp_not:N  \g_@@_backend_link_int
-        \c_space_tl
-        <<
-          /Type /Annot
-          #1
-        >>
-      }
-  }
-\cs_new_protected:Npn \@@_backend_link_end:
-  { \@@_backend:n { eann } }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_last:}
-%   Available using the backend mechanism with a suitably-recent
-%   version.
-%    \begin{macrocode}
-\cs_new:Npn \@@_backend_link_last:
-  { @pdf.lnk \int_use:N \g_@@_backend_link_int }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_margin:n}
-%   Pass to \texttt{dvipdfmx}.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_margin:n #1
-  { \__kernel_backend_literal:e { dvipdfmx:config~g~ \dim_eval:n {#1} } }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_backend_destination:nn}
 % \begin{macro}{\@@_backend_destination:nnnn,\@@_backend_destination_aux:nnnn}
 %   Here, we need to turn the zoom into a scale. The method for \texttt{FitR}
@@ -1544,47 +966,8 @@
 %<*dvisvgm>
 %    \end{macrocode}
 %
-% \subsubsection{Annotations}
+% \subsubsection{Destinations}
 %
-% \begin{macro}{\@@_backend_annotation:nnnn}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4 { }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_backend_annotation_last:}
-%    \begin{macrocode}
-\cs_new:Npn \@@_backend_annotation_last: { }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}
-%   {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
-% \begin{macro}{\@@_backend_link_begin:nnnw}
-% \begin{macro}{\@@_backend_link_end:}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2 { }
-\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2 { }
-\cs_new_protected:Npn \@@_backend_link_begin:nnnw #1#2#3 { }
-\cs_new_protected:Npn \@@_backend_link_end: { }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_last:}
-%    \begin{macrocode}
-\cs_new:Npe \@@_backend_link_last: { }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_link_margin:n}
-%   A simple task: pass the data to the primitive.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_link_margin:n #1 { }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_backend_destination:nn}
 % \begin{macro}{\@@_backend_destination:nnnn}
 %    \begin{macrocode}

Added: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdfannot.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdfannot.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdfannot.dtx	2025-04-08 20:12:26 UTC (rev 74880)
@@ -0,0 +1,787 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-pdfannot.dtx
+%
+% Copyright (C) 2025 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+%    https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+  \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+%   The \pkg{l3backend-pdfannot} module\\ Backend PDF annotation features^^A
+% }
+%
+% \author{^^A
+%  The \LaTeX{} Project\thanks
+%    {^^A
+%      E-mail:
+%        \href{mailto:latex-team at latex-project.org}
+%          {latex-team at latex-project.org}^^A
+%    }^^A
+% }
+%
+% \date{Released 2025-03-14}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-pdfannot} implementation}
+%
+%    \begin{macrocode}
+%<*package>
+%<@@=pdfannot>
+%    \end{macrocode}
+%
+% \subsection{\texttt{dvips} backend}
+%
+%    \begin{macrocode}
+%<*dvips>
+%    \end{macrocode}
+%
+% In \texttt{dvips}, annotations have to be constructed manually. As such,
+% we need the object code above for some definitions. Here, the PostScript
+% uses the \texttt{pdf} namespace: unlike for \pkg{expl3}, we do not really
+% control the namespacing and also have to cut across PDF-related areas.
+%
+% \begin{variable}{\l_@@_backend_content_box}
+%   The content of an annotation.
+%    \begin{macrocode}
+\box_new:N \l_@@_backend_content_box
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_backend_model_box}
+%   For creating model sizing for links.
+%    \begin{macrocode}
+\box_new:N \l_@@_backend_model_box
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_int}
+%   Needed to track annotations.
+%    \begin{macrocode}
+\int_new:N \g_@@_backend_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_generic:nnnn, \@@_backend_generic_aux:nnnn}
+%   Annotations are objects but they are not in the object data lists. Here, to
+%   get the coordinates of the annotation, we need to have the data collected
+%   at the PostScript level. That requires a bit of box trickery (effectively a
+%   \LaTeXe{} |picture| of zero size). Once the data is collected, use it to
+%   set up the annotation border.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_generic:nnnn #1#2#3#4
+  {
+    \exp_args:Nf \@@_backend_generic_aux:nnnn
+      { \dim_eval:n {#1} } {#2} {#3} {#4}
+  }
+\cs_new_protected:Npn \@@_backend_generic_aux:nnnn #1#2#3#4
+  {
+    \box_move_down:nn {#3}
+      { \hbox:n { \__kernel_backend_postscript:n { pdf.save.ll } } }
+    \box_move_up:nn {#2}
+      {
+        \hbox:n
+          {
+            \__kernel_kern:n {#1}
+            \__kernel_backend_postscript:n { pdf.save.ur }
+            \__kernel_kern:n { -#1 }
+          }
+      }
+    \int_gincr:N \g_@@_backend_int
+    \__kernel_backend_postscript:e
+      {
+        mark
+        /_objdef { pdf.annot \int_use:N \g_@@_backend_int }
+        pdf.rect
+        #4 ~
+        /ANN ~
+        pdfmark
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_last:}
+%   Provide the last annotation we created: could get tricky of course if
+%   other packages are loaded.
+%    \begin{macrocode}
+\cs_new:Npn \@@_backend_last:
+  { { pdf.annot \int_use:N \g_@@_backend_int } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_backend_link_int}
+%   To track annotations which are links.
+%    \begin{macrocode}
+\int_new:N \g_@@_backend_link_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_dict_tl}
+%   To pass information to the end-of-link function.
+%    \begin{macrocode}
+\tl_new:N \g_@@_backend_link_dict_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_sf_int}
+%   Needed to save/restore space factor, which is needed to deal with the face
+%   we need a box.
+%    \begin{macrocode}
+\int_new:N \g_@@_backend_link_sf_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_math_bool}
+%   Needed to save/restore math mode.
+%    \begin{macrocode}
+\bool_new:N \g_@@_backend_link_math_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_bool}
+%   Track link formation: we cannot nest at all.
+%    \begin{macrocode}
+\bool_new:N \g_@@_backend_link_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_backend_breaklink_pdfmark_tl}
+%   Swappable content for link breaking.
+%    \begin{macrocode}
+\tl_new:N \l_@@_backend_breaklink_pdfmark_tl
+\tl_set:Nn \l_@@_backend_breaklink_pdfmark_tl { pdfmark }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_breaklink_postscript:n}
+%   To allow dropping material unless link breaking is active.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_breaklink_postscript:n #1 { }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_breaklink_usebox:N}
+%   Swappable box unpacking or use.
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_backend_breaklink_usebox:N \box_use:N
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link:nw, \@@_backend_link_aux:nw}
+% \begin{macro}{\@@_backend_link_end:, \@@_backend_link_end_aux:}
+% \begin{macro}{\@@_backend_link_minima:}
+% \begin{macro}{\@@_backend_link_outerbox:n}
+% \begin{macro}{\@@_backend_link_sf_save:, \@@_backend_link_sf_restore:}
+%   Links are created like annotations but with dedicated code to allow for
+%   adjusting the size of the rectangle. In contrast to \pkg{hyperref}, we
+%   grab the link content as a box which can then unbox: this allows the same
+%   interface as for \pdfTeX{}.
+%
+%   Notice that the link setup here uses |/Action| not |/A|. That is because
+%   Distiller \emph{requires} this trigger word, rather than a \enquote{raw}
+%   PDF dictionary key (Ghostscript can handle either form).
+%
+%   Taking the idea of |evenboxes| from \pkg{hypdvips}, we implement a minimum
+%   box height and depth for link placement. This means that \enquote{underlining}
+%   with a hyperlink will generally give an even appearance. However, to ensure
+%   that the full content is always above the link border, we do not allow
+%   this to be negative (contrast \pkg{hypdvips} approach). The result should
+%   be similar to \pdfTeX{} in the vast majority of foreseeable cases.
+%
+%   The object number for a link is saved separately from the rest of the
+%   dictionary as this allows us to insert it just once, at either an
+%   unbroken link or only in the first line of a broken one. That makes the
+%   code clearer but also avoids a low-level PostScript error with the code
+%   as taken from \pkg{hypdvips}.
+%
+%   Getting the outer dimensions of the text area may be better using a two-pass
+%   approach and |\tex_savepos:D|. That plus generic mode are still to re-examine.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
+  {
+    \@@_backend_link_begin:nw
+      { #1 /Subtype /Link /Action << /S /GoTo /D ( #2 ) >> }
+  }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
+  { \@@_backend_link_begin:nw {#1#2} }
+\cs_new_protected:Npn \@@_backend_link_begin:nw #1
+  {
+    \bool_if:NF \g_@@_backend_link_bool
+      { \@@_backend_link_begin_aux:nw {#1} }
+  }
+%    \end{macrocode}
+%   The definition of |pdf.link.dict| here is needed as there is code in the
+%   PostScript headers for breaking links, and that can only work with this
+%   available.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_aux:nw #1
+  {
+    \bool_gset_true:N \g_@@_backend_link_bool
+    \__kernel_backend_postscript:n
+      { /pdf.link.dict ( #1 ) def }
+    \tl_gset:Nn \g_@@_backend_link_dict_tl {#1}
+    \@@_backend_link_sf_save:
+    \mode_if_math:TF
+      { \bool_gset_true:N \g_@@_backend_link_math_bool }
+      { \bool_gset_false:N \g_@@_backend_link_math_bool }
+    \hbox_set:Nw \l_@@_backend_content_box
+      \@@_backend_link_sf_restore:
+      \bool_if:NT \g_@@_backend_link_math_bool
+        { \c_math_toggle_token }
+  }
+\cs_new_protected:Npn \@@_backend_link_end:
+  {
+    \bool_if:NT \g_@@_backend_link_bool
+      { \@@_backend_link_end_aux: }
+  }
+\cs_new_protected:Npn \@@_backend_link_end_aux:
+  {
+      \bool_if:NT \g_@@_backend_link_math_bool
+        { \c_math_toggle_token }
+      \@@_backend_link_sf_save:
+    \hbox_set_end:
+    \@@_backend_link_minima:
+    \hbox_set:Nn \l_@@_backend_model_box { Gg }
+    \exp_args:Ne \@@_backend_link_outerbox:n
+      {
+        \int_if_odd:nTF { \value { page } }
+          { \oddsidemargin }
+          { \evensidemargin }
+      }
+    \box_move_down:nn { \box_dp:N \l_@@_backend_content_box }
+      { \hbox:n { \__kernel_backend_postscript:n { pdf.save.linkll } } }
+    \@@_backend_breaklink_postscript:n { pdf.bordertracking.begin }
+    \@@_backend_breaklink_usebox:N \l_@@_backend_content_box
+    \@@_backend_breaklink_postscript:n { pdf.bordertracking.end }
+    \box_move_up:nn { \box_ht:N \l_@@_backend_content_box }
+      {
+        \hbox:n
+          { \__kernel_backend_postscript:n { pdf.save.linkur } }
+      }
+    \int_gincr:N \g_@@_backend_int
+    \int_gset_eq:NN \g_@@_backend_link_int \g_@@_backend_int
+    \__kernel_backend_postscript:e
+      {
+        mark
+        /_objdef { pdf.annot \int_use:N \g_@@_backend_link_int }
+        \g_@@_backend_link_dict_tl \c_space_tl
+        pdf.rect
+        /ANN ~ \l_@@_backend_breaklink_pdfmark_tl
+      }
+    \@@_backend_link_sf_restore:
+    \bool_gset_false:N \g_@@_backend_link_bool
+  }
+\cs_new_protected:Npn \@@_backend_link_minima:
+  {
+    \hbox_set:Nn \l_@@_backend_model_box { Gg }
+    \__kernel_backend_postscript:e
+      {
+        /pdf.linkdp.pad ~
+          \dim_to_decimal:n
+            {
+              \dim_max:nn
+                {
+                    \box_dp:N \l_@@_backend_model_box
+                  - \box_dp:N \l_@@_backend_content_box
+                }
+                { 0pt }
+            } ~
+              pdf.pt.dvi ~ def
+        /pdf.linkht.pad ~
+          \dim_to_decimal:n
+            {
+              \dim_max:nn
+                {
+                    \box_ht:N \l_@@_backend_model_box
+                  - \box_ht:N \l_@@_backend_content_box
+                }
+                { 0pt }
+            } ~
+              pdf.pt.dvi ~ def
+      }
+  }
+\cs_new_protected:Npn \@@_backend_link_outerbox:n #1
+  {
+    \__kernel_backend_postscript:e
+      {
+        /pdf.outerbox
+          [
+            \dim_to_decimal:n {#1} ~
+            \dim_to_decimal:n { -\box_dp:N \l_@@_backend_model_box } ~
+            \dim_to_decimal:n { #1 + \textwidth } ~
+            \dim_to_decimal:n { \box_ht:N \l_@@_backend_model_box }
+          ]
+          [ exch { pdf.pt.dvi } forall ] def
+        /pdf.baselineskip ~
+          \dim_to_decimal:n { \tex_baselineskip:D } ~ dup ~ 0 ~ gt
+            { pdf.pt.dvi ~ def }
+            { pop ~ pop }
+          ifelse
+      }
+  }
+\cs_new_protected:Npn \@@_backend_link_sf_save:
+  {
+    \int_gset:Nn \g_@@_backend_link_sf_int
+      {
+        \mode_if_horizontal:TF
+          { \tex_spacefactor:D }
+          { 0 }
+      }
+  }
+\cs_new_protected:Npn \@@_backend_link_sf_restore:
+  {
+    \mode_if_horizontal:T
+      {
+        \int_compare:nNnT \g_@@_backend_link_sf_int > { 0 }
+          { \int_set:Nn \tex_spacefactor:D \g_@@_backend_link_sf_int }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Hooks to allow link breaking: something will be needed in format mode
+% at some stage. At present this code is disabled, pending a decision to
+% activate.
+%    \begin{macrocode}
+\use_none:nnn
+\cs_if_exist:NT \hook_gput_code:nnn
+  {
+    \hook_gput_code:nnn { build/column/after } { backend }
+      {
+        \box_if_empty:NF \l_shipout_box
+          {
+            \vbox_set:Nn \l_shipout_box
+              {
+                \__kernel_backend_postscript:n
+                  {
+                    pdf.globaldict /pdf.brokenlink.rect ~ known
+                      { pdf.bordertracking.continue }
+                    if
+                  }
+                \vbox_unpack_drop:N \l_shipout_box
+                \__kernel_backend_postscript:n
+                  { pdf.bordertracking.endpage }
+              }
+          }
+      }
+    \tl_set:Nn \l_@@_backend_breaklink_pdfmark_tl { pdf.pdfmark }
+    \cs_set_eq:NN \@@_backend_breaklink_postscript:n
+      \__kernel_backend_postscript:n
+    \cs_set_eq:NN \@@_backend_breaklink_usebox:N \hbox_unpack:N
+  }
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_backend_link_last:}
+%   The same as annotations, but with a custom integer.
+%    \begin{macrocode}
+\cs_new:Npn \@@_backend_link_last:
+  { { pdf.annot \int_use:N \g_@@_backend_link_int } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+%   Convert to big points and pass to PostScript.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1
+  {
+    \__kernel_backend_postscript:e
+      {
+        /pdf.linkmargin { \dim_to_decimal:n {#1} ~ pdf.pt.dvi } def
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_on:, \@@_backend_link_off:}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_on:  { }
+\cs_new_protected:Npn \@@_backend_link_off: { }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%</dvips>
+%    \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backend}
+%
+%    \begin{macrocode}
+%<*luatex|pdftex>
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_backend_generic:nnnn}
+%   Simply pass the raw data through, just dealing with evaluation of dimensions.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_generic:nnnn #1#2#3#4
+  {
+%<*luatex>
+    \tex_pdfextension:D annot ~
+%</luatex>
+%<*pdftex>
+    \tex_pdfannot:D
+%</pdftex>
+      width  ~ \dim_eval:n {#1} ~
+      height ~ \dim_eval:n {#2} ~
+      depth  ~ \dim_eval:n {#3} ~
+      {#4}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_last:}
+%   A tiny amount of extra data gets added here; we use \texttt{e}-type
+%   expansion to get the space in the right place and form. The \enquote{extra}
+%   space in the \LuaTeX{} version is \emph{required} as it is consumed in
+%   finding the end of the keyword.
+%    \begin{macrocode}
+\cs_new:Npe \@@_backend_last:
+  {
+    \exp_not:N \int_value:w
+%<*luatex>
+      \exp_not:N \tex_pdffeedback:D lastannot ~
+%</luatex>
+%<*pdftex>
+      \exp_not:N \tex_pdflastannot:D
+%</pdftex>
+      \c_space_tl 0 ~ R
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link_begin:nnnw}
+% \begin{macro}{\@@_backend_link_end:}
+%   Links are all created using the same internals.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
+  { \@@_backend_link_begin:nnnw {#1} { goto~name } {#2} }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
+  { \@@_backend_link_begin:nnnw {#1} { user } {#2} }
+\cs_new_protected:Npn \@@_backend_link_begin:nnnw #1#2#3
+  {
+%<*luatex>
+    \tex_pdfextension:D startlink ~
+%</luatex>
+%<*pdftex>
+    \tex_pdfstartlink:D
+%</pdftex>
+      attr {#1}
+      #2 {#3}
+  }
+\cs_new_protected:Npn \@@_backend_link_end:
+  {
+%<*luatex>
+    \tex_pdfextension:D endlink \scan_stop:
+%</luatex>
+%<*pdftex>
+    \tex_pdfendlink:D
+%</pdftex>
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_last:}
+%   Formatted for direct use.
+%    \begin{macrocode}
+\cs_new:Npe \@@_backend_link_last:
+  {
+    \exp_not:N \int_value:w
+%<*luatex>
+      \exp_not:N \tex_pdffeedback:D lastlink ~
+%</luatex>
+%<*pdftex>
+      \exp_not:N \tex_pdflastlink:D
+%</pdftex>
+      \c_space_tl 0 ~ R
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+%   A simple task: pass the data to the primitive.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1
+  {
+%<*luatex>
+    \tex_pdfvariable:D linkmargin
+%</luatex>
+%<*pdftex>
+    \tex_pdflinkmargin:D
+%</pdftex>
+      \dim_eval:n {#1} \scan_stop:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_on:, \@@_backend_link_off:}
+%   Separate definitions for the two engines.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_on:
+%<*luatex>
+  { \tex_pdfextension:D linkstate 0 ~ }
+%</luatex>
+%<*pdftex>
+   { \tex_pdfrunninglinkon:D }
+%</pdftex>
+\cs_new_protected:Npn \@@_backend_link_off:
+%<*luatex>
+  { \tex_pdfextension:D linkstate 1 ~ }
+%</luatex>
+%<*pdftex>
+  { \tex_pdfrunninglinkoff:D }
+%</pdftex>
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%</luatex|pdftex>
+%    \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx} backend}
+%
+%    \begin{macrocode}
+%<*dvipdfmx|xetex>
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_backend:n, \@@_backend:e}
+%   A generic function for the backend PDF specials
+%    \begin{macrocode}
+\cs_new_protected:Npe \@@_backend:n #1
+  { \__kernel_backend_literal:n { pdf: #1 } }
+\cs_generate_variant:Nn \@@_backend:n { e }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_backend_int}
+%   Annotations are objects: but made with a separate tracker integer.
+%    \begin{macrocode}
+\int_new:N \g_@@_backend_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_generic:nnnn}
+%   Simply pass the raw data through, just dealing with evaluation of dimensions.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_generic:nnnn #1#2#3#4
+  {
+    \int_gincr:N \g_@@_backend_int
+    \@@_backend:e
+      {
+        ann ~ @pdfannot \int_use:N \g_@@_backend_int \c_space_tl
+        width  ~ \dim_eval:n {#1} ~
+        height ~ \dim_eval:n {#2} ~
+        depth  ~ \dim_eval:n {#3} ~
+        << /Type /Annot #4 >>
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_last:}
+%    \begin{macrocode}
+\cs_new:Npn \@@_backend_last:
+  { @pdfannot \int_use:N \g_@@_backend_int }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_backend_link_int}
+%   To track annotations which are links.
+%    \begin{macrocode}
+\int_new:N \g_@@_backend_link_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+%   {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link_begin:n}
+% \begin{macro}{\@@_backend_link_end:}
+%   All created using the same internals.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
+  {
+    \@@_backend_link_begin:n
+      { #1 /Subtype /Link /A << /S /GoTo /D ( #2 ) >> }
+  }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
+  { \@@_backend_link_begin:n {#1#2} }
+\cs_new_protected:Npe \@@_backend_link_begin:n #1
+  {
+    \int_gincr:N \exp_not:N \g_@@_backend_int
+    \int_gset_eq:NN \exp_not:N \g_@@_backend_link_int
+      \exp_not:N \g_@@_backend_int
+    \@@_backend:e
+      {
+        bann ~
+        @pdfannot
+        \exp_not:N \int_use:N \exp_not:N \g_@@_backend_link_int
+        \c_space_tl
+        <<
+          /Type /Annot
+          #1
+        >>
+      }
+  }
+\cs_new_protected:Npn \@@_backend_link_end:
+  { \@@_backend:n { eann } }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_last:}
+%   Available using the backend mechanism with a suitably-recent
+%   version.
+%    \begin{macrocode}
+\cs_new:Npn \@@_backend_link_last:
+  { @pdfannot \int_use:N \g_@@_backend_link_int }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+%   Pass to \texttt{dvipdfmx}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1
+  { \__kernel_backend_literal:e { dvipdfmx:config~g~ \dim_eval:n {#1} } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_on:, \@@_backend_link_off:}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_on:  { \@@_backend:n { link } }
+\cs_new_protected:Npn \@@_backend_link_off: { \@@_backend:n { nolink } }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%</dvipdfmx|xetex>
+%    \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+%    \begin{macrocode}
+%<*dvisvgm>
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_backend_generic:nnnn}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_generic:nnnn #1#2#3#4 { }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_last:}
+%    \begin{macrocode}
+\cs_new:Npn \@@_backend_last: { }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link_begin:nnnw}
+% \begin{macro}{\@@_backend_link_end:}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2 { }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2 { }
+\cs_new_protected:Npn \@@_backend_link_begin:nnnw #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_link_end: { }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_last:}
+%    \begin{macrocode}
+\cs_new:Npe \@@_backend_link_last: { }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1 { }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_on:, \@@_backend_link_off:}
+%   For handling places like headers.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_on:  { }
+\cs_new_protected:Npn \@@_backend_link_off: { }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%</dvisvgm>
+%    \end{macrocode}
+%
+% \subsection{Transitional code}
+%
+% This block is temporary: we have moved the backend functions here to a
+% dedicated prefix. To facilitate that, we turn off DocStrip substitution
+% and handle things manually.
+%
+%    \begin{macrocode}
+%<@@=>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new_eq:NN \__pdf_backend_annotation:nnnn \__pdfannot_backend_generic:nnnn
+\cs_new_eq:NN \__pdf_backend_annotation_last: \__pdfannot_backend_last:
+\clist_map_inline:nn
+  {
+    begin_goto:nnw ,
+    begin_user:nnw ,
+    begin:nnnw     ,
+    end:           ,
+    last:          ,
+    margin:n
+  }
+  { \cs_new_eq:cc { __pdf_backend_link_ #1 } { __pdfannot_backend_link_ #1 } }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%</package>
+%    \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex


Property changes on: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdfannot.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend.ins	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend.ins	2025-04-08 20:12:26 UTC (rev 74880)
@@ -2,7 +2,7 @@
 
 File l3backend.ins
 
-Copyright (C) 2019-2024 The LaTeX Project
+Copyright (C) 2019-2025 The LaTeX Project
 
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -35,7 +35,7 @@
 
 \preamble
 
-Copyright (C) 2019-2024 The LaTeX Project
+Copyright (C) 2019-2025 The LaTeX Project
 
 It may be distributed and/or modified under the conditions of
 the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -64,6 +64,7 @@
         \from{l3backend-draw.dtx}    {package,dvipdfmx}
         \from{l3backend-graphics.dtx}{package,dvipdfmx}
         \from{l3backend-pdf.dtx}     {package,dvipdfmx}
+        \from{l3backend-pdfannot.dtx}{package,dvipdfmx}
         \from{l3backend-opacity.dtx} {package,dvipdfmx}
       }
   }
@@ -77,6 +78,7 @@
         \from{l3backend-draw.dtx}    {package,dvips}
         \from{l3backend-graphics.dtx}{package,dvips}
         \from{l3backend-pdf.dtx}     {package,dvips}
+        \from{l3backend-pdfannot.dtx}{package,dvips}
         \from{l3backend-opacity.dtx} {package,dvips}
       }
     \file{l3backend-dvips.pro}
@@ -94,6 +96,7 @@
         \from{l3backend-draw.dtx}    {package,dvisvgm}
         \from{l3backend-graphics.dtx}{package,dvisvgm}
         \from{l3backend-pdf.dtx}     {package,dvisvgm}
+        \from{l3backend-pdfannot.dtx}{package,dvisvgm}
         \from{l3backend-opacity.dtx} {package,dvisvgm}
       }
   }
@@ -107,6 +110,7 @@
         \from{l3backend-draw.dtx}    {package,luatex}
         \from{l3backend-graphics.dtx}{package,luatex}
         \from{l3backend-pdf.dtx}     {package,luatex}
+        \from{l3backend-pdfannot.dtx}{package,luatex}
         \from{l3backend-opacity.dtx} {package,luatex}
       }
   }
@@ -120,6 +124,7 @@
         \from{l3backend-draw.dtx}    {package,pdftex}
         \from{l3backend-graphics.dtx}{package,pdftex}
         \from{l3backend-pdf.dtx}     {package,pdftex}
+        \from{l3backend-pdfannot.dtx}{package,pdftex}
         \from{l3backend-opacity.dtx} {package,pdftex}
       }
   }
@@ -133,6 +138,7 @@
         \from{l3backend-draw.dtx}    {package,xetex}
         \from{l3backend-graphics.dtx}{package,xetex}
         \from{l3backend-pdf.dtx}     {package,xetex}
+        \from{l3backend-pdfannot.dtx}{package,xetex}
         \from{l3backend-opacity.dtx} {package,xetex}
       }
   }
@@ -142,7 +148,7 @@
 \def\MetaPrefix{--}
 \preamble
 
-Copyright (C) 2023,2024 The LaTeX Project
+Copyright (C) 2023-2025 The LaTeX Project
 
 It may be distributed and/or modified under the conditions of
 the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def	2025-04-08 20:12:26 UTC (rev 74880)
@@ -10,9 +10,10 @@
 %% l3backend-draw.dtx  (with options: `package,dvipdfmx')
 %% l3backend-graphics.dtx  (with options: `package,dvipdfmx')
 %% l3backend-pdf.dtx  (with options: `package,dvipdfmx')
+%% l3backend-pdfannot.dtx  (with options: `package,dvipdfmx')
 %% l3backend-opacity.dtx  (with options: `package,dvipdfmx')
 %% 
-%% Copyright (C) 2019-2024 The LaTeX Project
+%% Copyright (C) 2019-2025 The LaTeX Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -26,7 +27,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvipdfmx.def}{2024-05-08}{}
+  {l3backend-dvipdfmx.def}{2025-03-14}{}
   {L3 backend support: dvipdfmx}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -306,7 +307,7 @@
   }
 %% File: l3backend-draw.dtx
 \cs_new_eq:NN \__draw_backend_literal:n \__kernel_backend_literal_pdf:n
-\cs_generate_variant:Nn \__draw_backend_literal:n { e }
+\cs_new_eq:NN \__draw_backend_literal:e \__kernel_backend_literal_pdf:e
 \cs_new_protected:Npn \__draw_backend_begin:
   { \__draw_backend_scope_begin: }
 \cs_new_protected:Npn \__draw_backend_end:
@@ -402,12 +403,20 @@
   { \__draw_backend_literal:n { 1 ~ j } }
 \cs_new_protected:Npn \__draw_backend_join_bevel:
   { \__draw_backend_literal:n { 2 ~ j } }
-\cs_new_protected:Npn \__draw_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform:nnnn #1#2#3#4
   {
-    \__draw_backend_cm_decompose:nnnnN {#1} {#2} {#3} {#4}
-      \__draw_backend_cm_aux:nnnn
+    \str_if_eq:nnTF { #2 ~ #3 } { 0 ~ 0 }
+      {
+        \__kernel_backend_literal:n { x:rotate~0 }
+        \__kernel_backend_literal:n { x:scale~#1~#4 }
+        \__kernel_backend_literal:n { x:rotate~0 }
+      }
+      {
+        \__draw_backend_transform_decompose:nnnnN {#1} {#2} {#3} {#4}
+          \__draw_backend_transform_aux:nnnn
+      }
   }
-\cs_new_protected:Npn \__draw_backend_cm_aux:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform_aux:nnnn #1#2#3#4
   {
     \__kernel_backend_literal:e
       {
@@ -430,11 +439,16 @@
           { \fp_eval:n { round ( -#4 , 5 ) } }
       }
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_shift:nn #1#2
   {
+    \__draw_backend_literal:n
+      { 1 ~ 0 ~ 0 ~ 1 ~ #1 ~ #2 ~ cm }
+  }
+\cs_new_protected:Npn \__draw_backend_transform_decompose:nnnnN #1#2#3#4#5
+  {
     \use:e
       {
-        \__draw_backend_cm_decompose_auxi:nnnnN
+        \__draw_backend_transform_decompose_auxi:nnnnN
           { \fp_eval:n { (#1 + #4) / 2 } }
           { \fp_eval:n { (#1 - #4) / 2 } }
           { \fp_eval:n { (#3 + #2) / 2 } }
@@ -442,11 +456,11 @@
       }
         #5
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_transform_decompose_auxi:nnnnN #1#2#3#4#5
   {
     \use:e
       {
-        \__draw_backend_cm_decompose_auxii:nnnnN
+        \__draw_backend_transform_decompose_auxii:nnnnN
           { \fp_eval:n { 2 * sqrt ( #1 * #1 + #4 * #4 ) } }
           { \fp_eval:n { 2 * sqrt ( #2 * #2 + #3 * #3 ) } }
           { \fp_eval:n { atand ( #3 , #2 ) } }
@@ -454,11 +468,11 @@
       }
         #5
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_transform_decompose_auxii:nnnnN #1#2#3#4#5
   {
     \use:e
       {
-        \__draw_backend_cm_decompose_auxiii:nnnnN
+        \__draw_backend_transform_decompose_auxiii:nnnnN
           { \fp_eval:n { ( #4 - #3 ) / 2 } }
           { \fp_eval:n { ( #1 + #2 ) / 2 } }
           { \fp_eval:n { ( #1 - #2 ) / 2 } }
@@ -466,7 +480,7 @@
       }
         #5
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_transform_decompose_auxiii:nnnnN #1#2#3#4#5
   {
     \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
       { #5 {#1} {#2} {#3} {#4} }
@@ -482,27 +496,10 @@
     \__kernel_backend_scope_end:
   }
 %% File: l3backend-graphics.dtx
-\cs_new_protected:Npn \__graphics_backend_loaded:n #1
-  {
-    \cs_if_exist:NTF \hook_gput_code:nnn
-      {
-        \hook_gput_code:nnn
-          { package / l3graphics / after }
-          { backend }
-          {#1}
-      }
-      {#1}
-  }
-\__graphics_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn \l_graphics_search_ext_seq
-      { .pdf , .eps , .ps , .png , .jpg , .jpeg , .bmp }
-  }
-\__graphics_backend_loaded:n
-  {
-    \cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
-    \cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .pdf , .eps , .ps , .png , .jpg , .jpeg , .bmp }
+\cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
+\cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
 \cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
   {
     \int_zero:N \l__graphics_page_int
@@ -596,10 +593,8 @@
           }
       }
   }
-\__graphics_backend_loaded:n
-  { \cs_new_eq:NN \__graphics_backend_get_pagecount:n \__graphics_get_pagecount:n }
+\cs_new_eq:NN \__graphics_backend_get_pagecount:n \__graphics_get_pagecount:n
 %% File: l3backend-pdf.dtx
-\box_new:N \l__pdf_internal_box
 \cs_new_protected:Npe \__pdf_backend:n #1
   { \__kernel_backend_literal:n { pdf: #1 } }
 \cs_generate_variant:Nn \__pdf_backend:n { e }
@@ -652,48 +647,6 @@
   { @pdf.obj \int_use:N \g__pdf_backend_object_int }
 \cs_new:Npn \__pdf_backend_pageobject_ref:n #1
   { @page #1 }
-\int_new:N \g__pdf_backend_annotation_int
-\cs_new_protected:Npn \__pdf_backend_annotation:nnnn #1#2#3#4
-  {
-    \int_gincr:N \g__pdf_backend_object_int
-    \int_gset_eq:NN \g__pdf_backend_annotation_int \g__pdf_backend_object_int
-    \__pdf_backend:e
-      {
-        ann ~ @pdf.obj \int_use:N \g__pdf_backend_object_int \c_space_tl
-        width  ~ \dim_eval:n {#1} ~
-        height ~ \dim_eval:n {#2} ~
-        depth  ~ \dim_eval:n {#3} ~
-        << /Type /Annot #4 >>
-      }
-  }
-\cs_new:Npn \__pdf_backend_annotation_last:
-  { @pdf.obj \int_use:N \g__pdf_backend_annotation_int }
-\int_new:N \g__pdf_backend_link_int
-\cs_new_protected:Npn \__pdf_backend_link_begin_goto:nnw #1#2
-  { \__pdf_backend_link_begin:n { #1 /Subtype /Link /A << /S /GoTo /D ( #2 ) >> } }
-\cs_new_protected:Npn \__pdf_backend_link_begin_user:nnw #1#2
-  { \__pdf_backend_link_begin:n {#1#2} }
-\cs_new_protected:Npe \__pdf_backend_link_begin:n #1
-  {
-    \exp_not:N \int_gincr:N \exp_not:N  \g__pdf_backend_link_int
-    \__pdf_backend:e
-      {
-        bann ~
-        @pdf.lnk
-        \exp_not:N \int_use:N \exp_not:N  \g__pdf_backend_link_int
-        \c_space_tl
-        <<
-          /Type /Annot
-          #1
-        >>
-      }
-  }
-\cs_new_protected:Npn \__pdf_backend_link_end:
-  { \__pdf_backend:n { eann } }
-\cs_new:Npn \__pdf_backend_link_last:
-  { @pdf.lnk \int_use:N \g__pdf_backend_link_int }
-\cs_new_protected:Npn \__pdf_backend_link_margin:n #1
-  { \__kernel_backend_literal:e { dvipdfmx:config~g~ \dim_eval:n {#1} } }
 \cs_new_protected:Npn \__pdf_backend_destination:nn #1#2
   {
     \__pdf_backend:e
@@ -789,6 +742,70 @@
           }
       }
   }
+%% File: l3backend-pdfannot.dtx
+\cs_new_protected:Npe \__pdfannot_backend:n #1
+  { \__kernel_backend_literal:n { pdf: #1 } }
+\cs_generate_variant:Nn \__pdfannot_backend:n { e }
+\int_new:N \g__pdfannot_backend_int
+\cs_new_protected:Npn \__pdfannot_backend_generic:nnnn #1#2#3#4
+  {
+    \int_gincr:N \g__pdfannot_backend_int
+    \__pdfannot_backend:e
+      {
+        ann ~ @pdfannot \int_use:N \g__pdfannot_backend_int \c_space_tl
+        width  ~ \dim_eval:n {#1} ~
+        height ~ \dim_eval:n {#2} ~
+        depth  ~ \dim_eval:n {#3} ~
+        << /Type /Annot #4 >>
+      }
+  }
+\cs_new:Npn \__pdfannot_backend_last:
+  { @pdfannot \int_use:N \g__pdfannot_backend_int }
+\int_new:N \g__pdfannot_backend_link_int
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_goto:nnw #1#2
+  {
+    \__pdfannot_backend_link_begin:n
+      { #1 /Subtype /Link /A << /S /GoTo /D ( #2 ) >> }
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_user:nnw #1#2
+  { \__pdfannot_backend_link_begin:n {#1#2} }
+\cs_new_protected:Npe \__pdfannot_backend_link_begin:n #1
+  {
+    \int_gincr:N \exp_not:N \g__pdfannot_backend_int
+    \int_gset_eq:NN \exp_not:N \g__pdfannot_backend_link_int
+      \exp_not:N \g__pdfannot_backend_int
+    \__pdfannot_backend:e
+      {
+        bann ~
+        @pdfannot
+        \exp_not:N \int_use:N \exp_not:N \g__pdfannot_backend_link_int
+        \c_space_tl
+        <<
+          /Type /Annot
+          #1
+        >>
+      }
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_end:
+  { \__pdfannot_backend:n { eann } }
+\cs_new:Npn \__pdfannot_backend_link_last:
+  { @pdfannot \int_use:N \g__pdfannot_backend_link_int }
+\cs_new_protected:Npn \__pdfannot_backend_link_margin:n #1
+  { \__kernel_backend_literal:e { dvipdfmx:config~g~ \dim_eval:n {#1} } }
+\cs_new_protected:Npn \__pdfannot_backend_link_on:  { \__pdfannot_backend:n { link } }
+\cs_new_protected:Npn \__pdfannot_backend_link_off: { \__pdfannot_backend:n { nolink } }
+\cs_new_eq:NN \__pdf_backend_annotation:nnnn \__pdfannot_backend_generic:nnnn
+\cs_new_eq:NN \__pdf_backend_annotation_last: \__pdfannot_backend_last:
+\clist_map_inline:nn
+  {
+    begin_goto:nnw ,
+    begin_user:nnw ,
+    begin:nnnw     ,
+    end:           ,
+    last:          ,
+    margin:n
+  }
+  { \cs_new_eq:cc { __pdf_backend_link_ #1 } { __pdfannot_backend_link_ #1 } }
 %% File: l3backend-opacity.dtx
 \bool_lazy_and:nnT
   { \cs_if_exist_p:N \pdfmanagement_if_active_p: }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def	2025-04-08 20:12:26 UTC (rev 74880)
@@ -10,9 +10,10 @@
 %% l3backend-draw.dtx  (with options: `package,dvips')
 %% l3backend-graphics.dtx  (with options: `package,dvips')
 %% l3backend-pdf.dtx  (with options: `package,dvips')
+%% l3backend-pdfannot.dtx  (with options: `package,dvips')
 %% l3backend-opacity.dtx  (with options: `package,dvips')
 %% 
-%% Copyright (C) 2019-2024 The LaTeX Project
+%% Copyright (C) 2019-2025 The LaTeX Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -26,7 +27,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvips.def}{2024-05-08}{}
+  {l3backend-dvips.def}{2025-03-14}{}
   {L3 backend support: dvips}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -553,11 +554,16 @@
   { \__draw_backend_literal:n { 1 ~ setlinejoin } }
 \cs_new_protected:Npn \__draw_backend_join_bevel:
   { \__draw_backend_literal:n { 2 ~ setlinejoin } }
-\cs_new_protected:Npn \__draw_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform:nnnn #1#2#3#4
   {
     \__draw_backend_literal:n
       { [ #1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat }
   }
+\cs_new_protected:Npn \__draw_backend_shift:nn #1#2
+  {
+    \__draw_backend_literal:n
+      { [ 1 ~ 0 ~ 0 ~ 1 ~ #1 ~ #2 ] ~ concat }
+  }
 \cs_new_protected:Npn \__draw_backend_box_use:Nnnnn #1#2#3#4#5
   {
     \__draw_backend_literal:n { save }
@@ -569,9 +575,9 @@
     \__draw_backend_literal:n { save }
     \__draw_backend_literal:n { currentpoint }
     \__draw_backend_literal:n { currentpoint~translate }
-    \__draw_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
-    \__draw_backend_cm:nnnn {#2} {#3} {#4} {#5}
-    \__draw_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
+    \__draw_backend_transform:nnnn { 1 } { 0 } { 0 } { -1 }
+    \__draw_backend_transform:nnnn {#2} {#3} {#4} {#5}
+    \__draw_backend_transform:nnnn { 1 } { 0 } { 0 } { -1 }
     \__draw_backend_literal:n { neg~exch~neg~exch~translate }
     \__draw_backend_literal:n { [end] }
     \hbox_overlap_right:n { \box_use:N #1 }
@@ -582,24 +588,9 @@
     \__draw_backend_literal:n { restore }
   }
 %% File: l3backend-graphics.dtx
-\cs_new_protected:Npn \__graphics_backend_loaded:n #1
-  {
-    \cs_if_exist:NTF \hook_gput_code:nnn
-      {
-        \hook_gput_code:nnn
-          { package / l3graphics / after }
-          { backend }
-          {#1}
-      }
-      {#1}
-  }
-\__graphics_backend_loaded:n
-  { \seq_set_from_clist:Nn \l_graphics_search_ext_seq { .eps , .ps } }
-\__graphics_backend_loaded:n
-  {
-    \cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
-    \cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq { .eps , .ps }
+\cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
+\cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
 \cs_new_protected:Npn \__graphics_backend_include_eps:n #1
   {
     \__kernel_backend_literal:e
@@ -612,10 +603,8 @@
       }
   }
 \cs_new_eq:NN \__graphics_backend_include_ps:n \__graphics_backend_include_eps:n
-\__graphics_backend_loaded:n
-  { \cs_new_eq:NN \__graphics_backend_get_pagecount:n \__graphics_get_pagecount:n }
+\cs_new_eq:NN \__graphics_backend_get_pagecount:n \__graphics_get_pagecount:n
 %% File: l3backend-pdf.dtx
-\box_new:N \l__pdf_internal_box
 \cs_new_protected:Npn \__pdf_backend_pdfmark:n #1
   { \__kernel_backend_postscript:n { mark #1 ~ pdfmark } }
 \cs_generate_variant:Nn \__pdf_backend_pdfmark:n { e }
@@ -701,15 +690,123 @@
   { { pdf.obj \int_use:N \g__pdf_backend_object_int } }
 \cs_new:Npn \__pdf_backend_pageobject_ref:n #1
   { { Page #1 } }
-\box_new:N \l__pdf_backend_content_box
-\box_new:N \l__pdf_backend_model_box
-\int_new:N \g__pdf_backend_annotation_int
-\cs_new_protected:Npn \__pdf_backend_annotation:nnnn #1#2#3#4
+\cs_new_protected:Npn \__pdf_backend_destination:nn #1#2
   {
-    \exp_args:Nf \__pdf_backend_annotation_aux:nnnn
+    \__kernel_backend_postscript:n { pdf.dest.anchor }
+    \__pdf_backend_pdfmark:e
+      {
+        /View
+        [
+          \str_case:nnF {#2}
+            {
+              { xyz }   { /XYZ ~ pdf.dest.point ~ null }
+              { fit }   { /Fit }
+              { fitb }  { /FitB }
+              { fitbh } { /FitBH ~ pdf.dest.y }
+              { fitbv } { /FitBV ~ pdf.dest.x }
+              { fith }  { /FitH ~ pdf.dest.y }
+              { fitv }  { /FitV ~ pdf.dest.x }
+              { fitr }  { /Fit }
+            }
+            {
+              /XYZ ~ pdf.dest.point ~ \fp_eval:n { (#2) / 100 }
+            }
+        ]
+        /Dest ( \exp_not:n {#1} ) cvn
+        /DEST
+      }
+  }
+\cs_new_protected:Npn \__pdf_backend_destination:nnnn #1#2#3#4
+  {
+    \exp_args:Ne \__pdf_backend_destination_aux:nnnn
+      { \dim_eval:n {#2} } {#1} {#3} {#4}
+  }
+\cs_new_protected:Npn \__pdf_backend_destination_aux:nnnn #1#2#3#4
+  {
+    \vbox_to_zero:n
+      {
+        \__kernel_kern:n {#4}
+        \hbox:n { \__kernel_backend_postscript:n { pdf.save.ll } }
+        \tex_vss:D
+      }
+    \__kernel_kern:n {#1}
+    \vbox_to_zero:n
+      {
+        \__kernel_kern:n { -#3 }
+        \hbox:n { \__kernel_backend_postscript:n { pdf.save.ur } }
+        \tex_vss:D
+      }
+    \__kernel_kern:n { -#1 }
+    \__pdf_backend_pdfmark:n
+      {
+        /View
+        [
+          /FitR ~
+            pdf.llx ~ pdf.lly ~ pdf.dest2device ~
+            pdf.urx ~ pdf.ury ~ pdf.dest2device
+        ]
+        /Dest ( #2 ) cvn
+        /DEST
+      }
+  }
+\cs_new_protected:Npn \__pdf_backend_compresslevel:n #1
+  {
+    \int_compare:nNnT {#1} = 0
+      {
+        \__kernel_backend_literal_postscript:n
+          {
+            /setdistillerparams ~ where
+              { pop << /CompressPages ~ false >> setdistillerparams }
+            if
+          }
+      }
+  }
+\cs_new_protected:Npn \__pdf_backend_compress_objects:n #1
+  {
+    \bool_if:nF {#1}
+      {
+        \__kernel_backend_literal_postscript:n
+          {
+            /setdistillerparams ~ where
+              { pop << /CompressStreams ~ false >> setdistillerparams }
+            if
+          }
+      }
+  }
+\cs_new_protected:Npn \__pdf_backend_version_major_gset:n #1
+  {
+    \cs_gset:Npe \__pdf_backend_version_major: { \int_eval:n {#1} }
+  }
+\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1
+  {
+    \cs_gset:Npe \__pdf_backend_version_minor: { \int_eval:n {#1} }
+  }
+\cs_new:Npn \__pdf_backend_version_major: { -1 }
+\cs_new:Npn \__pdf_backend_version_minor: { -1 }
+\cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2
+  { \__pdf_backend_pdfmark:n { /#1 ~ #2 /BDC } }
+\cs_new_protected:Npn \__pdf_backend_emc:
+  { \__pdf_backend_pdfmark:n { /EMC } }
+\cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2
+  {
+    \__kernel_backend_first_shipout:n
+      {
+        \__kernel_backend_literal:e
+          {
+            papersize = \dim_eval:n {#1} , \dim_eval:n {#2}
+          }
+      }
+  }
+%% File: l3backend-pdfannot.dtx
+\box_new:N \l__pdfannot_backend_content_box
+\box_new:N \l__pdfannot_backend_model_box
+\int_new:N \g__pdfannot_backend_int
+\cs_new_protected:Npn \__pdfannot_backend_generic:nnnn #1#2#3#4
+  {
+    \exp_args:Nf \__pdfannot_backend_generic_aux:nnnn
       { \dim_eval:n {#1} } {#2} {#3} {#4}
   }
-\cs_new_protected:Npn \__pdf_backend_annotation_aux:nnnn #1#2#3#4
+\cs_new_protected:Npn \__pdfannot_backend_generic_aux:nnnn #1#2#3#4
   {
     \box_move_down:nn {#3}
       { \hbox:n { \__kernel_backend_postscript:n { pdf.save.ll } } }
@@ -722,99 +819,100 @@
             \__kernel_kern:n { -#1 }
           }
       }
-    \int_gincr:N \g__pdf_backend_object_int
-    \int_gset_eq:NN \g__pdf_backend_annotation_int \g__pdf_backend_object_int
-    \__pdf_backend_pdfmark:e
+    \int_gincr:N \g__pdfannot_backend_int
+    \__kernel_backend_postscript:e
       {
-        /_objdef { pdf.obj \int_use:N \g__pdf_backend_object_int }
+        mark
+        /_objdef { pdf.annot \int_use:N \g__pdfannot_backend_int }
         pdf.rect
         #4 ~
-        /ANN
+        /ANN ~
+        pdfmark
       }
   }
-\cs_new:Npn \__pdf_backend_annotation_last:
-  { { pdf.obj \int_use:N \g__pdf_backend_annotation_int } }
-\int_new:N \g__pdf_backend_link_int
-\tl_new:N \g__pdf_backend_link_dict_tl
-\int_new:N \g__pdf_backend_link_sf_int
-\bool_new:N \g__pdf_backend_link_math_bool
-\bool_new:N \g__pdf_backend_link_bool
-\tl_new:N \l__pdf_breaklink_pdfmark_tl
-\tl_set:Nn \l__pdf_breaklink_pdfmark_tl { pdfmark }
-\cs_new_protected:Npn \__pdf_breaklink_postscript:n #1 { }
-\cs_new_eq:NN \__pdf_breaklink_usebox:N \box_use:N
-\cs_new_protected:Npn \__pdf_backend_link_begin_goto:nnw #1#2
+\cs_new:Npn \__pdfannot_backend_last:
+  { { pdf.annot \int_use:N \g__pdfannot_backend_int } }
+\int_new:N \g__pdfannot_backend_link_int
+\tl_new:N \g__pdfannot_backend_link_dict_tl
+\int_new:N \g__pdfannot_backend_link_sf_int
+\bool_new:N \g__pdfannot_backend_link_math_bool
+\bool_new:N \g__pdfannot_backend_link_bool
+\tl_new:N \l__pdfannot_backend_breaklink_pdfmark_tl
+\tl_set:Nn \l__pdfannot_backend_breaklink_pdfmark_tl { pdfmark }
+\cs_new_protected:Npn \__pdfannot_backend_breaklink_postscript:n #1 { }
+\cs_new_eq:NN \__pdfannot_backend_breaklink_usebox:N \box_use:N
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_goto:nnw #1#2
   {
-    \__pdf_backend_link_begin:nw
+    \__pdfannot_backend_link_begin:nw
       { #1 /Subtype /Link /Action << /S /GoTo /D ( #2 ) >> }
   }
-\cs_new_protected:Npn \__pdf_backend_link_begin_user:nnw #1#2
-  { \__pdf_backend_link_begin:nw {#1#2} }
-\cs_new_protected:Npn \__pdf_backend_link_begin:nw #1
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_user:nnw #1#2
+  { \__pdfannot_backend_link_begin:nw {#1#2} }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin:nw #1
   {
-    \bool_if:NF \g__pdf_backend_link_bool
-      { \__pdf_backend_link_begin_aux:nw {#1} }
+    \bool_if:NF \g__pdfannot_backend_link_bool
+      { \__pdfannot_backend_link_begin_aux:nw {#1} }
   }
-\cs_new_protected:Npn \__pdf_backend_link_begin_aux:nw #1
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_aux:nw #1
   {
-    \bool_gset_true:N \g__pdf_backend_link_bool
+    \bool_gset_true:N \g__pdfannot_backend_link_bool
     \__kernel_backend_postscript:n
       { /pdf.link.dict ( #1 ) def }
-    \tl_gset:Nn \g__pdf_backend_link_dict_tl {#1}
-    \__pdf_backend_link_sf_save:
+    \tl_gset:Nn \g__pdfannot_backend_link_dict_tl {#1}
+    \__pdfannot_backend_link_sf_save:
     \mode_if_math:TF
-      { \bool_gset_true:N \g__pdf_backend_link_math_bool }
-      { \bool_gset_false:N \g__pdf_backend_link_math_bool }
-    \hbox_set:Nw \l__pdf_backend_content_box
-      \__pdf_backend_link_sf_restore:
-      \bool_if:NT \g__pdf_backend_link_math_bool
+      { \bool_gset_true:N \g__pdfannot_backend_link_math_bool }
+      { \bool_gset_false:N \g__pdfannot_backend_link_math_bool }
+    \hbox_set:Nw \l__pdfannot_backend_content_box
+      \__pdfannot_backend_link_sf_restore:
+      \bool_if:NT \g__pdfannot_backend_link_math_bool
         { \c_math_toggle_token }
   }
-\cs_new_protected:Npn \__pdf_backend_link_end:
+\cs_new_protected:Npn \__pdfannot_backend_link_end:
   {
-    \bool_if:NT \g__pdf_backend_link_bool
-      { \__pdf_backend_link_end_aux: }
+    \bool_if:NT \g__pdfannot_backend_link_bool
+      { \__pdfannot_backend_link_end_aux: }
   }
-\cs_new_protected:Npn \__pdf_backend_link_end_aux:
+\cs_new_protected:Npn \__pdfannot_backend_link_end_aux:
   {
-      \bool_if:NT \g__pdf_backend_link_math_bool
+      \bool_if:NT \g__pdfannot_backend_link_math_bool
         { \c_math_toggle_token }
-      \__pdf_backend_link_sf_save:
+      \__pdfannot_backend_link_sf_save:
     \hbox_set_end:
-    \__pdf_backend_link_minima:
-    \hbox_set:Nn \l__pdf_backend_model_box { Gg }
-    \exp_args:Ne \__pdf_backend_link_outerbox:n
+    \__pdfannot_backend_link_minima:
+    \hbox_set:Nn \l__pdfannot_backend_model_box { Gg }
+    \exp_args:Ne \__pdfannot_backend_link_outerbox:n
       {
         \int_if_odd:nTF { \value { page } }
           { \oddsidemargin }
           { \evensidemargin }
       }
-    \box_move_down:nn { \box_dp:N \l__pdf_backend_content_box }
+    \box_move_down:nn { \box_dp:N \l__pdfannot_backend_content_box }
       { \hbox:n { \__kernel_backend_postscript:n { pdf.save.linkll } } }
-    \__pdf_breaklink_postscript:n { pdf.bordertracking.begin }
-    \__pdf_breaklink_usebox:N \l__pdf_backend_content_box
-    \__pdf_breaklink_postscript:n { pdf.bordertracking.end }
-    \box_move_up:nn { \box_ht:N \l__pdf_backend_content_box }
+    \__pdfannot_backend_breaklink_postscript:n { pdf.bordertracking.begin }
+    \__pdfannot_backend_breaklink_usebox:N \l__pdfannot_backend_content_box
+    \__pdfannot_backend_breaklink_postscript:n { pdf.bordertracking.end }
+    \box_move_up:nn { \box_ht:N \l__pdfannot_backend_content_box }
       {
         \hbox:n
           { \__kernel_backend_postscript:n { pdf.save.linkur } }
       }
-    \int_gincr:N \g__pdf_backend_object_int
-    \int_gset_eq:NN \g__pdf_backend_link_int \g__pdf_backend_object_int
+    \int_gincr:N \g__pdfannot_backend_int
+    \int_gset_eq:NN \g__pdfannot_backend_link_int \g__pdfannot_backend_int
     \__kernel_backend_postscript:e
       {
         mark
-        /_objdef { pdf.obj \int_use:N \g__pdf_backend_link_int }
-        \g__pdf_backend_link_dict_tl \c_space_tl
+        /_objdef { pdf.annot \int_use:N \g__pdfannot_backend_link_int }
+        \g__pdfannot_backend_link_dict_tl \c_space_tl
         pdf.rect
-        /ANN ~ \l__pdf_breaklink_pdfmark_tl
+        /ANN ~ \l__pdfannot_backend_breaklink_pdfmark_tl
       }
-    \__pdf_backend_link_sf_restore:
-    \bool_gset_false:N \g__pdf_backend_link_bool
+    \__pdfannot_backend_link_sf_restore:
+    \bool_gset_false:N \g__pdfannot_backend_link_bool
   }
-\cs_new_protected:Npn \__pdf_backend_link_minima:
+\cs_new_protected:Npn \__pdfannot_backend_link_minima:
   {
-    \hbox_set:Nn \l__pdf_backend_model_box { Gg }
+    \hbox_set:Nn \l__pdfannot_backend_model_box { Gg }
     \__kernel_backend_postscript:e
       {
         /pdf.linkdp.pad ~
@@ -822,8 +920,8 @@
             {
               \dim_max:nn
                 {
-                    \box_dp:N \l__pdf_backend_model_box
-                  - \box_dp:N \l__pdf_backend_content_box
+                    \box_dp:N \l__pdfannot_backend_model_box
+                  - \box_dp:N \l__pdfannot_backend_content_box
                 }
                 { 0pt }
             } ~
@@ -833,8 +931,8 @@
             {
               \dim_max:nn
                 {
-                    \box_ht:N \l__pdf_backend_model_box
-                  - \box_ht:N \l__pdf_backend_content_box
+                    \box_ht:N \l__pdfannot_backend_model_box
+                  - \box_ht:N \l__pdfannot_backend_content_box
                 }
                 { 0pt }
             } ~
@@ -841,7 +939,7 @@
               pdf.pt.dvi ~ def
       }
   }
-\cs_new_protected:Npn \__pdf_backend_link_outerbox:n #1
+\cs_new_protected:Npn \__pdfannot_backend_link_outerbox:n #1
   {
     \__kernel_backend_postscript:e
       {
@@ -848,9 +946,9 @@
         /pdf.outerbox
           [
             \dim_to_decimal:n {#1} ~
-            \dim_to_decimal:n { -\box_dp:N \l__pdf_backend_model_box } ~
+            \dim_to_decimal:n { -\box_dp:N \l__pdfannot_backend_model_box } ~
             \dim_to_decimal:n { #1 + \textwidth } ~
-            \dim_to_decimal:n { \box_ht:N \l__pdf_backend_model_box }
+            \dim_to_decimal:n { \box_ht:N \l__pdfannot_backend_model_box }
           ]
           [ exch { pdf.pt.dvi } forall ] def
         /pdf.baselineskip ~
@@ -860,9 +958,9 @@
           ifelse
       }
   }
-\cs_new_protected:Npn \__pdf_backend_link_sf_save:
+\cs_new_protected:Npn \__pdfannot_backend_link_sf_save:
   {
-    \int_gset:Nn \g__pdf_backend_link_sf_int
+    \int_gset:Nn \g__pdfannot_backend_link_sf_int
       {
         \mode_if_horizontal:TF
           { \tex_spacefactor:D }
@@ -869,44 +967,43 @@
           { 0 }
       }
   }
-\cs_new_protected:Npn \__pdf_backend_link_sf_restore:
+\cs_new_protected:Npn \__pdfannot_backend_link_sf_restore:
   {
     \mode_if_horizontal:T
       {
-        \int_compare:nNnT \g__pdf_backend_link_sf_int > { 0 }
-          { \int_set_eq:NN \tex_spacefactor:D \g__pdf_backend_link_sf_int }
+        \int_compare:nNnT \g__pdfannot_backend_link_sf_int > { 0 }
+          { \int_set:Nn \tex_spacefactor:D \g__pdfannot_backend_link_sf_int }
       }
   }
-\use_none:n
+\use_none:nnn
+\cs_if_exist:NT \hook_gput_code:nnn
   {
-    \cs_if_exist:NT \@makecol at hook
+    \hook_gput_code:nnn { build/column/after } { backend }
       {
-        \tl_put_right:Nn \@makecol at hook
+        \box_if_empty:NF \l_shipout_box
           {
-            \box_if_empty:NF \l_shipout_box
+            \vbox_set:Nn \l_shipout_box
               {
-                \vbox_set:Nn \l_shipout_box
+                \__kernel_backend_postscript:n
                   {
-                    \__kernel_backend_postscript:n
-                      {
-                        pdf.globaldict /pdf.brokenlink.rect ~ known
-                          { pdf.bordertracking.continue }
-                        if
-                      }
-                    \vbox_unpack_drop:N \l_shipout_box
-                    \__kernel_backend_postscript:n
-                      { pdf.bordertracking.endpage }
+                    pdf.globaldict /pdf.brokenlink.rect ~ known
+                      { pdf.bordertracking.continue }
+                    if
                   }
+                \vbox_unpack_drop:N \l_shipout_box
+                \__kernel_backend_postscript:n
+                  { pdf.bordertracking.endpage }
               }
           }
-        \tl_set:Nn \l__pdf_breaklink_pdfmark_tl { pdf.pdfmark }
-        \cs_set_eq:NN \__pdf_breaklink_postscript:n \__kernel_backend_postscript:n
-        \cs_set_eq:NN \__pdf_breaklink_usebox:N \hbox_unpack:N
       }
+    \tl_set:Nn \l__pdfannot_backend_breaklink_pdfmark_tl { pdf.pdfmark }
+    \cs_set_eq:NN \__pdfannot_backend_breaklink_postscript:n
+      \__kernel_backend_postscript:n
+    \cs_set_eq:NN \__pdfannot_backend_breaklink_usebox:N \hbox_unpack:N
   }
-\cs_new:Npn \__pdf_backend_link_last:
-  { { pdf.obj \int_use:N \g__pdf_backend_link_int } }
-\cs_new_protected:Npn \__pdf_backend_link_margin:n #1
+\cs_new:Npn \__pdfannot_backend_link_last:
+  { { pdf.annot \int_use:N \g__pdfannot_backend_link_int } }
+\cs_new_protected:Npn \__pdfannot_backend_link_margin:n #1
   {
     \__kernel_backend_postscript:e
       {
@@ -913,113 +1010,20 @@
         /pdf.linkmargin { \dim_to_decimal:n {#1} ~ pdf.pt.dvi } def
       }
   }
-\cs_new_protected:Npn \__pdf_backend_destination:nn #1#2
+\cs_new_protected:Npn \__pdfannot_backend_link_on:  { }
+\cs_new_protected:Npn \__pdfannot_backend_link_off: { }
+\cs_new_eq:NN \__pdf_backend_annotation:nnnn \__pdfannot_backend_generic:nnnn
+\cs_new_eq:NN \__pdf_backend_annotation_last: \__pdfannot_backend_last:
+\clist_map_inline:nn
   {
-    \__kernel_backend_postscript:n { pdf.dest.anchor }
-    \__pdf_backend_pdfmark:e
-      {
-        /View
-        [
-          \str_case:nnF {#2}
-            {
-              { xyz }   { /XYZ ~ pdf.dest.point ~ null }
-              { fit }   { /Fit }
-              { fitb }  { /FitB }
-              { fitbh } { /FitBH ~ pdf.dest.y }
-              { fitbv } { /FitBV ~ pdf.dest.x }
-              { fith }  { /FitH ~ pdf.dest.y }
-              { fitv }  { /FitV ~ pdf.dest.x }
-              { fitr }  { /Fit }
-            }
-            {
-              /XYZ ~ pdf.dest.point ~ \fp_eval:n { (#2) / 100 }
-            }
-        ]
-        /Dest ( \exp_not:n {#1} ) cvn
-        /DEST
-      }
+    begin_goto:nnw ,
+    begin_user:nnw ,
+    begin:nnnw     ,
+    end:           ,
+    last:          ,
+    margin:n
   }
-\cs_new_protected:Npn \__pdf_backend_destination:nnnn #1#2#3#4
-  {
-    \exp_args:Ne \__pdf_backend_destination_aux:nnnn
-      { \dim_eval:n {#2} } {#1} {#3} {#4}
-  }
-\cs_new_protected:Npn \__pdf_backend_destination_aux:nnnn #1#2#3#4
-  {
-    \vbox_to_zero:n
-      {
-        \__kernel_kern:n {#4}
-        \hbox:n { \__kernel_backend_postscript:n { pdf.save.ll } }
-        \tex_vss:D
-      }
-    \__kernel_kern:n {#1}
-    \vbox_to_zero:n
-      {
-        \__kernel_kern:n { -#3 }
-        \hbox:n { \__kernel_backend_postscript:n { pdf.save.ur } }
-        \tex_vss:D
-      }
-    \__kernel_kern:n { -#1 }
-    \__pdf_backend_pdfmark:n
-      {
-        /View
-        [
-          /FitR ~
-            pdf.llx ~ pdf.lly ~ pdf.dest2device ~
-            pdf.urx ~ pdf.ury ~ pdf.dest2device
-        ]
-        /Dest ( #2 ) cvn
-        /DEST
-      }
-  }
-\cs_new_protected:Npn \__pdf_backend_compresslevel:n #1
-  {
-    \int_compare:nNnT {#1} = 0
-      {
-        \__kernel_backend_literal_postscript:n
-          {
-            /setdistillerparams ~ where
-              { pop << /CompressPages ~ false >> setdistillerparams }
-            if
-          }
-      }
-  }
-\cs_new_protected:Npn \__pdf_backend_compress_objects:n #1
-  {
-    \bool_if:nF {#1}
-      {
-        \__kernel_backend_literal_postscript:n
-          {
-            /setdistillerparams ~ where
-              { pop << /CompressStreams ~ false >> setdistillerparams }
-            if
-          }
-      }
-  }
-\cs_new_protected:Npn \__pdf_backend_version_major_gset:n #1
-  {
-    \cs_gset:Npe \__pdf_backend_version_major: { \int_eval:n {#1} }
-  }
-\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1
-  {
-    \cs_gset:Npe \__pdf_backend_version_minor: { \int_eval:n {#1} }
-  }
-\cs_new:Npn \__pdf_backend_version_major: { -1 }
-\cs_new:Npn \__pdf_backend_version_minor: { -1 }
-\cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2
-  { \__pdf_backend_pdfmark:n { /#1 ~ #2 /BDC } }
-\cs_new_protected:Npn \__pdf_backend_emc:
-  { \__pdf_backend_pdfmark:n { /EMC } }
-\cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2
-  {
-    \__kernel_backend_first_shipout:n
-      {
-        \__kernel_backend_literal:e
-          {
-            papersize = \dim_eval:n {#1} , \dim_eval:n {#2}
-          }
-      }
-  }
+  { \cs_new_eq:cc { __pdf_backend_link_ #1 } { __pdfannot_backend_link_ #1 } }
 %% File: l3backend-opacity.dtx
 \cs_new_protected:Npn \__opacity_backend_select:n #1
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def	2025-04-08 20:12:26 UTC (rev 74880)
@@ -10,9 +10,10 @@
 %% l3backend-draw.dtx  (with options: `package,dvisvgm')
 %% l3backend-graphics.dtx  (with options: `package,dvisvgm')
 %% l3backend-pdf.dtx  (with options: `package,dvisvgm')
+%% l3backend-pdfannot.dtx  (with options: `package,dvisvgm')
 %% l3backend-opacity.dtx  (with options: `package,dvisvgm')
 %% 
-%% Copyright (C) 2019-2024 The LaTeX Project
+%% Copyright (C) 2019-2025 The LaTeX Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -26,7 +27,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvisvgm.def}{2024-05-08}{}
+  {l3backend-dvisvgm.def}{2025-03-14}{}
   {L3 backend support: dvisvgm}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -439,7 +440,7 @@
   { \__kernel_backend_scope:n { stroke-linejoin="round" } }
 \cs_new_protected:Npn \__draw_backend_join_bevel:
   { \__kernel_backend_scope:n { stroke-linejoin="bevel" } }
-\cs_new_protected:Npn \__draw_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform:nnnn #1#2#3#4
   {
     \__kernel_backend_scope:n
       {
@@ -447,10 +448,18 @@
           " matrix ( #1 , #2 , #3 , #4 , 0pt , 0pt ) "
       }
   }
+\cs_new_protected:Npn \__draw_backend_shift:nn #1#2
+  {
+    \__kernel_backend_scope:n
+      {
+        transform =
+          " matrix ( 1 , 0 , 0 , 1 ,  #1pt , #2pt ) "
+      }
+  }
 \cs_new_protected:Npn \__draw_backend_box_use:Nnnnn #1#2#3#4#5
   {
     \__kernel_backend_scope_begin:
-    \__draw_backend_cm:nnnn {#2} {#3} {#4} {#5}
+    \__draw_backend_transform:nnnn {#2} {#3} {#4} {#5}
     \__kernel_backend_literal_svg:n
       {
         < g~
@@ -466,23 +475,8 @@
     \__kernel_backend_scope_end:
   }
 %% File: l3backend-graphics.dtx
-\cs_new_protected:Npn \__graphics_backend_loaded:n #1
-  {
-    \cs_if_exist:NTF \hook_gput_code:nnn
-      {
-        \hook_gput_code:nnn
-          { package / l3graphics / after }
-          { backend }
-          {#1}
-      }
-      {#1}
-  }
-\__graphics_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn
-      \l_graphics_search_ext_seq
-      { .svg , .pdf , .eps , .ps , .png , .jpg , .jpeg }
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .svg , .pdf , .eps , .ps , .png , .jpg , .jpeg }
 \cs_new_protected:Npn \__graphics_backend_getbb_svg:n #1
   {
     \__graphics_bb_restore:nF {#1}
@@ -562,11 +556,8 @@
     \dim_set_eq:NN #1 \l__graphics_internal_dim
   }
 \cs_new_protected:Npn \__graphics_backend_getbb_svg_auxvii:w #1 \scan_stop: { }
-\__graphics_backend_loaded:n
-  {
-    \cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
-    \cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
-  }
+\cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
+\cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
 \cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
   {
     \int_zero:N \l__graphics_page_int
@@ -618,17 +609,8 @@
 \cs_new_eq:NN \__graphics_backend_include_jpg:n \__graphics_backend_include_svg:n
 \cs_new:Npn \__graphics_backend_include_dequote:w #1 " #2 " #3 \s__graphics_stop
   {#2}
-\__graphics_backend_loaded:n
-  { \cs_new_eq:NN \__graphics_backend_get_pagecount:n \__graphics_get_pagecount:n }
+\cs_new_eq:NN \__graphics_backend_get_pagecount:n \__graphics_get_pagecount:n
 %% File: l3backend-pdf.dtx
-\cs_new_protected:Npn \__pdf_backend_annotation:nnnn #1#2#3#4 { }
-\cs_new:Npn \__pdf_backend_annotation_last: { }
-\cs_new_protected:Npn \__pdf_backend_link_begin_goto:nnw #1#2 { }
-\cs_new_protected:Npn \__pdf_backend_link_begin_user:nnw #1#2 { }
-\cs_new_protected:Npn \__pdf_backend_link_begin:nnnw #1#2#3 { }
-\cs_new_protected:Npn \__pdf_backend_link_end: { }
-\cs_new:Npe \__pdf_backend_link_last: { }
-\cs_new_protected:Npn \__pdf_backend_link_margin:n #1 { }
 \cs_new_protected:Npn \__pdf_backend_destination:nn #1#2 { }
 \cs_new_protected:Npn \__pdf_backend_destination:nnnn #1#2#3#4 { }
 \cs_new_protected:Npn \__pdf_backend_catalog_gput:nn #1#2 { }
@@ -651,6 +633,29 @@
 \cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2 { }
 \cs_new_protected:Npn \__pdf_backend_emc: { }
 \cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2 { }
+%% File: l3backend-pdfannot.dtx
+\cs_new_protected:Npn \__pdfannot_backend_generic:nnnn #1#2#3#4 { }
+\cs_new:Npn \__pdfannot_backend_last: { }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_goto:nnw #1#2 { }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_user:nnw #1#2 { }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin:nnnw #1#2#3 { }
+\cs_new_protected:Npn \__pdfannot_backend_link_end: { }
+\cs_new:Npe \__pdfannot_backend_link_last: { }
+\cs_new_protected:Npn \__pdfannot_backend_link_margin:n #1 { }
+\cs_new_protected:Npn \__pdfannot_backend_link_on:  { }
+\cs_new_protected:Npn \__pdfannot_backend_link_off: { }
+\cs_new_eq:NN \__pdf_backend_annotation:nnnn \__pdfannot_backend_generic:nnnn
+\cs_new_eq:NN \__pdf_backend_annotation_last: \__pdfannot_backend_last:
+\clist_map_inline:nn
+  {
+    begin_goto:nnw ,
+    begin_user:nnw ,
+    begin:nnnw     ,
+    end:           ,
+    last:          ,
+    margin:n
+  }
+  { \cs_new_eq:cc { __pdf_backend_link_ #1 } { __pdfannot_backend_link_ #1 } }
 %% File: l3backend-opacity.dtx
 \cs_new_protected:Npn \__opacity_backend_select:n #1
   { \__opacity_backend:nn {#1} { } }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def	2025-04-08 20:12:26 UTC (rev 74880)
@@ -10,9 +10,10 @@
 %% l3backend-draw.dtx  (with options: `package,luatex')
 %% l3backend-graphics.dtx  (with options: `package,luatex')
 %% l3backend-pdf.dtx  (with options: `package,luatex')
+%% l3backend-pdfannot.dtx  (with options: `package,luatex')
 %% l3backend-opacity.dtx  (with options: `package,luatex')
 %% 
-%% Copyright (C) 2019-2024 The LaTeX Project
+%% Copyright (C) 2019-2025 The LaTeX Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -26,7 +27,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-luatex.def}{2024-05-08}{}
+  {l3backend-luatex.def}{2025-03-14}{}
   {L3 backend support: PDF output (LuaTeX)}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -60,7 +61,11 @@
     \tex_pdfextension:D literal
       { \exp_not:n {#1} }
   }
-\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:e #1
+  {
+    \tex_pdfextension:D literal
+      {#1}
+  }
 \cs_new_protected:Npn \__kernel_backend_literal_page:n #1
   {
     \tex_pdfextension:D literal ~
@@ -84,7 +89,11 @@
     \tex_pdfextension:D setmatrix
         { \exp_not:n {#1} }
   }
-\cs_generate_variant:Nn \__kernel_backend_matrix:n { e }
+\cs_new_protected:Npn \__kernel_backend_matrix:e #1
+  {
+    \tex_pdfextension:D setmatrix
+        {#1}
+  }
 %% File: l3backend-color.dtx
 \int_new:N \l__color_backend_stack_int
 \cs_new_protected:Npn \__kernel_color_backend_stack_init:Nnn #1#2#3
@@ -384,7 +393,7 @@
   }
 %% File: l3backend-draw.dtx
 \cs_new_eq:NN \__draw_backend_literal:n \__kernel_backend_literal_pdf:n
-\cs_generate_variant:Nn \__draw_backend_literal:n { e }
+\cs_new_eq:NN \__draw_backend_literal:e \__kernel_backend_literal_pdf:e
 \cs_new_protected:Npn \__draw_backend_begin:
   { \__draw_backend_scope_begin: }
 \cs_new_protected:Npn \__draw_backend_end:
@@ -480,35 +489,25 @@
   { \__draw_backend_literal:n { 1 ~ j } }
 \cs_new_protected:Npn \__draw_backend_join_bevel:
   { \__draw_backend_literal:n { 2 ~ j } }
-\cs_new_protected:Npn \__draw_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform:nnnn #1#2#3#4
   {
     \__kernel_backend_matrix:n { #1 ~ #2 ~ #3 ~ #4 }
   }
+\cs_new_protected:Npn \__draw_backend_shift:nn #1#2
+  {
+    \__draw_backend_literal:n
+      { 1 ~ 0 ~ 0 ~ 1 ~ #1 ~ #2 ~ cm }
+  }
 \cs_new_protected:Npn \__draw_backend_box_use:Nnnnn #1#2#3#4#5
   {
     \__kernel_backend_scope_begin:
-    \__draw_backend_cm:nnnn {#2} {#3} {#4} {#5}
+    \__kernel_backend_matrix:n { #2 ~ #3 ~ #4 ~ #5 }
     \hbox_overlap_right:n { \box_use:N #1 }
     \__kernel_backend_scope_end:
   }
 %% File: l3backend-graphics.dtx
-\cs_new_protected:Npn \__graphics_backend_loaded:n #1
-  {
-    \cs_if_exist:NTF \hook_gput_code:nnn
-      {
-        \hook_gput_code:nnn
-          { package / l3graphics / after }
-          { backend }
-          {#1}
-      }
-      {#1}
-  }
-\__graphics_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn
-      \l_graphics_search_ext_seq
-      { .pdf , .eps , .ps , .png , .jpg , .jpeg  }
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .pdf , .eps , .ps , .png , .jpg , .jpeg  }
 \tl_new:N \l__graphics_attr_tl
 \cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
   {
@@ -648,46 +647,6 @@
       { \int_use:N \tex_pdflastximagepages:D }
   }
 %% File: l3backend-pdf.dtx
-\box_new:N \l__pdf_internal_box
-\cs_new_protected:Npn \__pdf_backend_annotation:nnnn #1#2#3#4
-  {
-    \tex_pdfextension:D annot ~
-      width  ~ \dim_eval:n {#1} ~
-      height ~ \dim_eval:n {#2} ~
-      depth  ~ \dim_eval:n {#3} ~
-      {#4}
-  }
-\cs_new:Npe \__pdf_backend_annotation_last:
-  {
-    \exp_not:N \int_value:w
-      \exp_not:N \tex_pdffeedback:D lastannot ~
-      \c_space_tl 0 ~ R
-  }
-\cs_new_protected:Npn \__pdf_backend_link_begin_goto:nnw #1#2
-  { \__pdf_backend_link_begin:nnnw {#1} { goto~name } {#2} }
-\cs_new_protected:Npn \__pdf_backend_link_begin_user:nnw #1#2
-  { \__pdf_backend_link_begin:nnnw {#1} { user } {#2} }
-\cs_new_protected:Npn \__pdf_backend_link_begin:nnnw #1#2#3
-  {
-    \tex_pdfextension:D startlink ~
-      attr {#1}
-      #2 {#3}
-  }
-\cs_new_protected:Npn \__pdf_backend_link_end:
-  {
-    \tex_pdfextension:D endlink \scan_stop:
-  }
-\cs_new:Npe \__pdf_backend_link_last:
-  {
-    \exp_not:N \int_value:w
-      \exp_not:N \tex_pdffeedback:D lastlink ~
-      \c_space_tl 0 ~ R
-  }
-\cs_new_protected:Npn \__pdf_backend_link_margin:n #1
-  {
-    \tex_pdfvariable:D linkmargin
-      \dim_eval:n {#1} \scan_stop:
-  }
 \cs_new_protected:Npn \__pdf_backend_destination:nn #1#2
   {
     \tex_pdfextension:D dest ~
@@ -832,6 +791,62 @@
     \dim_gset:Nn \tex_pagewidth:D  {#1}
     \dim_gset:Nn \tex_pageheight:D {#2}
   }
+%% File: l3backend-pdfannot.dtx
+\cs_new_protected:Npn \__pdfannot_backend_generic:nnnn #1#2#3#4
+  {
+    \tex_pdfextension:D annot ~
+      width  ~ \dim_eval:n {#1} ~
+      height ~ \dim_eval:n {#2} ~
+      depth  ~ \dim_eval:n {#3} ~
+      {#4}
+  }
+\cs_new:Npe \__pdfannot_backend_last:
+  {
+    \exp_not:N \int_value:w
+      \exp_not:N \tex_pdffeedback:D lastannot ~
+      \c_space_tl 0 ~ R
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_goto:nnw #1#2
+  { \__pdfannot_backend_link_begin:nnnw {#1} { goto~name } {#2} }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_user:nnw #1#2
+  { \__pdfannot_backend_link_begin:nnnw {#1} { user } {#2} }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin:nnnw #1#2#3
+  {
+    \tex_pdfextension:D startlink ~
+      attr {#1}
+      #2 {#3}
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_end:
+  {
+    \tex_pdfextension:D endlink \scan_stop:
+  }
+\cs_new:Npe \__pdfannot_backend_link_last:
+  {
+    \exp_not:N \int_value:w
+      \exp_not:N \tex_pdffeedback:D lastlink ~
+      \c_space_tl 0 ~ R
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_margin:n #1
+  {
+    \tex_pdfvariable:D linkmargin
+      \dim_eval:n {#1} \scan_stop:
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_on:
+  { \tex_pdfextension:D linkstate 0 ~ }
+\cs_new_protected:Npn \__pdfannot_backend_link_off:
+  { \tex_pdfextension:D linkstate 1 ~ }
+\cs_new_eq:NN \__pdf_backend_annotation:nnnn \__pdfannot_backend_generic:nnnn
+\cs_new_eq:NN \__pdf_backend_annotation_last: \__pdfannot_backend_last:
+\clist_map_inline:nn
+  {
+    begin_goto:nnw ,
+    begin_user:nnw ,
+    begin:nnnw     ,
+    end:           ,
+    last:          ,
+    margin:n
+  }
+  { \cs_new_eq:cc { __pdf_backend_link_ #1 } { __pdfannot_backend_link_ #1 } }
 %% File: l3backend-opacity.dtx
 \bool_lazy_and:nnT
   { \cs_if_exist_p:N \pdfmanagement_if_active_p: }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.lua
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.lua	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.lua	2025-04-08 20:12:26 UTC (rev 74880)
@@ -7,7 +7,7 @@
 -- l3backend-color.dtx  (with options: `lua')
 -- l3backend-opacity.dtx  (with options: `lua')
 -- 
--- Copyright (C) 2023,2024 The LaTeX Project
+-- Copyright (C) 2023-2025 The LaTeX Project
 -- 
 -- It may be distributed and/or modified under the conditions of
 -- the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def	2025-04-08 20:12:26 UTC (rev 74880)
@@ -10,9 +10,10 @@
 %% l3backend-draw.dtx  (with options: `package,pdftex')
 %% l3backend-graphics.dtx  (with options: `package,pdftex')
 %% l3backend-pdf.dtx  (with options: `package,pdftex')
+%% l3backend-pdfannot.dtx  (with options: `package,pdftex')
 %% l3backend-opacity.dtx  (with options: `package,pdftex')
 %% 
-%% Copyright (C) 2019-2024 The LaTeX Project
+%% Copyright (C) 2019-2025 The LaTeX Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -26,7 +27,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-pdftex.def}{2024-05-08}{}
+  {l3backend-pdftex.def}{2025-03-14}{}
   {L3 backend support: PDF output (pdfTeX)}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -60,7 +61,11 @@
     \tex_pdfliteral:D
       { \exp_not:n {#1} }
   }
-\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:e #1
+  {
+    \tex_pdfliteral:D
+      {#1}
+  }
 \cs_new_protected:Npn \__kernel_backend_literal_page:n #1
   {
     \tex_pdfliteral:D
@@ -84,7 +89,11 @@
     \tex_pdfsetmatrix:D
         { \exp_not:n {#1} }
   }
-\cs_generate_variant:Nn \__kernel_backend_matrix:n { e }
+\cs_new_protected:Npn \__kernel_backend_matrix:e #1
+  {
+    \tex_pdfsetmatrix:D
+        {#1}
+  }
 %% File: l3backend-color.dtx
 \int_new:N \l__color_backend_stack_int
 \cs_new_protected:Npn \__kernel_color_backend_stack_init:Nnn #1#2#3
@@ -383,7 +392,7 @@
   }
 %% File: l3backend-draw.dtx
 \cs_new_eq:NN \__draw_backend_literal:n \__kernel_backend_literal_pdf:n
-\cs_generate_variant:Nn \__draw_backend_literal:n { e }
+\cs_new_eq:NN \__draw_backend_literal:e \__kernel_backend_literal_pdf:e
 \cs_new_protected:Npn \__draw_backend_begin:
   { \__draw_backend_scope_begin: }
 \cs_new_protected:Npn \__draw_backend_end:
@@ -479,35 +488,25 @@
   { \__draw_backend_literal:n { 1 ~ j } }
 \cs_new_protected:Npn \__draw_backend_join_bevel:
   { \__draw_backend_literal:n { 2 ~ j } }
-\cs_new_protected:Npn \__draw_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform:nnnn #1#2#3#4
   {
     \__kernel_backend_matrix:n { #1 ~ #2 ~ #3 ~ #4 }
   }
+\cs_new_protected:Npn \__draw_backend_shift:nn #1#2
+  {
+    \__draw_backend_literal:n
+      { 1 ~ 0 ~ 0 ~ 1 ~ #1 ~ #2 ~ cm }
+  }
 \cs_new_protected:Npn \__draw_backend_box_use:Nnnnn #1#2#3#4#5
   {
     \__kernel_backend_scope_begin:
-    \__draw_backend_cm:nnnn {#2} {#3} {#4} {#5}
+    \__kernel_backend_matrix:n { #2 ~ #3 ~ #4 ~ #5 }
     \hbox_overlap_right:n { \box_use:N #1 }
     \__kernel_backend_scope_end:
   }
 %% File: l3backend-graphics.dtx
-\cs_new_protected:Npn \__graphics_backend_loaded:n #1
-  {
-    \cs_if_exist:NTF \hook_gput_code:nnn
-      {
-        \hook_gput_code:nnn
-          { package / l3graphics / after }
-          { backend }
-          {#1}
-      }
-      {#1}
-  }
-\__graphics_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn
-      \l_graphics_search_ext_seq
-      { .pdf , .eps , .ps , .png , .jpg , .jpeg  }
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .pdf , .eps , .ps , .png , .jpg , .jpeg  }
 \tl_new:N \l__graphics_attr_tl
 \cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
   {
@@ -647,46 +646,6 @@
       { \int_use:N \tex_pdflastximagepages:D }
   }
 %% File: l3backend-pdf.dtx
-\box_new:N \l__pdf_internal_box
-\cs_new_protected:Npn \__pdf_backend_annotation:nnnn #1#2#3#4
-  {
-    \tex_pdfannot:D
-      width  ~ \dim_eval:n {#1} ~
-      height ~ \dim_eval:n {#2} ~
-      depth  ~ \dim_eval:n {#3} ~
-      {#4}
-  }
-\cs_new:Npe \__pdf_backend_annotation_last:
-  {
-    \exp_not:N \int_value:w
-      \exp_not:N \tex_pdflastannot:D
-      \c_space_tl 0 ~ R
-  }
-\cs_new_protected:Npn \__pdf_backend_link_begin_goto:nnw #1#2
-  { \__pdf_backend_link_begin:nnnw {#1} { goto~name } {#2} }
-\cs_new_protected:Npn \__pdf_backend_link_begin_user:nnw #1#2
-  { \__pdf_backend_link_begin:nnnw {#1} { user } {#2} }
-\cs_new_protected:Npn \__pdf_backend_link_begin:nnnw #1#2#3
-  {
-    \tex_pdfstartlink:D
-      attr {#1}
-      #2 {#3}
-  }
-\cs_new_protected:Npn \__pdf_backend_link_end:
-  {
-    \tex_pdfendlink:D
-  }
-\cs_new:Npe \__pdf_backend_link_last:
-  {
-    \exp_not:N \int_value:w
-      \exp_not:N \tex_pdflastlink:D
-      \c_space_tl 0 ~ R
-  }
-\cs_new_protected:Npn \__pdf_backend_link_margin:n #1
-  {
-    \tex_pdflinkmargin:D
-      \dim_eval:n {#1} \scan_stop:
-  }
 \cs_new_protected:Npn \__pdf_backend_destination:nn #1#2
   {
     \tex_pdfdest:D
@@ -831,6 +790,62 @@
     \dim_gset:Nn \tex_pagewidth:D  {#1}
     \dim_gset:Nn \tex_pageheight:D {#2}
   }
+%% File: l3backend-pdfannot.dtx
+\cs_new_protected:Npn \__pdfannot_backend_generic:nnnn #1#2#3#4
+  {
+    \tex_pdfannot:D
+      width  ~ \dim_eval:n {#1} ~
+      height ~ \dim_eval:n {#2} ~
+      depth  ~ \dim_eval:n {#3} ~
+      {#4}
+  }
+\cs_new:Npe \__pdfannot_backend_last:
+  {
+    \exp_not:N \int_value:w
+      \exp_not:N \tex_pdflastannot:D
+      \c_space_tl 0 ~ R
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_goto:nnw #1#2
+  { \__pdfannot_backend_link_begin:nnnw {#1} { goto~name } {#2} }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_user:nnw #1#2
+  { \__pdfannot_backend_link_begin:nnnw {#1} { user } {#2} }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin:nnnw #1#2#3
+  {
+    \tex_pdfstartlink:D
+      attr {#1}
+      #2 {#3}
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_end:
+  {
+    \tex_pdfendlink:D
+  }
+\cs_new:Npe \__pdfannot_backend_link_last:
+  {
+    \exp_not:N \int_value:w
+      \exp_not:N \tex_pdflastlink:D
+      \c_space_tl 0 ~ R
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_margin:n #1
+  {
+    \tex_pdflinkmargin:D
+      \dim_eval:n {#1} \scan_stop:
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_on:
+   { \tex_pdfrunninglinkon:D }
+\cs_new_protected:Npn \__pdfannot_backend_link_off:
+  { \tex_pdfrunninglinkoff:D }
+\cs_new_eq:NN \__pdf_backend_annotation:nnnn \__pdfannot_backend_generic:nnnn
+\cs_new_eq:NN \__pdf_backend_annotation_last: \__pdfannot_backend_last:
+\clist_map_inline:nn
+  {
+    begin_goto:nnw ,
+    begin_user:nnw ,
+    begin:nnnw     ,
+    end:           ,
+    last:          ,
+    margin:n
+  }
+  { \cs_new_eq:cc { __pdf_backend_link_ #1 } { __pdfannot_backend_link_ #1 } }
 %% File: l3backend-opacity.dtx
 \bool_lazy_and:nnT
   { \cs_if_exist_p:N \pdfmanagement_if_active_p: }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def	2025-04-08 20:12:11 UTC (rev 74879)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def	2025-04-08 20:12:26 UTC (rev 74880)
@@ -10,9 +10,10 @@
 %% l3backend-draw.dtx  (with options: `package,xetex')
 %% l3backend-graphics.dtx  (with options: `package,xetex')
 %% l3backend-pdf.dtx  (with options: `package,xetex')
+%% l3backend-pdfannot.dtx  (with options: `package,xetex')
 %% l3backend-opacity.dtx  (with options: `package,xetex')
 %% 
-%% Copyright (C) 2019-2024 The LaTeX Project
+%% Copyright (C) 2019-2025 The LaTeX Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -26,7 +27,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-xetex.def}{2024-05-08}{}
+  {l3backend-xetex.def}{2025-03-14}{}
   {L3 backend support: XeTeX}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -306,7 +307,7 @@
   }
 %% File: l3backend-draw.dtx
 \cs_new_eq:NN \__draw_backend_literal:n \__kernel_backend_literal_pdf:n
-\cs_generate_variant:Nn \__draw_backend_literal:n { e }
+\cs_new_eq:NN \__draw_backend_literal:e \__kernel_backend_literal_pdf:e
 \cs_new_protected:Npn \__draw_backend_begin:
   { \__draw_backend_scope_begin: }
 \cs_new_protected:Npn \__draw_backend_end:
@@ -402,12 +403,20 @@
   { \__draw_backend_literal:n { 1 ~ j } }
 \cs_new_protected:Npn \__draw_backend_join_bevel:
   { \__draw_backend_literal:n { 2 ~ j } }
-\cs_new_protected:Npn \__draw_backend_cm:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform:nnnn #1#2#3#4
   {
-    \__draw_backend_cm_decompose:nnnnN {#1} {#2} {#3} {#4}
-      \__draw_backend_cm_aux:nnnn
+    \str_if_eq:nnTF { #2 ~ #3 } { 0 ~ 0 }
+      {
+        \__kernel_backend_literal:n { x:rotate~0 }
+        \__kernel_backend_literal:n { x:scale~#1~#4 }
+        \__kernel_backend_literal:n { x:rotate~0 }
+      }
+      {
+        \__draw_backend_transform_decompose:nnnnN {#1} {#2} {#3} {#4}
+          \__draw_backend_transform_aux:nnnn
+      }
   }
-\cs_new_protected:Npn \__draw_backend_cm_aux:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_backend_transform_aux:nnnn #1#2#3#4
   {
     \__kernel_backend_literal:e
       {
@@ -430,11 +439,16 @@
           { \fp_eval:n { round ( -#4 , 5 ) } }
       }
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_shift:nn #1#2
   {
+    \__draw_backend_literal:n
+      { 1 ~ 0 ~ 0 ~ 1 ~ #1 ~ #2 ~ cm }
+  }
+\cs_new_protected:Npn \__draw_backend_transform_decompose:nnnnN #1#2#3#4#5
+  {
     \use:e
       {
-        \__draw_backend_cm_decompose_auxi:nnnnN
+        \__draw_backend_transform_decompose_auxi:nnnnN
           { \fp_eval:n { (#1 + #4) / 2 } }
           { \fp_eval:n { (#1 - #4) / 2 } }
           { \fp_eval:n { (#3 + #2) / 2 } }
@@ -442,11 +456,11 @@
       }
         #5
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_transform_decompose_auxi:nnnnN #1#2#3#4#5
   {
     \use:e
       {
-        \__draw_backend_cm_decompose_auxii:nnnnN
+        \__draw_backend_transform_decompose_auxii:nnnnN
           { \fp_eval:n { 2 * sqrt ( #1 * #1 + #4 * #4 ) } }
           { \fp_eval:n { 2 * sqrt ( #2 * #2 + #3 * #3 ) } }
           { \fp_eval:n { atand ( #3 , #2 ) } }
@@ -454,11 +468,11 @@
       }
         #5
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_transform_decompose_auxii:nnnnN #1#2#3#4#5
   {
     \use:e
       {
-        \__draw_backend_cm_decompose_auxiii:nnnnN
+        \__draw_backend_transform_decompose_auxiii:nnnnN
           { \fp_eval:n { ( #4 - #3 ) / 2 } }
           { \fp_eval:n { ( #1 + #2 ) / 2 } }
           { \fp_eval:n { ( #1 - #2 ) / 2 } }
@@ -466,7 +480,7 @@
       }
         #5
   }
-\cs_new_protected:Npn \__draw_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
+\cs_new_protected:Npn \__draw_backend_transform_decompose_auxiii:nnnnN #1#2#3#4#5
   {
     \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
       { #5 {#1} {#2} {#3} {#4} }
@@ -482,27 +496,10 @@
     \__kernel_backend_scope_end:
   }
 %% File: l3backend-graphics.dtx
-\cs_new_protected:Npn \__graphics_backend_loaded:n #1
-  {
-    \cs_if_exist:NTF \hook_gput_code:nnn
-      {
-        \hook_gput_code:nnn
-          { package / l3graphics / after }
-          { backend }
-          {#1}
-      }
-      {#1}
-  }
-\__graphics_backend_loaded:n
-  {
-    \seq_set_from_clist:Nn \l_graphics_search_ext_seq
-      { .pdf , .eps , .ps , .png , .jpg , .jpeg , .bmp }
-  }
-\__graphics_backend_loaded:n
-  {
-    \cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
-    \cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
-  }
+\seq_set_from_clist:Nn \l_graphics_search_ext_seq
+  { .pdf , .eps , .ps , .png , .jpg , .jpeg , .bmp }
+\cs_new_eq:NN \__graphics_backend_getbb_eps:n \__graphics_read_bb:n
+\cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_read_bb:n
 \int_new:N \g__graphics_track_int
 \cs_new_protected:Npn \__graphics_backend_include_eps:n #1
   {
@@ -653,7 +650,6 @@
       }
   }
 %% File: l3backend-pdf.dtx
-\box_new:N \l__pdf_internal_box
 \cs_new_protected:Npe \__pdf_backend:n #1
   { \__kernel_backend_literal:n { pdf: #1 } }
 \cs_generate_variant:Nn \__pdf_backend:n { e }
@@ -706,48 +702,6 @@
   { @pdf.obj \int_use:N \g__pdf_backend_object_int }
 \cs_new:Npn \__pdf_backend_pageobject_ref:n #1
   { @page #1 }
-\int_new:N \g__pdf_backend_annotation_int
-\cs_new_protected:Npn \__pdf_backend_annotation:nnnn #1#2#3#4
-  {
-    \int_gincr:N \g__pdf_backend_object_int
-    \int_gset_eq:NN \g__pdf_backend_annotation_int \g__pdf_backend_object_int
-    \__pdf_backend:e
-      {
-        ann ~ @pdf.obj \int_use:N \g__pdf_backend_object_int \c_space_tl
-        width  ~ \dim_eval:n {#1} ~
-        height ~ \dim_eval:n {#2} ~
-        depth  ~ \dim_eval:n {#3} ~
-        << /Type /Annot #4 >>
-      }
-  }
-\cs_new:Npn \__pdf_backend_annotation_last:
-  { @pdf.obj \int_use:N \g__pdf_backend_annotation_int }
-\int_new:N \g__pdf_backend_link_int
-\cs_new_protected:Npn \__pdf_backend_link_begin_goto:nnw #1#2
-  { \__pdf_backend_link_begin:n { #1 /Subtype /Link /A << /S /GoTo /D ( #2 ) >> } }
-\cs_new_protected:Npn \__pdf_backend_link_begin_user:nnw #1#2
-  { \__pdf_backend_link_begin:n {#1#2} }
-\cs_new_protected:Npe \__pdf_backend_link_begin:n #1
-  {
-    \exp_not:N \int_gincr:N \exp_not:N  \g__pdf_backend_link_int
-    \__pdf_backend:e
-      {
-        bann ~
-        @pdf.lnk
-        \exp_not:N \int_use:N \exp_not:N  \g__pdf_backend_link_int
-        \c_space_tl
-        <<
-          /Type /Annot
-          #1
-        >>
-      }
-  }
-\cs_new_protected:Npn \__pdf_backend_link_end:
-  { \__pdf_backend:n { eann } }
-\cs_new:Npn \__pdf_backend_link_last:
-  { @pdf.lnk \int_use:N \g__pdf_backend_link_int }
-\cs_new_protected:Npn \__pdf_backend_link_margin:n #1
-  { \__kernel_backend_literal:e { dvipdfmx:config~g~ \dim_eval:n {#1} } }
 \cs_new_protected:Npn \__pdf_backend_destination:nn #1#2
   {
     \__pdf_backend:e
@@ -836,6 +790,70 @@
     \dim_gset:Nn \tex_pagewidth:D  {#1}
     \dim_gset:Nn \tex_pageheight:D {#2}
   }
+%% File: l3backend-pdfannot.dtx
+\cs_new_protected:Npe \__pdfannot_backend:n #1
+  { \__kernel_backend_literal:n { pdf: #1 } }
+\cs_generate_variant:Nn \__pdfannot_backend:n { e }
+\int_new:N \g__pdfannot_backend_int
+\cs_new_protected:Npn \__pdfannot_backend_generic:nnnn #1#2#3#4
+  {
+    \int_gincr:N \g__pdfannot_backend_int
+    \__pdfannot_backend:e
+      {
+        ann ~ @pdfannot \int_use:N \g__pdfannot_backend_int \c_space_tl
+        width  ~ \dim_eval:n {#1} ~
+        height ~ \dim_eval:n {#2} ~
+        depth  ~ \dim_eval:n {#3} ~
+        << /Type /Annot #4 >>
+      }
+  }
+\cs_new:Npn \__pdfannot_backend_last:
+  { @pdfannot \int_use:N \g__pdfannot_backend_int }
+\int_new:N \g__pdfannot_backend_link_int
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_goto:nnw #1#2
+  {
+    \__pdfannot_backend_link_begin:n
+      { #1 /Subtype /Link /A << /S /GoTo /D ( #2 ) >> }
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_begin_user:nnw #1#2
+  { \__pdfannot_backend_link_begin:n {#1#2} }
+\cs_new_protected:Npe \__pdfannot_backend_link_begin:n #1
+  {
+    \int_gincr:N \exp_not:N \g__pdfannot_backend_int
+    \int_gset_eq:NN \exp_not:N \g__pdfannot_backend_link_int
+      \exp_not:N \g__pdfannot_backend_int
+    \__pdfannot_backend:e
+      {
+        bann ~
+        @pdfannot
+        \exp_not:N \int_use:N \exp_not:N \g__pdfannot_backend_link_int
+        \c_space_tl
+        <<
+          /Type /Annot
+          #1
+        >>
+      }
+  }
+\cs_new_protected:Npn \__pdfannot_backend_link_end:
+  { \__pdfannot_backend:n { eann } }
+\cs_new:Npn \__pdfannot_backend_link_last:
+  { @pdfannot \int_use:N \g__pdfannot_backend_link_int }
+\cs_new_protected:Npn \__pdfannot_backend_link_margin:n #1
+  { \__kernel_backend_literal:e { dvipdfmx:config~g~ \dim_eval:n {#1} } }
+\cs_new_protected:Npn \__pdfannot_backend_link_on:  { \__pdfannot_backend:n { link } }
+\cs_new_protected:Npn \__pdfannot_backend_link_off: { \__pdfannot_backend:n { nolink } }
+\cs_new_eq:NN \__pdf_backend_annotation:nnnn \__pdfannot_backend_generic:nnnn
+\cs_new_eq:NN \__pdf_backend_annotation_last: \__pdfannot_backend_last:
+\clist_map_inline:nn
+  {
+    begin_goto:nnw ,
+    begin_user:nnw ,
+    begin:nnnw     ,
+    end:           ,
+    last:          ,
+    margin:n
+  }
+  { \cs_new_eq:cc { __pdf_backend_link_ #1 } { __pdfannot_backend_link_ #1 } }
 %% File: l3backend-opacity.dtx
 \bool_lazy_and:nnT
   { \cs_if_exist_p:N \pdfmanagement_if_active_p: }



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