Open schtandard opened 5 months ago
After some more tinkering, it looks like there is more to this. The decoration's final
seems to be executed, but \pgfpointdecoratedpathlast
points to the wrong coordinate, namely to (0pt,0pt)
in the transformed coordinate system.
Additionally, the length of the input path seems to make a difference somehow, though this may be a separate bug: When it matches the decoration's width
exactly, the resulting path is extended to the correct end point (though the decoration is still wrong). While this should not make a difference once the final
transformation is fixed, it is a bit weird that the output path is apparently extended past the \pgfusepath
in the meta-decoration's definition.
Here's an MWE illustrating this. foo
steps to the side, draws a straight line parallel to the original one, and curves back to the line in the last 0.5 cm. In the meta-decoration it curves back to the end of the main
state instead. When the input path has the length 2 cm, the result is extended. When the input path is longer, this (correctly) does not happen.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\pgfdeclaredecoration{foo}{initial}
{%
\state{initial}[
width=0pt,
next state=main,
persistent precomputation={%
\pgfmathsetlengthmacro\mainlength{\pgfdecoratedpathlength - .5cm}%
},
]{
\pgfpathlineto{\pgfpoint{0pt}{10pt}}
}%
\state{main}[width=\mainlength, next state=final]
{
\pgfpathlineto{\pgfpoint{\mainlength}{10pt}}
}%
\state{final}
{
\pgfpathcurveto
{\pgfpoint{.1cm}{10pt}}
{\pgfpoint{.4cm}{10pt}}
{\pgfpointdecoratedpathlast}
}%
}
\pgfdeclaremetadecoration{too short}{first}
{%
\state{first}[width=1cm, next state=second]
{
\decoration{foo}
}%
\state{second}[width=1cm, next state=final]
{
\decoration{curveto}
\afterdecoration{
\pgfusepath{stroke}
}
}%
\state{final}{}%
}
\begin{document}
\begin{tikzpicture}
\draw [help lines] (0,-2) grid (2,1);
\draw [decorate, decoration=foo] (0,0) -- ++(1,0);
\path [decorate, decoration=too short] (0,-1) -- ++(2.1,0);
\path [decorate, decoration=too short] (0,-2) -- ++(2,0);
\end{tikzpicture}
\end{document}
Brief outline of the bug
Many decorations fill up "missing" path length (i.e. a bit of the path at the end that cannot be filled by the other states) in the
final
state, e.g. by sayingWhen used in a meta-decoration, this state seems to be omitted, leading to the meta-state not filling its specified
width
. Over the whole meta-decoration these missing parts can accumulate to a substantial length.Minimal working example (MWE)
In this example, the final bit of the first centimeter of the decorated path should be a straight line, coming from the
final
state of thezigzag
decorator. This seems to be omitted, however, thesecond
state starts (and finishes) too early. Thus, the decoration does not cover the expectedwidth
of 2 cm.