2

I am trying to position elements absolutely on a page. These positioned elmenets 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.

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.

enter image description here

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}

enter image description here

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.

  • 3
    note it is better to make the examples inline here complete rather than link to an external site, unless you can guarantee that the example will be there forever as this question and answers are archived forever. – David Carlisle Jun 19 '18 at 14:36
  • Thank your for pointing this out. I never thought about this. I moved the code to the question and removed the link – miile7 Jun 19 '18 at 14:49
  • @miile7: You can position elements absolutely using eso-pic's \AtPageUpperLeft. It's not clear to me what you want though. – Werner Jun 19 '18 at 15:35
  • @Werner thank you. I will check this out even though I want to avoid additional packages. My goal is that the fancyhdr or the everypage box in the images are at the same position on each of the pages in my example. – miile7 Jun 19 '18 at 15:41
  • your heading is only misplaced because it is badly specified, fancyheader does warn you Package Fancyhdr Warning: \headheight is too small (56.9055pt): Make it at least 94.54448pt. We now make it that large for the rest of the document. This may cause the page layout to be inconsistent, however. – David Carlisle Jun 19 '18 at 15:52
3

It's much easier using eso-pic's \AtPageUpperLeft to place content at the upper-left of the page:

\usepackage{eso-pic}
\AddToShipoutPictureFG{
  \AtPageUpperLeft{%
    \raisebox{-\height}{%
      \fbox{everypage}%
    }%
  }%
}

Since content is usually placed on the baseline, \raisebox{-\height}{<stuff>} ensures that the top of <stuff> will be at the top of the page inside \AtPageUpperLeft.

enter image description here

  • This works very well. I wanted to avoid adding additional packages because I have to keep the compilation time as short as possible. After a quick benchmark I found out that there is no difference. (The eso-pic version was even faster but the time difference is in the range of errors, so in reality there is no difference I think.) – miile7 Jun 20 '18 at 7:11
3

beware adding spaces and also picture mode content should always be in \put so

\fancyhead[L]{%
        \begin{picture}(0,0)
            \put(10,-200){\fbox{fancyhdr}}
        \end{picture}%
    \headertext
}

would put the \fbox{fanchdr} at 10,-200 relative to the left edge of the page header, you can adjust the coordinates to place it anywhere on the page.

  • Thank you for your answer. This shows me that my question was not clear. I am looking for a way to set the coordinate origin (the 0/0-point) to the top corner of the paper. The \fbox{} was only added for the demo. I am "calling" a lot of commands which use the \put command. This is why I did not add the \put command. – miile7 Jun 19 '18 at 14:51
  • @miile7 so that's what this answer does, the zero sized picture is at the top left of the page and you can add as many \put as you need at whatever coordinates you need. – David Carlisle Jun 19 '18 at 15:15
  • I am sorry to tell you that it is not working for me. Or I got your idea wrong. I updated my question because it is too long for a comment. I hope I understood what you wanted to tell me and my problem is more clear after reading my update. – miile7 Jun 19 '18 at 15:39
  • @miile7 your setup is very weird:-) the whole point of page head and foot is that they are at a fixed position, and somehow you have broken that, also why all the \setlength with e-tex it doesn't really matter as there are plenty of lengths but in classical latex (ie pre 2015) you'd have been in danger of running out of length register allocation:-) I'll run your example and see if I can debug. – David Carlisle Jun 19 '18 at 15:46
  • You are right, my setup is weird :) Thank you for pointing out the "filling the length register". I haven't thought about this yet. My header and footer are at a fixed position. But not when I change the position. This happens in my document because the header is changing. In addition I don't know how the header is changing. This makes it very complicated (for me). – miile7 Jun 20 '18 at 7:04

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.