From 3cec2ccb0ffdd41a41ab55d4c1ba88d4866e71d1 Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Mon, 22 Jan 2018 15:49:16 +0100
Subject: [PATCH] Use correct margins when printing with QPrinter
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Margins were applied two times: PrintViewManagerQt included them when
rendering to a temporary PDF, then QPrinter applied them when printing.

This patch changes the parameters of PDF generation to not contain the
area of margins. This way the user-provided QPrinter can handle it
without any kind of customization.

Task-number: QTBUG-65715
Change-Id: Ie32785857e5195aa21c6e2ccb7ebd1e6f6ecd954
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
---
 src/core/print_view_manager_qt.cpp          | 40 +++++++++++++--------
 src/webenginewidgets/api/qwebenginepage.cpp |  7 ++--
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp
index b8df5a131..7c482b012 100644
--- a/src/core/print_view_manager_qt.cpp
+++ b/src/core/print_view_manager_qt.cpp
@@ -154,27 +154,37 @@ static base::DictionaryValue *createPrintSettings()
     return printSettings;
 }
 
-static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout)
+static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout, bool printToPdf)
 {
     base::DictionaryValue *printSettings = createPrintSettings();
 
     //Set page size attributes, chromium expects these in micrometers
-    QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter);
+    QRectF pageSizeInMillimeter = pageLayout.pageSize().rect(QPageSize::Millimeter);
+    if (!printToPdf) {
+        // QPrinter will extend this size with its margins
+        QMarginsF margins = pageLayout.margins(QPageLayout::Millimeter);
+        pageSizeInMillimeter = pageSizeInMillimeter.marginsRemoved(margins);
+    }
     std::unique_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue);
-    sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter);
-    sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter);
+    sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMillimeter.width() * kMicronsToMillimeter);
+    sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMillimeter.height() * kMicronsToMillimeter);
     printSettings->Set(printing::kSettingMediaSize, std::move(sizeDict));
 
-    // Apply page margins
-    QMargins pageMarginsInPoints = pageLayout.marginsPoints();
-    std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue);
-    marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top());
-    marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
-    marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left());
-    marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
-
-    printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict));
-    printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS);
+    if (printToPdf) {
+        // Apply page margins when printing to PDF
+        QMargins pageMarginsInPoints = pageLayout.marginsPoints();
+        std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue);
+        marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top());
+        marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
+        marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left());
+        marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
+
+        printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict));
+        printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS);
+    } else {
+        // QPrinter will handle margins
+        printSettings->SetInteger(printing::kSettingMarginsType, printing::NO_MARGINS);
+    }
 
     printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
 
@@ -244,7 +254,7 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool
     if (!pageLayout.isValid())
         return false;
 
-    m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout));
+    m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, !m_pdfOutputPath.empty()));
     m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds
         , web_contents()->GetRenderViewHost()->GetWebkitPreferences().should_print_backgrounds);
     m_printSettings->SetInteger(printing::kSettingColor,
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 438e3ea24..3f585cf78 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -106,8 +106,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer)
         return false;
     }
 
-    QRect printerPageRect = printer.pageRect();
-    PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), printerPageRect.size());
+    QSize pageSize = printer.pageRect().size();
+    PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), pageSize);
 
     int toPage = printer.toPage();
     int fromPage = printer.fromPage();
@@ -155,7 +155,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer)
                 if (currentImage.isNull())
                     return false;
 
-                painter.drawImage(printerPageRect, currentImage, currentImage.rect());
+                // Painting operations are automatically clipped to the bounds of the drawable part of the page.
+                painter.drawImage(QRect(0, 0, pageSize.width(), pageSize.height()), currentImage, currentImage.rect());
                 if (printedPages < pageCopies - 1)
                     printer.newPage();
             }
-- 
GitLab