% \iffalse meta-comment
%
%% File: l3drivers.dtx
%
% Copyright (C) 2011-2019 The LaTeX3 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 "l3kernel 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 \textsf{l3drivers} package\\ Drivers^^A
% }
%
% \author{^^A
%  The \LaTeX3 Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released 2019-05-09}
%
% \maketitle
%
% \begin{documentation}
%
% \TeX{} relies on drivers in order to carry out a number of tasks, such
% as using color, including graphics and setting up hyper-links. The nature
% of the code required depends on the exact driver in use. Currently,
% \LaTeX3 is aware of the following drivers:
% \begin{itemize}
%   \item \texttt{pdfmode}:  The \enquote{driver} for direct PDF output by
%     \emph{both} \pdfTeX{} and \LuaTeX{} (no separate driver is used in this
%     case: the engine deals with PDF creation itself).
%   \item \texttt{dvips}: The \texttt{dvips} program, which works in
%     conjugation with \pdfTeX{} or \LuaTeX{} in DVI mode.
%   \item \texttt{dvipdfmx}: The \texttt{dvipdfmx} program, which works in
%     conjugation with \pdfTeX{} or \LuaTeX{} in DVI mode.
%   \item \texttt{dvisvgm}:  The \texttt{dvisvgm} program, which works in
%     conjugation with \pdfTeX{} or \LuaTeX{} when run in DVI mode as well
%     as with (u)\pTeX{} and \XeTeX{}.
%   \item \texttt{xdvipdfmx}: The driver used by \XeTeX{}.
% \end{itemize}
%
% This module provides code closely tied to the exact driver in use: broadly,
% the functions here are implemented entirely independently for each case.
% As such, they often rely on higher-level code to provide necessary but
% shared operations. For example, in box rotation and scaling the functions
% here do no correct the final size of the box: this will always be required
% and thus is handled in the \pkg{box} module.
%
% Several of the operations here are low-level, and so may be used only in
% restricted contexts. Some also require understanding of PostScript/PDF
% concepts to be used corrected as they take \enquote{raw} arguments, similar
% in format to those used by the underlying driver.
%
% Given the close coupling of these functions to higher-level interfaces, at
% present the functions given here may change if this is useful for higher-level
% changes. However, equivalent \emph{functionality} will be provided for any
% higher-level function which is itself stable. For example,
% \cs{driver_box_use_rotate:Nn} is needed to implement the stable box rotation
% functions. As such, even if \cs{driver_box_use_rotate:Nn} were to be removed,
% a replacement would be provided.
%
% \section{Box clipping}
%
% \begin{function}[added = 2017-12-13]{\driver_box_use_clip:N}
%   \begin{syntax}
%     \cs{driver_box_use_clip:N} \meta{box}
%   \end{syntax}
%   Inserts the content of the \meta{box} at the current insertion point
%   such that any material outside of the bounding box is not displayed
%   by the driver. The material in the \meta{box} is still placed in the
%   output stream: the clipping takes place at a driver level.
% \end{function}
%
% \section{Box rotation and scaling}
%
% \begin{function}[added = 2017-12-13, updated = 2018-04-26]
%   {\driver_box_use_rotate:Nn}
%   \begin{syntax}
%     \cs{driver_box_use_rotate:Nn} \meta{box} \Arg{angle}
%   \end{syntax}
%   Inserts the content of the \meta{box} at the current insertion point
%   rotated by the \meta{angle} (an \meta{fp expression} expressed in degrees).
%   The material is
%   rotated such the the \TeX{} reference point of the box is the center of
%   rotation and remains the reference point after rotation. It is the
%   responsibility of the code using this function to adjust the apparent
%   size of the inserted material.
% \end{function}
%
% \begin{function}[added = 2017-12-13, updated = 2018-04-26]
%   {\driver_box_use_scale:Nnn}
%   \begin{syntax}
%     \cs{driver_box_use_scale:Nnn} \meta{box} \Arg{x-scale} \Arg{y-scale}
%   \end{syntax}
%   Inserts the content of the \meta{box} at the current insertion point
%   scale by the \meta{x-scale} and \meta{y-scale} (both \meta{fp expressions}).
%   The reference point
%   of the material will be unchanged. It is the responsibility of the
%   code using this function to adjust the apparent size of the inserted
%   material.
% \end{function}
%
% \section{Color support}
%
% \begin{function}[added = 2018-02-20]{\driver_color_cmyk:nnnn}
%   \begin{syntax}
%     \cs{driver_color_cmyk:nnnn} \Arg{cyan} \Arg{magenta} \Arg{yellow}
%       \Arg{black}
%   \end{syntax}
%   Sets the color to the CMYK values specified, all of which are
%   fp denotations in the range $0$ and $1$. For drawing colors, see
%   \cs{driver_draw_stroke_cmyk:nnnn}, \emph{etc.}
% \end{function}
%
% \begin{function}[added = 2018-02-20]{\driver_color_gray:n}
%   \begin{syntax}
%     \cs{driver_color_gray:n} \Arg{gray}
%   \end{syntax}
%   Sets the color to the grayscale value specified, which is
%   fp denotations in the range $0$ and $1$. For drawing colors, see
%   \cs{driver_draw_stroke_gray:n}, \emph{etc.}
% \end{function}
%
% \begin{function}[added = 2018-02-20]{\driver_color_rgb:nnn}
%   \begin{syntax}
%     \cs{driver_color_rgb:nnn} \Arg{red} \Arg{green} \Arg{blue}
%   \end{syntax}
%   Sets the color to the RGB values specified, all of which are
%   fp denotations in the range $0$ and $1$. For drawing colors, see
%   \cs{driver_draw_stroke_rgb:nnn}, \emph{etc.}
% \end{function}
%
% \begin{function}[added = 2018-02-20]{\driver_color_pickup:N}
%   \begin{syntax}
%     \cs{driver_color_pickup:N} \meta{tl}
%   \end{syntax}
%   In \LaTeXe{} package mode, collects data on the current color from
%   \tn{current@color} and stores it in the low-level format used by \pkg{expl3}
%   in the \meta{tl}.
% \end{function}
%
% \section{Drawing}
%
% These functions
% are inspired heavily by the system layer of \pkg{pgf} (most have the
% same interface as the same functions in the latter's \cs{pgfsys@\ldots}
% namespace). They are intended to form the basis for higher level drawing
% interfaces, which themselves are likely to be further abstracted for user
% access. Again, this model is heavily inspired by \pkg{pgf} and
% Ti\textit{k}z.
%
% These low level drawing interfaces abstract from the driver raw requirements
% but still require an appreciation of the concepts of PostScript/PDF/SVG
% graphic creation.
%
% \begin{function}
%   {\driver_draw_begin:, \driver_draw_end:}
%   \begin{syntax}
%     \cs{driver_draw_begin:}
%     \meta{content}
%     \cs{driver_draw_end:}
%   \end{syntax}
%   Defines a drawing environment. This is a scope for the purposes of
%   the graphics state. Depending on the driver, other set up may or may not
%   take place here. The natural size of the \meta{content} should be zero
%   from the \TeX{} perspective: allowance for the size of the content must
%   be made at a higher level (or indeed this can be skipped if the content is
%   to overlap other material).
% \end{function}
%
% \begin{function}
%   {\driver_draw_scope_begin:, \driver_draw_scope_end:}
%   \begin{syntax}
%     \cs{driver_draw_scope_begin:}
%     \meta{content}
%     \cs{driver_draw_scope_end:}
%   \end{syntax}
%   Defines a scope for drawing settings and so on. Changes to the graphic
%   state and concepts such as color or linewidth are localised to a scope.
%   This function pair must never be used if an partial path is under
%   construction: such paths must be entirely contained at one unbroken
%   scope level. Note that scopes do not form \TeX{} groups and may not
%   be aligned with them.
% \end{function}
%
% \subsection{Path construction}
%
% \begin{function}{\driver_draw_moveto:nn}
%   \begin{syntax}
%     \cs{driver_draw_move:nn} \Arg{x} \Arg{y}
%   \end{syntax}
%   Moves the current drawing reference point to (\meta{x}, \meta{y});
%   any active transformation matrix applies.
% \end{function}
%
% \begin{function}{\driver_draw_lineto:nn}
%   \begin{syntax}
%     \cs{driver_draw_lineto:nn} \Arg{x} \Arg{y}
%   \end{syntax}
%   Adds a path from the current drawing reference point to
%   (\meta{x}, \meta{y}); any active transformation matrix applies. Note
%   that nothing is drawn until a fill or stroke operation is applied, and that
%   the path may be discarded or used as a clip without appearing itself.
% \end{function}
%
% \begin{function}{\driver_draw_curveto:nnnnnn}
%   \begin{syntax}
%     \cs{driver_draw_curveto:nnnnnn} \Arg{x_1} \Arg{y_1}
%       \Arg{x_2} \Arg{y_2} \Arg{x_3} \Arg{y_3}
%   \end{syntax}
%   Adds a Bezier curve path from the current drawing reference point to
%   (\meta{x_3}, \meta{y_3}), using (\meta{x_1}, \meta{y_1}) and
%   (\meta{x_2}, \meta{y_2}) as control points; any active transformation
%   matrix applies.  Note that nothing is drawn until a fill or stroke
%   operation is applied, and that the path may be discarded or used as a clip
%   without appearing itself.
% \end{function}
%
% \begin{function}{\driver_draw_rectangle:nnnn}
%   \begin{syntax}
%     \cs{driver_draw_rectangle:nnnn} \Arg{x} \Arg{y} \Arg{width} \Arg{height}
%   \end{syntax}
%   Adds rectangular path from (\meta{x_1}, \meta{y_1}) of \meta{height}
%   and \meta{width}; any active transformation matrix applies.  Note that
%   nothing is drawn until a fill or stroke operation is applied, and that the
%   path may be discarded or used as a clip without appearing itself.
% \end{function}
%
% \begin{function}{\driver_draw_closepath:}
%   \begin{syntax}
%     \cs{driver_draw_closepath:}
%   \end{syntax}
%   Closes an existing path, adding a line from the current point to the
%   start of path. Note that nothing is drawn until a fill or stroke
%   operation is applied, and that the path may be discarded or used as a clip
%   without appearing itself.
% \end{function}
%
% \subsection{Stroking and filling}
%
% \begin{function}{\driver_draw_stroke:, \driver_draw_closestroke:}
%   \begin{syntax}
%     \meta{path construction}
%     \cs{driver_draw_stroke:}
%   \end{syntax}
%   Draws a line along the current path, which is also closed in the case of
%   \cs{driver_draw_closestroke:}. The nature of the line drawn
%   is influenced by settings for
%   \begin{itemize}
%     \item Line thickness
%     \item Stroke color (or the current color if no specific stroke color
%       is set)
%     \item Line capping (how non-closed line ends should look)
%     \item Join style (how a bend in the path should be rendered)
%     \item Dash pattern
%   \end{itemize}
%   The path may also be used for clipping.
% \end{function}
%
% \begin{function}{\driver_draw_fill:, \driver_draw_fillstroke:}
%   \begin{syntax}
%     \meta{path construction}
%     \cs{driver_draw_fill:}
%   \end{syntax}
%   Fills the area surrounded by the current path: this will be closed prior
%   to filling if it is not already. The \texttt{fillstroke} version also
%   strokes the path as described for \cs{driver_draw_stroke:}. The fill is
%   influenced by the setting for fill color (or the current color if no
%   specific stroke color is set). The path may also be used for clipping.
%   For paths which are self-intersecting or comprising multiple parts, the
%   determination of which areas are inside the path is made using the non-zero
%   winding number rule unless the even-odd rule is active.
% \end{function}
%
% \begin{function}{\driver_draw_nonzero_rule:, \driver_draw_evenodd_rule:}
%   \begin{syntax}
%     \cs{driver_draw_nonzero_rule:}
%   \end{syntax}
%   Active either the non-zero winding number or the even-odd rule,
%   respectively, for determining what is inside a fill or clip area.
%   For technical reasons, these command are not influenced by scoping
%   and apply on an ongoing basis.
% \end{function}
%
% \begin{function}{\driver_draw_clip:}
%   \begin{syntax}
%     \meta{path construction}
%     \cs{driver_draw_clip:}
%   \end{syntax}
%   Indicates that the current path should be used for clipping, such that
%   any subsequent material outside of the path (but within the current
%   scope) will not be shown. This command should be given once a path is
%   complete but before it is stroked or filled (if appropriate). This
%   command is \emph{not} affected by scoping: it applies to exactly one
%   path as shown.
% \end{function}
%
% \begin{function}{\driver_draw_discardpath:}
%   \begin{syntax}
%     \meta{path construction}
%     \cs{driver_draw_discardpath:}
%   \end{syntax}
%   Discards the current path without stroking or filling. This is primarily
%   useful for paths constructed purely for clipping, as this alone does not
%   end the paths existence.
% \end{function}
%
% \subsection{Stroke options}
%
% \begin{function}{\driver_draw_linewidth:n}
%   \begin{syntax}
%     \cs{driver_draw_linewidth:n} \Arg{dimexpr}
%   \end{syntax}
%   Sets the width to be used for stroking to \meta{dimexpr}.
% \end{function}
%
% \begin{function}{\driver_draw_dash_pattern:nn}
%   \begin{syntax}
%     \cs{driver_draw_dash:nn} \Arg{dash pattern} \Arg{phase}
%   \end{syntax}
%   Sets the pattern of dashing to be used when stroking a line. The
%   \meta{dash pattern} should be a comma-separated list of dimension
%   expressions. This is then interpreted as a series of pairs of line-on
%   and line-off lengths. For example \texttt{3pt, 4pt} means that $3$\,pt on,
%   $4$\,pt off, $3$\,pt on, and so on. A more complex pattern will also
%   repeat: \texttt{3pt, 4pt, 1pt, 2pt} results in $3$\,pt on, $4$\,pt off,
%   $1$\,pt on, $2$\,pt off, $3$\,pt on, and so on. An odd number of entries
%   means that the last is repeated, for example \texttt{3pt} is equal to
%   \texttt{3pt, 3pt}. An empty pattern yields a solid line.
%
%   The \meta{phase} specifies an offset at the start of the cycle. For
%   example, with a pattern \texttt{3pt} a phase of \texttt{1pt} means
%   that the output is $2$\,pt on, $3$\,pt off, $3$\,pt on, $3$\,pt on,
%   \emph{etc.}
% \end{function}
%
% \begin{function}
%   {
%     \driver_draw_cap_butt:      ,
%     \driver_draw_cap_rectangle: ,
%     \driver_draw_cap_round:
%   }
%   \begin{syntax}
%     \cs{driver_draw_cap_butt:}
%   \end{syntax}
%   Sets the style of terminal stroke position to one of butt, rectangle or
%   round.
% \end{function}
%
% \begin{function}
%   {
%     \driver_draw_join_bevel: ,
%     \driver_draw_join_miter: ,
%     \driver_draw_join_round:
%   }
%   \begin{syntax}
%     \cs{driver_draw_cap_butt:}
%   \end{syntax}
%   Sets the style of stroke joins to one of bevel, miter or round.
% \end{function}
%
% \begin{function}{\driver_draw_miterlimit:n}
%   \begin{syntax}
%     \cs{driver_draw_miterlimit:n} \Arg{factor}
%   \end{syntax}
%   Sets the miter limit of lines joined as a miter, as described in the
%   PDF and PostScript manuals. The \meta{factor} here is an
%   \meta{fp expression}.
% \end{function}
%
% \subsection{Color}
%
% \begin{function}
%   {
%     \driver_draw_color_fill_cmyk:nnnn  ,
%     \driver_draw_color_stroke_cmyk:nnnn
%   }
%   \begin{syntax}
%     \cs{driver_draw_color_fill_cmyk:nnnn} \Arg{cyan} \Arg{magenta} \Arg{yellow}
%       \Arg{black}
%   \end{syntax}
%   Sets the color for drawing to the CMYK values specified, all of which are
%   fp denotations in the range $0$ and $1$.
% \end{function}
%
% \begin{function}
%   {
%     \driver_draw_color_fill_gray:n  ,
%     \driver_draw_color_stroke_gray:n
%   }
%   \begin{syntax}
%     \cs{driver_draw_color_fill_gray:n} \Arg{gray}
%   \end{syntax}
%   Sets the color for drawing to the grayscale value specified, which is
%   fp denotations in the range $0$ and $1$.
% \end{function}
%
% \begin{function}
%   {
%     \driver_draw_color_fill_rgb:nnn  ,
%     \driver_draw_color_stroke_rgb:nnn
%   }
%   \begin{syntax}
%     \cs{driver_draw_color_fill_rgb:nnn} \Arg{red} \Arg{green} \Arg{blue}
%   \end{syntax}
%   Sets the color for drawing to the RGB values specified, all of which are
%   fp denotations in the range $0$ and $1$.
% \end{function}
%
% \subsection{Inserting \TeX{} material}
%
% \begin{function}{\driver_draw_box_use:Nnnnn}
%   \begin{syntax}
%     \cs{driver_draw_box_use:Nnnnn} \meta{box}
%       \Arg{a} \Arg{b} \Arg{c} \Arg{d} \Arg{x} \Arg{y}
%   \end{syntax}
%   Inserts the \meta{box} as an hbox with the box reference point placed
%   at ($x$, $y$). The transformation matrix $[a b c d]$ is applied
%   to the box, allowing it to be in synchronisation with any scaling, rotation
%   or skewing applying more generally. Note that \TeX{} material should not
%   be inserted directly into a drawing as it would not be in the correct
%   location. Also note that this function must be used inside a box of zero
%   size, shifted appropriately for the correct result; a low-level engine
%   error may result if this is not the case.
% \end{function}
%
% \subsection{Coordinate system transformations}
%
% \begin{function}{\driver_draw_cm:nnnn}
%   \begin{syntax}
%     \cs{driver_draw_cm:nnnn} \Arg{a} \Arg{b} \Arg{c} \Arg{d}
%   \end{syntax}
%   Applies the transformation matrix $[a b c d]$ to the current graphic state.
%   This affects any subsequent items in the same scope but not those already
%   given.
% \end{function}
%
% \section{Graphics inclusion}
%
% Graphics inclusion support is closely tied to the higher-level \pkg{l3graphics}
% module. This arises as information concerning images (\emph{e.g.}~page
% numbers in multi-page files) is needed to correct cache image data. As
% such, the driver code here assumes the following are defined
% \begin{itemize}
%   \item \cs{l_image_decodearray_tl}
%   \item \cs{l_image_interpolate_tl}
%   \item \cs{l_image_page_tl}
%   \item \cs{l_image_pagebox_tl}
% \end{itemize}
%
% Note also that the functions defined will depend on the file types supported
% by the driver. As such, a calling function should typically test for the
% existence of an appropriate function to determine if the image file is
% supported.
%
% \begin{function}[added = 2019-05-07]
%   {
%     \driver_graphics_getbb_eps:n,
%     \driver_graphics_getbb_jpg:n,
%     \driver_graphics_getbb_pdf:n,
%     \driver_graphics_getbb_png:n
%   }
%   \begin{syntax}
%     \cs{driver_graphics_getbb_pdf:n} \Arg{file}
%   \end{syntax}
%   These functions load the requested image \meta{file} and obtain the
%   bounding box information on the file. They may also cache the image for
%   subsequent inclusion: this is driver-dependent. The bounding box data
%   will be stored in \cs{l_image_llx_dim},  \cs{l_image_lly_dim},
%   \cs{l_image_urx_dim}, and  \cs{l_image_ury_dim} after use of these
%   functions.
% \end{function}
%
% \begin{function}[added = 2019-05-07]
%   {
%     \driver_graphics_include_eps:n,
%     \driver_graphics_include_jpg:n,
%     \driver_graphics_include_pdf:n,
%     \driver_graphics_include_png:n
%   }
%   \begin{syntax}
%     \cs{driver_graphics_include_pdf:n} \Arg{file}
%   \end{syntax}
%   These functions include the appropriate image type at the current position.
%   They should be preceded by use of the matching \texttt{getbb} function to
%   set the bounding box correctly; in some drivers, the \texttt{getbb}
%   function is also responsible for caching the image for later inclusion.
% \end{function}
%
% \section{PDF Features}
%
% A range of PDF features are exposed by \pdfTeX{} and \LuaTeX{} in direct PDF
% output mode, and the vast majority of these are also controllable using
% the \texttt{(x)dvipdfmx} driver (as DVI instructions are converted directly
% to PDF). Some of these functions are also available for cases where PDFs
% are generated by \texttt{dvips}: this depends on being able to pass
% information through correctly.
%
% \subsection{PDF Annotations}
%
% \begin{function}[added = 2019-04-10]
%   {\driver_pdf_annotation:nnnn}
%   \begin{syntax}
%     \cs{driver_pdf_annotation:nnnn} \Arg{width} \Arg{height} \Arg{depth} \Arg{dictionary}
%   \end{syntax}
%   Creates a generic PDF annotation of the given \meta{height}, \meta{width}
%   and \meta{depth} and featuring the \meta{dictionary}.
% \end{function}
%
% \begin{function}[added = 2019-04-17, updated = 2019-05-03]
%   {
%     \driver_pdf_link_begin_goto:nnw,
%     \driver_pdf_link_begin_user:nnw,
%     \driver_pdf_link_end:
%   }
%   \begin{syntax}
%     \cs{driver_pdf_link_begin_user:nnw} \Arg{attributes} \Arg{action}
%     \Arg{content}
%     \cs{driver_pdf_link_end:}
%     \cs{driver_pdf_link_begin_goto:nnw} \Arg{attributes} \Arg{target}
%     \Arg{content}
%     \cs{driver_pdf_link_end:}
%   \end{syntax}
%   Creates a link of the \meta{type} |goto| or |user| with the given
%   \meta{attributes}, points toward the \meta{action} and surround the
%   \TeX{} \meta{content}. The |begin| and |end| functions must be given
%   at the same box level. Depending upon the back-end in use, the
%   \meta{content} may be placed in a hbox as part of processing.
%   The |goto| type will automatically add |/Subtype /Link| to the PDF
%   dictionary for the annotation produced; other classes do not add
%   this, so the |/Subtype| must be provided as part of the \meta{action}.
% \end{function}
%
% \begin{function}[EXP, added = 2019-04-09]{\driver_pdf_link_last:}
%   \begin{syntax}
%     \cs{driver_pdf_link_last:}
%   \end{syntax}
%   Expands to the object reference 
% \end{function}
%
% \begin{function}[EXP, added = 2019-04-11]{\driver_pdf_link_margin:n}
%   \begin{syntax}
%     \cs{driver_pdf_link_margin:} \Arg{dimen}
%   \end{syntax}
%   Sets the length of the margin between content and the border of a link.
%   Different back-ends treat the scoping of this value in different ways:
%   \pdfTeX{} and \LuaTeX{} treat it as scoped by \TeX{}, whilst with
%   \texttt{dvips} the scope is managed at the PostScript level. For
%   \texttt{(x)dvipdfmx}, this setting applies to \emph{all} annotations
%   (\emph{i.e.}~it is global), and thus it may be necessary to set to
%   \texttt{0pt} to avoid breaking for example animations.
% \end{function}
%
% \begin{function}[added = 2019-04-26]{\driver_pdf_destination:nn}
%   \begin{syntax}
%     \cs{driver_pdf_destination:nn} \Arg{name} \Arg{action}
%   \end{syntax}
%   Creates a destination (anchor) called \meta{name}; when a jump is made
%   by a link to the destination, one of the following actions may take
%   place
%   \begin{itemize}
%     \item \texttt{xyz} Move the view such that the target point is at the
%       top-left of the viewer screen
%     \item \texttt{\meta{scale}} As for \texttt{xyz}, but also sets the
%       viewer \meta{scale}
%     \item \texttt{fit} Display the page containing the destination and fit
%       the entire page within the viewer window
%     \item \texttt{fitb} Display the page containing the destination and fit
%       the bounding box of the page within the viewer window
%     \item \texttt{fitbh} Move to the destination page such that the
%       anchor point is at the top of the viewer screen, and scale
%       such that the bounding box fills the viewer width
%     \item \texttt{fitbv} Move to the destination page such that the
%       anchor point is at the left of the viewer screen, and scale
%       such that the bounding box fills the viewer height
%     \item \texttt{fith} Move to the destination page such that the
%       anchor point is at the top of the viewer screen, and scale
%       such that the page fills the viewer width
%     \item \texttt{fitv} Move to the destination page such that the
%       anchor point is at the left of the viewer screen, and scale
%       such that the page fills the viewer height
%   \end{itemize}
%   A \meta{scale} of zero is equivalent to \texttt{xyz}.
% \end{function}
%
% \begin{function}[added = 2019-04-28]{\driver_pdf_destination_rectangle:nn}
%   \begin{syntax}
%     \cs{driver_pdf_destination_rectangle:nn} \Arg{name} \Arg{content}
%   \end{syntax}
%   Creates a destination (anchor) called \meta{name}; when a jump is made
%   by a link to the destination, the viewer will set the zoom such that all
%   of the \meta{content} is visible taking up the full width or height of the
%   viewer area.
% \end{function}
%
% \subsection{PDF Catalogue entries}
%
% \begin{function}[added = 2019-04-28]{\driver_pdf_catalog_gput:nn}
%   \begin{syntax}
%     \cs{driver_pdf_catalog_gput:nn} \Arg{key} \Arg{value}
%   \end{syntax}
%   Adds the key--value pair to the PDF catalog. The \meta{key} should
%   be given \emph{without} the leading |/|. The \meta{value} should be
%   a \enquote{raw} PDF dictionary entry, including the |(|/|)| pair for
%   a string, a leading |/| for a boolean, \emph{etc.}
% \end{function}
%
% \begin{function}[added = 2019-04-28]{\driver_pdf_info_gput:nn}
%   \begin{syntax}
%     \cs{driver_pdf_info_gput:nn} \Arg{key} \Arg{value}
%   \end{syntax}
%   Adds the key--value pair to the PDF information. The \meta{key} should
%   be given \emph{without} the leading |/|. The \meta{value} should be
%   a \enquote{raw} PDF dictionary entry, including the |(|/|)| pair for
%   a string or leading |/| for a boolean.
% \end{function}
%
% \subsection{PDF Objects}
%
% Objects are used to provide a range of data structures in a PDF. At the
% driver level, different PDF object types are declared separately. Objects
% are only \emph{written} to the PDF when referenced.
%
% \begin{function}{\driver_pdf_object_new:nn}
%   \begin{syntax}
%     \cs{driver_pdf_object_new:n} \Arg{name} \Arg{type}
%   \end{syntax}
%   Declares \meta{name} as a PDF object. The \texttt{type} should be one of
%   |array| or |dict|, |fstream| or |stream|.
% \end{function}
%
% \begin{function}[EXP]{\driver_pdf_object_ref:n}
%   \begin{syntax}
%     \cs{driver_pdf_object_ref:n} \Arg{object}
%   \end{syntax}
%   Inserts the appropriate information to reference the \meta{object}
%   in for example page resource allocation.
% \end{function}
%
% \begin{function}{\driver_pdf_object_write:nn}
%   \begin{syntax}
%     \cs{driver_pdf_object_write:nn} \Arg{name} \Arg{data}
%   \end{syntax}
%   Writes the \meta{data} as content of the \meta{object}. Depending on the
%   \meta{type} declared for the object, the format required for the
%   \meta{data} will vary
%   \begin{itemize}
%     \item[\texttt{array}] A space-separated list of values
%     \item[\texttt{dict}] Key--value pairs in the form
%       \texttt{/\meta{key} \meta{value}}
%     \item[\texttt{fstream}] Two brace groups: \meta{content} and
%       \meta{file name}
%     \item[\texttt{stream}] Two brace groups: \meta{content} and
%       \meta{additional attributes}
%   \end{itemize}
% \end{function}
%
% \subsection{PDF structure}
%
% \begin{function}{\driver_pdf_compresslevel:n}
%   \begin{syntax}
%     \cs{driver_pdf_compresslevel:n} \Arg{level}
%   \end{syntax}
%   Sets the degree of compression used for PDF files: the \meta{level} should
%   be in the range $0$ to $9$ (higher is more compression). Typically, either
%   compression is disables ($0$) or maximised ($9$). When used with
%   \texttt{(x)dvipdfmx}, this setting may only be applied globally: it should
%   be set only once.
% \end{function}
%
% \begin{function}[added = 2019-05-07]{\driver_pdf_objects:}
%   \begin{syntax}
%     \cs{driver_pdf_compress_objects:n} \Arg{switch}
%   \end{syntax}
%   Enables or disables the compression of non-stream objects when writing
%   the PDF. This depends on the \meta{switch}: either \texttt{true} or
%   \texttt{false}). Compression of non-stream objects is used to
%   reduce the size of PDFs, and typically are enabled as standard. When used
%   with \texttt{(x)dvipdfmx}, object creation can be disabled but not
%   re-enabled, and this setting may only be applied globally: it should
%   be set only once. Note that for \texttt{dvips} this setting has no action,
%   as control of this functionality is dependent on the conversion from
%   PostScript to PDF.
% \end{function}
%
% \begin{function}[EXP, added = 2019-04-11]
%   {\driver_pdf_version_major:, \driver_pdf_version_minor:}
%   \begin{syntax}
%     \cs{driver_pdf_version_major:}
%     \cs{driver_pdf_version_minor:}
%   \end{syntax}
%   Expands to the current value of the major or minor version of PDF being
%   created, a non-negative integer. Where a value is not available at the
%   \TeX{} run level, the result is $-1$. (This is necessary as the minor
%   version may be $0$.)
% \end{function}
%
% \begin{function}[EXP, added = 2019-04-11]
%   {\driver_pdf_version_major_gset:n, \driver_pdf_version_minor_gset:n}
%   \begin{syntax}
%     \cs{driver_pdf_version_major_gset:n} \Arg{integer}
%     \cs{driver_pdf_version_minor_gset:n} \Arg{integer}
%   \end{syntax}
%   Sets the PDF version as specified: the allowable range is not checked
%   at this level.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3drivers} Implementation}
%
% Nothing to see here: everything is in the subfiles!
%
% \end{implementation}
%
% \PrintIndex
