Placement issue with eso-pic / AddToShipoutPicture

eso-pic

I'm trying to add some ornaments to every page using pgfornament, in the way it's described in that package's documentation. I ran into some problems there which — I think — relate to eso-pic and \AddToShipoutPicture; some things being \put on the page don't show up where they should. Here's a fairly minimal example:

\documentclass{article}
\usepackage[a6paper]{geometry}
\usepackage{eso-pic}
\usepackage{calc}
\usepackage{lipsum}
\makeatletter
\AddToShipoutPicture{%
\begingroup
\setlength{\@tempdima}{2mm}%
\setlength{\@tempdimb}{\paperwidth-\@tempdima-2cm}%
\setlength{\@tempdimc}{\paperheight-\@tempdima}%
\put(\LenToUnit{\@tempdima},\LenToUnit{\@tempdimc}){OK} % upper left
\put(\LenToUnit{\@tempdima},\LenToUnit{\@tempdima}){OK} % lower left
\put(\LenToUnit{\@tempdimb},\LenToUnit{\@tempdimc}){wrong} % upper right
\put(\LenToUnit{\@tempdimb},\LenToUnit{\@tempdima}){OK} % lower right
\endgroup
}
\makeatother
\begin{document}
\lipsum[1]
\end{document}

This produces the following:

enter image description here

So as you can see, one of the added labels is in the wrong spot, and I have absolutely no idea why. The same thing also happens with e.g. the code from Gonzalo's answer to this question (which apparently worked for him when he posted it).

Would appreciate any help, I'm not even sure how to begin debugging this. eso-pic is current, there's nothing unusual in the log file.

Best Answer

It is never safe to assume scratch registers such as \@tempdimc are "safe" to use across non local scopes. It may work but (in newer latex implementations) it may get used for some other purpose so not have the value you set.

If you allocate a register then it works

\documentclass{article}
\usepackage[a6paper]{geometry}
\usepackage{eso-pic}
\usepackage{calc}
\newlength\zzz
\usepackage{lipsum}
\makeatletter
\AddToShipoutPicture{%
\begingroup
\setlength{\@tempdima}{2mm}%
\setlength{\@tempdimb}{\paperwidth-\@tempdima-2cm}%
\setlength{\zzz}{\paperheight-\@tempdima}%
\put(\LenToUnit{\@tempdima},\LenToUnit{\zzz}){OK} % upper left
\put(\LenToUnit{\@tempdima},\LenToUnit{\@tempdima}){OK} % lower left
\put(\LenToUnit{\@tempdimb},\LenToUnit{\zzz}){wrong} % upper right
\put(\LenToUnit{\@tempdimb},\LenToUnit{\@tempdima}){OK} % lower right
\endgroup
}
\makeatother
\begin{document}
\lipsum[1]
\end{document}

Note the change that introduced internal \@tempdimc usage was to allow lengths to be used, so you do not need \LenToUnit

\documentclass{article}
\usepackage[a6paper]{geometry}
\usepackage{eso-pic}
\usepackage{calc}
\newlength\zzz
\usepackage{lipsum}
\makeatletter
\AddToShipoutPicture{%
\begingroup
\setlength{\@tempdima}{2mm}%
\setlength{\@tempdimb}{\paperwidth-\@tempdima-2cm}%
\setlength{\zzz}{\paperheight-\@tempdima}%
\put(\@tempdima,\zzz){OK} % upper left
\put(\@tempdima,\@tempdima){OK} % lower left
\put(\@tempdimb,\zzz){wrong} % upper right
\put(\@tempdimb,\@tempdima){OK} % lower right
\endgroup
}
\makeatother
\begin{document}
\lipsum[1]
\end{document}

Although you do not need any register assignments (or calc package) here at all as you can use dimension expressions in all picture mode contexts.

\documentclass{article}
\usepackage[a6paper]{geometry}
\usepackage{eso-pic}
\usepackage{lipsum}

\AddToShipoutPicture{%
\put(2mm,\paperheight-2mm){OK} % upper left
\put(2mm,2mm){OK} % lower left
\put(\paperwidth-2mm-2cm,\paperheight-2mm){wrong} % upper right
\put(\paperwidth-2mm-2cm,2mm){OK} % lower right
}
\begin{document}
\lipsum[1]
\end{document}
Related Question