diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp --- a/generators/poppler/generator_pdf.cpp +++ b/generators/poppler/generator_pdf.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,13 @@ Q_OBJECT public: + + enum PrintBackend { + CUPSBackend, + QPrinterBackend + }; + Q_ENUM(PrintBackend) + PDFOptionsPage() { setWindowTitle( i18n( "PDF Options" ) ); @@ -87,11 +95,38 @@ 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, i18n("CUPS"), CUPSBackend); + m_printBackend->setItemData(CUPSBackend, xi18n("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::ToolTipRole); + m_printBackend->setItemData(CUPSBackend, xi18n("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 + + // Print 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. In fact, 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. + // On the positive side, QPrinter printing allows more printing options. +#if defined(Q_OS_WIN) || HAVE_POPPLER_0_60 + m_printBackend->insertItem(QPrinterBackend, i18n("QPrinter (experimental)"), QPrinterBackend); + m_printBackend->setItemData(QPrinterBackend, i18n("Print with Qt (experimental, you may see rendering artifacts)"), Qt::ToolTipRole); +#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 } @@ -115,9 +150,16 @@ m_forceRaster->setChecked( forceRaster ); } + PrintBackend printBackend() const + { + return m_printBackend->currentData().value(); + } + + private: QCheckBox *m_printAnnots; QCheckBox *m_forceRaster; + QComboBox *m_printBackend; }; @@ -1269,32 +1311,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); @@ -1311,6 +1346,8 @@ Poppler::Page *pp = pdfdoc->page( page ); if (pp) { + if ( forceRasterize ) + { #ifdef Q_OS_WIN QImage img = pp->renderToImage( printer.physicalDpiX(), printer.physicalDpiY() ); #else @@ -1318,6 +1355,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();