QTextDocument to PDF with watermarks and header/footer -> filesize too large?
-
Hi all
I try to create a PDF from a QTextDocument that contains long QTextTable (resulting in a PDF with 100+ pages).
When I just print the QTextDocument with
QTextDocument::print(QPagedPaintDevice *printer)
a PDF with for example 134 pages has about 1MB, which I think is not too bad.But when I try to put a footer and a watermark to each page, it results in a PDF that has about 30MB.
Code used to generate the pages:void MyProject::paintPage(QPrinter &printer, int pageNumber, int pageCount, QPainter* painter, QTextDocument* doc, const QRectF& textRect, qreal footerHeight) { //qDebug() << "Printing page" << pageNumber; const QSizeF pageSize = printer.paperRect().size(); //qDebug() << "pageSize=" << pageSize; QFont foo; foo.setPointSize(50); const double bm = mmToPixels(printer, 10); const QRectF borderRect(bm, bm, pageSize.width() - 2 * bm, pageSize.height() - 2 * bm); // painter->drawRect(borderRect); float wa = -qRadiansToDegrees(atan2(borderRect.height(),borderRect.width())); paintWatermark(*painter," - - D R A F T - - ",borderRect.width()/2,borderRect.height()/2,wa,foo); painter->save(); painter->setRenderHint(QPainter::TextAntialiasing,true); painter->setRenderHint(QPainter::HighQualityAntialiasing,false); qDebug() << painter->renderHints(); // textPageRect is the rectangle in the coordinate system of the QTextDocument, in pixels, // and starting at (0,0) for the first page. Second page is at y=doc->pageSize().height(). const QRectF textPageRect(0, pageNumber * doc->pageSize().height(), doc->pageSize().width(), doc->pageSize().height()); // Clip the drawing so that the text of the other pages doesn't appear in the margins painter->setClipRect(textRect); // Translate so that 0,0 is now the page corner painter->translate(0, -textPageRect.top()); // Translate so that 0,0 is the text rect corner painter->translate(textRect.left(), textRect.top()); doc->drawContents(painter); painter->restore(); // Footer: page number or "end" QRectF footerRect = textRect; footerRect.setTop(textRect.bottom()); footerRect.setHeight(footerHeight); painter->drawLine(footerRect.left(),footerRect.top(),footerRect.right(),footerRect.top()); painter->drawText(footerRect, Qt::AlignVCenter | Qt::AlignRight, QObject::tr("Page %1/%2").arg(pageNumber+1).arg(pageCount)); } void MyProject::printDocument(QPrinter &printer, QTextDocument* doc, QWidget* parentWidget) { QPainter painter( &printer ); QSizeF pageSize = printer.pageRect().size(); // page size in pixels // Calculate the rectangle where to lay out the text double tm = mmToPixels(printer, 12); qreal footerHeight = painter.fontMetrics().height(); QRectF textRect(tm, tm, pageSize.width() - 2 * tm, pageSize.height() - 2 * tm - footerHeight); //qDebug() << "textRect=" << textRect; doc->setPageSize(textRect.size()); const int pageCount = doc->pageCount(); QProgressDialog dialog( QObject::tr( "Printing" ), QObject::tr( "Cancel" ), 0, pageCount, parentWidget ); dialog.setWindowModality( Qt::ApplicationModal ); bool firstPage = true; for (int pageIndex = 0; pageIndex < pageCount; ++pageIndex) { dialog.setValue( pageIndex); dialog.setLabelText(tr("Page %1 / %2").arg(pageIndex).arg(pageCount)); if (dialog.wasCanceled()) break; if (!firstPage) printer.newPage(); paintPage( printer, pageIndex, pageCount, &painter, doc, textRect, footerHeight ); firstPage = false; } } void MyProject::paintWatermark(QPainter &p, QString wm, int x, int y, float a, QFont font) { p.save(); p.setFont(font); font.setWeight(QFont::Bold); p.translate(x,y); p.rotate(a); p.setPen(Qt::lightGray); p.setOpacity(0.3); p.drawText(-p.fontMetrics().width(wm)/2,p.fontMetrics().height()/2,wm); // p.resetTransform(); // p.setOpacity(1); p.restore(); } /* the printer is defined as QPrinter p; p.setOutputFileName("/tmp/test.pdf"); p.setOutputFormat(QPrinter::PdfFormat); p.setPageSize(QPrinter::A4); p.setOrientation(QPrinter::Portrait); p.setResolution(96); printDocument(p,&doc,this); */
What am I doing wrong here?
-
I think i just solved the problem myself.
adding a clipping rect to
QTextDocument::drawContents()
makes the resulting PDF much smaller (1.1MB for 134 pages)sorry for the noise
-
Seems that drawContents() always draws the full QTextDocument to the given painter if you miss the second parameter. So in my case it was drawing 134 times 134 pages to the PDF :)