Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Text from QPainter much nicer than from QPainterPath

Tags:

c++

qt

qt5

qpainter

I want to draw text using QPainter, and I want to use QPainterPath first (because ultimately I want to rotate the text in all sorts of ways). However, I find that the text produced by QPainterPath is much uglier than the text produced by QPainter.

The following code:

void MyWidget::paintEvent(QPaintEvent* /*event*/) {

     QFont font;
     font.setStyleHint(QFont::Times, QFont::PreferAntialias);
     font.setPointSize(30);

     QPainter painter;
     painter.begin(this);
     painter.setRenderHint(QPainter::Antialiasing);
     painter.setBrush(Qt::black);
     painter.setFont(font);
     painter.drawText(10, 40, "Hello World");

     QPainterPath textPath;
     textPath.addText(10, 100, font, "Hello world");
     painter.drawPath(textPath);

     painter.end();
}

produces the following result:

enter image description here

The former is clearly much cleaner and nicer, especially in smaller fonts. What should I do to get the same result from QPainterPath?

I'm producing the above results on a Windows 7 computer, with Qt 5.0.

like image 451
Yellow Avatar asked Jul 24 '13 11:07

Yellow


2 Answers

According to the Qt documentation for adding text to a QPainterPath: -

Adds the given text to this path as a set of closed subpaths created from the font supplied.

So there is a conversion going on here, which is why it doesn't look the same. If you need to rotate text, you could try rotating the QPainter before rendering and then restoring it afterwards. Alternatively, if you can use QGraphicsView and QGraphicsDisplay instead of just rendering onto the widget, there is the class QGraphicsTextItem which may help.

But overall, it's the conversion to the set of closed subpaths that is responsible for the different output of text quality.

like image 163
TheDarkKnight Avatar answered Nov 10 '22 20:11

TheDarkKnight


The two fonts don't look the same because you're adding extra contours to you QPainterPath text. The following piece of code should give good results :

QFont font;
font.setStyleHint(QFont::Times, QFont::PreferAntialias);
font.setPointSize(30);

QPainter painter;
painter.begin(this);
painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing);
painter.setFont(font);

// painter text color is modified by setPen()
painter.setPen(Qt::white);
painter.drawText(10, 40, "Hello World 1");

QPainterPath textPath;
textPath.addText(10, 100, font, "Hello World 2");

// painter path text color is modified by setBrush()
painter.setBrush(Qt::white);
// setPen(Qt::white) add extra white contour on text path (what you did)
painter.setPen(Qt::white);
painter.drawPath(textPath);

QPainterPath textPath2;
textPath2.addText(10, 160, font, "Hello World 3");

// painter path text color is modified by setBrush
painter.setBrush(Qt::white);
// setPen(Qt::NoPen) avoid extra contours for QPainter Path
painter.setPen(Qt::NoPen);
painter.drawPath(textPath2);

painter.end();

I admit that QPainterPath text "Hello World 3" is a little bit uglier that QPainterText "Hello World 1", but the result is still better than "Hello World 2"

enter image description here

like image 26
Mehdi-Antoine Avatar answered Nov 10 '22 20:11

Mehdi-Antoine