17

I found a curios behavior in TikZ. If I set the line width globaly or for the current scope it wont affect the line with inside a {pgfonlayer} but the arrow tips are changed:

line width

Did I found a bug and does anyone know a solution or at least a workaround?

Code

\documentclass{minimal}

\usepackage{tikz}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\begin{document}
\begin{tikzpicture}[line width=5pt]
    \draw (0,0) -- (5,0);
    \draw [<->] (0,1) -- (5,1);
    \begin{pgfonlayer}{background}
        \draw (0,2) -- (5,2) node [right] {on BG};
        \draw [<->] (0,3) -- (5,3) node [right] {on BG};
    \end{pgfonlayer}
\end{tikzpicture}
\end{document}

Update

As Christian Feuersäger said, it could be a feature that a new layer sets a fully new picture with the default settings. But in this case all settings should be reset. And in my opinion the every picture style should be evaluated anyway.

Here’s an extended example showing the inconsequent behavior with every picture (color is taken only for nodes of background layer, line width is completely ignored and arrow tips are changed even according to the line width setting).
It shows also my workaround, since I’m using a shortcut for the {pgfonlayer} environment it was easy to add a scope which uses every picture. Unfortunately this {scope}doesn’t respect settings given directly to the {tikzpicture}. And it seems to be incompatible with Caramdir’s \makeatletter\tikz@options\makeatother workaround …

\documentclass{minimal}

\usepackage{tikz}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}
\tikzset{every picture/.style={line width=5pt,blue,>=stealth}}

\newcommand{\bglayer}[1]{%
    \begin{pgfonlayer}{background}
        \begin{scope}[every picture]
        #1
        \end{scope}
    \end{pgfonlayer}
}

\begin{document}
\begin{tikzpicture}[green]
    \draw (0,0) -- (5,0);
    \draw [<->] (0,1) -- (5,1);
    \bglayer{%
        \draw (0,2) -- (5,2) node [right] {on BG};
        \draw [<->] (0,3) -- (5,3) node [right] {on BG};
    }
\end{tikzpicture}
\end{document}

example 2


Follow up question: Restore TikZ settings after {pgfonlayer}

2
  • I come across this problem a lot. I'd be very interested to see if it's something we're doing wrong or a bug.
    – qubyte
    Commented Nov 3, 2011 at 23:45
  • Just a little comment about the arrows. This shows that arrows are set at "definition-time" in that the shape and size of the arrows are set before the line is stuck into the layer box. Whereas the line width is set at render-time. Commented Nov 5, 2011 at 18:56

2 Answers 2

7

As noted in a comment, I believe that the PGF responsible will see your request as a feature request (not a bug report). As such, it might take longer for results. But perhaps the PGF responsible will see that it is quite unexpected that options set for the complete picture are not part of the layer, he may want to implement a fix for that particular part, I do not know. Many words just to state: I would like a better solution as well. But be prepared to wait (perhaps very long).

In the meantime, it might help to understand how the given layering architecture works in order to avoid such problems.

Here is what I understand of it. It consists of the interaction between

  1. layers
  2. option changes (especially styles)
  3. graphics settings

Usually, you can change options as you want and at any time. If you change styles, the styles will be evaluated on usage (for example every node will be evaluated during \node). But options which affect the graphics state (like color, linewidth and similar ones) are different: they are applied by scopes (at least I think so) and by \paths (including \draw, of course).

Whenever you switch the layer, pgf starts to collect low level drawing instructions into a different box. All low level drawing instructions which have been collected in a different layer will NOT be copied into the new layer.

This is pretty clear. But since "low level drawing instruction" includes things like \pgfsetlinewidth as well as color assignments, such settings are not copied to the activated layer as well.

After switching to the new layer, PGF will continue its normal processing. In particular, it will continue to evaluate styles, and these styles still have the same value as they had before switching layers.

I suppose this is also not new for you. But it means that you can (and perhaps should) define (custom) styles to share options between layers. Your approach with the every picture style actually uses the approach, but it can be applied in general.

For example,

\begin{tikzpicture}
\tikzset{my style/.style={red,line width=10pt}}
\begin{scope}[my style]
...
\end{scope}

\pgfonlayer{...}
\begin{scope}[my style]
...
\end{scope}
\endpgfonlayer}
\end{tikzpicture}

will do the job. It is not as simple as one would like (or expect), I agree. But this is how it has been designed until now; everything else will have to wait (until someone implements an improved version).

In other words: your approach with the every picture is correct and perhaps the only way to do it right now.

Concerning the "reset": as explained, a layer does not introduce a completely new picture. It inherits all current styles and all current options (except for those graphics state options which have already been written to its layer). Thus, "resetting" anything is not an option.

3
  • Thanks for this explanation! “Concerning the "reset": …” Ok but I thought the size of an arrow tip is depending on the line width so if the line width is set by {pgfonlayer} the arrow tips should be set to the normal size as well, thats what I meant as an inconsequent resetting chiefly.
    – Tobi
    Commented Nov 4, 2011 at 15:45
  • @Tobi I see your point. Commented Nov 5, 2011 at 1:24
  • Hi, it seems like your solution using a {scope} doesn't work anymore (or never has). I created a new example showing the (in my eyes) odd behaviour and be glad if you could take a look: tex.stackexchange.com/q/470351/4918
    – Tobi
    Commented Jan 16, 2019 at 9:25
7

This seems to be bug in pgf: path styles like \pgfsetlinewidth seem to be forgotten when the layers are set. I have no idea why this happens. Here is a minimal example directly in pgf:

\documentclass{article}

\usepackage{pgf}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\begin{document}
\begin{pgfpicture}
    \pgfsetlinewidth{5pt}
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{5cm}{0cm}}
    \pgfusepath{draw}

    \begin{pgfonlayer}{background}
        \pgfpathmoveto{\pgfpoint{0cm}{1cm}}
        \pgfpathlineto{\pgfpoint{5cm}{1cm}}
        \pgfusepath{draw}
    \end{pgfonlayer}
\end{pgfpicture}
\end{document}

Using TikZ, you can add \makeatletter\tikz@options\makeatother after \begin{pgfonlayer}{background}. This should get you the options set in the last scope (or tikzpicture), but it won't work correctly if you have nested scopes (i.e. only the options from the innermost scope are used).

6
  • 2
    I reported the bug: sourceforge.net/tracker/…
    – Caramdir
    Commented Nov 4, 2011 at 0:06
  • Technically, the observed problem arises because each layer collects the complete graphics state on its own. I am honestly unsure of whether this is a bug or a feature request. It should work if you replicate the changes of the graphics state to each layer (for example, by replicating \begin{scope}[<options>] for each layer). Anyway, introducing a completely hierarchy graphics state inheritance (which appears to be your expectation) might be way to involved. Commented Nov 4, 2011 at 8:35
  • @ChristianFeuersänger: But if the actual behavior is a feature all settings should be reset (please see the update to my question).
    – Tobi
    Commented Nov 4, 2011 at 9:46
  • There is a slight misunderstanding: I meant it is either a bug report or a feature request. If the pgf responsible considers this to be a bug, he may want to fix it. It he considers it to be a feature request, he may reject or postpone it. I am not responsible for this feature, but I would consider it to be a feature request. Commented Nov 4, 2011 at 13:23
  • @ChristianFeuersänger: Ah ok. In my opinion it’s a bug since it is so inconsistent (as said in my update) … but either way we have to wait what happens …
    – Tobi
    Commented Nov 4, 2011 at 15:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .