diff options
Diffstat (limited to 'macros/latex/contrib/l3backend')
-rw-r--r-- | macros/latex/contrib/l3backend/CHANGELOG.md | 393 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/README.md | 16 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-basics.dtx | 497 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-box.dtx | 470 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-code.pdf | bin | 908163 -> 0 bytes | |||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-code.tex | 63 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-color.dtx | 1356 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-draw.dtx | 1067 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-graphics.dtx | 931 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-header.dtx | 590 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-opacity.dtx | 353 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-pdf.dtx | 1775 | ||||
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend.ins | 168 |
13 files changed, 0 insertions, 7679 deletions
diff --git a/macros/latex/contrib/l3backend/CHANGELOG.md b/macros/latex/contrib/l3backend/CHANGELOG.md deleted file mode 100644 index 66a69a3bb3..0000000000 --- a/macros/latex/contrib/l3backend/CHANGELOG.md +++ /dev/null @@ -1,393 +0,0 @@ -# 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-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-03-14...HEAD -[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/macros/latex/contrib/l3backend/README.md b/macros/latex/contrib/l3backend/README.md deleted file mode 100644 index 7be33df8b8..0000000000 --- a/macros/latex/contrib/l3backend/README.md +++ /dev/null @@ -1,16 +0,0 @@ -LaTeX3 Backend Drivers -====================== - -Release 2024-03-14 - -This package forms parts of `expl3`, and contains the code used to interface -with backends (drivers) across the `expl3` codebase. The functions here are -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/macros/latex/contrib/l3backend/l3backend-basics.dtx b/macros/latex/contrib/l3backend/l3backend-basics.dtx deleted file mode 100644 index 4d3b68225a..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-basics.dtx +++ /dev/null @@ -1,497 +0,0 @@ -% \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-03-14} -% -% \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-03-14}{} - {L3 backend support: dvipdfmx} -%</dvipdfmx> -%<*dvips> - {l3backend-dvips.def}{2024-03-14}{} - {L3 backend support: dvips} -%</dvips> -%<*dvisvgm> - {l3backend-dvisvgm.def}{2024-03-14}{} - {L3 backend support: dvisvgm} -%</dvisvgm> -%<*luatex> - {l3backend-luatex.def}{2024-03-14}{} - {L3 backend support: PDF output (LuaTeX)} -%</luatex> -%<*pdftex> - {l3backend-pdftex.def}{2024-03-14}{} - {L3 backend support: PDF output (pdfTeX)} -%</pdftex> -%<*xetex> - {l3backend-xetex.def}{2024-03-14}{} - {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/macros/latex/contrib/l3backend/l3backend-box.dtx b/macros/latex/contrib/l3backend/l3backend-box.dtx deleted file mode 100644 index 3fc3243c42..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-box.dtx +++ /dev/null @@ -1,470 +0,0 @@ -% \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-03-14} -% -% \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/macros/latex/contrib/l3backend/l3backend-code.pdf b/macros/latex/contrib/l3backend/l3backend-code.pdf Binary files differdeleted file mode 100644 index 9affc7d856..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-code.pdf +++ /dev/null diff --git a/macros/latex/contrib/l3backend/l3backend-code.tex b/macros/latex/contrib/l3backend/l3backend-code.tex deleted file mode 100644 index df0dd0ea8c..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-code.tex +++ /dev/null @@ -1,63 +0,0 @@ -\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/macros/latex/contrib/l3backend/l3backend-color.dtx b/macros/latex/contrib/l3backend/l3backend-color.dtx deleted file mode 100644 index eaa89add8c..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-color.dtx +++ /dev/null @@ -1,1356 +0,0 @@ -% \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-03-14} -% -% \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/macros/latex/contrib/l3backend/l3backend-draw.dtx b/macros/latex/contrib/l3backend/l3backend-draw.dtx deleted file mode 100644 index eef86886f5..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-draw.dtx +++ /dev/null @@ -1,1067 +0,0 @@ -% \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-03-14} -% -% \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/macros/latex/contrib/l3backend/l3backend-graphics.dtx b/macros/latex/contrib/l3backend/l3backend-graphics.dtx deleted file mode 100644 index 9360bffd2e..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-graphics.dtx +++ /dev/null @@ -1,931 +0,0 @@ -% \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-03-14} -% -% \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/macros/latex/contrib/l3backend/l3backend-header.dtx b/macros/latex/contrib/l3backend/l3backend-header.dtx deleted file mode 100644 index 84f8ab53b7..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-header.dtx +++ /dev/null @@ -1,590 +0,0 @@ -% \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-03-14} -% -% \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/macros/latex/contrib/l3backend/l3backend-opacity.dtx b/macros/latex/contrib/l3backend/l3backend-opacity.dtx deleted file mode 100644 index a5828bfd90..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-opacity.dtx +++ /dev/null @@ -1,353 +0,0 @@ -% \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-03-14} -% -% \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/macros/latex/contrib/l3backend/l3backend-pdf.dtx b/macros/latex/contrib/l3backend/l3backend-pdf.dtx deleted file mode 100644 index 0a16a79f9e..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-pdf.dtx +++ /dev/null @@ -1,1775 +0,0 @@ -% \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-03-14} -% -% \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{variable}{\g_@@_backend_object_int} -% For tracking objects. -% \begin{macrocode} -\int_new:N \g_@@_backend_object_int -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_backend_object_new:n} -% \begin{macro}[EXP]{\@@_backend_object_ref:n} -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_object_new:n #1 - { - \int_gincr:N \g_@@_backend_object_int - \int_const:cn - { c_@@_object_ \tl_to_str:n {#1} _int } - { \g_@@_backend_object_int } - } -\cs_new:Npn \@@_backend_object_ref:n #1 - { { pdf.obj \int_use:c { c_@@_object_ \tl_to_str:n {#1} _int } } } -% \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:n} -% \begin{macro}[EXP]{\@@_backend_object_ref:n} -% Declaring objects means reserving at the PDF level plus starting -% tracking. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_object_new:n #1 - { -%<*luatex> - \tex_pdfextension:D obj ~ -%</luatex> -%<*pdftex> - \tex_pdfobj:D -%</pdftex> - reserveobjnum ~ - \int_const:cn - { c_@@_object_ \tl_to_str:n {#1} _int } -%<*luatex> - { \tex_pdffeedback:D lastobj } -%</luatex> -%<*pdftex> - { \tex_pdflastobj:D } -%</pdftex> - } -\cs_new:Npn \@@_backend_object_ref:n #1 - { \int_use:c { c_@@_object_ \tl_to_str:n {#1} _int } ~ 0 ~ R } -% \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 ~ - \int_use:c - { c_@@_object_ \tl_to_str:n {#1} _int } - \@@_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_int, \g_@@_backend_object_prop} -% For tracking objects to allow finalisation. -% \begin{macrocode} -\int_new:N \g_@@_backend_object_int -\prop_new:N \g_@@_backend_object_prop -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_backend_object_new:n} -% \begin{macro}[EXP]{\@@_backend_object_ref: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:n #1 - { - \int_gincr:N \g_@@_backend_object_int - \int_const:cn - { c_@@_object_ \tl_to_str:n {#1} _int } - { \g_@@_backend_object_int } - } -\cs_new:Npn \@@_backend_object_ref:n #1 - { @pdf.obj \int_use:c { c_@@_object_ \tl_to_str:n {#1} _int } } -% \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:n} -% \begin{macro}[EXP]{\@@_backend_object_ref: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:nn #1 { } -\cs_new:Npn \@@_backend_object_ref: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/macros/latex/contrib/l3backend/l3backend.ins b/macros/latex/contrib/l3backend/l3backend.ins deleted file mode 100644 index e24c41d236..0000000000 --- a/macros/latex/contrib/l3backend/l3backend.ins +++ /dev/null @@ -1,168 +0,0 @@ -\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 |