Multi-threaded text layout and printing

I just integrated a series of changes that adds support for doing multi-threaded text layout and printing. So it is now safe to use QFont and QFontMetrics outside the GUI thread. This means QPainter::drawText() works too (when painting on QImage, QPrinter, and QPicture). We've also done changes to QTextDocument that allow it to be cloned and passed off to a thread, so that all the layouting and printing happens without blocking the GUI.

For those interested, you can checkout tonight's 4.4 snapshot. In tools/assistant/mainwindow.cpp, you'll see code like this:

void PrintThread::start(QTextDocument *document)
{
_document = document->clone();
_document->moveToThread(this);
QThread::start();
}

void PrintThread::run()
{
_document->print(printer());
delete _document;
_document = 0;
}

void MainWindow::on_actionFilePrint_triggered()
{
if (!QFontDatabase::supportsThreadedFontRendering()) {
QPrinter printer(QPrinter::HighResolution);
printer.setFullPage(true);

QPrintDialog dlg(&printer, this);
if (dlg.exec() == QDialog::Accepted) {
qApp->setOverrideCursor(Qt::WaitCursor);
tabs->currentBrowser()->document()->print(&printer);
qApp->restoreOverrideCursor();
}
return;
}

PrintThread *thread = new PrintThread(this);

QPrintDialog dlg(thread->printer(), this);
if (dlg.exec() == QDialog::Accepted) {
connect(thread, SIGNAL(finished()), SLOT(printingFinished()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

qApp->setOverrideCursor(Qt::BusyCursor);
thread->start(tabs->currentBrowser()->document());
} else {
delete thread;
}
}

void MainWindow::printingFinished()
{
qApp->restoreOverrideCursor();
}

The Thread Support in Qt documentation has also been updated to show what is supported (Note, at the time of writing, the snapshot documentation has not been updated, check back later if you don't have a 4.4 snapshot after 27 Sep 2007).

And just to be clear, painting onto a QPixmap or a QWidget outside the GUI is not supported at all. We are looking at ways of making the GL paint engine safe for painting on to FrameBufferObjects and/or Pbuffers, which may or may not make it into 4.4.


Blog Topics:

Comments