Menu

#49 Adding sampled shading

Future
pending
nobody
None
1
2013-09-30
2009-10-22
Jeremy Lea
No

Hi,

This is half a feature request, half a patch... I needed to plot some data using something like matlab's pcolor command, which makes a grid and interpolates the color map values between the points. Most plotting programs offer something like this. PDF's sampled shading appeared to be a good choice for this, so I coded it rather like functional shadings (and changed Matfig2PGF to use it). Attached is my test case, which works for my purposes. The code for postscript should be similar...

This shading would be very useful to any plotting package using PGF. Overall, I would say that it might be better to allow someone to define a function and then redo functional shadings to accept the function rather than postscript. It's also pretty easy to use manually, to get some funky effects, and you can use it as a fading.

Thanks for a great graphics package.
-Jeremy

Discussion

  • Jeremy Lea

    Jeremy Lea - 2009-10-22

    Test implementation

     
  • Mark Wibrow

    Mark Wibrow - 2009-10-24

    Hi,

    Not a lot of time to look at this in detail, but the following adapts your approach so that the colors can be specified in a roughly similar manner to other shadings, with the addtion that an RGB hex specificaion can be given:

    \documentclass{article}
    \pagestyle{empty}
    \usepackage{pgf}
    \begin{document}
    
    \makeatletter
    
    \def\pgfdeclaresampledshading#1#2#3#4#5#6{%
    \pgf@shading@conv@tohex{#6}%
    \def\pgf@marshal{\pgfsys@sampledshading{#1}{#2}{#3}{#4}{#5}}%
    \expandafter\pgf@marshal\expandafter{\pgf@shading@hex@string}%
    }
    
    \def\pgfsys@sampledshading#1#2#3#4#5#6{%
    {%
    \pgf@process{#2}%
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \pgf@process{#3}%
    \advance\pgf@x by-\pgf@xa%
    \advance\pgf@y by-\pgf@ya%
    \setbox\pgfutil@tempboxa=\hbox to\pgf@x{\vbox to\pgf@y{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
    \pgf@sys@bp@correct{\pgf@xa}%
    \pgf@sys@bp@correct{\pgf@ya}%
    \pgf@sys@bp@correct{\pgf@x}%
    \pgf@sys@bp@correct{\pgf@y}%
    % Now build the function
    \pdfobj
    stream
    attr
    {
    /FunctionType 0
    /Order 1
    /Domain [0 1 0 1]
    /Range [0 1 0 1 0 1]
    /Decode [0 1 0 1 0 1]
    /BitsPerSample 8
    /Size [#4 #5]
    }{\pdfunescapehex{#6}}%
    \edef\pgf@temp@num{\the\pdflastobj}%
    \pdfxform resources {%
    /Shading << /Sh << /ShadingType 1
    /ColorSpace /DeviceRGB
    /Domain [0 1 0 1]
    /Matrix [\pgf@sys@tonumber{\pgf@x}\space 0 0 \pgf@sys@tonumber{\pgf@y}\space \pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@ya}]
    /Function \pgf@temp@num\space 0 R
    >> >>}\pgfutil@tempboxa% <<
    \expandafter\xdef\csname @pgfshading#1!\endcsname{%
    \leavevmode%
    \noexpand\pdfrefxform\the\pdflastxform%
    \noexpand\pdfrefobj\pgf@temp@num%
    }%
    }%
    }
    
    \def\pgfutil@count@tohexdigit#1{%
    \ifcase#10\or1\or2\or3\or4\or5\or6\or7\or8\or9%
    \or A\or B\or C\or D\or E\or F\else0\fi}
    
    \def\pgfutil@dectohex#1#2{%
    \let\pgfutil@hex@string=\pgfutil@empty%
    \begingroup%
    \pgfutil@@dectohex{#1}%
    \expandafter\endgroup%
    \expandafter\def\expandafter#2\expandafter{\pgfutil@hex@string}%
    }
    
    \def\pgfutil@@dectohex#1{%
    \ifnum#1<16
    \edef\pgfutil@hex@string{\pgfutil@count@tohexdigit{#1}\pgfutil@hex@string}%
    \else%
    \c@pgf@counta=#1\relax%
    \divide\c@pgf@counta by16\relax%
    \c@pgf@countb=\c@pgf@counta%
    \multiply\c@pgf@countb by-16\relax%
    \advance\c@pgf@countb by#1\relax%
    \edef\pgfutil@hex@string{\pgfutil@count@tohexdigit{\c@pgf@countb}\pgfutil@hex@string}%
    \expandafter\pgfutil@@dectohex\expandafter{\c@pgf@counta}%
    \fi}
    
    \def\pgf@shade@gobbletil@#1@{}
    
    \def\pgf@shading@conv@tohex#1{%
    \let\pgf@shading@hex@string=\pgfutil@empty%
    \pgf@shading@@conv@tohex#1@}
    
    \def\pgf@shading@@conv@tohex{%
    \pgfutil@ifnextchar r{\pgf@shading@@conv@tohex@rgb}{%
    \pgfutil@ifnextchar h{\pgf@shading@@conv@tohex@hex}{%
    \pgfutil@ifnextchar c{\pgf@shading@@conv@tohex@color}{%
    \pgfutil@ifnextchar ;{\afterassignment\pgf@shading@@conv@tohex\let\token=}{%
    \pgfutil@ifnextchar @{\pgf@shade@gobbletil@}{%
    \PackageError{pgf}{Unknown color specification in shading}{}%
    }}}}}}
    
    \def\pgf@shading@@conv@tohex@rgb#1rgb#2=#3(#4,#5,#6){%
    \pgf@x=255pt\relax
    \c@pgf@counta=1\relax%
    \pgfutil@for\arg:={#4,#5,#6}\do{%
    \pgf@xa=\arg\pgf@x%
    \afterassignment\pgf@shade@gobbletil@%
    \c@pgf@countb=\the\pgf@xa @%
    \pgfutil@dectohex\c@pgf@countb\pgf@shading@temp%
    \ifnum\c@pgf@countb<16\relax%
    \edef\pgf@shading@temp{0\pgf@shading@temp}%
    \fi%
    \edef\pgf@shading@hex@string{\pgf@shading@hex@string\pgf@shading@temp\space}%
    }%
    \pgf@shading@@conv@tohex%
    }
    
    \def\pgf@shading@@conv@tohex@hex#1hex#2=#3(#4 #5 #6){%
    \edef\pgf@shading@hex@string{\pgf@shading@hex@string#4\space#5\space#6\space}%
    \pgf@shading@@conv@tohex}
    
    \def\pgf@shading@@conv@tohex@color#1color#2=#3(#4){%
    \pgfutil@colorlet{pgf@tempcol}{#4}%
    \pgfutil@extractcolorspec{pgf@tempcol}{\pgf@tempcolor}%
    \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
    \def\pgf@marshal{\pgf@shading@@conv@tohex@rgb rgb=}%
    \expandafter\pgf@marshal\expandafter(\pgf@rgbcolor)%
    }
    
    \makeatother
    
    \begin{figure}
    \centering
    \begin{pgfpicture}
    \pgfdeclaresampledshading{lsd}
    {\pgfpointorigin}{\pgfpoint{4cm}{4cm}}{2}{2}
    {
    color=(red!70!black); hex=(00 FF 00);
    rgb=(0,0.5,0.9); color=(yellow)
    }
    \begin{pgfscope}
    \pgfpathrectangle{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{4cm}{4cm}}
    \pgfusepath{discard}
    
    \pgftransformshift{\pgfqpoint{2cm}{2cm}}
    \pgflowlevelsynccm\pgfuseshading{lsd}
    \end{pgfscope}
    \pgfpathcircle{\pgfpointorigin}{1pt}
    \pgfusepath{fill}
    \end{pgfpicture}
    \end{figure}
    
    \end{document}
    

    Regards
    Mark

     

    Last edit: Stefan Pinnow 2018-12-31
  • Till Tantau

    Till Tantau - 2013-09-30
    • status: open --> pending
    • Group: --> Future
    • Priority: 5 --> 1