16

In the following example the double line is shifted a bit to the right:

\documentclass[12pt]{article}
\usepackage{tikz}
\begin{document}
\begin{tabular}{ll}
\tikz[baseline=-0.5ex]\draw[thick](0,0)--(3ex,0);&test\\    \tikz[baseline=-0.5ex]\draw[thick,double](0,0)--(3ex,0);&test\\ 
\end{tabular}
\end{document}

enter image description here

Looks like a bug to me, but how can I correct it?

Addition

The shift gets larger with larger double distance values.

14

Status-by-design.

When TikZ works out how much a path contributes to a picture, it does its best to ensure that the entire visible path is included in the resulting box. As the actual path is done by the renderer, it has to do some guesswork to figure out exactly how big the box should be. Moreover, it isn't always easy to compute the actual bounding box (bézier curves being a case in point). Once it has an idea of the bounding box for the actual path, that still might not be enough because the path is only the infinitesimal path and the visible path has width. Since these measurements are, by their nature, somewhat crude, PGF simply adds half the line width to each side of the bounding box to take into account this extra part.

One way to see this in action is to repeat each drawing with the additional option line cap=rect. This extends the line by half the line width at each end, but doesn't change the bounding box because the potential for this extension has already been taken into account by the sizing mechanism.

If you want to force a particular bounding box you should specify it beforehand with the \useasboundingbox command.

\documentclass[12pt]{article}
%\url{http://tex.stackexchange.com/q/130456/86}
\usepackage{tikz}
\begin{document}
\begin{tabular}{ll}
\fbox{\tikz[baseline=-0.5ex]\draw[thick](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,line cap=rect](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double](0,0)--(3ex,0);}&test\\ 
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double,line cap=rect](0,0)--(3ex,0);}&test\\ 
\fbox{\tikz[baseline=-0.5ex]\draw[thick,line width=2.2pt](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,line width=2.2pt,line cap=rect](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double](0,0)--(3ex,0);}&test\\ 
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double,line cap=rect](0,0)--(3ex,0);}&test\\ 
\end{tabular}

\end{document}

Width of tikzpictures

So while one could classify this as undesired behaviour, to get it absolutely right would take more computation than I suspect PGF wants to do and certainly more than most people want!


Update 2013-08-29 Here's a straightforward way to achieve what (I think) you want: that only coordinates are used for computing the bounding box and not line width. It uses the fact that the two parts that you want to separate are already separated in the code: the coordinates are processed as the path is built up, and as the path is built then the bounding box is continually adjusted accordingly, but the linewidth is added to the bounding box only when the path is used. So the following inserts some code in between the path being built and the path being used to turn off the computation of the bounding box. There is already a hook to insert code at the relevant point: the \tikz@addmode command, and updating the bounding box is determined by the condition \ifpgf@relevantforpicturesize.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/130456/86}
\usepackage{tikz}

\makeatletter
\tikzset{
  only coordinates are relevant/.is choice,
  only coordinates are relevant/.default=true,
  only coordinates are relevant/true/.code={%
    \tikz@addmode{\pgf@relevantforpicturesizefalse}},
  only coordinates are relevant/false/.code={%
    \tikz@addmode{\pgf@relevantforpicturesizetrue}}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\draw[line width=1cm,red,only coordinates are relevant] (0,0) rectangle (5,5);
\draw (current bounding box.south east) rectangle (current bounding box.north west);
\end{tikzpicture}
\end{document}

Screenshot:

Only coordinates relevant for picture size

It might need a little tweaking to make it work with pre- and post-actions: I haven't tested it extensively.

  • I understand the logic and I found various ways (e.g. trim left/trim right, or a suitable \useasbounding-command before \draw command and the overlay from percusse) to get around the problem, but imho it would be useful if there were a \pathdraw command which would draw but calculate the bounding box like the \path command. – Ulrike Fischer Aug 28 '13 at 12:54
  • So that makes it a feature request, not a bug. – Loop Space Aug 28 '13 at 15:12
  • I agree with your argument however I also agree with Herbert's comment tex.stackexchange.com/questions/71299/… – percusse Aug 28 '13 at 15:20
  • @percusse and Andrew: yes after I did unterstand the problem (through your answers): I was asking for a feature request (realized with the code of @Qrrbrbirlbel). I also understand that people sometimes (or almost) want that the bounding box reflects the "black ink", but for precise placement it is also often useful if line width and arrow tips etc don't count. – Ulrike Fischer Aug 28 '13 at 15:40
  • @UlrikeFischer Just add a negative space before the picture :P – percusse Aug 28 '13 at 16:00
9

It is actually the internal box padding creating the illusion, if you keep the paths but do the drawing later then the problem disappears which supports the diagnosis about internal box padding depends on the aspect ratio (what?) line width. If I make the line width of single line equal to the double then we get proper alignment.

I agree that this can be considered as a bug. Again, a temporary fix can be issuing the paths without drawing but overlaying the actual drawings on top. Both are given below.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\tikzset{every picture/.style={
           baseline=-0.5ex,
           show background rectangle,
           %execute at begin picture={},
           %execute at end picture={}
     }
 }
\begin{document}
\begin{tabular}{ll}
\tikz{\draw[line width=2.2pt](0,0)--(3ex,0);}&test\\
\tikz{\draw[thick,double](0,0)--(3ex,0);}&test\\
\tikz{\path[postaction={overlay, double,draw,thick}](0,0)--(3ex,0);}&test\\
\tikz{\path[postaction={overlay, draw, thick}](0,0)--(3ex,0);}&test 
\end{tabular}
\end{document}

enter image description here

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.