[Tex/LaTex] pdflscape fails to rotate page containing only a float

floatslandscapepdflscaperotating

I'm using pdflscape to place some landscape pages in a long portrait document, because it contains some very wide floats.

However, when a float is so big that it needs its own page, it is no longer rotated correctly:

The following code:

\documentclass{article}
\usepackage{pdflscape}
\usepackage{lipsum}

\begin{document}
\lipsum[1-4]

\begin{landscape}
\lipsum[5-6]

\begin{figure}
\lipsum[7-8]
\caption{Some text, rotated correctly.}
\end{figure}

\begin{figure}
\lipsum[9-12]
\caption{Some more text, wrong side up.}
\end{figure}

\end{landscape}

\end{document}

Produces that output:

PDF output

How can I correctly rotate float-only pages?

Best Answer

Package pdflscape is just a wrapper for package lscape. It sets the /Rotate entry in the PDF page data structure. Thus the question shows the correct orientation of the paper, pages 2 and 3 are in landscape.

However the contents of the third page is not shown correctly. Package lscape hooks into macros of the output routine that constructs the page contents and rotates the output box. But it misses a case:

\documentclass[12pt]{article}
\usepackage[a6paper]{geometry}% smaller images for answer
\usepackage{lscape}

\begin{document}
\begin{landscape}
\rule{5mm}{50mm}\hfill\rule{5mm}{50mm}
\begin{figure}
\rule{5mm}{90mm}\hfill\rule{5mm}{90mm}
\caption{Some text, not rotated, wrong footer}
\end{figure}
\end{landscape}
\end{document}

Page 1:

Page 1

Page 2:

Page 2

Package lscape hooks into

  • \@makecol: normal page
  • \@makefcolumn: float page. It calls \@tryfcolumn inside a group and the actual work is done in macro \@vtryfc.

But this misses a case. The output routine starts with:

\output {%
  \let \par \@@par
  \ifnum \outputpenalty<-\@M
    \@specialoutput
  \else
    \@makecol
    \@opcol
    \@startcolumn
    \@whilesw \if@fcolmade \fi
      {%
       \@opcol\@startcolumn}%
  \fi

\@makecol constructs the first page, it is caught by package lscape and rotated. \@opcol outputs the page. Then \@startcolumn is called. It also invokes \@tryfcolumn, but not \@makefcolumn. Thus an output page is constructed, but not detected by package lscape. (The same happens to \@startdblcolumn that also invokes \@tryfcolumn, but I have not tested, whether twocolumn stuff works at all.)

Fix suggestion (after package lscape or pdflscape):

\makeatletter
\let\LS@vtryfc\@vtryfc
\g@addto@macro\landscape{%
  \def\@vtryfc#1{%
    \LS@vtryfc{#1}%
    \LS@rot
  }%
}   
\makeatother

Then the second page of the example becomes:

Page 2, corrected

And the last page of the question is also correct:

Last page of question, corrected