2

My problem

I want to define a frame with fixed dimensions (i.e. minimal size = maximal size = defined size), in which there is rich text (with potentially linebreaks, itemization, etc.).

Moreover, I want that it respects following properties :

  1. The text should fit within the frame, and not exceed vertically nor horizontally.
  2. The text should keep its relative fontsize (i.e. normalsize, or Huge, etc.), but might shrink it if it does not respect property #1 (in this case, chose the largest fontsize that enable the respect of property #1).
  3. The text should be vertically centered, and horizontally left-justified within the frame.
  4. The \linewidth should equal the fixed width (i.e. text should fill all the horizontal width, except for the last line).

Tried solutions

In order to keep the question clean and readable, please consult my answer below that lists all unsuccessful solutions I tried.


My question

Among the tried solution, which should be further investigate? And what settings am I missing, then? Maybe is there another packacge that would be more appropriate?

  • 1
  • updated question: your solution works (thanks !) but is not optimal as it doesn't fully use the defined width. (updated requirements as well) – ebosi Oct 8 '15 at 14:50
  • 1
    Your 3rd example of my method will work properly if you increase argument #4 from 20cm to 40cm. – Steven B. Segletes Oct 8 '15 at 15:01
  • Ideed, it works ! However, it is not the case for the 4th example (even with argument #4 = 210cm. Any guess why? Second question : how to make the original size be respected in the 1st example? – ebosi Oct 8 '15 at 15:07
  • 1
    The 4th example is tough, because the aspect can change drastically for a relatively short text when a line transitions from "wrap" to "doesn't wrap". I can manually intervene in the 4th example, and lower the height (argument #1) from 2cm to 1.98cm and get it almost where you want it. – Steven B. Segletes Oct 8 '15 at 15:10
6

This was a long problem description where several tried solution did not work. I can give assistence to \tcboxfit from tcolorbox.

The main reason for the failed scaling is that the standard algorithm needs a freely scalable font loaded. Also, setting fit fontsize macros would be needed to adapt \Huge.

One simple repair is to change the fitting algorithm to areasize which does not need a scalable font:

\documentclass[a4]{scrartcl}

\usepackage[most]{tcolorbox}
\tcbset{
  colframe=black,
  colback=white,
  size=tight,
  nobeforeafter,
  valign=center,
  fit fontsize macros,
  fit algorithm=areasize,
}

\begin{document}

\section*{tcolorbox solution}
    \tcboxfit[width=8cm,height=2cm]{
                Normal size, short text
    }
    \tcboxfit[width=8cm,height=2cm]{
                \Huge Huge size, short text
    }

    \vspace*{1cm}
    \noindent
    \tcboxfit[width=8cm,height=2cm]{
                Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters. And there is even more text such as lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum.
    }
    \tcboxfit[width=8cm,height=2cm]{
                \Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
    }
    \vspace*{0.5cm}

\end{document}

This gives:

enter image description here

  • It works like a charm, thank you (for your answer and for the package)! However, for long words and small boxes, the box doesn't force a word-break that makes the word go over the boundairies (e.g. \tcboxfit[width=8cm,height=2cm]{Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz} – ebosi Oct 9 '15 at 7:14
  • second improvement : in the case where you have following two boxes nearby, how to make that the vertical alignment is in both case relative to the bottom of 'e' , and not once to 'e' and once to 'p' ? \tcboxfit[width=8cm,height=2cm]{\Large Test} \tcboxfit[width=8cm,height=2cm]{\Large Exemple} (I have tried the global argument box align=base but it doesn't work) – ebosi Oct 9 '15 at 10:05
  • 1
    @ebo The first one is a pdflatex problem with can be circumvented by adding hyphenationfix like \tcboxfit[width=8cm,height=2cm,hyphenationfix]{Rindfleischetikettierungsüberwachungsaufgabenüb‌​ertragungsgesetz} – Thomas F. Sturm Oct 9 '15 at 10:23
  • @ebo The base alignment does not work for fixed height boxes. I see no way to get this feature here. – Thomas F. Sturm Oct 9 '15 at 10:28
  • @thomas-f-sturm you answered both of my questions. a warm thank you for guiding within the enormity of your work! (-: – ebosi Oct 9 '15 at 11:36
2

N.B.: In order to keep the original question readable (and thus, understandable), you'll find here my trials that were originally posted within the question. Note that there is here no fully satisfying solutions. This post serves more as food for thought, and for not losing time in this stalemates.


Tried solutions

I have found several thread discussing similar problems. I tried some of the suggested solutions.

  • Using the environ package + minibox + \relsize

For example kongo09's solution to question "Fit text into given box by adjusting the fontsize" works perfectly fine for me... except that the fontsize is increased if the text is not long enough (what I don't want, because if you have a small text within a big frame, you'll get an enormous fontsize, what is ugly).

  • Using \tcboxfit from the tcolorbox package

As suggested in this solution, there is also the tcboxfit solution. However, it doesn't works as in following MWE

    \documentclass[a4]{scrartcl}

    \usepackage[most]{tcolorbox}    
    \tcbset{
    colframe=black,
    colback=white,
    boxsep=0pt,
        top=0mm,
        bottom=0mm,
        left=0mm,
        right=0mm,
        nobeforeafter, 
        arc=0pt, 
        outer arc=0pt
    }

    \begin{document}

    \section*{tcolorbox solution}
        \tcboxfit[width=8cm,height=2cm]{
                    Normal size, short text
        }
        \tcboxfit[width=8cm,height=2cm]{
                    \Huge Huge size, short text 
        }

        \vspace*{1cm}
        \noindent
        \tcboxfit[width=8cm,height=2cm]{
                    Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters. And there is even more text such as lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. 
        }
        \tcboxfit[width=8cm,height=2cm]{
                    \Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
        }
        \vspace*{0.5cm}

    \end{document}

MWE tcboxfit

  • Using Steven's solution

As suggested in Steven's comment, I looked at his solution. However, I observe that the original font-size might be increased, and that not all the text width is used when decreasing the font size. Here is an MWE :

            \documentclass[a4]{scrartcl}

            \usepackage{scalerel}
            \usepackage{fp}
            \usepackage{stackengine}

            \newcount\boxheight
            \newcount\boxwidth
            \newlength\constrainedwidth
            \newsavebox\testbox
            \newlength\currentwidth

            \newcommand\aspect[1]{%
              \boxheight=\ht#1\relax%
              \boxwidth=\wd#1\relax%
              \FPdiv\testaspect{\the\boxheight}{\the\boxwidth}%
            %\testaspect\\%                                  COMMENT THIS LINE TO REMOVE ASPECT-RATIO PRINTS
            }

            % TARGET-HEIGHT, TARGET-WIDTH, CONTENT, GUESS>NATURAL-WIDTH, dWIDTH
            \newcommand\constraintext[5]{%
              \def\svfboxsep{\the\fboxsep}%
              \setlength\fboxsep{0pt}%
              \setlength\constrainedwidth{#2}%
              \sbox\testbox{\rule{#2}{#1}}%
            %TARGET ASPECT RATIO\\%                  COMMENT THIS LINE TO REMOVE COMMENT
            %V\\%                                                    COMMENT THIS LINE TO REMOVE COMMENT
              \aspect{\testbox}%
              \edef\aspectratio{\testaspect}%
              \constrainsize{#1}{\aspectratio}{#3}{#4}{#5}%
              \setlength\fboxsep{\svfboxsep}%
            }
            \newcommand\constrainsize[5]{%
              \sbox{\testbox}{\fbox{\parbox[b]{#4}{#3}}}%
              \aspect{\testbox}%
              \FPiflt{\testaspect}{#2}%
                \setlength{\currentwidth}{#4}%
                \addtolength{\currentwidth}{-#5}%
                \constrainsize{#1}{#2}{#3}{\currentwidth}{#5}%
              \else
                \setlength\constrainedwidth{#1}%
                \FPdiv\result{1.0}{#2}%
            %                                                       CHANGE \framebox TO \makebox TO REMOVE FRAME
                \framebox[\result\constrainedwidth]{\hfill%
                  \scaleto{\parbox[b]{\currentwidth}{#3}}{#1}%
                  \hfill%
                }%
              \fi%
            }
            \parindent 0pt

            \begin{document}

            \section*{Steven's solution}
                \constraintext{2cm}{8cm}{
                                            Normal size, short text
                }{20cm}{0.1cm}
                \constraintext{2cm}{8cm}{
                                            \Huge Huge size, short text 
                }{20cm}{0.1cm}

                            \vspace*{1cm}
                \noindent
                \constraintext{2cm}{8cm}{
                                            Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters. And there is even more text such as lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. 
                }{20cm}{0.1cm}
                \constraintext{2cm}{8cm}{
                                            \Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
                }{20cm}{0.1cm}
            \end{document}

Steven's solution

  • Using the adjustbox package

I also have heard about the adjustbox package, that -- imho -- seems adapted to my issue. However, after some trials, I cannot find the parameters that fit my requirements. I have explored two solutions :

  • an environment based on the \adjustbox command,
  • the \adjustbox

The first works well, except that I cannot make it force to respect the vertical maximal dimension. The latter is not acceptable in this case since it doesn't accept linebreaks, itemizations, etc.

Here is my MWE :

\documentclass[a4]{scrartcl}

\usepackage[calc]{adjustbox}

\newenvironment{fitbox}[2]{% \begin{fitbox}{<width>}{<height>} stuff \end{fitbox}
        \def\Xwidth{#1}
        \def\Yheight{#2}
        \noindent
        \adjustbox{
            frame,
            margin= 0pt 0pt 0pt 0pt,
            minipage=[c][\Yheight]{\Xwidth},
            min width=\Xwidth ,
            min totalheight=\Yheight ,          
            max width=\Xwidth ,
            max totalheight=\Yheight ,
            env={minipage}[t][\Yheight]{\Xwidth}
        }\bgroup
    }{%
        \egroup
    }

\begin{document}

\section{fitbox solution}
    \begin{fitbox}{8cm}{2cm}
                Normal size, short text
    \end{fitbox}
    \begin{fitbox}{8cm}{2cm}
                \Huge Huge size, short text 
\end{fitbox}

    \vspace*{1cm}
    \begin{fitbox}{8cm}{2cm}
                Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters. 
    \end{fitbox}
    \begin{fitbox}{8cm}{2cm}
                \Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
    \end{fitbox}
    \vspace*{0.5cm}

\section{maxsizebox solution}

    \maxsizebox*{8cm}{2cm}{\fbox{Normal size, short text}}
    \maxsizebox*{8cm}{2cm}{\fbox{\Huge Huge size, short text }}

    \noindent
    \maxsizebox*{8cm}{2cm}{\fbox{Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters.}}
    \maxsizebox*{8cm}{2cm}{\fbox{\Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.}}
\end{document}

And its output : MWE output

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.