%D \module %D [ file=colo-ini, %D version=1997.4.1, %D title=\CONTEXT\ Color Macros, %D subtitle=Initialization, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA / Hans Hagen \& Ton Otten}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{Context Color Macros} %D To do: stroke versus fill color \unprotect %D Color support is not present in \TEX. Colorful output can %D however be accomplished by using specials. This also means %D that this support depends on the \DVI\ driver used. At the %D moment this module was written, still no decent standard on %D color specials has been agreed upon. We therefore decided to %D implement a mechanism that is as independant as possible of %D drivers. %D %D Color support shares with fonts that is must be implemented %D in a way that permits processing of individual \DVI\ pages. %D Furthermore it should honour grouping. The first condition %D forces us to use a scheme that keeps track of colors at %D page boundaries. This can be done by means of \TEX's %D marking mechanism (\type{\mark}). %D %D When building pages, \TEX\ periodically looks at the %D accumulated typeset contents and breaks the page when %D suitable. At that moment, control is transfered to the %D output routine. This routine takes care of building the %D pagebody and for instance adds headers and footers. The page %D can be broken in the middle of some colored text, but %D headers and footers are often in black upon white or %D background. If colors are applied there, they definitely %D are used local, which means that they don't cross page %D borders. %D %D Boxes are handled as a whole, which means that when we %D apply colors inside a box, those colors don't cross page %D boundaries, unless of course boxes are split or unboxed. %D Especially in interactive texts, colors are often used in %D such a local way: in boxes (buttons and navigational tools) %D or in the pagebody (backgrounds). %D %D So we can distinguish local colors, that don't cross %D pages from global colors, of which we can end many pages %D later. The color macros will treat both types in a different %D way, thus gaining some speed. %D %D This module also deals with gray scales. Because similar %D colors can end up in the same gray scale when printed in %D black and white, we also implement a palet system that deals %D with these matters. Because of fundamental differences %D between color and gray scale printing, in \CONTEXT\ we also %D differ between these. For historic reasons |<|we first %D implemented gray scales using patterns of tiny periods|>| %D and therefore called them {\em rasters}. So don't be %D surprised if this term shows up. \startmessages dutch library: colors title: kleur 1: systeem -- is globaal actief 2: systeem -- is lokaal actief 3: -- is niet gedefinieerd 4: systeem -- wordt geladen 5: onbekend systeem -- 6: palet -- is beschikbaar 7: palet -- is niet beschikbaar 8: specificatie -- bij -- wordt zwart 9: -- kleurruimte wordt niet ondersteund 10: -- kleurruimte wordt ondersteund 11: kleur wordt vertaald in grijs \stopmessages \startmessages english library: colors title: color 1: system -- is global activated 2: system -- is local activated 3: -- is not defined 4: system -- is loaded 5: unknown system -- 6: palette -- is available 7: palette -- is not available 8: specification -- at color -- becomes black 9: -- color space is not supported 10: -- color space is supported 11: color is converted to gray \stopmessages \startmessages german library: colors title: farbe 1: system -- ist global aktiviert 2: system -- ist lokal aktiviert 3: -- ist undefiniert 4: system -- ist geladen 5: unbekanntes System -- 6: palette -- ist verfuegbar 7: palette -- ist nicht verfuegbar 8: Spezifikation -- bei Farbe -- wird schwarz 9: -- Farbraum wird nicht unterstuetzt 10: -- Farbraum wird unterstuetzt 11: Farbe wird in Grau umgewandelt \stopmessages \startmessages czech library: colors title: barva 1: system -- je globalne aktivovana 2: system -- je lokalne activovana 3: -- neni definovana 4: system -- je nacten 5: neznamy system -- 6: palette -- je k dispozici 7: palette -- neni k dispozici 8: specifikace -- v barve -- bude cerna 9: -- prostor barev neni podporovan 10: -- prostor barev je podporovan 11: barva je prevedena na sed \stopmessages \startmessages italian library: colors title: colore 1: sistema -- attivato globalmente 2: sistema -- attivato localmente 3: -- non definito 4: sistema -- caricato 5: sistema -- sconosciuto 6: tavolozza -- resa disponibile 7: tavolozza -- non disponibile 8: specifica -- del colore -- convertita in nero 9: spazio dei colori -- non supportato 10: spazio dei colori -- supportato 11: il colore è convertito in grigio \stopmessages \startmessages norwegian library: colors title: farge 1: system -- er aktivert globalt 2: system -- er aktivert lokalt 3: -- er udefinert 4: system -- er lest inn 5: ukjent system -- 6: palett -- er tilgjengelig 7: palett -- er ikke tilgjengelig 8: spesifikasjon -- for farge -- gir kun svart 9: -- fargerom er ikke støttet 10: -- fargerom er støttet 11: fargen vil bli vist som grå \stopmessages \startmessages romanian library: colors title: culori 1: sistem -- este activata global 2: sistem -- este activata local 3: -- nu este definita 4: sistem -- este incarcata 5: sistem -- necunoscuta 6: paleta -- este disponibila 7: palette -- nu este disponibila 8: specificatia -- la culoarea -- devine neagra 9: spatiul de culoare -- nu este suportat 10: spatiul de culoare -- este suportat 11: culoarea este convertita la gri \stopmessages %D We use a couple of local registers. That way we don't have %D to group when converting colors. By the way, this is not %D really faster. We can sqeeze half a second runtime for 50K %D switches on a 1G machine, but the macros will become rather %D ugly then. To mention one such improvement: no colon %D after the key character (.25 sec). \newdimen\colordimen \newcount\colorcount %D \macros %D {definecolor} %D %D We will enable users to specify colors in \kap{RGB} and %D \kap{CMYK} color spaces or gray scales using %D %D \showsetup{\y!definecolor} %D %D For example: %D %D \starttypen %D \definecolor [SomeKindOfRed] [r=.8,g=.05,b=.05] %D \stoptypen %D %D Such color specifications are saved in a macro in the %D following way: %D %D \starttypen %D \setvalue{\??cr name}{R:r:g:b} %D \setvalue{\??cr name}{C:c:m:y:k} %D \setvalue{\??cr name}{S:s} %D \stoptypen %D %D Gray scales are specified with the \type{s} parameter, %D where the \type {s} is derived from {\em screen}. %D %D Starting with \PDF\ 1.4 (2001) \CONTEXT\ supports %D transparent colors. The transparency factor is represented %D by a \type {t} and the transparency method by an \type {a} %D (alternative). Later we will implement more control %D (probably by symbolic methods. So, currently the data is %D stored as follows: %D %D \starttypen %D \setvalue{\??cr name}{R:r:g:b:a:t} %D \setvalue{\??cr name}{C:c:m:y:k:a:t} %D \setvalue{\??cr name}{S:s:a:t} %D \stoptypen \let\colorlist\empty \def\@@cl@@z{0} \def\@@cl@@o{1} \def\@@resetcolorparameters {\let\@@cl@@r\@@cl@@z\let\@@cl@@g\@@cl@@z\let\@@cl@@b\@@cl@@z \let\@@cl@@c\@@cl@@z\let\@@cl@@m\@@cl@@z\let\@@cl@@y\@@cl@@z \let\@@cl@@k\@@cl@@z\let\@@cl@@s\@@cl@@z \let\@@cl@@t\@@cl@@z\let\@@cl@@a\@@cl@@z} \def\@@cl@@A{\@@cl@@a} % a hook for symbolic conversion, see below \def\colorZpattern{S:\@@cl@@z:\@@cl@@A:\@@cl@@t} \def\colorSpattern{S:\@@cl@@s:\@@cl@@A:\@@cl@@t} \def\colorCpattern{C:\@@cl@@c:\@@cl@@m:\@@cl@@y:\@@cl@@k:\@@cl@@A:\@@cl@@t} \def\colorRpattern{R:\@@cl@@r:\@@cl@@g:\@@cl@@b:\@@cl@@A:\@@cl@@t} \def\definecolor% {\dodoubleargument\dodefinecolor} \def\dodefinecolor[#1][#2]% {\addtocommalist{#1}\colorlist \doifassignmentelse{#2} {\@@resetcolorparameters \getparameters[\??cl @@][#2]% \doifelse{\@@cl@@r\@@cl@@g\@@cl@@b}{\@@cl@@z\@@cl@@z\@@cl@@z} {\doifelse{\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k}{\@@cl@@z\@@cl@@z\@@cl@@z\@@cl@@z} {\doifelse{\@@cl@@s}{\@@cl@@z} {\showmessage{\m!colors}{8}{{[#2]},#1}% \setevalue{\??cr#1}{\colorZpattern}} {\setevalue{\??cr#1}{\colorSpattern}}} {\setevalue{\??cr#1}{\colorCpattern}}} {\setevalue{\??cr#1}{\colorRpattern}}} {\doifdefinedelse{\??cr#2} {\setevalue{\??cr#1}{\getvalue{\??cr#2}}} {\showmessage{\m!colors}{3}{#1}}}% \unexpanded\setvalue{#1}{\color[#1]}} % \unexpanded toegevoegd %D The names of colors are stored in a comma separated list %D only for the purpose of showing them with \type {\showcolor}. %D %D \typebuffer %D \haalbuffer %D %D This color shows up as \color[SomeKindOfRed]{some kind %D of red}. %D \macros %D {setupcolor} %D %D Color definitions can be grouped in files with the name: %D %D \starttypen %D \f!colorprefix-identifier.tex %D \stoptypen %D %D where \type{\f!colorprefix} is \unprotect {\tttf \f!colorprefix}. %D Loading such a file is done by \protect %D %D \showsetup{\y!setupcolor} %D %D Some default colors are specified in \type{colo-rgb.tex}, %D which is loaded into the format by: %D %D \starttypen %D \setupcolor[rgb] %D \stoptypen \let\colorstyle\empty \def\setupcolor% {\dosingleargument\dosetupcolor} \def\dosetupcolor[#1]% {\doifnot{#1}{\colorstyle} {\def\colorstyle{#1}% \processcommalist[#1]\dodosetupcolor}} \def\dodosetupcolor#1% {\makeshortfilename[\f!colorprefix\truefilename{#1}]% \readsysfile\shortfilename {\showmessage\m!colors4\colorstyle} {\showmessage\m!colors5\colorstyle}} %D When typesetting for paper, we prefer using the \kap{CMYK} %D color space, but for on||screen viewing we prefer \kap{RGB} %D (the previous implementation supported only this scheme). %D Independant of such specifications, we support some automatic %D conversions: %D %D \startopsomming[opelkaar] %D \som convert all colors to \kap{RGB} %D \som convert all colors to \kap{CMYK} %D \som convert all colors to gray scales %D \stopopsomming %D %D We also support optimization of colors to gray scales. %D %D \startopsomming[verder] %D \som reduce gray colors to gray scales %D \som reduce \kap{CMY} components to \kap{K} %D \stopopsomming %D %D These options are communicated by means of: \newif\ifRGBsupported \newif\ifCMYKsupported \newif\ifpreferGRAY \newif\ifGRAYprefered \newif\ifreduceCMYK %D The last boolean controls reduction of \kap{CMYK} to %D \kap{CMY} colors. When set to true, the black component %D is added to the other ones. %D %D Prefering gray is not the same as converting to gray. %D Conversion treats each color components in a different way, %D while prefering is just a reduction and thus a %D space||saving option. %D The next (internal) switch suppresses duplicate messages. \newif\ifconverttoGRAY %D This module also needs: % \newif\ifMPgraphics % \newif\ifinpagebody %D \macros %D {startcolormode,stopcolormode,permitcolormode} %D %D We use \type{\stopcolormode} to reset the color in %D whatever color space and do so by calling the corresponding %D special. Both commands can be used for fast color %D switching, like in colored verbatim, \newif\ifpermitcolormode \permitcolormodetrue %D Since color is used frequently today (at least by the %D author of this module) it makes sense to optimize switching %D to the max. %D %D \starttypen %D \def\startcolormode#1% %D {\ifincolor\ifpermitcolormode %D \doifcolorelse{#1} %D {\getcurrentcolorspecs{#1}% %D \expandafter\dostartcolormode\currentcolorspecs\od} %D {\nostartcolormode}% %D \fi\fi} %D \stoptypen %D %D So, the more readable alternatives like the one above are %D gone now. \beginETEX \ifcsname \def\dowithcolor#1#2% #1=\action #2=color {\ifincolor\ifpermitcolormode \ifcsname\??cr\currentpalet#2\endcsname \@EAEAEA#1\csname\??cr\currentpalet#2\endcsname\od \else\ifcsname\??cr#2\endcsname \@EAEAEA#1\csname\??cr#2\endcsname\od \fi\fi \fi\fi} \endETEX \beginTEX \def\dowithcolor#1#2% #1=\action #2=color {\ifincolor\ifpermitcolormode \@EA\ifx\csname\??cr\currentpalet#2\endcsname\relax \@EA\ifx\csname\??cr#2\endcsname\relax \else \@EAEAEA#1\csname\??cr#2\endcsname\od \fi \else \@EAEAEA#1\csname\??cr\currentpalet#2\endcsname\od \fi\fi \fi\fi} \endTEX \def\startcolormode % includes \ifincolor\ifpermitcolormode {\dowithcolor\execcolorRCS} \def\stopcolormode {\ifincolor\ifpermitcolormode \dostoptransparency \dostopcolormode \fi\fi} %D Color modes are entered using the next set of commands. %D The \type{\stop} alternatives are implemented in a way %D that permits non||grouped use. %D %D The, for this module redundant, check if we are in color %D mode is needed when we use these macros in other modules. \def\execcolorRCS#1:% {\csname execcolor#1\endcsname} \def\execcolorR#1:#2:#3:% {\edef\@@cl@@r{#1}\edef\@@cl@@g{#2}\edef\@@cl@@b{#3}% \ifpreferGRAY\ifx\@@cl@@r\@@cr@@g\ifx\@@cl@@r\@@cl@@b \GRAYpreferedtrue \fi\fi\fi \ifincolor\else\RGBsupportedfalse\CMYKsupportedfalse\fi \ifGRAYprefered \dostartgraycolormode\@@cl@@r \else\ifRGBsupported \dostartrgbcolormode\@@cl@@r\@@cl@@g\@@cl@@b \else\ifCMYKsupported \convertRGBtoCMYK\@@cl@@r\@@cl@@g\@@cl@@b \dostartcmykcolormode\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k \else \convertRGBtoGRAY\@@cl@@r\@@cl@@g\@@cl@@b \dostartgraycolormode\@@cl@@s \fi\fi\fi \exectransparency} \def\execcolorC#1:#2:#3:#4:% {\edef\@@cl@@c{#1}\edef\@@cl@@m{#2}\edef\@@cl@@y{#3}\edef\@@cl@@k{#4}% \ifpreferGRAY\ifx\@@cl@@k\@@cl@@z\ifx\@@cl@@c\@@cr@@m\ifx\@@cl@@c\@@cl@@y \GRAYpreferedtrue \fi\fi\fi\fi \ifincolor\else\RGBsupportedfalse\CMYKsupportedfalse\fi \ifGRAYprefered \dostartgraycolormode\@@cl@@c \else\ifCMYKsupported \ifreduceCMYK \convertCMYKtoCMY\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k \fi \dostartcmykcolormode\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k \else\ifRGBsupported \convertCMYKtoRGB\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k \dostartrgbcolormode\@@cl@@r\@@cl@@g\@@cl@@b \else \convertCMYKtoGRAY\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k \dostartgraycolormode\@@cl@@s \fi\fi\fi \exectransparency} \def\execcolorS#1:% {\dostartgraycolormode{#1}% \exectransparency} %D Transparency is handled similar for all three color modes. We %D can turn transparency off with the following switch: \newif\iftransparancysupported \transparancysupportedtrue % todo \def\exectransparency {\iftransparancysupported \expandafter\doexectransparency \else \expandafter\noexectransparency \fi} \def\doexectransparency#1:#2\od {\global\@EA\chardef\csname\@@currenttransparent\endcsname % nasty \ifcase#1\space \zerocount \else \plusone \dostarttransparency{#1}{#2}% \fi} \def\noexectransparency#1\od {} %D Todo: minimize resets. \def\conditionalstoptransparancy {\ifcase\csname\@@currenttransparent\endcsname\or \dostoptransparency \fi} %D We now use the \type {\@@cl@@A} hook to implement %D symbolic names. These are converted into numbers %D at definition time (which saves runtime). \def\definetransparency {\dodoubleargument\dodefinetransparency} %\def\dodefinetransparency[#1][#2]% % {\@EA\chardef\csname\??cl-#1\endcsname#2\relax % \ifundefined{\??cl-#2}#2\else\csname\??cl-#2\endcsname\fi} \def\dodefinetransparency[#1][#2]% {\@EA\chardef\csname\??cl-#1\endcsname#2\relax} \def\transparencynumber#1% {\the\executeifdefined{\??cl-#1}\zerocount} \definetransparency [none] [0] \definetransparency [0] [0] \definetransparency [normal] [1] \definetransparency [1] [1] \definetransparency [multiply] [2] \definetransparency [2] [2] \definetransparency [screen] [3] \definetransparency [3] [3] \definetransparency [overlay] [4] \definetransparency [4] [4] \definetransparency [softlight] [5] \definetransparency [5] [5] \definetransparency [hardlight] [6] \definetransparency [6] [6] \definetransparency [colordodge] [7] \definetransparency [7] [7] \definetransparency [colorburn] [8] \definetransparency [8] [8] \definetransparency [darken] [9] \definetransparency [9] [9] \definetransparency [lighten] [10] \definetransparency [10] [10] \definetransparency [difference] [11] \definetransparency [11] [11] \definetransparency [exclusion] [12] \definetransparency [12] [12] %D Now we hook 'm into the patterns: \def\@@cl@@A{\transparencynumber\@@cl@@a} %D \macros %D {startregistercolor,stopregistercolor,permitcolormode} %D %D If you only want to register a color, the switch \type %D {\ifpermitcolormode} can be used. That way the nested %D colors know where to go back to. \def\startregistercolor[#1]% {\permitcolormodefalse\startcolor[#1]\permitcolormodetrue} \def\stopregistercolor {\permitcolormodefalse\stopcolor\permitcolormodetrue} %D We use these macros for implementing text colors %D (actually, the first application was in foreground %D colors). %D %D \starttypen %D \starttextcolor[red] %D \dorecurse{10}{\input tufte \color[green]{oeps} \par} %D \stoptextcolor %D \stoptypen %D %D This is more efficient than the alternative: %D %D \starttypen %D \setupbackgrounds[text][foregroundcolor=red] %D \startregistercolor[red] %D \dorecurse{10}{\input tufte \color[green]{oeps} \par} %D \stopregistercolor %D \stoptypen \let\maintextcolor\empty \def\starttextcolor[#1]% {\doifsomething{#1} {\bgroup \def\stoptextcolor % also goes ok with \page after {\let\maintextcolor\empty % this one because the top of \stopregistercolor % page sets the color right (side \egroup}% % effect) \def\starttextcolor[##1]% {\bgroup \let\stoptextcolor\egroup}% \startregistercolor[#1]% \def\maintextcolor{#1}}} \let\stoptextcolor\relax %D The following hook permits proper support at the text %D level. This definition actually belongs in another %D module. \ifx\initializemaintextcolor\undefined % \let\initializemaintextcolor\relax \def\initializemaintextcolor {\doifsomething{\@@cltekstkleur} {\appendtoks\starttextcolor[\@@cltekstkleur]\to\everystarttext \appendtoks\stoptextcolor \to\everystoptext \let\initializemaintextcolor\relax}} \fi %D The next macro can be used to return to the (normal) %D page color. This macro is used in the same way as %D \type {\color}. \def\restoretextcolor {\ifx\maintextcolor\empty \expandafter\dorestoretextcolor \else % obey main text color \fi} \def\dorestoretextcolor {\color[black]} %D We use some reserved names for local color components. %D Consistent use of these scratch variables saves us %D unneccessary hash entries. %D %D \starttypen %D \@@cl@@r \@@cl@@g \@@cl@@b %D \@@cl@@c \@@cl@@m \@@cl@@y \@@cl@@k %D \@@cl@@s %D \stoptypen %D %D We implement several conversion routines. %D %D \starttypen %D \convertRGBtoCMYK {r} {g} {b} %D \convertRGBtoGRAY {r} {g} {b} %D \convertCMYKtoRGB {c} {m} {y} {k} %D \convertCMYKtoGRAY {c} {m} {y} {k} %D \convertCMYKtoCMY {c} {m} {y} {k} %D \stoptypen %D %D The relation between \kap{Gray}, \kap{RGB} and \kap{CMYK} %D is: %D %D \plaatsformule[-] %D \startformule %D G = .30r + .59g + .11b %D = 1.0 - \min(1.0,\ .30c + .59m + .11y + k) %D \stopformule %D %D When converting from \kap{CMYK} to \kap{RGB} we use the %D formula: %D %D \plaatsformule[-] %D \startformule %D \eqalign %D {r &= 1.0 - \min(1.0,\ c+k) \cr %D g &= 1.0 - \min(1.0,\ m+k) \cr %D b &= 1.0 - \min(1.0,\ y+k)} %D \stopformule %D %D In the conversion routine the color components are calculated %D in three digits precision. \def\realcolorvalue#1% {\ifnum#1<10 0.00\the#1\else \ifnum#1<100 0.0\the#1\else \ifnum#1<1000 0.\the#1\else 1\fi\fi\fi} \def\doconvertCMYKtoRGB#1\k#2\to#3% {\ifdim#2\s!pt<#1\s!pt \colordimen1\s!pt \advance\colordimen -#1\s!pt \advance\colordimen -#2\s!pt \multiply\colordimen 1000 \colorcount\colordimen \advance\colorcount \medcard \divide\colorcount \maxcard \edef#3{\realcolorvalue\colorcount}% \else % k >= color \let#3\@@cl@@z \fi} \def\convertCMYKtoRGB#1#2#3#4% {\doconvertCMYKtoRGB#1\k#4\to\@@cl@@r \doconvertCMYKtoRGB#2\k#4\to\@@cl@@g \doconvertCMYKtoRGB#3\k#4\to\@@cl@@b} \def\doconvertRGBtoCMYK#1\to#2% {\colordimen#1\s!pt \multiply\colordimen 1000 \colorcount\colordimen \advance\colorcount \medcard \divide\colorcount \maxcard \colorcount-\colorcount \advance\colorcount 1000 \edef#2{\realcolorvalue\colorcount}} \def\convertRGBtoCMYK#1#2#3% {\doconvertRGBtoCMYK#1\to\@@cl@@c \doconvertRGBtoCMYK#2\to\@@cl@@m \doconvertRGBtoCMYK#3\to\@@cl@@y \let\@@cl@@k\@@cl@@z} %D The following switch is mainly meant for (hidden) %D documentation purposes. \newif\ifweightGRAY \weightGRAYtrue \def\nGRAYfactor{333.333} \def\rGRAYfactor{\ifweightGRAY300\else\nGRAYfactor\fi} \def\gGRAYfactor{\ifweightGRAY590\else\nGRAYfactor\fi} \def\bGRAYfactor{\ifweightGRAY110\else\nGRAYfactor\fi} \def\convertRGBtoGRAY#1#2#3% {\colordimen#1\s!pt \colordimen\rGRAYfactor\colordimen \colorcount\colordimen \colordimen#2\s!pt \colordimen\gGRAYfactor\colordimen \advance\colorcount \colordimen \colordimen#3\s!pt \colordimen\bGRAYfactor\colordimen \advance\colorcount \colordimen \advance\colorcount \medcard \divide\colorcount \maxcard \edef\@@cl@@s{\realcolorvalue\colorcount}} \def\convertCMYKtoGRAY#1#2#3#4% {\convertCMYKtoRGB{#1}{#2}{#3}{#4}% \convertRGBtoGRAY\@@cl@@r\@@cl@@g\@@cl@@b} \def\doconvertCMYKtoCMY#1\k#2\to#3% {\colordimen#1\s!pt \advance\colordimen #2\s!pt\relax \ifdim\colordimen>1\s!pt \colordimen1\s!pt %\else % \colordimen\colordimen \fi \multiply\colordimen 1000 \colorcount\colordimen \advance\colorcount \medcard \divide\colorcount \maxcard \edef#3{\realcolorvalue\colorcount}} \def\convertCMYKtoCMY#1#2#3#4% {\doconvertCMYKtoCMY#1\k#4\to\@@cl@@c \doconvertCMYKtoCMY#2\k#4\to\@@cl@@m \doconvertCMYKtoCMY#3\k#4\to\@@cl@@y \let\@@cl@@k\@@cl@@z} %D Before we present the color macros, we first define the %D setup command. This command takes care of setting up the %D booleans that control local and global behavior (more on %D that later) and conversion to other color spaces. \newif\ifincolor \newif\iflocalcolor \def\setupcolors% {\dosingleargument\dosetupcolors} \def\dosetupcolors[#1]% {\getparameters[\??cl][#1]% \doifelse\@@clreductie\v!ja \reduceCMYKtrue \reduceCMYKfalse \doifelse\@@clrgb\v!nee {\ifRGBsupported \showmessage\m!colors {9}\v!rgb\RGBsupportedfalse\fi} {\ifRGBsupported\else\showmessage\m!colors{10}\v!rgb\RGBsupportedtrue \fi}% \doifelse\@@clcmyk\v!nee {\ifCMYKsupported \showmessage\m!colors {9}\v!cmyk\CMYKsupportedfalse\fi} {\ifCMYKsupported\else\showmessage\m!colors{10}\v!cmyk\CMYKsupportedtrue \fi}% \doifelse\@@clmpcmyk\v!nee {\ifMPcmyk \showmessage\m!colors {9}{\v!mp\v!cmyk}\MPcmykfalse\fi} {\ifMPcmyk\else\showmessage\m!colors{10}{\v!mp\v!cmyk}\MPcmyktrue \fi}% % \processaction % [\@@clconversie] % [ \v!ja=>\preferGRAYtrue, % \v!nee=>\preferGRAYfalse, % \v!altijd=>\preferGRAYtrue % \RGBsupportedfalse % \CMYKsupportedfalse, % \s!default=>\preferGRAYfalse, % \s!unknown=>\preferGRAYfalse]% % \preferGRAYfalse \processaction [\@@clconversie] [ \v!ja=>\preferGRAYtrue, \v!altijd=>\preferGRAYtrue\RGBsupportedfalse\CMYKsupportedfalse]% % \ifRGBsupported \converttoGRAYfalse \forcegrayMPcolorsfalse \else\ifCMYKsupported \converttoGRAYfalse \forcegrayMPcolorsfalse \convertMPcolorstrue \ifreduceCMYK \reduceMPcolorstrue \fi \else \ifconverttoGRAY\else\showmessage\m!colors{11}\empty\fi \converttoGRAYtrue \forcegrayMPcolorstrue \convertMPcolorsfalse \reduceMPcolorsfalse \fi\fi \processaction [\@@clstatus] [\v!globaal=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi \incolortrue\localcolorfalse, \v!lokaal=>\ifincolor\else\showmessage\m!colors2\colorstyle\fi \incolortrue\localcolortrue, \v!start=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi \incolortrue\localcolorfalse \let\@@clstatus\v!globaal, \v!stop=>\incolorfalse\localcolorfalse \forcegrayMPcolorstrue]% \initializemaintextcolor} %D \macros %D {doifcolorelse} %D %D Switching to a color is done by means of the following %D command. Later on we will explain the use of palets. We %D define ourselves a color conditional first. \let\currentpalet\empty \beginETEX \ifcsname \def\doifcolorelse#1% {\ifcsname\??cr\ifcsname\??cr\currentpalet#1\endcsname\currentpalet\fi#1\endcsname \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} % no longer needed % % \def\getcurrentcolorspecs#1% % {\edef\currentcolorspecs% % {\csname\??cr % \ifcsname\??cr\currentpalet#1\endcsname\currentpalet\fi % #1\endcsname}} \endETEX \beginTEX \def\doifcolorelse#1% {\@EA\ifx\csname\??cr\@EA\ifx\csname\??cr\currentpalet#1\endcsname\relax\else\currentpalet\fi#1\endcsname\relax \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} % no longer needed % % \def\getcurrentcolorspecs#1% % {\edef\currentcolorspecs% % {\csname\??cr\@EA % \ifx\csname\??cr\currentpalet#1\endcsname\relax\else\currentpalet\fi % #1\endcsname}} \endTEX %D \macros %D {localstartcolor,localstopcolor} %D %D Simple color support, that is without nesting, is provided %D by: \def\localstartcolor {\ifincolor \localcolortrue \expandafter\doglobalstartcolor \else \expandafter\noglobalstartcolor \fi} \def\localstopcolor {\ifincolor \doglobalstopcolor \else \noglobalstopcolor \fi} %D \macros %D {startcolor,stopcolor} %D %D The more save method, the one that saves the current color %D state and returns to this state afterward, is activated by: %D %D \showsetup{\y!startcolor} \def\startcolor {\ifincolor \expandafter\doglobalstartcolor \else \expandafter\noglobalstartcolor \fi} \def\stopcolor% {\ifincolor \doglobalstopcolor \else \noglobalstopcolor \fi} %D This macros call the global color switching ones. Starting %D a global, i.e. a possible page boundary crossing, color %D mode also sets a \type{\mark} in \TEX's internal list. \newcount\colorlevel \letvalue{\??cl0C}\empty % saved color \letvalue{\??cl0S}\empty % stop command %D We keep a positive color stack for foreground colors, and %D a negative one for backgrounds. Not that brilliant a %D solution, but it suits. The signs are swapped when the %D page ornaments are typeset. \let\@@colorplus \plusone \let\@@colorminus\minusone \def\@@currentcolorname {\??cl\the\colorlevel C} \def\@@currentcolorstop {\??cl\the\colorlevel S} \def\@@currenttransparent{\??cl\the\colorlevel T} \def\dodoglobalstartcolor {\global\@EA\let\@EA\currentcolor\csname\@@currentcolorname\endcsname \global\advance\colorlevel \@@colorplus \global\@EA\let\csname\@@currentcolorname\endcsname\@@askedcolor %\debuggerinfo{\m!colors} % {start \@@askedcolor\space at level \the\colorlevel}% \ifx\@@askedcolor\empty \global\@EA\let\csname\@@currentcolorname\endcsname\currentcolor \global\@EA\let\csname\@@currentcolorstop\endcsname\donoglobalstopcolor \else\ifx\@@askedcolor\currentcolor \global\@EA\let\csname\@@currentcolorstop\endcsname\donoglobalstopcolor \else \doifcolorelse\@@askedcolor {\docolormark\@@askedcolor \global\@EA\let\csname\@@currentcolorstop\endcsname\dodoglobalstopcolor \startcolormode\@@askedcolor} {\global\@EA\let\csname\@@currentcolorstop\endcsname\donoglobalstopcolor \showmessage\m!colors3\@@askedcolor}% \fi\fi} \def\doglobalstartcolor[#1]% {\edef\@@askedcolor{#1}% \ifcase\colorlevel\relax \ifx\@@askedcolor\empty \global\@EA\let\csname\@@currentcolorstop\endcsname\empty \else \dodoglobalstartcolor \fi \else \dodoglobalstartcolor \fi \ignorespaces} \def\noglobalstartcolor[#1]% {} \def\dodoglobalstopcolor {\ifcase\colorlevel \else \donoglobalstopcolor \global\@EA\let\@EA\previouscolor\csname\@@currentcolorname\endcsname \ifcase\colorlevel\relax \docolormark\empty \dostoptransparency \dostopcolormode \else % let's do a bit redundant testing here \docolormark\previouscolor \ifx\previouscolor\empty \dostoptransparency \dostopcolormode \else \doifcolorelse\previouscolor {\ifx\currentcolor\previouscolor\else \startcolormode\previouscolor \fi} {\dostoptransparency \dostopcolormode}% \fi \fi \fi} \def\donoglobalstopcolor {\ifcase\colorlevel \else \global\@EA\let\@EA\currentcolor\csname\@@currentcolorname\endcsname %\debuggerinfo{\m!colors} % {stop \currentcolor\normalspace at level \the\colorlevel}% \global\advance\colorlevel \@@colorminus \fi} \def\doglobalstopcolor {\csname\@@currentcolorstop\endcsname} \let\noglobalstopcolor\relax %D We don't use grouping and save each stop alternative. This %D permits be especially useful in for instance local color %D support in verbatim. Using \type{\bgroup}||\type{\egroup} %D pairs could interfere with calling commands %D This color mechanism takes care of nested colors, like in: %D %D \startbuffer %D \kleur[groen]{groen \kleur[groen]{groen \kleur[rood]{rood}} groen} %D \kleur[groen]{groen \kleur[]{groen \kleur[rood]{rood}} groen} %D \kleur[groen]{groen \kleur[rood]{rood \kleur[rood]{rood}} groen} %D \kleur[groen]{groen \kleur[groen]{groen \kleur[]{groen}} groen} %D \kleur[groen]{groen \kleur[rood]{rood} groen} %D \kleur[groen]{groen \kleur[]{groen} groen} %D \kleur[]{zwart \kleur[rood]{rood} zwart} %D \kleur[]{zwart} %D \stopbuffer %D %D \typebuffer %D %D or %D %D \startvoorbeeld %D \startregels %D \haalbuffer %D \stopregels %D \stopvoorbeeld %D %D Crossing page boundaries is of course also handled. %D Undefined or empty color specifications are treated as %D efficient as possible. %D %D \startbuffer %D \startkleur[groen] %D [groen] \input tufte [groen] \par %D \startkleur[] %D [groen] \input knuth [groen] \par %D \startkleur[rood] %D [rood] \input tufte [rood] \par %D \startkleur[geel] %D [geel] \input knuth [geel] \par %D \stopkleur %D [rood] \input tufte [rood] \par %D \stopkleur %D [groen] \input knuth [groen] \par %D \stopkleur %D [groen] \input tufte [groen] \par %D \stopkleur %D \stopbuffer %D %D \startopelkaar %D \haalbuffer %D \stopopelkaar %D %D These quotes are typeset by saying: %D %D \typebuffer %D We already mentioned that colors interfere with building %D the pagebody. This means that when the page is composed, %D the colors temporary have to be reset. After the page is %D shipped out, we have to revive the current color. %D %D We use \type{\marks} to keep track of colors across page %D boundaries. Unfortunately standard \TEX\ supports only one mark, %D and using this one for color support only would be a waste. %D We therefore use an adapted version of J.~Fox's multiple mark %D mechanism as (re|)|implemented in \module{supp-mrk}. \doifdefinedelse{newmark} {\newmark\colormark} {\let\colormark\gobbleoneargument} %D Using this mark mechanism with lots of colors has one %D major drawback: \TEX's memory tends to overflow when %D very colorful text is stored in a global box. Even worse is that %D the processing time grows considerably. We therefore support %D local as well as global color switching. %D %D Of the next macros, \type {\popcolor} is to be used after %D the actual \type {\shipout} and \type {\startcolorpage} and %D \type {\stopcolorpage} are called when entering and leaving %D the \type {\pagebody} builder. In case of emergencies %D \type {\pushcolor} can be used to undo the current color, %D for instance when insertions are appended to the page. %D %D Out of efficiency we only use marks when needed. The next %D macro tries to find out if indeed a mark should be set. %D This macro uses the boolean \type {\ifinpagebody}, which can %D be defined and set in the module that handles the pagebody. \def\docolormark#1% {\iflocalcolor \else \ifinpagebody \else \ifinframed \else \dodocolormark{#1}% \fi \fi \fi} \let\lastcolormark=\empty \def\dodocolormark#1% {\edef\newcolormark{#1}% \ifx\newcolormark\lastcolormark\else \global\let\lastcolormark\newcolormark \@EA\setmark\@EA\colormark\@EA{\lastcolormark}% \fi} %D \macros %D {pushcolor, popcolor} %D %D Pushing the current state in the output routine simply comes %D to resetting the color to black, while popping restores the %D color state to that of before the break. \def\topofpagecolor{\getbotmark\colormark} % see postponing \def\pushcolor {\stopcolormode} \def\popcolor {\doifsomething{\getbotmark\colormark} {%\debuggerinfo{\m!colors}{popping \getbotmark\colormark}% \startcolormode{\getbotmark\colormark}}} \def\popsplitcolor% {\getsplitmarks\colormark % hier wel \doifsomething{\getsplitbotmark\colormark} {%\debuggerinfo{\m!colors}{split popping \getsplitbotmark\colormark}% \startcolormode{\getsplitbotmark\colormark}}} %D \macros %D {startcolorpage, stopcolorpage} %D %D Local use can be forced with the next two macros. Nesting %D is still supported but colors are no longer marked. %D %D The next implementation makes (simple) color separation more %D easy. It also supports nested colors in page backgrounds %D and texts. \def\startcolorpage% {\bgroup \let\@@colorplus \minusone \let\@@colorminus\plusone \let\docolormark\gobbleoneargument \edef\savedcolorlevel{\the\colorlevel}% \global\colorlevel\zerocount % before \localstartcolor of \localstartcolor[black]} % course, ugly bug removed \def\stopcolorpage% {\localstopcolor \global\colorlevel\savedcolorlevel \egroup} %D \macros %D {color,graycolor} %D %D This leaves the simple color command: %D %D \showsetup{\y!color} %D \showsetup{\y!graycolor} %D %D Which can be used straightforward: \color[groen]{green as gras}. %D We want color support to be similar to font support and %D therefore implement \type{\color} as: \unexpanded\def\color[#1]% {\groupedcommand {\startcolor[#1]}\stopcolor} \unexpanded\def\graycolor[#1]% not \gray because this is a color {\groupedcommand {\RGBsupportedfalse\CMYKsupportedfalse\startcolor[#1]}\stopcolor} \let\grey\graycolor %D This implementation enables use of defined colors like: %D %D \starttypen %D Look at the {\brightgreen bright} side of life and get %D yourself no \red{red} head! %D \stoptypen %D \macros %D {colorvalue, grayvalue} %D %D We can typeset the color components using \type{\colorvalue} and %D \type{\grayvalue}. The commands: %D %D \startbuffer %D color value of SomeKindOfRed: \colorvalue{SomeKindOfRed} \crlf %D gray value of SomeKindOfRed: \grayvalue{SomeKindOfRed} %D \stopbuffer %D %D \typebuffer %D %D show us: %D %D \startvoorbeeld %D \haalbuffer %D \stopvoorbeeld %D %D We can speed the following macros a bit up, but this %D hardly pays off; they are only used in the manual. \def\realcolorformat#1% {\ifnum#1<10 0.00\the#1\else \ifnum#1<100 0.0\the#1\else \ifnum#1<1000 0.\the#1\else 1.000\fi\fi\fi} \def\colorformatseparator{ } \def\dodoformatcolor#1% {\colordimen#1\s!pt\relax \ifdim\colordimen>1\s!pt \colordimen1\s!pt \fi \multiply\colordimen 1000 \colorcount\colordimen \advance\colorcount \medcard \divide\colorcount \maxcard \relax \realcolorformat\colorcount} \def\doformatcolorR#1:#2:#3:#4:#5\od {\dodoformatcolor{#1}\colorformatseparator \dodoformatcolor{#2}\colorformatseparator \dodoformatcolor{#3}} \def\doformatcolorC#1:#2:#3:#4:#5:#6\od {\dodoformatcolor{#1}\colorformatseparator \dodoformatcolor{#2}\colorformatseparator \dodoformatcolor{#3}\colorformatseparator \dodoformatcolor{#4}} \def\doformatcolorS#1:#2:#3\od {\dodoformatcolor{#1}} \def\doformatcolor#1:% {\getvalue{doformatcolor#1}} \def\colorvalue {\dowithcolor\doformatcolor} \def\doformatgrayR#1:#2:#3:#4:#5\od {\convertRGBtoGRAY{#1}{#2}{#3}% \dodoformatcolor\@@cl@@s} \def\doformatgrayC#1:#2:#3:#4:#5:#6\od {\convertCMYKtoGRAY{#1}{#2}{#3}{#4}% \dodoformatcolor\@@cl@@s} \def\doformatgrayS#1:#2:#3\od {\dodoformatcolor{#1}} \def\doformatgray#1:% {\getvalue{doformatgray#1}} \def\grayvalue% {\dowithcolor\doformatgray} %D \macros %D {localstartraster,localstopraster, %D startraster,stopraster} %D %D The previous conversions are not linear and treat each color %D component according to human perception curves. Pure gray %D (we call them rasters) has equal color components. In %D \CONTEXT\ rasters are only used as backgrounds and these %D don't cross page boundaries in the way color does. Therefore %D we don't need stacks and marks. Just to be compatible with %D color support we offer both 'global' and 'local' commands. \def\localstartraster[#1]% {\doifelsenothing{#1} {\dostartgraymode{\@@rsraster}} {\dostartgraymode{#1}}} \def\localstopraster {\dostopgraymode} \def\startraster {\localstartraster} \def\stopraster {\localstopraster} %D In this documentation we will not go into too much details %D on palets. Curious users can find more information on this %D topic in \uit[use of color]. %D %D At the moment we implemented color in \CONTEXT\ color %D printing was not yet on the desktop. In spite of this lack our %D graphics designer made colorfull illustrations. When printed %D on a black and white printer, distinctive colors can come %D out equally gray. We therefore decided to use only colors %D that were distinctive in colors as well as in black and %D white print. %D %D Although none of the graphic packages we used supported %D logical colors and global color redefition, we build this %D support into \CONTEXT. This enabled us to experiment and %D also prepared us for the future. %D \macros %D {definepalet} %D %D Colors are grouped in palets. The colors in such a palet can %D have colorful names, but best is to use names that specify %D their use, like {\em important} or {\em danger}. As a sort %D of example \CONTEXT\ has some palets predefined, %D like:\voetnoot{At the time I wrote the palet support, I was %D reading 'A hort history of time' of S.~Hawkins, so that's %D why we stuck to quarks.} %D %D \starttypen %D \definepalet %D [alfa] %D [ top=rood:7, %D bottom=groen:6, %D up=blauw:5, %D down=cyaan:4, %D strange=magenta:3, %D charm=geel:2] %D \stoptypen %D %D It's formal definition is: %D %D \showsetup{\y!definepalet} %D %D Visualized, such a palet looks like: %D %D \startbuffer[palet] %D \showpalet [alfa] [horizontaal,naam,nummer,waarde] %D \stopbuffer %D %D \startregelcorrectie %D \haalbuffer[palet] %D \stopregelcorrectie %D %D This bar shows both the color and gray alternatives of the %D palet components (not visible in black and white print). %D %D When needed, one can copy a palet by saying: %D %D \starttypen %D \definepalet [TEXcolorpretty] [colorpretty] %D \stoptypen %D %D This saves us some typing in for instance the modules that %D deal with pretty verbatim typesetting. \def\definepalet% {\dodoubleargument\dodefinepalet} \def\dodefinepalet[#1][#2]% {\doifassignmentelse{#2} {\setvalue{\??pa#1}{}% \setevalue{\??pa\??pa#1}{#2}% \showmessage{\m!colors}{6}{#1}% \def\dodododefinepalet[##1=##2]% {\doifvaluesomething{\??pa#1} {\setevalue{\??pa#1}{\getvalue{\??pa#1},}}% \setevalue{\??pa#1}{\getvalue{\??pa#1}##1}% \doifdefinedelse{\??cr##2} {\setevalue{\??cr#1:##1}{\getvalue{\??cr##2}}} {\setevalue{\??cr#1:##1}{S:0:0:0}}}% \def\dododefinepalet##1% {\dodododefinepalet[##1]}% \processcommalist[#2]\dododefinepalet} {\doifdefined{\??pa#2} {\expanded{\dodefinepalet[#1][\getvalue{\??pa\??pa#2}]}}}} %D \macros %D {setuppalet} %D %D Colors are taken from the current palet, if defined. %D Setting the current palet is done by: %D %D \showsetup{\y!setuppalet} \let\currentpalet\empty \def\setuppalet% {\dosingleempty\dosetuppalet} \def\dosetuppalet[#1]% {\edef\currentpalet{#1}% \ifx\currentpalet\empty % seems to be a reset \else % fast enough for tex and etex \@EA\ifx\csname\??pa\currentpalet\endcsname\relax \showmessage\m!colors7\currentpalet \let\currentpalet\empty \else \def\currentpalet{#1:}% \fi \fi} %D \macros %D {showpalet} %D %D The previous visualization was typeset with: %D %D \typebuffer[palet] %D %D This commands is defined as: %D %D \showsetup{\y!showpalet} \fetchruntimecommand \showpalet {\f!colorprefix\s!run} %D \macros %D {definecolorgroup} %D %D The naming of the colors in this palet suggests some %D ordening, which in turn is suported by color grouping. %D %D \starttypen %D \definecolorgroup %D [rood] %D [1.00:0.90:0.90, %D 1.00:0.80:0.80, %D 1.00:0.70:0.70, %D 1.00:0.55:0.55, %D 1.00:0.40:0.40, %D 1.00:0.25:0.25, %D 1.00:0.15:0.15, %D 0.90:0.00:0.00] %D \stoptypen %D %D In such a color group colors are numbered from~$1$ to~$n$. %D %D \showsetup{\y!definecolorgroup} %D %D This kind of specification is not only more compact than %D defining each color separate, it also loads faster and takes %D less bytes. \def\definecolorgroup% {\dotripleempty\dodefinecolorgroup} \def\dodefinecolorgroup[#1][#2][#3]% {\ifthirdargument \processaction [#2] [ \v!cmyk=>\edef\currentcolorspace{C}, \v!rgb=>\edef\currentcolorspace{R}, \v!gray=>\edef\currentcolorspace{S}, \v!s=>\edef\currentcolorspace{S}, \s!unknown=>\edef\currentcolorspace{R}]% \colorcount=0 \def\dododefinecolorgroup##1% {\advance\colorcount 1 \setevalue{\??cr#1:\the\colorcount}{\currentcolorspace:##1:0:0}}% \processcommalist[#3]\dododefinecolorgroup \else \doifinstringelse{:}{#2} {\definecolorgroup[#1][\v!rgb][#2]} {\doloop {\doifdefinedelse{\??cr#2:\recurselevel} {\setevalue{\??cr#1:\recurselevel}% {\getvalue{\??cr#2:\recurselevel}}} {\exitloop}}}% \fi} %D \macros %D {showcolorgroup} %D %D We can show the group by: %D %D \startbuffer %D \showcolorgroup [blauw] [horizontaal,naam,nummer,waarde] %D \stopbuffer %D %D \typebuffer %D %D or in color: %D %D \startregelcorrectie %D \haalbuffer %D \stopregelcorrectie %D %D which uses: %D %D \showsetup{\y!showcolorgroup} \fetchruntimecommand \showcolorgroup {\f!colorprefix\s!run} %D There are ten predefined color groups, like %D \color[groen]{\em groen}, \color[rood]{\em rood}, %D \color[blauw]{\em blauw}, \color[cyaan]{\em cyaan}, %D \color[magenta]{\em magenta} and \color[geel]{\em geel}. %D %D \startregelcorrectie %D \hbox to \hsize %D {\hss %D \showcolorgroup [rood] [vertikaal,naam,nummer]\hss %D \showcolorgroup [groen] [vertikaal,naam]\hss %D \showcolorgroup [blauw] [vertikaal,naam]\hss %D \showcolorgroup [cyaan] [vertikaal,naam]\hss %D \showcolorgroup [magenta] [vertikaal,naam]\hss %D \showcolorgroup [geel] [vertikaal,naam]\hss} %D \stopregelcorrectie %D %D These groups are used to define palets {\em alfa} upto {\em %D zeta}. As long as we don't use colors from the same row, we %D get ourselves distinctive palets. By activating such a palet %D one gains access to its members {\em top} to {\em charm} (of %D course one should use more suitable names than these). %D %D \startregelcorrectie %D \hbox to \hsize %D {\showpalet [alfa] [vertikaal,naam,nummer]\hss %D \showpalet [beta] [vertikaal,naam]\hss %D \showpalet [gamma] [vertikaal,naam]\hss %D \showpalet [delta] [vertikaal,naam]\hss %D \showpalet [epsilon] [vertikaal,naam]\hss %D \showpalet [zeta] [vertikaal,naam]} %D \stopregelcorrectie %D %D By using the keyword \type{\v!waarde} the individual color %D components are shown too. When printed in color, these %D showcases show both the colors and the gray value. %D \macros %D {comparepalet} %D %D There are some more testing macros available: %D %D \startbuffer %D \comparepalet [alfa] %D \stopbuffer %D %D \typebuffer %D %D shows the palet colors against a background: %D %D \startregelcorrectie %D \haalbuffer %D \stopregelcorrectie %D %D The formal definition is: %D %D \showsetup{\y!comparepalet} \fetchruntimecommand \comparepalet {\f!colorprefix\s!run} %D \macros %D {comparecolorgroup} %D %D The similar command: %D %D \startbuffer %D \comparecolorgroup [blauw] %D \stopbuffer %D %D \typebuffer %D %D shows color groups: %D %D \startregelcorrectie %D \haalbuffer %D \stopregelcorrectie %D %D this commands are defined as: %D %D \showsetup{\y!comparecolorgroup} \fetchruntimecommand \comparecolorgroup {\f!colorprefix\s!run} %D \macros %D {showcolor} %D %D But let's not forget that we also have the more traditional %D non||related colors. These show up after: %D %D \starttypen %D \showcolor [name] %D \stoptypen %D %D Where \type{name} for instance can be \type{rgb}. %D %D \showsetup{\y!showcolor} \fetchruntimecommand \showcolor {\f!colorprefix\s!run} %D \macros %D {negativecolorbox} %D %D Sometimes, especially when we deal with typesetting %D devices, we want to reverse the color scheme. Instead of %D recalculating all those colors, we use a quick and dirty %D approach: %D %D \starttypen %D \negativecolorbox0 %D \stoptypen %D %D will negate the colors in box zero. \def\negatecolorbox#1% {\setbox#1=\hbox {\dostartnegative \localstartcolor[white]% \vrule\!!height\ht#1\!!depth\dp#1\!!width\wd#1% \localstopcolor \hskip-\wd#1% \box#1\dostopnegative}} %D \macros %D {ifMPgraphics, ifMPcmyk, MPcolor} %D %D A very special macro is \type{\MPcolor}. This one can be %D used to pass a \CONTEXT\ color to \METAPOST. %D %D \starttypen %D \MPcolor{my own red} %D \stoptypen %D %D This macro returns a \METAPOST\ triplet \type{(R,G,B)}. %D Unless \CMYK\ color support is turned on with \type %D {MPcmyk}, only \kap{RGB} colors and gray scales are %D supported. \newif\ifMPcmyk % \MPcmykfalse \beginTEX \def\MPcolor#1% {\ifMPgraphics \@EA\@EA\@EA\doMPcolor \csname\??cr\@EA \ifx\csname\??cr\currentpalet#1\endcsname\relax\else\currentpalet\fi #1\endcsname :::::::\end \else #1% \fi} \endTEX \beginETEX \ifcsname \def\MPcolor#1% {\ifMPgraphics \@EA\@EA\@EA\doMPcolor \csname\??cr \ifcsname\??cr\currentpalet#1\endcsname\currentpalet\fi #1\endcsname :::::::\end \else #1% \fi} \endETEX %D Before we had transparancy available, the following %D conversion macro was available: %D %D \starttypen %D \def\doMPcolor#1:#2:#3:#4:#5:#6:#7:#8\end %D {\if #1R(#2,#3,#4)% %D \else\if#1C\ifMPcmyk cmyk(#2,#3,#4,#5)\else(1-#2-#5,1-#3-#5,1-#4-#5)\fi %D \else\if#1S(#2,#2,#2)% %D \else (0,0,0)% %D \fi\fi\fi} %D \stoptypen %D %D In order to be useful, this macro is to be fully %D expandabele. The next alternative also handles transparant %D colors. We could have packaged everything in one macro, but %D splitting it up is not only more readable, but also faster %D (because less arguments have to be skipped) \def\doMPcolor#1:% {\if#1R% \@EA\doMPrgb \else\if#1C\ifMPcmyk \@EA\@EAEAEA\@EA\doMPcmykY \else \@EA\@EAEAEA\@EA\doMPcmykN \fi\else\if#1S% \@EA\@EAEAEA\@EA\doMPgray \else \@EA\@EAEAEA\@EA\doMPblack \fi\fi\fi} \def\transparentMP{transparent} \def\cmykspecialMP{cmyk} \def\doMPtransparent#1#2:#3:#4\end {\ifcase#2\space(#1)\else\transparentMP(#2,#3,(#1))\fi} \def\doMPgray #1:{\doMPtransparent{#1,#1,#1}} \def\doMPrgb #1:#2:#3:{\doMPtransparent{#1,#2,#3}} \def\doMPcmykY#1:#2:#3:#4:{\doMPtransparent{\cmykspecialMP(#1,#2,#3,#4)}} \def\doMPcmykN#1:#2:#3:#4:{\doMPtransparent{1-#1-#4,1-#2-#4,1-#3-#4}} \def\doMPblack#1:#2:#3:#4:#5:#6:#7\end{(0,0,0)} %D \macros %D {PDFcolor,FDFcolor} %D %D Similar alternatives are avaliable for \PDF: \def\PDFcolor#1% {\@EA\@EA\@EA\doPDFcolor\csname\??cr#1\endcsname:::::::\end} \def\doPDFcolor#1:#2:#3:#4:#5:#6:#7:#8\end {\if #1R#2 #3 #4 rg% \else\if#1C#2 #3 #4 #5 k% \else\if#1S#2 g% \else 0 g% \fi\fi\fi} \def\FDFcolor#1% {\@EA\@EA\@EA\doFDFcolor\csname\??cr#1\endcsname:::::::\end} \def\doFDFcolor#1:#2:#3:#4:#5:#6:#7:#8\end {[\if #1R#2 #3 #4% \else\if#1C#2 #3 #4 #5% \else\if#1S#2% \else 0% \fi\fi\fi]} %D We default to the colors defined in \module{colo-rgb} and %D support both \kap{RGB} and \kap{CMYK} output. \setupcolors [\c!status=\v!stop, \c!conversie=\v!ja, \c!reductie=\v!nee, \c!rgb=\v!ja, \c!cmyk=\v!ja, \c!mp\c!cmyk=\@@clcmyk, \c!tekstkleur=] \setupcolor [\v!rgb] %D As we can see, color support is turned off by default. %D Reduction of gray colors to gray scales is turned on. \protect \endinput