summaryrefslogtreecommitdiff
path: root/graphics/pgf/base/doc/text-en/pgfmanual-en-base-shadings.tex
blob: a091bc31b58ccf97120ee7d021219a5d95e90783 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
% Copyright 2019 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.


\section{Shadings}
\label{section-shadings}

\subsection{Overview}

A shading is an area in which the color changes smoothly between different
colors. Similarly to an image, a shading must first be declared before it can
be used. Also similarly to an image, a shading is put into a \TeX-box. Hence,
in order to include a shading in a |{pgfpicture}|, you have to use |\pgftext|
around it.

There are different kinds of shadings: horizontal, vertical, radial, and
functional shadings. However, you can rotate and clip shadings like any other
graphics object, which allows you to create more complicated shadings.
Horizontal shadings could be created by rotating a vertical shading by 90
degrees, but explicit commands for creating both horizontal and vertical
shadings are included for convenience.

Once you have declared a shading, you can insert it into the text using the
command |\pgfuseshading|. This command cannot be used directly in a
|{pgfpicture}|, you have to put a |\pgftext| around it. The second command for
using shadings, |\pgfshadepath|, on the other hand, can only be used  inside
|{pgfpicture}| environments. It will ``fill'' the current path with the
shading.

A horizontal shading is a horizontal bar of a certain height whose color
changes smoothly. You must at least specify the colors at the left and at the
right end of the bar, but you can also add color specifications for points in
between. For example, suppose you wish to create a bar that is red at the left
end, green in the middle, and blue at the end, and you would like the bar to be
4cm long. This could be specified as follows:
%
\begin{codeexample}[code only]
rgb(0cm)=(1,0,0); rgb(2cm)=(0,1,0); rgb(4cm)=(0,0,1)
\end{codeexample}
%
This line means that at 0cm (the left end) of the bar, the color should be red,
which has red-green-blue (rgb) components (1,0,0). At 2cm, the bar should be
green, and at 4cm it should be blue. Instead of |rgb|, you can currently also
specify |cmyk| as color model, in which case four values are needed,
|gray| as color model, in which case only one value is needed, or
|color|, in which case you must provide the name of a color in parentheses. In
a color specification the individual specifications must be separated using a
semicolon, which may be followed by a whitespace (like a space or a newline).
Individual specifications must be given in increasing order.

\subsubsection{Color models}

\noindent\emph{by David Purton}

An attempt is made to produce shadings consistent with the currently selected
|xcolor| package color model. The |rgb|, |cmyk|, and |gray| color models from
the |xcolor| package are supported.

\textbf{Note:} The color model chosen for a shading is based on the |xcolor|
color model \emph{at the time the shading is created}. This is either when
\cs{pgfdeclare*shading} is called with no optional argument or when
\cs{pgfuseshading} is called if \cs{pgfdeclare*shading} was called with an
optional argument.

If the |xcolor| package |natural| color model is in use then the shading color
model will be \textsc{rgb} by default. In practice this means that if you are
using the |natural| color model of the |xcolor| package you can get mismatched
colors if you, for example, create a shading from green (which is defined as
\textsc{rgb}) to magenta (which is defined as \textsc{cmyk}). The shading will
finish with \textsc{rgb} magenta which will look different to the
\textsc{cmyk} magenta used in solid colors.

You can avoid mismatched colors by loading the |xcolor| package first with an
explicit color model (|rgb|, |cmyk|, or |gray|).

\begin{codeexample}[code only]
\begin{tikzpicture}
  \fill[green] (0,0) rectangle (1,1);
  \shade[left color=green, right color=magenta] (1.25,0) rectangle (3.75,1);
  \fill[magenta] (4,0) rectangle (5,1);
\end{tikzpicture}
\end{codeexample}

\begin{center}
  \begin{minipage}{5cm}
    |xcolor| |natural| color model:\medskip

    \begin{tikzpicture}
      \fill[green] (0,0) rectangle (1,1);
      \shade[left color=green, right color=magenta] (1.25,0) rectangle (3.75,1);
      \fill[magenta] (4,0) rectangle (5,1);
    \end{tikzpicture}
  \end{minipage}\hspace{2cm}%
  \begin{minipage}{5cm}
    |xcolor| |cmyk| color model:\medskip

    \selectcolormodel{cmyk}
    \begin{tikzpicture}
      \fill[green] (0,0) rectangle (1,1);
      \shade[left color=green, right color=magenta] (1.25,0) rectangle (3.75,1);
      \fill[magenta] (4,0) rectangle (5,1);
    \end{tikzpicture}
  \end{minipage}\medskip

  \begin{minipage}{5cm}
    |xcolor| |rgb| color model:\medskip

    \selectcolormodel{rgb}
    \begin{tikzpicture}
      \fill[green] (0,0) rectangle (1,1);
      \shade[left color=green, right color=magenta] (1.25,0) rectangle (3.75,1);
      \fill[magenta] (4,0) rectangle (5,1);
    \end{tikzpicture}
  \end{minipage}\hspace{2cm}%
  \begin{minipage}{5cm}
    |xcolor| |gray| color model:\medskip

    \selectcolormodel{gray}
    \begin{tikzpicture}
      \fill[green] (0,0) rectangle (1,1);
      \shade[left color=green, right color=magenta] (1.25,0) rectangle (3.75,1);
      \fill[magenta] (4,0) rectangle (5,1);
    \end{tikzpicture}
  \end{minipage}
\end{center}

\subsection{Declaring Shadings}

\subsubsection{Horizontal and Vertical Shadings}

\begin{command}{\pgfdeclarehorizontalshading\oarg{color list}\marg{shading name}\marg{shading height}\marg{color specification}}
    Declares a horizontal shading named \meta{shading name} of the specified
    \meta{height} with the specified colors. The width of the bar is deduced
    automatically from the maximum dimension in the specification.
    %
\begin{codeexample}[]
\pgfdeclarehorizontalshading{myshadingA}
  {1cm}{rgb(0cm)=(1,0,0); color(2cm)=(green); color(4cm)=(blue)}
\pgfuseshading{myshadingA}
\end{codeexample}

    The effect of the \meta{color list}, which is a comma-separated list of
    colors, is the following: Normally, when this list is empty, once a shading
    has been declared, it becomes ``frozen''. This means that even if you
    change a color that was used in the declaration of the shading later on,
    the shading will not change. By specifying a \meta{color list} you can
    specify that the shading should be recalculated whenever one of the colors
    listed in the list changes (this includes effects like color mixins and
    |xcolor| color models). Thus, when you specify a \meta{color list},
    whenever the shading is used, \pgfname\ first converts the colors in the
    list to tuples in the current |xcolor| color model using the current
    values of the colors and taking any mixins and blends into account. If the
    resulting tuples have not yet been used,
    a new shading is internally created and used. Note that if the option
    \meta{color list} is used, then no shading is created until the first use
    of |\pgfuseshading|. In particular, the colors mentioned in the shading
    need not be defined when the declaration is given.

    When a shading is recalculated because of a change in the colors mentioned
    in \meta{color list}, the complete shading is recalculated. Thus even
    colors not mentioned in the list will be used with their current values,
    not with the values they had upon declaration.
    %
\begin{codeexample}[]
\pgfdeclarehorizontalshading[mycolor]{myshadingB}
  {1cm}{rgb(0cm)=(1,0,0); color(2cm)=(mycolor)}
\colorlet{mycolor}{green}
\pgfuseshading{myshadingB}
\colorlet{mycolor}{blue}
\pgfuseshading{myshadingB}
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfdeclareverticalshading\oarg{color list}\marg{shading name}\marg{shading width}\marg{color specification}}
    Declares a vertical shading named \meta{shading name} of the specified
    \meta{width}. The height of the bar is deduced automatically. The effect of
    \meta{color list} is the same as for horizontal shadings.
    %
\begin{codeexample}[]
\pgfdeclareverticalshading{myshadingC}
  {4cm}{rgb(0cm)=(1,0,0); rgb(1.5cm)=(0,1,0); rgb(2cm)=(0,0,1)}
\pgfuseshading{myshadingC}
\end{codeexample}
    %
\end{command}


\subsubsection{Radial Shadings}

\begin{command}{\pgfdeclareradialshading\oarg{color list}\marg{shading name}\marg{center point}\marg{color specification}}
    Declares a radial shading. A radial shading is a circle whose inner color
    changes as specified by the color specification. Assuming that the center
    of the shading is at the origin, the color of the center will be the color
    specified for 0cm and the color of the border of the circle will be the
    color for the maximum dimension given in the \meta{color specified}. This
    maximum will also be the radius of the circle. If the \meta{center point}
    is not at the origin, the whole shading inside the circle (whose size
    remains exactly the same) will be distorted such that the given center now
    has the color specified for 0cm. The effect of \meta{color list} is the
    same as for horizontal shadings.
    %
\begin{codeexample}[]
\pgfdeclareradialshading{sphere}{\pgfpoint{0.5cm}{0.5cm}}%
  {rgb(0cm)=(0.9,0,0);
   rgb(0.7cm)=(0.7,0,0);
   rgb(1cm)=(0.5,0,0);
   rgb(1.05cm)=(1,1,1)}
\pgfuseshading{sphere}
\end{codeexample}
    %
\end{command}


\subsubsection{General (Functional) Shadings}

\begin{command}{\pgfdeclarefunctionalshading\oarg{color list}\marg{shading
    name}\marg{lower left corner}\marg{upper right corner}\\
    \marg{init code}\marg{type 4 function}%
}
    \emph{Warning: These shadings are the least portable of all and they put
    the heaviest burden of the renderer. They are slow and, possibly, will not
    print correctly!}

    This command creates a \emph{functional shading}. For such a shading, the
    color of each point is calculated by calling a function that takes the
    coordinates of the point as input and yields the color as an output. Note
    that the function is evaluated by the \emph{renderer}, not by \pgfname\ or
    \TeX\ or someone else at compile-time. This means that the evaluation of
    this function has to be done \emph{extremely quickly} and the function
    should be \emph{very simple}. For this reason, only a very restricted set
    of operations are possible in the function and functions should be kept
    small. Any errors in the function will only be noticed by the renderer.

    The syntax for specifying functions is the following: You use a simplified
    form of a subset of the PostScript language. This subset will be understood
    by the PDF-renderer (yes, PDF-renderers do have a basic understanding of
    PostScript) and also by PostScript renders. This subset is detailed in
    Section~3.9.4 of the PDF-specification (version~1.7). In essence, the
    specification states that these functions may contain ``expressions
    involving integers, real numbers, and boolean values only. There are no
    composite data structures such as strings or arrays, no procedures, and no
    variables or names.'' The allowed operators are (exactly) the following:
    \texttt{abs}, \texttt{add}, \texttt{atan}, \texttt{ceiling}, \texttt{cos},
    \texttt{cvi}, \texttt{cvr}, \texttt{div}, \texttt{exp}, \texttt{floor},
    \texttt{idiv}, \texttt{ln}, \texttt{log}, \texttt{mod}, \texttt{mul},
    \texttt{neg}, \texttt{round}, \texttt{sin}, \texttt{sqrt}, \texttt{sub},
    \texttt{truncate}, \texttt{and}, \texttt{bitshift}, \texttt{eq},
    \texttt{false}, \texttt{ge}, \texttt{gt}, \texttt{le}, \texttt{lt},
    \texttt{ne}, \texttt{not}, \texttt{or}, \texttt{true}, \texttt{xor},
    \texttt{if}, \texttt{ifelse}, \texttt{copy}, \texttt{dup}, \texttt{exch},
    \texttt{index}, \texttt{pop}.

    When the function is evaluated, the top two stack elements are the
    coordinates of the point for which the color should be computed. The
    coordinates are dimensionless and given in big points, so for the
    coordinate $(50bp, 72.27pt)$ the top two stack elements would be
    \texttt{50.0} and \texttt{72.0}. Otherwise, the (virtual) stack is empty
    (or should be treated as if it were empty). The function should then
    replace these two values by three values, representing the red, green, and
    blue color of the point for an \textsc{rgb} shading, four colors,
    representing the cyan, magenta, yellow, and black color of the point for a
    \textsc{cmyk} shading, or one value representing the gray color for a
    grayscale shading. The numbers should be real values, not integers
    since, Apple's PDF renderer is broken in this regard (use \texttt{cvr} at
    the end if necessary).

    Conceptually, the function will be evaluated once for each point of the
    rectangle \meta{lower left corner} to \meta{upper right corner}, which
    should be a \pgfname-point expression like |\pgfpoint{100bp}{100bp}|. A
    renderer may choose to evaluate the function at less points, but, in
    principle, the function will be evaluated for each pixel independently.

    Because of the rather difficult PostScript syntax, use this macro only
    \emph{if you know what you are doing} (or if you are adventurous, of
    course).

    As for other shadings, the optional \meta{color list} is used to determine
    whether a shading needs to be recalculated when a color has changed.

    The \meta{init code} is executed each time a shading is (re)calculated.
    Typically, it will contain code to extract coordinates from colors.
    %
\begin{codeexample}[]
\pgfdeclarefunctionalshading{twospots}
    {\pgfpointorigin}{\pgfpoint{4cm}{4cm}}{}{
  % Save coordinates for later
  2 copy
  % Compute distance from (40bp,45bp), with x doubled
  45 sub dup mul exch
  40 sub dup mul 0.5 mul add sqrt
  % exponential decay
  dup mul neg 1.0005 exch exp 1.0 exch sub
  % Compute distance from (70bp,70bp) from stored coordinate, scaled
  3 1 roll
  70 sub dup mul .5 mul exch
  70 sub dup mul add sqrt
  % Decay
  dup mul neg 1.002 exch exp 1.0 exch sub
  % red component
  1.0 3 1 roll
}
\pgfuseshading{twospots}
\end{codeexample}

    Inside the PostScript function \meta{type 4 function} you cannot use colors
    directly. Rather, you must push the color components on the stack. For
    this, it is useful to call one of |\pgfshadecolortorgb|,
    |\pgfshadecolortocmyk|, or |\pgfshadecolortogray| in the \meta{init code}:

    \begin{command}{\pgfshadecolortorgb\marg{color name}\marg{macro}}
        This command takes \meta{color name} as input, converts it to
        \textsc{rgb} and stores the color's
        red/green/blue components real numbers between 0.0 and 1.0 separated by
        spaces (which is exactly what you need if you want to push it on a
        stack) in \meta{macro}. This macro can then be used inside the
        \meta{type 4 function} argument for |\pgfdeclarefunctionalshading|.
        %
\begin{codeexample}[]
\pgfdeclarefunctionalshading[mycol]{sweep}{\pgfpoint{-1cm}{-1cm}}
{\pgfpoint{1cm}{1cm}}{\pgfshadecolortorgb{mycol}{\myrgb}}{
  2 copy        % whirl
  % Calculate "safe" atan of position
  2 copy abs exch abs add 0.0001 ge { atan } { pop } ifelse
  3 1 roll
  dup mul exch
  dup mul add sqrt
  30 mul
  add
  sin
  1 add 2 div
  dup
  \myrgb        % push mycol
  5 4 roll      % multiply all components by calculated value
  mul
  3 1 roll
  3 index
  mul
  3 1 roll
  4 3 roll
  mul
  3 1 roll
}
\colorlet{mycol}{white}%
\pgfuseshading{sweep}%
\colorlet{mycol}{red}%
\pgfuseshading{sweep}
\end{codeexample}

        In addition, three macros suffixed with |red|, |green| and |blue| are
        defined, which store the individual components of \meta{color name}.
        These can also be used in the \meta{type 4 function} argument.
        %
\begin{codeexample}[]
\pgfshadecolortorgb{orange}{\mycol}
|\mycol|=\mycol |\mycolred|=\mycolred |\mycolgreen|=\mycolgreen |\mycolblue|=\mycolblue
\end{codeexample}
    \end{command}

\begin{codeexample}[]
\pgfdeclarefunctionalshading[col1,col2,col3,col4]{bilinear interpolation}
{\pgfpointorigin}{\pgfpoint{100bp}{100bp}}
{
\pgfshadecolortorgb{col1}{\first}\pgfshadecolortorgb{col2}{\second}
\pgfshadecolortorgb{col3}{\third}\pgfshadecolortorgb{col4}{\fourth}
}{
  100 div exch 100 div 2 copy                   % Calculate y/100 x/100.
  neg 1 add exch neg 1 add                      % Calculate 1-y/100 1-x/100.
  3 1 roll 2 copy exch 5 2 roll 6 copy 6 copy   % Set up stack.
  \firstred mul exch \secondred mul add mul     % Process red component.
  4 1 roll
  \thirdred mul exch \fourthred mul add mul
  add
  13 1 roll
  \firstgreen mul exch \secondgreen mul add mul % Process green component.
  4 1 roll
  \thirdgreen mul exch \fourthgreen mul add mul
  add
  7 1 roll
  \firstblue mul exch \secondblue mul add mul   % Process blue component.
  4 1 roll
  \thirdblue mul exch \fourthblue mul add mul
  add
}

\colorlet{col1}{blue}
\colorlet{col2}{yellow}
\colorlet{col3}{red}
\colorlet{col4}{green}
\pgfuseshading{bilinear interpolation}
\end{codeexample}

    \begin{command}{\pgfshadecolortocmyk\marg{color name}\marg{macro}}
        This command takes \meta{color name} as input, converts it to
        \textsc{cmyk} and stores the color's cyan/magenta/yellow/black
        components real numbers between 0.0 and 1.0 separated by spaces.

        In addition, four macros suffixed with |cyan|, |magenta|, |yellow| and
        |black| are defined, which store the individual components of
        \meta{color name}.
        %
    \end{command}

    \begin{command}{\pgfshadecolortogray\marg{color name}\marg{macro}}
        This command takes \meta{color name} as input converts it to grayscale
        and stores the color's value as a real number between 0.0 and 1.0.

        Although it's not needed, for consistency a second macro suffixed with
        |gray| is also defined.
        %
    \end{command}
    %
\end{command}

\paragraph{Color model independent functional shadings.}

By nature, the PostScript code used in functional shadings must output one of
\textsc{rgb}, \textsc{cmyk}, or grayscale data. Therefore,
\cs{pgfdeclarefunctionalshading} is \emph{not} portable across color models.

Take particular care that the same color model is in use at declaration time
and use time for functional shadings declared with an optional argument as
otherwise the PostScript data will not match the declared color space and
you will end up with a malformed PDF.

Having said this, it \emph{is} possible to create portable functional shadings
by providing conditional code to append color transformations to the
PostScript data. A variety of \cs{pgffuncshading*to*} (e.g.,
\cs{pgffuncshadingrgbtocmyk}) macros along with \cs{ifpgfshadingmodel*} (e.g.,
\cs{ifpgfshadingmodelcmyk}) conditionals are provided to assist with these
transformations. Obviously, this will make the PostScript code less efficient
than if you work in your intended color model.

\pgfdeclarefunctionalshading[black]{portabletwospots}
    {\pgfpointorigin}{\pgfpoint{3.5cm}{3.5cm}}{}{
  2 copy
  45 sub dup mul exch
  40 sub dup mul 0.5 mul add sqrt
  dup mul neg 1.0005 exch exp 1.0 exch sub
  3 1 roll
  70 sub dup mul .5 mul exch
  70 sub dup mul add sqrt
  dup mul neg 1.002 exch exp 1.0 exch sub
  1.0 3 1 roll
  \ifpgfshadingmodelcmyk
    \pgffuncshadingrgbtocmyk
  \fi
  \ifpgfshadingmodelgray
    \pgffuncshadingrgbtogray
  \fi
}
\begin{center}
  \begin{minipage}{3.5cm}
    |xcolor| |rgb| model:\medskip

    \selectcolormodel{rgb}
    \pgfuseshading{portabletwospots}
  \end{minipage}\hspace{2cm}
  \begin{minipage}{3.5cm}
    |xcolor| |cmyk| model:\medskip

    \selectcolormodel{cmyk}
    \pgfuseshading{portabletwospots}
  \end{minipage}\hspace{2cm}
  \begin{minipage}{3.5cm}
    |xcolor| |gray| model:\medskip

    \selectcolormodel{gray}
    \pgfuseshading{portabletwospots}
  \end{minipage}
\end{center}

\begin{codeexample}[code only]
\pgfdeclarefunctionalshading[black]{portabletwospots}{\pgfpointorigin}{\pgfpoint{3.5cm}{3.5cm}}{}{
  2 copy
  45 sub dup mul exch
  40 sub dup mul 0.5 mul add sqrt
  dup mul neg 1.0005 exch exp 1.0 exch sub
  3 1 roll
  70 sub dup mul .5 mul exch
  70 sub dup mul add sqrt
  dup mul neg 1.002 exch exp 1.0 exch sub
  1.0 3 1 roll
  \ifpgfshadingmodelcmyk
    \pgffuncshadingrgbtocmyk
  \fi
  \ifpgfshadingmodelgray
    \pgffuncshadingrgbtogray
  \fi
}
\end{codeexample}

\begin{command}{\pgffuncshadingrgbtocmyk}
  Within the \meta{type 4 function} argument of
  \cs{pgfdeclarefunctionalshading}, this command can be used to convert the
  top 3 elements on the stack from \textsc{rgb} to \textsc{cmyk}. In
  combination with the \cs{ifpgfshadingmodelcmyk} conditional this macro can
  be used to make functional shading declarations more portable across color
  models.
\end{command}

\begin{command}{\pgffuncshadingrgbtogray}
  Within the \meta{type 4 function} argument of
  \cs{pgfdeclarefunctionalshading}, this command can be used to convert the
  top 3 elements on the stack from \textsc{rgb} to grayscale. In combination
  with the \cs{ifpgfshadingmodelgray} conditional this macro can be used to
  make functional shading declarations more portable across color models.
\end{command}

\begin{command}{\pgffuncshadingcmyktorgb}
  Within the \meta{type 4 function} argument of
  \cs{pgfdeclarefunctionalshading}, this command can be used to convert the
  top 4 elements on the stack from \textsc{cmyk} to \textsc{rgb}. In
  combination with the \cs{ifpgfshadingmodelrgb} conditional this macro can be
  used to make functional shading declarations more portable across color
  models.
\end{command}

\begin{command}{\pgffuncshadingcmyktogray}
  Within the \meta{type 4 function} argument of
  \cs{pgfdeclarefunctionalshading}, this command can be used to convert the
  top 4 elements on the stack from \textsc{cmyk} to grayscale. In combination
  with the \cs{ifpgfshadingmodelgray} conditional this macro can be used to
  make functional shading declarations more portable across color models.
\end{command}

\begin{command}{\pgffuncshadinggraytorgb}
  Within the \meta{type 4 function} argument of
  \cs{pgfdeclarefunctionalshading}, this command can be used to convert the
  top element on the stack from grayscale to \textsc{rgb}. In combination with
  the \cs{ifpgfshadingmodelrgb} conditional this macro can be used to make
  functional shading declarations more portable across color models.
\end{command}

\begin{command}{\pgffuncshadinggraytocmyk}
  Within the \meta{type 4 function} argument of
  \cs{pgfdeclarefunctionalshading}, this command can be used to convert the
  top element on the stack from grayscale to \textsc{cmyk}. In combination
  with the \cs{ifpgfshadingmodelcmyk} conditional this macro can be used to
  make functional shading declarations more portable across color models.
\end{command}

{\let\ifpgfshadingmodelrgb=\relax
 \let\ifpgfshadingmodelcmyk=\relax
 \let\ifpgfshadingmodelgray=\relax
 \begin{command}{\ifpgfshadingmodelrgb}
   Within the \meta{type 4 function} argument of
   \cs{pgfdeclarefunctionalshading}, this command can be used to test if the
   |xcolor| color model is |rgb| \emph{at the time the shading is created}.
   This can be used to ensure that the data output in the \meta{type 4
   function} correctly matches the active color model.
 \end{command}

 \begin{command}{\ifpgfshadingmodelcmyk}
   Within the \meta{type 4 function} argument of
   \cs{pgfdeclarefunctionalshading}, this command can be used to test if the
   |xcolor| color model is |cmyk| \emph{at the time the shading is created}.
   This can be used to ensure that the data output in the \meta{type 4
   function} correctly matches the active color model.
 \end{command}

 \begin{command}{\ifpgfshadingmodelgray}
   Within the \meta{type 4 function} argument of
   \cs{pgfdeclarefunctionalshading}, this command can be used to test if the
   |xcolor| color model is |gray| \emph{at the time the shading is created}.
   This can be used to ensure that the data output in the \meta{type 4
   function} correctly matches the active color model.
 \end{command}
}

\subsection{Using Shadings}
\label{section-shading-a-path}

\begin{command}{\pgfuseshading\marg{shading name}}
    Inserts a previously declared shading into the text. If you wish to use it
    in a |pgfpicture| environment, you should put a |\pgftext| around it.
    %
\begin{codeexample}[]
\begin{pgfpicture}
  \pgfdeclareverticalshading{myshadingD}
    {20pt}{color(0pt)=(red); color(20pt)=(blue)}
  \pgftext[at=\pgfpoint{1cm}{0cm}]  {\pgfuseshading{myshadingD}}
  \pgftext[at=\pgfpoint{2cm}{0.5cm}]{\pgfuseshading{myshadingD}}
\end{pgfpicture}
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfshadepath\marg{shading name}\marg{angle}}
    This command must be used inside a |{pgfpicture}| environment. The effect
    is a bit complex, so let us go over it step by step.

    First, \pgfname\ will set up a local scope.

    Second, it uses the current path to clip everything inside this scope.
    However, the current path is once more available after the scope, so it can
    be used, for example, to stroke it.

    Now, the \meta{shading name} should be a shading whose width and height are
    100\,bp, that is, 100 big points. \pgfname\ has a look at the bounding box
    of the current path. This bounding box is computed automatically when a
    path is computed; however, it can sometimes be (quite a bit) too large,
    especially when complicated curves are involved.

    Inside the scope, the low-level transformation matrix is modified. The
    center of the shading is translated (moved) such that it lies on the center
    of the bounding box of the path. The low-level coordinate system is also
    scaled such that the shading ``covers'' the path (the details are a bit
    more complex, see below). Then, the coordinate system is rotated by
    \meta{angle}. Finally, if the macro |\pgfsetadditionalshadetransform| has
    been used, an additional transformation is applied.

    After everything has been set up, the shading is inserted. Due to the
    transformations and clippings, the effect will be that  the shading seems
    to ``fill'' the path.

    If both the path and the shadings were always rectangles and if rotations
    were never involved, it would be easy to scale shadings such they always
    cover the path. However, when a vertical shading is rotated, it must
    obviously be ``magnified'' so that it still covers the path. Things get
    worse when the path is not a rectangle itself.

    For these reasons, things work slightly differently ``in reality''. The
    shading is scaled and translated such that the point
    $(50\mathrm{bp},50\mathrm{bp})$, which is the middle of the shading, is at
    the middle of the path and such that the point
    $(25\mathrm{bp},25\mathrm{bp})$ is at the lower left corner of the path and
    that  $(75\mathrm{bp},75\mathrm{bp})$  is at upper right corner.

    In other words, only the center quarter of the shading will actually
    ``survive the clipping'' if the path is a rectangle. If the path is not a
    rectangle, but, say, a circle, even less is seen of the shading. Here is an
    example that demonstrates this effect:
    %
\begin{codeexample}[]
\pgfdeclareverticalshading{myshadingE}{100bp}
 {color(0bp)=(red); color(25bp)=(green);  color(75bp)=(blue);  color(100bp)=(black)}
\pgfuseshading{myshadingE}
\hskip 1cm
\begin{pgfpicture}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{2cm}{1cm}}
  \pgfshadepath{myshadingE}{0}
  \pgfusepath{stroke}
  \pgfpathrectangle{\pgfpoint{3cm}{0cm}}{\pgfpoint{1cm}{2cm}}
  \pgfshadepath{myshadingE}{0}
  \pgfusepath{stroke}
  \pgfpathrectangle{\pgfpoint{5cm}{0cm}}{\pgfpoint{2cm}{2cm}}
  \pgfshadepath{myshadingE}{45}
  \pgfusepath{stroke}
  \pgfpathcircle{\pgfpoint{9cm}{1cm}}{1cm}
  \pgfshadepath{myshadingE}{45}
  \pgfusepath{stroke}
\end{pgfpicture}
\end{codeexample}

    As can be seen above in the last case, the ``hidden'' part of the shading
    actually \emph{can} become visible if the shading is rotated. The reason is
    that it is scaled as if no rotation took place, then the rotation is done.

    The following graphics show which part of the shading are actually shown:
    %
\begin{codeexample}[]
\pgfdeclareverticalshading{myshadingF}{100bp}
 {color(0bp)=(red); color(25bp)=(green);  color(75bp)=(blue);  color(100bp)=(black)}
\begin{tikzpicture}
  \draw (50bp,50bp) node {\pgfuseshading{myshadingF}};
  \draw[white,thick] (25bp,25bp) rectangle (75bp,75bp);
  \draw (50bp,0bp) node[below] {first two applications};

  \begin{scope}[xshift=5cm]
    \draw (50bp,50bp) node{\pgfuseshading{myshadingF}};
    \draw[rotate around={45:(50bp,50bp)},white,thick] (25bp,25bp) rectangle (75bp,75bp);
    \draw (50bp,0bp) node[below] {third application};
  \end{scope}

  \begin{scope}[xshift=10cm]
    \draw (50bp,50bp) node{\pgfuseshading{myshadingF}};
    \draw[white,thick] (50bp,50bp) circle (25bp);
    \draw (50bp,0bp) node[below] {fourth application};
  \end{scope}
\end{tikzpicture}
\end{codeexample}

    An advantage of this approach is that when you rotate a radial shading, no
    distortion is introduced:
    %
\begin{codeexample}[]
\pgfdeclareradialshading{ballshading}{\pgfpoint{-10bp}{10bp}}
 {color(0bp)=(red!15!white); color(9bp)=(red!75!white);
 color(18bp)=(red!70!black); color(25bp)=(red!50!black); color(50bp)=(black)}
\pgfuseshading{ballshading}
\hskip 1cm
\begin{pgfpicture}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{1cm}{1cm}}
  \pgfshadepath{ballshading}{0}
  \pgfusepath{}
  \pgfpathcircle{\pgfpoint{3cm}{0cm}}{1cm}
  \pgfshadepath{ballshading}{0}
  \pgfusepath{}
  \pgfpathcircle{\pgfpoint{6cm}{0cm}}{1cm}
  \pgfshadepath{ballshading}{45}
  \pgfusepath{}
\end{pgfpicture}
\end{codeexample}

    If you specify a rotation of $90^\circ$ and if the path is not a square,
    but an elongated rectangle,  the ``desired'' effect results: The shading
    will exactly vary between the colors at the 25bp and 75bp boundaries. Here
    is an example:
    %
\begin{codeexample}[]
\pgfdeclareverticalshading{myshadingG}{100bp}
 {color(0bp)=(red); color(25bp)=(green);  color(75bp)=(blue);  color(100bp)=(black)}
\begin{pgfpicture}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{2cm}{1cm}}
  \pgfshadepath{myshadingG}{0}
  \pgfusepath{stroke}
  \pgfpathrectangle{\pgfpoint{3cm}{0cm}}{\pgfpoint{2cm}{1cm}}
  \pgfshadepath{myshadingG}{90}
  \pgfusepath{stroke}
  \pgfpathrectangle{\pgfpoint{6cm}{0cm}}{\pgfpoint{2cm}{1cm}}
  \pgfshadepath{myshadingG}{45}
  \pgfusepath{stroke}
\end{pgfpicture}
\end{codeexample}

    As a final example, let us define a ``rainbow spectrum'' shading for use
    with \tikzname.
    %
\begin{codeexample}[]
\pgfdeclareverticalshading{rainbow}{100bp}
 {color(0bp)=(red); color(25bp)=(red); color(35bp)=(yellow);
  color(45bp)=(green); color(55bp)=(cyan); color(65bp)=(blue);
  color(75bp)=(violet); color(100bp)=(violet)}
\begin{tikzpicture}[shading=rainbow]
  \shade (0,0) rectangle node[white] {\textsc{pride}} (2,1);
  \shade[shading angle=90] (3,0) rectangle +(1,2);
\end{tikzpicture}
\end{codeexample}

    Note that rainbow shadings are \emph{way} too colorful in almost all
    applications.
\end{command}

\begin{command}{\pgfsetadditionalshadetransform\marg{transformation}}
    This command allows you to specify an additional transformation that should
    be applied to shadings when the |\pgfshadepath| command is used. The
    \meta{transformation} should be transformation code like
    |\pgftransformrotate{20}|.
\end{command}


%%% Local Variables:
%%% mode: latex
%%% TeX-master: "pgfmanual"
%%% End: