QTextDocument::drawContents only renders at 96 dpi
Asked Answered
G

1

10

I am creating a high-resolution (1200 dpi) PDF document using QPrinter and QPainter. I am trying to draw text at the same resolution using QTextDocument::drawContents. The reason I want to use QTextDocument is because I need to include many tables and formatted text in my document.

My problem is that QTextDocument::drawContents always inserts the text at the screen resolution, which is 96 dpi in my case. All the solutions I have found thus far suggest scaling the text to achieve the correct size. However, this results in low quality text, which I cannot afford.

My question: Is there any way to draw the contents of a QTextDocument at a high resolution?

The code below creates a PDF file with 2 lines of text, one drawn using QPainter::drawText and one drawn using QTextDocument::drawContents. I have used an Arial 8pt font in order to emphasize the problem of the low quality resulting from the scaling.

// Read the screen resolution for scaling
QPrinter screenPrinter(QPrinter::ScreenResolution);
int screenResolution = screenPrinter.resolution();

// Setup the font
QFont font;
font.setFamily("Arial");
font.setPointSize(8);

// Define locations to insert text
QPoint textLocation1(20,10);
QPoint textLocation2(20,20);

// Define printer properties
QPrinter printer(QPrinter::HighResolution); 
printer.setOrientation(QPrinter::Portrait);
printer.setPaperSize(QPrinter::A4);
printer.setResolution(1200);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("test.pdf");    

// Write text using QPainter::drawText
QPainter painter;
painter.begin(&printer);
painter.setFont(font);
painter.drawText(textLocation1, "QPainter::drawText");

// Write text using QTextDocument::drawContents
QTextDocument doc;
doc.setPageSize(printer.pageRect().size());
QTextCursor cursor(&doc);
QTextCharFormat charFormat;
charFormat.setFont(font);
cursor.insertText("QTextDocument::drawContents", charFormat);
painter.save();
painter.translate(textLocation2);
painter.scale(printer.resolution()/screenResolution, printer.resolution()/screenResolution);
doc.drawContents(&painter);
painter.restore();
painter.end();
Geyer answered 24/4, 2012 at 14:6 Comment(3)
The problem doesn't seem to show with a pdf output, because the text is not stored rasterized in the PDF file with either method (QPainter treats text differently, even when you rotate or rescale it). Is there some options to change in adobe reader to reproduce the low quality problem ?Policyholder
I used Foxit Reader (with default settings) to open the created PDF file. I am running the code on a Windows environment and using Qt 4.7.1, in case these make a difference. I am actually surprised that the difference does not show on Adobe Reader.Geyer
It is really the fact that a scale transformation is required that tells me that the text is being drawn at 96 dpi. See what happens when the scale transformation is omitted and/or when the parameter passed to the constructor of the second QPrinter object is changed to QPrinter::ScreenResolution.Geyer
P
9

The QTextDocument use its own paint device for the layout which is by default at screen resolution.
You can change it with:

doc.documentLayout()->setPaintDevice(&printer);
// just before
doc.setPageSize(printer.pageRect().size());
Policyholder answered 24/4, 2012 at 23:0 Comment(1)
when I wanted to use doc.documentLayout()->setPaintDevice(&printer); before setting page size, the program crashes, eventhough I initialized printer and docLafollette

© 2022 - 2024 — McMap. All rights reserved.