summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2024-04-18 19:48:52 +0000
committerKarl Berry <karl@freefriends.org>2024-04-18 19:48:52 +0000
commitc39651dc8234f1a4e12d273b3b75e73e29e824a3 (patch)
tree906f2d43f1f8a7abf8e429922f81d3a67453d66b /Master
parent0c9828a4f12791b59e5d85a69976e43be42bdeae (diff)
l3backend-dev
git-svn-id: svn://tug.org/texlive/trunk@70977 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex-dev/l3backend/CHANGELOG.md402
-rw-r--r--Master/texmf-dist/doc/latex-dev/l3backend/README.md16
-rw-r--r--Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.pdfbin0 -> 907792 bytes
-rw-r--r--Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.tex63
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-basics.dtx497
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-box.dtx470
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-color.dtx1356
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-draw.dtx1067
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-graphics.dtx931
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-header.dtx590
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-opacity.dtx353
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend-pdf.dtx1755
-rw-r--r--Master/texmf-dist/source/latex-dev/l3backend/l3backend.ins168
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvipdfmx.def859
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.def1064
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.pro405
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvisvgm.def672
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.def903
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.lua125
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-pdftex.def902
-rw-r--r--Master/texmf-dist/tex/latex-dev/l3backend/l3backend-xetex.def906
-rw-r--r--Master/tlpkg/tlpsrc/l3backend-dev.tlpsrc3
22 files changed, 13507 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex-dev/l3backend/CHANGELOG.md b/Master/texmf-dist/doc/latex-dev/l3backend/CHANGELOG.md
new file mode 100644
index 00000000000..ecd85938815
--- /dev/null
+++ b/Master/texmf-dist/doc/latex-dev/l3backend/CHANGELOG.md
@@ -0,0 +1,402 @@
+# Changelog
+All notable changes to the `l3backend` bundle will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+this project uses date-based 'snapshot' version identifiers.
+
+## [Unreleased]
+
+## [2024-04-11]
+
+### Added
+- Support for 'raw' PDF object IDs
+
+### Changed
+- Update PDF object management code
+
+## [2024-03-14]
+
+### Removed
+- Range guard for opacity
+
+### Fixed
+- Initiation of opacity data (see \#1472)
+- ExtGState setup for stroking opacity (issue \#1472)
+- Inconsistent behavior of opacity functions w/o `pdfmanagement`
+ (issue \#1473)
+- Redundant braces in opacity backend for dvisvgm
+- Interaction of scope with box insertion with `dvips` (see \#1504)
+
+## [2024-02-20]
+
+### Fixed
+- Naming of a variable in the `draw` code
+
+## [2024-01-04]
+
+### Changed
+- Documentation tweaks
+
+## [2023-11-09]
+
+### Changed
+- Changed `luaotfload` integration to allow coexistance with (x)color.
+
+## [2023-11-04]
+
+### Fixed
+- Interaction with `luaotfload` transparency colorstacks
+
+## [2023-10-23]
+
+### Changed
+- Update minimal `expl3` version required
+
+## [2023-10-10]
+
+### Changed
+- Track `expl3` changes
+
+## [2023-04-19]
+
+### Changed
+- Pass additional attributes when loading graphics in PDF mode
+
+### Fixed
+- Remove a stray `>` from graphics inclusion code for `dvipdfmx`
+
+## [2023-03-30]
+
+### Changed
+- Integrate `l3color` and `l3opacity` with `luaotfload` to ensure that
+ opacity specifications don't conflict
+
+## [2023-01-16]
+
+### Changed
+- Adjust internal scope of a PDF function
+
+## [2022-10-26]
+
+### Changed
+- Avoid setting media box if `\mag` is non-standard
+
+## [2022-09-28]
+
+### Changed
+- Add support for media box setting
+
+## [2022-08-30]
+
+### Added
+- Support for new approach to writing PDF objects
+
+## [2022-08-23]
+
+### Changed
+- Approach to setting current color data from LaTeX2e
+
+## [2022-08-05]
+
+### Changed
+- Add no-op backend functions for annotations with `dvisvgm`
+
+## [2022-07-01]
+
+#### Fixed
+- Do not include PDF file to count pages on pdfTeX
+- Opacity creation with `dvipdfmx`/XeTeX (issue [\#1106](https://github.com/latex3/latex3/issues/1106))
+- Reset opacity when no stack is available at the backend (issue [\#1107](https://github.com/latex3/latex3/issues/1107))
+
+## [2022-04-20]
+
+### Changed
+- Adjust `(x)dvipdfmx` backend approach to color following issues with
+ multiple color stacks in `xetex.def`
+- Move some functions to `l3color`
+
+## [2022-04-14]
+
+### Added
+- Support for SVG graphic inclusion by `dvisvgm`
+
+### Fixed
+- `\color_ensure_current:` backend with DVI-based routes (issue [\#1085](https://github.com/latex3/latex3/issues/1085))
+
+## [2022-04-10]
+
+### Added
+- Support for graphics (PDF) page count extraction
+
+### Fixed
+- Setup for graphics extension searching
+- Various internal issues in graphics inclusion
+- Some missing functions for `dvisvgm` color support added
+
+### Removed
+- Support for pre-2020-11-11 `dvipdfmx`
+
+## [2022-02-07]
+
+### Fixed
+- Use of color stack int in scope end for `(x)dvipdfmx`
+
+## [2022-01-12]
+
+### Changed
+- Move some functions to `l3color`
+
+## [2021-12-14]
+
+### Fixed
+- Scoping issues for `dvisvgm`
+- Some incorrect functions in `l3draw` backend for `dvisvgm`
+
+## [2021-10-17]
+
+### Changed
+- Better DeviceN support
+
+## [2021-10-12]
+
+### Fixed
+- Issues with creating DeviceN color spaces
+
+## [2021-08-04]
+
+### Changed
+- Only use `pdfmanagement` module if active
+
+## [2021-07-12]
+
+### Fixed
+- GoTo link formation for Distiller-based workflows (issue [\#957](https://github.com/latex3/latex3/issues/957))
+- Support transparency with Distiller
+
+## [2021-05-07]
+
+### Changed
+- `\pdf_version_gset:n` in `dvips` now sets `\pdf_version_minor:` and
+ `\pdf_version_major:`. This doesn't set the PDF version but allows to test
+ which version the user intents to create.
+
+## [2021-03-18]
+
+### Fixed
+- Maintain stack color correctly with `(x)dvipdfmx`
+
+## [2021-03-02]
+
+### Changed
+- Drop 'correction' for link placement in `(x)dvidpfmx`: no longer required
+- Define `\main@pdfcolorstack` for `(x)dvipdfmx` if it does not exist
+
+### Fixed
+- Initialisation of color stacks for `(x)dvipdfmx`
+
+## [2021-02-18]
+
+### Changed
+- Update tracking of PDF management functions
+
+### Fixed
+- Opacity support for pdfTeX/LuaTeX
+
+## [2021-02-06]
+
+### Changed
+- Use new (internal) interface for kerns
+
+## [2021-01-29]
+
+### Added
+- Basic opacity support
+
+### Changed
+- Use color stack for fill color, and for stroke color if possible
+
+### Fixed
+- Implementation of `filldraw` for `dvips`
+
+## [2021-01-09]
+
+### Added
+- Support for referencing last link with `(x)dvipdfmx` (requires an up-to-date
+ backend)
+
+### Changed
+- Implementation of color wtih (x)dvipdfmx (requires an up-to-date
+ backend)
+
+## [2020-09-24]
+
+### Fixed
+- Documented source as PDF
+
+## [2020-09-11]
+
+### Added
+- Support for CIELAB separations with `dvips`
+
+### Fixed
+- Some PDF object functions
+- Separation color selection for `dvipdfmx`/XeTeX
+- Logic for some aspects of CIELAB Separation color
+
+## [2020-09-01]
+
+### Changed
+- Improved support for Separation colors
+- Updated approach to `dvipdfmx`/XeTeX color support
+- Split `pdfmode` driver into pdfTeX- and LuaTeX-specific files
+- Renamed `xdvipdfmx` backend files to `xetex`
+
+## [2020-08-07]
+
+### Changed
+- Color selection implementation
+- Improved support for Separation colors
+
+## [2020-06-29]
+
+### Fixed
+- Loading with `dvisvgm`
+
+## [2020-06-23]
+
+### Changed
+- Improved color support for drawings with `dvisvgm`
+
+### Fixed
+- Loading with `dvisvgm`
+
+## [2020-06-18]
+
+### Changed
+- Use `scn` operator for separations
+- Internal color model
+- Internal performance enhancements
+
+## [2020-06-03]
+
+### Fixed
+- Unneeded `[nobreak]` in `dvips` driver (issue [\#709](https://github.com/latex3/latex3/issues/709))
+- `\__pdf_backend_object_write_fstream:nn` with `dvips` backend (issue [\#710](https://github.com/latex3/latex3/issues/710))
+- Array writing in `dvips` mode
+
+## [2020-05-05]
+
+### Added
+- `\__pdf_backend_pageobject_ref:n`
+
+### Changed
+- Extend PDF compression control to `dvips`
+
+## [2020-03-12]
+
+### Fixed
+- Creation of PDF annotations with `dvips` backend
+
+## [2020-02-23]
+
+### Fixed
+- Mismatch between release tag and CTAN version
+
+## [2020-02-21]
+
+### Added
+- Support for suppressing backend headers (see matching change in
+ `l3kernel`)
+
+## [2020-02-03]
+
+### Fixed
+- Corrected release string information
+
+## [2019-11-25]
+
+### Changed
+- Move dvips header material to `.pro` file
+
+## [2019-10-11]
+
+### Changed
+- Improved functionality in generic mode
+
+## [2019-09-05]
+
+### Added
+- Support for EPS and PDF files with `dvisvgm` backend
+
+### Fixed
+- Some primitive use in the `dvips` backend
+
+## [2019-08-25]
+
+### Fixed
+- Setting for PDF version in `dvipdfmx` route
+- Support for PDF objects with XeTeX
+
+## [2019-07-01]
+
+### Added
+- Driver support for anonymous objects
+
+### Changed
+- Moved backend code to separate release module `l3backend`
+- Include `l3backend` in file names
+- Moved backend code to internal for each 'parent' module
+
+[Unreleased]: https://github.com/latex3/latex3/compare/2024-04-11...HEAD
+[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
+[2024-02-20]: https://github.com/latex3/latex3/compare/2024-01-04...2024-02-20
+[2024-01-04]: https://github.com/latex3/latex3/compare/2023-11-09...2024-01-04
+[2023-11-09]: https://github.com/latex3/latex3/compare/2023-11-04...2023-11-09
+[2023-11-04]: https://github.com/latex3/latex3/compare/2023-10-23...2023-11-04
+[2023-10-23]: https://github.com/latex3/latex3/compare/2023-10-10...2023-10-23
+[2023-10-10]: https://github.com/latex3/latex3/compare/2023-04-19...2023-10-10
+[2023-04-19]: https://github.com/latex3/latex3/compare/2023-03-30...2023-04-19
+[2023-03-30]: https://github.com/latex3/latex3/compare/2023-01-16...2023-03-30
+[2023-01-16]: https://github.com/latex3/latex3/compare/2022-10-26...2023-01-16
+[2022-10-26]: https://github.com/latex3/latex3/compare/2022-09-28...2022-10-26
+[2022-09-28]: https://github.com/latex3/latex3/compare/2022-08-30...2022-09-28
+[2022-08-30]: https://github.com/latex3/latex3/compare/2022-08-23...2022-08-30
+[2022-08-23]: https://github.com/latex3/latex3/compare/2022-08-05...2022-08-23
+[2022-08-05]: https://github.com/latex3/latex3/compare/2022-07-01...2022-08-05
+[2022-07-01]: https://github.com/latex3/latex3/compare/2022-04-20...2022-07-01
+[2022-04-20]: https://github.com/latex3/latex3/compare/2022-04-14...2022-04-20
+[2022-04-14]: https://github.com/latex3/latex3/compare/2022-04-10...2022-04-14
+[2022-04-10]: https://github.com/latex3/latex3/compare/2022-02-07...2022-04-10
+[2022-02-07]: https://github.com/latex3/latex3/compare/2022-01-12...2022-02-07
+[2022-01-12]: https://github.com/latex3/latex3/compare/2021-12-14...2022-01-12
+[2021-12-14]: https://github.com/latex3/latex3/compare/2021-10-17...2021-12-14
+[2021-10-17]: https://github.com/latex3/latex3/compare/2021-10-12...2021-10-17
+[2021-10-12]: https://github.com/latex3/latex3/compare/2021-08-04...2021-10-12
+[2021-08-04]: https://github.com/latex3/latex3/compare/2021-07-12...2021-08-04
+[2021-07-12]: https://github.com/latex3/latex3/compare/2021-05-07...2021-07-12
+[2021-05-07]: https://github.com/latex3/latex3/compare/2021-03-18...2021-05-07
+[2021-03-18]: https://github.com/latex3/latex3/compare/2021-03-02...2021-03-18
+[2021-03-02]: https://github.com/latex3/latex3/compare/2021-02-18...2021-03-02
+[2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18
+[2021-02-06]: https://github.com/latex3/latex3/compare/2021-01-29...2021-02-06
+[2021-01-29]: https://github.com/latex3/latex3/compare/2021-01-09...2021-01-29
+[2021-01-09]: https://github.com/latex3/latex3/compare/2020-09-24...2021-01-09
+[2020-09-24]: https://github.com/latex3/latex3/compare/2020-09-11...2020-09-24
+[2020-09-11]: https://github.com/latex3/latex3/compare/2020-09-01...2020-09-11
+[2020-09-01]: https://github.com/latex3/latex3/compare/2020-08-07...2020-09-01
+[2020-08-07]: https://github.com/latex3/latex3/compare/2020-06-29...2020-08-07
+[2020-06-29]: https://github.com/latex3/latex3/compare/2020-06-23...2020-06-29
+[2020-06-23]: https://github.com/latex3/latex3/compare/2020-06-18...2020-06-23
+[2020-06-18]: https://github.com/latex3/latex3/compare/2020-06-03...2020-06-18
+[2020-06-03]: https://github.com/latex3/latex3/compare/2020-05-05...2020-06-03
+[2020-05-05]: https://github.com/latex3/latex3/compare/2020-03-12...2020-05-05
+[2020-03-12]: https://github.com/latex3/latex3/compare/2020-02-23...2020-03-12
+[2020-02-23]: https://github.com/latex3/latex3/compare/2020-02-21...2020-02-23
+[2020-02-21]: https://github.com/latex3/latex3/compare/2020-02-03...2020-02-21
+[2020-02-03]: https://github.com/latex3/latex3/compare/2019-11-25...2020-02-03
+[2019-11-25]: https://github.com/latex3/latex3/compare/2019-10-11...2019-11-25
+[2019-10-11]: https://github.com/latex3/latex3/compare/2019-09-05...2019-10-11
+[2019-09-05]: https://github.com/latex3/latex3/compare/2019-08-25...2019-09-05
+[2019-08-25]: https://github.com/latex3/latex3/compare/2019-07-01...2019-08-25
+[2019-07-01]: https://github.com/latex3/latex3/compare/2019-05-28...2019-07-01
diff --git a/Master/texmf-dist/doc/latex-dev/l3backend/README.md b/Master/texmf-dist/doc/latex-dev/l3backend/README.md
new file mode 100644
index 00000000000..058fa63cc2a
--- /dev/null
+++ b/Master/texmf-dist/doc/latex-dev/l3backend/README.md
@@ -0,0 +1,16 @@
+LaTeX3 Backend Drivers
+======================
+
+Release 2024-04-11
+
+This package forms parts of `expl3`, and contains the code used to interface
+with backends (drivers) across the `expl3` codebase. The functions here are
+defined differently depending on the engine in use. As such, these are
+distributed separately from `l3kernel` to allow this code to be updated
+on an independent schedule.
+
+-----
+
+<p>Copyright (C) 2019-2024 The LaTeX Project <br />
+<a href="http://latex-project.org/">http://latex-project.org/</a> <br />
+All rights reserved.</p>
diff --git a/Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.pdf b/Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.pdf
new file mode 100644
index 00000000000..ce6b00698f9
--- /dev/null
+++ b/Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.tex b/Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.tex
new file mode 100644
index 00000000000..df0dd0ea8cd
--- /dev/null
+++ b/Master/texmf-dist/doc/latex-dev/l3backend/l3backend-code.tex
@@ -0,0 +1,63 @@
+\iffalse meta-comment
+
+File: l3backend-code.tex
+
+Copyright (C) 2019,2021 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 released version of this bundle is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+\fi
+
+\documentclass[full,kernel]{l3doc}
+
+\begin{document}
+
+\makeatletter
+\let\DelayPrintIndex\PrintIndex
+\let\PrintIndex\@empty
+\makeatother
+
+\ExplSyntaxOn
+\clist_gput_right:Nn \g_docinput_clist
+ {
+ l3backend-basics.dtx ,
+ l3backend-box.dtx ,
+ l3backend-color.dtx ,
+ l3backend-draw.dtx ,
+ l3backend-graphics.dtx ,
+ l3backend-pdf.dtx ,
+ l3backend-opacity.dtx ,
+ l3backend-header.dtx
+ }
+\ExplSyntaxOff
+
+\part{Implementation}
+
+\def\maketitle{}
+\EnableImplementation
+\DisableDocumentation
+\DocInputAgain
+
+\clearpage
+
+\DelayPrintIndex
+
+\end{document}
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-basics.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-basics.dtx
new file mode 100644
index 00000000000..fbac5033179
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-basics.dtx
@@ -0,0 +1,497 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-basics.dtx
+%
+% Copyright (C) 2019-2024 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-basics} module\\ Backend basics^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-basics} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% Whilst there is a reasonable amount of code overlap between backends,
+% it is much clearer to have the blocks more-or-less separated than run
+% in together and DocStripped out in parts. As such, most of the following
+% is set up on a per-backend basis, though there is some common code (again
+% given in blocks not interspersed with other material).
+%
+% All the file identifiers are up-front so that they come out in the right
+% place in the files.
+% \begin{macrocode}
+\ProvidesExplFile
+%<*dvipdfmx>
+ {l3backend-dvipdfmx.def}{2024-04-11}{}
+ {L3 backend support: dvipdfmx}
+%</dvipdfmx>
+%<*dvips>
+ {l3backend-dvips.def}{2024-04-11}{}
+ {L3 backend support: dvips}
+%</dvips>
+%<*dvisvgm>
+ {l3backend-dvisvgm.def}{2024-04-11}{}
+ {L3 backend support: dvisvgm}
+%</dvisvgm>
+%<*luatex>
+ {l3backend-luatex.def}{2024-04-11}{}
+ {L3 backend support: PDF output (LuaTeX)}
+%</luatex>
+%<*pdftex>
+ {l3backend-pdftex.def}{2024-04-11}{}
+ {L3 backend support: PDF output (pdfTeX)}
+%</pdftex>
+%<*xetex>
+ {l3backend-xetex.def}{2024-04-11}{}
+ {L3 backend support: XeTeX}
+%</xetex>
+% \end{macrocode}
+%
+% Check if the loaded kernel is at least enough to load this file.
+% The kernel date has to be at least equal to \cs{ExplBackendFileDate}
+% or later. If \cs{__kernel_dependency_version_check:Nn} doesn't
+% exist we're loading in an older kernel, so it's an error anyway.
+% With time, this test should vanish and only the dependency check
+% should remain.
+% \begin{macrocode}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+%<dvipdfmx> {l3backend-dvipdfmx.def}
+%<dvips> {l3backend-dvips.def}
+%<dvisvgm> {l3backend-dvisvgm.def}
+%<luatex> {l3backend-luatex.def}
+%<pdftex> {l3backend-pdftex.def}
+%<xetex> {l3backend-xetex.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+% \end{macrocode}
+%
+% The order of the backend code here is such that we get somewhat logical
+% outcomes in terms of code sharing whilst keeping things readable. (Trying to
+% mix all of the code by concept is almost unmanageable.) The key parts which
+% are shared are
+% \begin{itemize}
+% \item Color support is either \texttt{dvips}-like or \LuaTeX{}/pdfTeX{}-like.
+% \item \LuaTeX{}/pdfTeX{} and \texttt{dvipdfmx}/\XeTeX{} share drawing routines.
+% \item \XeTeX{} is the same as \texttt{dvipdfmx} other than image size
+% extraction so takes most of the same code.
+% \end{itemize}
+%
+% \begin{macro}
+% {
+% \__kernel_backend_literal:e,
+% \__kernel_backend_literal:n
+% }
+% The one shared function for all backends is access to the basic
+% \tn{special} primitive: it has slightly odd expansion behaviour
+% so a wrapper is provided.
+% \begin{macrocode}
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_first_shipout:n}
+% We need to write at first shipout in a few places. As we want to use the
+% most up-to-date method,
+% \begin{macrocode}
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}
+% {\__kernel_backend_literal_postscript:n, \__kernel_backend_literal_postscript:e}
+% Literal PostScript can be included using a few low-level formats. Here,
+% we use the form with no positioning: this is overall more convenient as
+% a wrapper. Note that this does require that where position is important,
+% an appropriate wrapper is included.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_postscript:n #1
+ { \__kernel_backend_literal:n { ps:: #1 } }
+\cs_generate_variant:Nn \__kernel_backend_literal_postscript:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_postscript:n, \__kernel_backend_postscript:e}
+% PostScript data that does have positioning, and also applying
+% a shift to |SDict| (which is not done automatically by
+% |ps:| or |ps::|, in contrast to |!| or |"|).
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_postscript:n #1
+ { \__kernel_backend_literal:n { ps: SDict ~ begin ~ #1 ~ end } }
+\cs_generate_variant:Nn \__kernel_backend_postscript:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% PostScript for the header: a small saving but makes the code clearer.
+% This is held until the start of shipout such that a document with no
+% actual output does not write anything.
+% \begin{macrocode}
+\bool_if:NT \g__kernel_backend_header_bool
+ {
+ \__kernel_backend_first_shipout:n
+ { \__kernel_backend_literal:n { header = l3backend-dvips.pro } }
+ }
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \__kernel_backend_align_begin:,
+% \__kernel_backend_align_end:
+% }
+% In \texttt{dvips} there is no built-in saving of the current
+% position, and so some additional PostScript is required to set up the
+% transformation matrix and also to restore it afterwards. Notice the use
+% of the stack to save the current position \enquote{up front} and to
+% move back to it at the end of the process. Notice that the |[begin]|/^^A
+% |[end]| pair here mean that we can use a run of PostScript statements
+% in separate lines: not \emph{required} but does make the code and
+% output more clear.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_align_begin:
+ {
+ \__kernel_backend_literal:n { ps::[begin] }
+ \__kernel_backend_literal_postscript:n { currentpoint }
+ \__kernel_backend_literal_postscript:n { currentpoint~translate }
+ }
+\cs_new_protected:Npn \__kernel_backend_align_end:
+ {
+ \__kernel_backend_literal_postscript:n { neg~exch~neg~exch~translate }
+ \__kernel_backend_literal:n { ps::[end] }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% Saving/restoring scope for general operations needs to be done with
+% \texttt{dvips} positioning (try without to see this!). Thus we need the
+% |ps:| version of the special here. As only the graphics state is ever
+% altered within this pairing, we use the lower-cost |g|-versions.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ { \__kernel_backend_literal:n { ps:gsave } }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ { \__kernel_backend_literal:n { ps:grestore } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backends}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% Both \LuaTeX{} and \pdfTeX{} write PDFs directly rather than via an
+% intermediate file. Although there are similarities, the move of \LuaTeX{}
+% to have more code in Lua means we create two independent files using
+% shared DocStrip code.
+%
+% \begin{macro}{\__kernel_backend_literal_pdf:n, \__kernel_backend_literal_pdf:e}
+% This is equivalent to \verb|\special{pdf:}| but the engine can
+% track it. Without the \texttt{direct} keyword everything is kept in
+% sync: the transformation matrix is set to the current point automatically.
+% Note that this is still inside the text (\texttt{BT} \dots \texttt{ET}
+% block).
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D literal
+%</luatex>
+%<*pdftex>
+ \tex_pdfliteral:D
+%</pdftex>
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_literal_page:n, \__kernel_backend_literal_page:e}
+% Page literals are pretty simple. To avoid an expansion, we write out
+% by hand.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_page:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D literal ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfliteral:D
+%</pdftex>
+ page { \exp_not:n {#1} }
+ }
+\cs_new_protected:Npn \__kernel_backend_literal_page:e #1
+ {
+%<*luatex>
+ \tex_pdfextension:D literal ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfliteral:D
+%</pdftex>
+ page {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% Higher-level interfaces for saving and restoring the graphic state.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ {
+%<*luatex>
+ \tex_pdfextension:D save \scan_stop:
+%</luatex>
+%<*pdftex>
+ \tex_pdfsave:D
+%</pdftex>
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ {
+%<*luatex>
+ \tex_pdfextension:D restore \scan_stop:
+%</luatex>
+%<*pdftex>
+ \tex_pdfrestore:D
+%</pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_matrix:n, \__kernel_backend_matrix:e}
+% Here the appropriate function is set up to insert an affine matrix
+% into the PDF. With \pdfTeX{} and \LuaTeX{} in direct PDF output mode there
+% is a primitive for this, which only needs the rotation/scaling/skew part.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_matrix:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D setmatrix
+%</luatex>
+%<*pdftex>
+ \tex_pdfsetmatrix:D
+%</pdftex>
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \__kernel_backend_matrix:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx} backend}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% The \texttt{dvipdfmx} shares code with the PDF mode one (using the common
+% section to this file) but also with \XeTeX{}. The latter is close
+% to identical to \texttt{dvipdfmx} and so all of the code here is extracted
+% for both backends, with some \texttt{clean up} for \XeTeX{} as
+% required.
+%
+% \begin{macro}{\__kernel_backend_literal_pdf:n, \__kernel_backend_literal_pdf:e}
+% Undocumented but equivalent to \pdfTeX{}'s |literal| keyword. It's similar to
+% be not the same as the documented |contents| keyword as that adds a |q|/|Q|
+% pair.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ { \__kernel_backend_literal:n { pdf:literal~ #1 } }
+\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_literal_page:n}
+% Whilst the manual says this is like |literal direct| in \pdfTeX{},
+% it closes the |BT| block!
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_page:n #1
+ { \__kernel_backend_literal:n { pdf:literal~direct~ #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% Scoping is done using the backend-specific specials. We use the versions
+% originally from \texttt{xdvidfpmx} (\texttt{x:}) as these are well-tested
+% \enquote{in the wild}.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ { \__kernel_backend_literal:n { x:gsave } }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ { \__kernel_backend_literal:n { x:grestore } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_backend_literal_svg:n, \__kernel_backend_literal_svg:e}
+% Unlike the other backends, the requirements for making SVG files mean
+% that we can't conveniently transform all operations to the current point.
+% That makes life a bit more tricky later as that needs to be accounted for.
+% A new line is added after each call to help to keep the output readable
+% for debugging.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_svg:n #1
+ { \__kernel_backend_literal:n { dvisvgm:raw~ #1 { ?nl } } }
+\cs_generate_variant:Nn \__kernel_backend_literal_svg:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g__kernel_backend_scope_int, \l__kernel_backend_scope_int}
+% In SVG, we need to track scope nesting as properties attach to scopes; that
+% requires a pair of \texttt{int} registers.
+% \begin{macrocode}
+\int_new:N \g__kernel_backend_scope_int
+\int_new:N \l__kernel_backend_scope_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% \begin{macro}{\__kernel_backend_scope_begin:n, \__kernel_backend_scope_begin:e}
+% \begin{macro}{\__kernel_backend_scope:n, \__kernel_backend_scope:e}
+% In SVG, the need to attach concepts to a scope means we need to be sure we
+% will close all of the open scopes. That is easiest done if we only need
+% an outer \enquote{wrapper} \texttt{begin}/\texttt{end} pair, and within
+% that we apply operations as a simple scoped statements. To keep down the
+% non-productive groups, we also have a \texttt{begin} version that does take
+% an argument.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ {
+ \__kernel_backend_literal_svg:n { <g> }
+ \int_set_eq:NN
+ \l__kernel_backend_scope_int
+ \g__kernel_backend_scope_int
+ \group_begin:
+ \int_gset:Nn \g__kernel_backend_scope_int { 1 }
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ {
+ \prg_replicate:nn
+ { \g__kernel_backend_scope_int }
+ { \__kernel_backend_literal_svg:n { </g> } }
+ \group_end:
+ \int_gset_eq:NN
+ \g__kernel_backend_scope_int
+ \l__kernel_backend_scope_int
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:n #1
+ {
+ \__kernel_backend_literal_svg:n { <g ~ #1 > }
+ \int_set_eq:NN
+ \l__kernel_backend_scope_int
+ \g__kernel_backend_scope_int
+ \group_begin:
+ \int_gset:Nn \g__kernel_backend_scope_int { 1 }
+ }
+\cs_generate_variant:Nn \__kernel_backend_scope_begin:n { e }
+\cs_new_protected:Npn \__kernel_backend_scope:n #1
+ {
+ \__kernel_backend_literal_svg:n { <g ~ #1 > }
+ \int_gincr:N \g__kernel_backend_scope_int
+ }
+\cs_generate_variant:Nn \__kernel_backend_scope:n { e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-box.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-box.dtx
new file mode 100644
index 00000000000..93d83293ef8
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-box.dtx
@@ -0,0 +1,470 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-box.dtx
+%
+% Copyright (C) 2019-2024 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-box} package\\ Backend box support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-box} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=box>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% The \texttt{dvips} backend scales all absolute dimensions based on the
+% output resolution selected and any \TeX{} magnification. Thus for any
+% operation involving absolute lengths there is a correction to make. See
+% \texttt{normalscale} from \texttt{special.pro} for the variables, noting
+% that here everything is saved on the stack rather than as a separate
+% variable. Once all of that is done, the actual clipping is trivial.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:n { matrix~currentmatrix }
+ \__kernel_backend_literal_postscript:n
+ { Resolution~72~div~VResolution~72~div~scale }
+ \__kernel_backend_literal_postscript:n { DVImag~dup~scale }
+ \__kernel_backend_literal_postscript:e
+ {
+ 0 ~
+ \dim_to_decimal_in_bp:n { \box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { -\box_ht:N #1 - \box_dp:N #1 } ~
+ rectclip
+ }
+ \__kernel_backend_literal_postscript:n { setmatrix }
+ \__kernel_backend_align_end:
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% \begin{macro}{\@@_backend_rotate_aux:Nn}
+% Rotating using \texttt{dvips} does not require that the box dimensions
+% are altered and has a very convenient built-in operation. Zero rotation
+% must be written as |0| not |-0| so there is a quick test.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ { \exp_args:NNf \@@_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \@@_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:e
+ {
+ \fp_compare:nNnTF {#2} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -(#2) , 5 ) } } ~
+ rotate
+ }
+ \__kernel_backend_align_end:
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% The \texttt{dvips} backend once again has a dedicated operation we can
+% use here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:e
+ {
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) } ~
+ scale
+ }
+ \__kernel_backend_align_end:
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backends}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% The general method is to save the current location, define a clipping path
+% equivalent to the bounding box, then insert the content at the current
+% position and in a zero width box. The \enquote{real} width is then made up
+% using a horizontal skip before tidying up. There are other approaches that
+% can be taken (for example using XForm objects), but the logic here shares
+% as much code as possible and uses the same conversions (and so same
+% rounding errors) in all cases.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% \begin{macro}{\@@_backend_rotate_aux:Nn}
+% \begin{variable}{\l_@@_backend_cos_fp, \l_@@_backend_sin_fp}
+% Rotations are set using an affine transformation matrix which therefore
+% requires sine/cosine values not the angle itself. We store the rounded
+% values to avoid rounding twice. There are also a couple of comparisons to
+% ensure that |-0| is not written to the output, as this avoids any issues
+% with problematic display programs. Note that numbers are compared to~$0$
+% after rounding.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ { \exp_args:NNf \@@_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \@@_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \box_set_wd:Nn #1 { 0pt }
+ \fp_set:Nn \l_@@_backend_cos_fp { round ( cosd ( #2 ) , 5 ) }
+ \fp_compare:nNnT \l_@@_backend_cos_fp = \c_zero_fp
+ { \fp_zero:N \l_@@_backend_cos_fp }
+ \fp_set:Nn \l_@@_backend_sin_fp { round ( sind ( #2 ) , 5 ) }
+ \__kernel_backend_matrix:e
+ {
+ \fp_use:N \l_@@_backend_cos_fp \c_space_tl
+ \fp_compare:nNnTF \l_@@_backend_sin_fp = \c_zero_fp
+ { 0~0 }
+ {
+ \fp_use:N \l_@@_backend_sin_fp
+ \c_space_tl
+ \fp_eval:n { -\l_@@_backend_sin_fp }
+ }
+ \c_space_tl
+ \fp_use:N \l_@@_backend_cos_fp
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\fp_new:N \l_@@_backend_cos_fp
+\fp_new:N \l_@@_backend_sin_fp
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% The same idea as for rotation but without the complexity of signs and
+% cosines.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_matrix:e
+ {
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ 0~0~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx}/\XeTeX{} backend}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% The code here is identical to that for \LuaTeX{}/\pdfTeX{}: unlike rotation and
+% scaling, there is no higher-level support in the backend for clipping.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% \begin{macro}{\@@_backend_rotate_aux:Nn}
+% Rotating in \texttt{dvipdmfx}/\XeTeX{} can be implemented using either PDF or
+% backend-specific code. The former approach however is not \enquote{aware}
+% of the content of boxes: this means that any embedded links would not be
+% adjusted by the rotation. As such, the backend-native approach is preferred:
+% the code therefore is similar (though not identical) to the \texttt{dvips}
+% version (notice the rotation angle here is positive). As for
+% \texttt{dvips}, zero rotation is written as |0| not |-0|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ { \exp_args:NNf \@@_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \@@_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#2} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( #2 , 5 ) } }
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% Much the same idea for scaling: use the higher-level backend operation to allow
+% for box content.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% \begin{variable}{\g__kernel_clip_path_int}
+% Clipping in SVG is more involved than with other backends. The first issue
+% is that the clipping path must be defined separately from where it is used,
+% so we need to track how many paths have applied. The naming here uses
+% \texttt{l3cp} as the namespace with a number following. Rather than use
+% a rectangular operation, we define the path manually as this allows it to
+% have a depth: easier than the alternative approach of shifting content
+% up and down using scopes to allow for the depth of the \TeX{} box and
+% keep the reference point the same!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \__kernel_backend_literal_svg:e
+ { < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " > }
+ \__kernel_backend_literal_svg:e
+ {
+ <
+ path ~ d =
+ "
+ M ~ 0 ~
+ \dim_to_decimal:n { -\box_dp:N #1 } ~
+ L ~ \dim_to_decimal:n { \box_wd:N #1 } ~
+ \dim_to_decimal:n { -\box_dp:N #1 } ~
+ L ~ \dim_to_decimal:n { \box_wd:N #1 } ~
+ \dim_to_decimal:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ L ~ 0 ~
+ \dim_to_decimal:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ Z
+ "
+ />
+ }
+ \__kernel_backend_literal_svg:n
+ { < /clipPath > }
+% \end{macrocode}
+% In general the SVG set up does not try to transform coordinates to the
+% current point. For clipping we need to do that, so have a transformation
+% here to get us to the right place, and a matching one just before the
+% \TeX{} box is inserted to get things back on track. The clip path needs to
+% come between those two such that if lines up with the current point, as
+% does the \TeX{} box.
+% \begin{macrocode}
+ \__kernel_backend_scope_begin:n
+ {
+ transform =
+ "
+ translate ( { ?x } , { ?y } ) ~
+ scale ( 1 , -1 )
+ "
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url ( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int ) "
+ }
+ \__kernel_backend_scope:n
+ {
+ transform =
+ "
+ scale ( -1 , 1 ) ~
+ translate ( { ?x } , { ?y } ) ~
+ scale ( -1 , -1 )
+ "
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\int_new:N \g__kernel_clip_path_int
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% Rotation has a dedicated operation which includes a centre-of-rotation
+% optional pair. That can be picked up from the backend syntax, so there is
+% no need to worry about the transformation matrix.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:e
+ {
+ transform =
+ "
+ rotate
+ ( \fp_eval:n { round ( -(#2) , 5 ) } , ~ { ?x } , ~ { ?y } )
+ "
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% In contrast to rotation, we have to account for the current position in this
+% case. That is done using a couple of translations in addition to the scaling
+% (which is therefore done backward with a flip).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:e
+ {
+ transform =
+ "
+ translate ( { ?x } , { ?y } ) ~
+ scale
+ (
+ \fp_eval:n { round ( -#2 , 5 ) } ,
+ \fp_eval:n { round ( -#3 , 5 ) }
+ ) ~
+ translate ( { ?x } , { ?y } ) ~
+ scale ( -1 )
+ "
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-color.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-color.dtx
new file mode 100644
index 00000000000..307432d554f
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-color.dtx
@@ -0,0 +1,1356 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-color.dtx
+%
+% Copyright (C) 2019-2024 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-color} module\\ Backend color support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-color} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=color>
+% \end{macrocode}
+%
+% Color support is split into parts: collecting data from \LaTeXe{}, the color
+% stack, general color, separations, and color for drawings. We have different
+% approaches in each backend, and have some choices to make about
+% \texttt{dvipdfmx}/\XeTeX{} in particular. Whilst it is in some ways
+% convenient to use the same approach in multiple backends, the fact that
+% \texttt{dvipdfmx}/\XeTeX{} is PDF-based means it (largely) sticks closer to
+% direct PDF output.
+%
+% \subsection{The color stack}
+%
+% For PDF-based engines, we have a color stack available inside the specials.
+% This is used for concepts beyond color itself: it is needed to manage the
+% graphics state generally. Although \texttt{dvipdfmx}/\XeTeX{} have multiple
+% color stacks in recent releases, the way these interact with the original
+% single stack and with other graphic state operations means that currently it
+% is not feasible to use the multiple stacks.
+%
+% \subsubsection{Common code}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_backend_stack_int}
+% For tracking which stack is in use where multiple stacks are used:
+% currently just \pdfTeX{}/\LuaTeX{} but at some future stage may also cover
+% \texttt{dvipdfmx}/\XeTeX{}.
+% \begin{macrocode}
+\int_new:N \l_@@_backend_stack_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsubsection{\LuaTeX and \pdfTeX{}}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_color_backend_stack_init:Nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_color_backend_stack_init:Nnn #1#2#3
+ {
+ \int_const:Nn #1
+ {
+%<*luatex>
+ \tex_pdffeedback:D colorstackinit ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfcolorstackinit:D
+%</pdftex>
+ \tl_if_blank:nF {#2} { #2 ~ }
+ {#3}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_color_backend_stack_push:nn}
+% \begin{macro}{\__kernel_color_backend_stack_pop:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D colorstack ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfcolorstack:D
+%</pdftex>
+ \int_eval:n {#1} ~ push ~ {#2}
+ }
+\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D colorstack ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfcolorstack:D
+%</pdftex>
+ \int_eval:n {#1} ~ pop \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{General color}
+%
+% \subsubsection{\texttt{dvips}-style}
+%
+% \begin{macrocode}
+%<*dvips|dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_named:n ,
+% \@@_backend_select_rgb:n ,
+% \@@_backend_select:n
+% }
+% \begin{macro}{\@@_backend_reset:}
+% Push the data to the stack. In the case of \texttt{dvips} also saves the
+% drawing color in raw PostScript. The |spot| model is for handling data
+% in classical format.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_cmyk:n #1
+ { \@@_backend_select:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select_gray:n #1
+ { \@@_backend_select:n { gray ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select_named:n #1
+ { \@@_backend_select:n { ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select_rgb:n #1
+ { \@@_backend_select:n { rgb ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+%<*dvips>
+ \__kernel_backend_postscript:n { /color.sc ~ { } ~ def }
+%</dvips>
+ }
+\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_backend_literal:n { color~pop } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips|dvisvgm>
+% \end{macrocode}
+%
+% \subsubsection{\LuaTeX{} and \pdfTeX{}}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_backend_fill_tl, \l_@@_backend_stroke_tl}
+% \begin{macrocode}
+\tl_new:N \l_@@_backend_fill_tl
+\tl_new:N \l_@@_backend_stroke_tl
+\tl_set:Nn \l_@@_backend_fill_tl { 0 ~ g }
+\tl_set:Nn \l_@@_backend_stroke_tl { 0 ~ G }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_rgb:n
+% }
+% \begin{macro}{\@@_backend_select:nn}
+% \begin{macro}{\@@_backend_reset:}
+% Store the values then pass to the stack.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_cmyk:n #1
+ { \@@_backend_select:nn { #1 ~ k } { #1 ~ K } }
+\cs_new_protected:Npn \@@_backend_select_gray:n #1
+ { \@@_backend_select:nn { #1 ~ g } { #1 ~ G } }
+\cs_new_protected:Npn \@@_backend_select_rgb:n #1
+ { \@@_backend_select:nn { #1 ~ rg } { #1 ~ RG } }
+\cs_new_protected:Npn \@@_backend_select:nn #1#2
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \tl_set:Nn \l_@@_backend_stroke_tl {#2}
+ \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ #2 }
+ }
+\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_color_backend_stack_pop:n \l_@@_backend_stack_int }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsubsection{\texttt{dvipmdfx}/\XeTeX{}}
+%
+% These backends have the most possible approaches: it recognises both
+% \texttt{dvips}-based color specials and its own format, plus one can
+% include PDF statements directly. Recent releases also have a color stack
+% approach similar to \pdfTeX{}. Of the stack methods, the dedicated
+% the most versatile is the latter as it can cover all of the use cases
+% we have. However, at present this interacts problematically with any color
+% on the original stack. We therefore stick to a single-stack approach here.
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select:n ,
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_rgb:n
+% }
+% \begin{macro}{\@@_backend_reset:}
+% Using the single stack is relatively easy as there is only one route.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ [ #1 ] } }
+\cs_new_eq:NN \@@_backend_select_cmyk:n \@@_backend_select:n
+\cs_new_eq:NN \@@_backend_select_gray:n \@@_backend_select:n
+\cs_new_eq:NN \@@_backend_select_rgb:n \@@_backend_select:n
+\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_backend_literal:n { pdf : ec } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select_named:n}
+% For classical named colors, the only value we should get is |Black|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_named:n #1
+ {
+ \str_if_eq:nnTF {#1} { Black }
+ { \@@_backend_select_gray:n { 0 } }
+ { \msg_error:nnn { color } { unknown-named-color } {#1} }
+ }
+\msg_new:nnn { color } { unknown-named-color }
+ { Named~color~'#1'~is~not~known. }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{Separations}
+%
+% Here, life gets interesting and we need essentially one approach per
+% backend.
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex|dvips>
+% \end{macrocode}
+%
+% But we start with some functionality needed for both PostScript and
+% PDF based backends.
+%
+% \begin{variable}{\g_@@_backend_colorant_prop}
+% \begin{macrocode}
+\prop_new:N \g_@@_backend_colorant_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_backend_devicen_colorants:n}
+% \begin{macro}[EXP]{\@@_backend_devicen_colorants:w}
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_devicen_colorants:n #1
+ {
+ \exp_not:N \tl_if_blank:nF {#1}
+ {
+ \c_space_tl
+ << ~
+ /Colorants ~
+ << ~
+ \exp_not:N \@@_backend_devicen_colorants:w #1 ~
+ \exp_not:N \q_recursion_tail \c_space_tl
+ \exp_not:N \q_recursion_stop
+ >> ~
+ >>
+ }
+ }
+\cs_new:Npn \@@_backend_devicen_colorants:w #1 ~
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \prop_if_in:NnT \g_@@_backend_colorant_prop {#1}
+ {
+ #1 ~
+ \prop_item:Nn \g_@@_backend_colorant_prop {#1} ~
+ }
+ \@@_backend_devicen_colorants:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex|dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_select_separation:nn, \@@_backend_select_devicen:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \@@_backend_select:n { separation ~ #1 ~ #2 } }
+\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select_iccbased:nn}
+% No support.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_iccbased:nn #1#2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_separation_init:nnnnn,
+% \@@_backend_separation_init:neenn
+% }
+% \begin{macro}
+% {\@@_backend_separation_init_aux:nnnnnn}
+% \begin{macro}[EXP]
+% {
+% \@@_backend_separation_init_/DeviceCMYK:nnn ,
+% \@@_backend_separation_init_/DeviceGray:nnn ,
+% \@@_backend_separation_init_/DeviceRGB:nnn
+% }
+% \begin{macro}[EXP]{\@@_backend_separation_init_Device:Nn}
+% \begin{macro}[EXP]{\@@_backend_separation_init:nnn}
+% \begin{macro}[EXP]{\@@_backend_separation_init_count:n}
+% \begin{macro}[EXP]{\@@_backend_separation_init_count:w}
+% \begin{macro}[EXP]{\@@_backend_separation_init:nnnn}
+% \begin{macro}[EXP]{\@@_backend_separation_init:w}
+% \begin{macro}[EXP]{\@@_backend_separation_init:n}
+% \begin{macro}[EXP]{\@@_backend_separation_init:nw}
+% \begin{macro}{\@@_backend_separation_init_CIELAB:nnn}
+% Initialising here means creating a small header set up plus massaging
+% some data. This comes about as we have to deal with PDF-focussed data,
+% which makes most sense \enquote{higher-up}. The approach is based on
+% ideas from \url{https://tex.stackexchange.com/q/560093} plus using
+% the PostScript manual for other aspects.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \bool_if:NT \g__kernel_backend_header_bool
+ {
+ \exp_not:N \exp_args:Ne \__kernel_backend_first_shipout:n
+ {
+ \exp_not:N \@@_backend_separation_init_aux:nnnnnn
+ { \exp_not:N \int_use:N \g_@@_model_int }
+ {#1} {#2} {#3} {#4} {#5}
+ }
+ \prop_gput:Nee \exp_not:N \g_@@_backend_colorant_prop
+ { / \exp_not:N \str_convert_pdfname:n {#1} }
+ {
+ << ~
+ /setcolorspace ~ {} ~
+ >> ~ begin ~
+ color \exp_not:N \int_use:N \g_@@_model_int \c_space_tl
+ end
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_backend_separation_init:nnnnn { nee }
+\cs_new_protected:Npn \@@_backend_separation_init_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \__kernel_backend_literal:e
+ {
+ !
+ TeXDict ~ begin ~
+ /color #1
+ {
+ [ ~
+ /Separation ~ ( \str_convert_pdfname:n {#2} ) ~
+ [ ~ #3 ~ ] ~
+ {
+ \cs_if_exist_use:cF { @@_backend_separation_init_ #3 :nnn }
+ { \@@_backend_separation_init:nnn }
+ {#4} {#5} {#6}
+ }
+ ] ~ setcolorspace
+ } ~ def ~
+ end
+ }
+ }
+\cs_new:cpn { @@_backend_separation_init_ /DeviceCMYK :nnn } #1#2#3
+ { \@@_backend_separation_init_Device:Nn 4 {#3} }
+\cs_new:cpn { @@_backend_separation_init_ /DeviceGray :nnn } #1#2#3
+ { \@@_backend_separation_init_Device:Nn 1 {#3} }
+\cs_new:cpn { @@_backend_separation_init_ /DeviceRGB :nnn } #1#2#3
+ { \@@_backend_separation_init_Device:Nn 2 {#3} }
+\cs_new:Npn \@@_backend_separation_init_Device:Nn #1#2
+ {
+ #2 ~
+ \prg_replicate:nn {#1}
+ { #1 ~ index ~ mul ~ #1 ~ 1 ~ roll ~ }
+ \int_eval:n { #1 + 1 } ~ -1 ~ roll ~ pop
+ }
+% \end{macrocode}
+% For the generic case, we cannot use |/FunctionType 2| unfortunately, so
+% we have to code that idea up in PostScript. Here, we will therefore assume
+% that a range is \emph{always} given. First, we count values in each argument:
+% at the backend level, we can assume there are always well-behaved with
+% spaces present.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_separation_init:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_backend_separation_init:nnnn
+ { \@@_backend_separation_init_count:n {#2} }
+ {#1} {#2} {#3}
+ }
+\cs_new:Npn \@@_backend_separation_init_count:n #1
+ { \int_eval:n { 0 \@@_backend_separation_init_count:w #1 ~ \s_@@_stop } }
+\cs_new:Npn \@@_backend_separation_init_count:w #1 ~ #2 \s_@@_stop
+ {
+ +1
+ \tl_if_blank:nF {#2}
+ { \@@_backend_separation_init_count:w #2 \s_@@_stop }
+ }
+% \end{macrocode}
+% Now we implement the algorithm. In the terms in the PostScript manual,
+% we have $\mathbf{N} = 1$ and $\mathbf{Domain} = [0~1]$, with
+% $\mathbf{Range}$ as |#2|, $\mathbf{C0}$ as |#3| and $\mathbf{C1}$
+% as |#4|, with the number of output components in |#1|. So all we have
+% to do is implement $y_{i} = \mathbf{C0}_{i} + x(\mathbf{C1}_{i} -
+% \mathbf{C0}_{i})$ with lots of stack manipulation, then check the
+% ranges. That's done by adding everything to the stack first, then using
+% the fact we know all of the offsets. As manipulating the stack is tricky,
+% we start by re-formatting the $\mathbf{C0}$ and $\mathbf{C1}$ arrays to
+% be interleaved, and add a \texttt{0} to each pair: this is used
+% to keep the stack of constant length while we are doing the first pass of
+% mathematics. We then working through that list, calculating from the
+% last to the first value before tidying up by removing all of the input
+% values. We do that by first copying all of the final $y$ values to the
+% end of the stack, then rolling everything so we can pop the now-unneeded
+% material.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_separation_init:nnnn #1#2#3#4
+ {
+ \@@_backend_separation_init:w #3 ~ \s_@@_stop #4 ~ \s_@@_stop
+ \prg_replicate:nn {#1}
+ {
+ pop ~ 1 ~ index ~ neg ~ 1 ~ index ~ add ~
+ \int_eval:n { 3 * #1 } ~ index ~ mul ~
+ 2 ~ index ~ add ~
+ \int_eval:n { 3 * #1 } ~ #1 ~ roll ~
+ }
+ \int_step_function:nnnN {#1} { -1 } { 1 }
+ \@@_backend_separation_init:n
+ \int_eval:n { 4 * #1 + 1 } ~ #1 ~ roll ~
+ \prg_replicate:nn { 3 * #1 + 1 } { pop ~ }
+ \tl_if_blank:nF {#2}
+ { \@@_backend_separation_init:nw {#1} #2 ~ \s_@@_stop }
+ }
+\cs_new:Npn \@@_backend_separation_init:w
+ #1 ~ #2 \s_@@_stop #3 ~ #4 \s_@@_stop
+ {
+ #1 ~ #3 ~ 0 ~
+ \tl_if_blank:nF {#2}
+ { \@@_backend_separation_init:w #2 \s_@@_stop #4 \s_@@_stop }
+ }
+\cs_new:Npn \@@_backend_separation_init:n #1
+ { \int_eval:n { #1 * 2 } ~ index ~ }
+% \end{macrocode}
+% Finally, we deal with the range limit if required. This is handled
+% by splitting the range into pairs. It's then just a question of doing
+% the comparisons, this time dropping everything except the desired
+% result.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_separation_init:nw #1#2 ~ #3 ~ #4 \s_@@_stop
+ {
+ #2 ~ #3 ~
+ 2 ~ index ~ 2 ~ index ~ lt ~
+ { ~ pop ~ exch ~ pop ~ } ~
+ { ~
+ 2 ~ index ~ 1 ~ index ~ gt ~
+ { ~ exch ~ pop ~ exch ~ pop ~ } ~
+ { ~ pop ~ pop ~ } ~
+ ifelse ~
+ }
+ ifelse ~
+ #1 ~ 1 ~ roll ~
+ \tl_if_blank:nF {#4}
+ { \@@_backend_separation_init:nw {#1} #4 \s_@@_stop }
+ }
+% \end{macrocode}
+% CIELAB support uses the detail from the PostScript reference, page 227;
+% other than that block of PostScript, this is the same as for PDF-based
+% routes.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \@@_backend_separation_init:neenn
+ {#2}
+ {
+ /CIEBasedABC ~
+ << ~
+ /RangeABC ~ [ ~ \c_@@_model_range_CIELAB_tl \c_space_tl ] ~
+ /DecodeABC ~
+ [ ~
+ { ~ 16 ~ add ~ 116 ~ div ~ } ~ bind ~
+ { ~ 500 ~ div ~ } ~ bind ~
+ { ~ 200 ~ div ~ } ~ bind ~
+ ] ~
+ /MatrixABC ~ [ ~ 1 ~ 1 ~ 1 ~ 1 ~ 0 ~ 0 ~ 0 ~ 0 ~ -1 ~ ] ~
+ /DecodeLMN ~
+ [ ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ 0.9505 ~ mul ~
+ } ~ bind ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ } ~ bind ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ 1.0890 ~ mul ~
+ } ~ bind
+ ] ~
+ /WhitePoint ~
+ [ ~ \tl_use:c { c_@@_model_whitepoint_CIELAB_ #1 _tl } ~ ] ~
+ >>
+ }
+ { \c_@@_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_devicen_init:nnn}
+% Trivial as almost all of the work occurs in the shared code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3
+ {
+ \__kernel_backend_literal:e
+ {
+ !
+ TeXDict ~ begin ~
+ /color \int_use:N \g_@@_model_int
+ {
+ [ ~
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ { ~ #3 ~ } ~
+ \@@_backend_devicen_colorants:n {#1}
+ ] ~ setcolorspace
+ } ~ def ~
+ end
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_iccbased_init:nnn}
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_separation:nn,
+% \@@_backend_select_devicen:nn
+% }
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 { }
+\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_separation_init:nnnnn, \@@_backend_separation_init_CIELAB:nnn}
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 { }
+\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnnnnn #1#2#3 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select_iccbased:nn}
+% As detailed in \url{https://www.w3.org/TR/css-color-4/#at-profile},
+% we can apply a color profile using CSS. As we have a local file, we use
+% a relative URL.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_iccbased:nn #1#2
+ {
+ \__kernel_backend_literal_svg:e
+ {
+ <style>
+ @color-profile ~
+ \str_if_eq:nnTF {#2} { cmyk }
+ { device-cmyk }
+ { --color \int_use:N \g_@@_model_int }
+ \c_space_tl
+ {
+ src:("#1")
+ }
+ </style>
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_separation:nn,
+% \@@_backend_select_devicen:nn ,
+% \@@_backend_select_iccbased:nn
+% }
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \__kernel_backend_literal:e { pdf : bc ~ \pdf_object_ref:n {#1} ~ [ #2 ] } }
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \@@_backend_select:nn { /#1 ~ cs ~ #2 ~ scn } { /#1 ~ CS ~ #2 ~ SCN } }
+%</luatex|pdftex>
+\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
+\cs_new_eq:NN \@@_backend_select_iccbased:nn \@@_backend_select_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_init_resource:n}
+% Resource initiation comes up a few times. For \texttt{dvipdfmx}/\XeTeX{},
+% we skip this as at present it's handled by the backend.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_init_resource:n #1
+ {
+%<*luatex|pdftex>
+ \bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \use:e
+ {
+ \pdfmanagement_add:nnn
+ { Page / Resources / ColorSpace }
+ { #1 }
+ { \pdf_object_ref_last: }
+ }
+ }
+%</luatex|pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_separation_init:nnnnn}
+% \begin{macro}{\@@_backend_separation_init:nn}
+% \begin{macro}{\@@_backend_separation_init_CIELAB:nnn}
+% Initialising the PDF structures needs two parts: creating an object
+% containing the \enquote{real} name of the Separation, then adding a reference
+% to that to each page. We use a separate object for the tint transformation
+% following the model in the PDF reference. The object here for the color
+% needs to be named as that way it's accessible to
+% \texttt{dvipdfmx}/\XeTeX{}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \pdf_object_unnamed_write:ne { dict }
+ {
+ /FunctionType ~ 2
+ /Domain ~ [0 ~ 1]
+ \tl_if_blank:nF {#3} { /Range ~ [#3] }
+ /C0 ~ [#4] ~
+ /C1 ~ [#5] /N ~ 1
+ }
+ \exp_args:Ne \@@_backend_separation_init:nn
+ { \str_convert_pdfname:n {#1} } {#2}
+ \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int }
+ }
+\cs_new_protected:Npn \@@_backend_separation_init:nn #1#2
+ {
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g_@@_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g_@@_model_int } { array }
+ { /Separation /#1 ~ #2 ~ \pdf_object_ref_last: }
+ }
+ \prop_gput:Nne \g_@@_backend_colorant_prop { /#1 }
+ { \pdf_object_ref_last: }
+ }
+% \end{macrocode}
+% For CIELAB colors, we need one object per document for the illuminant,
+% plus initialisation of the color space referencing that object.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { @@_illuminant_CIELAB_ #1 }
+ {
+ \pdf_object_new:n { @@_illuminant_CIELAB_ #1 }
+ \pdf_object_write:nne { @@_illuminant_CIELAB_ #1 } { array }
+ {
+ /Lab ~
+ <<
+ /WhitePoint ~
+ [ \tl_use:c { c_@@_model_whitepoint_CIELAB_ #1 _tl } ]
+ /Range ~ [ \c_@@_model_range_CIELAB_tl ]
+ >>
+ }
+ }
+ \@@_backend_separation_init:nnnnn
+ {#2}
+ { \pdf_object_ref:n { @@_illuminant_CIELAB_ #1 } }
+ { \c_@@_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_devicen_init:nnn}
+% \begin{macro}[EXP]{\@@_backend_devicen_init:w}
+% Similar to the Separations case, but with an arbitrary function for
+% the alternative space work.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3
+ {
+ \pdf_object_unnamed_write:ne { stream }
+ {
+ {
+ /FunctionType ~ 4 ~
+ /Domain ~
+ [ ~
+ \prg_replicate:nn
+ { 0 \@@_backend_devicen_init:w #1 ~ \s_@@_stop }
+ { 0 ~ 1 ~ }
+ ] ~
+ /Range ~
+ [ ~
+ \str_case:nn {#2}
+ {
+ { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ { /DeviceGray } { 0 ~ 1 }
+ { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ } ~
+ ]
+ }
+ { {#3} }
+ }
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g_@@_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g_@@_model_int } { array }
+ {
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ \pdf_object_ref_last:
+ \@@_backend_devicen_colorants:n {#1}
+ }
+ }
+ \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int }
+ }
+\cs_new:Npn \@@_backend_devicen_init:w #1 ~ #2 \s_@@_stop
+ {
+ + 1
+ \tl_if_blank:nF {#2}
+ { \@@_backend_devicen_init:w #2 \s_@@_stop }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_iccbased_init:nnn}
+% Lots of data to save here: we only want to do that once per file,
+% so track it by name.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { @@_icc_ #1 }
+ {
+ \pdf_object_new:n { @@_icc_ #1 }
+ \pdf_object_write:nne { @@_icc_ #1 } { fstream }
+ {
+ {
+ /N ~ \exp_not:n { #2 } ~
+ \tl_if_empty:nF { #3 } { /Range~[ #3 ] }
+ }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { @@_icc_ #1 } }
+ \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_iccbased_device:nnn}
+% This is very similar to setting up a color space: the only part we
+% add to the page resources differently.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_iccbased_device:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { @@_icc_ #1 }
+ {
+ \pdf_object_new:n { @@_icc_ #1 }
+ \pdf_object_write:nnn { @@_icc_ #1 } { fstream }
+ {
+ { /N ~ #3 }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { @@_icc_ #1 } }
+ \@@_backend_init_resource:n { Default #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \subsection{Fill and stroke color}
+%
+% Here, \texttt{dvipdfmx}/\XeTeX{} we write direct PDF specials for the fill,
+% and only use the stack for the stroke color (see above for comments on why
+% we cannot use multiple stacks with these backends). \LuaTeX{} and \pdfTeX{}
+% have mutiple stacks that can deal with fill and stroke. For \texttt{dvips}
+% we have to manage fill and stroke color ourselves. We also handle
+% \texttt{dvisvgm} independently, as there we can create SVG directly.
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill:n ,
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_stroke:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ fill ~ [ #1 ] } }
+\cs_new_eq:NN \@@_backend_fill_cmyk:n \@@_backend_fill:n
+\cs_new_eq:NN \@@_backend_fill_gray:n \@@_backend_fill:n
+\cs_new_eq:NN \@@_backend_fill_rgb:n \@@_backend_fill:n
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ stroke ~ [ #1 ] } }
+\cs_new_eq:NN \@@_backend_stroke_cmyk:n \@@_backend_stroke:n
+\cs_new_eq:NN \@@_backend_stroke_gray:n \@@_backend_stroke:n
+\cs_new_eq:NN \@@_backend_stroke_rgb:n \@@_backend_stroke:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ fill ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ stroke ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_eq:NN \@@_backend_stroke_reset: \@@_backend_reset:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_fill:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n ,
+% \@@_backend_stroke:n
+% }
+% Drawing (fill/stroke) color is handled in \texttt{dvipdfmx}/\XeTeX{} in the
+% same way as \LuaTeX{}/\pdfTeX{}. We use the same approach as earlier, except the
+% color stack is not involved so the generic direct PDF operation is used.
+% There is no worry about the nature of strokes: everything is handled
+% automatically.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \@@_backend_fill:n { #1 ~ k } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \@@_backend_fill:n { #1 ~ g } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \@@_backend_fill:n { #1 ~ rg } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int
+ { #1 ~ \l_@@_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \@@_backend_stroke:n { #1 ~ K } }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ { \@@_backend_stroke:n { #1 ~ G } }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \@@_backend_stroke:n { #1 ~ RG } }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ {
+ \tl_set:Nn \l_@@_backend_stroke_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int
+ { \l_@@_backend_fill_tl \c_space_tl #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2
+ { \@@_backend_fill:n { /#1 ~ cs ~ #2 ~ scn } }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
+ { \@@_backend_stroke:n { /#1 ~ CS ~ #2 ~ SCN } }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_eq:NN \@@_backend_stroke_reset: \@@_backend_reset:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_fill:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n
+% }
+% Fill color here is the same as general color \emph{except} we skip the
+% stroke part.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \@@_backend_fill:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \@@_backend_fill:n { gray ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \@@_backend_fill:n { rgb ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setcmykcolor } def } }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setgray } def } }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setrgbcolor } def } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2
+ { \@@_backend_fill:n { separation ~ #1 ~ #2 } }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
+ { \__kernel_backend_postscript:n { /color.sc { separation ~ #1 ~ #2 } def } }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_protected:Npn \@@_backend_stroke_reset: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_fill:n
+% }
+% Fill color here is the same as general color \emph{except} we skip the
+% stroke part.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \@@_backend_fill:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \@@_backend_fill:n { gray ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \@@_backend_fill:n { rgb ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_stroke_cmyk:n}
+% \begin{macro}{\@@_backend_stroke_cmyk:w}
+% \begin{macro}{\@@_backend_stroke_gray:n, \@@_backend_stroke_gray_aux:n}
+% \begin{macro}{\@@_backend_stroke_rgb:n}
+% \begin{macro}{\@@_backend_stroke_rgb:w}
+% \begin{macro}{\@@_backend:nnn}
+% For drawings in SVG, we use scopes for all stroke colors. That
+% requires using \texttt{RGB} values, which luckily are easy to
+% convert here (|cmyk| to |RGB| is a fixed function).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \@@_backend_cmyk:w #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:w
+ #1 ~ #2 ~ #3 ~ #4 \s_@@_stop
+ {
+ \use:e
+ {
+ \@@_backend:nnn
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #1 + #4 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #2 + #4 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #3 + #4 ) ) } }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ {
+ \use:e
+ {
+ \@@_backend_stroke_gray_aux:n
+ { \fp_eval:n { 100 * (#1) } }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_gray_aux:n #1
+ { \@@_backend:nnn {#1} {#1} {#1} }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \@@_backend_rgb:w #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:w
+ #1 ~ #2 ~ #3 \s_@@_stop
+ {
+ \use:e
+ {
+ \@@_backend:nnn
+ { \fp_eval:n { 100 * (#1) } }
+ { \fp_eval:n { 100 * (#2) } }
+ { \fp_eval:n { 100 * (#3) } }
+ }
+ }
+\cs_new_protected:Npe \@@_backend:nnn #1#2#3
+ {
+ \__kernel_backend_scope:n
+ {
+ stroke =
+ "
+ rgb
+ (
+ #1 \c_percent_str ,
+ #2 \c_percent_str ,
+ #3 \c_percent_str
+ )
+ "
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% At present, these are no-ops.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 { }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_protected:Npn \@@_backend_stroke_reset: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_devicen_init:nnn, \@@_backend_iccbased_init:nnn}
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \subsection{Font handling integration}
+%
+% In \LuaTeX{} these colors should also be usable to color fonts, so
+% \texttt{luaotfload} color handling is extended to include these.
+%
+% \begin{macrocode}
+%<*lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+local l = lpeg
+local spaces = l.P' '^0
+local digit16 = l.R('09', 'af', 'AF')
+
+local octet = digit16 * digit16 / function(s)
+ return string.format('%.3g ', tonumber(s, 16) / 255)
+end
+
+if luaotfload and luaotfload.set_transparent_colorstack then
+ local htmlcolor = l.Cs(octet * octet * octet * -1 * l.Cc'rg')
+ local color_export = {
+ token.create'tex_endlocalcontrol:D',
+ token.create'tex_hpack:D',
+ token.new(0, 1),
+ token.create'color_export:nnN',
+ token.new(0, 1),
+ '',
+ token.new(0, 2),
+ token.new(0, 1),
+ 'backend',
+ token.new(0, 2),
+ token.create'l_tmpa_tl',
+ token.create'exp_after:wN',
+ token.create'@@_select:nn',
+ token.create'l_tmpa_tl',
+ token.new(0, 2),
+ }
+ local group_end = token.create'group_end:'
+ local value = (1 - l.P'}')^0
+ luatexbase.add_to_callback('luaotfload.parse_color', function (value)
+% Also allow HTML colors to preserve compatibility
+ local html = htmlcolor:match(value)
+ if html then return html end
+
+% If no l3color named color with this name is known, check for defined xcolor colors
+ local l3color_prop = token.get_macro(string.format('l_@@_named_%s_prop', value))
+ if l3color_prop == nil or l3color_prop == '' then
+ local legacy_color_macro = token.create(string.format('\\color@%s', value))
+ if legacy_color_macro.cmdname ~= 'undefined_cs' then
+ token.put_next(legacy_color_macro)
+ return token.scan_argument()
+ end
+ end
+
+ tex.runtoks(function()
+ token.get_next()
+ color_export[6] = value
+ tex.sprint(-2, color_export)
+ end)
+ local list = token.scan_list()
+ if not list.head or list.head.next
+ or list.head.subtype ~= node.subtype'pdf_colorstack' then
+ error'Unexpected backend behavior'
+ end
+ local cmd = list.head.data
+ node.free(list)
+ return cmd
+ end, 'l3color')
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*luatex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\lua_load_module:n {l3backend-luatex}
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</luatex>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-draw.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-draw.dtx
new file mode 100644
index 00000000000..c651ab92fed
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-draw.dtx
@@ -0,0 +1,1067 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-draw.dtx
+%
+% Copyright (C) 2019-2024 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-draw} package\\ Backend drawing support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-draw} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=draw>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
+% The same as literal PostScript: same arguments about positioning apply
+% here.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_postscript:n
+\cs_generate_variant:Nn \@@_backend_literal:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
+% The |ps::[begin]| special here deals with positioning but allows us to
+% continue on to a matching |ps::[end]|: contrast with |ps:|, which positions
+% but where we can't split material between separate calls. The
+% |@beginspecial|/|@endspecial| pair are from |special.pro| and correct the
+% scale and $y$-axis direction.
+% As for \pkg{pgf}, we need to save the current point as this is
+% required for box placement. (Note that
+% |@beginspecial|/|@endspecial| forms a backend scope.)
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_begin:
+ {
+ \@@_backend_literal:n { [begin] }
+ \@@_backend_literal:n { /draw.x~currentpoint~/draw.y~exch~def~def }
+ \@@_backend_literal:n { @beginspecial }
+ }
+\cs_new_protected:Npn \@@_backend_end:
+ {
+ \@@_backend_literal:n { @endspecial }
+ \@@_backend_literal:n { [end] }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
+% Scope here may need to contain saved definitions, so the entire memory
+% rather than just the graphic state has to be sent to the stack.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scope_begin:
+ { \@@_backend_literal:n { save } }
+\cs_new_protected:Npn \@@_backend_scope_end:
+ { \@@_backend_literal:n { restore } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
+% \begin{macro}{\@@_backend_rectangle:nnnn}
+% \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
+% 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.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~
+ \dim_to_decimal_in_bp:n {#2} ~ moveto
+ }
+ }
+\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~
+ \dim_to_decimal_in_bp:n {#2} ~ lineto
+ }
+ }
+\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#4} ~ \dim_to_decimal_in_bp:n {#3} ~
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ moveto~dup~0~rlineto~exch~0~exch~rlineto~neg~0~rlineto~closepath
+ }
+ }
+\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ curveto
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
+% \begin{variable}{\g_@@_draw_eor_bool}
+% The even-odd rule here can be implemented as a simply switch.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_evenodd_rule:
+ { \bool_gset_true:N \g_@@_draw_eor_bool }
+\cs_new_protected:Npn \@@_backend_nonzero_rule:
+ { \bool_gset_false:N \g_@@_draw_eor_bool }
+\bool_new:N \g_@@_draw_eor_bool
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_closepath: ,
+% \@@_backend_stroke: ,
+% \@@_backend_closestroke: ,
+% \@@_backend_fill: ,
+% \@@_backend_fillstroke: ,
+% \@@_backend_clip: ,
+% \@@_backend_discardpath:
+% }
+% \begin{variable}{\g_@@_draw_clip_bool}
+% Unlike PDF, PostScript doesn't track separate colors for strokes and other
+% elements. It is also desirable to have the |clip| keyword after a stroke or
+% fill. To achieve those outcomes, there is some work to do. For color, the
+% stoke color is simple but the fill one has to be inserted by hand. For
+% clipping, the required ordering is achieved using a \TeX{} switch. All of
+% the operations end with a new path instruction as they do not terminate
+% (again in contrast to PDF).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_closepath:
+ { \@@_backend_literal:n { closepath } }
+\cs_new_protected:Npn \@@_backend_stroke:
+ {
+ \@@_backend_literal:n { gsave }
+ \@@_backend_literal:n { color.sc }
+ \@@_backend_literal:n { stroke }
+ \@@_backend_literal:n { grestore }
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\cs_new_protected:Npn \@@_backend_closestroke:
+ {
+ \@@_backend_closepath:
+ \@@_backend_stroke:
+ }
+\cs_new_protected:Npn \@@_backend_fill:
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ fill
+ }
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\cs_new_protected:Npn \@@_backend_fillstroke:
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ fill
+ }
+ \@@_backend_literal:n { gsave }
+ \@@_backend_literal:n { color.sc }
+ \@@_backend_literal:n { stroke }
+ \@@_backend_literal:n { grestore }
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\cs_new_protected:Npn \@@_backend_clip:
+ { \bool_gset_true:N \g_@@_draw_clip_bool }
+\bool_new:N \g_@@_draw_clip_bool
+\cs_new_protected:Npn \@@_backend_discardpath:
+ {
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_dash_pattern:nn}
+% \begin{macro}{\@@_backend_dash:n}
+% \begin{macro}{\@@_backend_linewidth:n}
+% \begin{macro}{\@@_backend_miterlimit:n}
+% \begin{macro}
+% {
+% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
+% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PostScript operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \@@_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ setdash
+ }
+ }
+\cs_new:Npn \@@_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \@@_backend_linewidth:n #1
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ setlinewidth }
+ }
+\cs_new_protected:Npn \@@_backend_miterlimit:n #1
+ { \@@_backend_literal:n { #1 ~ setmiterlimit } }
+\cs_new_protected:Npn \@@_backend_cap_butt:
+ { \@@_backend_literal:n { 0 ~ setlinecap } }
+\cs_new_protected:Npn \@@_backend_cap_round:
+ { \@@_backend_literal:n { 1 ~ setlinecap } }
+\cs_new_protected:Npn \@@_backend_cap_rectangle:
+ { \@@_backend_literal:n { 2 ~ setlinecap } }
+\cs_new_protected:Npn \@@_backend_join_miter:
+ { \@@_backend_literal:n { 0 ~ setlinejoin } }
+\cs_new_protected:Npn \@@_backend_join_round:
+ { \@@_backend_literal:n { 1 ~ setlinejoin } }
+\cs_new_protected:Npn \@@_backend_join_bevel:
+ { \@@_backend_literal:n { 2 ~ setlinejoin } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_backend_cm:nnnn}
+% 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
+% 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
+ {
+ \@@_backend_literal:n
+ { [ #1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_box_use:Nnnnn}
+% Inside a picture |@beginspecial|/|@endspecial| are active, which is
+% normally a good thing but means that the position and scaling would be off
+% if the box was inserted directly. To deal with that, there are a number of
+% possible approaches. A previous implementation suggested by Tom Rokici
+% used |@endspecial|/|@beginspecial|. This avoids needing internals of
+% \texttt{dvips}, but fails if there the box is used inside a scope
+% (see \url{https://github.com/latex3/latex3/issues/1504}). Instead,
+% we use the same method as \pkg{pgf}, which means tracking the position
+% at the PostScript level. Also note that using |@endspecial| would
+% close the scope it creates, meaning that after a box insertion, any
+% local changes would be lost. Keeping \texttt{dvips} on track is
+% non-trivial, hence the |[begin]|/|[end]| pair before the
+% |save| and around the |restore|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \@@_backend_literal:n { save }
+ \@@_backend_literal:n { 72~Resolution~div~72~VResolution~div~neg~scale }
+ \@@_backend_literal:n { magscale { 1~DVImag~div~dup~scale } if }
+ \@@_backend_literal:n { draw.x~neg~draw.y~neg~translate }
+ \@@_backend_literal:n { [end] }
+ \@@_backend_literal:n { [begin] }
+ \@@_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_literal:n { neg~exch~neg~exch~translate }
+ \@@_backend_literal:n { [end] }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \@@_backend_literal:n { [begin] }
+ \@@_backend_literal:n { restore }
+ \@@_backend_literal:n { [end] }
+ \@@_backend_literal:n { [begin] }
+ \@@_backend_literal:n { restore }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{}, \pdfTeX{}, \texttt{dvipdfmx} and \XeTeX{}}
+%
+% \LuaTeX{}, \pdfTeX{}, \texttt{dvipdfmx} and \XeTeX{} directly produce PDF output
+% and understand a shared set of specials for drawing commands.
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \subsubsection{Drawing}
+%
+% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
+% 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 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
+% No special requirements here, so simply set up a drawing scope.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_begin:
+ { \@@_backend_scope_begin: }
+\cs_new_protected:Npn \@@_backend_end:
+ { \@@_backend_scope_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
+% Use the backend-level scope mechanisms.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \@@_backend_scope_end: \__kernel_backend_scope_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
+% \begin{macro}{\@@_backend_curveto:nnnnnn}
+% \begin{macro}{\@@_backend_rectangle:nnnn}
+% Path creation operations all resolve directly to PDF primitive steps, with
+% only the need to convert to \texttt{bp}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
+ }
+\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
+ }
+\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ c
+ }
+ }
+\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ re
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
+% \begin{variable}{\g_@@_draw_eor_bool}
+% The even-odd rule here can be implemented as a simply switch.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_evenodd_rule:
+ { \bool_gset_true:N \g_@@_draw_eor_bool }
+\cs_new_protected:Npn \@@_backend_nonzero_rule:
+ { \bool_gset_false:N \g_@@_draw_eor_bool }
+\bool_new:N \g_@@_draw_eor_bool
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_closepath: ,
+% \@@_backend_stroke: ,
+% \@@_backend_closestroke: ,
+% \@@_backend_fill: ,
+% \@@_backend_fillstroke: ,
+% \@@_backend_clip: ,
+% \@@_backend_discardpath:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PDF operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_closepath:
+ { \@@_backend_literal:n { h } }
+\cs_new_protected:Npn \@@_backend_stroke:
+ { \@@_backend_literal:n { S } }
+\cs_new_protected:Npn \@@_backend_closestroke:
+ { \@@_backend_literal:n { s } }
+\cs_new_protected:Npn \@@_backend_fill:
+ {
+ \@@_backend_literal:e
+ { f \bool_if:NT \g_@@_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \@@_backend_fillstroke:
+ {
+ \@@_backend_literal:e
+ { B \bool_if:NT \g_@@_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \@@_backend_clip:
+ {
+ \@@_backend_literal:e
+ { W \bool_if:NT \g_@@_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \@@_backend_discardpath:
+ { \@@_backend_literal:n { n } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_dash_pattern:nn}
+% \begin{macro}{\@@_backend_dash:n}
+% \begin{macro}{\@@_backend_linewidth:n}
+% \begin{macro}{\@@_backend_miterlimit:n}
+% \begin{macro}
+% {
+% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
+% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PDF operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \@@_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ d
+ }
+ }
+\cs_new:Npn \@@_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \@@_backend_linewidth:n #1
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ w }
+ }
+\cs_new_protected:Npn \@@_backend_miterlimit:n #1
+ { \@@_backend_literal:e { #1 ~ M } }
+\cs_new_protected:Npn \@@_backend_cap_butt:
+ { \@@_backend_literal:n { 0 ~ J } }
+\cs_new_protected:Npn \@@_backend_cap_round:
+ { \@@_backend_literal:n { 1 ~ J } }
+\cs_new_protected:Npn \@@_backend_cap_rectangle:
+ { \@@_backend_literal:n { 2 ~ J } }
+\cs_new_protected:Npn \@@_backend_join_miter:
+ { \@@_backend_literal:n { 0 ~ j } }
+\cs_new_protected:Npn \@@_backend_join_round:
+ { \@@_backend_literal:n { 1 ~ j } }
+\cs_new_protected:Npn \@@_backend_join_bevel:
+ { \@@_backend_literal:n { 2 ~ j } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_cm:nnnn}
+% \begin{macro}{\@@_backend_cm_aux:nnnn}
+% 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
+% matrix into rotations and a scaling, then use those operations as they
+% are handled by the backend. (There is backend support for matrix operations in
+% \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!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_cm: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
+%</dvipdfmx|xetex>
+ }
+%<*dvipdfmx|xetex>
+\cs_new_protected:Npn \@@_backend_cm_aux:nnnn #1#2#3#4
+ {
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#1} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#1 , 5 ) } }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#4} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#4 , 5 ) } }
+ }
+ }
+%</dvipdfmx|xetex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_cm_decompose:nnnnN}
+% \begin{macro}
+% {
+% \@@_backend_cm_decompose_auxi:nnnnN,
+% \@@_backend_cm_decompose_auxii:nnnnN,
+% \@@_backend_cm_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
+% engine looses track of positions (for example for hyperlinks), and this is
+% not desirable. They do, however, allow us to track rotations and scalings.
+% Luckily, we can decompose any (two-dimensional) matrix into two rotations
+% and a single scaling:
+% \[
+% \begin{bmatrix}
+% A & B \\ C & D
+% \end{bmatrix}
+% =
+% \begin{bmatrix}
+% \cos\beta & \sin\beta \\ -\sin\beta & \cos\beta
+% \end{bmatrix}
+% \begin{bmatrix}
+% w_{1} & 0 \\ 0 & w_{2}
+% \end{bmatrix}
+% \begin{bmatrix}
+% \cos\gamma & \sin\gamma \\ -\sin\gamma & \cos\gamma
+% \end{bmatrix}
+% \]
+% The parent matrix can be converted to
+% \[
+% \begin{bmatrix}
+% A & B \\ C & D
+% \end{bmatrix}
+% =
+% \begin{bmatrix}
+% E & H \\-H & E
+% \end{bmatrix}
+% +
+% \begin{bmatrix}
+% F & G \\ G & -F
+% \end{bmatrix}
+% \]
+% From these, we can find that
+% \begin{align*}
+% \frac{w_{1} + w_{2}}{2} &= \sqrt{E^{2} + H^{2}} \\
+% \frac{w_{1} - w_{2}}{2} &= \sqrt{F^{2} + G^{2}} \\
+% \gamma - \beta &= \tan^{-1}(G/F) \\
+% \gamma + \beta &= \tan^{-1}(H/E)
+% \end{align*}
+% at which point we just have to do various pieces of re-arrangement to
+% get all of the values. (See J.~Blinn, \emph{IEEE Comput.\ Graph.\ Appl.},
+% 1996, \textbf{16}, 82--88.) There is one wrinkle: the PostScript (and PDF)
+% way of specifying a transformation matrix exchanges where one would
+% normally expect $B$ and $C$ to be.
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+\cs_new_protected:Npn \@@_backend_cm_decompose:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_cm_decompose_auxi:nnnnN
+ { \fp_eval:n { (#1 + #4) / 2 } }
+ { \fp_eval:n { (#1 - #4) / 2 } }
+ { \fp_eval:n { (#3 + #2) / 2 } }
+ { \fp_eval:n { (#3 - #2) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \@@_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_cm_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 ) } }
+ { \fp_eval:n { atand ( #4 , #1 ) } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \@@_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_cm_decompose_auxiii:nnnnN
+ { \fp_eval:n { ( #4 - #3 ) / 2 } }
+ { \fp_eval:n { ( #1 + #2 ) / 2 } }
+ { \fp_eval:n { ( #1 - #2 ) / 2 } }
+ { \fp_eval:n { ( #4 + #3 ) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \@@_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
+ {
+ \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
+ { #5 {#1} {#2} {#3} {#4} }
+ { #5 {#1} {#3} {#2} {#4} }
+ }
+%</dvipdfmx|xetex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_box_use:Nnnnn}
+% Inserting a \TeX{} box transformed to the requested position and using
+% the current matrix is done using a mixture of \TeX{} and low-level
+% manipulation. The offset can be handled by \TeX{}, so only any rotation/^^A
+% skew/scaling component needs to be done using the matrix operation. As this
+% operation can never be cached, the scope is set directly not using the
+% \texttt{draw} version.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \__kernel_backend_scope_begin:
+%<*luatex|pdftex>
+ \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
+%</luatex|pdftex>
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal:n
+ { pdf:btrans~matrix~ #2 ~ #3 ~ #4 ~ #5 ~ 0 ~ 0 }
+%</dvipdfmx|xetex>
+ \hbox_overlap_right:n { \box_use:N #1 }
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal:n { pdf:etrans }
+%</dvipdfmx|xetex>
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
+% The same as the more general literal call.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_svg:n
+\cs_generate_variant:Nn \@@_backend_literal:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
+% Use the backend-level scope mechanisms.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \@@_backend_scope_end: \__kernel_backend_scope_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
+% A drawing needs to be set up such that the co-ordinate system is
+% translated. That is done inside a scope, which as described below
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_begin:
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_scope:n { transform="translate({?x},{?y})~scale(1,-1)" }
+ }
+\cs_new_eq:NN \@@_backend_end: \__kernel_backend_scope_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
+% \begin{macro}{\@@_backend_rectangle:nnnn}
+% \begin{macro}{\@@_backend_curveto:nnnnnn}
+% \begin{macro}{\@@_backend_add_to_path:n}
+% \begin{variable}{\g_@@_backend_path_tl}
+% Once again, some work is needed to get path constructs correct. Rather
+% then write the values as they are given, the entire path needs to be
+% 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.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
+ {
+ \@@_backend_add_to_path:n
+ { M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
+ {
+ \@@_backend_add_to_path:n
+ { L ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
+ {
+ \@@_backend_add_to_path:n
+ {
+ M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2}
+ h ~ \dim_to_decimal:n {#3} ~
+ v ~ \dim_to_decimal:n {#4} ~
+ h ~ \dim_to_decimal:n { -#3 } ~
+ Z
+ }
+ }
+\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_backend_add_to_path:n
+ {
+ C ~
+ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} ~
+ \dim_to_decimal:n {#3} ~ \dim_to_decimal:n {#4} ~
+ \dim_to_decimal:n {#5} ~ \dim_to_decimal:n {#6}
+ }
+ }
+\cs_new_protected:Npn \@@_backend_add_to_path:n #1
+ {
+ \tl_gset:Ne \g_@@_backend_path_tl
+ {
+ \g_@@_backend_path_tl
+ \tl_if_empty:NF \g_@@_backend_path_tl { \c_space_tl }
+ #1
+ }
+ }
+\tl_new:N \g_@@_backend_path_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
+% The fill rules here have to be handled as scopes.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_evenodd_rule:
+ { \__kernel_backend_scope:n { fill-rule="evenodd" } }
+\cs_new_protected:Npn \@@_backend_nonzero_rule:
+ { \__kernel_backend_scope:n { fill-rule="nonzero" } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_path:n}
+% \begin{macro}
+% {
+% \@@_backend_closepath: ,
+% \@@_backend_stroke: ,
+% \@@_backend_closestroke: ,
+% \@@_backend_fill: ,
+% \@@_backend_fillstroke: ,
+% \@@_backend_clip: ,
+% \@@_backend_discardpath:
+% }
+% \begin{variable}{\g_@@_draw_clip_bool}
+% \begin{variable}{\g_@@_draw_path_int}
+% Setting fill and stroke effects and doing clipping all has to be done using
+% scopes. This means setting up the various requirements in a shared
+% auxiliary which deals with the bits and pieces. Clipping paths are reused
+% for path drawing: not essential but avoids constructing them twice.
+% Discarding a path needs a separate function as it's not quite the same.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_closepath:
+ { \@@_backend_add_to_path:n { Z } }
+\cs_new_protected:Npn \@@_backend_path:n #1
+ {
+ \bool_if:NTF \g_@@_draw_clip_bool
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \@@_backend_literal:e
+ {
+ < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
+ { ?nl }
+ <path~d=" \g_@@_backend_path_tl "/> { ?nl }
+ < /clipPath > { ? nl }
+ <
+ use~xlink:href =
+ "\c_hash_str l3path \int_use:N \g_@@_backend_path_int " ~
+ #1
+ />
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
+ }
+ }
+ {
+ \@@_backend_literal:e
+ { <path ~ d=" \g_@@_backend_path_tl " ~ #1 /> }
+ }
+ \tl_gclear:N \g_@@_backend_path_tl
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\int_new:N \g_@@_backend_path_int
+\cs_new_protected:Npn \@@_backend_stroke:
+ { \@@_backend_path:n { style="fill:none" } }
+\cs_new_protected:Npn \@@_backend_closestroke:
+ {
+ \@@_backend_closepath:
+ \@@_backend_stroke:
+ }
+\cs_new_protected:Npn \@@_backend_fill:
+ { \@@_backend_path:n { style="stroke:none" } }
+\cs_new_protected:Npn \@@_backend_fillstroke:
+ { \@@_backend_path:n { } }
+\cs_new_protected:Npn \@@_backend_clip:
+ { \bool_gset_true:N \g_@@_draw_clip_bool }
+\bool_new:N \g_@@_draw_clip_bool
+\cs_new_protected:Npn \@@_backend_discardpath:
+ {
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \@@_backend_literal:e
+ {
+ < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
+ { ?nl }
+ <path~d=" \g_@@_backend_path_tl "/> { ?nl }
+ < /clipPath >
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
+ }
+ }
+ \tl_gclear:N \g_@@_backend_path_tl
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_dash_pattern:nn}
+% \begin{macro}{\@@_backend_dash:n}
+% \begin{macro}{\@@_backend_dash_aux:nn}
+% \begin{macro}{\@@_backend_linewidth:n}
+% \begin{macro}{\@@_backend_miterlimit:n}
+% \begin{macro}
+% {
+% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
+% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
+% }
+% All of these ideas are properties of scopes in SVG. The only slight
+% complexity is converting the dash array properly (doing any required
+% maths).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
+ {
+ \use:e
+ {
+ \@@_backend_dash_aux:nn
+ { \clist_map_function:nN {#1} \@@_backend_dash:n }
+ { \dim_to_decimal:n {#2} }
+ }
+ }
+\cs_new:Npn \@@_backend_dash:n #1
+ { , \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \@@_backend_dash_aux:nn #1#2
+ {
+ \__kernel_backend_scope:e
+ {
+ stroke-dasharray =
+ "
+ \tl_if_empty:nTF {#1}
+ { none }
+ { \use_none:n #1 }
+ " ~
+ stroke-offset=" #2 "
+ }
+ }
+\cs_new_protected:Npn \@@_backend_linewidth:n #1
+ { \__kernel_backend_scope:e { stroke-width=" \dim_to_decimal:n {#1} " } }
+\cs_new_protected:Npn \@@_backend_miterlimit:n #1
+ { \__kernel_backend_scope:e { stroke-miterlimit=" #1 " } }
+\cs_new_protected:Npn \@@_backend_cap_butt:
+ { \__kernel_backend_scope:n { stroke-linecap="butt" } }
+\cs_new_protected:Npn \@@_backend_cap_round:
+ { \__kernel_backend_scope:n { stroke-linecap="round" } }
+\cs_new_protected:Npn \@@_backend_cap_rectangle:
+ { \__kernel_backend_scope:n { stroke-linecap="square" } }
+\cs_new_protected:Npn \@@_backend_join_miter:
+ { \__kernel_backend_scope:n { stroke-linejoin="miter" } }
+\cs_new_protected:Npn \@@_backend_join_round:
+ { \__kernel_backend_scope:n { stroke-linejoin="round" } }
+\cs_new_protected:Npn \@@_backend_join_bevel:
+ { \__kernel_backend_scope:n { stroke-linejoin="bevel" } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_cm:nnnn}
+% 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
+ {
+ \__kernel_backend_scope:n
+ {
+ transform =
+ " matrix ( #1 , #2 , #3 , #4 , 0pt , 0pt ) "
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_box_use:Nnnnn}
+% No special savings can be made here: simply displace the box inside
+% a scope. As there is nothing to re-box, just make the box passed of
+% zero size.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \__kernel_backend_scope_begin:
+ \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
+ \__kernel_backend_literal_svg:n
+ {
+ < g~
+ stroke="none"~
+ transform="scale(-1,1)~translate({?x},{?y})~scale(-1,-1)"
+ >
+ }
+ \box_set_wd:Nn #1 { 0pt }
+ \box_set_ht:Nn #1 { 0pt }
+ \box_set_dp:Nn #1 { 0pt }
+ \box_use:N #1
+ \__kernel_backend_literal_svg:n { </g> }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-graphics.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-graphics.dtx
new file mode 100644
index 00000000000..e20457368da
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-graphics.dtx
@@ -0,0 +1,931 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-graphics.dtx
+%
+% Copyright (C) 2019-2024 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-graphics} module\\ Backend graphics support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-graphics} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=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}
+%<*dvips>
+% \end{macrocode}
+%
+% \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 } }
+% \end{macrocode}
+% \end{variable}
+%
+% \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
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_include_eps:n, \@@_backend_include_ps:n}
+% The special syntax is relatively clear here: remember we need PostScript
+% sizes here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_eps:n #1
+ {
+ \__kernel_backend_literal:e
+ {
+ PSfile = #1 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l_@@_ury_dim
+ }
+ }
+\cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backends}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \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 }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_attr_tl}
+% In PDF mode, additional attributes of an graphic (such as page number) are
+% needed both to obtain the bounding box and when inserting the graphic: this
+% occurs as the graphic dictionary approach means they are read as part of
+% the bounding box operation. As such, it is easier to track additional
+% attributes using a dedicated |tl| rather than build up the same data
+% twice.
+% \begin{macrocode}
+\tl_new:N \l_@@_attr_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_getbb_jpg:n ,
+% \@@_backend_getbb_jpeg:n ,
+% \@@_backend_getbb_pdf:n ,
+% \@@_backend_getbb_png:n
+% }
+% \begin{macro}
+% {
+% \@@_backend_getbb_auxi:n ,
+% \@@_backend_getbb_auxii:n ,
+% \@@_backend_getbb_auxiii:n
+% }
+% \begin{macro}[EXP]{\@@_backend_dequote:w}
+% Getting the bounding box here requires us to box up the graphic and
+% measure it. To deal with the difference in feature support in bitmap
+% and vector graphics but keeping the common parts, there is a little work
+% to do in terms of auxiliaries. The key here is to notice that we need
+% two forms of the attributes: a \enquote{short} set to allow us to
+% track for caching, and the full form to pass to the primitive.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \tl_set:Ne \l_@@_attr_tl
+ {
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { :D \l_@@_decodearray_str }
+ \bool_if:NT \l_@@_interpolate_bool
+ { :I }
+ \str_if_empty:NF \l_@@_pdf_str
+ { :X \l_@@_pdf_str }
+ }
+ \@@_backend_getbb_auxi:n {#1}
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \tl_set:Ne \l_@@_attr_tl
+ {
+ : \l_@@_pagebox_tl
+ \int_compare:nNnT \l_@@_page_int > 1
+ { :P \int_use:N \l_@@_page_int }
+ \str_if_empty:NF \l_@@_pdf_str
+ { :X \l_@@_pdf_str }
+ }
+ \@@_backend_getbb_auxi:n {#1}
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxi:n #1
+ {
+ \@@_bb_restore:eF { #1 \l_@@_attr_tl }
+ { \@@_backend_getbb_auxii:n {#1} }
+ }
+% \end{macrocode}
+% Measuring the graphic is done by boxing up: for PDF graphics we could
+% use |\tex_pdfximagebbox:D|, but if doesn't work for other types.
+% As the box always starts at $(0,0)$ there is no need to worry about
+% the lower-left position. Quotes need to be \emph{removed} as \LuaTeX{}
+% does not like them here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_auxii:n #1
+ {
+ \exp_args:Ne \@@_backend_getbb_auxiii:n
+ { \@@_backend_dequote:w #1 " #1 " \s_@@_stop }
+ \int_const:cn { c_@@_ #1 \l_@@_attr_tl _int }
+ { \tex_the:D \tex_pdflastximage:D }
+ \@@_bb_save:e { #1 \l_@@_attr_tl }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxiii:n #1
+ {
+ \tex_immediate:D \tex_pdfximage:D
+ \bool_lazy_any:nT
+ {
+ { \l_@@_interpolate_bool }
+ { ! \tl_if_empty_p:N \l_@@_decodearray_str }
+ { ! \str_if_empty_p:N \l_@@_pdf_str }
+ }
+ {
+ attr ~
+ {
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { /Decode~[ \l_@@_decodearray_str ] }
+ \bool_if:NT \l_@@_interpolate_bool
+ { /Interpolate~true }
+ \l_@@_pdf_str
+ }
+ }
+ \int_compare:nNnT \l_@@_page_int > 0
+ { page ~ \int_use:N \l_@@_page_int }
+ \tl_if_empty:NF \l_@@_pagebox_tl
+ { \l_@@_pagebox_tl }
+ {#1}
+ \hbox_set:Nn \l_@@_internal_box
+ { \tex_pdfrefximage:D \tex_pdflastximage:D }
+ \dim_set:Nn \l_@@_urx_dim { \box_wd:N \l_@@_internal_box }
+ \dim_set:Nn \l_@@_ury_dim { \box_ht:N \l_@@_internal_box }
+ }
+\cs_new:Npn \@@_backend_dequote:w #1 " #2 " #3 \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_jpg:n ,
+% \@@_backend_include_jpeg:n ,
+% \@@_backend_include_pdf:n ,
+% \@@_backend_include_png:n
+% }
+% Images are already loaded for the measurement part of the code, so
+% inclusion is straight-forward, with only any attributes to worry about. The
+% latter carry through from determination of the bounding box.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_jpg:n #1
+ {
+ \tex_pdfrefximage:D
+ \int_use:c { c_@@_ #1 \l_@@_attr_tl _int }
+ }
+\cs_new_eq:NN \@@_backend_include_jpeg:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_pdf:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_png:n \@@_backend_include_jpg:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_getbb_eps:n, \@@_backend_getbb_ps:n}
+% \begin{macro}{\@@_backend_getbb_eps:nm}
+% \begin{macro}{\@@_backend_include_eps:n, \@@_backend_include_ps:n}
+% \begin{variable}
+% {\l_@@_backend_dir_str, \l_@@_backend_name_str, \l_@@_backend_ext_str}
+% EPS graphics may be included in \LuaTeX{}/pdfTeX{} by conversion to
+% PDF: this requires restricted shell escape. Modelled on the \pkg{epstopdf}
+% \LaTeXe{} package, but simplified, conversion takes place here if we have
+% shell access.
+% \begin{macrocode}
+\sys_if_shell:T
+ {
+ \str_new:N \l_@@_backend_dir_str
+ \str_new:N \l_@@_backend_name_str
+ \str_new:N \l_@@_backend_ext_str
+ \cs_new_protected:Npn \@@_backend_getbb_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l_@@_backend_dir_str
+ \l_@@_backend_name_str
+ \l_@@_backend_ext_str
+ \exp_args:Ne \@@_backend_getbb_eps:nn
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l_@@_backend_name_str
+ - \str_tail:N \l_@@_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ {#1}
+ }
+ \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_backend_getbb_eps:n
+ \cs_new_protected:Npn \@@_backend_getbb_eps:nn #1#2
+ {
+ \file_compare_timestamp:nNnT {#2} > {#1}
+ {
+ \sys_shell_now:n
+ { repstopdf ~ #2 ~ #1 }
+ }
+ \tl_set:Nn \l_@@_final_name_str {#1}
+ \@@_backend_getbb_pdf:n {#1}
+ }
+ \cs_new_protected:Npn \@@_backend_include_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l_@@_backend_dir_str \l_@@_backend_name_str \l_@@_backend_ext_str
+ \exp_args:Ne \@@_backend_include_pdf:n
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l_@@_backend_name_str
+ - \str_tail:N \l_@@_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ }
+ \cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% Simply load and store.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_get_pagecount:n #1
+ {
+ \tex_pdfximage:D {#1}
+ \int_const:cn { c_@@_ #1 _pages_int }
+ { \int_use:N \tex_pdflastximagepages:D }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx} backend}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \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 }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_getbb_eps:n , \@@_backend_getbb_ps:n ,
+% \@@_backend_getbb_jpg:n , \@@_backend_getbb_jpeg:n ,
+% \@@_backend_getbb_pdf:n , \@@_backend_getbb_png:n ,
+% \@@_backend_getbb_bmp:n
+% }
+% 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
+ }
+%<*dvipdfmx>
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \@@_extract_bb:n {#1}
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_bmp:n \@@_backend_getbb_jpg:n
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \@@_extract_bb:n {#1}
+ }
+%</dvipdfmx>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_track_int}
+% Used to track the object number associated with each graphic.
+% \begin{macrocode}
+\int_new:N \g_@@_track_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_eps:n , \@@_backend_include_ps:n ,
+% \@@_backend_include_jpg:n , \@@_backend_include_jpseg:n ,
+% \@@_backend_include_pdf:n , \@@_backend_include_png:n ,
+% \@@_backend_include_bmp:n ,
+% }
+% \begin{macro}{\@@_backend_include_auxi:nn}
+% \begin{macro}{\@@_backend_include_auxii:nnn, \@@_backend_include_auxii:enn}
+% \begin{macro}{\@@_backend_include_auxiii:nnn}
+% The special syntax depends on the file type. There is a difference in
+% how PDF graphics are best handled between |dvipdfmx| and \XeTeX{}: for
+% the latter it is better to use the primitive route. The relevant code for
+% that is included later in this file.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_eps:n #1
+ {
+ \__kernel_backend_literal:e
+ {
+ PSfile = #1 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l_@@_ury_dim
+ }
+ }
+\cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+\cs_new_protected:Npn \@@_backend_include_jpg:n #1
+ { \@@_backend_include_auxi:nn {#1} { image } }
+\cs_new_eq:NN \@@_backend_include_jpeg:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_png:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_bmp:n \@@_backend_include_jpg:n
+%<*dvipdfmx>
+\cs_new_protected:Npn \@@_backend_include_pdf:n #1
+ { \@@_backend_include_auxi:nn {#1} { epdf } }
+%</dvipdfmx>
+% \end{macrocode}
+% Graphic inclusion is set up to use the fact that each image is stored in
+% the PDF as an XObject. This means that we can include repeated images
+% only once and refer to them. To allow that, track the nature of each
+% image: much the same as for the direct PDF mode case.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_auxi:nn #1#2
+ {
+ \@@_backend_include_auxii:enn
+ {
+ \tl_if_empty:NF \l_@@_pagebox_tl
+ { : \l_@@_pagebox_tl }
+ \int_compare:nNnT \l_@@_page_int > 1
+ { :P \int_use:N \l_@@_page_int }
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { :D \l_@@_decodearray_str }
+ \bool_if:NT \l_@@_interpolate_bool
+ { :I }
+ }
+ {#1} {#2}
+ }
+\cs_new_protected:Npn \@@_backend_include_auxii:nnn #1#2#3
+ {
+ \int_if_exist:cTF { c_@@_ #2#1 _int }
+ {
+ \__kernel_backend_literal:e
+ { pdf:usexobj~@graphic \int_use:c { c_@@_ #2#1 _int } }
+ }
+ { \@@_backend_include_auxiii:nnn {#2} {#1} {#3} }
+ }
+\cs_generate_variant:Nn \@@_backend_include_auxii:nnn { e }
+% \end{macrocode}
+% Inclusion using the specials is relatively straight-forward, but there
+% is one wrinkle. To get the |pagebox| correct for PDF graphics in all cases,
+% it is necessary to provide both that information and the |bbox| argument:
+% odd things happen otherwise!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_auxiii:nnn #1#2#3
+ {
+ \int_gincr:N \g_@@_track_int
+ \int_const:cn { c_@@_ #1#2 _int } { \g_@@_track_int }
+ \__kernel_backend_literal:e
+ {
+ pdf:#3~
+ @graphic \int_use:c { c_@@_ #1#2 _int } ~
+ \int_compare:nNnT \l_@@_page_int > 1
+ { page ~ \int_use:N \l_@@_page_int \c_space_tl }
+ \tl_if_empty:NF \l_@@_pagebox_tl
+ {
+ pagebox ~ \l_@@_pagebox_tl \c_space_tl
+ bbox ~
+ \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l_@@_ury_dim \c_space_tl
+ }
+ (#1)
+ \bool_lazy_or:nnT
+ { \l_@@_interpolate_bool }
+ { ! \tl_if_empty_p:N \l_@@_decodearray_str }
+ {
+ <<
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { /Decode~[ \l_@@_decodearray_str ] }
+ \bool_if:NT \l_@@_interpolate_bool
+ { /Interpolate~true }
+ >>
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% \begin{macrocode}
+%<*dvipdfmx>
+\@@_backend_loaded:n
+ { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+%</dvipdfmx>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\XeTeX{} backend}
+%
+% \begin{macrocode}
+%<*xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_getbb_jpg:n ,
+% \@@_backend_getbb_jpeg:n ,
+% \@@_backend_getbb_pdf:n ,
+% \@@_backend_getbb_png:n ,
+% \@@_backend_getbb_bmp:n
+% }
+% \begin{macro}{\@@_backend_getbb_auxi:nN}
+% \begin{macro}{\@@_backend_getbb_auxii:nnN, \@@_backend_getbb_auxii:VnN}
+% \begin{macro}{\@@_backend_getbb_auxiii:nNnn}
+% \begin{macro}{\@@_backend_getbb_auxiv:nnNnn, \@@_backend_getbb_auxiv:VnNnn}
+% \begin{macro}{\@@_backend_getbb_auxv:nNnn, \@@_backend_getbb_auxv:nNnn}
+% \begin{macro}[EXP]{\@@_backend_getbb_pagebox:w}
+% For \XeTeX{}, there are two primitives that allow us to obtain
+% the bounding box without needing \texttt{extractbb}. The only complexity
+% is passing the various minor variations to a common core process. The
+% \XeTeX{} primitive omits the text |box| from the page box specification,
+% so there is also some \enquote{trimming} to do here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \@@_backend_getbb_auxi:nN {#1} \tex_XeTeXpicfile:D
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_bmp:n \@@_backend_getbb_jpg:n
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \@@_backend_getbb_auxi:nN {#1} \tex_XeTeXpdffile:D
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxi:nN #1#2
+ {
+ \int_compare:nNnTF \l_@@_page_int > 1
+ { \@@_backend_getbb_auxii:VnN \l_@@_page_int {#1} #2 }
+ { \@@_backend_getbb_auxiii:nNnn {#1} #2 { :P 1 } { page 1 } }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxii:nnN #1#2#3
+ { \@@_backend_getbb_auxiii:nNnn {#2} #3 { :P #1 } { page #1 } }
+\cs_generate_variant:Nn \@@_backend_getbb_auxii:nnN { V }
+\cs_new_protected:Npn \@@_backend_getbb_auxiii:nNnn #1#2#3#4
+ {
+ \tl_if_empty:NTF \l_@@_pagebox_tl
+ { \@@_backend_getbb_auxiv:VnNnn \l_@@_pagebox_tl }
+ { \@@_backend_getbb_auxv:nNnn }
+ {#1} #2 {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxiv:nnNnn #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_getbb_auxv:nNnn {#2} #3 { : #1 #4 }
+ {
+ #5
+ \tl_if_blank:nF {#1}
+ { \c_space_tl \@@_backend_getbb_pagebox:w #1 }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_backend_getbb_auxiv:nnNnn { V }
+\cs_new_protected:Npn \@@_backend_getbb_auxv:nNnn #1#2#3#4
+ {
+ \@@_bb_restore:nF {#1#3}
+ { \@@_backend_getbb_auxvi:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxvi:nNnn #1#2#3#4
+ {
+ \hbox_set:Nn \l_@@_internal_box { #2 #1 ~ #4 }
+ \dim_set:Nn \l_@@_urx_dim { \box_wd:N \l_@@_internal_box }
+ \dim_set:Nn \l_@@_ury_dim { \box_ht:N \l_@@_internal_box }
+ \@@_bb_save:n {#1#3}
+ }
+\cs_new:Npn \@@_backend_getbb_pagebox:w #1 box {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_include_pdf:n}
+% For PDF graphics, properly supporting the |pagebox| concept in \XeTeX{}
+% is best done using the |\tex_XeTeXpdffile:D| primitive. The syntax here
+% is the same as for the graphic measurement part, although we know at this
+% stage that there must be some valid setting for \cs{l_@@_pagebox_tl}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_pdf:n #1
+ {
+ \tex_XeTeXpdffile:D #1 ~
+ \int_compare:nNnT \l_@@_page_int > 0
+ { page ~ \int_use:N \l_@@_page_int \c_space_tl }
+ \exp_after:wN \@@_backend_getbb_pagebox:w \l_@@_pagebox_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% Very little to do here other than cover the case of a non-PDF file.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_get_pagecount:n #1
+ {
+ \int_const:cn { c_@@_ #1 _pages_int }
+ {
+ \int_max:nn
+ { \int_use:N \tex_XeTeXpdfpagecount:D #1 ~ }
+ { 1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \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 }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_getbb_svg:n}
+% \begin{macro}{\@@_backend_getbb_svg_auxi:nNn}
+% \begin{macro}{\@@_backend_getbb_svg_auxii:w}
+% \begin{macro}
+% {
+% \@@_backend_getbb_svg_auxiii:Nw ,
+% \@@_backend_getbb_svg_auxiv:Nw ,
+% \@@_backend_getbb_svg_auxv:Nw
+% }
+% \begin{macro}{\@@_backend_getbb_svg_auxvi:Nn}
+% \begin{macro}{\@@_backend_getbb_svg_auxvii:w}
+% This is relatively similar to reading bounding boxes for |.eps| files. Life
+% is though made more tricky as we cannot pick a single line for the data. So
+% we have to loop until we collect up both height and width. To do that, we
+% can use a marker value. We also have to allow for the default units of the
+% lengths: they are big points and may be omitted.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_svg:n #1
+ {
+ \@@_bb_restore:nF {#1}
+ {
+ \ior_open:Nn \l_@@_internal_ior {#1}
+ \ior_if_eof:NTF \l_@@_internal_ior
+ { \msg_error:nnn { graphics } { graphic-not-found } {#1} }
+ {
+ \dim_zero:N \l_@@_llx_dim
+ \dim_zero:N \l_@@_lly_dim
+ \dim_set:Nn \l_@@_urx_dim { -\c_max_dim }
+ \dim_set:Nn \l_@@_ury_dim { -\c_max_dim }
+ \ior_str_map_inline:Nn \l_@@_internal_ior
+ {
+ \dim_compare:nNnT \l_@@_urx_dim = { -\c_max_dim }
+ {
+ \@@_backend_getbb_svg_auxi:nNn
+ { width } \l_@@_urx_dim {##1}
+ }
+ \dim_compare:nNnT \l_@@_ury_dim = { -\c_max_dim }
+ {
+ \@@_backend_getbb_svg_auxi:nNn
+ { height } \l_@@_ury_dim {##1}
+ }
+ \bool_lazy_and:nnF
+ { \dim_compare_p:nNn \l_@@_urx_dim = { -\c_max_dim } }
+ { \dim_compare_p:nNn \l_@@_ury_dim = { -\c_max_dim } }
+ { \ior_map_break: }
+ }
+ \@@_bb_save:n {#1}
+ }
+ \ior_close:N \l_@@_internal_ior
+ }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxi:nNn #1#2#3
+ {
+ \use:e
+ {
+ \cs_set_protected:Npn \@@_backend_getbb_svg_auxii:w
+ ##1 \tl_to_str:n {#1} = ##2 \tl_to_str:n {#1} = ##3
+ \s_@@_stop
+ }
+ {
+ \tl_if_blank:nF {##2}
+ {
+ \peek_remove_spaces:n
+ {
+ \peek_meaning:NTF ' % '
+ { \@@_backend_getbb_svg_auxiii:Nw #2 }
+ {
+ \peek_meaning:NTF " % "
+ { \@@_backend_getbb_svg_auxiv:Nw #2 }
+ { \@@_backend_getbb_svg_auxv:Nw #2 }
+ }
+ }
+ ##2 \s_@@_stop
+ }
+ }
+ \use:e
+ {
+ \@@_backend_getbb_svg_auxii:w #3
+ \tl_to_str:n {#1} = \tl_to_str:n {#1} =
+ \s_@@_stop
+ }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxii:w { }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxiii:Nw #1 ' #2 ' #3 \s_@@_stop
+ { \@@_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxiv:Nw #1 " #2 " #3 \s_@@_stop
+ { \@@_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxv:Nw #1 #2 ~ #3 \s_@@_stop
+ { \@@_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxvi:Nn #1#2
+ {
+ \tex_afterassignment:D \@@_backend_getbb_svg_auxvii:w
+ \l_@@_internal_dim #2 bp \scan_stop:
+ \dim_set_eq:NN #1 \l_@@_internal_dim
+ }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxvii:w #1 \scan_stop: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \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
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_getbb_png:n, \@@_backend_getbb_jpg:n, \@@_backend_getbb_jpeg:n}
+% These can be included by extracting the bounding box data.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \@@_extract_bb:n {#1}
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_getbb_pdf:n}
+% Same as for \texttt{dvipdfmx}: use the generic function
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \@@_extract_bb:n {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_eps:n ,
+% \@@_backend_include_ps:n ,
+% \@@_backend_include_pdf:n
+% }
+% \begin{macro}{\@@_backend_include:nn}
+% The special syntax is relatively clear here: remember we need PostScript
+% sizes here. (This is the same as the \texttt{dvips} code.)
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_eps:n #1
+ { \@@_backend_include:nn { PSfile } {#1} }
+\cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+\cs_new_protected:Npn \@@_backend_include_pdf:n #1
+ { \@@_backend_include:nn { pdffile } {#1} }
+\cs_new_protected:Npn \@@_backend_include:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ {
+ #1 = #2 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l_@@_ury_dim
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_svg:n ,
+% \@@_backend_include_png:n ,
+% \@@_backend_include_jpg:n ,
+% \@@_backend_include_jpeg:n
+% }
+% \begin{macro}{\@@_backend_include_dequote:w}
+% The backend here has built-in support for basic graphic inclusion (see
+% \texttt{dvisvgm.def} for a more complex approach, needed if clipping,
+% \emph{etc.}, is covered at the graphic backend level). We have to deal
+% with the fact that the image reference point is at the \emph{top}, so
+% there is a need for a vertical shift to put it in the right place.
+% The other issue is that |#1| must be quote-corrected. The
+% \texttt{dvisvgm:img} operation quotes the file name, but if it is already
+% quoted (contains spaces) then we have an issue: we simply strip off any
+% quotes as a result.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_svg:n #1
+ {
+ \box_move_up:nn { \l_@@_ury_dim }
+ {
+ \hbox:n
+ {
+ \__kernel_backend_literal:e
+ {
+ dvisvgm:img~
+ \dim_to_decimal:n { \l_@@_urx_dim } ~
+ \dim_to_decimal:n { \l_@@_ury_dim } ~
+ \@@_backend_include_dequote:w #1 " #1 " \s_@@_stop
+ }
+ }
+ }
+ }
+\cs_new_eq:NN \@@_backend_include_png:n \@@_backend_include_svg:n
+\cs_new_eq:NN \@@_backend_include_jpeg:n \@@_backend_include_svg:n
+\cs_new_eq:NN \@@_backend_include_jpg:n \@@_backend_include_svg:n
+\cs_new:Npn \@@_backend_include_dequote:w #1 " #2 " #3 \s_@@_stop
+ {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-header.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-header.dtx
new file mode 100644
index 00000000000..486f5648224
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-header.dtx
@@ -0,0 +1,590 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-header.dtx
+%
+% Copyright (C) 2019-2024 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-header} module\\ Backend graphics support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-header} implementation}
+%
+% \begin{macrocode}
+%<*dvips&header>
+% \end{macrocode}
+%
+% \begin{macro}[no-user-doc]{color.sc}
+% Empty definition for color at the top level.
+% \begin{macrocode}
+/color.sc { } def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{TeXcolorseparation, separation}
+% Support for separation/spot colors: this strange naming is so
+% things work with the color stack.
+% \begin{macrocode}
+TeXDict begin
+/TeXcolorseparation { setcolor } def
+end
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{pdf.globaldict}
+% A small global dictionary for backend use.
+% \begin{macrocode}
+true setglobal
+/pdf.globaldict 4 dict def
+false setglobal
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.cvs ,
+% pdf.dvi.pt ,
+% pdf.pt.dvi ,
+% pdf.rect.ht
+% }
+% Small utilities for PostScript manipulations. Conversion to DVI dimensions
+% is done here to allow for |Resolution|. The total height of a rectangle
+% (an array) needs a little maths, in contrast to simply extracting a value.
+% \begin{macrocode}
+/pdf.cvs { 65534 string cvs } def
+/pdf.dvi.pt { 72.27 mul Resolution div } def
+/pdf.pt.dvi { 72.27 div Resolution mul } def
+/pdf.rect.ht { dup 1 get neg exch 3 get add } def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{pdf.linkmargin, pdf.linkdp.pad, pdf.linkht.pad}
+% Settings which are defined up-front in |SDict|.
+% \begin{macrocode}
+/pdf.linkmargin { 1 pdf.pt.dvi } def
+/pdf.linkdp.pad { 0 } def
+/pdf.linkht.pad { 0 } def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.rect ,
+% pdf.save.ll ,
+% pdf.save.ur ,
+% pdf.save.linkll ,
+% pdf.save.linkur ,
+% pdf.llx ,
+% pdf.lly ,
+% pdf.urx ,
+% pdf.ury
+% }
+% Functions for marking the limits of an annotation/link, plus drawing the
+% border. We separate links for generic annotations to support adding a
+% margin and setting a minimal size.
+% \begin{macrocode}
+/pdf.rect
+ { /Rect [ pdf.llx pdf.lly pdf.urx pdf.ury ] } def
+/pdf.save.ll
+ {
+ currentpoint
+ /pdf.lly exch def
+ /pdf.llx exch def
+ }
+ def
+/pdf.save.ur
+ {
+ currentpoint
+ /pdf.ury exch def
+ /pdf.urx exch def
+ }
+ def
+/pdf.save.linkll
+ {
+ currentpoint
+ pdf.linkmargin add
+ pdf.linkdp.pad add
+ /pdf.lly exch def
+ pdf.linkmargin sub
+ /pdf.llx exch def
+ }
+ def
+/pdf.save.linkur
+ {
+ currentpoint
+ pdf.linkmargin sub
+ pdf.linkht.pad sub
+ /pdf.ury exch def
+ pdf.linkmargin add
+ /pdf.urx exch def
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.dest.anchor ,
+% pdf.dest.x ,
+% pdf.dest.y ,
+% pdf.dest.point ,
+% pdf.dest2device ,
+% pdf.dev.x ,
+% pdf.dev.y ,
+% pdf.tmpa ,
+% pdf.tmpb ,
+% pdf.tmpc ,
+% pdf.tmpd
+% }
+% For finding the anchor point of a destination link. We make the use case
+% a separate function as it comes up a lot, and as this makes it easier to
+% adjust if we need additional effects. We also need a more complex approach
+% to convert a co-ordinate pair correctly when defining a rectangle: this
+% can otherwise be out when using a landscape page. (Thanks to Alexander
+% Grahn for the approach here.)
+% \begin{macrocode}
+/pdf.dest.anchor
+ {
+ currentpoint exch
+ pdf.dvi.pt 72 add
+ /pdf.dest.x exch def
+ pdf.dvi.pt
+ vsize 72 sub exch sub
+ /pdf.dest.y exch def
+ }
+ def
+/pdf.dest.point
+ { pdf.dest.x pdf.dest.y } def
+/pdf.dest2device
+ {
+ /pdf.dest.y exch def
+ /pdf.dest.x exch def
+ matrix currentmatrix
+ matrix defaultmatrix
+ matrix invertmatrix
+ matrix concatmatrix
+ cvx exec
+ /pdf.dev.y exch def
+ /pdf.dev.x exch def
+ /pdf.tmpd exch def
+ /pdf.tmpc exch def
+ /pdf.tmpb exch def
+ /pdf.tmpa exch def
+ pdf.dest.x pdf.tmpa mul
+ pdf.dest.y pdf.tmpc mul add
+ pdf.dev.x add
+ pdf.dest.x pdf.tmpb mul
+ pdf.dest.y pdf.tmpd mul add
+ pdf.dev.y add
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.bordertracking ,
+% pdf.bordertracking.begin ,
+% pdf.bordertracking.end ,
+% pdf.leftboundary ,
+% pdf.rightboundary ,
+% pdf.brokenlink.rect ,
+% pdf.brokenlink.skip ,
+% pdf.brokenlink.dict ,
+% pdf.bordertracking.endpage ,
+% pdf.bordertracking.continue ,
+% pdf.originx ,
+% pdf.originy
+% }
+% To know where a breakable link can go, we need to track the boundary
+% rectangle. That can be done by hooking into |a| and |x| operations:
+% those names have to be retained. The boundary is stored at the end of
+% the operation. Special effort is needed at the start and end of pages
+% (or rather galleys), such that everything works properly.
+% \begin{macrocode}
+/pdf.bordertracking false def
+/pdf.bordertracking.begin
+ {
+ SDict /pdf.bordertracking true put
+ SDict /pdf.leftboundary undef
+ SDict /pdf.rightboundary undef
+ /a where
+ {
+ /a
+ {
+ currentpoint pop
+ SDict /pdf.rightboundary known dup
+ {
+ SDict /pdf.rightboundary get 2 index lt
+ { not }
+ if
+ }
+ if
+ { pop }
+ { SDict exch /pdf.rightboundary exch put }
+ ifelse
+ moveto
+ currentpoint pop
+ SDict /pdf.leftboundary known dup
+ {
+ SDict /pdf.leftboundary get 2 index gt
+ { not }
+ if
+ }
+ if
+ { pop }
+ { SDict exch /pdf.leftboundary exch put }
+ ifelse
+ }
+ put
+ }
+ if
+ }
+ def
+/pdf.bordertracking.end
+ {
+ /a where { /a { moveto } put } if
+ /x where { /x { 0 exch rmoveto } put } if
+ SDict /pdf.leftboundary known
+ { pdf.outerbox 0 pdf.leftboundary put }
+ if
+ SDict /pdf.rightboundary known
+ { pdf.outerbox 2 pdf.rightboundary put }
+ if
+ SDict /pdf.bordertracking false put
+ }
+ def
+ /pdf.bordertracking.endpage
+{
+ pdf.bordertracking
+ {
+ pdf.bordertracking.end
+ true setglobal
+ pdf.globaldict
+ /pdf.brokenlink.rect [ pdf.outerbox aload pop ] put
+ pdf.globaldict
+ /pdf.brokenlink.skip pdf.baselineskip put
+ pdf.globaldict
+ /pdf.brokenlink.dict
+ pdf.link.dict pdf.cvs put
+ false setglobal
+ mark pdf.link.dict cvx exec /Rect
+ [
+ pdf.llx
+ pdf.lly
+ pdf.outerbox 2 get pdf.linkmargin add
+ currentpoint exch pop
+ pdf.outerbox pdf.rect.ht sub pdf.linkmargin sub
+ ]
+ /ANN pdf.pdfmark
+ }
+ if
+}
+ def
+/pdf.bordertracking.continue
+ {
+ /pdf.link.dict pdf.globaldict
+ /pdf.brokenlink.dict get def
+ /pdf.outerbox pdf.globaldict
+ /pdf.brokenlink.rect get def
+ /pdf.baselineskip pdf.globaldict
+ /pdf.brokenlink.skip get def
+ pdf.globaldict dup dup
+ /pdf.brokenlink.dict undef
+ /pdf.brokenlink.skip undef
+ /pdf.brokenlink.rect undef
+ currentpoint
+ /pdf.originy exch def
+ /pdf.originx exch def
+ /a where
+ {
+ /a
+ {
+ moveto
+ SDict
+ begin
+ currentpoint pdf.originy ne exch
+ pdf.originx ne or
+ {
+ pdf.save.linkll
+ /pdf.lly
+ pdf.lly pdf.outerbox 1 get sub def
+ pdf.bordertracking.begin
+ }
+ if
+ end
+ }
+ put
+ }
+ if
+ /x where
+ {
+ /x
+ {
+ 0 exch rmoveto
+ SDict
+ begin
+ currentpoint
+ pdf.originy ne exch pdf.originx ne or
+ {
+ pdf.save.linkll
+ /pdf.lly
+ pdf.lly pdf.outerbox 1 get sub def
+ pdf.bordertracking.begin
+ }
+ if
+ end
+ }
+ put
+ }
+ if
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.breaklink ,
+% pdf.breaklink.write ,
+% pdf.count ,
+% pdf.currentrect
+% }
+% Dealing with link breaking itself has multiple stage. The first step is to
+% find the |Rect| entry in the dictionary, looping over key--value pairs.
+% The first line is handled first, adjusting the rectangle to stay inside the
+% text area. The second phase is a loop over the height of the bulk of the
+% link area, done on the basis of a number of baselines. Finally, the end of
+% the link area is tidied up, again from the boundary of the text area.
+% \begin{macrocode}
+/pdf.breaklink
+ {
+ pop
+ counttomark 2 mod 0 eq
+ {
+ counttomark /pdf.count exch def
+ {
+ pdf.count 0 eq { exit } if
+ counttomark 2 roll
+ 1 index /Rect eq
+ {
+ dup 4 array copy
+ dup dup
+ 1 get
+ pdf.outerbox pdf.rect.ht
+ pdf.linkmargin 2 mul add sub
+ 3 exch put
+ dup
+ pdf.outerbox 2 get
+ pdf.linkmargin add
+ 2 exch put
+ dup dup
+ 3 get
+ pdf.outerbox pdf.rect.ht
+ pdf.linkmargin 2 mul add add
+ 1 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ {
+ pdf.currentrect
+ dup
+ pdf.outerbox 0 get
+ pdf.linkmargin sub
+ 0 exch put
+ dup
+ pdf.outerbox 2 get
+ pdf.linkmargin add
+ 2 exch put
+ dup dup
+ 1 get
+ pdf.baselineskip add
+ 1 exch put
+ dup dup
+ 3 get
+ pdf.baselineskip add
+ 3 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ }
+ 1 index 3 get
+ pdf.linkmargin 2 mul add
+ pdf.outerbox pdf.rect.ht add
+ 2 index 1 get sub
+ pdf.baselineskip div round cvi 1 sub
+ exch
+ repeat
+ pdf.currentrect
+ dup
+ pdf.outerbox 0 get
+ pdf.linkmargin sub
+ 0 exch put
+ dup dup
+ 1 get
+ pdf.baselineskip add
+ 1 exch put
+ dup dup
+ 3 get
+ pdf.baselineskip add
+ 3 exch put
+ dup 2 index 2 get 2 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ SDict /pdf.pdfmark.good false put
+ exit
+ }
+ { pdf.count 2 sub /pdf.count exch def }
+ ifelse
+ }
+ loop
+ }
+ if
+ /ANN
+ }
+ def
+/pdf.breaklink.write
+ {
+ counttomark 1 sub
+ index /_objdef eq
+ {
+ counttomark -2 roll
+ dup wcheck
+ {
+ readonly
+ counttomark 2 roll
+ }
+ { pop pop }
+ ifelse
+ }
+ if
+ counttomark 1 add copy
+ pop pdf.currentrect
+ /ANN pdfmark
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.pdfmark ,
+% pdf.pdfmark.good ,
+% pdf.outerbox ,
+% pdf.baselineskip ,
+% pdf.pdfmark.dict
+% }
+% The business end of breaking links starts by hooking into |pdfmarks|.
+% Unlike \pkg{hypdvips}, we avoid altering any links we have not created
+% by using a copy of the core |pdfmarks| function. Only mark types which
+% are known are altered. At present, this is purely |ANN| marks, which are
+% measured relative to the size of the baseline skip. If they are
+% more than one apparent line high, breaking is applied.
+% \begin{macrocode}
+/pdf.pdfmark
+ {
+ SDict /pdf.pdfmark.good true put
+ dup /ANN eq
+ {
+ pdf.pdfmark.store
+ pdf.pdfmark.dict
+ begin
+ Subtype /Link eq
+ currentdict /Rect known and
+ SDict /pdf.outerbox known and
+ SDict /pdf.baselineskip known and
+ {
+ Rect 3 get
+ pdf.linkmargin 2 mul add
+ pdf.outerbox pdf.rect.ht add
+ Rect 1 get sub
+ pdf.baselineskip div round cvi 0 gt
+ { pdf.breaklink }
+ if
+ }
+ if
+ end
+ SDict /pdf.outerbox undef
+ SDict /pdf.baselineskip undef
+ currentdict /pdf.pdfmark.dict undef
+ }
+ if
+ pdf.pdfmark.good
+ { pdfmark }
+ { cleartomark }
+ ifelse
+ }
+ def
+/pdf.pdfmark.store
+ {
+ /pdf.pdfmark.dict 65534 dict def
+ counttomark 1 add copy
+ pop
+ {
+ dup mark eq
+ {
+ pop
+ exit
+ }
+ {
+ pdf.pdfmark.dict
+ begin def end
+ }
+ ifelse
+ }
+ loop
+}
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips&header>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-opacity.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-opacity.dtx
new file mode 100644
index 00000000000..0c29574c377
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-opacity.dtx
@@ -0,0 +1,353 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-opacity.dtx
+%
+% Copyright (C) 2021-2024 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-opacity} module\\ Backend opacity support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-opacity} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=opacity>
+% \end{macrocode}
+%
+% Although opacity is not color, it needs to be managed in a somewhat
+% similar way: using a dedicated stack if possible. Depending on the backend,
+% that may not be possible. There is also the need to cover fill/stroke setting
+% as well as more general running opacity. It is easiest to describe the value
+% used in terms of opacity, although commonly this is referred to as
+% transparency.
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_select:n}
+% \begin{macro}{\@@_backend_fill:n, \@@_backend_stroke:n}
+% \begin{macro}{\@@_backend:nnn}
+% No stack so set values directly. The need to deal with Distiller and
+% Ghostscript separately means we use a common auxiliary: the two
+% systems require different PostScript for transparency. This is
+% of course not quite as efficient as doing one test for setting all
+% transparency, but it keeps things clearer here. Thanks to Alex Grahn
+% for the detail on testing for GhostScript.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ {
+ \@@_backend:nnn {#1} { fill } { ca }
+ \@@_backend:nnn {#1} { stroke } { CA }
+ }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \@@_backend:nnn
+ { #1 }
+ { fill }
+ { ca }
+ }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ {
+ \@@_backend:nnn
+ { #1 }
+ { stroke }
+ { CA }
+ }
+\cs_new_protected:Npn \@@_backend:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ product ~ (Ghostscript) ~ search
+ {
+ pop ~ pop ~ pop ~
+ #1 ~ .set #2 constantalpha
+ }
+ {
+ pop ~
+ mark ~
+ /#3 ~ #1
+ /SetTransparency ~
+ pdfmark
+ }
+ ifelse
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{variable}{\c_@@_backend_stack_int}
+% Set up a stack, where that is applicable.
+% \begin{macrocode}
+\bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_init:Nnn \c_@@_backend_stack_int
+ { page ~ direct } { /opacity 1 ~ gs }
+%</luatex|pdftex>
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity 1 } { << /ca ~ 1 /CA ~ 1 >> }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_backend_fill_tl, \l_@@_backend_stroke_tl}
+% We use |tl| here for speed: at the backend, this should be reasonable.
+% Both need to start off fully opaque.
+% \begin{macrocode}
+\tl_new:N \l_@@_backend_fill_tl
+\tl_new:N \l_@@_backend_stroke_tl
+\tl_set:Nn \l_@@_backend_fill_tl { 1 }
+\tl_set:Nn \l_@@_backend_stroke_tl { 1 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_select:n}
+% \begin{macro}{\@@_backend_reset:}
+% Much the same as color.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \tl_set:Nn \l_@@_backend_stroke_tl {#1}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity #1 }
+ { << /ca ~ #1 /CA ~ #1 >> }
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal_pdf:n
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int
+%</luatex|pdftex>
+ { /opacity #1 ~ gs }
+ \group_insert_after:N \@@_backend_reset:
+ }
+\cs_new_protected:Npn \@@_backend_reset:
+ {
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal_pdf:n
+ { /opacity1 ~ gs }
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_pop:n \c_@@_backend_stack_int
+%</luatex|pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill:n, \@@_backend_stroke:n}
+% \begin{macro}{\@@_backend_fill_stroke:nn}
+% For separate fill and stroke, we need to work out if we need to do
+% more work or if we can stick to a single setting.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \exp_args:Nno \@@_backend_fill_stroke:nn
+ { #1 }
+ { \l_@@_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ {
+ \exp_args:No \@@_backend_fill_stroke:nn
+ { \l_@@_backend_fill_tl }
+ { #1 }
+ }
+\cs_new_protected:Npn \@@_backend_fill_stroke:nn #1#2
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \@@_backend_select:n {#1} }
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \tl_set:Nn \l_@@_backend_stroke_tl {#2}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.fill #1 }
+ { << /ca ~ #1 >> }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.stroke #2 }
+ { << /CA ~ #2 >> }
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal_pdf:n
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int
+%</luatex|pdftex>
+ { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
+ \group_insert_after:N \@@_backend_reset:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select:n, \@@_backend_fill_stroke:nn}
+% Redefine them to stubs if pdfmanagement is either not loaded or
+% deactivated.
+% \begin{macrocode}
+\bool_lazy_and:nnF
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \cs_gset_protected:Npn \@@_backend_select:n #1 { }
+ \cs_gset_protected:Npn \@@_backend_fill_stroke:nn #1#2 { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_select:n, \@@_backend_fill:n, \@@_backend_stroke:n}
+% \begin{macro}{\@@_backend:nn}
+% Once again, we use a scope here. There is a general opacity function for
+% SVG, but that is of course not set up using the stack.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ { \@@_backend:nn {#1} { } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ { \@@_backend:nn {#1} { fill- } }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ { \@@_backend:nn {#1} { stroke- } }
+\cs_new_protected:Npn \@@_backend:nn #1#2
+ { \__kernel_backend_scope:e { #2 opacity = " #1 " } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \subsection{Font handling integration}
+%
+% In \LuaTeX{} we want to use these functions also for transparent fonts
+% to avoid interference between both uses of transparency.
+%
+% \begin{macrocode}
+%<*lua>
+% \end{macrocode}
+%
+% First we need to check if pdfmanagement is active from Lua.
+% \begin{macrocode}
+local pdfmanagement_active do
+ local pdfmanagement_if_active_p = token.create'pdfmanagement_if_active_p:'
+ local cmd = pdfmanagement_if_active_p.cmdname
+ if cmd == 'undefined_cs' then
+ pdfmanagement_active = false
+ else
+ token.put_next(pdfmanagement_if_active_p)
+ pdfmanagement_active = token.scan_int() ~= 0
+ end
+end
+
+if pdfmanagement_active and luaotfload and luaotfload.set_transparent_colorstack then
+ luaotfload.set_transparent_colorstack(function() return token.create'c_@@_backend_stack_int'.index end)
+
+ local transparent_register = {
+ token.create'pdfmanagement_add:nnn',
+ token.new(0, 1),
+ 'Page/Resources/ExtGState',
+ token.new(0, 2),
+ token.new(0, 1),
+ '',
+ token.new(0, 2),
+ token.new(0, 1),
+ '<</ca ',
+ '',
+ '/CA ',
+ '',
+ '>>',
+ token.new(0, 2),
+ }
+ luatexbase.add_to_callback('luaotfload.parse_transparent', function(value)
+ value = (octet * -1):match(value)
+ if not value then
+ tex.error'Invalid transparency value'
+ return
+ end
+ value = value:sub(1, -2)
+ local result = 'opacity' .. value
+ tex.runtoks(function()
+ transparent_register[6], transparent_register[10], transparent_register[12] = result, value, value
+ tex.sprint(-2, transparent_register)
+ end)
+ return '/' .. result .. ' gs'
+ end, 'l3opacity')
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</lua>
+% \end{macrocode}
+%
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend-pdf.dtx b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-pdf.dtx
new file mode 100644
index 00000000000..cf09c0eec22
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend-pdf.dtx
@@ -0,0 +1,1755 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-pdf.dtx
+%
+% Copyright (C) 2019-2024 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-pdf} module\\ Backend PDF features^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-pdf} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=pdf>
+% \end{macrocode}
+%
+% Setting up PDF resources is a complex area with only limited documentation
+% in the engine manuals. The following code builds heavily on existing ideas
+% from \pkg{hyperref} work by Sebastian Rahtz and Heiko Oberdiek, and
+% 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}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pdfmark:n, \@@_backend_pdfmark:e}
+% Used often enough it should be a separate function.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pdfmark:n #1
+ { \__kernel_backend_postscript:n { mark #1 ~ pdfmark } }
+\cs_generate_variant:Nn \@@_backend_pdfmark:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2
+ { \@@_backend_pdfmark:n { { Catalog } << /#1 ~ #2 >> /PUT } }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2
+ { \@@_backend_pdfmark:n { /#1 ~ #2 /DOCINFO } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new:
+ { \int_gincr:N \g_@@_backend_object_int }
+\cs_new:Npn \@@_backend_object_ref:n #1 { { pdf.obj #1 } }
+\cs_new_eq:NN \@@_backend_object_id:n \@@_backend_object_ref:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_object_write:nnn, \@@_backend_object_write:nne,
+% \@@_backend_object_write_aux:nnn
+% }
+% \begin{macro}
+% {
+% \@@_backend_object_write_array:nn ,
+% \@@_backend_object_write_dict:nn ,
+% \@@_backend_object_write_fstream:nn ,
+% \@@_backend_object_write_stream:nn
+% }
+% \begin{macro}{\@@_backend_object_write_stream:nnn}
+% This is where we choose the actual type: some work to get things
+% right. To allow code sharing with the anonymous version, we use an
+% auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3
+ {
+ \@@_backend_object_write_aux:nnn
+ { \@@_backend_object_ref:n {#1} }
+ {#2} {#3}
+ }
+\cs_generate_variant:Nn \@@_backend_object_write:nnn { nne }
+\cs_new_protected:Npn \@@_backend_object_write_aux:nnn #1#2#3
+ {
+ \@@_backend_pdfmark:e
+ {
+ /_objdef ~ #1
+ /type
+ \str_case:nn {#2}
+ {
+ { array } { /array }
+ { dict } { /dict }
+ { fstream } { /stream }
+ { stream } { /stream }
+ }
+ /OBJ
+ }
+ \use:c { @@_backend_object_write_ #2 :nn } {#1} {#3}
+ }
+\cs_new_protected:Npn \@@_backend_object_write_array:nn #1#2
+ {
+ \@@_backend_pdfmark:e
+ { #1 ~0~ [ ~ \exp_not:n {#2} ~ ] ~ /PUTINTERVAL }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_dict:nn #1#2
+ {
+ \@@_backend_pdfmark:e
+ { #1 << \exp_not:n {#2} >> /PUT }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_fstream:nn #1#2
+ {
+ \exp_args:Ne
+ \@@_backend_object_write_fstream:nnn {#1} #2
+ }
+\cs_new_protected:Npn \@@_backend_object_write_fstream:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ SDict ~ begin ~
+ mark ~ #1 ~ << #2 >> /PUT ~ pdfmark ~
+ mark ~ #1 ~ ( #3 )~ ( r )~ file ~ /PUT ~ pdfmark ~
+ end
+ }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nn #1#2
+ {
+ \exp_args:Ne
+ \@@_backend_object_write_stream:nnn {#1} #2
+ }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ mark ~ #1 ~ ( #3 ) /PUT ~ pdfmark ~
+ mark ~ #1 ~ << #2 >> /PUT ~ pdfmark
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_now:nn, \@@_backend_object_now:ne}
+% No anonymous objects, so things are done manually.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2
+ {
+ \int_gincr:N \g_@@_backend_object_int
+ \@@_backend_object_write_aux:nnn
+ { { pdf.obj \int_use:N \g_@@_backend_object_int } }
+ {#1} {#2}
+ }
+\cs_generate_variant:Nn \@@_backend_object_now:nn { ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_object_last:}
+% Much like the annotation version.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_object_last:
+ { { pdf.obj \int_use:N \g_@@_backend_object_int } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% Page references are easy in \texttt{dvips}.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_pageobject_ref:n #1
+ { { Page #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Annotations}
+%
+% 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 co-ordinates 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 crated 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@hook
+ {
+ \tl_put_right:Nn \@makecol@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
+% the current anchor point actually is: worked out in PostScript. For the
+% rectangle version, we have a bit more PostScript: we need two points.
+% fitr without rule spec doesn't work, so it falls back to \texttt{/Fit} here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2
+ {
+ \__kernel_backend_postscript:n { pdf.dest.anchor }
+ \@@_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 \@@_backend_destination:nnnn #1#2#3#4
+ {
+ \exp_args:Ne \@@_backend_destination_aux:nnnn
+ { \dim_eval:n {#2} } {#1} {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_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 }
+ \@@_backend_pdfmark:n
+ {
+ /View
+ [
+ /FitR ~
+ pdf.llx ~ pdf.lly ~ pdf.dest2device ~
+ pdf.urx ~ pdf.ury ~ pdf.dest2device
+ ]
+ /Dest ( #2 ) cvn
+ /DEST
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% Doable for the usual \texttt{ps2pdf} method.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_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 \@@_backend_compress_objects:n #1
+ {
+ \bool_if:nF {#1}
+ {
+ \__kernel_backend_literal_postscript:n
+ {
+ /setdistillerparams ~ where
+ { pop << /CompressStreams ~ false >> setdistillerparams }
+ if
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_version_major_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_major: { \int_eval:n {#1} }
+ }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_minor: { \int_eval:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% Data not available!
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_version_major: { -1 }
+\cs_new:Npn \@@_backend_version_minor: { -1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Marked content}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% Simple wrappers.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2
+ { \@@_backend_pdfmark:n { /#1 ~ #2 /BDC } }
+\cs_new_protected:Npn \@@_backend_emc:
+ { \@@_backend_pdfmark:n { /EMC } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backend}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \subsubsection{Annotations}
+%
+% \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
+% with the danger of an unterminated keyword. The zoom given here is a
+% percentage, but we need to pass it as \emph{per mille}. The rectangle
+% version is also easy as everything is build in.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D dest ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfdest:D
+%</pdftex>
+ name {#1}
+ \str_case:nnF {#2}
+ {
+ { xyz } { xyz }
+ { fit } { fit }
+ { fitb } { fitb }
+ { fitbh } { fitbh }
+ { fitbv } { fitbv }
+ { fith } { fith }
+ { fitv } { fitv }
+ { fitr } { fitr }
+ }
+ { xyz ~ zoom \fp_eval:n { #2 * 10 } }
+ \scan_stop:
+ }
+\cs_new_protected:Npn \@@_backend_destination:nnnn #1#2#3#4
+ {
+%<*luatex>
+ \tex_pdfextension:D dest ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfdest:D
+%</pdftex>
+ name {#1}
+ fitr ~
+ width \dim_eval:n {#2} ~
+ height \dim_eval:n {#3} ~
+ depth \dim_eval:n {#4} \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D catalog
+%</luatex>
+%<*pdftex>
+ \tex_pdfcatalog:D
+%</pdftex>
+ { / #1 ~ #2 }
+ }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D info
+%</luatex>
+%<*pdftex>
+ \tex_pdfinfo:D
+%</pdftex>
+ { / #1 ~ #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{variable}{\g_@@_backend_object_prop}
+% For tracking objects to allow finalisation.
+% \begin{macrocode}
+\prop_new:N \g_@@_backend_object_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% Declaring objects means reserving at the PDF level plus starting
+% tracking.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new:
+ {
+%<*luatex>
+ \tex_pdfextension:D obj ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfobj:D
+%</pdftex>
+ reserveobjnum ~
+ \int_gset:Nn \g_@@_backend_object_int
+%<*luatex>
+ { \tex_pdffeedback:D lastobj }
+%</luatex>
+%<*pdftex>
+ { \tex_pdflastobj:D }
+%</pdftex>
+ }
+\cs_new:Npn \@@_backend_object_ref:n #1 { #1 ~ 0 ~ R }
+\cs_new:Npn \@@_backend_object_id:n #1 {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_write:nnn, \@@_backend_object_write:nne}
+% \begin{macro}[EXP]{\@@_backend_object_write:nn}
+% \begin{macro}[EXP]{\@@_exp_not_i:nn, \@@_exp_not_ii:nn}
+% Writing the data needs a little information about the structure of the
+% object.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3
+ {
+%<*luatex>
+ \tex_immediate:D \tex_pdfextension:D obj ~
+%</luatex>
+%<*pdftex>
+ \tex_immediate:D \tex_pdfobj:D
+%</pdftex>
+ useobjnum ~ #1
+ \@@_backend_object_write:nn {#2} {#3}
+ }
+\cs_new:Npn \@@_backend_object_write:nn #1#2
+ {
+ \str_case:nn {#1}
+ {
+ { array } { { [ ~ \exp_not:n {#2} ~ ] } }
+ { dict } { { << ~ \exp_not:n {#2} ~ >> } }
+ { fstream }
+ {
+ stream ~ attr ~ { \@@_exp_not_i:nn #2 } ~
+ file ~ { \@@_exp_not_ii:nn #2 }
+ }
+ { stream }
+ {
+ stream ~ attr ~ { \@@_exp_not_i:nn #2 } ~
+ { \@@_exp_not_ii:nn #2 }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_backend_object_write:nnn { nne }
+\cs_new:Npn \@@_exp_not_i:nn #1#2 { \exp_not:n {#1} }
+\cs_new:Npn \@@_exp_not_ii:nn #1#2 { \exp_not:n {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_now:nn, \@@_backend_object_now:ne}
+% Much like writing, but direct creation.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2
+ {
+%<*luatex>
+ \tex_immediate:D \tex_pdfextension:D obj ~
+%</luatex>
+%<*pdftex>
+ \tex_immediate:D \tex_pdfobj:D
+%</pdftex>
+ \@@_backend_object_write:nn {#1} {#2}
+ }
+\cs_generate_variant:Nn \@@_backend_object_now:nn { ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_object_last:}
+% Much like annotation.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_object_last:
+ {
+ \exp_not:N \int_value:w
+%<*luatex>
+ \exp_not:N \tex_pdffeedback:D lastobj ~
+%</luatex>
+%<*pdftex>
+ \exp_not:N \tex_pdflastobj:D
+%</pdftex>
+ \c_space_tl 0 ~ R
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% The usual wrapper situation; the three spaces here are essential.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_pageobject_ref:n #1
+ {
+ \exp_not:N \int_value:w
+%<*luatex>
+ \exp_not:N \tex_pdffeedback:D pageref
+%</luatex>
+%<*pdftex>
+ \exp_not:N \tex_pdfpageref:D
+%</pdftex>
+ \c_space_tl #1 \c_space_tl \c_space_tl \c_space_tl 0 ~ R
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% \begin{macro}{\@@_backend_objcompresslevel:n}
+% Simply pass data to the engine.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_compresslevel:n #1
+ {
+ \tex_global:D
+%<*luatex>
+ \tex_pdfvariable:D compresslevel
+%</luatex>
+%<*pdftex>
+ \tex_pdfcompresslevel:D
+%</pdftex>
+ \int_value:w \int_eval:n {#1} \scan_stop:
+ }
+\cs_new_protected:Npn \@@_backend_compress_objects:n #1
+ {
+ \bool_if:nTF {#1}
+ { \@@_backend_objcompresslevel:n { 2 } }
+ { \@@_backend_objcompresslevel:n { 0 } }
+ }
+\cs_new_protected:Npn \@@_backend_objcompresslevel:n #1
+ {
+ \tex_global:D
+%<*luatex>
+ \tex_pdfvariable:D objcompresslevel
+%</luatex>
+%<*pdftex>
+ \tex_pdfobjcompresslevel:D
+%</pdftex>
+ #1 \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% The availability of the primitive is not universal, so we have to test
+% at load time.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_backend_version_major_gset:n #1
+ {
+%<*luatex>
+ \int_compare:nNnT \tex_luatexversion:D > { 106 }
+ {
+ \exp_not:N \tex_global:D \tex_pdfvariable:D majorversion
+ \exp_not:N \int_eval:n {#1} \scan_stop:
+ }
+%</luatex>
+%<*pdftex>
+ \cs_if_exist:NT \tex_pdfmajorversion:D
+ {
+ \exp_not:N \tex_global:D \tex_pdfmajorversion:D
+ \exp_not:N \int_eval:n {#1} \scan_stop:
+ }
+%</pdftex>
+ }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1
+ {
+ \tex_global:D
+%<*luatex>
+ \tex_pdfvariable:D minorversion
+%</luatex>
+%<*pdftex>
+ \tex_pdfminorversion:D
+%</pdftex>
+ \int_eval:n {#1} \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% As above.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_version_major:
+ {
+%<*luatex>
+ \int_compare:nNnTF \tex_luatexversion:D > { 106 }
+ { \exp_not:N \tex_the:D \tex_pdfvariable:D majorversion }
+ { 1 }
+%</luatex>
+%<*pdftex>
+ \cs_if_exist:NTF \tex_pdfmajorversion:D
+ { \exp_not:N \tex_the:D \tex_pdfmajorversion:D }
+ { 1 }
+%</pdftex>
+ }
+\cs_new:Npn \@@_backend_version_minor:
+ {
+ \tex_the:D
+%<*luatex>
+ \tex_pdfvariable:D minorversion
+%</luatex>
+%<*pdftex>
+ \tex_pdfminorversion:D
+%</pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Marked content}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% Simple wrappers. May need refinement: see
+% \url{https://chat.stackexchange.com/transcript/message/49970158#49970158}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \@@_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+% \end{macrocode}
+% \end{macro}
+% \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: used where we can.
+% \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}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2
+ { \@@_backend:n { put ~ @catalog << /#1 ~ #2 >> } }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2
+ { \@@_backend:n { docinfo << /#1 ~ #2 >> } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{variable}{\g_@@_backend_object_prop}
+% For tracking objects to allow finalisation.
+% \begin{macrocode}
+\prop_new:N \g_@@_backend_object_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% Objects are tracked at the macro level, but we don't have to do anything
+% at this stage.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new:
+ { \int_gincr:N \g_@@_backend_object_int }
+\cs_new:Npn \@@_backend_object_ref:n #1 { @pdf.obj #1 }
+\cs_new_eq:NN \@@_backend_object_id:n \@@_backend_object_ref:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_write:nnn, \@@_backend_object_write:nne}
+% \begin{macro}
+% {
+% \@@_backend_object_write_array:nn ,
+% \@@_backend_object_write_dict:nn ,
+% \@@_backend_object_write_fstream:nn ,
+% \@@_backend_object_write_stream:nn
+% }
+% \begin{macro}{\@@_backend_object_write_stream:nnnn}
+% This is where we choose the actual type.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3
+ {
+ \use:c { @@_backend_object_write_ #2 :nn }
+ { \@@_backend_object_ref:n {#1} } {#3}
+ }
+\cs_generate_variant:Nn \@@_backend_object_write:nnn { nne }
+\cs_new_protected:Npn \@@_backend_object_write_array:nn #1#2
+ {
+ \@@_backend:e
+ { obj ~ #1 ~ [ ~ \exp_not:n {#2} ~ ] }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_dict:nn #1#2
+ {
+ \@@_backend:e
+ { obj ~ #1 ~ << ~ \exp_not:n {#2} ~ >> }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_fstream:nn #1#2
+ { \@@_backend_object_write_stream:nnnn { f } {#1} #2 }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nn #1#2
+ { \@@_backend_object_write_stream:nnnn { } {#1} #2 }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nnnn #1#2#3#4
+ {
+ \@@_backend:e
+ {
+ #1 stream ~ #2 ~
+ ( \exp_not:n {#4} ) ~ << \exp_not:n {#3} >>
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_now:nn, \@@_backend_object_now:ne}
+% No anonymous objects with \texttt{dvipdfmx} so we have to give an
+% object name.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2
+ {
+ \int_gincr:N \g_@@_backend_object_int
+ \exp_args:Nne \use:c { @@_backend_object_write_ #1 :nn }
+ { @pdf.obj \int_use:N \g_@@_backend_object_int }
+ {#2}
+ }
+\cs_generate_variant:Nn \@@_backend_object_now:nn { ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_last:}
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_object_last:
+ { @pdf.obj \int_use:N \g_@@_backend_object_int }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% Page references are easy in \texttt{dvipdfmx}/\XeTeX{}.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_pageobject_ref:n #1
+ { @page #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Annotations}
+%
+% \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}
+% is from Alexander Grahn: the idea is to avoid needing to do any calculations
+% in \TeX{} by using the backend data for \texttt{@xpos} and \texttt{@ypos}.
+% \texttt{/FitR} without rule spec doesn't work, so it falls back to
+% \texttt{/Fit} here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2
+ {
+ \@@_backend:e
+ {
+ dest ~ ( \exp_not:n {#1} )
+ [
+ @thispage
+ \str_case:nnF {#2}
+ {
+ { xyz } { /XYZ ~ @xpos ~ @ypos ~ null }
+ { fit } { /Fit }
+ { fitb } { /FitB }
+ { fitbh } { /FitBH }
+ { fitbv } { /FitBV ~ @xpos }
+ { fith } { /FitH ~ @ypos }
+ { fitv } { /FitV ~ @xpos }
+ { fitr } { /Fit }
+ }
+ { /XYZ ~ @xpos ~ @ypos ~ \fp_eval:n { (#2) / 100 } }
+ ]
+ }
+ }
+\cs_new_protected:Npn \@@_backend_destination:nnnn #1#2#3#4
+ {
+ \exp_args:Ne \@@_backend_destination_aux:nnnn
+ { \dim_eval:n {#2} } {#1} {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_backend_destination_aux:nnnn #1#2#3#4
+ {
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n {#4}
+ \hbox:n
+ {
+ \@@_backend:n { obj ~ @pdf_ #2 _llx ~ @xpos }
+ \@@_backend:n { obj ~ @pdf_ #2 _lly ~ @ypos }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n {#1}
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n { -#3 }
+ \hbox:n
+ {
+ \@@_backend:n
+ {
+ dest ~ (#2)
+ [
+ @thispage
+ /FitR ~
+ @pdf_ #2 _llx ~ @pdf_ #2 _lly ~
+ @xpos ~ @ypos
+ ]
+ }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n { -#1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% Pass data to the backend: these are a one-shot.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_compresslevel:n #1
+ { \__kernel_backend_literal:e { dvipdfmx:config~z~ \int_eval:n {#1} } }
+\cs_new_protected:Npn \@@_backend_compress_objects:n #1
+ {
+ \bool_if:nF {#1}
+ { \__kernel_backend_literal:n { dvipdfmx:config~C~0x40 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% We start with the assumption that the default is active.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_version_major_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_major: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:majorversion~ \@@_backend_version_major: }
+ }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_minor: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:minorversion~ \@@_backend_version_minor: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% We start with the assumption that the default is active.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_version_major: { 1 }
+\cs_new:Npn \@@_backend_version_minor: { 5 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Marked content}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% Simple wrappers. May need refinement: see
+% \url{https://chat.stackexchange.com/transcript/message/49970158#49970158}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \@@_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \subsubsection{Annotations}
+%
+% \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}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_destination:nnnn #1#2#3#4 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% No-op.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% \begin{macro}{\@@_backend_object_write:nnn, \@@_backend_object_write:ne}
+% \begin{macro}{\@@_backend_object_now:nn, , \@@_backend_object_now:ne}
+% \begin{macro}{\@@_backend_object_last:}
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% All no-ops here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new: { }
+\cs_new:Npn \@@_backend_object_ref:n #1 { }
+\cs_new:Npn \@@_backend_object_id:n #1 { }
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_object_write:nne #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_object_now:ne #1#2 { }
+\cs_new:Npn \@@_backend_object_last: { }
+\cs_new:Npn \@@_backend_pageobject_ref:n #1 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% These are all no-ops.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_compresslevel:n #1 { }
+\cs_new_protected:Npn \@@_backend_compress_objects:n #1 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% Data not available!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_version_major_gset:n #1 { }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% Data not available!
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_version_major: { -1 }
+\cs_new:Npn \@@_backend_version_minor: { -1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% More no-ops.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_emc: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \subsection{PDF Page size (media box)}
+%
+% For setting the media box, the split between backends is somewhat different
+% to other areas, thus we approach this separately. The code here assumes a
+% recent \LaTeXe{}: that is ensured at the level above.
+%
+% \begin{macrocode}
+%<*dvipdfmx|dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pagesize_gset:nn}
+% This is done as a backend literal, so we deal with it using the shipout
+% hook.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pagesize_gset:nn #1#2
+ {
+ \__kernel_backend_first_shipout:n
+ {
+ \__kernel_backend_literal:e
+ {
+%<*dvipdfmx>
+ pdf:pagesize ~
+ width ~ \dim_eval:n {#1} ~
+ height ~ \dim_eval:n {#2}
+%</dvipdfmx>
+%<*dvips>
+ papersize = \dim_eval:n {#1} , \dim_eval:n {#2}
+%</dvips>
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pagesize_gset:nn}
+% Pass to the primitives.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pagesize_gset:nn #1#2
+ {
+ \dim_gset:Nn \tex_pagewidth:D {#1}
+ \dim_gset:Nn \tex_pageheight:D {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pagesize_gset:nn}
+% A no-op.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pagesize_gset:nn #1#2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex-dev/l3backend/l3backend.ins b/Master/texmf-dist/source/latex-dev/l3backend/l3backend.ins
new file mode 100644
index 00000000000..e24c41d2365
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/l3backend/l3backend.ins
@@ -0,0 +1,168 @@
+\iffalse meta-comment
+
+File l3backend.ins
+
+Copyright (C) 2019-2024 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.
+
+-----------------------------------------------------------------------
+
+Any modification of this file should ensure that the copyright and
+license information is placed in the derived files.
+
+\fi
+
+\let\jobname\relax
+\input docstrip %
+\askforoverwritefalse
+
+\preamble
+
+Copyright (C) 2019-2024 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.
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+
+\keepsilent
+
+\generate
+ {
+ \file{l3backend-dvipdfmx.def}
+ {
+ \from{l3backend-basics.dtx} {package,dvipdfmx}
+ \from{l3backend-color.dtx} {package,dvipdfmx}
+ \from{l3backend-box.dtx} {package,dvipdfmx}
+ \from{l3backend-draw.dtx} {package,dvipdfmx}
+ \from{l3backend-graphics.dtx}{package,dvipdfmx}
+ \from{l3backend-pdf.dtx} {package,dvipdfmx}
+ \from{l3backend-opacity.dtx} {package,dvipdfmx}
+ }
+ }
+\generate
+ {
+ \file{l3backend-dvips.def}
+ {
+ \from{l3backend-basics.dtx} {package,dvips}
+ \from{l3backend-color.dtx} {package,dvips}
+ \from{l3backend-box.dtx} {package,dvips}
+ \from{l3backend-draw.dtx} {package,dvips}
+ \from{l3backend-graphics.dtx}{package,dvips}
+ \from{l3backend-pdf.dtx} {package,dvips}
+ \from{l3backend-opacity.dtx} {package,dvips}
+ }
+ \file{l3backend-dvips.pro}
+ {
+ \from{l3backend-header.dtx} {header,dvips}
+ }
+ }
+\generate
+ {
+ \file{l3backend-dvisvgm.def}
+ {
+ \from{l3backend-basics.dtx} {package,dvisvgm}
+ \from{l3backend-color.dtx} {package,dvisvgm}
+ \from{l3backend-box.dtx} {package,dvisvgm}
+ \from{l3backend-draw.dtx} {package,dvisvgm}
+ \from{l3backend-graphics.dtx}{package,dvisvgm}
+ \from{l3backend-pdf.dtx} {package,dvisvgm}
+ \from{l3backend-opacity.dtx} {package,dvisvgm}
+ }
+ }
+\generate
+ {
+ \file{l3backend-luatex.def}
+ {
+ \from{l3backend-basics.dtx} {package,luatex}
+ \from{l3backend-color.dtx} {package,luatex}
+ \from{l3backend-box.dtx} {package,luatex}
+ \from{l3backend-draw.dtx} {package,luatex}
+ \from{l3backend-graphics.dtx}{package,luatex}
+ \from{l3backend-pdf.dtx} {package,luatex}
+ \from{l3backend-opacity.dtx} {package,luatex}
+ }
+ }
+\generate
+ {
+ \file{l3backend-pdftex.def}
+ {
+ \from{l3backend-basics.dtx} {package,pdftex}
+ \from{l3backend-color.dtx} {package,pdftex}
+ \from{l3backend-box.dtx} {package,pdftex}
+ \from{l3backend-draw.dtx} {package,pdftex}
+ \from{l3backend-graphics.dtx}{package,pdftex}
+ \from{l3backend-pdf.dtx} {package,pdftex}
+ \from{l3backend-opacity.dtx} {package,pdftex}
+ }
+ }
+\generate
+ {
+ \file{l3backend-xetex.def}
+ {
+ \from{l3backend-basics.dtx} {package,xetex}
+ \from{l3backend-color.dtx} {package,xetex}
+ \from{l3backend-box.dtx} {package,xetex}
+ \from{l3backend-draw.dtx} {package,xetex}
+ \from{l3backend-graphics.dtx}{package,xetex}
+ \from{l3backend-pdf.dtx} {package,xetex}
+ \from{l3backend-opacity.dtx} {package,xetex}
+ }
+ }
+
+% Lua code
+
+\def\MetaPrefix{--}
+\preamble
+
+Copyright (C) 2023,2024 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.
+
+\endpreamble
+\nopostamble
+\generate
+ {
+ \file{l3backend-luatex.lua}
+ {
+ \from{l3backend-color.dtx} {lua}
+ \from{l3backend-opacity.dtx} {lua}
+ }
+ }
+
+\endbatchfile
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvipdfmx.def b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvipdfmx.def
new file mode 100644
index 00000000000..a8a54ec2dae
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvipdfmx.def
@@ -0,0 +1,859 @@
+%%
+%% This is file `l3backend-dvipdfmx.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3backend-basics.dtx (with options: `package,dvipdfmx')
+%% l3backend-color.dtx (with options: `package,dvipdfmx')
+%% l3backend-box.dtx (with options: `package,dvipdfmx')
+%% l3backend-draw.dtx (with options: `package,dvipdfmx')
+%% l3backend-graphics.dtx (with options: `package,dvipdfmx')
+%% l3backend-pdf.dtx (with options: `package,dvipdfmx')
+%% l3backend-opacity.dtx (with options: `package,dvipdfmx')
+%%
+%% Copyright (C) 2019-2024 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.
+%%
+%% File: l3backend-basics.dtx
+\ProvidesExplFile
+ {l3backend-dvipdfmx.def}{2024-04-11}{}
+ {L3 backend support: dvipdfmx}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+ {l3backend-dvipdfmx.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ { \__kernel_backend_literal:n { pdf:literal~ #1 } }
+\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+\cs_new_protected:Npn \__kernel_backend_literal_page:n #1
+ { \__kernel_backend_literal:n { pdf:literal~direct~ #1 } }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ { \__kernel_backend_literal:n { x:gsave } }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ { \__kernel_backend_literal:n { x:grestore } }
+%% File: l3backend-color.dtx
+\cs_new_protected:Npn \__color_backend_select:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ [ #1 ] } }
+\cs_new_eq:NN \__color_backend_select_cmyk:n \__color_backend_select:n
+\cs_new_eq:NN \__color_backend_select_gray:n \__color_backend_select:n
+\cs_new_eq:NN \__color_backend_select_rgb:n \__color_backend_select:n
+\cs_new_protected:Npn \__color_backend_reset:
+ { \__kernel_backend_literal:n { pdf : ec } }
+\cs_new_protected:Npn \__color_backend_select_named:n #1
+ {
+ \str_if_eq:nnTF {#1} { Black }
+ { \__color_backend_select_gray:n { 0 } }
+ { \msg_error:nnn { color } { unknown-named-color } {#1} }
+ }
+\msg_new:nnn { color } { unknown-named-color }
+ { Named~color~'#1'~is~not~known. }
+\prop_new:N \g__color_backend_colorant_prop
+\cs_new:Npe \__color_backend_devicen_colorants:n #1
+ {
+ \exp_not:N \tl_if_blank:nF {#1}
+ {
+ \c_space_tl
+ << ~
+ /Colorants ~
+ << ~
+ \exp_not:N \__color_backend_devicen_colorants:w #1 ~
+ \exp_not:N \q_recursion_tail \c_space_tl
+ \exp_not:N \q_recursion_stop
+ >> ~
+ >>
+ }
+ }
+\cs_new:Npn \__color_backend_devicen_colorants:w #1 ~
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \prop_if_in:NnT \g__color_backend_colorant_prop {#1}
+ {
+ #1 ~
+ \prop_item:Nn \g__color_backend_colorant_prop {#1} ~
+ }
+ \__color_backend_devicen_colorants:w
+ }
+\cs_new_protected:Npn \__color_backend_select_separation:nn #1#2
+ { \__kernel_backend_literal:e { pdf : bc ~ \pdf_object_ref:n {#1} ~ [ #2 ] } }
+\cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
+\cs_new_eq:NN \__color_backend_select_iccbased:nn \__color_backend_select_separation:nn
+\cs_new_protected:Npn \__color_backend_init_resource:n #1
+ {
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \pdf_object_unnamed_write:ne { dict }
+ {
+ /FunctionType ~ 2
+ /Domain ~ [0 ~ 1]
+ \tl_if_blank:nF {#3} { /Range ~ [#3] }
+ /C0 ~ [#4] ~
+ /C1 ~ [#5] /N ~ 1
+ }
+ \exp_args:Ne \__color_backend_separation_init:nn
+ { \str_convert_pdfname:n {#1} } {#2}
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nn #1#2
+ {
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ { /Separation /#1 ~ #2 ~ \pdf_object_ref_last: }
+ }
+ \prop_gput:Nne \g__color_backend_colorant_prop { /#1 }
+ { \pdf_object_ref_last: }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_illuminant_CIELAB_ #1 }
+ {
+ \pdf_object_new:n { __color_illuminant_CIELAB_ #1 }
+ \pdf_object_write:nne { __color_illuminant_CIELAB_ #1 } { array }
+ {
+ /Lab ~
+ <<
+ /WhitePoint ~
+ [ \tl_use:c { c__color_model_whitepoint_CIELAB_ #1 _tl } ]
+ /Range ~ [ \c__color_model_range_CIELAB_tl ]
+ >>
+ }
+ }
+ \__color_backend_separation_init:nnnnn
+ {#2}
+ { \pdf_object_ref:n { __color_illuminant_CIELAB_ #1 } }
+ { \c__color_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+\cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
+ {
+ \pdf_object_unnamed_write:ne { stream }
+ {
+ {
+ /FunctionType ~ 4 ~
+ /Domain ~
+ [ ~
+ \prg_replicate:nn
+ { 0 \__color_backend_devicen_init:w #1 ~ \s__color_stop }
+ { 0 ~ 1 ~ }
+ ] ~
+ /Range ~
+ [ ~
+ \str_case:nn {#2}
+ {
+ { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ { /DeviceGray } { 0 ~ 1 }
+ { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ } ~
+ ]
+ }
+ { {#3} }
+ }
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ {
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ \pdf_object_ref_last:
+ \__color_backend_devicen_colorants:n {#1}
+ }
+ }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
+ {
+ + 1
+ \tl_if_blank:nF {#2}
+ { \__color_backend_devicen_init:w #2 \s__color_stop }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_init:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nne { __color_icc_ #1 } { fstream }
+ {
+ {
+ /N ~ \exp_not:n { #2 } ~
+ \tl_if_empty:nF { #3 } { /Range~[ #3 ] }
+ }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_device:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nnn { __color_icc_ #1 } { fstream }
+ {
+ { /N ~ #3 }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { Default #2 }
+ }
+\cs_new_protected:Npn \__color_backend_fill:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ fill ~ [ #1 ] } }
+\cs_new_eq:NN \__color_backend_fill_cmyk:n \__color_backend_fill:n
+\cs_new_eq:NN \__color_backend_fill_gray:n \__color_backend_fill:n
+\cs_new_eq:NN \__color_backend_fill_rgb:n \__color_backend_fill:n
+\cs_new_protected:Npn \__color_backend_stroke:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ stroke ~ [ #1 ] } }
+\cs_new_eq:NN \__color_backend_stroke_cmyk:n \__color_backend_stroke:n
+\cs_new_eq:NN \__color_backend_stroke_gray:n \__color_backend_stroke:n
+\cs_new_eq:NN \__color_backend_stroke_rgb:n \__color_backend_stroke:n
+\cs_new_protected:Npn \__color_backend_fill_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ fill ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ stroke ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_eq:NN \__color_backend_fill_devicen:nn \__color_backend_fill_separation:nn
+\cs_new_eq:NN \__color_backend_stroke_devicen:nn \__color_backend_stroke_separation:nn
+\cs_new_eq:NN \__color_backend_fill_reset: \__color_backend_reset:
+\cs_new_eq:NN \__color_backend_stroke_reset: \__color_backend_reset:
+%% File: l3backend-box.dtx
+\cs_new_protected:Npn \__box_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+\cs_new_protected:Npn \__box_backend_rotate:Nn #1#2
+ { \exp_args:NNf \__box_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \__box_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#2} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( #2 , 5 ) } }
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\cs_new_protected:Npn \__box_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+%% 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_protected:Npn \__draw_backend_begin:
+ { \__draw_backend_scope_begin: }
+\cs_new_protected:Npn \__draw_backend_end:
+ { \__draw_backend_scope_end: }
+\cs_new_eq:NN \__draw_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \__draw_backend_scope_end: \__kernel_backend_scope_end:
+\cs_new_protected:Npn \__draw_backend_moveto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
+ }
+\cs_new_protected:Npn \__draw_backend_lineto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
+ }
+\cs_new_protected:Npn \__draw_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ c
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_rectangle:nnnn #1#2#3#4
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ re
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_evenodd_rule:
+ { \bool_gset_true:N \g__draw_draw_eor_bool }
+\cs_new_protected:Npn \__draw_backend_nonzero_rule:
+ { \bool_gset_false:N \g__draw_draw_eor_bool }
+\bool_new:N \g__draw_draw_eor_bool
+\cs_new_protected:Npn \__draw_backend_closepath:
+ { \__draw_backend_literal:n { h } }
+\cs_new_protected:Npn \__draw_backend_stroke:
+ { \__draw_backend_literal:n { S } }
+\cs_new_protected:Npn \__draw_backend_closestroke:
+ { \__draw_backend_literal:n { s } }
+\cs_new_protected:Npn \__draw_backend_fill:
+ {
+ \__draw_backend_literal:e
+ { f \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_fillstroke:
+ {
+ \__draw_backend_literal:e
+ { B \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_clip:
+ {
+ \__draw_backend_literal:e
+ { W \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_discardpath:
+ { \__draw_backend_literal:n { n } }
+\cs_new_protected:Npn \__draw_backend_dash_pattern:nn #1#2
+ {
+ \__draw_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \__draw_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ d
+ }
+ }
+\cs_new:Npn \__draw_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \__draw_backend_linewidth:n #1
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ w }
+ }
+\cs_new_protected:Npn \__draw_backend_miterlimit:n #1
+ { \__draw_backend_literal:e { #1 ~ M } }
+\cs_new_protected:Npn \__draw_backend_cap_butt:
+ { \__draw_backend_literal:n { 0 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_round:
+ { \__draw_backend_literal:n { 1 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_rectangle:
+ { \__draw_backend_literal:n { 2 ~ J } }
+\cs_new_protected:Npn \__draw_backend_join_miter:
+ { \__draw_backend_literal:n { 0 ~ j } }
+\cs_new_protected:Npn \__draw_backend_join_round:
+ { \__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
+ {
+ \__draw_backend_cm_decompose:nnnnN {#1} {#2} {#3} {#4}
+ \__draw_backend_cm_aux:nnnn
+ }
+\cs_new_protected:Npn \__draw_backend_cm_aux:nnnn #1#2#3#4
+ {
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#1} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#1 , 5 ) } }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#4} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#4 , 5 ) } }
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \__draw_backend_cm_decompose_auxi:nnnnN
+ { \fp_eval:n { (#1 + #4) / 2 } }
+ { \fp_eval:n { (#1 - #4) / 2 } }
+ { \fp_eval:n { (#3 + #2) / 2 } }
+ { \fp_eval:n { (#3 - #2) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \__draw_backend_cm_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 ) } }
+ { \fp_eval:n { atand ( #4 , #1 ) } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \__draw_backend_cm_decompose_auxiii:nnnnN
+ { \fp_eval:n { ( #4 - #3 ) / 2 } }
+ { \fp_eval:n { ( #1 + #2 ) / 2 } }
+ { \fp_eval:n { ( #1 - #2 ) / 2 } }
+ { \fp_eval:n { ( #4 + #3 ) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
+ {
+ \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
+ { #5 {#1} {#2} {#3} {#4} }
+ { #5 {#1} {#3} {#2} {#4} }
+ }
+\cs_new_protected:Npn \__draw_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:n
+ { pdf:btrans~matrix~ #2 ~ #3 ~ #4 ~ #5 ~ 0 ~ 0 }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_literal:n { pdf:etrans }
+ \__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
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l__graphics_page_int
+ \tl_clear:N \l__graphics_pagebox_tl
+ \__graphics_extract_bb:n {#1}
+ }
+\cs_new_eq:NN \__graphics_backend_getbb_jpeg:n \__graphics_backend_getbb_jpg:n
+\cs_new_eq:NN \__graphics_backend_getbb_png:n \__graphics_backend_getbb_jpg:n
+\cs_new_eq:NN \__graphics_backend_getbb_bmp:n \__graphics_backend_getbb_jpg:n
+\cs_new_protected:Npn \__graphics_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l__graphics_decodearray_str
+ \bool_set_false:N \l__graphics_interpolate_bool
+ \__graphics_extract_bb:n {#1}
+ }
+\int_new:N \g__graphics_track_int
+\cs_new_protected:Npn \__graphics_backend_include_eps:n #1
+ {
+ \__kernel_backend_literal:e
+ {
+ PSfile = #1 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l__graphics_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l__graphics_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l__graphics_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l__graphics_ury_dim
+ }
+ }
+\cs_new_eq:NN \__graphics_backend_include_ps:n \__graphics_backend_include_eps:n
+\cs_new_protected:Npn \__graphics_backend_include_jpg:n #1
+ { \__graphics_backend_include_auxi:nn {#1} { image } }
+\cs_new_eq:NN \__graphics_backend_include_jpeg:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_png:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_bmp:n \__graphics_backend_include_jpg:n
+\cs_new_protected:Npn \__graphics_backend_include_pdf:n #1
+ { \__graphics_backend_include_auxi:nn {#1} { epdf } }
+\cs_new_protected:Npn \__graphics_backend_include_auxi:nn #1#2
+ {
+ \__graphics_backend_include_auxii:enn
+ {
+ \tl_if_empty:NF \l__graphics_pagebox_tl
+ { : \l__graphics_pagebox_tl }
+ \int_compare:nNnT \l__graphics_page_int > 1
+ { :P \int_use:N \l__graphics_page_int }
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { :D \l__graphics_decodearray_str }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { :I }
+ }
+ {#1} {#2}
+ }
+\cs_new_protected:Npn \__graphics_backend_include_auxii:nnn #1#2#3
+ {
+ \int_if_exist:cTF { c__graphics_ #2#1 _int }
+ {
+ \__kernel_backend_literal:e
+ { pdf:usexobj~@graphic \int_use:c { c__graphics_ #2#1 _int } }
+ }
+ { \__graphics_backend_include_auxiii:nnn {#2} {#1} {#3} }
+ }
+\cs_generate_variant:Nn \__graphics_backend_include_auxii:nnn { e }
+\cs_new_protected:Npn \__graphics_backend_include_auxiii:nnn #1#2#3
+ {
+ \int_gincr:N \g__graphics_track_int
+ \int_const:cn { c__graphics_ #1#2 _int } { \g__graphics_track_int }
+ \__kernel_backend_literal:e
+ {
+ pdf:#3~
+ @graphic \int_use:c { c__graphics_ #1#2 _int } ~
+ \int_compare:nNnT \l__graphics_page_int > 1
+ { page ~ \int_use:N \l__graphics_page_int \c_space_tl }
+ \tl_if_empty:NF \l__graphics_pagebox_tl
+ {
+ pagebox ~ \l__graphics_pagebox_tl \c_space_tl
+ bbox ~
+ \dim_to_decimal_in_bp:n \l__graphics_llx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l__graphics_lly_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l__graphics_urx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l__graphics_ury_dim \c_space_tl
+ }
+ (#1)
+ \bool_lazy_or:nnT
+ { \l__graphics_interpolate_bool }
+ { ! \tl_if_empty_p:N \l__graphics_decodearray_str }
+ {
+ <<
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { /Decode~[ \l__graphics_decodearray_str ] }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { /Interpolate~true }
+ >>
+ }
+ }
+ }
+\__graphics_backend_loaded: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 }
+\cs_new_protected:Npn \__pdf_backend_catalog_gput:nn #1#2
+ { \__pdf_backend:n { put ~ @catalog << /#1 ~ #2 >> } }
+\cs_new_protected:Npn \__pdf_backend_info_gput:nn #1#2
+ { \__pdf_backend:n { docinfo << /#1 ~ #2 >> } }
+\prop_new:N \g__pdf_backend_object_prop
+\cs_new_protected:Npn \__pdf_backend_object_new:
+ { \int_gincr:N \g__pdf_backend_object_int }
+\cs_new:Npn \__pdf_backend_object_ref:n #1 { @pdf.obj #1 }
+\cs_new_eq:NN \__pdf_backend_object_id:n \__pdf_backend_object_ref:n
+\cs_new_protected:Npn \__pdf_backend_object_write:nnn #1#2#3
+ {
+ \use:c { __pdf_backend_object_write_ #2 :nn }
+ { \__pdf_backend_object_ref:n {#1} } {#3}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_write:nnn { nne }
+\cs_new_protected:Npn \__pdf_backend_object_write_array:nn #1#2
+ {
+ \__pdf_backend:e
+ { obj ~ #1 ~ [ ~ \exp_not:n {#2} ~ ] }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_dict:nn #1#2
+ {
+ \__pdf_backend:e
+ { obj ~ #1 ~ << ~ \exp_not:n {#2} ~ >> }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_fstream:nn #1#2
+ { \__pdf_backend_object_write_stream:nnnn { f } {#1} #2 }
+\cs_new_protected:Npn \__pdf_backend_object_write_stream:nn #1#2
+ { \__pdf_backend_object_write_stream:nnnn { } {#1} #2 }
+\cs_new_protected:Npn \__pdf_backend_object_write_stream:nnnn #1#2#3#4
+ {
+ \__pdf_backend:e
+ {
+ #1 stream ~ #2 ~
+ ( \exp_not:n {#4} ) ~ << \exp_not:n {#3} >>
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_now:nn #1#2
+ {
+ \int_gincr:N \g__pdf_backend_object_int
+ \exp_args:Nne \use:c { __pdf_backend_object_write_ #1 :nn }
+ { @pdf.obj \int_use:N \g__pdf_backend_object_int }
+ {#2}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_now:nn { ne }
+\cs_new:Npn \__pdf_backend_object_last:
+ { @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
+ {
+ dest ~ ( \exp_not:n {#1} )
+ [
+ @thispage
+ \str_case:nnF {#2}
+ {
+ { xyz } { /XYZ ~ @xpos ~ @ypos ~ null }
+ { fit } { /Fit }
+ { fitb } { /FitB }
+ { fitbh } { /FitBH }
+ { fitbv } { /FitBV ~ @xpos }
+ { fith } { /FitH ~ @ypos }
+ { fitv } { /FitV ~ @xpos }
+ { fitr } { /Fit }
+ }
+ { /XYZ ~ @xpos ~ @ypos ~ \fp_eval:n { (#2) / 100 } }
+ ]
+ }
+ }
+\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
+ {
+ \__pdf_backend:n { obj ~ @pdf_ #2 _llx ~ @xpos }
+ \__pdf_backend:n { obj ~ @pdf_ #2 _lly ~ @ypos }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n {#1}
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n { -#3 }
+ \hbox:n
+ {
+ \__pdf_backend:n
+ {
+ dest ~ (#2)
+ [
+ @thispage
+ /FitR ~
+ @pdf_ #2 _llx ~ @pdf_ #2 _lly ~
+ @xpos ~ @ypos
+ ]
+ }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n { -#1 }
+ }
+\cs_new_protected:Npn \__pdf_backend_compresslevel:n #1
+ { \__kernel_backend_literal:e { dvipdfmx:config~z~ \int_eval:n {#1} } }
+\cs_new_protected:Npn \__pdf_backend_compress_objects:n #1
+ {
+ \bool_if:nF {#1}
+ { \__kernel_backend_literal:n { dvipdfmx:config~C~0x40 } }
+ }
+\cs_new_protected:Npn \__pdf_backend_version_major_gset:n #1
+ {
+ \cs_gset:Npe \__pdf_backend_version_major: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:majorversion~ \__pdf_backend_version_major: }
+ }
+\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1
+ {
+ \cs_gset:Npe \__pdf_backend_version_minor: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:minorversion~ \__pdf_backend_version_minor: }
+ }
+\cs_new:Npn \__pdf_backend_version_major: { 1 }
+\cs_new:Npn \__pdf_backend_version_minor: { 5 }
+\cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \__pdf_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+\cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2
+ {
+ \__kernel_backend_first_shipout:n
+ {
+ \__kernel_backend_literal:e
+ {
+ pdf:pagesize ~
+ width ~ \dim_eval:n {#1} ~
+ height ~ \dim_eval:n {#2}
+ }
+ }
+ }
+%% File: l3backend-opacity.dtx
+\bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity 1 } { << /ca ~ 1 /CA ~ 1 >> }
+ }
+\tl_new:N \l__opacity_backend_fill_tl
+\tl_new:N \l__opacity_backend_stroke_tl
+\tl_set:Nn \l__opacity_backend_fill_tl { 1 }
+\tl_set:Nn \l__opacity_backend_stroke_tl { 1 }
+\cs_new_protected:Npn \__opacity_backend_select:n #1
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#1}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity #1 }
+ { << /ca ~ #1 /CA ~ #1 >> }
+ \__kernel_backend_literal_pdf:n
+ { /opacity #1 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+\cs_new_protected:Npn \__opacity_backend_reset:
+ {
+ \__kernel_backend_literal_pdf:n
+ { /opacity1 ~ gs }
+ }
+\cs_new_protected:Npn \__opacity_backend_fill:n #1
+ {
+ \exp_args:Nno \__opacity_backend_fill_stroke:nn
+ { #1 }
+ { \l__opacity_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \__opacity_backend_stroke:n #1
+ {
+ \exp_args:No \__opacity_backend_fill_stroke:nn
+ { \l__opacity_backend_fill_tl }
+ { #1 }
+ }
+\cs_new_protected:Npn \__opacity_backend_fill_stroke:nn #1#2
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \__opacity_backend_select:n {#1} }
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#2}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.fill #1 }
+ { << /ca ~ #1 >> }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.stroke #2 }
+ { << /CA ~ #2 >> }
+ \__kernel_backend_literal_pdf:n
+ { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+ }
+\bool_lazy_and:nnF
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \cs_gset_protected:Npn \__opacity_backend_select:n #1 { }
+ \cs_gset_protected:Npn \__opacity_backend_fill_stroke:nn #1#2 { }
+ }
+%%
+%%
+%% End of file `l3backend-dvipdfmx.def'.
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.def b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.def
new file mode 100644
index 00000000000..0c60ac3e936
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.def
@@ -0,0 +1,1064 @@
+%%
+%% This is file `l3backend-dvips.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3backend-basics.dtx (with options: `package,dvips')
+%% l3backend-color.dtx (with options: `package,dvips')
+%% l3backend-box.dtx (with options: `package,dvips')
+%% l3backend-draw.dtx (with options: `package,dvips')
+%% l3backend-graphics.dtx (with options: `package,dvips')
+%% l3backend-pdf.dtx (with options: `package,dvips')
+%% l3backend-opacity.dtx (with options: `package,dvips')
+%%
+%% Copyright (C) 2019-2024 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.
+%%
+%% File: l3backend-basics.dtx
+\ProvidesExplFile
+ {l3backend-dvips.def}{2024-04-11}{}
+ {L3 backend support: dvips}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+ {l3backend-dvips.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+\cs_new_protected:Npn \__kernel_backend_literal_postscript:n #1
+ { \__kernel_backend_literal:n { ps:: #1 } }
+\cs_generate_variant:Nn \__kernel_backend_literal_postscript:n { e }
+\cs_new_protected:Npn \__kernel_backend_postscript:n #1
+ { \__kernel_backend_literal:n { ps: SDict ~ begin ~ #1 ~ end } }
+\cs_generate_variant:Nn \__kernel_backend_postscript:n { e }
+\bool_if:NT \g__kernel_backend_header_bool
+ {
+ \__kernel_backend_first_shipout:n
+ { \__kernel_backend_literal:n { header = l3backend-dvips.pro } }
+ }
+\cs_new_protected:Npn \__kernel_backend_align_begin:
+ {
+ \__kernel_backend_literal:n { ps::[begin] }
+ \__kernel_backend_literal_postscript:n { currentpoint }
+ \__kernel_backend_literal_postscript:n { currentpoint~translate }
+ }
+\cs_new_protected:Npn \__kernel_backend_align_end:
+ {
+ \__kernel_backend_literal_postscript:n { neg~exch~neg~exch~translate }
+ \__kernel_backend_literal:n { ps::[end] }
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ { \__kernel_backend_literal:n { ps:gsave } }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ { \__kernel_backend_literal:n { ps:grestore } }
+%% File: l3backend-color.dtx
+\cs_new_protected:Npn \__color_backend_select_cmyk:n #1
+ { \__color_backend_select:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select_gray:n #1
+ { \__color_backend_select:n { gray ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select_named:n #1
+ { \__color_backend_select:n { ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select_rgb:n #1
+ { \__color_backend_select:n { rgb ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ \__kernel_backend_postscript:n { /color.sc ~ { } ~ def }
+ }
+\cs_new_protected:Npn \__color_backend_reset:
+ { \__kernel_backend_literal:n { color~pop } }
+\prop_new:N \g__color_backend_colorant_prop
+\cs_new:Npe \__color_backend_devicen_colorants:n #1
+ {
+ \exp_not:N \tl_if_blank:nF {#1}
+ {
+ \c_space_tl
+ << ~
+ /Colorants ~
+ << ~
+ \exp_not:N \__color_backend_devicen_colorants:w #1 ~
+ \exp_not:N \q_recursion_tail \c_space_tl
+ \exp_not:N \q_recursion_stop
+ >> ~
+ >>
+ }
+ }
+\cs_new:Npn \__color_backend_devicen_colorants:w #1 ~
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \prop_if_in:NnT \g__color_backend_colorant_prop {#1}
+ {
+ #1 ~
+ \prop_item:Nn \g__color_backend_colorant_prop {#1} ~
+ }
+ \__color_backend_devicen_colorants:w
+ }
+\cs_new_protected:Npn \__color_backend_select_separation:nn #1#2
+ { \__color_backend_select:n { separation ~ #1 ~ #2 } }
+\cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
+\cs_new_protected:Npn \__color_backend_select_iccbased:nn #1#2 { }
+\cs_new_protected:Npe \__color_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \bool_if:NT \g__kernel_backend_header_bool
+ {
+ \exp_not:N \exp_args:Ne \__kernel_backend_first_shipout:n
+ {
+ \exp_not:N \__color_backend_separation_init_aux:nnnnnn
+ { \exp_not:N \int_use:N \g__color_model_int }
+ {#1} {#2} {#3} {#4} {#5}
+ }
+ \prop_gput:Nee \exp_not:N \g__color_backend_colorant_prop
+ { / \exp_not:N \str_convert_pdfname:n {#1} }
+ {
+ << ~
+ /setcolorspace ~ {} ~
+ >> ~ begin ~
+ color \exp_not:N \int_use:N \g__color_model_int \c_space_tl
+ end
+ }
+ }
+ }
+\cs_generate_variant:Nn \__color_backend_separation_init:nnnnn { nee }
+\cs_new_protected:Npn \__color_backend_separation_init_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \__kernel_backend_literal:e
+ {
+ !
+ TeXDict ~ begin ~
+ /color #1
+ {
+ [ ~
+ /Separation ~ ( \str_convert_pdfname:n {#2} ) ~
+ [ ~ #3 ~ ] ~
+ {
+ \cs_if_exist_use:cF { __color_backend_separation_init_ #3 :nnn }
+ { \__color_backend_separation_init:nnn }
+ {#4} {#5} {#6}
+ }
+ ] ~ setcolorspace
+ } ~ def ~
+ end
+ }
+ }
+\cs_new:cpn { __color_backend_separation_init_ /DeviceCMYK :nnn } #1#2#3
+ { \__color_backend_separation_init_Device:Nn 4 {#3} }
+\cs_new:cpn { __color_backend_separation_init_ /DeviceGray :nnn } #1#2#3
+ { \__color_backend_separation_init_Device:Nn 1 {#3} }
+\cs_new:cpn { __color_backend_separation_init_ /DeviceRGB :nnn } #1#2#3
+ { \__color_backend_separation_init_Device:Nn 2 {#3} }
+\cs_new:Npn \__color_backend_separation_init_Device:Nn #1#2
+ {
+ #2 ~
+ \prg_replicate:nn {#1}
+ { #1 ~ index ~ mul ~ #1 ~ 1 ~ roll ~ }
+ \int_eval:n { #1 + 1 } ~ -1 ~ roll ~ pop
+ }
+\cs_new:Npn \__color_backend_separation_init:nnn #1#2#3
+ {
+ \exp_args:Ne \__color_backend_separation_init:nnnn
+ { \__color_backend_separation_init_count:n {#2} }
+ {#1} {#2} {#3}
+ }
+\cs_new:Npn \__color_backend_separation_init_count:n #1
+ { \int_eval:n { 0 \__color_backend_separation_init_count:w #1 ~ \s__color_stop } }
+\cs_new:Npn \__color_backend_separation_init_count:w #1 ~ #2 \s__color_stop
+ {
+ +1
+ \tl_if_blank:nF {#2}
+ { \__color_backend_separation_init_count:w #2 \s__color_stop }
+ }
+\cs_new:Npn \__color_backend_separation_init:nnnn #1#2#3#4
+ {
+ \__color_backend_separation_init:w #3 ~ \s__color_stop #4 ~ \s__color_stop
+ \prg_replicate:nn {#1}
+ {
+ pop ~ 1 ~ index ~ neg ~ 1 ~ index ~ add ~
+ \int_eval:n { 3 * #1 } ~ index ~ mul ~
+ 2 ~ index ~ add ~
+ \int_eval:n { 3 * #1 } ~ #1 ~ roll ~
+ }
+ \int_step_function:nnnN {#1} { -1 } { 1 }
+ \__color_backend_separation_init:n
+ \int_eval:n { 4 * #1 + 1 } ~ #1 ~ roll ~
+ \prg_replicate:nn { 3 * #1 + 1 } { pop ~ }
+ \tl_if_blank:nF {#2}
+ { \__color_backend_separation_init:nw {#1} #2 ~ \s__color_stop }
+ }
+\cs_new:Npn \__color_backend_separation_init:w
+ #1 ~ #2 \s__color_stop #3 ~ #4 \s__color_stop
+ {
+ #1 ~ #3 ~ 0 ~
+ \tl_if_blank:nF {#2}
+ { \__color_backend_separation_init:w #2 \s__color_stop #4 \s__color_stop }
+ }
+\cs_new:Npn \__color_backend_separation_init:n #1
+ { \int_eval:n { #1 * 2 } ~ index ~ }
+\cs_new:Npn \__color_backend_separation_init:nw #1#2 ~ #3 ~ #4 \s__color_stop
+ {
+ #2 ~ #3 ~
+ 2 ~ index ~ 2 ~ index ~ lt ~
+ { ~ pop ~ exch ~ pop ~ } ~
+ { ~
+ 2 ~ index ~ 1 ~ index ~ gt ~
+ { ~ exch ~ pop ~ exch ~ pop ~ } ~
+ { ~ pop ~ pop ~ } ~
+ ifelse ~
+ }
+ ifelse ~
+ #1 ~ 1 ~ roll ~
+ \tl_if_blank:nF {#4}
+ { \__color_backend_separation_init:nw {#1} #4 \s__color_stop }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \__color_backend_separation_init:neenn
+ {#2}
+ {
+ /CIEBasedABC ~
+ << ~
+ /RangeABC ~ [ ~ \c__color_model_range_CIELAB_tl \c_space_tl ] ~
+ /DecodeABC ~
+ [ ~
+ { ~ 16 ~ add ~ 116 ~ div ~ } ~ bind ~
+ { ~ 500 ~ div ~ } ~ bind ~
+ { ~ 200 ~ div ~ } ~ bind ~
+ ] ~
+ /MatrixABC ~ [ ~ 1 ~ 1 ~ 1 ~ 1 ~ 0 ~ 0 ~ 0 ~ 0 ~ -1 ~ ] ~
+ /DecodeLMN ~
+ [ ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ 0.9505 ~ mul ~
+ } ~ bind ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ } ~ bind ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ 1.0890 ~ mul ~
+ } ~ bind
+ ] ~
+ /WhitePoint ~
+ [ ~ \tl_use:c { c__color_model_whitepoint_CIELAB_ #1 _tl } ~ ] ~
+ >>
+ }
+ { \c__color_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+\cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
+ {
+ \__kernel_backend_literal:e
+ {
+ !
+ TeXDict ~ begin ~
+ /color \int_use:N \g__color_model_int
+ {
+ [ ~
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ { ~ #3 ~ } ~
+ \__color_backend_devicen_colorants:n {#1}
+ ] ~ setcolorspace
+ } ~ def ~
+ end
+ }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_init:nnn #1#2#3 { }
+\cs_new_protected:Npn \__color_backend_fill_cmyk:n #1
+ { \__color_backend_fill:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \__color_backend_fill_gray:n #1
+ { \__color_backend_fill:n { gray ~ #1 } }
+\cs_new_protected:Npn \__color_backend_fill_rgb:n #1
+ { \__color_backend_fill:n { rgb ~ #1 } }
+\cs_new_protected:Npn \__color_backend_fill:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_cmyk:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setcmykcolor } def } }
+\cs_new_protected:Npn \__color_backend_stroke_gray:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setgray } def } }
+\cs_new_protected:Npn \__color_backend_stroke_rgb:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setrgbcolor } def } }
+\cs_new_protected:Npn \__color_backend_fill_separation:nn #1#2
+ { \__color_backend_fill:n { separation ~ #1 ~ #2 } }
+\cs_new_protected:Npn \__color_backend_stroke_separation:nn #1#2
+ { \__kernel_backend_postscript:n { /color.sc { separation ~ #1 ~ #2 } def } }
+\cs_new_eq:NN \__color_backend_fill_devicen:nn \__color_backend_fill_separation:nn
+\cs_new_eq:NN \__color_backend_stroke_devicen:nn \__color_backend_stroke_separation:nn
+\cs_new_eq:NN \__color_backend_fill_reset: \__color_backend_reset:
+\cs_new_protected:Npn \__color_backend_stroke_reset: { }
+%% File: l3backend-box.dtx
+\cs_new_protected:Npn \__box_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:n { matrix~currentmatrix }
+ \__kernel_backend_literal_postscript:n
+ { Resolution~72~div~VResolution~72~div~scale }
+ \__kernel_backend_literal_postscript:n { DVImag~dup~scale }
+ \__kernel_backend_literal_postscript:e
+ {
+ 0 ~
+ \dim_to_decimal_in_bp:n { \box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { -\box_ht:N #1 - \box_dp:N #1 } ~
+ rectclip
+ }
+ \__kernel_backend_literal_postscript:n { setmatrix }
+ \__kernel_backend_align_end:
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+\cs_new_protected:Npn \__box_backend_rotate:Nn #1#2
+ { \exp_args:NNf \__box_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \__box_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:e
+ {
+ \fp_compare:nNnTF {#2} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -(#2) , 5 ) } } ~
+ rotate
+ }
+ \__kernel_backend_align_end:
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\cs_new_protected:Npn \__box_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:e
+ {
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) } ~
+ scale
+ }
+ \__kernel_backend_align_end:
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+%% File: l3backend-draw.dtx
+\cs_new_eq:NN \__draw_backend_literal:n \__kernel_backend_literal_postscript:n
+\cs_generate_variant:Nn \__draw_backend_literal:n { e }
+\cs_new_protected:Npn \__draw_backend_begin:
+ {
+ \__draw_backend_literal:n { [begin] }
+ \__draw_backend_literal:n { /draw.x~currentpoint~/draw.y~exch~def~def }
+ \__draw_backend_literal:n { @beginspecial }
+ }
+\cs_new_protected:Npn \__draw_backend_end:
+ {
+ \__draw_backend_literal:n { @endspecial }
+ \__draw_backend_literal:n { [end] }
+ }
+\cs_new_protected:Npn \__draw_backend_scope_begin:
+ { \__draw_backend_literal:n { save } }
+\cs_new_protected:Npn \__draw_backend_scope_end:
+ { \__draw_backend_literal:n { restore } }
+\cs_new_protected:Npn \__draw_backend_moveto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~
+ \dim_to_decimal_in_bp:n {#2} ~ moveto
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_lineto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~
+ \dim_to_decimal_in_bp:n {#2} ~ lineto
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_rectangle:nnnn #1#2#3#4
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#4} ~ \dim_to_decimal_in_bp:n {#3} ~
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ moveto~dup~0~rlineto~exch~0~exch~rlineto~neg~0~rlineto~closepath
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ curveto
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_evenodd_rule:
+ { \bool_gset_true:N \g__draw_draw_eor_bool }
+\cs_new_protected:Npn \__draw_backend_nonzero_rule:
+ { \bool_gset_false:N \g__draw_draw_eor_bool }
+\bool_new:N \g__draw_draw_eor_bool
+\cs_new_protected:Npn \__draw_backend_closepath:
+ { \__draw_backend_literal:n { closepath } }
+\cs_new_protected:Npn \__draw_backend_stroke:
+ {
+ \__draw_backend_literal:n { gsave }
+ \__draw_backend_literal:n { color.sc }
+ \__draw_backend_literal:n { stroke }
+ \__draw_backend_literal:n { grestore }
+ \bool_if:NT \g__draw_draw_clip_bool
+ {
+ \__draw_backend_literal:e
+ {
+ \bool_if:NT \g__draw_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \__draw_backend_literal:n { newpath }
+ \bool_gset_false:N \g__draw_draw_clip_bool
+ }
+\cs_new_protected:Npn \__draw_backend_closestroke:
+ {
+ \__draw_backend_closepath:
+ \__draw_backend_stroke:
+ }
+\cs_new_protected:Npn \__draw_backend_fill:
+ {
+ \__draw_backend_literal:e
+ {
+ \bool_if:NT \g__draw_draw_eor_bool { eo }
+ fill
+ }
+ \bool_if:NT \g__draw_draw_clip_bool
+ {
+ \__draw_backend_literal:e
+ {
+ \bool_if:NT \g__draw_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \__draw_backend_literal:n { newpath }
+ \bool_gset_false:N \g__draw_draw_clip_bool
+ }
+\cs_new_protected:Npn \__draw_backend_fillstroke:
+ {
+ \__draw_backend_literal:e
+ {
+ \bool_if:NT \g__draw_draw_eor_bool { eo }
+ fill
+ }
+ \__draw_backend_literal:n { gsave }
+ \__draw_backend_literal:n { color.sc }
+ \__draw_backend_literal:n { stroke }
+ \__draw_backend_literal:n { grestore }
+ \bool_if:NT \g__draw_draw_clip_bool
+ {
+ \__draw_backend_literal:e
+ {
+ \bool_if:NT \g__draw_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \__draw_backend_literal:n { newpath }
+ \bool_gset_false:N \g__draw_draw_clip_bool
+ }
+\cs_new_protected:Npn \__draw_backend_clip:
+ { \bool_gset_true:N \g__draw_draw_clip_bool }
+\bool_new:N \g__draw_draw_clip_bool
+\cs_new_protected:Npn \__draw_backend_discardpath:
+ {
+ \bool_if:NT \g__draw_draw_clip_bool
+ {
+ \__draw_backend_literal:e
+ {
+ \bool_if:NT \g__draw_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \__draw_backend_literal:n { newpath }
+ \bool_gset_false:N \g__draw_draw_clip_bool
+ }
+\cs_new_protected:Npn \__draw_backend_dash_pattern:nn #1#2
+ {
+ \__draw_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \__draw_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ setdash
+ }
+ }
+\cs_new:Npn \__draw_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \__draw_backend_linewidth:n #1
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ setlinewidth }
+ }
+\cs_new_protected:Npn \__draw_backend_miterlimit:n #1
+ { \__draw_backend_literal:n { #1 ~ setmiterlimit } }
+\cs_new_protected:Npn \__draw_backend_cap_butt:
+ { \__draw_backend_literal:n { 0 ~ setlinecap } }
+\cs_new_protected:Npn \__draw_backend_cap_round:
+ { \__draw_backend_literal:n { 1 ~ setlinecap } }
+\cs_new_protected:Npn \__draw_backend_cap_rectangle:
+ { \__draw_backend_literal:n { 2 ~ setlinecap } }
+\cs_new_protected:Npn \__draw_backend_join_miter:
+ { \__draw_backend_literal:n { 0 ~ setlinejoin } }
+\cs_new_protected:Npn \__draw_backend_join_round:
+ { \__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
+ {
+ \__draw_backend_literal:n
+ { [ #1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat }
+ }
+\cs_new_protected:Npn \__draw_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \__draw_backend_literal:n { save }
+ \__draw_backend_literal:n { 72~Resolution~div~72~VResolution~div~neg~scale }
+ \__draw_backend_literal:n { magscale { 1~DVImag~div~dup~scale } if }
+ \__draw_backend_literal:n { draw.x~neg~draw.y~neg~translate }
+ \__draw_backend_literal:n { [end] }
+ \__draw_backend_literal:n { [begin] }
+ \__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_literal:n { neg~exch~neg~exch~translate }
+ \__draw_backend_literal:n { [end] }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__draw_backend_literal:n { [begin] }
+ \__draw_backend_literal:n { restore }
+ \__draw_backend_literal:n { [end] }
+ \__draw_backend_literal:n { [begin] }
+ \__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
+ }
+\cs_new_protected:Npn \__graphics_backend_include_eps:n #1
+ {
+ \__kernel_backend_literal:e
+ {
+ PSfile = #1 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l__graphics_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l__graphics_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l__graphics_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l__graphics_ury_dim
+ }
+ }
+\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 }
+%% 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 }
+\cs_new_protected:Npn \__pdf_backend_catalog_gput:nn #1#2
+ { \__pdf_backend_pdfmark:n { { Catalog } << /#1 ~ #2 >> /PUT } }
+\cs_new_protected:Npn \__pdf_backend_info_gput:nn #1#2
+ { \__pdf_backend_pdfmark:n { /#1 ~ #2 /DOCINFO } }
+\cs_new_protected:Npn \__pdf_backend_object_new:
+ { \int_gincr:N \g__pdf_backend_object_int }
+\cs_new:Npn \__pdf_backend_object_ref:n #1 { { pdf.obj #1 } }
+\cs_new_eq:NN \__pdf_backend_object_id:n \__pdf_backend_object_ref:n
+\cs_new_protected:Npn \__pdf_backend_object_write:nnn #1#2#3
+ {
+ \__pdf_backend_object_write_aux:nnn
+ { \__pdf_backend_object_ref:n {#1} }
+ {#2} {#3}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_write:nnn { nne }
+\cs_new_protected:Npn \__pdf_backend_object_write_aux:nnn #1#2#3
+ {
+ \__pdf_backend_pdfmark:e
+ {
+ /_objdef ~ #1
+ /type
+ \str_case:nn {#2}
+ {
+ { array } { /array }
+ { dict } { /dict }
+ { fstream } { /stream }
+ { stream } { /stream }
+ }
+ /OBJ
+ }
+ \use:c { __pdf_backend_object_write_ #2 :nn } {#1} {#3}
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_array:nn #1#2
+ {
+ \__pdf_backend_pdfmark:e
+ { #1 ~0~ [ ~ \exp_not:n {#2} ~ ] ~ /PUTINTERVAL }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_dict:nn #1#2
+ {
+ \__pdf_backend_pdfmark:e
+ { #1 << \exp_not:n {#2} >> /PUT }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_fstream:nn #1#2
+ {
+ \exp_args:Ne
+ \__pdf_backend_object_write_fstream:nnn {#1} #2
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_fstream:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ SDict ~ begin ~
+ mark ~ #1 ~ << #2 >> /PUT ~ pdfmark ~
+ mark ~ #1 ~ ( #3 )~ ( r )~ file ~ /PUT ~ pdfmark ~
+ end
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_stream:nn #1#2
+ {
+ \exp_args:Ne
+ \__pdf_backend_object_write_stream:nnn {#1} #2
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_stream:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ mark ~ #1 ~ ( #3 ) /PUT ~ pdfmark ~
+ mark ~ #1 ~ << #2 >> /PUT ~ pdfmark
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_now:nn #1#2
+ {
+ \int_gincr:N \g__pdf_backend_object_int
+ \__pdf_backend_object_write_aux:nnn
+ { { pdf.obj \int_use:N \g__pdf_backend_object_int } }
+ {#1} {#2}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_now:nn { ne }
+\cs_new:Npn \__pdf_backend_object_last:
+ { { 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
+ {
+ \exp_args:Nf \__pdf_backend_annotation_aux:nnnn
+ { \dim_eval:n {#1} } {#2} {#3} {#4}
+ }
+\cs_new_protected:Npn \__pdf_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__pdf_backend_object_int
+ \int_gset_eq:NN \g__pdf_backend_annotation_int \g__pdf_backend_object_int
+ \__pdf_backend_pdfmark:e
+ {
+ /_objdef { pdf.obj \int_use:N \g__pdf_backend_object_int }
+ pdf.rect
+ #4 ~
+ /ANN
+ }
+ }
+\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
+ {
+ \__pdf_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
+ {
+ \bool_if:NF \g__pdf_backend_link_bool
+ { \__pdf_backend_link_begin_aux:nw {#1} }
+ }
+\cs_new_protected:Npn \__pdf_backend_link_begin_aux:nw #1
+ {
+ \bool_gset_true:N \g__pdf_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:
+ \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
+ { \c_math_toggle_token }
+ }
+\cs_new_protected:Npn \__pdf_backend_link_end:
+ {
+ \bool_if:NT \g__pdf_backend_link_bool
+ { \__pdf_backend_link_end_aux: }
+ }
+\cs_new_protected:Npn \__pdf_backend_link_end_aux:
+ {
+ \bool_if:NT \g__pdf_backend_link_math_bool
+ { \c_math_toggle_token }
+ \__pdf_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
+ {
+ \int_if_odd:nTF { \value { page } }
+ { \oddsidemargin }
+ { \evensidemargin }
+ }
+ \box_move_down:nn { \box_dp:N \l__pdf_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 }
+ {
+ \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
+ \__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
+ pdf.rect
+ /ANN ~ \l__pdf_breaklink_pdfmark_tl
+ }
+ \__pdf_backend_link_sf_restore:
+ \bool_gset_false:N \g__pdf_backend_link_bool
+ }
+\cs_new_protected:Npn \__pdf_backend_link_minima:
+ {
+ \hbox_set:Nn \l__pdf_backend_model_box { Gg }
+ \__kernel_backend_postscript:e
+ {
+ /pdf.linkdp.pad ~
+ \dim_to_decimal:n
+ {
+ \dim_max:nn
+ {
+ \box_dp:N \l__pdf_backend_model_box
+ - \box_dp:N \l__pdf_backend_content_box
+ }
+ { 0pt }
+ } ~
+ pdf.pt.dvi ~ def
+ /pdf.linkht.pad ~
+ \dim_to_decimal:n
+ {
+ \dim_max:nn
+ {
+ \box_ht:N \l__pdf_backend_model_box
+ - \box_ht:N \l__pdf_backend_content_box
+ }
+ { 0pt }
+ } ~
+ pdf.pt.dvi ~ def
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_link_outerbox:n #1
+ {
+ \__kernel_backend_postscript:e
+ {
+ /pdf.outerbox
+ [
+ \dim_to_decimal:n {#1} ~
+ \dim_to_decimal:n { -\box_dp:N \l__pdf_backend_model_box } ~
+ \dim_to_decimal:n { #1 + \textwidth } ~
+ \dim_to_decimal:n { \box_ht:N \l__pdf_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 \__pdf_backend_link_sf_save:
+ {
+ \int_gset:Nn \g__pdf_backend_link_sf_int
+ {
+ \mode_if_horizontal:TF
+ { \tex_spacefactor:D }
+ { 0 }
+ }
+ }
+\cs_new_protected:Npn \__pdf_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 }
+ }
+ }
+\use_none:n
+ {
+ \cs_if_exist:NT \@makecol@hook
+ {
+ \tl_put_right:Nn \@makecol@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__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
+ }
+ }
+\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
+ {
+ \__kernel_backend_postscript:e
+ {
+ /pdf.linkmargin { \dim_to_decimal:n {#1} ~ pdf.pt.dvi } def
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_destination:nn #1#2
+ {
+ \__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-opacity.dtx
+\cs_new_protected:Npn \__opacity_backend_select:n #1
+ {
+ \__opacity_backend:nnn {#1} { fill } { ca }
+ \__opacity_backend:nnn {#1} { stroke } { CA }
+ }
+\cs_new_protected:Npn \__opacity_backend_fill:n #1
+ {
+ \__opacity_backend:nnn
+ { #1 }
+ { fill }
+ { ca }
+ }
+\cs_new_protected:Npn \__opacity_backend_stroke:n #1
+ {
+ \__opacity_backend:nnn
+ { #1 }
+ { stroke }
+ { CA }
+ }
+\cs_new_protected:Npn \__opacity_backend:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ product ~ (Ghostscript) ~ search
+ {
+ pop ~ pop ~ pop ~
+ #1 ~ .set #2 constantalpha
+ }
+ {
+ pop ~
+ mark ~
+ /#3 ~ #1
+ /SetTransparency ~
+ pdfmark
+ }
+ ifelse
+ }
+ }
+%%
+%%
+%% End of file `l3backend-dvips.def'.
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.pro b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.pro
new file mode 100644
index 00000000000..574b83c8b1a
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvips.pro
@@ -0,0 +1,405 @@
+%%
+%% This is file `l3backend-dvips.pro',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3backend-header.dtx (with options: `header,dvips')
+%%
+%% Copyright (C) 2019-2024 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.
+%%
+%% File: l3backend-header.dtx
+/color.sc { } def
+TeXDict begin
+/TeXcolorseparation { setcolor } def
+end
+true setglobal
+/pdf.globaldict 4 dict def
+false setglobal
+/pdf.cvs { 65534 string cvs } def
+/pdf.dvi.pt { 72.27 mul Resolution div } def
+/pdf.pt.dvi { 72.27 div Resolution mul } def
+/pdf.rect.ht { dup 1 get neg exch 3 get add } def
+/pdf.linkmargin { 1 pdf.pt.dvi } def
+/pdf.linkdp.pad { 0 } def
+/pdf.linkht.pad { 0 } def
+/pdf.rect
+ { /Rect [ pdf.llx pdf.lly pdf.urx pdf.ury ] } def
+/pdf.save.ll
+ {
+ currentpoint
+ /pdf.lly exch def
+ /pdf.llx exch def
+ }
+ def
+/pdf.save.ur
+ {
+ currentpoint
+ /pdf.ury exch def
+ /pdf.urx exch def
+ }
+ def
+/pdf.save.linkll
+ {
+ currentpoint
+ pdf.linkmargin add
+ pdf.linkdp.pad add
+ /pdf.lly exch def
+ pdf.linkmargin sub
+ /pdf.llx exch def
+ }
+ def
+/pdf.save.linkur
+ {
+ currentpoint
+ pdf.linkmargin sub
+ pdf.linkht.pad sub
+ /pdf.ury exch def
+ pdf.linkmargin add
+ /pdf.urx exch def
+ }
+ def
+/pdf.dest.anchor
+ {
+ currentpoint exch
+ pdf.dvi.pt 72 add
+ /pdf.dest.x exch def
+ pdf.dvi.pt
+ vsize 72 sub exch sub
+ /pdf.dest.y exch def
+ }
+ def
+/pdf.dest.point
+ { pdf.dest.x pdf.dest.y } def
+/pdf.dest2device
+ {
+ /pdf.dest.y exch def
+ /pdf.dest.x exch def
+ matrix currentmatrix
+ matrix defaultmatrix
+ matrix invertmatrix
+ matrix concatmatrix
+ cvx exec
+ /pdf.dev.y exch def
+ /pdf.dev.x exch def
+ /pdf.tmpd exch def
+ /pdf.tmpc exch def
+ /pdf.tmpb exch def
+ /pdf.tmpa exch def
+ pdf.dest.x pdf.tmpa mul
+ pdf.dest.y pdf.tmpc mul add
+ pdf.dev.x add
+ pdf.dest.x pdf.tmpb mul
+ pdf.dest.y pdf.tmpd mul add
+ pdf.dev.y add
+ }
+ def
+/pdf.bordertracking false def
+/pdf.bordertracking.begin
+ {
+ SDict /pdf.bordertracking true put
+ SDict /pdf.leftboundary undef
+ SDict /pdf.rightboundary undef
+ /a where
+ {
+ /a
+ {
+ currentpoint pop
+ SDict /pdf.rightboundary known dup
+ {
+ SDict /pdf.rightboundary get 2 index lt
+ { not }
+ if
+ }
+ if
+ { pop }
+ { SDict exch /pdf.rightboundary exch put }
+ ifelse
+ moveto
+ currentpoint pop
+ SDict /pdf.leftboundary known dup
+ {
+ SDict /pdf.leftboundary get 2 index gt
+ { not }
+ if
+ }
+ if
+ { pop }
+ { SDict exch /pdf.leftboundary exch put }
+ ifelse
+ }
+ put
+ }
+ if
+ }
+ def
+/pdf.bordertracking.end
+ {
+ /a where { /a { moveto } put } if
+ /x where { /x { 0 exch rmoveto } put } if
+ SDict /pdf.leftboundary known
+ { pdf.outerbox 0 pdf.leftboundary put }
+ if
+ SDict /pdf.rightboundary known
+ { pdf.outerbox 2 pdf.rightboundary put }
+ if
+ SDict /pdf.bordertracking false put
+ }
+ def
+ /pdf.bordertracking.endpage
+{
+ pdf.bordertracking
+ {
+ pdf.bordertracking.end
+ true setglobal
+ pdf.globaldict
+ /pdf.brokenlink.rect [ pdf.outerbox aload pop ] put
+ pdf.globaldict
+ /pdf.brokenlink.skip pdf.baselineskip put
+ pdf.globaldict
+ /pdf.brokenlink.dict
+ pdf.link.dict pdf.cvs put
+ false setglobal
+ mark pdf.link.dict cvx exec /Rect
+ [
+ pdf.llx
+ pdf.lly
+ pdf.outerbox 2 get pdf.linkmargin add
+ currentpoint exch pop
+ pdf.outerbox pdf.rect.ht sub pdf.linkmargin sub
+ ]
+ /ANN pdf.pdfmark
+ }
+ if
+}
+ def
+/pdf.bordertracking.continue
+ {
+ /pdf.link.dict pdf.globaldict
+ /pdf.brokenlink.dict get def
+ /pdf.outerbox pdf.globaldict
+ /pdf.brokenlink.rect get def
+ /pdf.baselineskip pdf.globaldict
+ /pdf.brokenlink.skip get def
+ pdf.globaldict dup dup
+ /pdf.brokenlink.dict undef
+ /pdf.brokenlink.skip undef
+ /pdf.brokenlink.rect undef
+ currentpoint
+ /pdf.originy exch def
+ /pdf.originx exch def
+ /a where
+ {
+ /a
+ {
+ moveto
+ SDict
+ begin
+ currentpoint pdf.originy ne exch
+ pdf.originx ne or
+ {
+ pdf.save.linkll
+ /pdf.lly
+ pdf.lly pdf.outerbox 1 get sub def
+ pdf.bordertracking.begin
+ }
+ if
+ end
+ }
+ put
+ }
+ if
+ /x where
+ {
+ /x
+ {
+ 0 exch rmoveto
+ SDict
+ begin
+ currentpoint
+ pdf.originy ne exch pdf.originx ne or
+ {
+ pdf.save.linkll
+ /pdf.lly
+ pdf.lly pdf.outerbox 1 get sub def
+ pdf.bordertracking.begin
+ }
+ if
+ end
+ }
+ put
+ }
+ if
+ }
+ def
+/pdf.breaklink
+ {
+ pop
+ counttomark 2 mod 0 eq
+ {
+ counttomark /pdf.count exch def
+ {
+ pdf.count 0 eq { exit } if
+ counttomark 2 roll
+ 1 index /Rect eq
+ {
+ dup 4 array copy
+ dup dup
+ 1 get
+ pdf.outerbox pdf.rect.ht
+ pdf.linkmargin 2 mul add sub
+ 3 exch put
+ dup
+ pdf.outerbox 2 get
+ pdf.linkmargin add
+ 2 exch put
+ dup dup
+ 3 get
+ pdf.outerbox pdf.rect.ht
+ pdf.linkmargin 2 mul add add
+ 1 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ {
+ pdf.currentrect
+ dup
+ pdf.outerbox 0 get
+ pdf.linkmargin sub
+ 0 exch put
+ dup
+ pdf.outerbox 2 get
+ pdf.linkmargin add
+ 2 exch put
+ dup dup
+ 1 get
+ pdf.baselineskip add
+ 1 exch put
+ dup dup
+ 3 get
+ pdf.baselineskip add
+ 3 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ }
+ 1 index 3 get
+ pdf.linkmargin 2 mul add
+ pdf.outerbox pdf.rect.ht add
+ 2 index 1 get sub
+ pdf.baselineskip div round cvi 1 sub
+ exch
+ repeat
+ pdf.currentrect
+ dup
+ pdf.outerbox 0 get
+ pdf.linkmargin sub
+ 0 exch put
+ dup dup
+ 1 get
+ pdf.baselineskip add
+ 1 exch put
+ dup dup
+ 3 get
+ pdf.baselineskip add
+ 3 exch put
+ dup 2 index 2 get 2 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ SDict /pdf.pdfmark.good false put
+ exit
+ }
+ { pdf.count 2 sub /pdf.count exch def }
+ ifelse
+ }
+ loop
+ }
+ if
+ /ANN
+ }
+ def
+/pdf.breaklink.write
+ {
+ counttomark 1 sub
+ index /_objdef eq
+ {
+ counttomark -2 roll
+ dup wcheck
+ {
+ readonly
+ counttomark 2 roll
+ }
+ { pop pop }
+ ifelse
+ }
+ if
+ counttomark 1 add copy
+ pop pdf.currentrect
+ /ANN pdfmark
+ }
+ def
+/pdf.pdfmark
+ {
+ SDict /pdf.pdfmark.good true put
+ dup /ANN eq
+ {
+ pdf.pdfmark.store
+ pdf.pdfmark.dict
+ begin
+ Subtype /Link eq
+ currentdict /Rect known and
+ SDict /pdf.outerbox known and
+ SDict /pdf.baselineskip known and
+ {
+ Rect 3 get
+ pdf.linkmargin 2 mul add
+ pdf.outerbox pdf.rect.ht add
+ Rect 1 get sub
+ pdf.baselineskip div round cvi 0 gt
+ { pdf.breaklink }
+ if
+ }
+ if
+ end
+ SDict /pdf.outerbox undef
+ SDict /pdf.baselineskip undef
+ currentdict /pdf.pdfmark.dict undef
+ }
+ if
+ pdf.pdfmark.good
+ { pdfmark }
+ { cleartomark }
+ ifelse
+ }
+ def
+/pdf.pdfmark.store
+ {
+ /pdf.pdfmark.dict 65534 dict def
+ counttomark 1 add copy
+ pop
+ {
+ dup mark eq
+ {
+ pop
+ exit
+ }
+ {
+ pdf.pdfmark.dict
+ begin def end
+ }
+ ifelse
+ }
+ loop
+}
+ def
+%%
+%%
+%% End of file `l3backend-dvips.pro'.
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvisvgm.def b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvisvgm.def
new file mode 100644
index 00000000000..e1483003cc7
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-dvisvgm.def
@@ -0,0 +1,672 @@
+%%
+%% This is file `l3backend-dvisvgm.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3backend-basics.dtx (with options: `package,dvisvgm')
+%% l3backend-color.dtx (with options: `package,dvisvgm')
+%% l3backend-box.dtx (with options: `package,dvisvgm')
+%% l3backend-draw.dtx (with options: `package,dvisvgm')
+%% l3backend-graphics.dtx (with options: `package,dvisvgm')
+%% l3backend-pdf.dtx (with options: `package,dvisvgm')
+%% l3backend-opacity.dtx (with options: `package,dvisvgm')
+%%
+%% Copyright (C) 2019-2024 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.
+%%
+%% File: l3backend-basics.dtx
+\ProvidesExplFile
+ {l3backend-dvisvgm.def}{2024-04-11}{}
+ {L3 backend support: dvisvgm}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+ {l3backend-dvisvgm.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+\cs_new_protected:Npn \__kernel_backend_literal_svg:n #1
+ { \__kernel_backend_literal:n { dvisvgm:raw~ #1 { ?nl } } }
+\cs_generate_variant:Nn \__kernel_backend_literal_svg:n { e }
+\int_new:N \g__kernel_backend_scope_int
+\int_new:N \l__kernel_backend_scope_int
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ {
+ \__kernel_backend_literal_svg:n { <g> }
+ \int_set_eq:NN
+ \l__kernel_backend_scope_int
+ \g__kernel_backend_scope_int
+ \group_begin:
+ \int_gset:Nn \g__kernel_backend_scope_int { 1 }
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ {
+ \prg_replicate:nn
+ { \g__kernel_backend_scope_int }
+ { \__kernel_backend_literal_svg:n { </g> } }
+ \group_end:
+ \int_gset_eq:NN
+ \g__kernel_backend_scope_int
+ \l__kernel_backend_scope_int
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:n #1
+ {
+ \__kernel_backend_literal_svg:n { <g ~ #1 > }
+ \int_set_eq:NN
+ \l__kernel_backend_scope_int
+ \g__kernel_backend_scope_int
+ \group_begin:
+ \int_gset:Nn \g__kernel_backend_scope_int { 1 }
+ }
+\cs_generate_variant:Nn \__kernel_backend_scope_begin:n { e }
+\cs_new_protected:Npn \__kernel_backend_scope:n #1
+ {
+ \__kernel_backend_literal_svg:n { <g ~ #1 > }
+ \int_gincr:N \g__kernel_backend_scope_int
+ }
+\cs_generate_variant:Nn \__kernel_backend_scope:n { e }
+%% File: l3backend-color.dtx
+\cs_new_protected:Npn \__color_backend_select_cmyk:n #1
+ { \__color_backend_select:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select_gray:n #1
+ { \__color_backend_select:n { gray ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select_named:n #1
+ { \__color_backend_select:n { ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select_rgb:n #1
+ { \__color_backend_select:n { rgb ~ #1 } }
+\cs_new_protected:Npn \__color_backend_select:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ }
+\cs_new_protected:Npn \__color_backend_reset:
+ { \__kernel_backend_literal:n { color~pop } }
+\cs_new_protected:Npn \__color_backend_select_separation:nn #1#2 { }
+\cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
+\cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { }
+\cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnnnnn #1#2#3 { }
+\cs_new_protected:Npn \__color_backend_select_iccbased:nn #1#2
+ {
+ \__kernel_backend_literal_svg:e
+ {
+ <style>
+ @color-profile ~
+ \str_if_eq:nnTF {#2} { cmyk }
+ { device-cmyk }
+ { --color \int_use:N \g__color_model_int }
+ \c_space_tl
+ {
+ src:("#1")
+ }
+ </style>
+ }
+ }
+\cs_new_protected:Npn \__color_backend_fill_cmyk:n #1
+ { \__color_backend_fill:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \__color_backend_fill_gray:n #1
+ { \__color_backend_fill:n { gray ~ #1 } }
+\cs_new_protected:Npn \__color_backend_fill_rgb:n #1
+ { \__color_backend_fill:n { rgb ~ #1 } }
+\cs_new_protected:Npn \__color_backend_fill:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_cmyk:n #1
+ { \__color_backend_cmyk:w #1 \s__color_stop }
+\cs_new_protected:Npn \__color_backend_stroke_cmyk:w
+ #1 ~ #2 ~ #3 ~ #4 \s__color_stop
+ {
+ \use:e
+ {
+ \__color_backend:nnn
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #1 + #4 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #2 + #4 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #3 + #4 ) ) } }
+ }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_gray:n #1
+ {
+ \use:e
+ {
+ \__color_backend_stroke_gray_aux:n
+ { \fp_eval:n { 100 * (#1) } }
+ }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_gray_aux:n #1
+ { \__color_backend:nnn {#1} {#1} {#1} }
+\cs_new_protected:Npn \__color_backend_stroke_rgb:n #1
+ { \__color_backend_rgb:w #1 \s__color_stop }
+\cs_new_protected:Npn \__color_backend_stroke_rgb:w
+ #1 ~ #2 ~ #3 \s__color_stop
+ {
+ \use:e
+ {
+ \__color_backend:nnn
+ { \fp_eval:n { 100 * (#1) } }
+ { \fp_eval:n { 100 * (#2) } }
+ { \fp_eval:n { 100 * (#3) } }
+ }
+ }
+\cs_new_protected:Npe \__color_backend:nnn #1#2#3
+ {
+ \__kernel_backend_scope:n
+ {
+ stroke =
+ "
+ rgb
+ (
+ #1 \c_percent_str ,
+ #2 \c_percent_str ,
+ #3 \c_percent_str
+ )
+ "
+ }
+ }
+\cs_new_protected:Npn \__color_backend_fill_separation:nn #1#2 { }
+\cs_new_protected:Npn \__color_backend_stroke_separation:nn #1#2 { }
+\cs_new_eq:NN \__color_backend_fill_devicen:nn \__color_backend_fill_separation:nn
+\cs_new_eq:NN \__color_backend_stroke_devicen:nn \__color_backend_stroke_separation:nn
+\cs_new_eq:NN \__color_backend_fill_reset: \__color_backend_reset:
+\cs_new_protected:Npn \__color_backend_stroke_reset: { }
+\cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { }
+\cs_new_protected:Npn \__color_backend_iccbased_init:nnn #1#2#3 { }
+%% File: l3backend-box.dtx
+\cs_new_protected:Npn \__box_backend_clip:N #1
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \__kernel_backend_literal_svg:e
+ { < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " > }
+ \__kernel_backend_literal_svg:e
+ {
+ <
+ path ~ d =
+ "
+ M ~ 0 ~
+ \dim_to_decimal:n { -\box_dp:N #1 } ~
+ L ~ \dim_to_decimal:n { \box_wd:N #1 } ~
+ \dim_to_decimal:n { -\box_dp:N #1 } ~
+ L ~ \dim_to_decimal:n { \box_wd:N #1 } ~
+ \dim_to_decimal:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ L ~ 0 ~
+ \dim_to_decimal:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ Z
+ "
+ />
+ }
+ \__kernel_backend_literal_svg:n
+ { < /clipPath > }
+ \__kernel_backend_scope_begin:n
+ {
+ transform =
+ "
+ translate ( { ?x } , { ?y } ) ~
+ scale ( 1 , -1 )
+ "
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url ( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int ) "
+ }
+ \__kernel_backend_scope:n
+ {
+ transform =
+ "
+ scale ( -1 , 1 ) ~
+ translate ( { ?x } , { ?y } ) ~
+ scale ( -1 , -1 )
+ "
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\int_new:N \g__kernel_clip_path_int
+\cs_new_protected:Npn \__box_backend_rotate:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:e
+ {
+ transform =
+ "
+ rotate
+ ( \fp_eval:n { round ( -(#2) , 5 ) } , ~ { ?x } , ~ { ?y } )
+ "
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\cs_new_protected:Npn \__box_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:e
+ {
+ transform =
+ "
+ translate ( { ?x } , { ?y } ) ~
+ scale
+ (
+ \fp_eval:n { round ( -#2 , 5 ) } ,
+ \fp_eval:n { round ( -#3 , 5 ) }
+ ) ~
+ translate ( { ?x } , { ?y } ) ~
+ scale ( -1 )
+ "
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+%% File: l3backend-draw.dtx
+\cs_new_eq:NN \__draw_backend_literal:n \__kernel_backend_literal_svg:n
+\cs_generate_variant:Nn \__draw_backend_literal:n { e }
+\cs_new_eq:NN \__draw_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \__draw_backend_scope_end: \__kernel_backend_scope_end:
+\cs_new_protected:Npn \__draw_backend_begin:
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_scope:n { transform="translate({?x},{?y})~scale(1,-1)" }
+ }
+\cs_new_eq:NN \__draw_backend_end: \__kernel_backend_scope_end:
+\cs_new_protected:Npn \__draw_backend_moveto:nn #1#2
+ {
+ \__draw_backend_add_to_path:n
+ { M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \__draw_backend_lineto:nn #1#2
+ {
+ \__draw_backend_add_to_path:n
+ { L ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \__draw_backend_rectangle:nnnn #1#2#3#4
+ {
+ \__draw_backend_add_to_path:n
+ {
+ M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2}
+ h ~ \dim_to_decimal:n {#3} ~
+ v ~ \dim_to_decimal:n {#4} ~
+ h ~ \dim_to_decimal:n { -#3 } ~
+ Z
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \__draw_backend_add_to_path:n
+ {
+ C ~
+ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} ~
+ \dim_to_decimal:n {#3} ~ \dim_to_decimal:n {#4} ~
+ \dim_to_decimal:n {#5} ~ \dim_to_decimal:n {#6}
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_add_to_path:n #1
+ {
+ \tl_gset:Ne \g__draw_backend_path_tl
+ {
+ \g__draw_backend_path_tl
+ \tl_if_empty:NF \g__draw_backend_path_tl { \c_space_tl }
+ #1
+ }
+ }
+\tl_new:N \g__draw_backend_path_tl
+\cs_new_protected:Npn \__draw_backend_evenodd_rule:
+ { \__kernel_backend_scope:n { fill-rule="evenodd" } }
+\cs_new_protected:Npn \__draw_backend_nonzero_rule:
+ { \__kernel_backend_scope:n { fill-rule="nonzero" } }
+\cs_new_protected:Npn \__draw_backend_closepath:
+ { \__draw_backend_add_to_path:n { Z } }
+\cs_new_protected:Npn \__draw_backend_path:n #1
+ {
+ \bool_if:NTF \g__draw_draw_clip_bool
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \__draw_backend_literal:e
+ {
+ < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
+ { ?nl }
+ <path~d=" \g__draw_backend_path_tl "/> { ?nl }
+ < /clipPath > { ? nl }
+ <
+ use~xlink:href =
+ "\c_hash_str l3path \int_use:N \g__draw_backend_path_int " ~
+ #1
+ />
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
+ }
+ }
+ {
+ \__draw_backend_literal:e
+ { <path ~ d=" \g__draw_backend_path_tl " ~ #1 /> }
+ }
+ \tl_gclear:N \g__draw_backend_path_tl
+ \bool_gset_false:N \g__draw_draw_clip_bool
+ }
+\int_new:N \g__draw_backend_path_int
+\cs_new_protected:Npn \__draw_backend_stroke:
+ { \__draw_backend_path:n { style="fill:none" } }
+\cs_new_protected:Npn \__draw_backend_closestroke:
+ {
+ \__draw_backend_closepath:
+ \__draw_backend_stroke:
+ }
+\cs_new_protected:Npn \__draw_backend_fill:
+ { \__draw_backend_path:n { style="stroke:none" } }
+\cs_new_protected:Npn \__draw_backend_fillstroke:
+ { \__draw_backend_path:n { } }
+\cs_new_protected:Npn \__draw_backend_clip:
+ { \bool_gset_true:N \g__draw_draw_clip_bool }
+\bool_new:N \g__draw_draw_clip_bool
+\cs_new_protected:Npn \__draw_backend_discardpath:
+ {
+ \bool_if:NT \g__draw_draw_clip_bool
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \__draw_backend_literal:e
+ {
+ < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
+ { ?nl }
+ <path~d=" \g__draw_backend_path_tl "/> { ?nl }
+ < /clipPath >
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
+ }
+ }
+ \tl_gclear:N \g__draw_backend_path_tl
+ \bool_gset_false:N \g__draw_draw_clip_bool
+ }
+\cs_new_protected:Npn \__draw_backend_dash_pattern:nn #1#2
+ {
+ \use:e
+ {
+ \__draw_backend_dash_aux:nn
+ { \clist_map_function:nN {#1} \__draw_backend_dash:n }
+ { \dim_to_decimal:n {#2} }
+ }
+ }
+\cs_new:Npn \__draw_backend_dash:n #1
+ { , \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \__draw_backend_dash_aux:nn #1#2
+ {
+ \__kernel_backend_scope:e
+ {
+ stroke-dasharray =
+ "
+ \tl_if_empty:nTF {#1}
+ { none }
+ { \use_none:n #1 }
+ " ~
+ stroke-offset=" #2 "
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_linewidth:n #1
+ { \__kernel_backend_scope:e { stroke-width=" \dim_to_decimal:n {#1} " } }
+\cs_new_protected:Npn \__draw_backend_miterlimit:n #1
+ { \__kernel_backend_scope:e { stroke-miterlimit=" #1 " } }
+\cs_new_protected:Npn \__draw_backend_cap_butt:
+ { \__kernel_backend_scope:n { stroke-linecap="butt" } }
+\cs_new_protected:Npn \__draw_backend_cap_round:
+ { \__kernel_backend_scope:n { stroke-linecap="round" } }
+\cs_new_protected:Npn \__draw_backend_cap_rectangle:
+ { \__kernel_backend_scope:n { stroke-linecap="square" } }
+\cs_new_protected:Npn \__draw_backend_join_miter:
+ { \__kernel_backend_scope:n { stroke-linejoin="miter" } }
+\cs_new_protected:Npn \__draw_backend_join_round:
+ { \__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
+ {
+ \__kernel_backend_scope:n
+ {
+ transform =
+ " matrix ( #1 , #2 , #3 , #4 , 0pt , 0pt ) "
+ }
+ }
+\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_literal_svg:n
+ {
+ < g~
+ stroke="none"~
+ transform="scale(-1,1)~translate({?x},{?y})~scale(-1,-1)"
+ >
+ }
+ \box_set_wd:Nn #1 { 0pt }
+ \box_set_ht:Nn #1 { 0pt }
+ \box_set_dp:Nn #1 { 0pt }
+ \box_use:N #1
+ \__kernel_backend_literal_svg:n { </g> }
+ \__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 }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_svg:n #1
+ {
+ \__graphics_bb_restore:nF {#1}
+ {
+ \ior_open:Nn \l__graphics_internal_ior {#1}
+ \ior_if_eof:NTF \l__graphics_internal_ior
+ { \msg_error:nnn { graphics } { graphic-not-found } {#1} }
+ {
+ \dim_zero:N \l__graphics_llx_dim
+ \dim_zero:N \l__graphics_lly_dim
+ \dim_set:Nn \l__graphics_urx_dim { -\c_max_dim }
+ \dim_set:Nn \l__graphics_ury_dim { -\c_max_dim }
+ \ior_str_map_inline:Nn \l__graphics_internal_ior
+ {
+ \dim_compare:nNnT \l__graphics_urx_dim = { -\c_max_dim }
+ {
+ \__graphics_backend_getbb_svg_auxi:nNn
+ { width } \l__graphics_urx_dim {##1}
+ }
+ \dim_compare:nNnT \l__graphics_ury_dim = { -\c_max_dim }
+ {
+ \__graphics_backend_getbb_svg_auxi:nNn
+ { height } \l__graphics_ury_dim {##1}
+ }
+ \bool_lazy_and:nnF
+ { \dim_compare_p:nNn \l__graphics_urx_dim = { -\c_max_dim } }
+ { \dim_compare_p:nNn \l__graphics_ury_dim = { -\c_max_dim } }
+ { \ior_map_break: }
+ }
+ \__graphics_bb_save:n {#1}
+ }
+ \ior_close:N \l__graphics_internal_ior
+ }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_svg_auxi:nNn #1#2#3
+ {
+ \use:e
+ {
+ \cs_set_protected:Npn \__graphics_backend_getbb_svg_auxii:w
+ ##1 \tl_to_str:n {#1} = ##2 \tl_to_str:n {#1} = ##3
+ \s__graphics_stop
+ }
+ {
+ \tl_if_blank:nF {##2}
+ {
+ \peek_remove_spaces:n
+ {
+ \peek_meaning:NTF ' % '
+ { \__graphics_backend_getbb_svg_auxiii:Nw #2 }
+ {
+ \peek_meaning:NTF " % "
+ { \__graphics_backend_getbb_svg_auxiv:Nw #2 }
+ { \__graphics_backend_getbb_svg_auxv:Nw #2 }
+ }
+ }
+ ##2 \s__graphics_stop
+ }
+ }
+ \use:e
+ {
+ \__graphics_backend_getbb_svg_auxii:w #3
+ \tl_to_str:n {#1} = \tl_to_str:n {#1} =
+ \s__graphics_stop
+ }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_svg_auxii:w { }
+\cs_new_protected:Npn \__graphics_backend_getbb_svg_auxiii:Nw #1 ' #2 ' #3 \s__graphics_stop
+ { \__graphics_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \__graphics_backend_getbb_svg_auxiv:Nw #1 " #2 " #3 \s__graphics_stop
+ { \__graphics_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \__graphics_backend_getbb_svg_auxv:Nw #1 #2 ~ #3 \s__graphics_stop
+ { \__graphics_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \__graphics_backend_getbb_svg_auxvi:Nn #1#2
+ {
+ \tex_afterassignment:D \__graphics_backend_getbb_svg_auxvii:w
+ \l__graphics_internal_dim #2 bp \scan_stop:
+ \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_protected:Npn \__graphics_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l__graphics_page_int
+ \tl_clear:N \l__graphics_pagebox_tl
+ \__graphics_extract_bb:n {#1}
+ }
+\cs_new_eq:NN \__graphics_backend_getbb_jpeg:n \__graphics_backend_getbb_jpg:n
+\cs_new_eq:NN \__graphics_backend_getbb_png:n \__graphics_backend_getbb_jpg:n
+\cs_new_protected:Npn \__graphics_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l__graphics_decodearray_str
+ \bool_set_false:N \l__graphics_interpolate_bool
+ \__graphics_extract_bb:n {#1}
+ }
+\cs_new_protected:Npn \__graphics_backend_include_eps:n #1
+ { \__graphics_backend_include:nn { PSfile } {#1} }
+\cs_new_eq:NN \__graphics_backend_include_ps:n \__graphics_backend_include_eps:n
+\cs_new_protected:Npn \__graphics_backend_include_pdf:n #1
+ { \__graphics_backend_include:nn { pdffile } {#1} }
+\cs_new_protected:Npn \__graphics_backend_include:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ {
+ #1 = #2 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l__graphics_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l__graphics_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l__graphics_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l__graphics_ury_dim
+ }
+ }
+\cs_new_protected:Npn \__graphics_backend_include_svg:n #1
+ {
+ \box_move_up:nn { \l__graphics_ury_dim }
+ {
+ \hbox:n
+ {
+ \__kernel_backend_literal:e
+ {
+ dvisvgm:img~
+ \dim_to_decimal:n { \l__graphics_urx_dim } ~
+ \dim_to_decimal:n { \l__graphics_ury_dim } ~
+ \__graphics_backend_include_dequote:w #1 " #1 " \s__graphics_stop
+ }
+ }
+ }
+ }
+\cs_new_eq:NN \__graphics_backend_include_png:n \__graphics_backend_include_svg:n
+\cs_new_eq:NN \__graphics_backend_include_jpeg:n \__graphics_backend_include_svg:n
+\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 }
+%% 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 { }
+\cs_new_protected:Npn \__pdf_backend_info_gput:nn #1#2 { }
+\cs_new_protected:Npn \__pdf_backend_object_new: { }
+\cs_new:Npn \__pdf_backend_object_ref:n #1 { }
+\cs_new:Npn \__pdf_backend_object_id:n #1 { }
+\cs_new_protected:Npn \__pdf_backend_object_write:nnn #1#2#3 { }
+\cs_new_protected:Npn \__pdf_backend_object_write:nne #1#2#3 { }
+\cs_new_protected:Npn \__pdf_backend_object_now:nn #1#2 { }
+\cs_new_protected:Npn \__pdf_backend_object_now:ne #1#2 { }
+\cs_new:Npn \__pdf_backend_object_last: { }
+\cs_new:Npn \__pdf_backend_pageobject_ref:n #1 { }
+\cs_new_protected:Npn \__pdf_backend_compresslevel:n #1 { }
+\cs_new_protected:Npn \__pdf_backend_compress_objects:n #1 { }
+\cs_new_protected:Npn \__pdf_backend_version_major_gset:n #1 { }
+\cs_new_protected:Npn \__pdf_backend_version_minor_gset: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 { }
+\cs_new_protected:Npn \__pdf_backend_emc: { }
+\cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2 { }
+%% File: l3backend-opacity.dtx
+\cs_new_protected:Npn \__opacity_backend_select:n #1
+ { \__opacity_backend:nn {#1} { } }
+\cs_new_protected:Npn \__opacity_backend_fill:n #1
+ { \__opacity_backend:nn {#1} { fill- } }
+\cs_new_protected:Npn \__opacity_backend_stroke:n #1
+ { \__opacity_backend:nn {#1} { stroke- } }
+\cs_new_protected:Npn \__opacity_backend:nn #1#2
+ { \__kernel_backend_scope:e { #2 opacity = " #1 " } }
+%%
+%%
+%% End of file `l3backend-dvisvgm.def'.
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.def b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.def
new file mode 100644
index 00000000000..cdd871cceda
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.def
@@ -0,0 +1,903 @@
+%%
+%% This is file `l3backend-luatex.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3backend-basics.dtx (with options: `package,luatex')
+%% l3backend-color.dtx (with options: `package,luatex')
+%% l3backend-box.dtx (with options: `package,luatex')
+%% l3backend-draw.dtx (with options: `package,luatex')
+%% l3backend-graphics.dtx (with options: `package,luatex')
+%% l3backend-pdf.dtx (with options: `package,luatex')
+%% l3backend-opacity.dtx (with options: `package,luatex')
+%%
+%% Copyright (C) 2019-2024 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.
+%%
+%% File: l3backend-basics.dtx
+\ProvidesExplFile
+ {l3backend-luatex.def}{2024-04-11}{}
+ {L3 backend support: PDF output (LuaTeX)}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+ {l3backend-luatex.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ {
+ \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_page:n #1
+ {
+ \tex_pdfextension:D literal ~
+ page { \exp_not:n {#1} }
+ }
+\cs_new_protected:Npn \__kernel_backend_literal_page:e #1
+ {
+ \tex_pdfextension:D literal ~
+ page {#1}
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ {
+ \tex_pdfextension:D save \scan_stop:
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ {
+ \tex_pdfextension:D restore \scan_stop:
+ }
+\cs_new_protected:Npn \__kernel_backend_matrix:n #1
+ {
+ \tex_pdfextension:D setmatrix
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \__kernel_backend_matrix:n { e }
+%% 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
+ {
+ \int_const:Nn #1
+ {
+ \tex_pdffeedback:D colorstackinit ~
+ \tl_if_blank:nF {#2} { #2 ~ }
+ {#3}
+ }
+ }
+\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
+ {
+ \tex_pdfextension:D colorstack ~
+ \int_eval:n {#1} ~ push ~ {#2}
+ }
+\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
+ {
+ \tex_pdfextension:D colorstack ~
+ \int_eval:n {#1} ~ pop \scan_stop:
+ }
+\tl_new:N \l__color_backend_fill_tl
+\tl_new:N \l__color_backend_stroke_tl
+\tl_set:Nn \l__color_backend_fill_tl { 0 ~ g }
+\tl_set:Nn \l__color_backend_stroke_tl { 0 ~ G }
+\cs_new_protected:Npn \__color_backend_select_cmyk:n #1
+ { \__color_backend_select:nn { #1 ~ k } { #1 ~ K } }
+\cs_new_protected:Npn \__color_backend_select_gray:n #1
+ { \__color_backend_select:nn { #1 ~ g } { #1 ~ G } }
+\cs_new_protected:Npn \__color_backend_select_rgb:n #1
+ { \__color_backend_select:nn { #1 ~ rg } { #1 ~ RG } }
+\cs_new_protected:Npn \__color_backend_select:nn #1#2
+ {
+ \tl_set:Nn \l__color_backend_fill_tl {#1}
+ \tl_set:Nn \l__color_backend_stroke_tl {#2}
+ \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
+ }
+\cs_new_protected:Npn \__color_backend_reset:
+ { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int }
+\prop_new:N \g__color_backend_colorant_prop
+\cs_new:Npe \__color_backend_devicen_colorants:n #1
+ {
+ \exp_not:N \tl_if_blank:nF {#1}
+ {
+ \c_space_tl
+ << ~
+ /Colorants ~
+ << ~
+ \exp_not:N \__color_backend_devicen_colorants:w #1 ~
+ \exp_not:N \q_recursion_tail \c_space_tl
+ \exp_not:N \q_recursion_stop
+ >> ~
+ >>
+ }
+ }
+\cs_new:Npn \__color_backend_devicen_colorants:w #1 ~
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \prop_if_in:NnT \g__color_backend_colorant_prop {#1}
+ {
+ #1 ~
+ \prop_item:Nn \g__color_backend_colorant_prop {#1} ~
+ }
+ \__color_backend_devicen_colorants:w
+ }
+\cs_new_protected:Npn \__color_backend_select_separation:nn #1#2
+ { \__color_backend_select:nn { /#1 ~ cs ~ #2 ~ scn } { /#1 ~ CS ~ #2 ~ SCN } }
+\cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
+\cs_new_eq:NN \__color_backend_select_iccbased:nn \__color_backend_select_separation:nn
+\cs_new_protected:Npn \__color_backend_init_resource:n #1
+ {
+ \bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \use:e
+ {
+ \pdfmanagement_add:nnn
+ { Page / Resources / ColorSpace }
+ { #1 }
+ { \pdf_object_ref_last: }
+ }
+ }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \pdf_object_unnamed_write:ne { dict }
+ {
+ /FunctionType ~ 2
+ /Domain ~ [0 ~ 1]
+ \tl_if_blank:nF {#3} { /Range ~ [#3] }
+ /C0 ~ [#4] ~
+ /C1 ~ [#5] /N ~ 1
+ }
+ \exp_args:Ne \__color_backend_separation_init:nn
+ { \str_convert_pdfname:n {#1} } {#2}
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nn #1#2
+ {
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ { /Separation /#1 ~ #2 ~ \pdf_object_ref_last: }
+ }
+ \prop_gput:Nne \g__color_backend_colorant_prop { /#1 }
+ { \pdf_object_ref_last: }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_illuminant_CIELAB_ #1 }
+ {
+ \pdf_object_new:n { __color_illuminant_CIELAB_ #1 }
+ \pdf_object_write:nne { __color_illuminant_CIELAB_ #1 } { array }
+ {
+ /Lab ~
+ <<
+ /WhitePoint ~
+ [ \tl_use:c { c__color_model_whitepoint_CIELAB_ #1 _tl } ]
+ /Range ~ [ \c__color_model_range_CIELAB_tl ]
+ >>
+ }
+ }
+ \__color_backend_separation_init:nnnnn
+ {#2}
+ { \pdf_object_ref:n { __color_illuminant_CIELAB_ #1 } }
+ { \c__color_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+\cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
+ {
+ \pdf_object_unnamed_write:ne { stream }
+ {
+ {
+ /FunctionType ~ 4 ~
+ /Domain ~
+ [ ~
+ \prg_replicate:nn
+ { 0 \__color_backend_devicen_init:w #1 ~ \s__color_stop }
+ { 0 ~ 1 ~ }
+ ] ~
+ /Range ~
+ [ ~
+ \str_case:nn {#2}
+ {
+ { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ { /DeviceGray } { 0 ~ 1 }
+ { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ } ~
+ ]
+ }
+ { {#3} }
+ }
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ {
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ \pdf_object_ref_last:
+ \__color_backend_devicen_colorants:n {#1}
+ }
+ }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
+ {
+ + 1
+ \tl_if_blank:nF {#2}
+ { \__color_backend_devicen_init:w #2 \s__color_stop }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_init:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nne { __color_icc_ #1 } { fstream }
+ {
+ {
+ /N ~ \exp_not:n { #2 } ~
+ \tl_if_empty:nF { #3 } { /Range~[ #3 ] }
+ }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_device:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nnn { __color_icc_ #1 } { fstream }
+ {
+ { /N ~ #3 }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { Default #2 }
+ }
+\cs_new_protected:Npn \__color_backend_fill_cmyk:n #1
+ { \__color_backend_fill:n { #1 ~ k } }
+\cs_new_protected:Npn \__color_backend_fill_gray:n #1
+ { \__color_backend_fill:n { #1 ~ g } }
+\cs_new_protected:Npn \__color_backend_fill_rgb:n #1
+ { \__color_backend_fill:n { #1 ~ rg } }
+\cs_new_protected:Npn \__color_backend_fill:n #1
+ {
+ \tl_set:Nn \l__color_backend_fill_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
+ { #1 ~ \l__color_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_cmyk:n #1
+ { \__color_backend_stroke:n { #1 ~ K } }
+\cs_new_protected:Npn \__color_backend_stroke_gray:n #1
+ { \__color_backend_stroke:n { #1 ~ G } }
+\cs_new_protected:Npn \__color_backend_stroke_rgb:n #1
+ { \__color_backend_stroke:n { #1 ~ RG } }
+\cs_new_protected:Npn \__color_backend_stroke:n #1
+ {
+ \tl_set:Nn \l__color_backend_stroke_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
+ { \l__color_backend_fill_tl \c_space_tl #1 }
+ }
+\cs_new_protected:Npn \__color_backend_fill_separation:nn #1#2
+ { \__color_backend_fill:n { /#1 ~ cs ~ #2 ~ scn } }
+\cs_new_protected:Npn \__color_backend_stroke_separation:nn #1#2
+ { \__color_backend_stroke:n { /#1 ~ CS ~ #2 ~ SCN } }
+\cs_new_eq:NN \__color_backend_fill_devicen:nn \__color_backend_fill_separation:nn
+\cs_new_eq:NN \__color_backend_stroke_devicen:nn \__color_backend_stroke_separation:nn
+\cs_new_eq:NN \__color_backend_fill_reset: \__color_backend_reset:
+\cs_new_eq:NN \__color_backend_stroke_reset: \__color_backend_reset:
+\lua_load_module:n {l3backend-luatex}
+%% File: l3backend-box.dtx
+\cs_new_protected:Npn \__box_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+\cs_new_protected:Npn \__box_backend_rotate:Nn #1#2
+ { \exp_args:NNf \__box_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \__box_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \box_set_wd:Nn #1 { 0pt }
+ \fp_set:Nn \l__box_backend_cos_fp { round ( cosd ( #2 ) , 5 ) }
+ \fp_compare:nNnT \l__box_backend_cos_fp = \c_zero_fp
+ { \fp_zero:N \l__box_backend_cos_fp }
+ \fp_set:Nn \l__box_backend_sin_fp { round ( sind ( #2 ) , 5 ) }
+ \__kernel_backend_matrix:e
+ {
+ \fp_use:N \l__box_backend_cos_fp \c_space_tl
+ \fp_compare:nNnTF \l__box_backend_sin_fp = \c_zero_fp
+ { 0~0 }
+ {
+ \fp_use:N \l__box_backend_sin_fp
+ \c_space_tl
+ \fp_eval:n { -\l__box_backend_sin_fp }
+ }
+ \c_space_tl
+ \fp_use:N \l__box_backend_cos_fp
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\fp_new:N \l__box_backend_cos_fp
+\fp_new:N \l__box_backend_sin_fp
+\cs_new_protected:Npn \__box_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_matrix:e
+ {
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ 0~0~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+%% 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_protected:Npn \__draw_backend_begin:
+ { \__draw_backend_scope_begin: }
+\cs_new_protected:Npn \__draw_backend_end:
+ { \__draw_backend_scope_end: }
+\cs_new_eq:NN \__draw_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \__draw_backend_scope_end: \__kernel_backend_scope_end:
+\cs_new_protected:Npn \__draw_backend_moveto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
+ }
+\cs_new_protected:Npn \__draw_backend_lineto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
+ }
+\cs_new_protected:Npn \__draw_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ c
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_rectangle:nnnn #1#2#3#4
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ re
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_evenodd_rule:
+ { \bool_gset_true:N \g__draw_draw_eor_bool }
+\cs_new_protected:Npn \__draw_backend_nonzero_rule:
+ { \bool_gset_false:N \g__draw_draw_eor_bool }
+\bool_new:N \g__draw_draw_eor_bool
+\cs_new_protected:Npn \__draw_backend_closepath:
+ { \__draw_backend_literal:n { h } }
+\cs_new_protected:Npn \__draw_backend_stroke:
+ { \__draw_backend_literal:n { S } }
+\cs_new_protected:Npn \__draw_backend_closestroke:
+ { \__draw_backend_literal:n { s } }
+\cs_new_protected:Npn \__draw_backend_fill:
+ {
+ \__draw_backend_literal:e
+ { f \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_fillstroke:
+ {
+ \__draw_backend_literal:e
+ { B \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_clip:
+ {
+ \__draw_backend_literal:e
+ { W \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_discardpath:
+ { \__draw_backend_literal:n { n } }
+\cs_new_protected:Npn \__draw_backend_dash_pattern:nn #1#2
+ {
+ \__draw_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \__draw_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ d
+ }
+ }
+\cs_new:Npn \__draw_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \__draw_backend_linewidth:n #1
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ w }
+ }
+\cs_new_protected:Npn \__draw_backend_miterlimit:n #1
+ { \__draw_backend_literal:e { #1 ~ M } }
+\cs_new_protected:Npn \__draw_backend_cap_butt:
+ { \__draw_backend_literal:n { 0 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_round:
+ { \__draw_backend_literal:n { 1 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_rectangle:
+ { \__draw_backend_literal:n { 2 ~ J } }
+\cs_new_protected:Npn \__draw_backend_join_miter:
+ { \__draw_backend_literal:n { 0 ~ j } }
+\cs_new_protected:Npn \__draw_backend_join_round:
+ { \__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
+ {
+ \__kernel_backend_matrix:n { #1 ~ #2 ~ #3 ~ #4 }
+ }
+\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}
+ \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 }
+ }
+\tl_new:N \l__graphics_attr_tl
+\cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l__graphics_page_int
+ \tl_clear:N \l__graphics_pagebox_tl
+ \tl_set:Ne \l__graphics_attr_tl
+ {
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { :D \l__graphics_decodearray_str }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { :I }
+ \str_if_empty:NF \l__graphics_pdf_str
+ { :X \l__graphics_pdf_str }
+ }
+ \__graphics_backend_getbb_auxi:n {#1}
+ }
+\cs_new_eq:NN \__graphics_backend_getbb_jpeg:n \__graphics_backend_getbb_jpg:n
+\cs_new_eq:NN \__graphics_backend_getbb_png:n \__graphics_backend_getbb_jpg:n
+\cs_new_protected:Npn \__graphics_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l__graphics_decodearray_str
+ \bool_set_false:N \l__graphics_interpolate_bool
+ \tl_set:Ne \l__graphics_attr_tl
+ {
+ : \l__graphics_pagebox_tl
+ \int_compare:nNnT \l__graphics_page_int > 1
+ { :P \int_use:N \l__graphics_page_int }
+ \str_if_empty:NF \l__graphics_pdf_str
+ { :X \l__graphics_pdf_str }
+ }
+ \__graphics_backend_getbb_auxi:n {#1}
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxi:n #1
+ {
+ \__graphics_bb_restore:eF { #1 \l__graphics_attr_tl }
+ { \__graphics_backend_getbb_auxii:n {#1} }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxii:n #1
+ {
+ \exp_args:Ne \__graphics_backend_getbb_auxiii:n
+ { \__graphics_backend_dequote:w #1 " #1 " \s__graphics_stop }
+ \int_const:cn { c__graphics_ #1 \l__graphics_attr_tl _int }
+ { \tex_the:D \tex_pdflastximage:D }
+ \__graphics_bb_save:e { #1 \l__graphics_attr_tl }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxiii:n #1
+ {
+ \tex_immediate:D \tex_pdfximage:D
+ \bool_lazy_any:nT
+ {
+ { \l__graphics_interpolate_bool }
+ { ! \tl_if_empty_p:N \l__graphics_decodearray_str }
+ { ! \str_if_empty_p:N \l__graphics_pdf_str }
+ }
+ {
+ attr ~
+ {
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { /Decode~[ \l__graphics_decodearray_str ] }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { /Interpolate~true }
+ \l__graphics_pdf_str
+ }
+ }
+ \int_compare:nNnT \l__graphics_page_int > 0
+ { page ~ \int_use:N \l__graphics_page_int }
+ \tl_if_empty:NF \l__graphics_pagebox_tl
+ { \l__graphics_pagebox_tl }
+ {#1}
+ \hbox_set:Nn \l__graphics_internal_box
+ { \tex_pdfrefximage:D \tex_pdflastximage:D }
+ \dim_set:Nn \l__graphics_urx_dim { \box_wd:N \l__graphics_internal_box }
+ \dim_set:Nn \l__graphics_ury_dim { \box_ht:N \l__graphics_internal_box }
+ }
+\cs_new:Npn \__graphics_backend_dequote:w #1 " #2 " #3 \s__graphics_stop {#2}
+\cs_new_protected:Npn \__graphics_backend_include_jpg:n #1
+ {
+ \tex_pdfrefximage:D
+ \int_use:c { c__graphics_ #1 \l__graphics_attr_tl _int }
+ }
+\cs_new_eq:NN \__graphics_backend_include_jpeg:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_pdf:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_png:n \__graphics_backend_include_jpg:n
+\sys_if_shell:T
+ {
+ \str_new:N \l__graphics_backend_dir_str
+ \str_new:N \l__graphics_backend_name_str
+ \str_new:N \l__graphics_backend_ext_str
+ \cs_new_protected:Npn \__graphics_backend_getbb_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l__graphics_backend_dir_str
+ \l__graphics_backend_name_str
+ \l__graphics_backend_ext_str
+ \exp_args:Ne \__graphics_backend_getbb_eps:nn
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l__graphics_backend_name_str
+ - \str_tail:N \l__graphics_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ {#1}
+ }
+ \cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_backend_getbb_eps:n
+ \cs_new_protected:Npn \__graphics_backend_getbb_eps:nn #1#2
+ {
+ \file_compare_timestamp:nNnT {#2} > {#1}
+ {
+ \sys_shell_now:n
+ { repstopdf ~ #2 ~ #1 }
+ }
+ \tl_set:Nn \l__graphics_final_name_str {#1}
+ \__graphics_backend_getbb_pdf:n {#1}
+ }
+ \cs_new_protected:Npn \__graphics_backend_include_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l__graphics_backend_dir_str \l__graphics_backend_name_str \l__graphics_backend_ext_str
+ \exp_args:Ne \__graphics_backend_include_pdf:n
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l__graphics_backend_name_str
+ - \str_tail:N \l__graphics_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ }
+ \cs_new_eq:NN \__graphics_backend_include_ps:n \__graphics_backend_include_eps:n
+ }
+\cs_new_protected:Npn \__graphics_backend_get_pagecount:n #1
+ {
+ \tex_pdfximage:D {#1}
+ \int_const:cn { c__graphics_ #1 _pages_int }
+ { \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 ~
+ name {#1}
+ \str_case:nnF {#2}
+ {
+ { xyz } { xyz }
+ { fit } { fit }
+ { fitb } { fitb }
+ { fitbh } { fitbh }
+ { fitbv } { fitbv }
+ { fith } { fith }
+ { fitv } { fitv }
+ { fitr } { fitr }
+ }
+ { xyz ~ zoom \fp_eval:n { #2 * 10 } }
+ \scan_stop:
+ }
+\cs_new_protected:Npn \__pdf_backend_destination:nnnn #1#2#3#4
+ {
+ \tex_pdfextension:D dest ~
+ name {#1}
+ fitr ~
+ width \dim_eval:n {#2} ~
+ height \dim_eval:n {#3} ~
+ depth \dim_eval:n {#4} \scan_stop:
+ }
+\cs_new_protected:Npn \__pdf_backend_catalog_gput:nn #1#2
+ {
+ \tex_pdfextension:D catalog
+ { / #1 ~ #2 }
+ }
+\cs_new_protected:Npn \__pdf_backend_info_gput:nn #1#2
+ {
+ \tex_pdfextension:D info
+ { / #1 ~ #2 }
+ }
+\prop_new:N \g__pdf_backend_object_prop
+\cs_new_protected:Npn \__pdf_backend_object_new:
+ {
+ \tex_pdfextension:D obj ~
+ reserveobjnum ~
+ \int_gset:Nn \g__pdf_backend_object_int
+ { \tex_pdffeedback:D lastobj }
+ }
+\cs_new:Npn \__pdf_backend_object_ref:n #1 { #1 ~ 0 ~ R }
+\cs_new:Npn \__pdf_backend_object_id:n #1 {#1}
+\cs_new_protected:Npn \__pdf_backend_object_write:nnn #1#2#3
+ {
+ \tex_immediate:D \tex_pdfextension:D obj ~
+ useobjnum ~ #1
+ \__pdf_backend_object_write:nn {#2} {#3}
+ }
+\cs_new:Npn \__pdf_backend_object_write:nn #1#2
+ {
+ \str_case:nn {#1}
+ {
+ { array } { { [ ~ \exp_not:n {#2} ~ ] } }
+ { dict } { { << ~ \exp_not:n {#2} ~ >> } }
+ { fstream }
+ {
+ stream ~ attr ~ { \__pdf_exp_not_i:nn #2 } ~
+ file ~ { \__pdf_exp_not_ii:nn #2 }
+ }
+ { stream }
+ {
+ stream ~ attr ~ { \__pdf_exp_not_i:nn #2 } ~
+ { \__pdf_exp_not_ii:nn #2 }
+ }
+ }
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_write:nnn { nne }
+\cs_new:Npn \__pdf_exp_not_i:nn #1#2 { \exp_not:n {#1} }
+\cs_new:Npn \__pdf_exp_not_ii:nn #1#2 { \exp_not:n {#2} }
+\cs_new_protected:Npn \__pdf_backend_object_now:nn #1#2
+ {
+ \tex_immediate:D \tex_pdfextension:D obj ~
+ \__pdf_backend_object_write:nn {#1} {#2}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_now:nn { ne }
+\cs_new:Npe \__pdf_backend_object_last:
+ {
+ \exp_not:N \int_value:w
+ \exp_not:N \tex_pdffeedback:D lastobj ~
+ \c_space_tl 0 ~ R
+ }
+\cs_new:Npe \__pdf_backend_pageobject_ref:n #1
+ {
+ \exp_not:N \int_value:w
+ \exp_not:N \tex_pdffeedback:D pageref
+ \c_space_tl #1 \c_space_tl \c_space_tl \c_space_tl 0 ~ R
+ }
+\cs_new_protected:Npn \__pdf_backend_compresslevel:n #1
+ {
+ \tex_global:D
+ \tex_pdfvariable:D compresslevel
+ \int_value:w \int_eval:n {#1} \scan_stop:
+ }
+\cs_new_protected:Npn \__pdf_backend_compress_objects:n #1
+ {
+ \bool_if:nTF {#1}
+ { \__pdf_backend_objcompresslevel:n { 2 } }
+ { \__pdf_backend_objcompresslevel:n { 0 } }
+ }
+\cs_new_protected:Npn \__pdf_backend_objcompresslevel:n #1
+ {
+ \tex_global:D
+ \tex_pdfvariable:D objcompresslevel
+ #1 \scan_stop:
+ }
+\cs_new_protected:Npe \__pdf_backend_version_major_gset:n #1
+ {
+ \int_compare:nNnT \tex_luatexversion:D > { 106 }
+ {
+ \exp_not:N \tex_global:D \tex_pdfvariable:D majorversion
+ \exp_not:N \int_eval:n {#1} \scan_stop:
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1
+ {
+ \tex_global:D
+ \tex_pdfvariable:D minorversion
+ \int_eval:n {#1} \scan_stop:
+ }
+\cs_new:Npe \__pdf_backend_version_major:
+ {
+ \int_compare:nNnTF \tex_luatexversion:D > { 106 }
+ { \exp_not:N \tex_the:D \tex_pdfvariable:D majorversion }
+ { 1 }
+ }
+\cs_new:Npn \__pdf_backend_version_minor:
+ {
+ \tex_the:D
+ \tex_pdfvariable:D minorversion
+ }
+\cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \__pdf_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+\cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2
+ {
+ \dim_gset:Nn \tex_pagewidth:D {#1}
+ \dim_gset:Nn \tex_pageheight:D {#2}
+ }
+%% File: l3backend-opacity.dtx
+\bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \__kernel_color_backend_stack_init:Nnn \c__opacity_backend_stack_int
+ { page ~ direct } { /opacity 1 ~ gs }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity 1 } { << /ca ~ 1 /CA ~ 1 >> }
+ }
+\tl_new:N \l__opacity_backend_fill_tl
+\tl_new:N \l__opacity_backend_stroke_tl
+\tl_set:Nn \l__opacity_backend_fill_tl { 1 }
+\tl_set:Nn \l__opacity_backend_stroke_tl { 1 }
+\cs_new_protected:Npn \__opacity_backend_select:n #1
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#1}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity #1 }
+ { << /ca ~ #1 /CA ~ #1 >> }
+ \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
+ { /opacity #1 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+\cs_new_protected:Npn \__opacity_backend_reset:
+ {
+ \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int
+ }
+\cs_new_protected:Npn \__opacity_backend_fill:n #1
+ {
+ \exp_args:Nno \__opacity_backend_fill_stroke:nn
+ { #1 }
+ { \l__opacity_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \__opacity_backend_stroke:n #1
+ {
+ \exp_args:No \__opacity_backend_fill_stroke:nn
+ { \l__opacity_backend_fill_tl }
+ { #1 }
+ }
+\cs_new_protected:Npn \__opacity_backend_fill_stroke:nn #1#2
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \__opacity_backend_select:n {#1} }
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#2}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.fill #1 }
+ { << /ca ~ #1 >> }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.stroke #2 }
+ { << /CA ~ #2 >> }
+ \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
+ { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+ }
+\bool_lazy_and:nnF
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \cs_gset_protected:Npn \__opacity_backend_select:n #1 { }
+ \cs_gset_protected:Npn \__opacity_backend_fill_stroke:nn #1#2 { }
+ }
+%%
+%%
+%% End of file `l3backend-luatex.def'.
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.lua b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.lua
new file mode 100644
index 00000000000..ef34f055780
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-luatex.lua
@@ -0,0 +1,125 @@
+--
+-- This is file `l3backend-luatex.lua',
+-- generated with the docstrip utility.
+--
+-- The original source files were:
+--
+-- l3backend-color.dtx (with options: `lua')
+-- l3backend-opacity.dtx (with options: `lua')
+--
+-- Copyright (C) 2023,2024 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.
+--
+-- File: l3backend-color.dtx
+local l = lpeg
+local spaces = l.P' '^0
+local digit16 = l.R('09', 'af', 'AF')
+
+local octet = digit16 * digit16 / function(s)
+ return string.format('%.3g ', tonumber(s, 16) / 255)
+end
+
+if luaotfload and luaotfload.set_transparent_colorstack then
+ local htmlcolor = l.Cs(octet * octet * octet * -1 * l.Cc'rg')
+ local color_export = {
+ token.create'tex_endlocalcontrol:D',
+ token.create'tex_hpack:D',
+ token.new(0, 1),
+ token.create'color_export:nnN',
+ token.new(0, 1),
+ '',
+ token.new(0, 2),
+ token.new(0, 1),
+ 'backend',
+ token.new(0, 2),
+ token.create'l_tmpa_tl',
+ token.create'exp_after:wN',
+ token.create'__color_select:nn',
+ token.create'l_tmpa_tl',
+ token.new(0, 2),
+ }
+ local group_end = token.create'group_end:'
+ local value = (1 - l.P'}')^0
+ luatexbase.add_to_callback('luaotfload.parse_color', function (value)
+ local html = htmlcolor:match(value)
+ if html then return html end
+
+ local l3color_prop = token.get_macro(string.format('l__color_named_%s_prop', value))
+ if l3color_prop == nil or l3color_prop == '' then
+ local legacy_color_macro = token.create(string.format('\\color@%s', value))
+ if legacy_color_macro.cmdname ~= 'undefined_cs' then
+ token.put_next(legacy_color_macro)
+ return token.scan_argument()
+ end
+ end
+
+ tex.runtoks(function()
+ token.get_next()
+ color_export[6] = value
+ tex.sprint(-2, color_export)
+ end)
+ local list = token.scan_list()
+ if not list.head or list.head.next
+ or list.head.subtype ~= node.subtype'pdf_colorstack' then
+ error'Unexpected backend behavior'
+ end
+ local cmd = list.head.data
+ node.free(list)
+ return cmd
+ end, 'l3color')
+end
+-- File: l3backend-opacity.dtx
+local pdfmanagement_active do
+ local pdfmanagement_if_active_p = token.create'pdfmanagement_if_active_p:'
+ local cmd = pdfmanagement_if_active_p.cmdname
+ if cmd == 'undefined_cs' then
+ pdfmanagement_active = false
+ else
+ token.put_next(pdfmanagement_if_active_p)
+ pdfmanagement_active = token.scan_int() ~= 0
+ end
+end
+
+if pdfmanagement_active and luaotfload and luaotfload.set_transparent_colorstack then
+ luaotfload.set_transparent_colorstack(function() return token.create'c__opacity_backend_stack_int'.index end)
+
+ local transparent_register = {
+ token.create'pdfmanagement_add:nnn',
+ token.new(0, 1),
+ 'Page/Resources/ExtGState',
+ token.new(0, 2),
+ token.new(0, 1),
+ '',
+ token.new(0, 2),
+ token.new(0, 1),
+ '<</ca ',
+ '',
+ '/CA ',
+ '',
+ '>>',
+ token.new(0, 2),
+ }
+ luatexbase.add_to_callback('luaotfload.parse_transparent', function(value)
+ value = (octet * -1):match(value)
+ if not value then
+ tex.error'Invalid transparency value'
+ return
+ end
+ value = value:sub(1, -2)
+ local result = 'opacity' .. value
+ tex.runtoks(function()
+ transparent_register[6], transparent_register[10], transparent_register[12] = result, value, value
+ tex.sprint(-2, transparent_register)
+ end)
+ return '/' .. result .. ' gs'
+ end, 'l3opacity')
+end
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-pdftex.def b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-pdftex.def
new file mode 100644
index 00000000000..3c51094bbc8
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-pdftex.def
@@ -0,0 +1,902 @@
+%%
+%% This is file `l3backend-pdftex.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3backend-basics.dtx (with options: `package,pdftex')
+%% l3backend-color.dtx (with options: `package,pdftex')
+%% l3backend-box.dtx (with options: `package,pdftex')
+%% l3backend-draw.dtx (with options: `package,pdftex')
+%% l3backend-graphics.dtx (with options: `package,pdftex')
+%% l3backend-pdf.dtx (with options: `package,pdftex')
+%% l3backend-opacity.dtx (with options: `package,pdftex')
+%%
+%% Copyright (C) 2019-2024 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.
+%%
+%% File: l3backend-basics.dtx
+\ProvidesExplFile
+ {l3backend-pdftex.def}{2024-04-11}{}
+ {L3 backend support: PDF output (pdfTeX)}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+ {l3backend-pdftex.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ {
+ \tex_pdfliteral:D
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+\cs_new_protected:Npn \__kernel_backend_literal_page:n #1
+ {
+ \tex_pdfliteral:D
+ page { \exp_not:n {#1} }
+ }
+\cs_new_protected:Npn \__kernel_backend_literal_page:e #1
+ {
+ \tex_pdfliteral:D
+ page {#1}
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ {
+ \tex_pdfsave:D
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ {
+ \tex_pdfrestore:D
+ }
+\cs_new_protected:Npn \__kernel_backend_matrix:n #1
+ {
+ \tex_pdfsetmatrix:D
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \__kernel_backend_matrix:n { e }
+%% 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
+ {
+ \int_const:Nn #1
+ {
+ \tex_pdfcolorstackinit:D
+ \tl_if_blank:nF {#2} { #2 ~ }
+ {#3}
+ }
+ }
+\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
+ {
+ \tex_pdfcolorstack:D
+ \int_eval:n {#1} ~ push ~ {#2}
+ }
+\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
+ {
+ \tex_pdfcolorstack:D
+ \int_eval:n {#1} ~ pop \scan_stop:
+ }
+\tl_new:N \l__color_backend_fill_tl
+\tl_new:N \l__color_backend_stroke_tl
+\tl_set:Nn \l__color_backend_fill_tl { 0 ~ g }
+\tl_set:Nn \l__color_backend_stroke_tl { 0 ~ G }
+\cs_new_protected:Npn \__color_backend_select_cmyk:n #1
+ { \__color_backend_select:nn { #1 ~ k } { #1 ~ K } }
+\cs_new_protected:Npn \__color_backend_select_gray:n #1
+ { \__color_backend_select:nn { #1 ~ g } { #1 ~ G } }
+\cs_new_protected:Npn \__color_backend_select_rgb:n #1
+ { \__color_backend_select:nn { #1 ~ rg } { #1 ~ RG } }
+\cs_new_protected:Npn \__color_backend_select:nn #1#2
+ {
+ \tl_set:Nn \l__color_backend_fill_tl {#1}
+ \tl_set:Nn \l__color_backend_stroke_tl {#2}
+ \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
+ }
+\cs_new_protected:Npn \__color_backend_reset:
+ { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int }
+\prop_new:N \g__color_backend_colorant_prop
+\cs_new:Npe \__color_backend_devicen_colorants:n #1
+ {
+ \exp_not:N \tl_if_blank:nF {#1}
+ {
+ \c_space_tl
+ << ~
+ /Colorants ~
+ << ~
+ \exp_not:N \__color_backend_devicen_colorants:w #1 ~
+ \exp_not:N \q_recursion_tail \c_space_tl
+ \exp_not:N \q_recursion_stop
+ >> ~
+ >>
+ }
+ }
+\cs_new:Npn \__color_backend_devicen_colorants:w #1 ~
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \prop_if_in:NnT \g__color_backend_colorant_prop {#1}
+ {
+ #1 ~
+ \prop_item:Nn \g__color_backend_colorant_prop {#1} ~
+ }
+ \__color_backend_devicen_colorants:w
+ }
+\cs_new_protected:Npn \__color_backend_select_separation:nn #1#2
+ { \__color_backend_select:nn { /#1 ~ cs ~ #2 ~ scn } { /#1 ~ CS ~ #2 ~ SCN } }
+\cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
+\cs_new_eq:NN \__color_backend_select_iccbased:nn \__color_backend_select_separation:nn
+\cs_new_protected:Npn \__color_backend_init_resource:n #1
+ {
+ \bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \use:e
+ {
+ \pdfmanagement_add:nnn
+ { Page / Resources / ColorSpace }
+ { #1 }
+ { \pdf_object_ref_last: }
+ }
+ }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \pdf_object_unnamed_write:ne { dict }
+ {
+ /FunctionType ~ 2
+ /Domain ~ [0 ~ 1]
+ \tl_if_blank:nF {#3} { /Range ~ [#3] }
+ /C0 ~ [#4] ~
+ /C1 ~ [#5] /N ~ 1
+ }
+ \exp_args:Ne \__color_backend_separation_init:nn
+ { \str_convert_pdfname:n {#1} } {#2}
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nn #1#2
+ {
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ { /Separation /#1 ~ #2 ~ \pdf_object_ref_last: }
+ }
+ \prop_gput:Nne \g__color_backend_colorant_prop { /#1 }
+ { \pdf_object_ref_last: }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_illuminant_CIELAB_ #1 }
+ {
+ \pdf_object_new:n { __color_illuminant_CIELAB_ #1 }
+ \pdf_object_write:nne { __color_illuminant_CIELAB_ #1 } { array }
+ {
+ /Lab ~
+ <<
+ /WhitePoint ~
+ [ \tl_use:c { c__color_model_whitepoint_CIELAB_ #1 _tl } ]
+ /Range ~ [ \c__color_model_range_CIELAB_tl ]
+ >>
+ }
+ }
+ \__color_backend_separation_init:nnnnn
+ {#2}
+ { \pdf_object_ref:n { __color_illuminant_CIELAB_ #1 } }
+ { \c__color_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+\cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
+ {
+ \pdf_object_unnamed_write:ne { stream }
+ {
+ {
+ /FunctionType ~ 4 ~
+ /Domain ~
+ [ ~
+ \prg_replicate:nn
+ { 0 \__color_backend_devicen_init:w #1 ~ \s__color_stop }
+ { 0 ~ 1 ~ }
+ ] ~
+ /Range ~
+ [ ~
+ \str_case:nn {#2}
+ {
+ { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ { /DeviceGray } { 0 ~ 1 }
+ { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ } ~
+ ]
+ }
+ { {#3} }
+ }
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ {
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ \pdf_object_ref_last:
+ \__color_backend_devicen_colorants:n {#1}
+ }
+ }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
+ {
+ + 1
+ \tl_if_blank:nF {#2}
+ { \__color_backend_devicen_init:w #2 \s__color_stop }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_init:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nne { __color_icc_ #1 } { fstream }
+ {
+ {
+ /N ~ \exp_not:n { #2 } ~
+ \tl_if_empty:nF { #3 } { /Range~[ #3 ] }
+ }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_device:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nnn { __color_icc_ #1 } { fstream }
+ {
+ { /N ~ #3 }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { Default #2 }
+ }
+\cs_new_protected:Npn \__color_backend_fill_cmyk:n #1
+ { \__color_backend_fill:n { #1 ~ k } }
+\cs_new_protected:Npn \__color_backend_fill_gray:n #1
+ { \__color_backend_fill:n { #1 ~ g } }
+\cs_new_protected:Npn \__color_backend_fill_rgb:n #1
+ { \__color_backend_fill:n { #1 ~ rg } }
+\cs_new_protected:Npn \__color_backend_fill:n #1
+ {
+ \tl_set:Nn \l__color_backend_fill_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
+ { #1 ~ \l__color_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_cmyk:n #1
+ { \__color_backend_stroke:n { #1 ~ K } }
+\cs_new_protected:Npn \__color_backend_stroke_gray:n #1
+ { \__color_backend_stroke:n { #1 ~ G } }
+\cs_new_protected:Npn \__color_backend_stroke_rgb:n #1
+ { \__color_backend_stroke:n { #1 ~ RG } }
+\cs_new_protected:Npn \__color_backend_stroke:n #1
+ {
+ \tl_set:Nn \l__color_backend_stroke_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
+ { \l__color_backend_fill_tl \c_space_tl #1 }
+ }
+\cs_new_protected:Npn \__color_backend_fill_separation:nn #1#2
+ { \__color_backend_fill:n { /#1 ~ cs ~ #2 ~ scn } }
+\cs_new_protected:Npn \__color_backend_stroke_separation:nn #1#2
+ { \__color_backend_stroke:n { /#1 ~ CS ~ #2 ~ SCN } }
+\cs_new_eq:NN \__color_backend_fill_devicen:nn \__color_backend_fill_separation:nn
+\cs_new_eq:NN \__color_backend_stroke_devicen:nn \__color_backend_stroke_separation:nn
+\cs_new_eq:NN \__color_backend_fill_reset: \__color_backend_reset:
+\cs_new_eq:NN \__color_backend_stroke_reset: \__color_backend_reset:
+%% File: l3backend-box.dtx
+\cs_new_protected:Npn \__box_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+\cs_new_protected:Npn \__box_backend_rotate:Nn #1#2
+ { \exp_args:NNf \__box_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \__box_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \box_set_wd:Nn #1 { 0pt }
+ \fp_set:Nn \l__box_backend_cos_fp { round ( cosd ( #2 ) , 5 ) }
+ \fp_compare:nNnT \l__box_backend_cos_fp = \c_zero_fp
+ { \fp_zero:N \l__box_backend_cos_fp }
+ \fp_set:Nn \l__box_backend_sin_fp { round ( sind ( #2 ) , 5 ) }
+ \__kernel_backend_matrix:e
+ {
+ \fp_use:N \l__box_backend_cos_fp \c_space_tl
+ \fp_compare:nNnTF \l__box_backend_sin_fp = \c_zero_fp
+ { 0~0 }
+ {
+ \fp_use:N \l__box_backend_sin_fp
+ \c_space_tl
+ \fp_eval:n { -\l__box_backend_sin_fp }
+ }
+ \c_space_tl
+ \fp_use:N \l__box_backend_cos_fp
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\fp_new:N \l__box_backend_cos_fp
+\fp_new:N \l__box_backend_sin_fp
+\cs_new_protected:Npn \__box_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_matrix:e
+ {
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ 0~0~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+%% 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_protected:Npn \__draw_backend_begin:
+ { \__draw_backend_scope_begin: }
+\cs_new_protected:Npn \__draw_backend_end:
+ { \__draw_backend_scope_end: }
+\cs_new_eq:NN \__draw_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \__draw_backend_scope_end: \__kernel_backend_scope_end:
+\cs_new_protected:Npn \__draw_backend_moveto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
+ }
+\cs_new_protected:Npn \__draw_backend_lineto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
+ }
+\cs_new_protected:Npn \__draw_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ c
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_rectangle:nnnn #1#2#3#4
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ re
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_evenodd_rule:
+ { \bool_gset_true:N \g__draw_draw_eor_bool }
+\cs_new_protected:Npn \__draw_backend_nonzero_rule:
+ { \bool_gset_false:N \g__draw_draw_eor_bool }
+\bool_new:N \g__draw_draw_eor_bool
+\cs_new_protected:Npn \__draw_backend_closepath:
+ { \__draw_backend_literal:n { h } }
+\cs_new_protected:Npn \__draw_backend_stroke:
+ { \__draw_backend_literal:n { S } }
+\cs_new_protected:Npn \__draw_backend_closestroke:
+ { \__draw_backend_literal:n { s } }
+\cs_new_protected:Npn \__draw_backend_fill:
+ {
+ \__draw_backend_literal:e
+ { f \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_fillstroke:
+ {
+ \__draw_backend_literal:e
+ { B \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_clip:
+ {
+ \__draw_backend_literal:e
+ { W \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_discardpath:
+ { \__draw_backend_literal:n { n } }
+\cs_new_protected:Npn \__draw_backend_dash_pattern:nn #1#2
+ {
+ \__draw_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \__draw_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ d
+ }
+ }
+\cs_new:Npn \__draw_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \__draw_backend_linewidth:n #1
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ w }
+ }
+\cs_new_protected:Npn \__draw_backend_miterlimit:n #1
+ { \__draw_backend_literal:e { #1 ~ M } }
+\cs_new_protected:Npn \__draw_backend_cap_butt:
+ { \__draw_backend_literal:n { 0 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_round:
+ { \__draw_backend_literal:n { 1 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_rectangle:
+ { \__draw_backend_literal:n { 2 ~ J } }
+\cs_new_protected:Npn \__draw_backend_join_miter:
+ { \__draw_backend_literal:n { 0 ~ j } }
+\cs_new_protected:Npn \__draw_backend_join_round:
+ { \__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
+ {
+ \__kernel_backend_matrix:n { #1 ~ #2 ~ #3 ~ #4 }
+ }
+\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}
+ \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 }
+ }
+\tl_new:N \l__graphics_attr_tl
+\cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l__graphics_page_int
+ \tl_clear:N \l__graphics_pagebox_tl
+ \tl_set:Ne \l__graphics_attr_tl
+ {
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { :D \l__graphics_decodearray_str }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { :I }
+ \str_if_empty:NF \l__graphics_pdf_str
+ { :X \l__graphics_pdf_str }
+ }
+ \__graphics_backend_getbb_auxi:n {#1}
+ }
+\cs_new_eq:NN \__graphics_backend_getbb_jpeg:n \__graphics_backend_getbb_jpg:n
+\cs_new_eq:NN \__graphics_backend_getbb_png:n \__graphics_backend_getbb_jpg:n
+\cs_new_protected:Npn \__graphics_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l__graphics_decodearray_str
+ \bool_set_false:N \l__graphics_interpolate_bool
+ \tl_set:Ne \l__graphics_attr_tl
+ {
+ : \l__graphics_pagebox_tl
+ \int_compare:nNnT \l__graphics_page_int > 1
+ { :P \int_use:N \l__graphics_page_int }
+ \str_if_empty:NF \l__graphics_pdf_str
+ { :X \l__graphics_pdf_str }
+ }
+ \__graphics_backend_getbb_auxi:n {#1}
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxi:n #1
+ {
+ \__graphics_bb_restore:eF { #1 \l__graphics_attr_tl }
+ { \__graphics_backend_getbb_auxii:n {#1} }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxii:n #1
+ {
+ \exp_args:Ne \__graphics_backend_getbb_auxiii:n
+ { \__graphics_backend_dequote:w #1 " #1 " \s__graphics_stop }
+ \int_const:cn { c__graphics_ #1 \l__graphics_attr_tl _int }
+ { \tex_the:D \tex_pdflastximage:D }
+ \__graphics_bb_save:e { #1 \l__graphics_attr_tl }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxiii:n #1
+ {
+ \tex_immediate:D \tex_pdfximage:D
+ \bool_lazy_any:nT
+ {
+ { \l__graphics_interpolate_bool }
+ { ! \tl_if_empty_p:N \l__graphics_decodearray_str }
+ { ! \str_if_empty_p:N \l__graphics_pdf_str }
+ }
+ {
+ attr ~
+ {
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { /Decode~[ \l__graphics_decodearray_str ] }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { /Interpolate~true }
+ \l__graphics_pdf_str
+ }
+ }
+ \int_compare:nNnT \l__graphics_page_int > 0
+ { page ~ \int_use:N \l__graphics_page_int }
+ \tl_if_empty:NF \l__graphics_pagebox_tl
+ { \l__graphics_pagebox_tl }
+ {#1}
+ \hbox_set:Nn \l__graphics_internal_box
+ { \tex_pdfrefximage:D \tex_pdflastximage:D }
+ \dim_set:Nn \l__graphics_urx_dim { \box_wd:N \l__graphics_internal_box }
+ \dim_set:Nn \l__graphics_ury_dim { \box_ht:N \l__graphics_internal_box }
+ }
+\cs_new:Npn \__graphics_backend_dequote:w #1 " #2 " #3 \s__graphics_stop {#2}
+\cs_new_protected:Npn \__graphics_backend_include_jpg:n #1
+ {
+ \tex_pdfrefximage:D
+ \int_use:c { c__graphics_ #1 \l__graphics_attr_tl _int }
+ }
+\cs_new_eq:NN \__graphics_backend_include_jpeg:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_pdf:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_png:n \__graphics_backend_include_jpg:n
+\sys_if_shell:T
+ {
+ \str_new:N \l__graphics_backend_dir_str
+ \str_new:N \l__graphics_backend_name_str
+ \str_new:N \l__graphics_backend_ext_str
+ \cs_new_protected:Npn \__graphics_backend_getbb_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l__graphics_backend_dir_str
+ \l__graphics_backend_name_str
+ \l__graphics_backend_ext_str
+ \exp_args:Ne \__graphics_backend_getbb_eps:nn
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l__graphics_backend_name_str
+ - \str_tail:N \l__graphics_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ {#1}
+ }
+ \cs_new_eq:NN \__graphics_backend_getbb_ps:n \__graphics_backend_getbb_eps:n
+ \cs_new_protected:Npn \__graphics_backend_getbb_eps:nn #1#2
+ {
+ \file_compare_timestamp:nNnT {#2} > {#1}
+ {
+ \sys_shell_now:n
+ { repstopdf ~ #2 ~ #1 }
+ }
+ \tl_set:Nn \l__graphics_final_name_str {#1}
+ \__graphics_backend_getbb_pdf:n {#1}
+ }
+ \cs_new_protected:Npn \__graphics_backend_include_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l__graphics_backend_dir_str \l__graphics_backend_name_str \l__graphics_backend_ext_str
+ \exp_args:Ne \__graphics_backend_include_pdf:n
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l__graphics_backend_name_str
+ - \str_tail:N \l__graphics_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ }
+ \cs_new_eq:NN \__graphics_backend_include_ps:n \__graphics_backend_include_eps:n
+ }
+\cs_new_protected:Npn \__graphics_backend_get_pagecount:n #1
+ {
+ \tex_pdfximage:D {#1}
+ \int_const:cn { c__graphics_ #1 _pages_int }
+ { \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
+ name {#1}
+ \str_case:nnF {#2}
+ {
+ { xyz } { xyz }
+ { fit } { fit }
+ { fitb } { fitb }
+ { fitbh } { fitbh }
+ { fitbv } { fitbv }
+ { fith } { fith }
+ { fitv } { fitv }
+ { fitr } { fitr }
+ }
+ { xyz ~ zoom \fp_eval:n { #2 * 10 } }
+ \scan_stop:
+ }
+\cs_new_protected:Npn \__pdf_backend_destination:nnnn #1#2#3#4
+ {
+ \tex_pdfdest:D
+ name {#1}
+ fitr ~
+ width \dim_eval:n {#2} ~
+ height \dim_eval:n {#3} ~
+ depth \dim_eval:n {#4} \scan_stop:
+ }
+\cs_new_protected:Npn \__pdf_backend_catalog_gput:nn #1#2
+ {
+ \tex_pdfcatalog:D
+ { / #1 ~ #2 }
+ }
+\cs_new_protected:Npn \__pdf_backend_info_gput:nn #1#2
+ {
+ \tex_pdfinfo:D
+ { / #1 ~ #2 }
+ }
+\prop_new:N \g__pdf_backend_object_prop
+\cs_new_protected:Npn \__pdf_backend_object_new:
+ {
+ \tex_pdfobj:D
+ reserveobjnum ~
+ \int_gset:Nn \g__pdf_backend_object_int
+ { \tex_pdflastobj:D }
+ }
+\cs_new:Npn \__pdf_backend_object_ref:n #1 { #1 ~ 0 ~ R }
+\cs_new:Npn \__pdf_backend_object_id:n #1 {#1}
+\cs_new_protected:Npn \__pdf_backend_object_write:nnn #1#2#3
+ {
+ \tex_immediate:D \tex_pdfobj:D
+ useobjnum ~ #1
+ \__pdf_backend_object_write:nn {#2} {#3}
+ }
+\cs_new:Npn \__pdf_backend_object_write:nn #1#2
+ {
+ \str_case:nn {#1}
+ {
+ { array } { { [ ~ \exp_not:n {#2} ~ ] } }
+ { dict } { { << ~ \exp_not:n {#2} ~ >> } }
+ { fstream }
+ {
+ stream ~ attr ~ { \__pdf_exp_not_i:nn #2 } ~
+ file ~ { \__pdf_exp_not_ii:nn #2 }
+ }
+ { stream }
+ {
+ stream ~ attr ~ { \__pdf_exp_not_i:nn #2 } ~
+ { \__pdf_exp_not_ii:nn #2 }
+ }
+ }
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_write:nnn { nne }
+\cs_new:Npn \__pdf_exp_not_i:nn #1#2 { \exp_not:n {#1} }
+\cs_new:Npn \__pdf_exp_not_ii:nn #1#2 { \exp_not:n {#2} }
+\cs_new_protected:Npn \__pdf_backend_object_now:nn #1#2
+ {
+ \tex_immediate:D \tex_pdfobj:D
+ \__pdf_backend_object_write:nn {#1} {#2}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_now:nn { ne }
+\cs_new:Npe \__pdf_backend_object_last:
+ {
+ \exp_not:N \int_value:w
+ \exp_not:N \tex_pdflastobj:D
+ \c_space_tl 0 ~ R
+ }
+\cs_new:Npe \__pdf_backend_pageobject_ref:n #1
+ {
+ \exp_not:N \int_value:w
+ \exp_not:N \tex_pdfpageref:D
+ \c_space_tl #1 \c_space_tl \c_space_tl \c_space_tl 0 ~ R
+ }
+\cs_new_protected:Npn \__pdf_backend_compresslevel:n #1
+ {
+ \tex_global:D
+ \tex_pdfcompresslevel:D
+ \int_value:w \int_eval:n {#1} \scan_stop:
+ }
+\cs_new_protected:Npn \__pdf_backend_compress_objects:n #1
+ {
+ \bool_if:nTF {#1}
+ { \__pdf_backend_objcompresslevel:n { 2 } }
+ { \__pdf_backend_objcompresslevel:n { 0 } }
+ }
+\cs_new_protected:Npn \__pdf_backend_objcompresslevel:n #1
+ {
+ \tex_global:D
+ \tex_pdfobjcompresslevel:D
+ #1 \scan_stop:
+ }
+\cs_new_protected:Npe \__pdf_backend_version_major_gset:n #1
+ {
+ \cs_if_exist:NT \tex_pdfmajorversion:D
+ {
+ \exp_not:N \tex_global:D \tex_pdfmajorversion:D
+ \exp_not:N \int_eval:n {#1} \scan_stop:
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1
+ {
+ \tex_global:D
+ \tex_pdfminorversion:D
+ \int_eval:n {#1} \scan_stop:
+ }
+\cs_new:Npe \__pdf_backend_version_major:
+ {
+ \cs_if_exist:NTF \tex_pdfmajorversion:D
+ { \exp_not:N \tex_the:D \tex_pdfmajorversion:D }
+ { 1 }
+ }
+\cs_new:Npn \__pdf_backend_version_minor:
+ {
+ \tex_the:D
+ \tex_pdfminorversion:D
+ }
+\cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \__pdf_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+\cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2
+ {
+ \dim_gset:Nn \tex_pagewidth:D {#1}
+ \dim_gset:Nn \tex_pageheight:D {#2}
+ }
+%% File: l3backend-opacity.dtx
+\bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \__kernel_color_backend_stack_init:Nnn \c__opacity_backend_stack_int
+ { page ~ direct } { /opacity 1 ~ gs }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity 1 } { << /ca ~ 1 /CA ~ 1 >> }
+ }
+\tl_new:N \l__opacity_backend_fill_tl
+\tl_new:N \l__opacity_backend_stroke_tl
+\tl_set:Nn \l__opacity_backend_fill_tl { 1 }
+\tl_set:Nn \l__opacity_backend_stroke_tl { 1 }
+\cs_new_protected:Npn \__opacity_backend_select:n #1
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#1}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity #1 }
+ { << /ca ~ #1 /CA ~ #1 >> }
+ \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
+ { /opacity #1 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+\cs_new_protected:Npn \__opacity_backend_reset:
+ {
+ \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int
+ }
+\cs_new_protected:Npn \__opacity_backend_fill:n #1
+ {
+ \exp_args:Nno \__opacity_backend_fill_stroke:nn
+ { #1 }
+ { \l__opacity_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \__opacity_backend_stroke:n #1
+ {
+ \exp_args:No \__opacity_backend_fill_stroke:nn
+ { \l__opacity_backend_fill_tl }
+ { #1 }
+ }
+\cs_new_protected:Npn \__opacity_backend_fill_stroke:nn #1#2
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \__opacity_backend_select:n {#1} }
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#2}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.fill #1 }
+ { << /ca ~ #1 >> }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.stroke #2 }
+ { << /CA ~ #2 >> }
+ \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
+ { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+ }
+\bool_lazy_and:nnF
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \cs_gset_protected:Npn \__opacity_backend_select:n #1 { }
+ \cs_gset_protected:Npn \__opacity_backend_fill_stroke:nn #1#2 { }
+ }
+%%
+%%
+%% End of file `l3backend-pdftex.def'.
diff --git a/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-xetex.def b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-xetex.def
new file mode 100644
index 00000000000..e05725885ca
--- /dev/null
+++ b/Master/texmf-dist/tex/latex-dev/l3backend/l3backend-xetex.def
@@ -0,0 +1,906 @@
+%%
+%% This is file `l3backend-xetex.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3backend-basics.dtx (with options: `package,xetex')
+%% l3backend-color.dtx (with options: `package,xetex')
+%% l3backend-box.dtx (with options: `package,xetex')
+%% l3backend-draw.dtx (with options: `package,xetex')
+%% l3backend-graphics.dtx (with options: `package,xetex')
+%% l3backend-pdf.dtx (with options: `package,xetex')
+%% l3backend-opacity.dtx (with options: `package,xetex')
+%%
+%% Copyright (C) 2019-2024 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.
+%%
+%% File: l3backend-basics.dtx
+\ProvidesExplFile
+ {l3backend-xetex.def}{2024-04-11}{}
+ {L3 backend support: XeTeX}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+ {l3backend-xetex.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ { \__kernel_backend_literal:n { pdf:literal~ #1 } }
+\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+\cs_new_protected:Npn \__kernel_backend_literal_page:n #1
+ { \__kernel_backend_literal:n { pdf:literal~direct~ #1 } }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ { \__kernel_backend_literal:n { x:gsave } }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ { \__kernel_backend_literal:n { x:grestore } }
+%% File: l3backend-color.dtx
+\cs_new_protected:Npn \__color_backend_select:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ [ #1 ] } }
+\cs_new_eq:NN \__color_backend_select_cmyk:n \__color_backend_select:n
+\cs_new_eq:NN \__color_backend_select_gray:n \__color_backend_select:n
+\cs_new_eq:NN \__color_backend_select_rgb:n \__color_backend_select:n
+\cs_new_protected:Npn \__color_backend_reset:
+ { \__kernel_backend_literal:n { pdf : ec } }
+\cs_new_protected:Npn \__color_backend_select_named:n #1
+ {
+ \str_if_eq:nnTF {#1} { Black }
+ { \__color_backend_select_gray:n { 0 } }
+ { \msg_error:nnn { color } { unknown-named-color } {#1} }
+ }
+\msg_new:nnn { color } { unknown-named-color }
+ { Named~color~'#1'~is~not~known. }
+\prop_new:N \g__color_backend_colorant_prop
+\cs_new:Npe \__color_backend_devicen_colorants:n #1
+ {
+ \exp_not:N \tl_if_blank:nF {#1}
+ {
+ \c_space_tl
+ << ~
+ /Colorants ~
+ << ~
+ \exp_not:N \__color_backend_devicen_colorants:w #1 ~
+ \exp_not:N \q_recursion_tail \c_space_tl
+ \exp_not:N \q_recursion_stop
+ >> ~
+ >>
+ }
+ }
+\cs_new:Npn \__color_backend_devicen_colorants:w #1 ~
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \prop_if_in:NnT \g__color_backend_colorant_prop {#1}
+ {
+ #1 ~
+ \prop_item:Nn \g__color_backend_colorant_prop {#1} ~
+ }
+ \__color_backend_devicen_colorants:w
+ }
+\cs_new_protected:Npn \__color_backend_select_separation:nn #1#2
+ { \__kernel_backend_literal:e { pdf : bc ~ \pdf_object_ref:n {#1} ~ [ #2 ] } }
+\cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
+\cs_new_eq:NN \__color_backend_select_iccbased:nn \__color_backend_select_separation:nn
+\cs_new_protected:Npn \__color_backend_init_resource:n #1
+ {
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \pdf_object_unnamed_write:ne { dict }
+ {
+ /FunctionType ~ 2
+ /Domain ~ [0 ~ 1]
+ \tl_if_blank:nF {#3} { /Range ~ [#3] }
+ /C0 ~ [#4] ~
+ /C1 ~ [#5] /N ~ 1
+ }
+ \exp_args:Ne \__color_backend_separation_init:nn
+ { \str_convert_pdfname:n {#1} } {#2}
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init:nn #1#2
+ {
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ { /Separation /#1 ~ #2 ~ \pdf_object_ref_last: }
+ }
+ \prop_gput:Nne \g__color_backend_colorant_prop { /#1 }
+ { \pdf_object_ref_last: }
+ }
+\cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_illuminant_CIELAB_ #1 }
+ {
+ \pdf_object_new:n { __color_illuminant_CIELAB_ #1 }
+ \pdf_object_write:nne { __color_illuminant_CIELAB_ #1 } { array }
+ {
+ /Lab ~
+ <<
+ /WhitePoint ~
+ [ \tl_use:c { c__color_model_whitepoint_CIELAB_ #1 _tl } ]
+ /Range ~ [ \c__color_model_range_CIELAB_tl ]
+ >>
+ }
+ }
+ \__color_backend_separation_init:nnnnn
+ {#2}
+ { \pdf_object_ref:n { __color_illuminant_CIELAB_ #1 } }
+ { \c__color_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+\cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
+ {
+ \pdf_object_unnamed_write:ne { stream }
+ {
+ {
+ /FunctionType ~ 4 ~
+ /Domain ~
+ [ ~
+ \prg_replicate:nn
+ { 0 \__color_backend_devicen_init:w #1 ~ \s__color_stop }
+ { 0 ~ 1 ~ }
+ ] ~
+ /Range ~
+ [ ~
+ \str_case:nn {#2}
+ {
+ { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ { /DeviceGray } { 0 ~ 1 }
+ { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ } ~
+ ]
+ }
+ { {#3} }
+ }
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g__color_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g__color_model_int } { array }
+ {
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ \pdf_object_ref_last:
+ \__color_backend_devicen_colorants:n {#1}
+ }
+ }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
+ {
+ + 1
+ \tl_if_blank:nF {#2}
+ { \__color_backend_devicen_init:w #2 \s__color_stop }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_init:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nne { __color_icc_ #1 } { fstream }
+ {
+ {
+ /N ~ \exp_not:n { #2 } ~
+ \tl_if_empty:nF { #3 } { /Range~[ #3 ] }
+ }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { color \int_use:N \g__color_model_int }
+ }
+\cs_new_protected:Npn \__color_backend_iccbased_device:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { __color_icc_ #1 }
+ {
+ \pdf_object_new:n { __color_icc_ #1 }
+ \pdf_object_write:nnn { __color_icc_ #1 } { fstream }
+ {
+ { /N ~ #3 }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { __color_icc_ #1 } }
+ \__color_backend_init_resource:n { Default #2 }
+ }
+\cs_new_protected:Npn \__color_backend_fill:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ fill ~ [ #1 ] } }
+\cs_new_eq:NN \__color_backend_fill_cmyk:n \__color_backend_fill:n
+\cs_new_eq:NN \__color_backend_fill_gray:n \__color_backend_fill:n
+\cs_new_eq:NN \__color_backend_fill_rgb:n \__color_backend_fill:n
+\cs_new_protected:Npn \__color_backend_stroke:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ stroke ~ [ #1 ] } }
+\cs_new_eq:NN \__color_backend_stroke_cmyk:n \__color_backend_stroke:n
+\cs_new_eq:NN \__color_backend_stroke_gray:n \__color_backend_stroke:n
+\cs_new_eq:NN \__color_backend_stroke_rgb:n \__color_backend_stroke:n
+\cs_new_protected:Npn \__color_backend_fill_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ fill ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_protected:Npn \__color_backend_stroke_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ stroke ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_eq:NN \__color_backend_fill_devicen:nn \__color_backend_fill_separation:nn
+\cs_new_eq:NN \__color_backend_stroke_devicen:nn \__color_backend_stroke_separation:nn
+\cs_new_eq:NN \__color_backend_fill_reset: \__color_backend_reset:
+\cs_new_eq:NN \__color_backend_stroke_reset: \__color_backend_reset:
+%% File: l3backend-box.dtx
+\cs_new_protected:Npn \__box_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+\cs_new_protected:Npn \__box_backend_rotate:Nn #1#2
+ { \exp_args:NNf \__box_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \__box_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#2} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( #2 , 5 ) } }
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\cs_new_protected:Npn \__box_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+%% 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_protected:Npn \__draw_backend_begin:
+ { \__draw_backend_scope_begin: }
+\cs_new_protected:Npn \__draw_backend_end:
+ { \__draw_backend_scope_end: }
+\cs_new_eq:NN \__draw_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \__draw_backend_scope_end: \__kernel_backend_scope_end:
+\cs_new_protected:Npn \__draw_backend_moveto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
+ }
+\cs_new_protected:Npn \__draw_backend_lineto:nn #1#2
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
+ }
+\cs_new_protected:Npn \__draw_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ c
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_rectangle:nnnn #1#2#3#4
+ {
+ \__draw_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ re
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_evenodd_rule:
+ { \bool_gset_true:N \g__draw_draw_eor_bool }
+\cs_new_protected:Npn \__draw_backend_nonzero_rule:
+ { \bool_gset_false:N \g__draw_draw_eor_bool }
+\bool_new:N \g__draw_draw_eor_bool
+\cs_new_protected:Npn \__draw_backend_closepath:
+ { \__draw_backend_literal:n { h } }
+\cs_new_protected:Npn \__draw_backend_stroke:
+ { \__draw_backend_literal:n { S } }
+\cs_new_protected:Npn \__draw_backend_closestroke:
+ { \__draw_backend_literal:n { s } }
+\cs_new_protected:Npn \__draw_backend_fill:
+ {
+ \__draw_backend_literal:e
+ { f \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_fillstroke:
+ {
+ \__draw_backend_literal:e
+ { B \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_clip:
+ {
+ \__draw_backend_literal:e
+ { W \bool_if:NT \g__draw_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \__draw_backend_discardpath:
+ { \__draw_backend_literal:n { n } }
+\cs_new_protected:Npn \__draw_backend_dash_pattern:nn #1#2
+ {
+ \__draw_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \__draw_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ d
+ }
+ }
+\cs_new:Npn \__draw_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \__draw_backend_linewidth:n #1
+ {
+ \__draw_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ w }
+ }
+\cs_new_protected:Npn \__draw_backend_miterlimit:n #1
+ { \__draw_backend_literal:e { #1 ~ M } }
+\cs_new_protected:Npn \__draw_backend_cap_butt:
+ { \__draw_backend_literal:n { 0 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_round:
+ { \__draw_backend_literal:n { 1 ~ J } }
+\cs_new_protected:Npn \__draw_backend_cap_rectangle:
+ { \__draw_backend_literal:n { 2 ~ J } }
+\cs_new_protected:Npn \__draw_backend_join_miter:
+ { \__draw_backend_literal:n { 0 ~ j } }
+\cs_new_protected:Npn \__draw_backend_join_round:
+ { \__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
+ {
+ \__draw_backend_cm_decompose:nnnnN {#1} {#2} {#3} {#4}
+ \__draw_backend_cm_aux:nnnn
+ }
+\cs_new_protected:Npn \__draw_backend_cm_aux:nnnn #1#2#3#4
+ {
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#1} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#1 , 5 ) } }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#4} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#4 , 5 ) } }
+ }
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \__draw_backend_cm_decompose_auxi:nnnnN
+ { \fp_eval:n { (#1 + #4) / 2 } }
+ { \fp_eval:n { (#1 - #4) / 2 } }
+ { \fp_eval:n { (#3 + #2) / 2 } }
+ { \fp_eval:n { (#3 - #2) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \__draw_backend_cm_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 ) } }
+ { \fp_eval:n { atand ( #4 , #1 ) } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \__draw_backend_cm_decompose_auxiii:nnnnN
+ { \fp_eval:n { ( #4 - #3 ) / 2 } }
+ { \fp_eval:n { ( #1 + #2 ) / 2 } }
+ { \fp_eval:n { ( #1 - #2 ) / 2 } }
+ { \fp_eval:n { ( #4 + #3 ) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \__draw_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
+ {
+ \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
+ { #5 {#1} {#2} {#3} {#4} }
+ { #5 {#1} {#3} {#2} {#4} }
+ }
+\cs_new_protected:Npn \__draw_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:n
+ { pdf:btrans~matrix~ #2 ~ #3 ~ #4 ~ #5 ~ 0 ~ 0 }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_literal:n { pdf:etrans }
+ \__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
+ }
+\int_new:N \g__graphics_track_int
+\cs_new_protected:Npn \__graphics_backend_include_eps:n #1
+ {
+ \__kernel_backend_literal:e
+ {
+ PSfile = #1 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l__graphics_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l__graphics_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l__graphics_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l__graphics_ury_dim
+ }
+ }
+\cs_new_eq:NN \__graphics_backend_include_ps:n \__graphics_backend_include_eps:n
+\cs_new_protected:Npn \__graphics_backend_include_jpg:n #1
+ { \__graphics_backend_include_auxi:nn {#1} { image } }
+\cs_new_eq:NN \__graphics_backend_include_jpeg:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_png:n \__graphics_backend_include_jpg:n
+\cs_new_eq:NN \__graphics_backend_include_bmp:n \__graphics_backend_include_jpg:n
+\cs_new_protected:Npn \__graphics_backend_include_auxi:nn #1#2
+ {
+ \__graphics_backend_include_auxii:enn
+ {
+ \tl_if_empty:NF \l__graphics_pagebox_tl
+ { : \l__graphics_pagebox_tl }
+ \int_compare:nNnT \l__graphics_page_int > 1
+ { :P \int_use:N \l__graphics_page_int }
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { :D \l__graphics_decodearray_str }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { :I }
+ }
+ {#1} {#2}
+ }
+\cs_new_protected:Npn \__graphics_backend_include_auxii:nnn #1#2#3
+ {
+ \int_if_exist:cTF { c__graphics_ #2#1 _int }
+ {
+ \__kernel_backend_literal:e
+ { pdf:usexobj~@graphic \int_use:c { c__graphics_ #2#1 _int } }
+ }
+ { \__graphics_backend_include_auxiii:nnn {#2} {#1} {#3} }
+ }
+\cs_generate_variant:Nn \__graphics_backend_include_auxii:nnn { e }
+\cs_new_protected:Npn \__graphics_backend_include_auxiii:nnn #1#2#3
+ {
+ \int_gincr:N \g__graphics_track_int
+ \int_const:cn { c__graphics_ #1#2 _int } { \g__graphics_track_int }
+ \__kernel_backend_literal:e
+ {
+ pdf:#3~
+ @graphic \int_use:c { c__graphics_ #1#2 _int } ~
+ \int_compare:nNnT \l__graphics_page_int > 1
+ { page ~ \int_use:N \l__graphics_page_int \c_space_tl }
+ \tl_if_empty:NF \l__graphics_pagebox_tl
+ {
+ pagebox ~ \l__graphics_pagebox_tl \c_space_tl
+ bbox ~
+ \dim_to_decimal_in_bp:n \l__graphics_llx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l__graphics_lly_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l__graphics_urx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l__graphics_ury_dim \c_space_tl
+ }
+ (#1)
+ \bool_lazy_or:nnT
+ { \l__graphics_interpolate_bool }
+ { ! \tl_if_empty_p:N \l__graphics_decodearray_str }
+ {
+ <<
+ \tl_if_empty:NF \l__graphics_decodearray_str
+ { /Decode~[ \l__graphics_decodearray_str ] }
+ \bool_if:NT \l__graphics_interpolate_bool
+ { /Interpolate~true }
+ >>
+ }
+ }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l__graphics_page_int
+ \tl_clear:N \l__graphics_pagebox_tl
+ \__graphics_backend_getbb_auxi:nN {#1} \tex_XeTeXpicfile:D
+ }
+\cs_new_eq:NN \__graphics_backend_getbb_jpeg:n \__graphics_backend_getbb_jpg:n
+\cs_new_eq:NN \__graphics_backend_getbb_png:n \__graphics_backend_getbb_jpg:n
+\cs_new_eq:NN \__graphics_backend_getbb_bmp:n \__graphics_backend_getbb_jpg:n
+\cs_new_protected:Npn \__graphics_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l__graphics_decodearray_str
+ \bool_set_false:N \l__graphics_interpolate_bool
+ \__graphics_backend_getbb_auxi:nN {#1} \tex_XeTeXpdffile:D
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxi:nN #1#2
+ {
+ \int_compare:nNnTF \l__graphics_page_int > 1
+ { \__graphics_backend_getbb_auxii:VnN \l__graphics_page_int {#1} #2 }
+ { \__graphics_backend_getbb_auxiii:nNnn {#1} #2 { :P 1 } { page 1 } }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxii:nnN #1#2#3
+ { \__graphics_backend_getbb_auxiii:nNnn {#2} #3 { :P #1 } { page #1 } }
+\cs_generate_variant:Nn \__graphics_backend_getbb_auxii:nnN { V }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxiii:nNnn #1#2#3#4
+ {
+ \tl_if_empty:NTF \l__graphics_pagebox_tl
+ { \__graphics_backend_getbb_auxiv:VnNnn \l__graphics_pagebox_tl }
+ { \__graphics_backend_getbb_auxv:nNnn }
+ {#1} #2 {#3} {#4}
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxiv:nnNnn #1#2#3#4#5
+ {
+ \use:e
+ {
+ \__graphics_backend_getbb_auxv:nNnn {#2} #3 { : #1 #4 }
+ {
+ #5
+ \tl_if_blank:nF {#1}
+ { \c_space_tl \__graphics_backend_getbb_pagebox:w #1 }
+ }
+ }
+ }
+\cs_generate_variant:Nn \__graphics_backend_getbb_auxiv:nnNnn { V }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxv:nNnn #1#2#3#4
+ {
+ \__graphics_bb_restore:nF {#1#3}
+ { \__graphics_backend_getbb_auxvi:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new_protected:Npn \__graphics_backend_getbb_auxvi:nNnn #1#2#3#4
+ {
+ \hbox_set:Nn \l__graphics_internal_box { #2 #1 ~ #4 }
+ \dim_set:Nn \l__graphics_urx_dim { \box_wd:N \l__graphics_internal_box }
+ \dim_set:Nn \l__graphics_ury_dim { \box_ht:N \l__graphics_internal_box }
+ \__graphics_bb_save:n {#1#3}
+ }
+\cs_new:Npn \__graphics_backend_getbb_pagebox:w #1 box {#1}
+\cs_new_protected:Npn \__graphics_backend_include_pdf:n #1
+ {
+ \tex_XeTeXpdffile:D #1 ~
+ \int_compare:nNnT \l__graphics_page_int > 0
+ { page ~ \int_use:N \l__graphics_page_int \c_space_tl }
+ \exp_after:wN \__graphics_backend_getbb_pagebox:w \l__graphics_pagebox_tl
+ }
+\cs_new_protected:Npn \__graphics_backend_get_pagecount:n #1
+ {
+ \int_const:cn { c__graphics_ #1 _pages_int }
+ {
+ \int_max:nn
+ { \int_use:N \tex_XeTeXpdfpagecount:D #1 ~ }
+ { 1 }
+ }
+ }
+%% 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 }
+\cs_new_protected:Npn \__pdf_backend_catalog_gput:nn #1#2
+ { \__pdf_backend:n { put ~ @catalog << /#1 ~ #2 >> } }
+\cs_new_protected:Npn \__pdf_backend_info_gput:nn #1#2
+ { \__pdf_backend:n { docinfo << /#1 ~ #2 >> } }
+\prop_new:N \g__pdf_backend_object_prop
+\cs_new_protected:Npn \__pdf_backend_object_new:
+ { \int_gincr:N \g__pdf_backend_object_int }
+\cs_new:Npn \__pdf_backend_object_ref:n #1 { @pdf.obj #1 }
+\cs_new_eq:NN \__pdf_backend_object_id:n \__pdf_backend_object_ref:n
+\cs_new_protected:Npn \__pdf_backend_object_write:nnn #1#2#3
+ {
+ \use:c { __pdf_backend_object_write_ #2 :nn }
+ { \__pdf_backend_object_ref:n {#1} } {#3}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_write:nnn { nne }
+\cs_new_protected:Npn \__pdf_backend_object_write_array:nn #1#2
+ {
+ \__pdf_backend:e
+ { obj ~ #1 ~ [ ~ \exp_not:n {#2} ~ ] }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_dict:nn #1#2
+ {
+ \__pdf_backend:e
+ { obj ~ #1 ~ << ~ \exp_not:n {#2} ~ >> }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_write_fstream:nn #1#2
+ { \__pdf_backend_object_write_stream:nnnn { f } {#1} #2 }
+\cs_new_protected:Npn \__pdf_backend_object_write_stream:nn #1#2
+ { \__pdf_backend_object_write_stream:nnnn { } {#1} #2 }
+\cs_new_protected:Npn \__pdf_backend_object_write_stream:nnnn #1#2#3#4
+ {
+ \__pdf_backend:e
+ {
+ #1 stream ~ #2 ~
+ ( \exp_not:n {#4} ) ~ << \exp_not:n {#3} >>
+ }
+ }
+\cs_new_protected:Npn \__pdf_backend_object_now:nn #1#2
+ {
+ \int_gincr:N \g__pdf_backend_object_int
+ \exp_args:Nne \use:c { __pdf_backend_object_write_ #1 :nn }
+ { @pdf.obj \int_use:N \g__pdf_backend_object_int }
+ {#2}
+ }
+\cs_generate_variant:Nn \__pdf_backend_object_now:nn { ne }
+\cs_new:Npn \__pdf_backend_object_last:
+ { @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
+ {
+ dest ~ ( \exp_not:n {#1} )
+ [
+ @thispage
+ \str_case:nnF {#2}
+ {
+ { xyz } { /XYZ ~ @xpos ~ @ypos ~ null }
+ { fit } { /Fit }
+ { fitb } { /FitB }
+ { fitbh } { /FitBH }
+ { fitbv } { /FitBV ~ @xpos }
+ { fith } { /FitH ~ @ypos }
+ { fitv } { /FitV ~ @xpos }
+ { fitr } { /Fit }
+ }
+ { /XYZ ~ @xpos ~ @ypos ~ \fp_eval:n { (#2) / 100 } }
+ ]
+ }
+ }
+\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
+ {
+ \__pdf_backend:n { obj ~ @pdf_ #2 _llx ~ @xpos }
+ \__pdf_backend:n { obj ~ @pdf_ #2 _lly ~ @ypos }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n {#1}
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n { -#3 }
+ \hbox:n
+ {
+ \__pdf_backend:n
+ {
+ dest ~ (#2)
+ [
+ @thispage
+ /FitR ~
+ @pdf_ #2 _llx ~ @pdf_ #2 _lly ~
+ @xpos ~ @ypos
+ ]
+ }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n { -#1 }
+ }
+\cs_new_protected:Npn \__pdf_backend_compresslevel:n #1
+ { \__kernel_backend_literal:e { dvipdfmx:config~z~ \int_eval:n {#1} } }
+\cs_new_protected:Npn \__pdf_backend_compress_objects:n #1
+ {
+ \bool_if:nF {#1}
+ { \__kernel_backend_literal:n { dvipdfmx:config~C~0x40 } }
+ }
+\cs_new_protected:Npn \__pdf_backend_version_major_gset:n #1
+ {
+ \cs_gset:Npe \__pdf_backend_version_major: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:majorversion~ \__pdf_backend_version_major: }
+ }
+\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1
+ {
+ \cs_gset:Npe \__pdf_backend_version_minor: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:minorversion~ \__pdf_backend_version_minor: }
+ }
+\cs_new:Npn \__pdf_backend_version_major: { 1 }
+\cs_new:Npn \__pdf_backend_version_minor: { 5 }
+\cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \__pdf_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+\cs_new_protected:Npn \__pdf_backend_pagesize_gset:nn #1#2
+ {
+ \dim_gset:Nn \tex_pagewidth:D {#1}
+ \dim_gset:Nn \tex_pageheight:D {#2}
+ }
+%% File: l3backend-opacity.dtx
+\bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity 1 } { << /ca ~ 1 /CA ~ 1 >> }
+ }
+\tl_new:N \l__opacity_backend_fill_tl
+\tl_new:N \l__opacity_backend_stroke_tl
+\tl_set:Nn \l__opacity_backend_fill_tl { 1 }
+\tl_set:Nn \l__opacity_backend_stroke_tl { 1 }
+\cs_new_protected:Npn \__opacity_backend_select:n #1
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#1}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity #1 }
+ { << /ca ~ #1 /CA ~ #1 >> }
+ \__kernel_backend_literal_pdf:n
+ { /opacity #1 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+\cs_new_protected:Npn \__opacity_backend_reset:
+ {
+ \__kernel_backend_literal_pdf:n
+ { /opacity1 ~ gs }
+ }
+\cs_new_protected:Npn \__opacity_backend_fill:n #1
+ {
+ \exp_args:Nno \__opacity_backend_fill_stroke:nn
+ { #1 }
+ { \l__opacity_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \__opacity_backend_stroke:n #1
+ {
+ \exp_args:No \__opacity_backend_fill_stroke:nn
+ { \l__opacity_backend_fill_tl }
+ { #1 }
+ }
+\cs_new_protected:Npn \__opacity_backend_fill_stroke:nn #1#2
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \__opacity_backend_select:n {#1} }
+ {
+ \tl_set:Nn \l__opacity_backend_fill_tl {#1}
+ \tl_set:Nn \l__opacity_backend_stroke_tl {#2}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.fill #1 }
+ { << /ca ~ #1 >> }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.stroke #2 }
+ { << /CA ~ #2 >> }
+ \__kernel_backend_literal_pdf:n
+ { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
+ \group_insert_after:N \__opacity_backend_reset:
+ }
+ }
+\bool_lazy_and:nnF
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \cs_gset_protected:Npn \__opacity_backend_select:n #1 { }
+ \cs_gset_protected:Npn \__opacity_backend_fill_stroke:nn #1#2 { }
+ }
+%%
+%%
+%% End of file `l3backend-xetex.def'.
diff --git a/Master/tlpkg/tlpsrc/l3backend-dev.tlpsrc b/Master/tlpkg/tlpsrc/l3backend-dev.tlpsrc
new file mode 100644
index 00000000000..cc23539bf28
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/l3backend-dev.tlpsrc
@@ -0,0 +1,3 @@
+runpattern d texmf-dist/tex/latex-dev/l3backend
+srcpattern d texmf-dist/source/latex-dev/l3backend
+docpattern d texmf-dist/doc/latex-dev/l3backend