Nominate our 2022 Qt Champions!

Get remaining part of a large string to fit fixed rectangle

  • I have a very large string, a font and a rectangle to draw that string into. If the string doesn't fit, I would like to know the size of string that does fit into that rectangle... if the string does fit, then I would like to know bounding rectangle height. How to achieve this?

  • Lifetime Qt Champion

    hi have you read about
    It can return a rectangle for the complete text.

  • @mrjj Yes, I have seen that. Unfortunately, it doesn't help in getting length of string that fits.

  • Lifetime Qt Champion

    So say we have
    abcdefg and we can only display abc
    you want to know the sub string that was possible to draw
    given the rect?

    hmm, it reports back in pixels not letters.
    Sorry Im not aware of anything that would report back such info.

  • @mrjj Yes, that is correct. Of course, I could create a method that acts like a binary search, halfing/doubling string length calling boundingRect(), until low margin == high margin, but I assume this is not very optimized.

  • Lifetime Qt Champion

    well, you could also do the word wrap yourself, using
    or look at source code for drawtext and see if you reuse some of it for a version
    that can return the substring.

    Is this big string with spaces ?

  • I am posting my own binary search algorithm. BTW you can use QFontMetrics instead of QPainter if you want.

    int FontUtils::FittingLength(const QString& s, QPainter &p, const QRectF& rect,
                                 int flags/* = Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap*/)
        QRectF r = p.boundingRect(rect, flags, s);
        if (r.height() <= rect.height()) // String fits rect.
            return s.length();
        // Apply binary search.
        QString sub;
        int left = 0, right = s.length()-1;
            int pivot = (left + right)>>1; // Middle point.
            sub = s.mid(0, pivot+1);
            r = p.boundingRect(rect, flags, sub);
            if (r.height() > rect.height()) // Doesn't fit.
                right = pivot-1;
                left = pivot+1;
        } while (left < right);
        left++; // Length of string is one char more.
        // Remove trailing word if it doesn't fit.
        if  ( ! && ! )
            while ( (--left > 0) && ! );
        return left;

Log in to reply