From feff1cc0f96b1f1fe3efe5e730ace078c021827b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 11 Jan 2006 23:56:52 +0000 Subject: trunk/Master/texmf-dist/source/latex/pst-slpe git-svn-id: svn://tug.org/texlive/trunk@476 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/source/latex/pst-slpe/pst-slpe.dtx | 830 +++++++++++++++++++++ .../texmf-dist/source/latex/pst-slpe/pst-slpe.ins | 25 + 2 files changed, 855 insertions(+) create mode 100644 Master/texmf-dist/source/latex/pst-slpe/pst-slpe.dtx create mode 100644 Master/texmf-dist/source/latex/pst-slpe/pst-slpe.ins diff --git a/Master/texmf-dist/source/latex/pst-slpe/pst-slpe.dtx b/Master/texmf-dist/source/latex/pst-slpe/pst-slpe.dtx new file mode 100644 index 00000000000..a67664b0057 --- /dev/null +++ b/Master/texmf-dist/source/latex/pst-slpe/pst-slpe.dtx @@ -0,0 +1,830 @@ +%\iffalse -*-mode:Latex;tex-command:"latex *;dvips pst-slpe -o"-*- \fi +%\iffalse +% $Id: pst-slpe.dtx,v 1.7 1998/09/15 12:43:03 giese Exp $ +% +% Copyright 1998 Martin Giese, giese@ira.uka.de +% 2005 Herbert Voss (using xkeyval) +% +% This file is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +% +% IMPORTANT COPYRIGHT NOTICE: +% +% Permission is granted to copy this file to another file with a clearly +% different name and to customize the declarations in that copy to serve +% the needs of your installation, provided that you comply with +% the conditions in the file legal.txt from the LaTeX2e distribution. +% +% However, NO PERMISSION is granted to produce or to distribute a +% modified version of this file under its original name. +% +% You are NOT ALLOWED to change this file. +% +%\fi +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% \CheckSum{163} +% +% \changes{v1.1}{2005/10/05}{% +% using the extended pst-xkey instead of the old pst-key package; +% creating a dtx file (hv)} +% \changes{v1.0}{2005/03/05}{More compatible to the other PStricks +% packages. (RN)} +% +%\iffalse +%<*!prolog> +\def\pstslpefileversion{1.1} +\def\pstslpefiledate{2005/10/05} +% +%\fi +% +% \title{\textsf{pst-slpe} package \\ version \pstslpefileversion} +% \author{Martin Giese\footnote{email:\texttt{giese@ira.uka.de}}} +% \date{\pstslpefiledate} +% \maketitle +% +%\section{Introduction} +%As of the 97 release, PSTricks contains the |pst-grad| +%package, which provides a gradient fill style for arbitrary shapes. +%Although it often produces nice results, it has a number of +%deficiencies: +%\begin{enumerate} +%\item It is not possible to go from a colour $A$ to $B$ to $C$, +%etc. The most evident application of such a multi-colour gradient are +%of course rainbow effects. But they can also be useful in informative +%contexts, eg to identify modes of operation in a scale of values +%(normal/danger/overload). +%\item Colours are interpolated linearly in the RGB space. This is +%often OK, but when you want to go from red $(1,0,0)$ to green +%$(0,1,0)$, it looks much better to get there via yellow $(1,1,0)$ than +%via brown $(0.5,0.5,0)$. The point is, that to get from one saturated +%colour to another, the colours on the way should also be saturated to +%produce an optically pleasing result. +%\item |pst-grad| is limited to {\em linear} gradients, ie~there +%is a (possibly rotated) rectilinear coordinate system, such that the +%colour at every point depends only on the $x$ coordinate of the +%point. In particular, there is no way to get circular patterns. +%\end{enumerate} +%|pst-slpe| solves {\em all} of the mentioned +%problems in {\em one} package. +% +%Problems 1.~is addressed by permitting the user to specify an +%arbitrary number of colours, along with the points at which these are +%to be reached. A special form of each of the fill styles is provided, +%which just needs two colours as parameters, and goes from one to the +%other. This makes the fill styles easier to use in that simple case. +% +%Problem 2.~is solved by interpolating in the hue-saturation-value +%colour space. Conversion between RGB and HSV is done behind the +%scenes. The user specifies colours in RGB. +% +%Finally, |pst-slpe| provides {\em concentric} and {\em radial} +%gradients. What these mean is best explained with a polar coordinate +%system: In a concentric pattern, the colour of a point depends on the +%radius coordinate, while in a radial pattern, it depends on the angle +%coordinate. +% +%As a special bonus, the PostScript part of |pst-slpe| is somewhat +%optimized for speed. In |ghostscript|, rendering is about 30\% faster +%than with |pst-grad|. +%\medskip +% +%For most of these problems, solutions have been posted in the +%appropriate \TeX\ newsgroup over the years. |pst-slpe| has however +%been developed independently from these proposals. It is based on +%the original PSTricks 0.93 |gradient| code, most of which has been +%changed or replaced. The +%author is indebted to Denis Girou, whose encouragement triggered the +%process of making this a shipable package instead of a private +%experiment. +%\medskip +% +%The new fill styles and the +%graphics parameters provided to use them are described in +%section 2 of this document. Section 3, if present, documents the +%implementation consisting of a generic \TeX\ file and a PostScript +%header for the |dvi|-to-PostScript converter. You can get section 3 +%by calling \LaTeX\ as follows on most relevant systems: +%\begin{verbatim} +%latex '\AtBeginDocument{\AlsoImplementation}\input{pst-slpe.dtx}' +%\end{verbatim} +%\section{Package Usage} +% To use |pst-slpe|, you have to say +% \begin{verbatim} +% \usepackage{pst-slpe} +% \end{verbatim} +% in the document prologue for \LaTeX, and +% \begin{verbatim} +% \input pst-slpe.tex +% \end{verbatim} +% in ``plain'' \TeX. +% +% \DescribeMacro{slope} +% \DescribeMacro{slopes} +% \DescribeMacro{ccslope} +% \DescribeMacro{ccslopes} +% \DescribeMacro{radslope} +% \DescribeMacro{radslopes} +% |pst-slpe| provides six new fill styles called |slope|, |slopes|, +% |ccslope|, |ccslopes|, |radslope| and |radslopes|. These obviously +% come in pairs: The $\ldots$|slope|-styles are simplified versions of +% the general $\ldots$|slopes|-styles.\footnote{By the way, I use slope +% as a synonym for gradient. It sounds less pretentious and avoids +% name clashes.} The |cc|$\ldots$ styles paint concentric patterns, +% and the |rad|$\ldots$ styles do radial ones. Here is a little +% overview of what they look like: +% \newcommand{\st}{$\vcenter to30pt{}$} +% \begin{quote}\LARGE +% \begin{tabular}{cc} +% \psframebox[fillstyle=slope]{\st|slope|} &\qquad +% \psframebox[fillstyle=slopes]{\st|slopes|} \\[2ex] +% \psframebox[fillstyle=ccslope]{\st|ccslope|} &\qquad +% \psframebox[fillstyle=ccslopes]{\st|ccslopes|} \\[2ex] +% \psframebox[fillstyle=radslope]{\st|radslope|} &\qquad +% \psframebox[fillstyle=radslopes]{\st|radslopes|} \\[2ex] +% \end{tabular} +% \end{quote} +% These examples were produced by saying simply +% \begin{verbatim} +% \psframebox[fillstyle=slope]{...} +% \end{verbatim} +% etc.~without setting any further graphics parameters. The package +% provides a number of parameters that can be used to control +% the way these patterns +% are painted. +% \medskip +% +% \DescribeMacro{slopebegin} +% \DescribeMacro{slopeend} +% The graphics parameters |slopebegin| and |slopeend| set the colours +% between which the three $\ldots$|slope| styles should interpolate. +% Eg, +% \begin{verbatim} +% \psframebox[fillstyle=slope,slopebegin=red,slopeend=green]{...} +% \end{verbatim} +% produces: +% \begin{quote}\Large +% \psframebox[fillstyle=slope,slopebegin=red,slopeend=green]{\st slopes!} +% \end{quote} +% The same settings of |slopebegin| and |slopeend| for the |ccslope| +% and |radslope| fillstyles produce +% \begin{quote}\Large +% \psframebox[fillstyle=ccslope,slopebegin=red,slopeend=green]{\st slopes!} +% \quad{\normalsize resp.}\quad +% \psframebox[fillstyle=radslope,slopebegin=red,slopeend=green]{\st slopes!} +% \end{quote} +% The default settings go from a greenish yellow to pure blue. +% \medskip +% +% \DescribeMacro{slopecolors} +% If you want to interpolate between more than two colours, you have +% to use the $\ldots$|slopes| styles, which are controlled by the +% |slopecolors| parameter instead of |slopebegin| and |slopeend|. The +% idea is to specify the colour to use at certain points `on the +% way'. To fill a shape with |slopes|, imagine a linear scale +% from its left edge to its right edge. The left edge must lie at +% coordinate 0. Pick an arbitrary value for the right edge, say 23. +% Now you want to get light yellow at the left edge, a pastel green at $17/23$ +% of the way and dark cyan at the right edge, like this: +% \begin{quote}\psset{unit=0.45cm} +% \begin{pspicture}(-1,0)(24,6) +% \pscustom[fillstyle=slopes, +% slopecolors=0 1 1 .9 17 .5 1 .5 23 0 0.5 0.5 3]{ +% \psccurve(0,2.5)(12,3.5)(20,4)(23,2)(17,2.5)} +% \psaxes(0,5)(-0.01,5)(23.01,5) +% \psline(0,5)(0,1) +% \psline(17,5)(17,1) +% \psline(23,5)(23,1) +% \end{pspicture} +% \end{quote} +% The RGB values for the three colours are $(1,1,0.9)$, $(0.5,1,0.5)$ +% and $(0,0.5,0.5)$. The value for the |slopecolors| parameter is a list +% of `colour infos' followed by the number of `colour infos'. +% Each `colour info' consists +% of the coordinate value where a colour is to be specified, followed by +% the RGB values of that colour. All these values are separated by +% white space. The correct setting for the example is thus: +% \begin{verbatim} +% slopecolors=0 1 1 .9 17 .5 1 .5 23 0 .5 .5 3 +% \end{verbatim} +% For |ccslopes|, specify the colours from the center outward. +% For |radslopes| (with no rotation specified), 0 represents the ray +% going `eastward'. Specify the colours anti-clockwise. If you want a +% smooth gradient at the beginning and starting ray of |radslopes|, you +% should pick the first and last colours identical. +% +% Please note, that the |slopecolors| parameter is not subject to any +% parsing on the \TeX\ side. If you forget a number or specify the wrong +% number of segments, the PostScript interpreter will probably crash. +% +% The default value for |slopecolors| specifies a rainbow. +% +% \medskip +% +% \DescribeMacro{slopesteps} +% The parameter |slopesteps| controls the number of distinct colour steps +% rendered. Higher values for this parameter result in better quality +% but proportionally slower rendering. Eg, setting +% |slopesteps| to 5 with the |slope| fill style results in +% \begin{quote}\Large +% \psframebox[fillstyle=slope,slopesteps=5]{\st slopes!} +% \end{quote} +% +% The default value is 100, which +% suffices for most purposes. Remember that the number of distinct colours +% reproducible by a given device is limited. Pushing |slopesteps| to +% high will result only in loss of performance at no gain in quality. +% \medskip +% +% \DescribeMacro{slopeangle} +% The |slope(s)| and |radslope(s)| patterns may be rotated. As usual, +% the angles are given anti-clockwise. Eg, an angle of 30 degrees +% gives +% \begin{quote}\Large\psset{slopeangle=30} +% \psframebox[fillstyle=slope]{\st slopes!} +% \quad{\normalsize and}\quad +% \psframebox[fillstyle=radslope]{\st slopes!} +% \end{quote} +% with the |slope| and |radslope| fillstyles. +% \medskip +% +% \DescribeMacro{slopecenter} +% For the |cc|$\ldots$ and |rad|$\ldots$ styles, it is possible to +% set the center of the pattern. The |slopecenter| parameter is set to +% the coordinates of that center relative to the bounding box of the +% current path. The following effect: +% \begin{quote}\psset{unit=0.45cm} +% \begin{pspicture}(-1,-1)(24,5) +% \pscustom[fillstyle=radslope,slopecenter=0.2 0.4]{ +% \pspolygon(0,2.5)(12,2.5)(20,4)(23,2)(17,2.5)(3,0)} +% \psaxes[axesstyle=frame,Dx=0.1,dx=2.2999,Dy=0.2,dy=0.7999](0,0)(23,4) +% \psline(4.6,0)(4.6,4) +% \psline(0,1.6)(23,1.6) +% \end{pspicture} +% \end{quote} +% was achieved with +% \begin{verbatim} +% fillstyle=radslope,slopecenter=0.2 0.4 +% \end{verbatim} +% The default value for |slopecenter| is |0.5 0.5|, which is the +% center for symmetrical shapes. Note that this parameter is not +% parsed by \TeX, so setting it to anything else than two numbers +% between 0 and 1 might crash the PostScript interpreter. +% \medskip +% +% \DescribeMacro{sloperadius} +% Normally, the |cc|$\ldots$ and |rad|$\ldots$ styles distribute the +% given colours so that the center is painted in the first colour given, +% and the points of the shape furthest from the center are painted in +% the last colour. In other words the maximum radius to which the +% |slopecolors| parameter refers is the maximum distance from the +% center (defined by |slopecenter|) to any point on the periphery +% of the shape. This radius can be explicitly set with |sloperadius|. +% Eg, setting |sloperadius=0.5cm| gives +% \begin{quote}\Large\psset{sloperadius=0.5cm} +% \psframebox[fillstyle=ccslope]{\st slopes!} +% \end{quote} +% Any point further from the center than the given |sloperadius| is +% painted with the last colour in |slopeclours|, resp.~|slopeend|. +% +% The default value for |sloperadius| is 0, which invokes the default +% behaviour of automatically calculating the radius. +% +% \StopEventually{} +%\section{The Code} +% \subsection{Producing the documentation} +% +% A short driver is provided that can be extracted if necessary by +% the \textsc{docstrip} program provided with \LaTeXe. +% \begin{macrocode} +%<*driver> +\NeedsTeXFormat{LaTeX2e} +\documentclass{ltxdoc} +\usepackage{pst-slpe} +\usepackage{pst-plot} +\DisableCrossrefs +\MakeShortVerb{\|} +\newcommand\Lopt[1]{\textsf{#1}} +\newcommand\file[1]{\texttt{#1}} +\AtEndDocument{ +\PrintChanges +%\PrintIndex +} +%\OnlyDescription +\begin{document} +\DocInput{pst-slpe.dtx} +\end{document} +% +% \end{macrocode} +% +% \subsection{The \file{pst-slpe.sty} file} +% The \file{pst-slpe.sty} file is very simple. It just loads +% the generic \file{pst-slpe.tex} file. +% \begin{macrocode} +%<*stylefile> +\RequirePackage{pstricks} +\ProvidesPackage{pst-slpe}[2005/03/05 package wrapper for `pst-slpe.tex'] +\input{pst-slpe.tex} +\ProvidesFile{pst-slpe.tex} + [\pstslpefiledate\space v\pstslpefileversion\space `pst-slpe' (Martin Giese)] +% +% \end{macrocode} +% +% \subsection{The \file{pst-slpe.tex} file} +% \file{pst-slpe.tex} contains the \TeX-side of things. We begin +% by identifying ourselves and setting things up, the same as in +% other PSTricks packages. +% \begin{macrocode} +%<*texfile> +\message{ v\pstslpefileversion, \pstslpefiledate} +\csname PstSlopeLoaded\endcsname +\let\PstSlopeLoaded\endinput +\ifx\PSTricksLoaded\endinput\else + \def\next{\input pstricks.tex }\expandafter\next +\fi +\ifx\PSTXKeyLoaded\endinput\else\input pst-xkey \fi % --> hv +\edef\TheAtCode{\the\catcode`\@} +\catcode`\@=11 +\pst@addfams{pst-slpe} % --> hv +\pstheader{pst-slpe.pro} +% \end{macrocode} +% \begin{macro}{slopebegin} +% \begin{macro}{slopeend} +% \begin{macro}{slopesteps} +% \begin{macro}{slopeangle} +% \subsubsection{New graphics parameters} +% We now define the various new parameters needed by the |slope| +% fill styles and install default values. First come the colours, +% ie~graphics parameters |slopebegin| and |slopeend|, followed +% by the number of steps, |slopesteps|, and the rotation angle, +% |slopeangle|. +% \begin{macrocode} +\newrgbcolor{slopebegin}{0.9 1 0} +\define@key[psset]{pst-slpe}{slopebegin}{\pst@getcolor{#1}\psslopebegin}% --> hv +\psset[pst-slpe]{slopebegin=slopebegin} % --> hv + +\newrgbcolor{slopeend}{0 0 1} +\define@key[psset]{pst-slpe}{slopeend}{\pst@getcolor{#1}\psslopeend}% --> hv +\psset[pst-slpe]{slopeend=slopeend}% --> hv + +\define@key[psset]{pst-slpe}{slopesteps}{\pst@getint{#1}\psslopesteps}% --> hv +\psset[pst-slpe]{slopesteps=100}% --> hv + +\define@key[psset]{pst-slpe}{slopeangle}{\pst@getangle{#1}\psx@slopeangle}% --> hv +\psset[pst-slpe]{slopeangle=0}% --> hv +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{slopecolors} +% The value for |slopecolors| is not parsed. It is directly copied +% to the PostScript output. This is certainly not the way it +% should be, but it's simple. The default value is a rainbow from +% red to magenta. +% \begin{macrocode} +\define@key[psset]{pst-slpe}{slopecolors}{\def\psx@slopecolors{#1}}% --> hv +\psset[pst-slpe]{slopecolors={% --> hv +0.0 1 0 0 +0.4 0 1 0 +0.8 0 0 1 +1.0 1 0 1 +4}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{slopecenter} +% The argument to |slopecenter| isn't parsed either. But there's +% probably not much that can go wrong with two decimal numbers. +% \begin{macrocode} +\define@key[psset]{pst-slpe}{slopecenter}{\def\psx@slopecenter{#1}}% --> hv +\psset[pst-slpe]{slopecenter={0.5 0.5}}% --> hv +% \end{macrocode} +% \end{macro} +% \begin{macro}{sloperadius} +% The default value for |sloperadius| is 0, which makes the +% PostScript procedure |PatchRadius| determine a value for the radius. +% \begin{macrocode} +\define@key[psset]{pst-slpe}{sloperadius}{\pst@getlength{#1}\psx@sloperadius}% --> hv +\psset[pst-slpe]{sloperadius=0}% --> hv +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Fill style macros} +% +% Now come the fill style definitions that use these parameters. +% There is one macro for each fill style named |\psfs@|$style$. +% PSTricks calls this macro whenever the current path needs to +% be filled in that style. The current path should not be +% clobbered by the PostScript code output by the macro. +% +% \begin{macro}{slopes} +% For the slopes fill style we produce PostScript code that +% first puts the |slopecolors| parameter onto the stack. Note that +% the number of colours listed, which comes last in |slopecolors| is +% now on the top of the stack. Next come the |slopesteps| and +% |slopeangle| parameters. We switch to the dictionary established +% by the \file{pst-slop.pro} Prolog and call |SlopesFill|, which +% does the artwork and takes care to leave the path alone. +% \begin{macrocode} +\def\psfs@slopes{% + \addto@pscode{ + \psx@slopecolors\space + \psslopesteps + \psx@slopeangle + tx@PstSlopeDict begin SlopesFill end}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{slope} +% The |slope| style uses parameters |slopebegin| and |slopeend| +% instead of |slopecolors|. So the produced PostScript uses these +% parameters to build a stack in |slopecolors| format. The +% |\pst@usecolor| generates PostScript to set the current colour. +% We can query the RGB values with |currentrgbcolor|. +% A |gsave|/|grestore| pair is used to avoid changing the +% PostScript graphics state. Once the stack is set up, +% |SlopesFill| is called as before. +% \begin{macrocode} +\def\psfs@slope{% + \addto@pscode{% + gsave + 0 \pst@usecolor\psslopebegin currentrgbcolor + 1 \pst@usecolor\psslopeend currentrgbcolor + 2 + grestore + \psslopesteps \psx@slopeangle tx@PstSlopeDict begin SlopesFill end}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ccslopes} +% \begin{macro}{ccslope} +% \begin{macro}{radslopes} +% The code for the other fill styles is about the same, except for a few +% parameters more or less and different PostScript procedures called +% to do the work. +% \begin{macrocode} +\def\psfs@ccslopes{% + \addto@pscode{% + \psx@slopecolors\space + \psslopesteps \psx@slopecenter\space \psx@sloperadius\space + tx@PstSlopeDict begin CcSlopesFill end}} +\def\psfs@ccslope{% + \addto@pscode{% + gsave 0 \pst@usecolor\psslopebegin currentrgbcolor + 1 \pst@usecolor\psslopeend currentrgbcolor + 2 grestore + \psslopesteps \psx@slopecenter\space \psx@sloperadius\space + tx@PstSlopeDict begin CcSlopesFill end}} +\def\psfs@radslopes{% + \addto@pscode{% + \psx@slopecolors\space + \psslopesteps\psx@slopecenter\space\psx@sloperadius\space\psx@slopeangle + tx@PstSlopeDict begin RadSlopesFill end}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{radslope} +% |radslope| is slightly different: Just going from one colour to +% another in 360 degrees is usually not what is wanted. |radslope| just +% does something pretty with the colours provided. +% \begin{macrocode} +\def\psfs@radslope{% + \addto@pscode{% + gsave 0 \pst@usecolor\psslopebegin currentrgbcolor + 1 \pst@usecolor\psslopeend currentrgbcolor + 2 \pst@usecolor\psslopebegin currentrgbcolor + 3 \pst@usecolor\psslopeend currentrgbcolor + 4 \pst@usecolor\psslopebegin currentrgbcolor + 5 grestore + \psslopesteps\psx@slopecenter\space\psx@sloperadius\space\psx@slopeangle + tx@PstSlopeDict begin RadSlopesFill end}} + +\catcode`\@=\TheAtCode\relax +% +% \end{macrocode} +% \end{macro} +% +% \subsection{The \file{pst-slpe.pro} file} +% The file \file{pst-slpe.pro} contains PostScript definitions +% to be included in the PostScript output by the +% |dvi|-to-PostScript converter, eg |dvips|. +% First thing is to define a +% dictionary to keep definitions local. +% \begin{macrocode} +%<*prolog> +/tx@PstSlopeDict 60 dict def tx@PstSlopeDict begin +% \end{macrocode} +% +% \begin{macro}{max} +% $x1 \quad x2 \quad \mathtt{max}\quad max$\\ +% |max| is a utility function that calculates the maximum +% of two numbers. +% \begin{macrocode} +/max {2 copy lt {exch} if pop} bind def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{Iterate} +% $p_1\quad r_1\quad g_1\quad b_1\quad\ldots\quad +% p_n\quad r_n\quad g_n\quad b_n\quad n\quad \mathtt{Iterate}\quad -$\\ +% This is the actual iteration, which goes through the colour +% information and plots the segments. +% It uses the value of |NumSteps| which is set by the wrapper +% procedures. |DrawStep| is called all of |NumSteps| times, so +% it had better be fast. +% +% First, the number of colour infos is read from the +% top of the stack and decremented, to get the number of segments. +% \begin{macrocode} +/Iterate { + 1 sub /NumSegs ED +% \end{macrocode} +% Now we get the first colour. This is really the {\em last} +% colour given in the |slopecolors| argument. We have to work +% {\em down} the stack, so we shall be careful to plot the segments +% in reverse order. The |dup mul| stuff squares the RGB +% components. This does a kind-of-gamma correction, without +% which primary colours tend to take up too much space in the +% slope. This is nothing deep, it just looks better in my opinion. +% The following lines convert RGB to HSB and store the resulting +% components, as well as the |Pt| coordinate in four variables. +% \begin{macrocode} + dup mul 3 1 roll dup mul 3 1 roll dup mul 3 1 roll + setrgbcolor currenthsbcolor + /ThisB ED + /ThisS ED + /ThisH ED + /ThisPt ED +% \end{macrocode} +% To avoid gaps, we fill the whole path in that first colour. +% \begin{macrocode} + gsave fill grestore +% \end{macrocode} +% The body of the following outer loop is executed +% once for each segment. +% It expects a current colour and |Pt| coordinate in the |This*| +% variables and pops the next colour and point from the stack. It +% then draws the single steps of that segment. +% \begin{macrocode} + NumSegs { + dup mul 3 1 roll dup mul 3 1 roll dup mul 3 1 roll + setrgbcolor currenthsbcolor + /NextB ED + /NextS ED + /NextH ED + /NextPt ED +% \end{macrocode} +% |NumSteps| always contains the remaining number of steps available. +% These are evenly distributed between |Pt| coordinates |ThisPt| +% to 0, so for the current segment we may use +% $|NumSteps|*(|ThisPt|-|NextPt|)/|ThisPt|$ steps. +% \begin{macrocode} + ThisPt NextPt sub ThisPt div NumSteps mul cvi /SegSteps exch def + /NumSteps NumSteps SegSteps sub def +% \end{macrocode} +% |SegSteps| may be zero. In that case there is nothing to do for +% this segment. +% \begin{macrocode} + SegSteps 0 eq not { +% \end{macrocode} +% If one of the colours is gray, ie~0 saturation, its hue is +% useless. In this case, instead of starting of with a random hue, +% we take the hue of the other endpoint. (If both have saturation +% 0, we have a pure gray scale and no harm is done) +% \begin{macrocode} + ThisS 0 eq {/ThisH NextH def} if + NextS 0 eq {/NextH ThisH def} if +% \end{macrocode} +% To interpolate between two colours of different hue, we want to +% go the shorter way around the colour circle. The following code +% assures that this happens if we go linearly from |This*| to +% |Next*| by conditionally adding 1.0 to one of the hue values. +% The new hue values can lie between 0.0 and 2.0, so we will later +% have to subtract 1.0 from values greater than one. +% \begin{macrocode} + ThisH NextH sub 0.5 gt + {/NextH NextH 1.0 add def} + { NextH ThisH sub 0.5 ge {/ThisH ThisH 1.0 add def} if } + ifelse +% \end{macrocode} +% We define three variables to hold the current colour coordinates +% and calculate the corresponding increments per step. +% \begin{macrocode} + /B ThisB def + /S ThisS def + /H ThisH def + /BInc NextB ThisB sub SegSteps div def + /SInc NextS ThisS sub SegSteps div def + /HInc NextH ThisH sub SegSteps div def +% \end{macrocode} +% The body of the following inner loop sets the current colour, +% according to |H|, |S| and |B| and +% undoes the kind-of-gamma correction by converting to RGB colour. +% It then calls |DrawStep|, which draws one step and maybe updates +% the current point or user space, or variables of its own. Finally, +% it increments the three colour variables. +% \begin{macrocode} + SegSteps { + H dup 1. gt {1. sub} if S B sethsbcolor + currentrgbcolor + sqrt 3 1 roll sqrt 3 1 roll sqrt 3 1 roll + setrgbcolor + DrawStep + /H H HInc add def + /S S SInc add def + /B B BInc add def + } bind repeat +% \end{macrocode} +% The outer loop ends by moving on to the |Next| colour and point. +% +% \begin{macrocode} + /ThisH NextH def + /ThisS NextS def + /ThisB NextB def + /ThisPt NextPt def + } if + } bind repeat +} def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{PatchRadius} +% $-\quad\mathtt{PatchRadius}\quad-$\\ +% This macro inspects the value of the variable |Radius|. If it is +% 0, it is set to the maximum distance of any point in the +% current path from the origin of user space. This has the effect +% that the current path will be totally filled. To find the maximum +% distance, we flatten the path and call |UpdRR| for each endpoint +% of the generated polygon. The current maximum square distance is +% gathered in |RR|. +% \begin{macrocode} +/PatchRadius { + Radius 0 eq { + /UpdRR { dup mul exch dup mul add RR max /RR ED } bind def + gsave + flattenpath + /RR 0 def + {UpdRR} {UpdRR} {} {} pathforall + grestore + /Radius RR sqrt def + } if +} def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{SlopesFill} +% $p_1\quad r_1\quad g_1\quad b_1\quad\ldots\quad +% p_n\quad r_n\quad g_n\quad b_n\quad n\quad s\quad\alpha\quad +% \mathtt{SlopesFill}\quad -$\\ +% Fill the current path with a slope described by $p_1,\ldots,b_n,n$. +% Use a total of $s$ single steps. Rotate the slope by $\alpha$ +% degrees, 0 meaning $r_1,g_1,b_1$ left to $r_n,g_n,b_n$ right. +% +% After saving the current path, we do the rotation and get the +% number of steps, which is later needed by |Iterate|. Remember, +% that iterate calls |DrawStep| in the reverse order, ie~from +% right to left. We work around this by adding 180 degrees to +% the rotation. Filling +% works by clipping to the path and painting an appropriate sequence +% of rectangles. |DrawStep| is set up for |Iterate| to draw a +% rectangle of width |XInc| high enough to cover the whole +% clippath (we use the Level 2 operator |rectfill| for speed) and +% translate the user system by |XInc|. +% \begin{macrocode} +/SlopesFill { + gsave + 180 add rotate + /NumSteps ED + clip + pathbbox + /h ED /w ED + 2 copy translate + h sub neg /h ED + w sub neg /w ED + /XInc w NumSteps div def + /DrawStep { + 0 0 XInc h rectfill + XInc 0 translate + } bind def + Iterate + grestore +} def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{CcSlopesFill} $p_1\quad r_1\quad g_1\quad +% b_1\quad\ldots\quad p_n\quad r_n\quad g_n\quad b_n\quad n\quad +% c_x\quad c_y \quad r\quad \mathtt{CcSlopesFill}\quad -$\\ Fills +% the current path with a concentric pattern, +% ie~in a polar coordinate system, the colour depends on the +% radius and not on the angle. +% Centered around a point with coordinates $(c_x,c_y)$ relative to +% the bounding box of the path, ie~for a rectangle, $(0,0)$ will +% center the pattern around the lower left corner of the rectangle, +% $(0.5,0.5)$ around its center. The largest circle has a radius of +% $r$. If $r=0$, $r$ is taken to be the maximum distance of any +% point on the current path from the center defined by $(c_x,c_y)$. +% The colours are given from the center outwards, +% ie~$(r_1,g_1,b_1)$ describe the colour at the center. +% +% The code is similar to that of |SlopesFill|. The main differences +% are the call to |PatchRadius|, which catches the case that $r=0$ +% and the different definition for |DrawStep|, Which now fills a +% circle of radius |Rad| and decreases that Variable. Of course, +% drawing starts on the outside, so we work down the stack and circles +% drawn later partially cover those drawn first. Painting +% non-overlapping, `donut-shapes' would be slower. +% \begin{macrocode} +/CcSlopesFill { + gsave + /Radius ED + /CenterY ED + /CenterX ED + /NumSteps ED + clip + pathbbox + /h ED /w ED + 2 copy translate + h sub neg /h ED + w sub neg /w ED + w CenterX mul h CenterY mul translate + PatchRadius + /RadPerStep Radius NumSteps div neg def + /Rad Radius def + /DrawStep { + 0 0 Rad 0 360 arc + closepath fill + /Rad Rad RadPerStep add def + } bind def + Iterate + grestore +} def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{RadSlopesFill} +% $p_1\quad r_1\quad g_1\quad b_1\quad\ldots +% \quad p_n\quad r_n\quad g_n\quad b_n\quad n\quad +% c_x\quad c_y \quad r\quad\alpha\quad \mathtt{CcSlopesFill}\quad -$\\ +% This fills the current path with a radial pattern, ie~in a +% polar coordinate system the colour depends on the angle and not on +% the radius. All this is very similar to |CcSlopesFill|. There +% is an extra parameter $\alpha$, which rotates the pattern. +% +% The only new thing in the code is the |DrawStep| procedure. +% This does {\em not} draw a circular arc, but a triangle, which is +% considerably faster. One of the short sides of the triangle is +% determined by |Radius|, the other one by |dY|, which is calculated +% as $|dY|:=|Radius|\times\tan(|AngleIncrement|)$. +% \begin{macrocode} +/RadSlopesFill { + gsave + rotate + /Radius ED + /CenterY ED + /CenterX ED + /NumSteps ED + clip + pathbbox + /h ED /w ED + 2 copy translate + h sub neg /h ED + w sub neg /w ED + w CenterX mul h CenterY mul translate + PatchRadius + /AngleIncrement 360 NumSteps div neg def + /dY AngleIncrement sin AngleIncrement cos div Radius mul def + /DrawStep { + 0 0 moveto + Radius 0 rlineto + 0 dY rlineto + closepath fill + AngleIncrement rotate + } bind def + Iterate + grestore +} def +% \end{macrocode} +% \end{macro} +% Last, but not least, we have to close the private dictionary. +% \begin{macrocode} +end +% +% \end{macrocode} +% \Finale +% diff --git a/Master/texmf-dist/source/latex/pst-slpe/pst-slpe.ins b/Master/texmf-dist/source/latex/pst-slpe/pst-slpe.ins new file mode 100644 index 00000000000..b455b5045ba --- /dev/null +++ b/Master/texmf-dist/source/latex/pst-slpe/pst-slpe.ins @@ -0,0 +1,25 @@ +\def\batchfile{pst-slpe.ins} + +\input docstrip.tex + +\keepsilent + +\askforoverwritefalse + +\generate{\file{pst-slpe.sty}{\from{pst-slpe.dtx}{stylefile}}% + \file{pst-slpe.tex}{\from{pst-slpe.dtx}{texfile}}% + \usepostamble\empty% + \file{pst-slpe.pro}{\from{pst-slpe.dtx}{prolog}}% +} + +\Msg{************************************************************} +\Msg{ } +\Msg{ To finish the installation you have to move the files} +\Msg{ `pst-slpe.sty' and `pst-slpe.tex' into a directory} +\Msg{ searched by TeX and the file `pst-slpe.pro'} +\Msg{ to a directory searched by dvips.} +\Msg{ } +\Msg{ To type-set the documentation, including instructions,} +\Msg{ run the file `pst-slpe.dtx' through LaTeX.} +\Msg{ } +\Msg{***********************************************************} -- cgit v1.2.3