Results 1 to 9 of 9

Thread: How to get the line height of a QTextBlock?

  1. #1
    Join Date
    Jan 2013
    Posts
    9
    Thanks
    3
    Qt products
    Qt4

    Default How to get the line height of a QTextBlock?

    Windows 7 SP1
    MSVS 2010
    Qt 4.8.4

    Given this code:


    Qt Code:
    1. #include <QTGui>
    2.  
    3. int main(int argc, char *argv[])
    4. {
    5. QTextDocument* text_document = new QTextDocument("testing");
    6. QTextBlock text_block = text_document->begin();
    7. qDebug() << text_block.text() << text_block.blockFormat().lineHeight()
    8. << text_block.blockFormat().lineHeightType();
    9. }
    To copy to clipboard, switch view to plain text mode 

    The console displays:

    "testing" 0 0

    Question: Why doesn't lineHeight return "the LineHeight property for the paragraph"? The lineHeightType is set for single spacing.

    Even trying:

    Qt Code:
    1. qDebug() << text_block.text() << text_block.layout()->boundingRect().height();
    To copy to clipboard, switch view to plain text mode 

    gives me zero.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get the line height of a QTextBlock?

    Was there something wrong with the answer you got the last time you asked exactly this question?

  3. #3
    Join Date
    Jan 2013
    Posts
    9
    Thanks
    3
    Qt products
    Qt4

    Default Re: How to get the line height of a QTextBlock?

    Yes, it did not answer the question (Why doesn't lineHeight return "the LineHeight property for the paragraph"?). Nor did the suggested technique for solving the problem help with a QTextBlock with multiple fonts, i.e., multiple fragments nor did it help with the general one of handling Unicode. I was hoping that this forum may have been more appropriate.

    I believe the general solution is to iterate the fragments and search for the maximum ascent & maximum descent (one font may have the max descent, another the max ascent) and then add 1 for the baseline. Then add in the maximum leading for the fonts(s) with the maximum height. This is theoretical but it appears to work with the small set of experiments I have tried. I would prefer to have lineHeight method return the property to me so that I do not have to guess. I suspect I am misunderstanding how to get at this property -- I've tried the above, cursors on the block and the document, and several other methods to no avail.

    For example, Consalas 14 has height 22, ascent 17, descent 4 and leading 0. If that is the only font in the text block, then the line height is 22.

    Arial 14 has height 22, ascent 18, descent 3 and leading 1. If that is the only font, then the line height is 18 + 3 + 1 + 1 = 23.

    If you have Consolas 14 and Arial 14 fragments in a text block, then the line height = max ascent (18) + max descent (4) + 1 + max leading(1) = 24.

    Consolas 24 has height 37, ascent 29, descent 7, leading 0. The line height is 37 whether it is combined with Aria 14 or not because it has all the maximum values and its leading 0 is used because it is the larger font. That would be reversed if Arial was the larger font (i.e., leading of 1 would be used).

    Anyway, again, all theoretical. I would prefer to get Qt's answer, the property LineHeight, gotten from lineHeight.
    Last edited by therefore; 7th February 2013 at 06:16.

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get the line height of a QTextBlock?

    This property is an input to the formatter for you to dictate what the line height policy is to be, not to report what the formatter has ultimately allocated for a given text. QTextBlockFormat::lineHeight() does return the line height property of the block format. Unless you have done something to change this with setLineHeight() it will continue to return 0 and a type of SingleHeight, and the formatter lays out the paragraph at its natural height during rendering. If you set the type to MinimumHeight or FixedHeight and set a line height of 32 pixels that's what will be returned and the formatter will act accordingly.

    If you want to know the ultimate height of the entire text block (which may span several lines?) then you may be able to get it from the QAbstractTextDocumentLayout::blockBoundingRect() method of the QTextDocument's documentLayout.
    Qt Code:
    1. QAbstractTextDocumentLayout *layout = text_document->documentLayout();
    2. qDebug() << layout->blockBoundingRect(text_block);
    3. // QRectF(4,4 44x14) for your example on my machine
    To copy to clipboard, switch view to plain text mode 

    If you want to know what the actual height of a particular rendered line is... The layout engine does this stuff with QTextLayout and QTextLine (see Rich Text Layouts). I cannot really help with custom layout. Perhaps now we have some more information one of the others may know.

  5. The following user says thank you to ChrisW67 for this useful post:

    therefore (7th February 2013)

  6. #5
    Join Date
    Jan 2013
    Posts
    9
    Thanks
    3
    Qt products
    Qt4

    Default Re: How to get the line height of a QTextBlock?

    Thank you. That answers the first question why lineHeight does not return the rendered height of the line -- because that is not what it is. Instead, it is the programmer dictated line height. So, I should stop at attempt #10 to get a non-zero number.

    Yes, I am interested in the rendered line height (not the paragraph's). I will go drill into Qt source to see if I can see how it calculates it vs. trying to reverse engineer. Unless someone can point me in the right direction to use the API instead.

    Thanks again!

  7. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get the line height of a QTextBlock?

    You can use QTextLayout yourself (per the docs I linked) but then you are calculating your own line contents and heights anyway, which is basically what you'd like to avoid. However, your own layout engine may be the best way to align the text with other things on the page; to ensure the text lines up with a pre-printed form for example.

    See getLineHeightParams() and QTextDocumentLayoutPrivate::layoutBlock() in src/gui/text/qtextdocumentlayout.cpp for a start.

  8. The following user says thank you to ChrisW67 for this useful post:

    therefore (10th February 2013)

  9. #7
    Join Date
    Jan 2013
    Posts
    9
    Thanks
    3
    Qt products
    Qt4

    Default Re: How to get the line height of a QTextBlock?

    Thanks for the guidance! I am not trying to calculate my own line heights -- I am trying to determine what the rendered heights are. To simplify things, here is what I want to do:

    Qt Code:
    1. #include <QTGui>
    2.  
    3. int CalculateLineHeight(QTextBlock text_block);
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QApplication app(argc, argv);
    8. QMainWindow* window = new QMainWindow;
    9. QTextEdit* editor = new QTextEdit(window);
    10.  
    11. QTextDocument* text_document = new QTextDocument(window);
    12. editor->setDocument(text_document);
    13.  
    14. QFile file("test.html");
    15. if (file.open(QFile::ReadOnly | QFile::Text))
    16. editor->setHtml(file.readAll());
    17.  
    18. QTextBlock text_block = text_document->begin();
    19. while (text_block.isValid() )
    20. {
    21. qDebug() << text_block.text() << CalculateLineHeight(text_block);
    22. text_block = text_block.next();
    23. }
    24. window->setCentralWidget(editor);
    25. window->show();
    26. return app.exec();
    27. }
    28.  
    29. int CalculateLineHeight(QTextBlock text_block)
    30. {
    31. QList<QTextLayout::FormatRange> text_block_format_ranges;
    32.  
    33. // Gather the format ranges for each fragment of the text block.
    34. for (QTextBlock::Iterator fragment_it = text_block.begin(); !(fragment_it.atEnd()); ++fragment_it)
    35. {
    36. QTextFragment fragment = fragment_it.fragment();
    37.  
    38. QTextCharFormat fragment_format = fragment.charFormat();
    39. QTextLayout::FormatRange text_block_format_range;
    40. text_block_format_range.format = fragment_format;
    41. text_block_format_range.start = fragment.position();
    42. text_block_format_range.length = fragment.length();
    43.  
    44. text_block_format_ranges << text_block_format_range;
    45. }
    46. // Create text layout
    47. QTextLayout text_layout(text_block.text());
    48. text_layout.setAdditionalFormats( text_block_format_ranges );
    49. text_layout.beginLayout();
    50. QTextLine line = text_layout.createLine();
    51. text_layout.endLayout();
    52.  
    53. return text_layout.boundingRect().height();
    54. }
    To copy to clipboard, switch view to plain text mode 

    This is test.html:

    Qt Code:
    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <style>
    5. .consolas{
    6. font-family: "Consolas";
    7. font-size:14pt;
    8. background-color: cyan;
    9. }
    10. .arial{
    11. font-family: "Arial";
    12. font-size:14pt;
    13. background-color: cyan;
    14. }
    15. </style>
    16. </head>
    17.  
    18. <body>
    19. <p><span class="consolas">E</span></p>
    20. <p><span class="arial">E</span></p>
    21. <p><span class="consolas">E</span><span class="arial">E</span></p>
    22. </body>
    23. </html>
    To copy to clipboard, switch view to plain text mode 
    The window displays (with my annotations indicating the LineHeights):

    editor window.JPG

    But I get the following console output:

    "E" 22
    "E" 13
    "EE" 13


    So, it apparently calculates it properly on the first line, but subsequent lines it does not calculate it properly (2nd line s/b 23, 3rd s/b 24). So, I believe I am closer but I suspect my problem lies in how I am handling the text layouts.

    Any thoughts?

  10. #8
    Join Date
    Jan 2013
    Posts
    9
    Thanks
    3
    Qt products
    Qt4

    Default Re: How to get the line height of a QTextBlock?

    I finally got it -- couldn't have done it without your guidance, so THANKS!

    I did not realize that fragment.position is the position within the document and not the text block. So had to subtract out the document position of the text block start. And I needed to make sure the calculation on the QTextLine included the leading.

    Qt Code:
    1. int CalculateLineHeight(QTextBlock text_block)
    2. {
    3. QList<QTextLayout::FormatRange> text_block_format_ranges;
    4.  
    5. // Gather the format ranges for each fragment of the text block.
    6. for (QTextBlock::Iterator fragment_it = text_block.begin(); !(fragment_it.atEnd()); ++fragment_it)
    7. {
    8. QTextFragment fragment = fragment_it.fragment();
    9.  
    10. QTextCharFormat fragment_format = fragment.charFormat();
    11. QTextLayout::FormatRange text_block_format_range;
    12. text_block_format_range.format = fragment_format;
    13. // fragment.position = position within the document whereas
    14. // .start = position within the text block. Therefore, need
    15. // to subtract out the text block's starting position within the document.
    16. text_block_format_range.start = fragment.position()
    17. - text_block.position();
    18. text_block_format_range.length = fragment.length();
    19.  
    20. text_block_format_ranges << text_block_format_range;
    21. }
    22.  
    23. // Create text layout
    24. QTextLayout text_layout(text_block.text());
    25. text_layout.setAdditionalFormats( text_block_format_ranges );
    26. text_layout.beginLayout();
    27. QTextLine line = text_layout.createLine();
    28. text_layout.endLayout();
    29. line.setLeadingIncluded(true); // Need to include the leading
    30. return line.height();
    31. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by therefore; 10th February 2013 at 04:30.

  11. #9
    Join Date
    Apr 2013
    Posts
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to get the line height of a QTextBlock?

    Did I understand this right that QTextBlock contains text from '\n' up to the next '\n' unless the text between this two new_line symbols contains less or equal chars than QTextBlockFormat::FixedHeight? And if the number of symbols is greater then this piece of the text is separated on two QTextBlocks. Can I forbid to add new chars in the line if this line already contains max number of chars that QTextBlockFormat allows to have so that one line won't be separated in two pieces?

Similar Threads

  1. How to get the line height of a QTextBlock?
    By therefore in forum Newbie
    Replies: 1
    Last Post: 3rd February 2013, 23:00
  2. QLABEL how to Set Line Height?
    By lamp in forum Qt Programming
    Replies: 2
    Last Post: 8th November 2010, 12:22
  3. Changing line height in QTextEdit (Qt4)
    By ultr in forum Qt Programming
    Replies: 0
    Last Post: 19th February 2010, 15:59
  4. QTextBlock::setVisible()
    By jgrauman in forum Qt Programming
    Replies: 3
    Last Post: 11th December 2009, 01:06
  5. QTextDocument and line height
    By vooft in forum Qt Programming
    Replies: 0
    Last Post: 25th November 2008, 16:47

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.