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 want to design a tikz shape that uses different background paths for different purposes.

Consider the following minimal example where a new shape named simple rectangle is declared. The background path used for filling the shape is different from the background path for other purposes, like drawing or clipping: filling does not include the region of the text below the base line.

\documentclass[tikz]{standalone}

\makeatletter

\pgfdeclareshape{simple rectangle}{
  \savedanchor{\upperrightcorner}{
    \pgf@x=.5\wd\pgfnodeparttextbox % widht of the box
    \pgf@y=.5\ht\pgfnodeparttextbox % height of the box, ignoring the depth
  }
  \saveddimen{\depth}{
    \pgf@x=\dp\pgfnodeparttextbox
  }
  \anchor{north east}{
    \upperrightcorner
  }
  \anchor{center}{
    \pgfpointorigin
  }
  \anchor{text}{
    \upperrightcorner
    \pgf@x=-\pgf@x
    \pgf@y=-\pgf@y
  }
  \backgroundpath{
    \tikz@mode
    \upperrightcorner
    \pgf@xa=-\pgf@x
    \pgf@ya=-\pgf@y
    \iftikz@mode@draw
      \advance \pgf@ya by -\depth
    \fi
    \pgfpathrectanglecorners{\upperrightcorner}{\pgfpoint{\pgf@xa}{\pgf@ya}}
  }
}

\makeatother

\begin{document}

\huge
\begin{tikzpicture}
  \node at (0,3) [simple rectangle]{This is my test.};
  \node at (0,2) [simple rectangle,fill=yellow!40]{This is my test.};
  \node at (0,1) [simple rectangle,draw]{This is my test.};
  \node at (0,0) [simple rectangle,fill=yellow!40,draw]{This is my test.};
\end{tikzpicture}

\end{document}

different paths for background

This example works only if filling is not combined with other actions, like drawing, as can be seen.

How to fix this?

share|improve this question
    
To clarify: in the last node, if you put your draw option into a postaction={draw} the draw will follow the simple rectangle border. Is this what you want to achieve? –  dcmst Nov 3 '13 at 17:08
    
Well, no surprise, you subtract \depth from \pgf@ya when you draw the path (\iftikz@mode@draw) and in both last two examples you draw the path. If you want to use different paths for drawing and filling you can use \behindbackgroundpath for the filling. (I also wouldn’t include TikZ stuff in the background path.) –  Qrrbrbirlbel Nov 3 '13 at 17:09
    
@Qrrbrbirlbel, I would like to see a not too complex example of a shape that uses \behindbackgroundpath, but I am not finding one. It seems to be rarely used. I want to use different paths for drawing and filling, but without the need of using different commands or options when using the shape in a tikzpictue. That is, the document body should remain the same. For instance, the filling colour should be one specified by the fill option. How the shape should be fixed then? I am hoping someone could show the fix, or how to fix in more details. –  Romildo Nov 3 '13 at 17:50

1 Answer 1

This is a simplification, but once you get to filling and drawing a path, the path is essentially fixed: the "shape" of the path is independent of the parameters (e.g., line width, dash pattern) or the actions applied (e.g., filling or drawing, and so on).

So creating different paths depending on whether the action is a fill or draw, isn't supported, would (I think) be a nightmare to implement in the general case, and I am not sure it would be logical to do so.

But the behind background path is pretty easy to illustrate:

\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\makeatletter

\pgfkeys{/pgf/.cd,
  simple rectangle fill/.store in=\pgf@lib@sh@simplerectangle@fill,
  simple rectangle fill=}

\pgfdeclareshape{simple rectangle}{
  \saveddimen{\width}{\pgf@x=\wd\pgfnodeparttextbox}
  \saveddimen{\height}{\pgf@x=\ht\pgfnodeparttextbox}
  \saveddimen{\depth}{\pgf@x=\dp\pgfnodeparttextbox}
  \saveddimen{\innerxsep}{\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}}
  \saveddimen{\innerysep}{\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner ysep}}}
  \anchor{center}{\pgfpoint{\width/2}{\height-\depth}}
  \backgroundpath{
    \pgfpathrectanglecorners{\pgfpoint{-\innerxsep}{-\depth-\innerysep}}%
        {\pgfpoint{\width+\innerxsep}{\height+\innerysep}}
  }
  \behindbackgroundpath{%
    % Only set the behind background path if
    % \pgf@lib@sh@simplerectangle@fill is not empty 
    \ifx\pgf@lib@sh@simplerectangle@fill\pgfutil@empty%
    \else%
        \pgfpathrectanglecorners{\pgfpoint{-\innerxsep}{0pt}}%
        {\pgfpoint{\width+\innerxsep}{\height+\innerysep}}%
        \pgfsetfillcolor{\pgf@lib@sh@simplerectangle@fill}%
        \pgfusepath{fill}%
    \fi%
  }
}

\begin{document}
\begin{tikzpicture}

\node [simple rectangle, draw] at (0,0) {Test 1};

\node [simple rectangle, draw, simple rectangle fill=red!20] at (0,-1) {Test 2};

\end{tikzpicture}
\end{document}   

enter image description here

share|improve this answer

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.