PDF: Implement scaling options for non-rasterized printing

Summary:
This adds another 'FilePrinter::printFile' method that
accepts an additional parameter to specify whether or not to
do scaling and passes the 'fit-to-page' to CUPS dependent
on what is specified.

If FilePrinter is used, The PDF generator now passes this
option depending on the scaling mode that was selected in the
custom print options widget, which is therefore now enabled
for non-rasterized printing as well.

Test Plan:
1) open a PDF document in Okular and open the print dialog
2) go to the "PDF Options" tab
3) verify that "Force rasterisation" is disabled, but the
  "Scale mode" combobox is active.
4) test all the three options available in the "Scale mode"
   combobox do what they say
5) Make sure the three options still work as expected for
   the "Force rasterisation" case.

Reviewers: #okular, ngraham, sander

Reviewed By: ngraham

Subscribers: aacid, fvogt, okular-devel

Tags: #okular

Differential Revision: https://phabricator.kde.org/D18179
This commit is contained in:
Michael Weghorn 2019-04-14 21:08:59 -06:00 committed by Nate Graham
parent aa3813abf6
commit 748884b4c7
3 changed files with 107 additions and 29 deletions

View file

@ -34,16 +34,33 @@ using namespace Okular;
int FilePrinter::printFile( QPrinter &printer, const QString file,
QPrinter::Orientation documentOrientation, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, const QString &pageRange )
{
return printFile( printer, file, documentOrientation, fileDeletePolicy,
pageSelectPolicy, pageRange, ScaleMode::FitToPrintArea );
}
int FilePrinter::printFile( QPrinter &printer, const QString file,
QPrinter::Orientation documentOrientation,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
const QString &pageRange, ScaleMode scaleMode )
{
FilePrinter fp;
return fp.doPrintFiles( printer, QStringList( file ), fileDeletePolicy, pageSelectPolicy, pageRange,
documentOrientation );
return fp.doPrintFiles( printer, QStringList( file ), fileDeletePolicy, pageSelectPolicy, pageRange,
documentOrientation, scaleMode );
}
int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, const QString &pageRange,
QPrinter::Orientation documentOrientation )
{
return doPrintFiles( printer, fileList, fileDeletePolicy, pageSelectPolicy, pageRange,
documentOrientation, ScaleMode::FitToPrintArea );
}
int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, const QString &pageRange,
QPrinter::Orientation documentOrientation, ScaleMode scaleMode )
{
if ( fileList.size() < 1 ) {
return -8;
@ -130,7 +147,7 @@ int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDele
bool useCupsOptions = cupsAvailable();
argList = printArguments( printer, fileDeletePolicy, pageSelectPolicy,
useCupsOptions, pageRange, exe, documentOrientation ) << fileList;
useCupsOptions, pageRange, exe, documentOrientation, scaleMode ) << fileList;
qCDebug(OkularCoreDebug) << "Executing" << exe << "with arguments" << argList;
ret = KProcess::execute( exe, argList );
@ -319,12 +336,19 @@ Generator::PrintError FilePrinter::printError( int c )
return pe;
}
QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, bool useCupsOptions,
const QString &pageRange, const QString &version,
QPrinter::Orientation documentOrientation ) {
return printArguments( printer, fileDeletePolicy, pageSelectPolicy, useCupsOptions,
pageRange, version, documentOrientation, ScaleMode::FitToPrintArea);
}
QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, bool useCupsOptions,
const QString &pageRange, const QString &version,
QPrinter::Orientation documentOrientation )
QPrinter::Orientation documentOrientation, ScaleMode scaleMode )
{
QStringList argList;
@ -344,8 +368,8 @@ QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fil
argList << pages( printer, pageSelectPolicy, pageRange, useCupsOptions, version );
}
if ( useCupsOptions && ! cupsOptions( printer, documentOrientation ).isEmpty() ) {
argList << cupsOptions( printer, documentOrientation);
if ( useCupsOptions && ! cupsOptions( printer, documentOrientation, scaleMode ).isEmpty() ) {
argList << cupsOptions( printer, documentOrientation, scaleMode);
}
if ( ! deleteFile( printer, fileDeletePolicy, version ).isEmpty() ) {
@ -450,6 +474,11 @@ QStringList FilePrinter::pages( QPrinter &printer, PageSelectPolicy pageSelectPo
}
QStringList FilePrinter::cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation )
{
return cupsOptions( printer, documentOrientation, ScaleMode::FitToPrintArea );
}
QStringList FilePrinter::cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation, ScaleMode scaleMode )
{
QStringList optionList;
@ -473,8 +502,8 @@ QStringList FilePrinter::cupsOptions( QPrinter &printer, QPrinter::Orientation d
optionList << optionCollateCopies( printer );
}
if ( ! optionPageMargins( printer ).isEmpty() ) {
optionList << optionPageMargins( printer );
if ( ! optionPageMargins( printer, scaleMode ).isEmpty() ) {
optionList << optionPageMargins( printer, scaleMode );
}
optionList << optionCupsProperties( printer );
@ -611,6 +640,11 @@ QStringList FilePrinter::optionCollateCopies( QPrinter &printer )
}
QStringList FilePrinter::optionPageMargins( QPrinter &printer )
{
return optionPageMargins( printer, ScaleMode::FitToPrintArea );
}
QStringList FilePrinter::optionPageMargins( QPrinter &printer, ScaleMode scaleMode )
{
if (printer.printEngine()->property(QPrintEngine::PPK_PageMargins).isNull()) {
return QStringList();
@ -619,10 +653,16 @@ QStringList FilePrinter::optionPageMargins( QPrinter &printer )
if (!printer.fullPage()) {
printer.getPageMargins( &l, &t, &r, &b, QPrinter::Point );
}
return QStringList(QStringLiteral("-o")) << QStringLiteral("page-left=%1").arg(l)
QStringList marginOptions;
marginOptions << (QStringLiteral("-o")) << QStringLiteral("page-left=%1").arg(l)
<< QStringLiteral("-o") << QStringLiteral("page-top=%1").arg(t)
<< QStringLiteral("-o") << QStringLiteral("page-right=%1").arg(r)
<< QStringLiteral("-o") << QStringLiteral("page-bottom=%1").arg(b) << QStringLiteral("-o") << QStringLiteral("fit-to-page");
<< QStringLiteral("-o") << QStringLiteral("page-bottom=%1").arg(b);
if (scaleMode == ScaleMode::FitToPrintArea) {
marginOptions << QStringLiteral("-o") << QStringLiteral("fit-to-page");
}
return marginOptions;
}
}

View file

@ -48,6 +48,20 @@ public:
*/
enum PageSelectPolicy { ApplicationSelectsPages, SystemSelectsPages };
/** Whether to apply scaling when printing.
*
* 'NoScaling' indicates that no scaling should be applied.
* 'FitToPrintArea' indicates that the document should be scaled to the
* area that is available for printing. Whether or not this includes the printer's
* hardware margins depends on the value of 'QPrinter::fullPage()' for the given printer.
*
* @since 1.8
*/
enum ScaleMode {
NoScaling = 0,
FitToPrintArea = 1
};
/** Print a file using the settings in QPrinter
*
* Only supports CUPS and LPR on *NIX. Page Range only supported in CUPS.
@ -58,6 +72,7 @@ public:
* @param printer the print settings to use
* @param file the file to print
* @param documentOrientation the orientation stored in the document itself
* @param scaleMode scale mode to use
* @param fileDeletePolicy if the application or system deletes the file
* @param pageSelectPolicy if the application or system selects the pages to print
* @param pageRange page range to print if SystemSelectsPages and user chooses Selection in Print Dialog
@ -72,9 +87,24 @@ public:
* -1 if the KProcess crashed
* otherwise the KProcess exit code
*
* @since 1.8
*/
static int printFile( QPrinter &printer, const QString file,
QPrinter::Orientation documentOrientation,
FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy,
const QString &pageRange,
ScaleMode scaleMode
);
/** Print a file using the settings in QPrinter
*
* Same as 'printFile()' with 7 parameters, but always using a 'scaleMode' of
* 'FitToPrintArea'.
*
* @since 0.14 (KDE 4.8)
*/
// TODO merge with function above when a BIC change happens somehwere else
static int printFile( QPrinter &printer, const QString file,
QPrinter::Orientation documentOrientation,
FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles,
@ -156,11 +186,23 @@ protected:
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
const QString &pageRange,
QPrinter::Orientation documentOrientation );
// TODO merge with function above when a BIC change happens somehwere else
/// @since 1.8
int doPrintFiles( QPrinter &printer, const QStringList fileList,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
const QString &pageRange,
QPrinter::Orientation documentOrientation, ScaleMode scaleMode );
QStringList printArguments( QPrinter &printer,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
bool useCupsOptions, const QString &pageRange, const QString &version,
QPrinter::Orientation documentOrientation );
// TODO merge with function above when a BIC change happens somehwere else
/// @since 1.8
QStringList printArguments( QPrinter &printer,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
bool useCupsOptions, const QString &pageRange, const QString &version,
QPrinter::Orientation documentOrientation, ScaleMode scaleMode );
QStringList destination( QPrinter &printer, const QString &version );
QStringList copies( QPrinter &printer, const QString &version );
@ -171,6 +213,9 @@ protected:
const QString &pageRange, bool useCupsOptions, const QString &version );
QStringList cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation );
// TODO merge with function above when a BIC change happens somehwere else
/// @since 1.8
QStringList cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation, ScaleMode scaleMode );
QStringList optionMedia( QPrinter &printer );
QString mediaPageSize( QPrinter &printer );
QString mediaPaperSource( QPrinter &printer );
@ -179,6 +224,9 @@ protected:
QStringList optionPageOrder( QPrinter &printer );
QStringList optionCollateCopies( QPrinter &printer );
QStringList optionPageMargins( QPrinter &printer );
// TODO merge with function above when a BIC change happens somehwere else
/// @since 1.8
QStringList optionPageMargins( QPrinter &printer, ScaleMode scaleMode );
QStringList optionCupsProperties( QPrinter &printer );
};

View file

@ -80,17 +80,6 @@ static const int defaultPageHeight = 842;
class PDFOptionsPage : public Okular::PrintOptionsWidget
{
Q_OBJECT
public slots:
void enableOrDisableScaleMode()
{
m_scaleMode->setEnabled ( m_forceRaster->isChecked() );
if ( m_forceRaster->isChecked() ) {
m_scaleMode->setToolTip( i18n( "Scaling mode for the printed pages" ) );
} else {
m_scaleMode->setToolTip( i18n( "Select rasterization to enable this!" ) );
}
}
public:
enum ScaleMode {
@ -120,18 +109,13 @@ public slots:
m_scaleMode->insertItem(FitToPrintableArea, i18n("Fit to printable area"), FitToPrintableArea);
m_scaleMode->insertItem(FitToPage, i18n("Fit to full page"), FitToPage);
m_scaleMode->insertItem(None, i18n("None; print original size"), None);
m_scaleMode->setToolTip(i18n("Select rasterization to enable this!"));
m_scaleMode->setToolTip(i18n( "Scaling mode for the printed pages" ) );
printBackendLayout->addRow(i18n("Scale mode:"), m_scaleMode);
layout->addWidget(formWidget);
layout->addStretch(1);
// Enable scaleMode only if the file is to be rasterized before printing
m_scaleMode->setEnabled( false );
connect( m_forceRaster, &QCheckBox::stateChanged, this, &PDFOptionsPage::enableOrDisableScaleMode );
#if defined(Q_OS_WIN) && !defined HAVE_POPPLER_0_60
m_printAnnots->setVisible( false );
#endif
@ -1491,11 +1475,17 @@ bool PDFGenerator::print( QPrinter& printer )
userMutex()->unlock();
delete psConverter;
tf.close();
const Okular::FilePrinter::ScaleMode filePrinterScaleMode =
(scaleMode == PDFOptionsPage::None) ? Okular::FilePrinter::ScaleMode::NoScaling : Okular::FilePrinter::ScaleMode::FitToPrintArea;
int ret = Okular::FilePrinter::printFile( printer, tempfilename,
document()->orientation(),
Okular::FilePrinter::SystemDeletesFiles,
Okular::FilePrinter::ApplicationSelectsPages,
document()->bookmarkedPageRange() );
document()->bookmarkedPageRange(),
filePrinterScaleMode
);
lastPrintError = Okular::FilePrinter::printError( ret );