Hi all,

I want to render some text with Qt that will be used in a texture in OpenGL. I have the basic setup done using QGraphicsView::render(QPainter...) and QGLWidget::convertToGLFormat(image), and that works. I use a QWidget with a QLabel with setWordWrap(true) inside my QGraphicsScene.

The problem is that I'm using a fixed font size. What I'd like is that given a string of text and a font family (say Arial), find the maximum size that will fit the texture. This has to consider word wrapping when possible. For example:

Qt Code:
  1. QFont getMaximumFontSize(const QString& text, const QString& fontFamily, int width, int height)
  2. {
  3. //...
  4. }
To copy to clipboard, switch view to plain text mode 
(width and height are the dimensions of the texture)

I have an iterative approach that kind of works, using QFontMetrics::boundingRect() starting at a large size and going down when it doesn't fit well enough. The problem is that there is no clear indication that the text doesn't fit.

Qt Code:
  1. QFont getMaxFontSize(const QString& text, const QString& fontFamily, int width, int height)
  2. {
  3. int size = 1000;
  4. QFont font("Arial", size);
  5. QRect max(0,0,width,height);
  6. int widthThreshold = int(float(max.width()) * 0.1);
  7. int heightThreshold = int(float(max.height()) * 0.1);
  8.  
  9. while (size > 1)
  10. {
  11. QFontMetrics metrics(font);
  12. QRect bb = metrics.boundingRect(max, Qt::TextWordWrap, text);
  13. if (bb.width() > (max.width() - widthThreshold) ||
  14. bb.height() > (max.height() - heightThreshold))
  15. {
  16. --size;
  17. font = QFont("Arial", size);
  18. }
  19. else
  20. {
  21. break;
  22. }
  23. }
  24.  
  25. return font;
  26. }
To copy to clipboard, switch view to plain text mode 
In addition to being potentially slow (going from 1000 in steps of 1, creating a new QFont and QFontMetrics each iteration), sometimes putting all the text on one line is a better "fit" according to the criteria in my while() loop above. But in most cases it works well.

Would anyone have some ideas as to how to get the information I want, to improve upon what I have? What I would really like is to get that info in one shot instead of iterating over font sizes. Thanks in advance,

Skylark