% \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} % % \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} % % \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} % % \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} % % \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 % % \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} % % \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} % % \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} % % \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} % % \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} % % \end{macrocode} % % \Finale %