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
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.
Code:
{
Q_OBJECT
public:
virtual QSize sizeHint
() const{return szHint;
} virtual QSize minimumSizeHint
() const{return minSzHint;
} private:
};
{
minSzHint
= QSize(10,
10);
adjustSize ();
m_text = text;
}
QRectF GraphicsTextItem
::boundingRect() const {
qreal penWidth = 1;
return QRectF(4 - penWidth
/ 2,
0 - penWidth
/ 2,
30 + penWidth / 2, PIN_HEIGHT + penWidth / 2);
}
{
painter->drawRect(boundingRect());
painter->drawText(boundingRect(),Qt::AlignCenter,m_text.left(5));
}
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:
Code:
path.lineTo(10, 0); // Horizontal line
path.lineTo(20, 10); // 45° line
path.
addText(QPointF(20,
10), m_font,
"Hello");
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.
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:
Code:
mat.rotate(myAngle);
and then you should use
Code:
//QPainterPath map ( const QPainterPath & path ) const
//e.g.:
this shold get the job done, I think
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 :-)
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):
Code:
{
// Rectangle mapping
rotationMatrix.translate(begin.x(), begin.y());
rotationMatrix.rotate(angle);
path.
addPolygon(rotationMatrix.
map(QPolygonF(textRectangle
)));
// Text mapping
// Take text size
QSizeF textSize
= fm.
size(0, text
);
// Calculate how much to scale the text to fit the rectangle
qreal scaleX = textRectangle.width() / textSize.width();
qreal scaleY = textRectangle.height() / textSize.height();
// Apply the scale factors
rotationMatrix.scale(scaleX, -scaleY);
// Draw the text
textPath.
addText(QPointF(0,
-fm.
descent()), font, text
);
path.addPath(rotationMatrix.map(textPath));
}
Re: How draw a rotated text in a QPainterPath?
I also added a little border to not have the text touching the rectangle:
Code:
{
// [...]
// Leave a 1 pixel wide border around the text
const qreal borderSize = 1;
const qreal doubleBorder = borderSize * 2;
// Calculate how much to scale the text to fit the rectangle
qreal scaleX = textRectangle.width() / (textSize.width() + doubleBorder);
qreal scaleY = textRectangle.height() / (textSize.height() + doubleBorder);
// Apply the scale factors
rotationMatrix.scale(scaleX, -scaleY);
// Center the text (because of the border)
qreal offsetX = borderSize;
qreal offsetY = borderSize;
// Draw the text
textPath.
addText(QPointF(offsetX,
-(offsetY
+ fm.
descent())), font, text
);
// [...]
}
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 :D, anyway I think it is not easily solvable (Qt or X11 or KDE Bug?).