[Tex/LaTex] Fancyhdr headrulewidth-related question

fancyhdrheader-footerspacing

I have a work-around for this one, but I'd like to do it more elegantly if possible.

Suppression of the line under the header when using fancyhdr seems to be well understood, and I have been doing it for a while. But, now I have noticed something a bit odd. When including (using \chead and \includegraphics) a PDF file which (according to the document properties in Acrobat) is 27mm high, the \headheight seems to be too small, even though I set it at 27mm. The console output says the \headheight of 80.90546pt (which is about 28.435mm) is too small, and it has been adjusted to 80.91379pt (which is about 28.438mm). Those two measurements are only about 3 microns apart, but leaving the header out causes a noticeable difference in the placement of text on the second page – I think the important difference is between 28.438mm and the original 27mm.

When I set the \headrulewidth to be greater than zero, there is a clearly visible space between the line and the PDF header, so I think there must be some additional spacing placed there. I am not sure whether this is put there by fancyhdr (I can't find anything in the documentation, and I tried to look at the .sty file itself, but I'm afraid I'm not at the level where I can interpret it well enough), or by normal LaTeX inter-line or inter-paragraph spacing (baseline stretch and parskip seemed to have no effect).

My simple work-around was just to set \headheight to the specified amount, and subtract the same amount from \headsep. However, this is not very elegant, and I wonder whether changing other parameters might break this solution. So I am wondering, how does this extra space between the header contents and the \hrule get set, and is there a way to suppress it?

My class file is below, stripped of irrelevant commands/features. In a two-page document (nothing more than \documentclass{sample}, \begin{document}, \end{document} and some contents are needed in the .tex file), the appearance of the second page changes when the original measurements are used and the suppressHeaders option is added; when the new measurements are used, it doesn't.

(In case anyone is wondering about the odd handling of the side margins/spacing, the PDF file in the header is 210mm wide, covering the entire width of an A4 sheet. However, using a less wide PDF file doesn't seem to change anything.)

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{sample}[2016/01/17 v2.0]

\RequirePackage{graphicx}
\RequirePackage{ifthen}
\RequirePackage{fancyhdr}

\newboolean{suppressHeaders}
\DeclareOption{suppressHeaders}{\setboolean{suppressHeaders}{true}}
\ProcessOptions
\LoadClass[a4paper,11pt]{article}

% Set up vertical spacing parameters
\setlength{\voffset}            {-25.4mm}
\setlength{\topmargin}          {0mm}
% Original settings on next two lines
\setlength{\headheight}         {27mm}  
\setlength{\headsep}            {8mm}
% Modified settings to avoid problem on next two lines
%\setlength{\headheight}        {28.4380mm}
%\setlength{\headsep}           {6.5620mm}
\setlength{\footskip}           {15mm}
\setlength{\textheight}         {222mm}

% Set up horizontal spacing parameters
\setlength{\hoffset}            {-25.4mm}
\setlength{\oddsidemargin}      {0mm}
\setlength{\evensidemargin}     {0mm}
\setlength{\textwidth}          {210mm}
\setlength{\leftskip}           {25mm}
\setlength{\rightskip}          {20mm}

% Set up paragraph formatting parameters
\setlength{\parskip}            {4mm}
\setlength{\parindent}          {0mm}

\fancypagestyle{sampleFirstPage}{\renewcommand{\headrulewidth}{0pt}\ifthenelse{\boolean{suppressHeaders}}{}{\chead{\includegraphics{sampleFirstPageHeader}}\lfoot{\includegraphics{SampleFirstPageFooter}}}\cfoot{}}
\fancypagestyle{sampleContinuationPage}{\renewcommand{\headrulewidth}{0pt}\ifthenelse{\boolean{suppressHeaders}}{}{\chead{\includegraphics{sampleSecondPageHeader}}}\cfoot{}}

\thispagestyle{sampleFirstPage}
\pagestyle{sampleContinuationPage}

Best Answer

If your \headheight is not properly set, fancyhdr will set it for you. It will only be set after the page where it detects it to be too small as is reported in the .log:

Package Fancyhdr Warning: \headheight is too small (XX.XXXXXpt): 
 Make it at least YY.YYYYYpt.
 We now make it that large for the rest of the document.
 This may cause the page layout to be inconsistent, however.

You are forgetting that placing an image inline with text (which is done when placing it in the header), the image sits on the baseline by default. Also, even though the image has no descender (like p, g or q), this forms part of your \headheight. You can set it to

\setlength{\headheight}{\dimexpr27mm+\dp\strutbox}

which includes the depth of the font-specific strut.

\documentclass{article}
\usepackage{graphicx,fancyhdr,lipsum}

\pagestyle{fancy}
\chead{\includegraphics[height=27mm]{example-image}}
\setlength{\headheight}{\dimexpr27mm+\dp\strutbox}
\showthe\headheight

\begin{document}

\lipsum[1-20]

\end{document}