% \iffalse
%
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{refcol.dtx}
         [1994/03/14 v0.1b Reference colour files (DPC)]
%
\documentclass{ltxdoc}
\GetFileInfo{refcol.dtx}
\begin{document}
 \title{Reference colour drivers\thanks{This file
        has version number \fileversion, last
        revised \filedate.}}
 \author{David Carlisle}
 \date{\filedate}
 \maketitle
 \DocInput{refcol.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{519}
%
% \author{David Carlisle}
%
% \changes{0.1a}{1994/02/18}{Initial version}
%
% \section{Introduction}
% The \LaTeX\ colour interface does not directly access any macros that
% refer to the |\special| command, or particular colour models. Instead
% it relies on certain commands being defined in `driver' files.
% Several of these files need to be written because a) there is no
% agreed syntax for |\special| commands, and b) there is some
% flexibility in the way the colour commands may be implemented (for
% instance the amount of checking \TeX\ does).
%
% Despite the lack of agreement on |\special| syntax, Tom Rokicki, the
% author of the popular dvips driver has proposed a syntax for colour
% specials which do \emph{not} rely on the syntax of the target
% language. If specials obeying these conventions are used, all the
% features of the colour interface may be supported without any explict
% PostScript (or other language) being inserted into the dvi file.
%
% Various `reference driver files' are defined here. They may be used as
% a model for defining a file for a particular driver. They all have the
% extension |.col| for `colour'. 
% All the reference files do in fact work with |dvips|, but use
% different features, or implement different levels of error checking. 
%
% \begin{description}
% \item[ref0] This is a monochrome driver. No colour specials are
%      produced. The main point of interest here is that this does not
%      make the colour commands into no-ops. A \meta{whatsit} is
%      inserted in place of the |\special| to ensure that spacing is not
%      affected. For want of a better idea, the \meta{whatsit} writes
%      some tracing information to the log file.
% \item[ref1] This driver supports the models |named| |rgb| |cmyk| and
%      |gray|. It is quite small and efficient with \TeX\ memory, but
%      does no error checking. This can mean that your printer will be
%      sent invalid PostScript (and crash) even if \LaTeX\ gave you no
%      error. 
% \item[ref2] This supports the same models as ref1, but checks the
%      arguments given as any \emph{colour specification}. In the case
%      of numeric specifications (such as |rgb|) this does not cost much
%      memory, but of course is slightly slower as the checks have to be
%      made. However for `named' models, the checking implemented here
%      costs one macro name for each colour name known to the driver.
%      Depending on the number of predefined colours, and the size of
%      your \TeX, this may be expensive.
% \item[ref2b] Almost identical to ref2, but checks `named' colours by a
%      different procedure that only requires a single macro (with a
%      very long name) to check \emph{all} the colour names. This
%      is more efficient in terms of \TeX\ memory, but is slower, as the
%      long macro name has to be decoded whenever a check is made.
% \item[ref3] This is a sample of a driver which does not support
%      specific colour specials. Colour is implemented using specials
%      that insert literal PostScript. Also it is aimed at a driver that
%      does not support CMYK or named colours. Simple minded
%      translations to RGB are done within \TeX. This translation is not
%      visible at the \LaTeX\ interface level. This driver may produce
%      incorrect colours on a page with floats such as figure
%      environments. See `thoughts.tex' for reasons, and `testcol.tex'
%      for an example. 
% \item[dvips] Almost identical to ref2, but all the colours predefined
%      by dvips are checked.
% \end{description}
%
% \section{The Interface}
%
% A driver file should define the following four macros, which should
% produce one (or two) \meta{whatsit}s into the current list. Normally
% of course these will be |\special| commands inserting the colour
% requests. 
%
% |\set@color| This should insert a |\special| based on the current
% value of |\current@color|. It should then execute
% |\aftergroup\reset@color|.  
%
% |\current@color| This macro will be used to store the current colour
% in a format determined by the driver file. The driver file should
% initialise it to the representation for `Black'.
%
% |\reset@color| This should `pop the colour stack'. If the driver
% maintains its own stack, then just issue a `pop' special, otherwise 
% \TeX's save stack will approximate, so  a special inserting a colour
% request based on the current value of |\current@color| should be
% inserted. 
%
% |\set@page@color| This should insert a special making a global request
% to set the background colour on the current, and subsequent pages to
% the value specified in |\current@color|.
%
% Note that background colours are only supported at the page level.
%
% Often one just wants to set a background for an individual box. One
% could imagine specifying a special to give a background colour to a
% certain area. These drivers do not support this, as basically this
% amounts to `drawing a line in the current colour'. This is not
% possible with the `language independent' colour specials proposed by
% Tom Rokicki. 
% However a graphics package for (eg) PostScript will have such
% functionality, and may implement box backgrounds in this manner. Using
% the features provided here, box backgrounds can be implemented by
% selecting the background colour, drawing a \TeX\ rule, selecting the
% forground colour, and over-printing. One disadvantage of this approach
% is that if previewed on a monochrome device, the rule will obscure the
% box contents. For this reason most high level constructs for making
% such boxes should test the flag |\ifcolors@| and \emph{omit} the rule
% if the flag is false. This allows preview, at the cost of requiring a
% a \LaTeX\ run using a different driver option.
%
% Then for each model supported by the driver, the file should define:
%
% |\color@|\emph{model} This should take one argument, a colour
% specification for \emph{model}, define |\current@color|
% appropriately, and then call |\set@color|.
%
% |\definecolor@|\emph{model} This should take two arguments, a
% \emph{name}, and a colour specification for \emph{model}.
% It should define |\\color@|\emph{name} to expand to a macro which
% inserts the colour specified.
%
% \StopEventually{}
%
% \section{\ttfamily ref0.col}
%    \begin{macrocode}
%<*ref0>
%    \end{macrocode}
%
% Defines |named| |rgb| |gray| |cmyk| models.
% No checking is done on any model, and no  colours are produced.
%
% \subsection{specials}
%
% For this driver no |\special|s are in fact produced. A (non-immediate)
% |\write| is used instead, to ensure that spacing is not altered if
% this driver is used to `preview' a colour document on a monochrome
% device. 
%    \begin{macrocode}
\def\set@color{%
  \write\m@ne{color push \current@color}\aftergroup\reset@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\reset@color{\write\m@ne{color pop}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\set@page@color{\write\m@ne{background \current@color}}
%    \end{macrocode}
%
% \subsection{Using Colours}
%
%    \begin{macrocode}
\def\color@named#1{%
  \def\current@color{#1}%
  \set@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@rgb#1{%
  \def\current@color{rgb #1}%
  \set@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@cmyk#1{%
  \def\current@color{cmyk #1}%
  \set@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@gray#1{%
  \def\current@color{gray #1}%
  \set@color}
%    \end{macrocode}
%
% \subsection{Defining Colours}
%
%    \begin{macrocode}
\def\definecolor@named#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@named{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@gray#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@gray{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@rgb#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@rgb{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@cmyk#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@cmyk{#2}}}
%    \end{macrocode}
%
% \subsection{Initialisation}
% Specify Black in the internal syntax of the `named' model.
%
%    \begin{macrocode}
\def\current@color{Black}
%    \end{macrocode}
%

%    \begin{macrocode}
%</ref0>
%    \end{macrocode}
%
% \section{\ttfamily ref1.col}
%    \begin{macrocode}
%<*ref1>
%    \end{macrocode}
%
% Defines |named| |rgb gray| |cmyk| models.
% No checking is done on any model.
%
% \subsection{specials}
%
%    \begin{macrocode}
\def\set@color{%
  \special{color push \current@color}\aftergroup\reset@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\reset@color{\special{color pop}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\set@page@color{\special{background \current@color}}
%    \end{macrocode}
%
% \subsection{Using Colours}
%
% Basic version common to all models.
%    \begin{macrocode}
\def\color@@#1{%
  \def\current@color{#1}%
  \set@color}
%    \end{macrocode}
%
% Named
%    \begin{macrocode}
\let\color@named\color@@
%    \end{macrocode}
%
% RGB
%    \begin{macrocode}
\def\color@rgb#1{\color@rgb@#1\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@rgb@#1,#2,#3\@@{\color@@{rgb #1 #2 #3}}
%    \end{macrocode}
%
% CMYK
%    \begin{macrocode}
\def\color@cmyk#1{\color@cmyk@#1\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@cmyk@#1,#2,#3,#4\@@{\color@@{cmyk #1 #2 #3 #4}}
%    \end{macrocode}
%
% Grey
%    \begin{macrocode}
\def\color@gray#1{\color@@{gray #1}}
%    \end{macrocode}
%
% \subsection{Defining Colours}
%
%    \begin{macrocode}
\def\definecolor@named#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@named{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@gray#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@gray{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@rgb#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@rgb{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@cmyk#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@cmyk{#2}}}
%    \end{macrocode}
%
% \subsection{Initialisation}
% Specify Black in the internal syntax of the `named' model.
%
%    \begin{macrocode}
\def\current@color{Black}
%    \end{macrocode}
%
%    \begin{macrocode}
%</ref1>
%    \end{macrocode}
%
% \section{{\ttfamily ref2.col}, {\ttfamily ref2b.col}}
%    \begin{macrocode}
%<*ref2|ref2b>
%    \end{macrocode}
%
% \subsection{specials}
%
% Defines |named| |rgb| |gray| |cmyk| models.
% Full checking is done on all models.
% User defined colours are checked at time of definition, and then 
% defined in terms of an `unchecked' version of the appropriate model.
%
%    \begin{macrocode}
\def\set@color{%
  \special{color push \current@color}\aftergroup\reset@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\reset@color{\special{color pop}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\set@page@color{\special{background \current@color}}
%    \end{macrocode}
%
%
% \subsection{Using Colours}
%
% \subsubsection{Checking named colours}
% Named colours are only accepted if |\col@|\emph{name}
% is defined. 
%    \begin{macrocode}
%<*ref2>
\def\color@named#1{%
  \expandafter\ifx\csname col@#1\endcsname\color@check
    \color@named@{#1}%
  \else
    \UndefinedColor
  \fi}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@check{\color@check}
%</ref2>
%    \end{macrocode}
%
% |ref2| only allows the additive primary colours.
%    \begin{macrocode}
%<*ref2>
\let\col@Black\color@check % Black is OK
\let\col@White\color@check % White is OK
\let\col@Red\color@check   % Red   is OK
\let\col@Green\color@check % Green is OK
\let\col@Blue\color@check  % Blue  is OK
%</ref2>
%    \end{macrocode}
%
% |ref2b| makes a macro name out of a comma separated list of the
% allowed colour names. This is more efficient on memory but slower.
% Actually the present implementation is not very good, as each name
% that is checked results in a macro name being defined, which spoils
% some of the efficiency if the document uses a lot of colours.
%    \begin{macrocode}
%<*ref2b>
\def\color@named#1{%
  \begingroup
    \escapechar\m@ne
    \edef\@tempa{%
      \noexpand\in@
         {\expandafter\string\csname,#1,\endcsname}%
         {\expandafter\string\color@check}}%
    \@tempa
    \ifin@
      \endgroup\color@named@{#1}%
    \else
      \endgroup\UndefinedColor
    \fi}
%    \end{macrocode}
%
%    \begin{macrocode}
\edef\color@check{\expandafter\noexpand\csname
,%
Black,% Black is OK
White,% White is OK
Red,%   Red   is OK
Green,% Green is OK
Blue,%  Blue  is OK
\endcsname}
%</ref2b>
%    \end{macrocode}
%
% Unchecked version for user defined colours (already checked).
% 
%    \begin{macrocode}
\def\color@@#1{%
  \def\current@color{#1}%
  \set@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\let\color@named@\color@@
%    \end{macrocode}
%
% \subsubsection{Checking Numeric colour models}
%
% |\color@arg| produces a \TeX\ error if its argument is not a real
% number between $0$~and~$1$.
%    \begin{macrocode}
\def\color@arg#1{%
  \dimen@#1\p@
  \ifdim\dimen@<\z@\out@of@range
  \else\ifdim\dimen@>\p@\out@of@range
  \fi\fi}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@rgb#1{\color@@rgb#1\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@@rgb#1,#2,#3\@@{%
  \color@arg{#1}%
  \color@arg{#2}%
  \color@arg{#3}%
  \color@rgb@{ #1 #2 #3}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@rgb@#1{\color@@{rgb #1}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@cmyk#1{\color@@cmyk#1\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@@cmyk#1,#2,#3,#4\@@{%
  \color@arg{#1}%
  \color@arg{#2}%
  \color@arg{#3}%
  \color@arg{#4}%
  \color@cmyk@{#1 #2 #3 #4}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@cmyk@#1{\color@@{cmyk #1}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@gray#1{%
  \color@arg{#1}%
  \color@gray@{#1}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@gray@#1{\color@@{gray #1}}
%    \end{macrocode}
%
% \subsection{Defining Colours}
%
%    \begin{macrocode}
%<*ref2>
\def\definecolor@named#1#2{%
  \expandafter\ifx\csname col@#2\endcsname\color@check
    \expandafter\def\csname\string\color @#1\endcsname{%
                            \color@named@{#2}}%
  \else
    \UndefinedColor
  \fi}
%</ref2>
%    \end{macrocode}
%
%    \begin{macrocode}
%<*ref2b>
\def\definecolor@named#1#2{%
  \begingroup
    \escapechar\m@ne
    \edef\@tempa{%
      \noexpand\in@
         {\expandafter\string\csname,#2,\endcsname}%
         {\expandafter\string\color@check}}%
    \@tempa
    \ifin@
      \endgroup
      \expandafter\def\csname\string\color @#1\endcsname{%
                            \color@named@{#2}}%
    \else
      \endgroup\UndefinedColor
    \fi}
%</ref2b>
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@gray#1#2{%
  \color@arg{#2}%
  \expandafter\def\csname\string\color @#1\endcsname{%
                          \color@gray@{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@rgb#1#2{\definecolor@rgb@{#1}#2\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@rgb@#1#2,#3,#4\@@{%
  \color@arg{#2}%
  \color@arg{#3}%
  \color@arg{#4}%
  \expandafter\def\csname\string\color @#1\endcsname{%
                          \color@rgb@{#2 #3 #4}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@cmyk#1#2{\definecolor@cmyk@{#1}#2\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@cmyk@#1#2,#3,#4,#5\@@{%
  \color@arg{#2}%
  \color@arg{#3}%
  \color@arg{#4}%
  \color@arg{#5}%
  \expandafter\def\csname\string\color @#1\endcsname{%
                          \color@cmyk@{#2 #3 #4 #5}}}
%    \end{macrocode}
%
% \subsection{Initialisation}
% Specify Black in the internal syntax of the `named' model.
%
%    \begin{macrocode}
\def\current@color{Black}
%    \end{macrocode}
%
%    \begin{macrocode}
%</ref2|ref2b>
%    \end{macrocode}
%
% \section{\ttfamily ref3.col}
%    \begin{macrocode}
%<*ref3>
%    \end{macrocode}
%
% Defines |named| |rgb| |gray| |cmyk| models.
% No checking is done on any model.
%
% \subsection{specials}
% |ref3| does not use the inbuilt colour stack provided by dvips. It
% provides a model for a file for a dvi driver that only allows specials
% that change the current colour using the native target language
% (PostScript in this case). For reasons given in |thoughts.tex| this
% driver is unable to fully support \LaTeX\ floats. If the example
% document |testcol.tex| is used with this driver, the phrase
% `black (but not with ref3 or literalPS)'
% is typeset in red, not black. Note that this is on a page on to which
% a figure environment has `floated'. All the other supplied driver
% files do correctly set this phrase to black (including |ref0.col|!).
% If used directly, |ref3| also does not correctly treat any saved box.
% After any text inserted by a |\usebox| command, the colour will be
% restored to the colour at the time the box was saved. This also
% affects the labels used in \LaTeX\ list environments. As the
% positioning of these boxes is under \LaTeX\ comtrol, this may be
% compensated for by adding an extra |\color@set| command after every
% |\usebox| command. The |literalPS| option of the |color| package uses
% this driver file, but modifies certain \LaTeX\ commands to compensate
% for the lack of a colour stack. The file |testcol.tex| has some
% examples that show the behaviour of the various options.
%    \begin{macrocode}
\def\set@color{%
  \special{ps: \current@color}\aftergroup\reset@color}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\reset@color{\special{ps: \current@color}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\set@page@color{%
  \write\sixt@@n{background color ignored: \current@color}}
%    \end{macrocode}
%
% \subsection{Using Colours}
%
%
% `named' colours are immediately converted to RGB values.
%    \begin{macrocode}
\def\color@named#1{%
  \edef\@tempa{\noexpand\color@rgb{\csname named@#1\endcsname}}%
  \@tempa}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\named@Black{0,0,0}
\def\named@White{1,1,1}
\def\named@Red  {1,0,0}
\def\named@Green{0,1,0}
\def\named@Blue {0,0,1}
%    \end{macrocode}
%
% RGB is supported.
%    \begin{macrocode}
\def\color@rgb#1{\color@rgb@#1\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@rgb@#1,#2,#3\@@{%
  \edef\current@color{#1 #2 #3 setrgbcolor}%
  \set@color}
%    \end{macrocode}
%
% CMYK is translated to RGB. (If the colours do not look the same after
% translation, do not blame me!)
% \changes{0.1b}{1994/03/02}{Remove surplus comma}
%    \begin{macrocode}
\def\cmyk@rgb#1{%
  \dimen@#1\p@
  \advance\dimen@\@tempdima
  \ifdim\dimen@>\p@
    \dimen@\z@
  \else
    \advance\dimen@-\p@
    \dimen@-\dimen@
  \fi
  \edef\@tempa{\@tempa,\strip@pt\dimen@}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@cmyk#1{\color@cmyk@#1\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\color@cmyk@#1,#2,#3,#4\@@{%
  \@tempdima#4\p@
  \let\@tempa\@gobble
  \cmyk@rgb{#1}%
  \cmyk@rgb{#2}%
  \cmyk@rgb{#3}%
  \expandafter\color@rgb\expandafter{\@tempa}}
%    \end{macrocode}
%
% Grey is supported.
%    \begin{macrocode}
\def\color@gray#1{%
  \edef\current@color{#1 setgray}%
  \set@color}
%    \end{macrocode}
%
% \subsection{Defining Colours}
%
%    \begin{macrocode}
\def\definecolor@named#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@named{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@gray#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@gray{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@rgb#1#2{%
  \expandafter\def\csname\string\color @#1\endcsname{\color@rgb{#2}}}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@cmyk#1#2{%
  \definecolor@cmyk@{#1}#2\@@}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\definecolor@cmyk@#1#2,#3,#4,#5\@@{%
  \@tempdima#5\p@
  \let\@tempa\@gobble
  \cmyk@rgb{#2}%
  \cmyk@rgb{#3}%
  \cmyk@rgb{#4}%
  \edef\@tempa{\noexpand\definecolor@rgb{#1}{\@tempa}}%
  \@tempa}
%    \end{macrocode}
%
% \subsection{Initialisation}
% Specify Black in the internal syntax of the |gray| model.
%
%    \begin{macrocode}
\def\current@color{0 setgray}
%    \end{macrocode}
%
%    \begin{macrocode}
%</ref3>
%    \end{macrocode}
%
% \Finale
%







