Index: generators/poppler/generator_pdf.cpp =================================================================== --- generators/poppler/generator_pdf.cpp +++ generators/poppler/generator_pdf.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,13 @@ Q_OBJECT public: + + enum PrintBackend { + CUPSBackend, + QPrinterBackend + }; + Q_ENUM(PrintBackend) + PDFOptionsPage() { setWindowTitle( i18n( "PDF Options" ) ); @@ -83,11 +91,35 @@ m_forceRaster->setToolTip(i18n("Rasterize into an image before printing")); m_forceRaster->setWhatsThis(i18n("Forces the rasterization of each page into an image before printing it. This usually gives somewhat worse results, but is useful when printing documents that appear to print incorrectly.")); layout->addWidget(m_forceRaster); + + m_printBackend = new QComboBox; + // Windows can only print with the QPrinter backend, because the CUPS backend + // is UNIX-specific. +#if !defined(Q_OS_WIN) + m_printBackend->insertItem(CUPSBackend, "CUPS", CUPSBackend); + m_printBackend->setItemData(CUPSBackend, i18n("Print with CUPS"), Qt::ToolTipRole); + m_printBackend->setItemData(CUPSBackend, i18n("Print using the CUPS printing system. This will convert your pdf file to postscript first, and then send the postscript file to the printer."), Qt::WhatsThisRole); +#endif + // Printing with a QPrinter without rasterization uses the poppler Arthur backend. + // The backend is so bad before poppler 0.60 that we'd rather not expose the QPrinter + // option at all for older poppler versions. On Windows we have no choice, because + // there the CUPS backend will not work. +#if defined(Q_OS_WIN) || HAVE_POPPLER_0_60 + m_printBackend->insertItem(QPrinterBackend, "QPrinter (experimental)", QPrinterBackend); + m_printBackend->setItemData(QPrinterBackend, i18n("Print with Qt (experimental, you may see rendering artifacts)"), Qt::ToolTipRole); + m_printBackend->setItemData(QPrinterBackend, i18n("Print by using the platform-independent Qt infrastructure. By necessity, this uses a backend of the Poppler pdf library which is called 'Arthur'. This Arthur backend is still somewhat immature, and you may see misrenderings of your pdf document. On the positive side, QPrinter printing allows more printing options."), Qt::WhatsThisRole); +#endif + QWidget* formWidget = new QWidget(this); + QFormLayout *printBackendLayout = new QFormLayout(formWidget); + printBackendLayout->addRow(i18n("Print backend"), m_printBackend); + layout->addWidget(formWidget); + layout->addStretch(1); #if defined(Q_OS_WIN) && !defined HAVE_POPPLER_0_60 m_printAnnots->setVisible( false ); #endif + setPrintAnnots( true ); // Default value } @@ -111,9 +143,16 @@ m_forceRaster->setChecked( forceRaster ); } + PrintBackend printBackend() const + { + return m_printBackend->currentData().value(); + } + + private: QCheckBox *m_printAnnots; QCheckBox *m_forceRaster; + QComboBox *m_printBackend; }; @@ -1068,32 +1107,25 @@ { bool printAnnots = true; bool forceRasterize = false; + PDFOptionsPage::PrintBackend printBackend = PDFOptionsPage::CUPSBackend; if ( pdfOptionsPage ) { printAnnots = pdfOptionsPage->printAnnots(); forceRasterize = pdfOptionsPage->printForceRaster(); + printBackend = pdfOptionsPage->printBackend(); } -#ifdef Q_OS_WIN - // Windows can only print by rasterization, because that is - // currently the only way Okular implements printing without using UNIX-specific - // tools like 'lpr'. - forceRasterize = true; -#ifndef HAVE_POPPLER_0_60 - // The Document::HideAnnotations flags was introduced in poppler 0.60 - printAnnots = true; -#endif -#endif - -#ifdef HAVE_POPPLER_0_60 - if ( forceRasterize ) - { - pdfdoc->setRenderHint(Poppler::Document::HideAnnotations, !printAnnots); -#else - if ( forceRasterize && printAnnots) + if ( printBackend==PDFOptionsPage::QPrinterBackend ) { +#ifdef HAVE_POPPLER_0_60 + // The Document::HideAnnotations flags was introduced in poppler 0.60 + pdfdoc->setRenderHint( Poppler::Document::HideAnnotations, !printAnnots ); #endif + + // Scale to the entire page, not only the printable area + printer.setFullPage( true ); + QPainter painter; painter.begin(&printer); @@ -1110,6 +1142,8 @@ Poppler::Page *pp = pdfdoc->page( page ); if (pp) { + if ( forceRasterize ) + { #ifdef Q_OS_WIN QImage img = pp->renderToImage( printer.physicalDpiX(), printer.physicalDpiY() ); #else @@ -1117,6 +1151,16 @@ QImage img = pp->renderToImage( 300, 300 ); #endif painter.drawImage( painter.window(), img, QRectF(0, 0, img.width(), img.height()) ); + } else { + // temporarily switch to poppler's Arthur backend. + // It is the only one that implements renderToPainter. + auto actualRenderBackend = pdfdoc->renderBackend(); + pdfdoc->setRenderBackend( Poppler::Document::ArthurBackend ); + + pp->renderToPainter( &painter, printer.logicalDpiX(), printer.logicalDpiY() ); + + pdfdoc->setRenderBackend( actualRenderBackend ); + } delete pp; } userMutex()->unlock();