% \iffalse meta-comment
% 
%% File: l3drivers.dtx Copyright(C) 2011 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
%%
%%    http://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 released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX Project Team.
%%
%% -----------------------------------------------------------------------
%%
%
%<*driver>
\RequirePackage{l3names}
\GetIdInfo$Id: l3drivers.dtx 2717 2011-09-03 13:40:31Z joseph $
  {L3 Experimental drivers}
%</driver>
%<*driver>
\documentclass[full]{l3doc}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% 
% \title{^^A
%   The \textsf{l3drivers} package\\ Drivers^^A
%   \thanks{This file describes v\ExplFileVersion,
%     last revised \ExplFileDate.}^^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 \ExplFileDate}
%
% \maketitle
%
% \begin{documentation}
% 
% \TeX{} relies on drivers in order to carry out a number of tasks, such
% as using colour, 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 dvips program, which works in conjugation with
%     \pdfTeX{} or \LuaTeX{} in DVI mode.
%   \item \texttt{xdvipdfmx}: The driver used by \XeTeX{}.
% \end{itemize}
% 
% The code here is all very low-level, and should not in general be used
% outside of the kernel. It is also important to note that many of the
% functions here are closely tied to the immediate level \enquote{up}:
% several variable values must be in the correct locations for the driver
% code to function.
% 
% \section{Box rotation and scaling}
% 
% \begin{function}{\driver_box_rotate_begin:, \driver_box_rotate_end:}
%   \begin{syntax}
%     \cs{driver_box_rotate_begin:}
%     \cs{box_use:N} \cs{l_box_tmp_box}
%     \cs{driver_box_rotate_end:}
%   \end{syntax}
%   Rotates the \meta{box material} anti-clockwise around the current
%   insertion point. The angle of rotation (in degrees counter-clockwise)
%   and the sine and cosine of this angle should be stored in
%   \cs{l_box_angle_fp}, \cs{l_box_sin_fp} and \cs{l_box_cos_fp},
%   respectively. Typically, the box material inserted between the beginning
%   and end markers will be stored in \cs{l_box_tmp_box}: this fact is
%   required by some drivers to obtain the correct output.
% \end{function}
% 
% \begin{function}{\driver_box_scale_begin:, \driver_box_scale_end:}
%   \begin{syntax}
%     \cs{driver_box_scale_begin:}
%     \meta{box material}
%     \cs{driver_box_scale_end:}
%   \end{syntax}
%   Scales the \meta{box material} (which should be either a \cs{box_use:N}
%   or \cs{hbox:n} construct). The \meta{box material} is scaled by the values
%   stored in \cs{l_box_scale_x_fp} and \cs{l_box_scale_y_fp} in the
%   horizontal and vertical directions, respectively. This function is
%   also reused when resizing boxes: at a driver level, only scalings are
%   supported and so the higher-level code must convert the absolute sizes
%   to scale factors.
% \end{function}
% 
% \section{Colour support}
% 
% \begin{function}{\driver_color_ensure_current:}
%   \begin{syntax}
%     \cs{driver_color_ensure_current:}
%   \end{syntax}
%   Ensures that the colour used to typeset material is that which was
%   set when the material was placed in a box. This function is therefore
%   required inside any \enquote{colour safe} box to ensure that the box may
%   be inserted in a location where the foreground colour has been altered, 
%   while preserving the colour used in the box.
% \end{function}
% 
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3drivers} Implementation}
% 
%    \begin{macrocode}
%<*initex>
%    \end{macrocode}
%    
% \subsection{Settings for direct PDF output}
% 
% If the driver loaded is \texttt{pdfmode} then direct PDF output is required.
% (This may of course alter: it might be that the driver is picked based on the
% value of \cs{pdfmode_pdfoutput:D}.)
%    \begin{macrocode}
%<*pdfmode>
\pdftex_pdfoutput:D = 1 \scan_stop:
%</pdfmode>
%    \end{macrocode}
%
% Set up the driver for direct PDF output to set the PDF origin equal to
% \TeX{}'s standard origin. The other settings make use of PDF~$1.5$, which
% is standard in \TeX{} Live 2011 and should be a reasonable baseline for
% the future.
%    \begin{macrocode}
%<*pdfmode>
\pdftex_pdfhorigin:D          = 1 true in \scan_stop:
\pdftex_pdfvorigin:D          = 1 true in \scan_stop:
\pdftex_pdfdecimaldigits:D    = 3         \scan_stop:
\pdftex_pdfpkresolution:D     = 600       \scan_stop:
\pdftex_pdfminorversion:D     = 5         \scan_stop:
\pdftex_pdfcompresslevel:D    = 9         \scan_stop:
\pdftex_pdfobjcompresslevel:D = 2         \scan_stop:
%</pdfmode>
%    \end{macrocode}
%    
% \subsection{Box rotation and scaling}
%
% \begin{variable}{\l_driver_box_matrix_tl}
%   A token list for the affine transformation matrix.
%    \begin{macrocode}
%<*pdfmode>
\tl_new:N \l_driver_box_matrix_tl
%</pdfmode>
%    \end{macrocode}
% \end{variable}
% 
% \begin{variable}{\l_driver_tmp_fp}
%  Needed for a safe sign inversion in PDF mode.
%    \begin{macrocode}
%<*pdfmode>
\fp_new:N \l_driver_tmp_fp
%</pdfmode>
%    \end{macrocode}
% \end{variable}
% 
% \begin{macro}{\driver_box_rotate_begin:, \driver_box_rotate_end:}
%   Systems which require only the rotation angle have simple drivers.
%   On the other hand, in PDF mode the affine transformation matrix is
%   needed, which has to be set up. This also requires that the sine
%   value does not have two |-| tokens at the start, hence having to
%   work out the negative sine carefully. This driver also requires
%   that the width of the box in use for the output is set to zero, hence
%   needing to know where the output is actually stored.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \driver_box_rotate_begin:
  {
%<*dvips>
    \tex_special:D
      {
        ps:~gsave~currentpoint~
        currentpoint~translate~ \fp_use:N \l_box_angle_fp \c_space_tl
        neg~rotate~neg~exch~neg~exch~translate
      }
%</dvips>
%<*pdfmode>
    \fp_set_eq:NN \l_driver_tmp_fp \l_box_sin_fp
    \fp_neg:N \l_driver_tmp_fp 
    \tl_set:Nx \l_driver_box_matrix_tl
      { 
        \fp_use:N \l_box_cos_fp \c_space_tl 
        \fp_use:N \l_box_sin_fp \c_space_tl
        \fp_use:N \l_driver_tmp_fp \c_space_tl
        \fp_use:N \l_box_cos_fp
      }
    \pdftex_pdfsave:D
    \pdftex_pdfsetmatrix:D { \l_driver_box_matrix_tl }
    \box_set_wd:Nn \l_box_tmp_box \c_zero_dim
%</pdfmode>
%<*xdvipdfmx>
    \tex_special:D { x:gsave }
    \tex_special:D { x:rotate~ \fp_use:N \l_box_angle_fp }
%</xdvipdfmx>
  }
%    \end{macrocode}
% The end of a rotation means tidying up the output grouping.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \driver_box_rotate_end:
%<*dvips>
  { \tex_special:D { ps:~currentpoint~grestore~moveto } }
%</dvips>
%<*pdfmode>
  { \pdftex_pdfrestore:D }
%</pdfmode>
%<*xdvipdfmx>
  { \tex_special:D { x:grestore } }
%</xdvipdfmx>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\driver_box_scale_begin:, \driver_box_scale_end:}
%   Scaling is not dissimilar to rotation, but the calculations are somewhat
%   less complex. 
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \driver_box_scale_begin:
  {
%<*dvips>
    \tex_special:D
      {
        ps:~currentpoint~
        currentpoint~translate~
        \fp_use:N \l_box_scale_x_fp \c_space_tl
        \fp_use:N \l_box_scale_y_fp \c_space_tl
        scale~neg~exch~neg~exch~
        translate
      }
%</dvips>
%<*pdfmode>
    \tl_set:Nx \l_driver_box_matrix_tl
      { 
        \fp_use:N \l_box_scale_x_fp \c_space_tl 
        0 ~ 0 ~
        \fp_use:N \l_box_scale_y_fp
      }
    \pdftex_pdfsave:D
    \pdftex_pdfsetmatrix:D { \l_driver_box_matrix_tl }
%</pdfmode>
%<*xdvipdfmx>
    \tex_special:D { x:gsave }
    \tex_special:D
      {
        x:scale ~
        \fp_use:N \l_box_scale_x_fp \c_space_tl
        \fp_use:N \l_box_scale_y_fp
      }
%</xdvipdfmx>
  }
%    \end{macrocode}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \driver_box_scale_end:
%<*dvips>
   {
     \tex_special:D
       {
         ps:~currentpoint~
         currentpoint~translate~
         1~\fp_use:N \l_box_scale_x_fp \c_space_tl div~
         1~\fp_use:N \l_box_scale_y_fp \c_space_tl div~
         scale~neg~exch~neg~exch~
         translate
       } 
   }
%</dvips>
%<*pdfmode>
  { \pdftex_pdfrestore:D }
%</pdfmode>
%<*xdvipdfmx>
  { \tex_special:D { x:grestore } }
%</xdvipdfmx>
%    \end{macrocode}
% \end{macro}
%    
% \subsection{Colour support}
% 
% \begin{variable}{\l_driver_current_color_tl}
%   The current colour is needed by all of the engines, but the way this
%   is stored varies.
%    \begin{macrocode}
\tl_new:N \l_driver_current_color_tl
%<*dvips>
\tl_set:Nn \l_driver_current_color_tl { Black }
%</dvips>
%<*pdfmode>
\tl_set:Nn \l_driver_current_color_tl { 0~g~0~G }
%</pdfmode>
%<*xdvipdfmx>
\tl_set:Nn \l_driver_current_color_tl { gray~0 }
%</xdvipdfmx>
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_driver_color_stack_int}
%   \pdfTeX{} and \LuaTeX{} have multiple stacks available, and the colour
%   stack therefore needs a number.
%    \begin{macrocode}
%<*pdfmode>
\int_new:N  \l_driver_color_stack_int
%</pdfmode>
%    \end{macrocode}
% \end{variable}
% 
% \begin{macro}{\driver_color_group_begin:, \driver_color_group_end:}
%    \begin{macrocode}

%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\driver_color_ensure_current:}
% \begin{macro}[aux]{\driver_color_reset:}
%   Setting the current colour depends on the nature of the colour stack
%   available. In all cases there is a need to reset the colour after
%   the current group.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \driver_color_ensure_current:
  {
%<*dvips|xdvipdfmx>
    \tex_special:D { color~push~\l_driver_current_color_tl }
%</dvips|xdvipdfmx>
%<*pdfmode>
    \pdftex_pdfcolorstack:D \l_driver_color_stack_int push
      { \l_driver_current_color_tl }
%</pdfmode>
    \group_insert_after:N \driver_color_reset:
  }
\cs_new_protected_nopar:Npn \driver_color_reset:
%<*dvips|xdvipdfmx>
  { \tex_special:D { color~pop } }
%</dvips|xdvipdfmx>
%<*pdfmode>
  { \pdftex_pdfcolorstack:D \l_driver_color_stack_int pop \scan_stop: }
%</pdfmode>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</initex>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex