1

I have a .tex document that I use to produce trough pdflatex a .pdf file, it works fine but i want to understand why to show up all the tikz images correctly i always have to call pdflatex twice. Is there a reason for this strange behaviour?

pdflatex myfile.tex .
pdflatex myfile.tex .

pdfTeX, Version 3.14159265-2.6-1.40.17

Here a code example:

\documentclass[english,12pt,a4paper]{article}
\usepackage[left=48pt,right=46pt]{geometry}
\usepackage[latin9]{inputenc}
\usepackage{imakeidx}
\usepackage{graphicx}
\usepackage{epigraph}
\usepackage{babel}
\usepackage{tikz}% loads also graphicx, xcolor
\usepackage{lmodern}
\usepackage{scrbase}
\usepackage{scrlayer}[31/10/2013]
\usepackage{hyperref}
\hypersetup{pdftex,colorlinks=true,allcolors=blue}
\usepackage{hypcap}
\newkomafont{myheadfoot}{\color{white}\bfseries\sffamily}
\newkomafont{myhead}{\Huge}
\newkomafont{mypagenumber}{\normalsize}
\newkomafont{mysepline}{\color{blue}}

\newcommand\headimageheight{2cm}
\newcommand\footimageheight{.5cm}
\newcommand\seplineheight{.2cm}
\newcommand\headtexthoffset{1cm}


\renewcommand\epigraphflush{flushright}
\renewcommand\epigraphsize{\normalsize}
\setlength\epigraphwidth{0.7\textwidth}

\renewcommand\sectionmark[1]{\markright{#1}}
\newcommand\titleinhead{}
\newcommand\mytitle[1]{\title{#1}\renewcommand\titleinhead{#1}}

\newsavebox\headimage
\sbox\headimage{%
  \tikz{
    \clip(0,0)rectangle(\paperwidth,-\headimageheight);
    \node[inner sep=0pt,outer sep=0pt,anchor=north west]{%
      \includegraphics[width=\paperwidth]{myHeaderPicture}};
  }%
  \llap{\usekomafont{mysepline}\rule[-\seplineheight]{\paperwidth}{\seplineheight}}%
}
\newsavebox\footimage
\sbox\footimage{%
  \tikz{
    \clip(0,0)rectangle(\paperwidth,\footimageheight);
    \node[inner sep=0pt,outer sep=0pt,anchor=south west]{%
      \includegraphics[width=\paperwidth]{myFooterPicture}};
  }%
  \llap{\usekomafont{mysepline}\rule[\footimageheight]{\paperwidth}{\seplineheight}}%
}

\DeclareNewLayer[
  background,
  area={0pt}{0pt}{\paperwidth}{\headimageheight},
  contents={%
    \parbox[c][\layerheight]{\layerwidth}{%
      \vspace*{\stretch{2}}
      \hspace*{\headtexthoffset}%
      \usekomafont{myheadfoot}\usekomafont{myhead}\smash{\MakeUppercase{%
        \ifodd\value{page}\titleinhead\else\rightmark\fi%
      }}%
      \vspace*{\stretch{1}}}%
    %}%
  }
]{headtext}
\DeclareNewLayer[
  clone=headtext,
  %% addheight=\seplineheight,
  contents={\usebox\headimage}
]{headimage}
\DeclareNewLayer[
  background,
  align=b,
  area={0pt}{\paperheight}{\paperwidth}{\footimageheight},
  contents={%
    \parbox[c][\layerheight][c]{\layerwidth}{\centering\usekomafont{myheadfoot}\usekomafont{mypagenumber}\thepage}%
  }
]{foottext}
\DeclareNewLayer[
  clone=foottext,
  %% addheight=\seplineheight,
  contents={\parbox{\layerwidth}{\usebox\footimage}}
]{footimage}

\DeclarePageStyleByLayers{headfootimage}{%
  headimage,headtext,%
  footimage,foottext%
}

\definecolor{titlepagecolor}{cmyk}{1,.60,0,.40}
\definecolor{namecolor}{cmyk}{1,.50,0,.10}


\newcommand\titlepagedecoration{%
\begin{tikzpicture}[remember picture,overlay,shorten >= -10pt]

\coordinate (aux1) at ([yshift=-15pt]current page.north east);
\coordinate (aux2) at ([yshift=-410pt]current page.north east);
\coordinate (aux3) at ([xshift=-4.5cm]current page.north east);
\coordinate (aux4) at ([yshift=-150pt]current page.north east);

\begin{scope}[titlepagecolor!40,line width=12pt,rounded corners=12pt]
\draw
  (aux1) -- coordinate (a)
  ++(225:5) --
  ++(-45:5.1) coordinate (b);
\draw[shorten <= -10pt]
  (aux3) --
  (a) --
  (aux1);
\draw[opacity=0.6,titlepagecolor,shorten <= -10pt]
  (b) --
  ++(225:2.2) --
  ++(-45:2.2);
\end{scope}
\draw[titlepagecolor,line width=8pt,rounded corners=8pt,shorten <= -10pt]
  (aux4) --
  ++(225:0.8) --
  ++(-45:0.8);
\begin{scope}[titlepagecolor!70,line width=6pt,rounded corners=8pt]
\draw[shorten <= -10pt]
  (aux2) --
  ++(225:3) coordinate[pos=0.45] (c) --
  ++(-45:3.1);
\draw
  (aux2) --
  (c) --
  ++(135:2.5) --
  ++(45:2.5) --
  ++(-45:2.5) coordinate[pos=0.3] (d);   
\draw 
  (d) -- +(45:1);
\end{scope}
\end{tikzpicture}%
}

\makeindex

\begin{document}

% Title Page 
\begin{titlepage}
\newgeometry{left=6.5cm} % defines the geometry for the titlepage
\pagecolor{titlepagecolor}
\noindent
\includegraphics[width=10cm]{myLogoImage}\\[-1em]
\color{white}
\makebox[0pt][l]{\rule{1.3\textwidth}{1pt}}
\par
\noindent
\textbf{\textsf{MyName}} \textcolor{namecolor}{\textsf{MyFamilyName}}
% \noindent
\titlepagedecoration
\vfill
\noindent
{\huge \textsf{My Title}}
\vskip\baselineskip
\noindent
\end{titlepage}
% Title Page End

\restoregeometry % restores the geometry
\nopagecolor% Use this to restore the color pages to white

\end{document}

enter image description here enter image description here

12
  • 4
    Do you happen to have something like remember picture,overlay in the options to the tikzpicture environments? If not, can you make a minimal example demonstrating the behaviour? Nov 22 '16 at 0:03
  • 2
    Ehm, you were saying? \begin{tikzpicture}[remember picture,overlay,shorten >= -10pt] Nov 22 '16 at 0:27
  • 2
    why is running latex twice an issue? all cross referencing tables of contents, remembering coordinates etc requires at least two runs. Nov 22 '16 at 0:29
  • 2
    as I say any real document will take two or three runs. if you use \label \ref \tableofcontents etc and similarly recording coordinates which are not known until the page is shipped out so read next time, tex does not have the whole document in memory it typically only has a page at a time, so any forward references need to use data saved the previous run. It's trivial for a makefile to run latex twice, surely? Nov 22 '16 at 0:38
  • 2
    It has to do with how the current page node is handled, read section 17.13 in the manual. Nov 22 '16 at 0:39
2

The basic blocks of TeX are hboxes and vboxes. Everything you write or draw will be put inside some hbox inside some vbox. Every box will be assigned a position only after TeX finishes line-breaking and page-breaking. And TeX will do line/page-breaking only after you finish the current picture/hbox/vbox. So there is a causal dependency, and you have to compile twice.

The argument above has an implicit assumption that the position of the current TikZ picture is important. This is usually the case because people like to write

\tikz[remember picture,overlay](0,0)--(current page.center);

So what TikZ does is to calculate the position of (current page.center) with respect to the local coordinate.

This is not the desired behavior when we want to use only the absolute coordinate. We all know that footnote and header and footer do not require double compiling. They are put at the correct position at the very first compiling.

So the answer to your question is actually
No, there is no reason.
We can do the job that the first compilation does.

For example:

\documentclass{article}
    \usepackage{tikz}
        \pgfsyspdfmark{pgfid1}{8799518}{45527859}
\begin{document}

    \newbox\mybox
    \setbox\mybox=\hbox{%
        \tikz[remember picture,overlay]{
            \draw++(current page.north east)+(-.1,-.1)--+(-1,-1)
                 node[below left]{this is the top right corenr};
        }%
    }
    \pagestyle{headings}
    \markright{\box\mybox}

    \leavevmode

\end{document}

Notice that I am still using [remember picture,overlay]. And I add a guess of the position of the picture \pgfsyspdfmark{pgfid1}{8799518}{45527859}. This represents the position of the left endpoint of the baseline of the header, and it could be calculated by hand.

In particular, 8799518 is the x-coordinate in scaled point, which is

one inch + \hoffset + .5\marginparwidth + \marginparsep.

And 45527859 is the y-coordinate in scaled point, which is

\paperheight - one inch - \voffset - \topmargin - \headheight.

See https://en.wikibooks.org/wiki/LaTeX/Page_Layout

A fancy way

This is compiler-specific.

The basic idea is that except boxes, pdfTeX provide a way to access to the absolute coordinate. In samplepdf.tex there is an example:

% pdfTeX keeps the origin point of coordinates in the lower-left corner of the
% page (native PDF space origin). \pdfliteral used without `direct' keyword
% moves this position temporarily to the point user probably expect; current
% position on the page. That is why the rectangle above appears in-line.
% Drawing anything relative to the page origin is a bit problematic. In most
% cases, one can't simply say `\pdfliteral direct {q <paiting operators> Q}'.
% That is because q..Q operators can't appear inside BT..ET blocks.
%
% Starting from pdfTeX 1.30.0, another \pdfliteral modifier can be used instead
% of `direct'. If the keyword is `page', pdfTeX closes internal text block with `ET'
% before putting the literal content; like with `direct', without translation.

\feature 1.30.0 {\cs\pdfliteral{ \tt page} keyword}
...and now look at the lower-left corner of the page.\par
\pdfliteral page {q 1 j 0 1 0 rg 0 0 1 RG 0 0 10 10 re B Q}
\pdfliteral page {q -1 0 0 1 612 0 cm .5 g}\hfill Do you like that?\pdfliteral page {Q}
\endfeature

But we the people do not speak PDF's language, only PGF/TikZ does. So we can somehow rewrite the system layer of PGF and obtain:

\documentclass{article}
\usepackage{tikz}

\begin{document}

(You have to say something in order to setup font)

(Use {\tt\string\leavevmode} for text-free graphics)

(See the next page to see what happened on this page)

\makeatletter

\def\myliteralstring{}
\def\pgfsys@invoke#1{\g@addto@macro\myliteralstring{#1}}
\def\pgftext#1{
    \pgfsys@invoke{
        q
    }
    \pgftransformshift{\pgfqpoint{\pgf@path@lastx}{\pgf@path@lasty}}\pgflowlevelsynccm
    \pgfsys@invoke{
            4 Tw BT [(#1)] TJ ET
        Q
    }
}
\def\tikz@fig ode#1;{
    \endgroup
    \pgftext{#1}
}
    \tikz[line width=1]{
        \draw[<-,red](.1,.1)--(.9,.9);
        \path(1,1)node{this is our origin};
        \draw[<-]++(8.5in,11in)+(-.1,-.1)--+(-.9,-.9);
        \path++(8.5in,11in)+(-5,-1)node{this the opposite corner};
        \draw[<-]++(8.5in/2,11in/2)circle(1);
        \pgftext{this is the center of the page}
    }

\pdfliteral page{
    q
        \myliteralstring
    Q
}

\clearpage

\myliteralstring

\end{document}

This is buggy. But it is better than nothing.

Old answer

There is actually a very primitive way to avoid double compiling. It actually avoid the usage of TikZ. I hope you like it.

\documentclass{article}
\begin{document}

\leavevmode

\pdfliteral page {
q 1 0.6 0 0.4 k 1 0.6 0 0.4 K n 0 0 597.50787 845.04684 re f Q
0 g 0 G
0 g 0 G
0 g 0 G
1 g 1 G
q
1 0 0 1 184.252 729.405 cm
[]0 d 0 J 0.996 w 0 0 m 418.252 0 l S
Q
1 0 0 1 317.796 714.461 cm
q 
1 G 
1 g 
0.3985 w 
q 
q 
0.4 0.24 0 0.16 k 0.4 0.24 0 0.16 K
11.95532 w 
277.48364 112.48627 m 
185.71669 20.71877 l 
181.0475 16.04987 181.0475 8.48029 185.71669 3.81137 c 
286.53308 -97.00525 l 
S 
q 
Q 
q 
Q 
142.25674 133.86983 m 
218.21884 70.0652 l 
223.27463 65.81834 231.1581 66.16046 235.8273 70.82938 c 
284.5284 119.53102 l 
S 
q 
/pgf@CA0.6 gs 
/pgf@ca0.6 gs 
1 0.6 0 0.4 k 1 0.6 0 0.4 K
286.53308 -82.91574 m 
243.84503 -125.60405 l 
239.17584 -130.27295 239.17584 -137.84253 243.84503 -142.51144 c 
286.53308 -185.19974 l 
S 
0.4 0.24 0 0.16 k 0.4 0.24 0 0.16 K
Q 
1 g 1 G
Q 
q 
1 0.6 0 0.4 k 1 0.6 0 0.4 K
7.97021 w 
284.5287 -14.96634 m 
267.08464 -32.41034 l 
263.97192 -35.52295 263.97192 -40.56934 267.08464 -43.68193 c 
284.5287 -61.12593 l 
S 
1 g 1 G
Q 
q 
0.7 0.42 0 0.28 k 0.7 0.42 0 0.28 K
5.97766 w 
284.5284 -273.99832 m 
222.98709 -335.54 l 
219.8743 -338.65259 219.8743 -343.69899 222.98709 -346.81158 c 
286.53278 -410.35764 l 
S 
q 
Q 
277.48364 -281.04308 m 
256.06015 -302.46681 l 
252.94743 -305.5794 247.90076 -305.5794 244.78795 -302.46681 c 
205.94989 -263.62802 l 
202.83708 -260.51541 202.83708 -255.46902 205.94989 -252.35641 c 
244.78795 -213.51764 l 
247.90076 -210.40503 252.94748 -210.40503 256.06027 -213.51764 c 
307.57925 -265.03697 l 
S 
q 
Q 
265.45738 -222.9151 m 
292.54681 -195.82611 l 
S 
1 g 1 G
Q 
Q 
n 
Q 
1 0 0 1 -317.796 -714.461 cm
}

\end{document}

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.