% Copyright 2006 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Public License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.

\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreshade.code.tex,v 1.13 2008/11/23 16:07:47 ludewich Exp $

%
% Parsing functions
%
\newdimen\pgf@max
\newcount\pgf@sys@shading@range@num
\def\pgf@parsefunc#1{%
  \edef\temp{{#1}}%
  \expandafter\pgf@convertrgbstring\temp%
  \edef\temp{{\pgf@rgbconv}}%
  \expandafter\pgf@@parsefunc\temp}
\def\pgf@@parsefunc#1{%
  \let\pgf@bounds=\pgfutil@empty%
  \let\pgf@funcs=\pgfutil@empty%
  \let\pgf@psfuncs=\pgfutil@empty%
  \let\pgf@encode=\pgfutil@empty%
  \let\pgf@sys@shading@ranges=\pgfutil@empty%
  \pgf@sys@shading@range@num=0\relax%
  \pgf@parsefirst[#1; ]%
  \pgf@parselastdom[#1; ]%
  \pgf@parsemid[#1; ]%
  \ifx\pgf@bounds\pgfutil@empty%
    \edef\pgf@pdfparseddomain{0 1}%
    \edef\pgf@pdfparsedfunction{\pgf@singlefunc\space}%
  \else%
    \edef\pgf@pdfparseddomain{\pgf@doma\space\pgf@domb}%
    \edef\pgf@pdfparsedfunction{%
      << /FunctionType 3 /Domain [\pgf@doma\space\pgf@domb] /Functions
      [\pgf@funcs\space] /Bounds [\pgf@bounds] /Encode [0 1 \pgf@encode]
      >> }% <<
  \fi%
  \xdef\pgf@psfuncs{\pgf@psfuncs}%
  }
\def\pgf@parsefirst[rgb(#1)=(#2,#3,#4)#5]{%
  \pgfmathsetlength\pgf@x{#1}%
  \edef\pgf@sys@shading@start@pos{\the\pgf@x}%
  \pgf@sys@bp@correct\pgf@x%
  \edef\pgf@doma{\pgf@sys@tonumber{\pgf@x}}%
  \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
  \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
  \edef\pgf@sys@shading@start@rgb{\pgf@sys@rgb}%
  \let\pgf@sys@prevcolor=\pgf@sys@shading@start@rgb%
  \let\pgf@sys@prevpos=\pgf@sys@shading@start@pos%
  \edef\pgf@prevcolor{\pgf@rgb}%
  \edef\pgf@firstcolor{\pgf@rgb}}
\def\pgf@parselastdom[rgb(#1)=(#2,#3,#4); {%
  \pgfutil@ifnextchar]{%
    \pgfmathsetlength\pgf@x{#1}%
    \edef\pgf@sys@shading@end@pos{\the\pgf@x}%
    \pgf@max=\pgf@x\relax%
    \pgf@sys@bp@correct\pgf@x%
    \edef\pgf@domb{\pgf@sys@tonumber{\pgf@x}}%
    \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
    \edef\pgf@sys@shading@end@rgb{\pgf@sys@rgb}%
    \pgfutil@gobble}{\pgf@parselastdom[}}
\def\pgf@parsemid[rgb(#1)=(#2,#3,#4); {\pgf@parserest[}
\def\pgf@parserest[rgb(#1)=(#2,#3,#4); {%
  \advance\pgf@sys@shading@range@num by1\relax%
  \pgfutil@ifnextchar]{%
    \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
    \edef\pgf@singlefunc{\space%
      << /FunctionType 2 /Domain [0 1] /C0
      [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
    \edef\pgf@funcs{\pgf@funcs\space%
      << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
      [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
    \edef\pgf@psfuncs{\pgf@prevx\space \pgf@rgb\space \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
    \pgfmathsetlength\pgf@x{#1}%
    \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{{\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@rgb}}}%
    \edef\pgf@sys@prevpos{\the\pgf@x}%
    \let\pgf@sys@prevcolor=\pgf@sys@rgb%
    \pgfutil@gobble}{%
    \pgfmathsetlength\pgf@x{#1}%
    \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
    \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{{\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@rgb}}}%
    \edef\pgf@sys@prevpos{\the\pgf@x}%
    \let\pgf@sys@prevcolor=\pgf@sys@rgb%
    \edef\pgf@psfuncs{\pgf@prevx\space \pgf@rgb\space \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
    \pgf@sys@bp@correct\pgf@x%
    \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
    \edef\pgf@bounds{\pgf@bounds\space\pgf@sys@tonumber{\pgf@x}}%
    \edef\pgf@encode{\pgf@encode\space0 1}%
    \edef\pgf@singlefunc{\space%
      << /FunctionType 2 /Domain [0 1] /C0
      [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
    \edef\pgf@funcs{\pgf@funcs\space%
      << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
      [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
    \edef\pgf@prevcolor{\pgf@rgb}%
    \pgf@parserest[}}

\def\pgf@getrgbtuplewithmixin#1#2#3{%
  \pgfutil@definecolor{pgfshadetemp}{rgb}{#1,#2,#3}%
  \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfshadetemp}}%
  \pgfutil@extractcolorspec{pgfshadetemp}{\pgf@tempcolor}%
  \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
  \expandafter\pgf@getrgb@@\pgf@rgbcolor!}
\def\pgf@getrgb@@#1,#2,#3!{%
  \def\pgf@rgb{#1 #2 #3}%
  \def\pgf@sys@rgb{{#1}{#2}{#3}}%
}


% Normalized a <color specification> argument for shadings into a
% series of rgb color specifications and writes the result into
% \pgf@rgbconv.
%
% Example:
% \pgf@convertrgbstring{rgb(0cm)=(1,0,0); rgb(2cm)=(0,1,0); rgb(4cm)=(0,0,1); gray(1cm)=(3);  color(2cm)=(green); }
% ->
% \pgf@rgbconv = macro:->'rgb(0cm)=(1,0,0); rgb(2cm)=(0,1,0); rgb(4cm)=(0,0,1); rgb(1cm)=(3,3,3); rgb(2cm)=(0,1,0); '
\def\pgf@convertrgbstring#1{%
  \def\pgf@rgbconv{}%
  \pgf@converttorgb#1]%
  }
\def\pgf@converttorgb{%
  \pgfutil@ifnextchar]{\pgfutil@gobble}%done!
  {%
    \pgfutil@ifnextchar;{\pgf@grabsemicolor}%
    {%
      \pgfutil@ifnextchar r{\pgf@grabrgb}%
      {%
        \pgfutil@ifnextchar g{\pgf@grabgray}%
        {%
          \pgfutil@ifnextchar c{\pgf@grabcolor}%
          {\PackageError{pgfshade}{Illformed shading
              specification}{}\pgf@converttorgb}%
        }%
      }%
    }%
  }%
}
\def\pgf@grabsemicolor;{%
  \edef\pgf@rgbconv{\pgf@rgbconv; }\pgf@converttorgb}
\def\pgf@grabrgb rgb(#1)=(#2,#3,#4){%
  \edef\pgf@rgbconv{\pgf@rgbconv rgb(#1)=(#2,#3,#4)}\pgf@converttorgb}
\def\pgf@grabgray gray(#1)=(#2){%
  \edef\pgf@rgbconv{\pgf@rgbconv rgb(#1)=(#2,#2,#2)}\pgf@converttorgb}
\def\pgf@grabcolor color(#1)=(#2){%
  \pgfutil@colorlet{pgf@tempcol}{#2}%
  \pgfutil@extractcolorspec{pgf@tempcol}{\pgf@tempcolor}%
  \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
  \expandafter\pgf@convgetrgb@\expandafter{\pgf@rgbcolor}{#1}%
}
\def\pgf@convgetrgb@#1#2{%
  \edef\pgf@rgbconv{\pgf@rgbconv rgb(#2)=(#1)}\pgf@converttorgb}




% Declares a horizontal shading for later use. The shading is a
% horizontal bar that changes its color.
%
% #1 = optional dependencies
% #2 = name of the shading for later use
% #3 = height of the shading
% #4 = color specification in the following format: A list of colors
%      that the bar should have at certain points. If the bar should
%      be red at 1cm, this is specified as
%      "rgb(1cm)=(1,0,0)". Multiple specifications are separated by a
%      semicolon and a space. At least two specifications must be
%      given. The specified positions must be given in increasing
%      order. 
%
% Description:
%
% The optional dependecies have the following effect: If present, it
% should consist of a list of colors, separated by commas. Each time
% the shading is used, these colors will be reevaluated. It will be
% checked whether the colors still have their "original meaning". If
% the colors have changed, a new shading will be created internally to
% reflect the changed color's values.
%
% Example:
%
% \pgfdeclarehorizontalshading{redtogreentoblue}{1cm}{%
%   rgb(0cm)=(1,0,0); % red
%   rgb(1cm)=(0,1,0); % green
%   rgb(2cm)=(0,0,1)}
%
% \begin{document}
%   The following bar is 2cm long: \pgfuseshading{redtogreentoblue}.
% \end{document}

\def\pgfdeclarehorizontalshading{\pgfutil@ifnextchar[\pgf@declarehorizontalshading{\pgf@declarehorizontalshading[]}}%
\def\pgf@declarehorizontalshading[#1]#2#3#4{%
  \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
  \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
    \pgfsys@horishading{#2}{#3}{#4}%
  \else%
    \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfsys@horishading}%
    \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}}%
    \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
  \fi}


% Declares a vertical shading for later use. 
%
% #1 = optinal dependecies
% #2 = name of the shading for later use
% #3 = height of the shading
% #4 = color specification 
%
% Example:
%
% \pgfdeclareverticalshading{redtogreentoblue}{1cm}{%
%   rgb(0cm)=(1,0,0); % red
%   rgb(1cm)=(0,1,0); % green
%   rgb(2cm)=(0,0,1)}
%
% \begin{document}
%   The following bar is 2cm high: \pgfuseshading{redtogreentoblue}.
% \end{document}

\def\pgfdeclareverticalshading{\pgfutil@ifnextchar[\pgf@declareverticalshading{\pgf@declareverticalshading[]}}%
\def\pgf@declareverticalshading[#1]#2#3#4{%
  \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
  \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
    \pgfsys@vertshading{#2}{#3}{#4}%
  \else%
    \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfsys@vertshading}%
    \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}}%
    \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
  \fi}


% Declares a radial shading for later use. 
%
% #1 = optional dependencies
% #2 = name of the shading for later use
% #3 = center of inner circle
% #4 = color specification 
%
% Description:
%
% A radial shading creates a smooth color transition between two
% circles. The center of the inner circle is at the give position. Its
% radius is the start of the color specification. The
% center of the outer circle is at the center of the whole shading,
% whose radius is the end of the color specification. For example,
% suppose the color specification is "rgb(1cm)=(1,1,1); rgb(2cm)=(0,0,0)".  
% Then the shading would be 4cm times 4cm large. The inner circle would
% have diameter 1cm and the outer circle would have diameter 2cm. The
% outer circle would be centered in the middle of the shading, whereas
% the outer circle would be centered at the given position.
%
% Example:
%
% \pgfdeclareradialshading{redtogreentoblue}{\pgfpoint{2cm}{2cm}}{%
%   rgb(10pt)=(1,0,0); % red
%   rgb(2cm)=(0,1,0); % green
%   rgb(3cm)=(0,0,1)}
%
% \begin{document}
%   The following ball has diameter 3cm: \pgfuseshading{redtogreentoblue}.
% \end{document}

\def\pgfdeclareradialshading{\pgfutil@ifnextchar[\pgf@declareradialshading{\pgf@declareradialshading[]}}%
\def\pgf@declareradialshading[#1]#2#3#4{%
  \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
  \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
    \pgfsys@radialshading{#2}{#3}{#4}%
  \else%
    \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfsys@radialshading}%
    \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}}%
    \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
  \fi}




% Declares a functional shading for later use. 
%
% #1 = optional dependecies
% #2 = name of the shading for later use
% #3 = lower left corner of the shading as a pgfpoint.
% #4 = upper right corner of the shading as a pgfpoint.
% #5 = Preparation code
% #6 = a PDF type 4 function (restricted Postscript function), see the 
%      PDF-specification 1.7, section 3.9.4
%
% Description:
%
% This command creates a so-called functional shading. For such a
% shading the color of each point is calculated by calling a function
% for each point that gets the coordinates as input and yields the
% color as an output. Note that the function is evaluated by the
% *renderer*, not by PGF or TeX or someone else at compile-time. This
% means that the evaluation of this function has to be done *extremely
% quickly* and the funciton should be *very simple*. For this reason,
% only a very restricted set of operations are possible in the
% function (see 3.9.4 of the PDF-spec 1.7). Also functions should be
% kept small. Any errors in the function will only be noticed by the
% renderer.
%
% The function gets the coordinates of a point as input (as bp). This
% input consists of the top two elements of an otherwise empty
% (virtual, PostScript) stack. The function should then replace these
% two values by three values, representing the red, green, and blue
% color of the point. The numbers should be real values, not integers
% since Apple's PDF renderer is broken in this regard (use cvr at the
% end if necessary).
%
% Conceptually, the function will be evaluated once for each point of
% the rectangle (#3) to (#4). 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 *if you know what you are doing* (or if you are advanterous, of
% course). 
%
% As for other shadings, the optional depencies argument is used to
% determine whether a shading needs to be recalculated when a color
% has changed.
%
% The code #5 is executed each time a shading is
% (re)calculated. Typically, it will contain code to extract
% coordinates from colors (see below).
%
% Inside the PostScript function #6 you cannot use colors
% directly. Rather, you must push the color components on the
% stack. For this, it is useful to call \pgfshadergb in the startup
% code #4. The macro takes a color name as input 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 a macro. 
%
% Example:
%
%\pgfdeclarefunctionalshading{twospots}{\pgfpointorigin}{\pgfpoint{200bp}{200bp}}{}{
%  2 copy
%  90 sub dup mul exch
%  80 sub dup mul add sqrt
%  dup mul neg 1.0005 exch exp 1.0 exch sub
%  3 1 roll
%  120 sub dup mul exch
%  100 sub dup mul add sqrt
%  dup mul neg 1.002 exch exp 1.0 exch sub
%  1.0
%}
%
% \pgfdeclarefunctionalshading[mycol]{sweep}{\pgfpointorigin}{\pgfpoint{100bp}{100bp}}
% {\pgfshadecolortorgb{mycol}{\myrgb}}{
%   add 150 div   % not very useful...
%   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
% }
%
% \begin{document}
%   Have a look at this: \pgfuseshading{twospots}.
%   Here is \colorlet{mycol}{green!50}\pgfuseshading{sweep} in green
%   and in \colorlet{mycol}{red!50!blue}\pgfuseshading{sweep} in red/blue.
% \end{document}

\def\pgfdeclarefunctionalshading{\pgfutil@ifnextchar[\pgf@declarefunctionalshading{\pgf@declarefunctionalshading[]}}%
\def\pgf@declarefunctionalshading[#1]#2#3#4#5#6{%
  \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
  \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
    \pgfshade@functionaldo{#2}{#3}{#4}{#5}{#6}%
  \else%
    \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfshade@functionaldo}%
    \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}{#5}{#6}}%
    \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
  \fi}
\def\pgfshade@functionaldo#1#2#3#4#5{%
  {%
    #4%
    \pgfsys@functionalshading{#1}{#2}{#3}{#5}%
  }%
}

\def\pgfshadecolortorgb#1#2{%
  \pgfutil@colorlet{pgf@tempcol}{#1}%
  \pgfutil@extractcolorspec{pgf@tempcol}{\pgf@tempcolor}%
  \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
  \expandafter\pgfshading@rgb\pgf@rgbcolor\relax%
  \edef#2{\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@xc}\space}%
  \c@pgf@counta\escapechar%
  \escapechar-1\relax%
  \expandafter\edef\csname\string#2red\endcsname{\pgf@sys@tonumber{\pgf@xa}\space}%
  \expandafter\edef\csname\string#2green\endcsname{\pgf@sys@tonumber{\pgf@xb}\space}%
  \expandafter\edef\csname\string#2blue\endcsname{\pgf@sys@tonumber{\pgf@xc}\space}%
  \escapechar\c@pgf@counta%
}
\def\pgfshading@rgb#1,#2,#3\relax{%
  \pgf@xa=#1pt%
  \pgf@xb=#2pt%
  \pgf@xc=#3pt%
}




% Inserts a box into the text that contains a previously defined
% shading. 
%
% #1 = Name of a shading
%
% Example:
%
% \pgfuseshading{redtogreentoblue}

\def\pgfuseshading#1{%
  \edef\pgf@shadingname{@pgfshading#1}%
  \pgf@tryextensions{\pgf@shadingname}{\pgfalternateextension}%
  \expandafter\pgfutil@ifundefined\expandafter{\pgf@shadingname}%
  {\PackageError{pgfshade}{Undefined shading "#1"}{}}%
  {%
    {%
      \pgfutil@globalcolorsfalse%
      \def\pgf@shade@adds{}%
      \pgfutil@ifundefined{pgf@deps\pgf@shadingname}%
      {}%
      {%
        \edef\@list{\csname pgf@deps\pgf@shadingname\endcsname}%
        \pgfutil@for\@temp:=\@list\do{%
          {%
            \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{\@temp}}%
            \pgfutil@extractcolorspec{\@temp}{\pgf@tempcolor}%
            \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
            \xdef\pgf@shade@adds{\pgf@shade@adds,\pgf@rgbcolor}%
          }%
        }%
      }%
      \expandafter\pgf@strip@shadename\pgf@shadingname!!%
      \pgfutil@ifundefined{@pgfshading\pgf@basename\pgf@shade@adds!}%
      {%
        {%
          \expandafter\def\expandafter\@temp\expandafter{\csname pgf@func\pgf@shadingname\endcsname}%
          \edef\@args{{\pgf@basename\pgf@shade@adds}}%
          \expandafter\expandafter\expandafter\def%
          \expandafter\expandafter\expandafter\@@args%
          \expandafter\expandafter\expandafter{\csname pgf@args\pgf@shadingname\endcsname}%
          \expandafter\expandafter\expandafter\@temp\expandafter\@args\@@args%
          %
        }%
      }%
      {}%
      \pgf@invokeshading{\csname @pgfshading\pgf@basename\pgf@shade@adds!\endcsname}%
    }%
  }%
}

\def\pgf@strip@shadename @pgfshading#1!!!{\def\pgf@basename{#1}}

\def\pgf@invokeshading#1{%
  \ifpgfpicture%
    \pgfsys@shadinginsidepgfpicture{#1}%
  \else%
    \pgfsys@shadingoutsidepgfpicture{#1}%  
  \fi%
}


% Create an alias name for a shading
%
% #1 = name of the alias
% #2 = name of the original
%
% Example:
%
% \pgfaliasshading{shading!25}{shadingshaded}

\def\pgfaliasshading#1#2{%
  \expandafter\let\expandafter\pgf@temp\expandafter=\csname @pgfshading#2!\endcsname%
  \expandafter\let\csname @pgfshading#1!\endcsname=\pgf@temp%
  \expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@deps@pgfshading#2!\endcsname%
  \expandafter\let\csname pgf@deps@pgfshading#1!\endcsname=\pgf@temp%
  \expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@func@pgfshading#2!\endcsname%
  \expandafter\let\csname pgf@func@pgfshading#1!\endcsname=\pgf@temp%
  \expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@args@pgfshading#2!\endcsname%
  \expandafter\let\csname pgf@args@pgfshading#1!\endcsname=\pgf@temp%
}




% Shades the current path, but does not discard it.
%
% #1 - a shading (see below)
% #2 - an angle
%
% Description:
%
% \pgfshadepath  ``tries'' to fill the
% current path with a shading. The shading's original size should
% completely cover the area between (0,0) and (100bp,100bp). The
% shading will be rotated by #2 and then rescaled so that it
% completely covers the path. Then the path will be used (locally) for
% clipping and the shading is drawn.
%
% In addition to the rotation, any transformation set by the
%\pgfsetadditionalshadetransform will also be applied.
%
% After all this, the path can still be used for the normal
% stroking/clipping operations.
%
% The shading is rotated around its middle. If no rotation occurs, the
% lower left corner of the path will lie on (25bp, 25bp), the upper
% right corner on (75bp, 75bp).
%
% Example:
%
% \pgfdeclareverticalshading{myshading}{100bp}{color(0pt)=(red); color(100bp)=(green)}
%
% \pgfpathmoveto{\pgforigin}
% \pgfpathlineto{\pgfxy(1,0)}
% \pgfpathlineto{\pgfxy(1,1)}
% \pgfshadepath{myshading}{0}
% \pgfusepath{stroke}

\def\pgfshadepath#1#2{%
  \ifdim\pgf@pathminx=16000pt%
    \PackageWarning{pgfshade}{No path specified that can be filled}%
  \else%
    \begingroup%  
      \pgfsys@beginscope%
        % Calculate center:
        \pgf@xb=.5\pgf@pathmaxx%
        \advance\pgf@xb by.5\pgf@pathminx%
        \pgf@yb=.5\pgf@pathmaxy%
        \advance\pgf@yb by.5\pgf@pathminy%
        % Calculate scaling:
        \pgf@xc=\pgf@pathmaxx%
        \advance\pgf@xc by-\pgf@pathminx%
        \pgf@yc=\pgf@pathmaxy%
        \advance\pgf@yc by-\pgf@pathminy%
        \pgf@xc=.01992528\pgf@xc%
        \pgf@yc=.01992528\pgf@yc%
        \pgfsyssoftpath@invokecurrentpath%
        \pgfsys@clipnext%
        \pgfsys@discardpath%
        % Compute new transformation matrix:
        \pgfsys@transformcm{1}{0}{0}{1}{\pgf@xb}{\pgf@yb}%
        \pgfsys@transformcm%
        {\pgf@sys@tonumber{\pgf@xc}}{0}%
        {0}{\pgf@sys@tonumber{\pgf@yc}}{0pt}{0pt}%
        \pgfmathparse{#2}%
        \let\pgfshade@angle=\pgfmathresult%
        \pgfmathsin@{\pgfshade@angle}%
        \let\pgfshade@sin=\pgfmathresult%
        \pgfmathcos@{\pgfshade@angle}%
        \let\pgfshade@cos=\pgfmathresult%
        \pgf@x=\pgfshade@sin pt%
        \pgf@xa=-\pgf@x%
        \pgfsys@transformcm{\pgfshade@cos}{\pgfshade@sin}{\pgf@sys@tonumber{\pgf@xa}}{\pgfshade@cos}{0pt}{0pt}%
        \ifx\pgf@shade@extra@transform\pgfutil@empty%
        \else%
          \pgflowlevel{\pgf@shade@extra@transform}%
        \fi%
        \pgfuseshading{#1}%
      \pgfsys@endscope%
    \endgroup%
  \fi%
}


% Additionally transform shade paths
%
% #1 = Transformation code that is used in addition to the normal
%      shading transformation.
%
% Example:
%
% \pgfsetadditionalshadetransform{\pgftransformrotate{30}}

\def\pgfsetadditionalshadetransform#1{\def\pgf@shade@extra@transform{#1}}
\let\pgf@shade@extra@transform=\pgfutil@empty





\endinput
