summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/mk/mk-colors.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/manuals/mk/mk-colors.tex')
-rw-r--r--doc/context/sources/general/manuals/mk/mk-colors.tex467
1 files changed, 467 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/mk/mk-colors.tex b/doc/context/sources/general/manuals/mk/mk-colors.tex
new file mode 100644
index 000000000..0d12c976e
--- /dev/null
+++ b/doc/context/sources/general/manuals/mk/mk-colors.tex
@@ -0,0 +1,467 @@
+% language=uk
+
+\startcomponent mk-colors
+
+\environment mk-environment
+
+\chapter{Colors redone}
+
+\subject{introduction}
+
+Color support has been present in \CONTEXT\ right from the start and
+support has been gradualy extended, for instance with transparency
+and spot colors. About 10 years later we have the first major rewrite
+of this mechanism using attributes as implemented in \LUATEX.
+
+Because I needed a test file to check if all things still work as
+expected, I decided to recap the most important commands in this
+chapter.
+
+\subject{color support}
+
+The core command is \type {\definecolor}, so let's define a few
+colors:
+
+\startbuffer
+\definecolor [red] [r=1]
+\definecolor [green] [g=1]
+\definecolor [blue] [b=1]
+\definecolor [yellow] [y=1]
+\definecolor [magenta] [m=1]
+\definecolor [cyan] [c=1]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This gives us the following colors:
+
+\showcolorcomponents[red,green,blue,,yellow,magenta,cyan]
+
+As you can see in this table, transparency is part of a color
+specification, so let's define a few transparent colors:
+
+\startbuffer
+\definecolor [t-red] [r=1,a=1,t=.5]
+\definecolor [t-green] [g=1,a=1,t=.5]
+\definecolor [t-blue] [b=1,a=1,t=.5]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\showcolorcomponents[t-red,t-green,t-blue]
+
+Because transparency is now separated from color, we can define
+transparent behaviour as follows:
+
+\startbuffer
+\definecolor[half-transparent] [a=1,t=.5]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Implementing process color spaces was not that complex, but spot and multitone
+colors took a bit more code.
+
+\startbuffer
+\definecolor [parentspot] [r=.5,g=.2,b=.8]
+\definespotcolor [childspot-1] [parentspot] [p=.7]
+\definespotcolor [childspot-2] [parentspot] [p=.4]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The three colors, two of them are spot colors, show up as follows:
+
+\showcolorcomponents[parentspot,childspot-1,childspot-2]
+
+Multitone colors can also be defined:
+
+\startbuffer
+\definespotcolor [spotone] [red] [p=1]
+\definespotcolor [spottwo] [green] [p=1]
+
+\definespotcolor [spotone-t] [red] [a=1,t=.5]
+\definespotcolor [spottwo-t] [green] [a=1,t=.5]
+
+\definemultitonecolor
+ [whatever]
+ [spotone=.5,spottwo=.5]
+ [b=.5]
+\definemultitonecolor
+ [whatever-t]
+ [spotone=.5,spottwo=.5]
+ [b=.5]
+ [a=1,t=.5]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Transparencies don't carry over:
+
+\showcolorcomponents[spotone,spottwo,spotone-t,spottwo-t,whatever,whatever-t]
+
+Transparencies combine as follows:
+
+\startbuffer
+\blackrule[width=3cm,height=1cm,color=spotone-t]\hskip-1.5cm
+\blackrule[width=3cm,height=1cm,color=spotone-t]
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\dontleavehmode\getbuffer
+\stoplinecorrection
+
+We can still clone colors and overload color dynamically. I used the following
+test code for the \MKIV\ code:
+
+\startbuffer
+{\green green->red}
+\definecolor[green] [g=1]
+{\green green->green}
+\definecolor[green] [blue]
+{\green green->blue}
+\definecolor[blue] [red]
+{\green green->red}
+\setupcolors[expansion=yes]%
+\definecolor[blue] [red]
+\definecolor[green] [blue]
+\definecolor[blue] [r=1]
+{\green green->blue}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Of course palets and color groups are supported too. We seldom use
+colorgroups, but here is an example:
+
+\startbuffer
+\definecolorgroup
+ [redish]
+ [1.00:0.90:0.90,1.00:0.80:0.80,1.00:0.70:0.70,1.00:0.55:0.55,
+ 1.00:0.40:0.40,1.00:0.25:0.25,1.00:0.15:0.15,0.90:0.00:0.00]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The redish color is called by number:
+
+\startbuffer
+\blackrule[width=3cm,height=1cm,depth=0pt,color=redish:1]\quad
+\blackrule[width=3cm,height=1cm,depth=0pt,color=redish:2]\quad
+\blackrule[width=3cm,height=1cm,depth=0pt,color=redish:3]
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\dontleavehmode\getbuffer
+\stoplinecorrection
+
+Palets work with names:
+
+\startbuffer
+\definepalet
+ [complement]
+ [red=cyan,green=magenta,blue=yellow]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This is used as:
+
+\startbuffer
+\blackrule[width=1cm,height=1cm,depth=0pt,color=red]\quad
+\blackrule[width=1cm,height=1cm,depth=0pt,color=green]\quad
+\blackrule[width=1cm,height=1cm,depth=0pt,color=blue]\quad
+\setuppalet[complement]%
+\blackrule[width=1cm,height=1cm,depth=0pt,color=red]\quad
+\blackrule[width=1cm,height=1cm,depth=0pt,color=green]\quad
+\blackrule[width=1cm,height=1cm,depth=0pt,color=blue]
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\dontleavehmode\getbuffer
+\stoplinecorrection
+
+% Rasters are still supported but normally one will use colors:
+%
+% \startbuffer
+% \raster[.5]{\blackrule[width=3cm,height=1cm]}\quad
+% \raster[.8]{\blackrule[width=3cm,height=1cm]}
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection
+% \dontleavehmode\getbuffer
+% \stoplinecorrection
+
+Of course the real torture test is \METAPOST\ inclusion:
+
+\startbuffer
+\startMPcode
+ path p ; p := fullcircle scaled 4cm ;
+ fill p withcolor \MPcolor{spotone-t} ;
+ fill p shifted(2cm,0cm) withcolor \MPcolor{spottwo-t} ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+These transparent color circles up as:
+
+\startlinecorrection
+\dontleavehmode\getbuffer
+\stoplinecorrection
+
+Multitone colors also work:
+
+\startbuffer
+\startMPcode
+ path p ; p := fullcircle scaled 2cm ;
+ fill p withcolor \MPcolor{spotone} ;
+ fill p shifted(2cm,0cm) withcolor \MPcolor{spottwo} ;
+ fill p shifted(4cm,0cm) withcolor \MPcolor{whatever} ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+\startlinecorrection
+\dontleavehmode\getbuffer
+\stoplinecorrection
+
+\subject{implementation}
+
+The implementation of colors using attributes if quite different
+from the traditional method. In \MKII\ color support works okay but
+the associated code is not that clean, if only because:
+
+\startitemize[packed]
+\item we need to keep track of grouped color usage
+\item and we do that using dedicated marks (using \TEX's mark mechanism)
+\item since this has limitations, we have quite some optimizations
+\item like local (no marks) and global colors (marks)
+\item and real dirty code to push and pop color states around pages
+\item and some messy code to deal with document colors
+\item and quite some conversion macros (think of \TEX\ not having floats)
+\stopitemize
+
+Although recent versions of \PDFTEX\ have a color stack mechanism, this
+is not adequate for our usage, if only because we support more colorspaces
+than this mechanism is supposed to deal with. (The color stack mechanism is
+written with a particular macro packag ein mind.)
+
+In \MKIV\ attributes behave like colors and therefore we no longer
+need to care about what happens at pageboundaries. Also, we no
+longer have to deal with the limitations of marks. Here:
+
+\startitemize[packed]
+\item we have distributed color spaces, color itself and transparency
+\item all injection of backend code is postponed to shipout time
+\item definition and conversion is delegated to \LUA
+\stopitemize
+
+Of course the current implementation is not as nice as we would like it
+to be. This because:
+
+\startitemize[packed]
+\item support mechanism are under construction
+\item we need to support both \MKII\ and \MKIV\ in one interface
+\item backend support is yet limited
+\stopitemize
+
+Although in principle a mechanism based on attributes is much faster than
+using marks cum suis, the new implementation is slower. The main reason is
+that we need to finalize the to be shipped out box. However, since this
+task involved more than just color, we will gain back some runtime when other
+mechanisms also use attributes.
+
+\subject{complications}
+
+This paragraph is somewhat complex, so skip it when you don't feel comfortable with
+the subject of when you've never seen low level \CONTEXT\ code.
+
+Attributes behave like fonts. This means that they are kind of frozen once
+material is boxed. Consider that we define a box as follows:
+
+\starttyping
+\setbox0\hbox{default {\red red \green green} default}
+\stoptyping
+
+What do you expect to come out the next code? In \MKII\ the \quote
+{default} inside the box will be colored yellow but the internal
+red and and green words will keep their color.
+
+\starttyping
+default {\yellow yellow \box0\ yellow} default
+\stoptyping
+
+When we use fonts switches we don't expect the content of the
+box to change. So, in the following the \quote {default} texts will
+{\em not} become bold.
+
+\starttyping
+\setbox0\hbox{default {\sl slanted \bi bold italic} default}
+default {\bf bold \box0\ bold} default
+\stoptyping
+
+Future versions of \LUATEX\ will provide more control over how attributes
+are applied to boxes, but for the moment we need to fallback on a solution
+built in \MKIV:
+
+\starttyping
+default {\yellow yellow \attributedbox0\ yellow} default
+\stoptyping
+
+There is also a \type {\attributedcopy} macro. These macros signal the
+attribute resolver (that kicks in just before shipout) that this box is to
+be treated special.
+
+In \MKII\ we had a similar situation which is why we had the option (only used
+deep down in \CONTEXT) to encapsulate a bunch of code with
+
+\starttyping
+\startregistercolor[foregroundcolor]
+some macro code ... here foregroundcolor is applied ... more code
+\stopregisteringcode
+\stoptyping
+
+This is for instance used in the \type {\framed} macro. First we package the content,
+foregroundcolor is not yet applied because the injected specials of literals can interfere
+badly, but by registering the colors the nested color calls are tricked into thinking that
+preceding and following content is colored. When packaged, we apply backgrounds, frames,
+and foregroundcolor to the whole result. Because nested colors were aware of the
+foregroundcolor they have properly reverted to this color when needed.
+
+In \MKIV\ the situation is reversed. Here we definitely need to set the foregroundcolor
+because otherwise attributes are not set and here they don't interfere at all (no extra nodes).
+For this we use the same registration macros. When the lot is packaged, applying foregroundcolor
+is ineffective because the attributes are already applied. Instead of registering we could
+have flushed the framed content using \type {\attributedbox}, but this way we can keep the
+\MKII\ and \MKIV\ code base the same.
+
+To summarize, first the na\"ive approach. Here the nested colors know how to revert, but
+the color switch can interfere with the content (since color commands inject nodes).
+
+\starttyping
+\setbox\framed\vbox
+ {\color[foregroundcolor]{packaged framed content, can have color switches}}
+\stoptyping
+
+The \MKII\ approach registers the foreground color so the nested colors
+know what to do. There is no interfering code:
+
+\starttyping
+\startregistercolor[foregroundcolor]
+\setbox\framed
+\stopregisteringcode
+\setbox\framed{\color[foregroundcolor]{\box\framed}}
+\stoptyping
+
+The registration actually sets the color, so in fact the final coloring is not
+needed (does nothing). An alternative \MKIV\ approach is the following:
+
+\starttyping
+\color
+ [foregroundcolor]
+ {\setbox\framed{packaged framed content, can have color switches}}
+\stoptyping
+
+This works ok because attributes are applied to the whole content, i.e.\
+the box. In \MKII\ this would be quite ineffective and actually result
+in weird side effects.
+
+\starttyping
+< color stack is pushed and marks are set (unless local) >
+< color special or literal sets color to foregroundcolor >
+\setbox\framed{packaged framed content, can have color switches}
+< color special or literal sets color to foregroundcolor >
+< color stack is popped and marks are set (unless local) >
+\stoptyping
+
+So, effectively we set a box, and end up with:
+
+\starttyping
+< whatsits (special, literal and.or mark) >
+< whatsits (special, literal and.or mark) >
+\stoptyping
+
+in the main vertical lost and that will interfere badly with spacing
+and friends.
+
+In \MKIV\ however, a color switch, like a font switch does not leave any
+traces, it just sets a state. Anyway, keep in mind that there are some
+rather fundamental conceptual differences between the two appoaches.
+
+Let's end with an example that demonstrates the problem. We fill two boxes:
+
+% in previous examples we may have messed up colors
+
+\definecolor[red] [darkred]
+\definecolor[green] [darkgreen]
+\definecolor[blue] [darkblue]
+\definecolor[yellow][darkyellow]
+
+\startbuffer
+\setbox0\hbox{RED {\blue blue} RED}
+\setbox2\hbox{RED {\blue blue} {\attributedcopy0} RED}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We will flush these in the following lines:
+
+\startbuffer
+{unset \color[red]{red \CopyMe} unset
+ \color[red]{red \hbox{red \CopyMe}} unset}
+{unset \color[red]{red \CopyMe} unset
+ {\red red \hbox{red \CopyMe}} unset}
+{unset \color[red]{red \CopyMe} unset
+ {\red red \setbox0\hbox{red \CopyMe}\box0} unset}
+{unset \color[red]{red \CopyMe} unset
+ {\hbox{\red red \CopyMe}} unset}
+{\blue blue \color[red]{red \CopyMe} blue
+ \color[red]{red \hbox{red \CopyMe}} blue}
+\stopbuffer
+
+\typebuffer
+
+\startbuffer[yes]
+\def\CopyMe{\attributedcopy2\ \copy4}
+\stopbuffer
+
+\startbuffer[no]
+\def\CopyMe{\copy2\ \copy4}
+\stopbuffer
+
+First we define \type {\CopyMe} as follows:
+
+\typebuffer[yes]
+
+This gives:
+
+\start \enableattributeinheritance \getbuffer[yes] \getbuffer \stop
+
+Compare this with:
+
+\typebuffer[no]
+
+This gives:
+
+\getbuffer[no] \getbuffer
+
+You get the picture? At least in early version of \MKIV\ you need to
+enable support for inheritance with:
+
+\starttyping
+\enableattributeinheritance
+\stoptyping
+
+\stopcomponent