Results 1 to 7 of 7

Thread: How draw a rotated text in a QPainterPath?

  1. #1
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default How draw a rotated text in a QPainterPath?

    Hi,
    I need to draw a rotated text as part of a QPainterPath to be drawn in a QGraphicsScene (I use a custom subclass of QGraphicsItem).
    I can draw the text with QPainterPath::addText(), but it accepts only the starting point.
    Really I have 2 problems:
    1) I need the text to stay inside a specified rectangle
    2) the rectangle may be rotated

    For 1) I thought about this solution: a while() loop which reduces font size until QFontMetricsF::boundingRect() is small enough to fit in the requested rectangle.
    Is there a better way?

    For 2) I don't have a solution at the moment.

    I don't know how to use the QTextLayout and QTextLine classes, may them help me in some way?

    Any help/suggestion is really appreciated!

    Thanks,
    Alessandro

  2. #2
    Join Date
    May 2006
    Location
    Bangalore,India
    Posts
    235
    Thanks
    7
    Thanked 25 Times in 24 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: How draw a rotated text in a QPainterPath?

    in QPainterPath you can draw any type of data.
    I dont understand your question.
    is your question is to display rotated text in QGraphicsView?
    for your 1st question: you can create own GraphicsTextItem by drive QGraphicTextItem and inside boundingRect() you can create rect.

    Qt Code:
    1. class GraphicsTextItem : public QGraphicsTextItem
    2. {
    3. Q_OBJECT
    4. public:
    5. GraphicsTextItem(const QString & text, QGraphicsItem * parent = 0, QGraphicsScene * scene = 0 );
    6. virtual QSize sizeHint() const{return szHint;}
    7. virtual QSize minimumSizeHint() const{return minSzHint;}
    8. QRectF boundingRect() const;
    9. void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    10. private:
    11. QSize szHint, minSzHint;
    12. QString m_text;
    13. };
    14.  
    15. GraphicsTextItem::GraphicsTextItem(const QString & text, QGraphicsItem * parent , QGraphicsScene * scene )
    16. :QGraphicsTextItem( text,parent,scene )
    17. {
    18. szHint = QSize(10,10);
    19. minSzHint = QSize(10, 10);
    20. adjustSize ();
    21. m_text = text;
    22. }
    23.  
    24. QRectF GraphicsTextItem::boundingRect() const
    25. {
    26. qreal penWidth = 1;
    27. return QRectF(4 - penWidth / 2, 0 - penWidth / 2,
    28. 30 + penWidth / 2, PIN_HEIGHT + penWidth / 2);
    29. }
    30.  
    31. void GraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    32. QWidget *widget)
    33. {
    34. painter->drawRect(boundingRect());
    35. painter->drawText(boundingRect(),Qt::AlignCenter,m_text.left(5));
    36. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How draw a rotated text in a QPainterPath?

    Thank you rajesh for the reply.
    For now I can use your suggestion.

    Anyway my full problem is how to draw a text in a rotated rectangle with QPainterPath.
    The idea is that I don't want to rotate all the QGraphicsItem, but I want to draw a rotated text inside a path with other elements in it. The result will go inside a QGraphicsPathItem.
    May be there is a better way to obtain this effect.

    Example:
    Qt Code:
    1. QPainterPath path(0, 0);
    2. path.lineTo(10, 0); // Horizontal line
    3. path.lineTo(20, 10); // 45° line
    4. path.addText(QPointF(20,10), m_font, "Hello");
    To copy to clipboard, switch view to plain text mode 

    The last line should specify the rectangle (= text size) in which to draw the text and the angle (in this example 45°), so that the text fits the rectangle and follows the previous line direction.
    Last edited by iw2nhl; 15th August 2007 at 03:41.

  4. #4
    Join Date
    Jan 2007
    Posts
    68
    Thanks
    9
    Thanked 8 Times in 8 Posts

    Default Re: How draw a rotated text in a QPainterPath?

    don't know exactly, coz i've not yet worked with QPainterPath,

    but you should take a look @ the QMatrix class

    you could do something like:

    Qt Code:
    1. QMatrix mat;
    2. mat.rotate(myAngle);
    To copy to clipboard, switch view to plain text mode 

    and then you should use
    Qt Code:
    1. //QPainterPath map ( const QPainterPath & path ) const
    2. //e.g.:
    3. QPainterPath newPath = mat.map(oldPath);
    To copy to clipboard, switch view to plain text mode 

    this shold get the job done, I think

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

    iw2nhl (16th August 2007)

  6. #5
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Thumbs up Re: How draw a rotated text in a QPainterPath?

    Thank you very much darksaga!!!
    This was exactly what I was looking for!

    Now the rotated rectangle is no more a problem.
    Probably I can use the same way to make the text fit the rectangle: I could draw a text in a generic size (say 10 pts), than I can scale it's painter path in both x and y to fill the rectangle.
    I'll post if it works or not :-)

  7. #6
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How draw a rotated text in a QPainterPath?

    Thank you again because I solved the other problem too, in fact I could scale and rotate the text perfectly!
    I just draw the text with the default size and then I scale it depending on the rectangle size.

    Just I changed the rectangle mapping from a QPainterPath to a QPolygonF, because I think it is faster (QPainterPath handles curves too, while QPolygonF handles just points). I converted it to a QPainterPath after the mapping.

    Here is the code (may be it can be useful to someone else):
    Qt Code:
    1. {
    2. // Rectangle mapping
    3.  
    4. QLineF rectBase = QLineF(begin, end);
    5. qreal angle = rectBase.angle(QLineF(QPointF(0, 0), QPointF(1, 0)));
    6. QMatrix rotationMatrix;
    7. rotationMatrix.translate(begin.x(), begin.y());
    8. rotationMatrix.rotate(angle);
    9. path.addPolygon(rotationMatrix.map(QPolygonF(textRectangle)));
    10.  
    11. // Text mapping
    12.  
    13. QFont font = QFont("courier");
    14. // Take text size
    15. QFontMetricsF fm(font);
    16. QSizeF textSize = fm.size(0, text);
    17. // Calculate how much to scale the text to fit the rectangle
    18. qreal scaleX = textRectangle.width() / textSize.width();
    19. qreal scaleY = textRectangle.height() / textSize.height();
    20. // Apply the scale factors
    21. rotationMatrix.scale(scaleX, -scaleY);
    22. // Draw the text
    23. QPainterPath textPath;
    24. textPath.addText(QPointF(0, -fm.descent()), font, text);
    25. path.addPath(rotationMatrix.map(textPath));
    26. }
    To copy to clipboard, switch view to plain text mode 

  8. #7
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How draw a rotated text in a QPainterPath?

    I also added a little border to not have the text touching the rectangle:
    Qt Code:
    1. {
    2. // [...]
    3.  
    4. // Leave a 1 pixel wide border around the text
    5. const qreal borderSize = 1;
    6. const qreal doubleBorder = borderSize * 2;
    7. // Calculate how much to scale the text to fit the rectangle
    8. qreal scaleX = textRectangle.width() / (textSize.width() + doubleBorder);
    9. qreal scaleY = textRectangle.height() / (textSize.height() + doubleBorder);
    10. // Apply the scale factors
    11. rotationMatrix.scale(scaleX, -scaleY);
    12. // Center the text (because of the border)
    13. qreal offsetX = borderSize;
    14. qreal offsetY = borderSize;
    15. // Draw the text
    16. QPainterPath textPath;
    17. textPath.addText(QPointF(offsetX, -(offsetY + fm.descent())), font, text);
    18.  
    19. // [...]
    20. }
    To copy to clipboard, switch view to plain text mode 

    Now I have troubles in getting exact font size because QFontMetricsF seems to be very inaccurate and often the text goes outside the rectangle because it is bigger than what is reported.
    Probably I'll make another post for this problem , anyway I think it is not easily solvable (Qt or X11 or KDE Bug?).

Similar Threads

  1. Unhandled exception in qatomic
    By NewGuy in forum Qt Programming
    Replies: 14
    Last Post: 23rd July 2013, 09:49

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.