Having trouble dividing lengths with calc package

Ian's answer pointed me into the right direction: This is easily possible with the adjustbox package by Martin Scharrer. It basically gives you an \includegraphics-like interface to be used with any (boxable) material:

\documentclass{article}
\usepackage{adjustbox}

\begin{document}

  \adjustbox{width=400pt,height=800pt,keepaspectratio=true}{Hello, World}

\end{document}

When you use \includegraphics, you can specify height, width and whether you wish to preserve the aspect ratio. With the option keepaspectratio=true, the image will be made as large as possible, whilst not exceeding the specified height or width.

\includegraphics[width=400pt,height=800pt,keepaspectratio=true]{myfile}

For details of the options accepted by \includegraphics, see section 7.5 of epslatex.pdf.

More generally, you could make two boxes:

  • the original object, scaled so that its width is the total width available,
  • the original object, scaled so that its height is the total height available.

The box that you want will always be the smaller of these two.

\documentclass{article}
\usepackage{graphicx}
\newcommand{\myscale}[1]{%
\newbox\bigbox
\newbox\anotherbigbox
\sbox\bigbox{\resizebox{\textwidth}{!}{#1}}%
\sbox\anotherbigbox{\resizebox{!}{\textheight}{#1}}%
\newdimen\bigboxwidth
\newdimen\anotherbigboxwidth
\bigboxwidth=\wd\bigbox
\anotherbigboxwidth=\wd\anotherbigbox
\ifnum\bigboxwidth<\anotherbigboxwidth\usebox\bigbox\else\usebox\anotherbigbox\fi
}%
\begin{document}
\noindent
\myscale{\rule{10pt}{1pt}}
\newpage
\myscale{\rule{1pt}{10pt}}
\end{document}

Besides using my adjustbox package already mentioned in the accepted answer of Daniel, you also can use an internal if-switch to make \resizebox do the work for you. The keepaspectratio option of \includegraphics (which comes from the same package as \resizebox, graphicx) simply set the Gin@iso switch to true. There is no public interface for this for \resizebox, but you can use \Gin@isotrue to set it locally, either between \makeatletter .. \makeatother, or using \csname Gin@isotrue\endcsname:

{\csname Gin@isotrue\endcsname
 \resizebox{<height>}{<width>}{<content>}}

This is identical to using height=<height>,width=<width>,keepaspectratio with either \includegraphics, \adjustbox or {adjustbox}. However, the last two process the content as box not as macro argument and therefore allow for verbatim content.