c++qtqtextdocument

Qt detect breakline when writing to QTextTable


I'm using QTextTable and QTextTableFormat to create a PDF file and insert HTML code into the table cells.

"<span style=\"font-weight: bold; font-size: %1px\">%2</span>"

I want to shrink my tables header content so it will fit in 2 lines. I user QFontMetrics to calculate the width of the string that I want to display then start reducing font size till it fit in. The minimum font size I allow is 8pixel, if the text is wider I elide the end of the text with (...).

The problem: I calculate the maximum width of cell, let's say 50, therefore, the width of 2 lines for the header will be 100. I shrunk the text to 90 pixels and it still won't fit if the text is like "iii aaaaaaaaa" because the second word is a lot longer then the first one. And the first word will take the entire first line even tho it is only around 20 pixels wide and the second word will break into two lin e resulting in 3 lines.

What I am looking for is a way to detect or calculate if the given QFont and QString inserted on QTextDocument using QTextTableFormat will result in how many lines


Solution

  • You could count the lines using a trivial function like this:

    QStringList getLines(const QFontMetrics & metrics, const QString & source, const int maxwidth)
    {
        QStringList lines;
    
        QString text;
        for(auto c : source)
        {
            if(metrics.horizontalAdvance(text + c) > maxwidth)
            {
                lines << text;
                text.clear();
            }
            text.append(c);
        }
        lines << text;
    
        return lines;
    }
    

    If this happens to return more than two lines, you can set ellipsis on the second with a function like:

    QString setEllipses(const QFontMetrics & metrics, const QString & source, const int maxwidth)
    {
        QString text;
        int i = 0;
        while((i <= source.length()) && (metrics.horizontalAdvance(text) < maxwidth))
        {
            text = source.left(++i) + " ...";
        }
        return text;
    }
    

    then recompose the cell text, e.g.

    auto lines = getLines(metrics, original_text, maxwidth);
    if(lines.size() > 2)
    {
        QString celltext = lines[0] + "<br>" + setEllipses(metrics, lines[1], 300);
        //...
    }