[Tex/LaTex] tikz: Better raised text effect

tikz-pgftikz-styles

If you look carefully at the raised text in this image, you can see that it has two drop shadows: as well as the black one to the southeast of the text, there is a white one to the northwest. I know how to insert one drop shadow in tikz using e.g.

drop shadow={shadow xshift=-0.5mm,shadow yshift=-0.5mm,black}

Is there any easy way to add two shadows of the kind specified? (NB. Being able to specify the 'light direction' via shadow xshift,shadow yshift is very useful.)

enter image description here

Best Answer

Duplicate shadows

With key preaction another shadow can be inserted, e.g.:

\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{shadows}

\begin{document}
\begin{tikzpicture}
  \fill[lightgray] (0,0) rectangle (2,2);
  \node[
    fill=darkgray,
    preaction={
      drop shadow={
        fill=white,
        opacity=1,
        shadow xshift=-.5mm,
        shadow yshift=.5mm,
      },
    },  
    drop shadow={
      fill=black,
      opacity=1,
      shadow xshift=.5mm,
      shadow yshift=-.5mm
    },
  ] at (1,1) {\rule{8mm}{0mm}\rule{0mm}{8mm}};
\end{tikzpicture}
\end{document}

Two shadows

This can be further simplified. drop shadow uses general shadow, which is already implemented via preaction. Thus the preaction part can be dropped:

  \node[
    fill=darkgray,
    drop shadow={ 
      fill=white, 
      opacity=1,  
      shadow xshift=-.5mm,
      shadow yshift=.5mm, 
    },
    drop shadow={
      fill=black,
      opacity=1, 
      shadow xshift=.5mm,
      shadow yshift=-.5mm
    },
  ] at (1,1) {\rule{8mm}{0mm}\rule{0mm}{8mm}};

Also a style can be defined to simplify the use case, e.g.:

\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{shadows}

\pgfkeysdefnargs{/my/get value}{2}{%
  \pgfkeysgetvalue{#1}{#2}%
}
\tikzset{
  /tikz/drop raised shadow/.style={
    drop shadow={%
      fill=white,
      opacity=1,
      #1,%
      /my/get value={/tikz/shadow xshift}{\xshift},
      /my/get value={/tikz/shadow yshift}{\yshift},
      shadow xshift=-\xshift,
      shadow yshift=-\yshift,
    },
    drop shadow={%
      fill=black,
      opacity=1,
      #1%
    }
  }  
}

\begin{document}
\begin{tikzpicture}
  \fill[lightgray] (0,0) rectangle (2,2);
  \node[
    fill=darkgray,
    drop shadow={
      fill=white,
      opacity=1,
      shadow xshift=-.5mm,
      shadow yshift=.5mm,
    },
    drop shadow={
      fill=black,
      opacity=1,
      shadow xshift=.5mm,
      shadow yshift=-.5mm
    },
  ] at (1,1) {\rule{8mm}{0mm}\rule{0mm}{8mm}};
\end{tikzpicture}
\quad 
\begin{tikzpicture}
  \fill[lightgray] (0,0) rectangle (2,2);
  \node[
    fill=darkgray,
    drop raised shadow={
      shadow xshift=.5mm,
      shadow yshift=-.5mm,
    },
  ] at (1,1) {\rule{8mm}{0mm}\rule{0mm}{8mm}};
\end{tikzpicture}

\end{document}

Result

Text shadows

The following version without package tikz sets the text three times, first in color white, moved to the left and raised, then in color black to the right and below, finally the the text:

\documentclass{article}
\usepackage{xcolor}

\newcommand*{\RaisedText}[1]{%
  \begingroup
    \leavevmode
    \rlap{\kern-.1pt\raise.1pt\hbox{\color{white}#1}}%
    \rlap{\kern.1pt\raise-.1pt\hbox{\color{black}#1}}%
    \hbox{#1}%
  \endgroup
}

\begin{document}
\colorbox{lightgray}{%
  \color{darkgray}\RaisedText{Raised Text}%
}
\end{document}

Result

A variant with package pdfrender:

\documentclass{article}
\usepackage{xcolor}
\usepackage{pdfrender}

\newcommand*{\RaisedText}[1]{%
  \begingroup
    \leavevmode
    \rlap{\kern-.1pt\raise.1pt\hbox{%
      \pdfrender{
        TextRenderingMode=Stroke,
        LineWidth=.2pt,
        StrokeColor=white,
      }#1%
    }}%
    \rlap{\kern.1pt\raise-.1pt\hbox{%
      \pdfrender{
        TextRenderingMode=Stroke,
        LineWidth=.2pt,
        StrokeColor=black,
      }#1%
    }}%
    \rlap{%
      \pdfrender{
        TextRenderingMode=Stroke,
        LineWidth=.2pt,
      }#1%
    }%
    \hbox{#1}%
  \endgroup
}

\begin{document}
\colorbox{lightgray}{%
  \color{darkgray}\RaisedText{Raised Text}%
}
\end{document}

Result pdfrender