David Burson David Burson - 3 months ago 23
C++ Question

QPainterPath text renders wrong when printing

With Qt 5.4.2, I'm using a

QPainterPath
to render text, since the text may be split into characters and each character rendered along a curve. I see different results across platforms and when I print. To render the text, I've tried using
QPainter
's
drawPath()
and
drawPolygon()
methods.

OS X 10.11.6:


  • drawPath
    : top line in Indic text has gaps that should not be there, both in a
    QGraphicsView
    and when I print.

  • drawPolygon
    : the top line is solid as it should be, both in a
    QGraphicsView
    and when I print. However, when printed, I get lots of extra fine lines between various random points in the text.



Window 7:


  • drawPath
    : same as on the Mac: there are gaps in top line, both the
    QGraphicsView
    and when I print.

  • drawPolygon
    : the
    QGraphicsView
    is correct (no gaps), but printing still has the gaps in the top line, though it does not have the extra fine lines as when printed on the Mac. So printing with
    drawPolygon
    produces identical incorrect output as printing with
    drawPath
    .



Here's a sample app that demonstrates these issues. Here's the paint code from my
QGraphicsItem
subclass in my sample app:

void MapGraphicsTextElement::paint(QPainter *painter,
const QStyleOptionGraphicsItem * /*option*/,
QWidget * /*widget*/) {

painter->setFont(font_);
painter->setRenderHint(QPainter::Antialiasing);
painter->setBrush(QBrush(QColor(Qt::black)));
painter->setPen(Qt::NoPen);

QPainterPath path;
path.addText(0, 0, font_, text_);

if (fix_gaps_) {
QPolygonF poly = path.toFillPolygon();
painter->drawPolygon(poly, Qt::WindingFill);
} else {
painter->drawPath(path);
}
}


Here's the code from the sample app that creates the scene and adds two of my
QGraphicsItem
subclass objects to the scene:

QGraphicsScene * PrintsLines::CreateScene()
{
QGraphicsScene *scene = new QGraphicsScene(0, 0, 500, 500, this);

QScopedPointer<MapGraphicsTextElement> item(new MapGraphicsTextElement());

item->SetText("My test text here.");
item->SetFixGaps(fix_gaps_->isChecked());
QFont item_font("Arial");
item_font.setPixelSize(12);
item->SetFont(item_font);
item->setPos(128, 115);
scene->addItem(item.take());

QScopedPointer<MapGraphicsTextElement> item2(new MapGraphicsTextElement());

item2->SetText("मेदितेरेनियन सि");
item2->SetFixGaps(fix_gaps_->isChecked());
QFont item_font2("Arial");
item_font2.setPixelSize(48);
item2->SetFont(item_font2);
item2->setPos(128, 215);
scene->addItem(item2.take());

return scene;
}


How can I make what is rendered in a
QGraphicsView
and is printed are identical and correct? If different solutions are required for OS X and Windows, that's ok. Or if a newer version of Qt is required to solve this, I could upgrade Qt.

UPDATE:

As Kuba Ober suggested, I have demonstrated the printing bugs with this simple app below. I'm not sure how to proceed from here.

#include <QApplication>

#include <QtGui/QPainter>
#include <QtGui/QPainterPath>
#include <QtGui/QFont>
#include <QtPrintSupport/QPrintDialog>
#include <QtPrintSupport/QPrinter>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QPrinter *printer = new QPrinter();
QPrintDialog dialog(printer);
if (dialog.exec() == QDialog::Accepted) {
QFont font("Arial");
font.setPointSize(48);

QPainter painter(printer);
painter.setFont(font);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(QColor(Qt::black)));
painter.setPen(Qt::NoPen);

// drawPath()
QPainterPath path_drawPath;
path_drawPath.addText(100, 200, font, "मेदितेरेनियन सि");
painter.drawPath(path_drawPath);

// drawPolygon()
QPainterPath path_drawPoly;
path_drawPoly.addText(100, 300, font, "मेदितेरेनियन सि");
QPolygonF poly = path_drawPoly.toFillPolygon();
painter.drawPolygon(poly, Qt::WindingFill);
}

return 0;
}

Answer

painter.drawText() is working for printing and for creating pdf's. painter.drawPolygon() is working for on-screen rendering and outputting raster images (png & jpg). This workaround appears to be sufficient to solve my problem.

Comments