Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I know how to use TikZ even and odd rule, but what I need is to apply it on a node text. Compare

even odd no text

I need the text to be punched out such that when I use the resulting pdf on top of a background, the background will be visible where the glyphs are located.

\documentclass{standalone}
\usepackage{palatino}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
  \path[use as bounding box] (-.1,-.1) rectangle (2.4,1.1);
  \filldraw[fill=blue,even odd rule]
  (0,0) rectangle (1,1) (0.5,0.5) circle (0.4cm);
  \begin{scope}[xshift=1.3cm]
    \filldraw[fill=blue,even odd rule]
    % the node text is black (I guess foreground colour)
    (0,0) rectangle (1,1) (0.5,0.5) node  {as};
  \end{scope}
\end{tikzpicture}
\end{document}

I also tried node[text opacity=0], but this makes the glyphs vanish.

I guess I can export the text to svg, and the use tikz2svg to have it available as path, but this is quite inconvenient.

share|improve this question
1  
Perhaps I'm wrong, but I think this cannot be done with tikz because it has no access to the character outlines. This answer can be relevant here. –  JLDiaz Jul 4 at 11:31
    
I have played around with something similar, but I hoped there was an easier way. –  Sebastian Jul 4 at 11:38
1  
Asymptote is the tool for such things. –  percusse Jul 4 at 11:41
    
If you don't have to draw the borders around the letters, fading seems to be a solution. –  krnk Jul 4 at 13:02

2 Answers 2

up vote 18 down vote accepted

I guess this is "proof-of-concept" rather than any kind of practical solution (it certainly isn't practical). It does some rather naughty stuff with low level PDF literals:

\documentclass[border=5]{standalone}
\usepackage{tikz}
\usetikzlibrary{fadings}

\tikzset{
  outline text/.style={
    execute at begin node={%
      \pgfsetfillopacity{0}%
      \pgfsetlinewidth{\pgflinewidth}%
      \pgfsetstrokecolor{#1}%
      \special{pdf:literal 1 Tr }%    
    }
  }
}

\begin{tikzfadingfrompicture}[name=Aa] 
\node [text=transparent!100, font=\Large\bfseries, 
  minimum size=1cm, fill=transparent!0] {Aa};
\end{tikzfadingfrompicture}

\begin{document}
\begin{tikzpicture}
\path [left color=yellow, right color=red, middle color=purple, 
  shading angle=45] circle [radius=2cm/3];

\node [fill=blue!20,fit fading=false, draw, minimum size=1cm,
  path fading=Aa, font=\Large\bfseries, outline text=black] {Aa};

\end{tikzpicture}    
\end{document}

enter image description here

And here's an sort of automatic version, which (perhaps unsurprisingly) requires some low level hacking.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{fadings}
\makeatletter

\tikzset{
  outline text/.style={
    execute at begin node={%
      \pgfsetfillopacity{0}%
      \pgfsetlinewidth{\pgflinewidth}%
      \pgfsetstrokecolor{#1}%
      \special{pdf:literal 1 Tr }%      
    },
  },
  knockout text fading/.code={%
    \tikz@addmode{%
      % Interrupt the picture to create a fading.
      \pgfinterruptpicture%
        \let\tikz@atbegin@node=\relax%
        \begin{tikzfadingfrompicture}[name=.]
          \node [node contents=, #1,text=transparent!100, fill=transparent!0];%
          \xdef\fadingboundingbox{{\noexpand\pgfpoint{\the\pgf@picminx}{\the\pgf@picminy}}%
            {\noexpand\pgfpoint{\the\pgf@picmaxx}{\the\pgf@picmaxy}}}%
          \expandafter\pgfpathrectanglecorners\fadingboundingbox%
          \pgfusepath{discard}%
         \end{tikzfadingfrompicture}%
       \endpgfinterruptpicture%
       % Make the fading happen.
       \def\tikz@path@fading{.}%
       \tikz@mode@fade@pathtrue%
       \tikz@fade@adjustfalse%
       \pgfpointscale{0.5}{\expandafter\pgfpointadd\fadingboundingbox}%
       \def\tikz@fade@transform{shift={(\the\pgf@x,\the\pgf@y)}}%
    }%
    \tikzset{#1}% 
  }
} 
\makeatother

\begin{document}
\begin{tikzpicture}[line join=round] 
\path [left color=yellow, right color=red, middle color=purple, 
  shading angle=45] circle [radius=2cm];

\node [outline text=black,
   knockout text fading={
     rotate=-45,
     fill=blue!20, draw, text width=4.5cm, align=center,
     font=\sffamily\Large\bfseries, 
     node contents={The quick brown fox jumps over the lazy dog}
   }];

\end{tikzpicture}    
\end{document}

enter image description here

share|improve this answer

I have found examples in the TikZ & PGF manual that may help you. I have edited the two examples I found. The first picture is based on an example in section 23.4.1 Creating Fadings, the other two is based on an example in section 23.5 Transparency Groups in the TikZ & PGF manual.

        

Unfortunately, the text in the second and third example only was displayed in Adobe Reader (it didn't work with TeXworks and Evince).

You can download the background image I used in the third example here.

\documentclass[10pt]{article}

\usepackage{tikz}

\usetikzlibrary{fadings, patterns}

\newcommand{\normalfontsize}{\fontsize{10pt}{12pt}\selectfont}
\newcommand{\largefontsize}{\fontsize{1.5cm}{1.5cm}\selectfont}

\begin{document}

\normalfontsize

Example \#1

\largefontsize

\begin{tikzfadingfrompicture}[name=mypath]
\node [text=transparent!20, font=\bfseries] {Aa};
\end{tikzfadingfrompicture}

\begin{tikzpicture}
    \fill [black!20] (-1, -1) rectangle (1, 1);
    \pattern [pattern=checkerboard,%
        pattern color=black!30] (-1, -1) rectangle (1, 1);
    \shade[path fading=mypath,%
        fit fading=false,%
        left color=lime,%
        right color=orange] (-1, -1) rectangle (1, 1);
\end{tikzpicture}

\normalfontsize

Example \#2

\largefontsize

\begin{tikzpicture}
    \shade [left color=lime, right color=orange] (-1, -1) rectangle (1, 1);

    \begin{scope}[transparency group=knockout]
        \filldraw[lightgray] (-1, -1) rectangle (1, 1);
        \node[opacity=0, font=\bfseries] {Aa};
    \end{scope}
\end{tikzpicture}

\normalfontsize

Example \#3

\largefontsize

\begin{tikzpicture}
    \node[inner sep=0pt, outer sep=0pt] (background) at (0, 0)%
    {\includegraphics[width=2cm, height=2cm]{bg.png}};

    \begin{scope}[transparency group=knockout]
        \filldraw[lightgray] (-1, -1) rectangle (1, 1);
        \node[opacity=0, font=\bfseries] {Aa};
    \end{scope}
\end{tikzpicture}

\end{document}
share|improve this answer
    
Nice one, but it's the complement of that needs to be filled/faded. So it won't work with fadings from picture. –  percusse Jul 4 at 14:23
    
interesting, thanks for teaching me about fadingsfrompicture (didn't know about it). I also tried mupdf/zathura (my favourite pdf viewers). The second and third examples are only gray. –  Sebastian Jul 4 at 14:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.