Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. How to calcuate font size to fit a text inside a given rectangle
QtWS25 Last Chance

How to calcuate font size to fit a text inside a given rectangle

Scheduled Pinned Locked Moved Mobile and Embedded
13 Posts 7 Posters 15.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gianluca
    wrote on 10 Jun 2013, 10:31 last edited by
    #1

    Dear all,
    I want to display a text fitting all inside the screen of a mobile device.
    So, I'm trying to find out an efficient way to calculate the correct font size in order to display the text all inside the screen size.

    Any suggestions ??

    Thanks,
    Gianluca.

    1 Reply Last reply
    1
    • S Offline
      S Offline
      SergioDanielG
      wrote on 10 Jun 2013, 11:05 last edited by
      #2

      Hi Gianluca.
      Did you try with "QFontMetrics":http://qt-project.org/doc/qt-4.8/qfontmetrics.html ?
      From doc:
      "The QFontMetrics class provides font metrics information.
      QFontMetrics functions calculate the size of characters and strings for a given font.
      ..."
      Regards.

      www.ftatv.com.ar El foro argentino de la TV libre

      1 Reply Last reply
      -1
      • G Offline
        G Offline
        Gianluca
        wrote on 10 Jun 2013, 11:43 last edited by
        #3

        I played a bit with QFontMetrics... but if the text is a rich text it continue to work??
        I'm bit confused by the documentation of QFontMetrics::boundingRect:

        "Newline characters are processed as normal characters, not as linebreaks."

        So, it seems that it returns the boundingRect as if the text is written on a long single line.

        And it say nothing about right text :-(

        Thanks,
        Gianluca.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          steno
          wrote on 3 Oct 2013, 20:09 last edited by
          #4

          I'm in the same boat. I'm given a rectangle size, and I want to grow my font to fit within a rectangle. I think QFontMetrics allows you to calculate a rectangle with a string, not a font size based off of a rectangle.

          1 Reply Last reply
          0
          • R Offline
            R Offline
            raven-worx
            Moderators
            wrote on 4 Oct 2013, 11:09 last edited by
            #5

            if you want to do checks with rich text you will need to do this with QTextDocument instead. You can use the following methods for this:

            QTextDocument::setHtml()
            QTextDocument::setPageSize();
            QTextDocument::setDefaultFont()
            QTextDocument::::documentLayout()->documentSize()

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            0
            • G Offline
              G Offline
              Gianluca
              wrote on 4 Oct 2013, 12:25 last edited by
              #6

              But the question is the opposite.
              I want to know what should be the font size in order to fit inside a given rectangle.
              With the documentSize() method only, for get the answer of the above question I should iterate over all possible font size starting from 1 until I get the value corresponding to the nearest documentSize() to the given rectangle.
              But this procedure it's very heavy and the computational cost is not acceptable.

              1 Reply Last reply
              1
              • R Offline
                R Offline
                raven-worx
                Moderators
                wrote on 4 Oct 2013, 12:41 last edited by
                #7

                exactly... AFAIK there is no function which provides it the other way around.
                What are the estimated bounds of the font size in your case?
                5pt - 30pt ... meaning 25 iterations in worst case. What system you developing for? Embedded?

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  Gianluca
                  wrote on 4 Oct 2013, 12:56 last edited by
                  #8

                  I'm developing for mobile platforms.
                  I would like to get a way to estimate the font size to drastically reduce the number of iterations. Because 20 iterations on setting font on a QTextDocument and ask the documentSize() it seems too much for me.
                  It's too much because I need to do the calculation during the dynamical changing of the screen dimension due to rotations or to the appear of keyboard. And in that situations if my code spend more than few milliseconds to calculate the new fontsize the animation will be crap.
                  Using a QTextDocument, I cannot do more that 5 iterations.

                  Also, calculating the bounds for the font size it's not too easy if I don't know the answer to my question. Because, there are many different phones and tablets with so many different screen dimension and density of pixel that It's unreasonable to use a bounds that works for all mobile devices.
                  Instead, if I can figure out a way to estimate the font size for a given rectangle, I can use the routine to calculate the bounds of the font on the basis of the maximum dimension for the rectangle depending on the screen resolution of the mobile device.

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    raven-worx
                    Moderators
                    wrote on 4 Oct 2013, 13:14 last edited by
                    #9

                    have you tested it ... i mean performance wise?
                    I would assume you could easily load 50 iterations at least without noticing (depending on the device ofc).

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      Gianluca
                      wrote on 4 Oct 2013, 13:52 last edited by
                      #10

                      Yes, I tested... only visually not with precise timing.
                      And, If the program do more than 5 iterations the rotation animation (from landscape to portrait and viceversa) will stop about in the middle and then restart.
                      I suppose that the delay of iterations in the code that block the GUI thread, blocks also the animations.
                      (On a very cheap mobile phone).

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        mcniva
                        wrote on 4 Oct 2013, 15:33 last edited by
                        #11

                        Maybe I am not understanding, but can't you just use the initial rich-text result as a scale?

                        If you take your initial estimated font size (f) and your resulting rich-text rect (r) and your size constraint (c) you should be able to get it in one try with a formula like this:

                        int meanSize = r.width * r.height;
                        int meanCanvas = c.width * c.height;
                        int newPixelSize = floor( f * (meanCanvas / meanSize) );

                        So for example my test text renders to 200 x 335 inside a 210x210 space at 24px font:
                        meanSize = 67000
                        meanCanvas = 44100
                        newPixelSize = 15.797 => 15

                        It works in my tests:

                        [code]Mean volume: 50576
                        Canvas volume: 29736
                        Scale 12 to 7
                        Mean volume: 50184
                        Canvas volume: 34846
                        Scale 12 to 8
                        Mean volume: 48928
                        Canvas volume: 47978
                        Scale 12 to 11
                        Mean volume: 51800
                        Canvas volume: 71154
                        Scale 12 to 16
                        Mean volume: 52680
                        Canvas volume: 120053
                        Scale 12 to 27
                        Mean volume: 54000
                        Canvas volume: 128028
                        Scale 12 to 28 [/code]

                        Here's the relevant method. It's a basic QMainWindow object with a QTextBrowser as the central widget called 'textBrowser':

                        [code]void MainWindow::resizeEvent(QResizeEvent *e)
                        {
                        QSizeF meanSize = ui->textBrowser->document()->size();
                        int meanVolume = meanSize.width() * meanSize.height();
                        qDebug() << "Mean volume:" << meanVolume;
                        if( meanVolume <= 0 )
                        return;

                        int canvasVolume = ui->textBrowser->width() * ui->textBrowser->height();
                        qDebug() << "Canvas volume:" << canvasVolume;
                        if( canvasVolume <= 0 )
                            return;
                        
                        int pixelSize = ui->textBrowser->fontInfo().pixelSize();
                        
                        int newPixelSize = qFloor( (double)pixelSize * ( (double)canvasVolume / (double)meanVolume ) );
                        qDebug() << "Scale" << pixelSize << "to" << newPixelSize;
                        
                        QMainWindow::resizeEvent(e);
                        

                        }[/code]

                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          JDGascuel
                          wrote on 4 Oct 2013, 21:26 last edited by
                          #12

                          Nice.

                          I have the same question for a QSplashScreen...

                          Because splash->showMessage( richText ) enables you to set some styled and translated document, is seems impossible to know its original size, and tweak the font as you proposed.

                          Any clue ?

                          --
                          JeanDo http://ostc-planner.net

                          1 Reply Last reply
                          0
                          • SebastienLS Offline
                            SebastienLS Offline
                            SebastienL
                            wrote on 25 Jul 2016, 07:45 last edited by SebastienL
                            #13

                            Here is my code the fit (in heigth) a text, works quite well (error < 2% I guess) :

                            void scalePainterFontSizeToFit(QPainter &painter, QFont &r_font, float _heightToFitIn)
                            {
                                float oldFontSize, newFontSize, oldHeight;
                            
                                // Init
                                oldFontSize=r_font.pointSizeF();
                            
                                // Loop
                                for (int i=0 ; i<3 ; i++)
                                {
                                    oldHeight = painter.fontMetrics().boundingRect('D').height();
                                    newFontSize = (_heightToFitIn / oldHeight) * oldFontSize;
                                    r_font.setPointSizeF(newFontSize);
                                    painter.setFont(r_font);
                                    oldFontSize = newFontSize;
                                    //qDebug() << "OldFontSize=" << oldFontSize << "HtoFitIn=" << _heightToFitIn << "  fontHeight=" << oldHeight << "  newFontSize=" << newFontSize;
                                }
                            
                                // End
                                r_font.setPointSizeF(newFontSize);
                                painter.setFont(r_font);
                            }
                            
                            1 Reply Last reply
                            1

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved