I am trying to position elements absolutely on a page. These positioned elements use the put{}
command itself. The coordinate origin should always be in the top left corner on every page, also when changing the page layout (by using \newgeometry{}
).
To achieve this I want to use the second parameter set of the picture
environment. This should translate my coordinate system to the top left corner of the paper.
The position of the picture
environment is defined by the position of the header and/or the page layout. So the second set of parameters should depend on any or multiple of the page margins. When the page changes the margins will change and my origin will stay the same.
So in other words: I am trying to calculate back the position of the header/picture
-environment. When I know how this position is calculated relative to the top left corner I can calculate back the position from inside the header to the top left paper corner.
For setting the elements I tried to use the fancyhdr
package together with geometry
and including a picture
environment. But I could not figure out how the position of the picture
is being calculated. Something like this (whole code and result shown below):
\fancyhead[L]{
\begin{minipage}{\textwidth}
\headertext \\
\begin{picture}(0,0)(\geometryleft,-\geometrytop)
\put(0, 0){\fbox{fancyhdr}}
\end{picture}
\end{minipage}
}
But when I change the page layout by using \newgeometry
the element changes its position. The \geometryleft
works. After reading the geometry
documentation I modified the \geometrytop
but I was not able to find the correct calculation. According to the docs I was expecting that the correct term is
\top - \headsep - \layoutvoffset.
But this is not correct. (For a better clearness I only wrote \geometrytop
here.)
Also I tried to use the everypage
package because I have to include it anyway. It seems like the everypage
version positions the elements indipendently of the geometry
package but still I could not figure out how to calculate the correct 0/0
-point to set it in the top left corner. The short code looks something like this (whole code and result shown below):
\AddEverypageHook{
\begin{picture}(0,0)(\hoffset+1in,-\voffset-1in)
\put(0, 0){fbox{everypage}}
\end{picture}
}
Because the layout changing of the geometry
package are completely ignored I was expecting that the everypage
version uses the (La-?)TeX defaults. I found them to be \hoffset + 1 in
for the left margin and \voffset + 1 in
for the top offset. As in the fancyhdr
version the left offset works, the right one is wrong.
Now my question is: How do I get the correct distances from the top and left of the paper to the picture
-environment position? Which version I use does not matter. If you know another possibility (without including an additional pacakge if possible) I would also appreciate it.
Note that I want to avoid using tikz
. Also I am not placing simple boxes but I am "calling" definded commands. Those commands contain the put{}
command itself. It is very important for them that the coordinate origin will always be the same.
A working minimal example can be found below the image. The results of both versions are shown in the image below. There are boxes (in the top left corner). Both of them should exactly be in the corner on every page, no matter how the layout is changed.
The full code is:
\documentclass[a4paper]{article}
\newlength{\geometryleft}
\setlength{\geometryleft}{2cm}
\newlength{\geometryright}
\setlength{\geometryright}{2cm}
\newlength{\geometrytop}
\setlength{\geometrytop}{5.5cm}
\newlength{\geometrybottom}
\setlength{\geometrybottom}{1cm}
\newlength{\geometryheadheight}
\setlength{\geometryheadheight}{5.5cm}
\usepackage[
showframe,
left=\geometryleft,
right=\geometryright,
top=\geometrytop,
bottom=\geometrybottom,
headheight=\geometryheadheight
]{geometry}
\usepackage{fancyhdr}
\usepackage{picture}
\usepackage{calc}
\usepackage{color}
\usepackage{everypage}
\newcommand{\headertext}{Text of the first header}
\fancypagestyle{fancyhdr}{
\renewcommand{\headrule}{%
\hbox to\textwidth{%
\color{black}\leaders\hrule height .4pt\hfill%
}%
}
\renewcommand{\footrule}{%
\hbox to\textwidth{%
\color{black}\leaders\hrule height .4pt\hfill%
}%
}
\fancyhead[L]{%
\begin{minipage}{\textwidth}
\headertext \\
\begin{picture}(0,0)(\geometryleft,-\geometrytop+3cm)
\fbox{fancyhdr}
\end{picture}
\end{minipage}
}
}
\pagestyle{fancyhdr}
\AddEverypageHook{
\begin{picture}(0,0)(\hoffset+1in,-\voffset-1in)
\fbox{everypage}
\end{picture}
}
\begin{document}
Text
\clearpage
\renewcommand{\headertext}{
A lot longer header text \\
with \\
multiple \\
lines \\
so \\
it \\
is \\
higher
}
Text
\clearpage
\setlength{\geometryheadheight}{2cm}
\newgeometry{
headheight=\geometryheadheight,
top=\geometrytop,
left=\geometryleft,
right=\geometryright
}
Text
\clearpage
\setlength{\geometryleft}{5cm}
\setlength{\geometryright}{.5cm}
\setlength{\geometrytop}{.5cm}
\newgeometry{
headheight=\geometryheadheight,
top=\geometrytop,
left=\geometryleft
,right=\geometryright
}
Text
\end{document}
Why @David Carlisle answer is not working
The code below shows why the code of @David Carlisle is not working. My problem is, that the page dimension is changing in the document but my commands (\fancycommand
) do not know how they are changing. The following code shows his code in my minimal example:
\documentclass[a4paper]{article}
\newlength{\geometryleft}
\setlength{\geometryleft}{2cm}
\newlength{\geometryright}
\setlength{\geometryright}{2cm}
\newlength{\geometrytop}
\setlength{\geometrytop}{5.5cm}
\newlength{\geometrybottom}
\setlength{\geometrybottom}{1cm}
\newlength{\geometryheadheight}
\setlength{\geometryheadheight}{5.5cm}
\usepackage[
showframe,
left=\geometryleft,
right=\geometryright,
top=\geometrytop,
bottom=\geometrybottom,
headheight=\geometryheadheight
]{geometry}
\usepackage{fancyhdr}
\usepackage{picture}
\usepackage{calc}
\usepackage{color}
\usepackage{everypage}
\newcommand{\headertext}{Text of the first header}
\fancypagestyle{fancyhdr}{
\fancyhead[L]{%
\begin{picture}(0,0)
\put(-57,117){\fancycommand}
% this is only included to show that the fancytext is
% still displayed and that the position changes
\put(0,0){\fancycommand}
\end{picture}%
\headertext
}
}
\newcommand{\fancycommand}{\put(10, -10){\color{red}Fancy text}}
\pagestyle{fancyhdr}
\begin{document}
Text
\clearpage
\renewcommand{\headertext}{
A lot longer header text \\
with \\
multiple \\
lines \\
so \\
it \\
is \\
higher
}
Text
\clearpage
\setlength{\geometryheadheight}{2cm}
\newgeometry{
headheight=\geometryheadheight,
top=\geometrytop,
left=\geometryleft,
right=\geometryright
}
Text
\clearpage
\setlength{\geometryleft}{5cm}
\setlength{\geometryright}{.5cm}
\setlength{\geometrytop}{.5cm}
\newgeometry{
headheight=\geometryheadheight,
top=\geometrytop,
left=\geometryleft
,right=\geometryright
}
Text
\end{document}
In the result you can see that on page one (left) the red "Fancy text" is displayed perfectly on the top left corner of the page. On the second page this is not the case anymore. This is because the layout changed. The problem is, that the position in the fancyhdr
put{}
is hard coded here. This has to be dependent on the page layout. Exactly this is my question: How the position (no matter if the first put
or the origin of the picture
environment) depends on the page margins.
The \fancycommand
should only set its coordinate relative to the complete page. It should not be necessary to check the page dimensions. So the \fancycommand
uses the full page as a coordinate system. I hope this helps to clarify my question.
eso-pic
's\AtPageUpperLeft
. It's not clear to me what you want though.