11

The built-in double line functionality in TikZ uses the exact same length for the inner line as for the outer/background line, which is reasonable enough. However, because of rounding errors or anti-aliasing or the like, the background line then tends to “seep out” at the ends during rendering. The “seepage” is minuscule, of course, but often still quite obvious, rouning the illusion of a double line. An example:

\documentclass[border=3pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}
\begin{document}
    \tikz\draw (0,0) edge[double equal sign distance,-implies] (.5,0);
\end{document}

This has the following result:

enter image description here

The leaking black line is seen on the left. (It generally shows up on both sides when rendering to my screen—which is relevant for presentations or reading documents electronically—and when using lower resolutions.)

What I'd like, is simply to extend the inner line by a tiny amount, which will remove the artifact. I can do so if I construct the double line myself, and if I can make that work well with the implies arrow and double equal sign distance, that would also be an acceptable solution, I guess. (Or anything else that fixes the leaking artifact.)

Is there any option I could use to insert a shorten <=-.1pt or the like into the style of the inner line? Given that it's such a low-level mechanism, there is perhaps no way of doing this without major hackage?

  • I remember looking at this for the knots package and ended up reimplementing the inner/outer redrawing. So I don't think that there's a simple key that will do it, but it should be possible by means of a decoration. – Andrew Stacey Nov 13 '16 at 19:20
  • shorten <=-.1pt is a good thing to try. Nonetheless it is nothing but shifting the starting point by the amount. So it will break with curves. – Symbol 1 Nov 16 '16 at 20:28
6

The inner line is drawn by the following macros, in pgfcorepathusage.code.tex.

\def\pgf@stroke@inner@line@if@needed{%
  \ifdim\pgfinnerlinewidth>0pt\relax%
    \let\pgf@temp@save=\pgf@strokecolor@global
    \pgfsys@beginscope%
    {%
      \pgfsys@setlinewidth{\pgfinnerlinewidth}%
      \pgfsetstrokecolor{\pgfinnerstrokecolor}%
      \pgfsyssoftpath@invokecurrentpath%
      \pgfsys@stroke%
    }%
    \pgfsys@endscope%
    \global\let\pgf@strokecolor@global=\pgf@temp@save
  \fi%
}

So a simple workaround is to drawn the inner line with line-cap rect or round.

\documentclass[tikz,border=3pt]{standalone}
\usetikzlibrary{arrows}

\makeatletter
\def\pgf@stroke@inner@line@if@needed{%
  \ifdim\pgfinnerlinewidth>0pt\relax%
    \let\pgf@temp@save=\pgf@strokecolor@global
    \pgfsys@beginscope%
    {%
      \pgfsetrectcap%   <-- adding this line
      \pgfsys@setlinewidth{\pgfinnerlinewidth}%
      \pgfsetstrokecolor{\pgfinnerstrokecolor}%
      \pgfsyssoftpath@invokecurrentpath%
      \pgfsys@stroke%
    }%
    \pgfsys@endscope%
    \global\let\pgf@strokecolor@global=\pgf@temp@save
  \fi%
}

\begin{document}

    \tikz\draw (0,0) edge[double equal sign distance,double=red,-implies] (.5,0);

    \tikz\draw (0,0) edge[double equal sign distance,double=red,line cap=round] (.5 ,0);

    \tikz\draw (0,0) edge[double equal sign distance,double=red,line cap=rect] (.5 ,0);

\end{document}

Notice that this will give you funny results when the outer line is drawn with specific line-cap.

To fix this, one can redefine \pgfsetbuttcap, pgfsetroundcap, and \pgfsetrectcap so that TikZ will remember the global setting of line-cap and choose the proper line-cap for the inner line.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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