summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSzabolcs David <davidsz@inf.u-szeged.hu>2019-05-14 17:02:45 +0200
committerSzabolcs David <davidsz@inf.u-szeged.hu>2019-06-04 15:34:48 +0200
commit7f89badd0e1b71dabb5a88d1330b08ce9d8b6eb7 (patch)
treecc4f7d878a60127c535804299d19e3e500d505dd
parent8b848e4aee238edb58dba0ded8d773c8b70392f6 (diff)
Workaround for CSS orientation issues
Web content can define its orientation for printing using the @page rule in CSS. This creates some edge cases, for example when the pages are not uniform and some of them has different orientation than the others. The current version of desktop Chromium can't handle this perfectly: sometimes it renders portrait pages to landscape papers by cutting down the extra parts. This patch makes our result similar to Chromium's - by ignoring the user's orientation settings in QPrinter. Task-number: QTBUG-75092 Change-Id: Ifaea69c94b6ee1b6a83609cb15207a58554975f9 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--src/core/printing/pdfium_document_wrapper_qt.cpp25
-rw-r--r--src/core/printing/pdfium_document_wrapper_qt.h5
-rw-r--r--src/webenginewidgets/printer_worker.cpp40
3 files changed, 45 insertions, 25 deletions
diff --git a/src/core/printing/pdfium_document_wrapper_qt.cpp b/src/core/printing/pdfium_document_wrapper_qt.cpp
index 1be27f1c6..6f415b50b 100644
--- a/src/core/printing/pdfium_document_wrapper_qt.cpp
+++ b/src/core/printing/pdfium_document_wrapper_qt.cpp
@@ -50,11 +50,11 @@ int PdfiumDocumentWrapperQt::m_libraryUsers = 0;
class PdfiumPageWrapperQt {
public:
- PdfiumPageWrapperQt(FPDF_DOCUMENT data, int pageIndex, int targetWidth, int targetHeight)
+ PdfiumPageWrapperQt(FPDF_DOCUMENT data, int pageIndex)
: m_pageData(FPDF_LoadPage(data, pageIndex))
, m_width(FPDF_GetPageWidth(m_pageData))
, m_height(FPDF_GetPageHeight(m_pageData))
- , m_image(createImage(targetWidth, targetHeight))
+ , m_image(createImage())
{
}
@@ -77,16 +77,11 @@ public:
}
private:
- QImage createImage(int targetWidth, int targetHeight)
+ QImage createImage()
{
Q_ASSERT(m_pageData);
- if (targetWidth <= 0)
- targetWidth = m_width;
- if (targetHeight <= 0)
- targetHeight = m_height;
-
- QImage image(targetWidth, targetHeight, QImage::Format_ARGB32);
+ QImage image(m_width * 2, m_height * 2, QImage::Format_ARGB32);
Q_ASSERT(!image.isNull());
image.fill(0xFFFFFFFF);
@@ -112,9 +107,7 @@ private:
PdfiumDocumentWrapperQt::PdfiumDocumentWrapperQt(const void *pdfData, size_t size,
- const QSize& imageSize,
const char *password)
- : m_imageSize(imageSize * 2.0)
{
Q_ASSERT(pdfData);
Q_ASSERT(size);
@@ -137,11 +130,17 @@ QImage PdfiumDocumentWrapperQt::pageAsQImage(size_t index)
return QImage();
}
- PdfiumPageWrapperQt pageWrapper((FPDF_DOCUMENT)m_documentHandle, index,
- m_imageSize.width(), m_imageSize.height());
+ PdfiumPageWrapperQt pageWrapper((FPDF_DOCUMENT)m_documentHandle, index);
return pageWrapper.image();
}
+bool PdfiumDocumentWrapperQt::pageIsLandscape(size_t index)
+{
+ double width = 0, height = 0;
+ FPDF_GetPageSizeByIndex((FPDF_DOCUMENT)m_documentHandle, index, &width, &height);
+ return (width > height);
+}
+
PdfiumDocumentWrapperQt::~PdfiumDocumentWrapperQt()
{
FPDF_CloseDocument((FPDF_DOCUMENT)m_documentHandle);
diff --git a/src/core/printing/pdfium_document_wrapper_qt.h b/src/core/printing/pdfium_document_wrapper_qt.h
index 2dab268fc..121742aa3 100644
--- a/src/core/printing/pdfium_document_wrapper_qt.h
+++ b/src/core/printing/pdfium_document_wrapper_qt.h
@@ -61,17 +61,16 @@ class PdfiumPageWrapperQt;
class Q_WEBENGINECORE_PRIVATE_EXPORT PdfiumDocumentWrapperQt
{
public:
- PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const QSize &imageSize,
- const char *password = nullptr);
+ PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const char *password = nullptr);
virtual ~PdfiumDocumentWrapperQt();
QImage pageAsQImage(size_t index);
+ bool pageIsLandscape(size_t index);
int pageCount() const { return m_pageCount; }
private:
static int m_libraryUsers;
int m_pageCount;
void *m_documentHandle;
- QSize m_imageSize;
};
} // namespace QtWebEngineCore
diff --git a/src/webenginewidgets/printer_worker.cpp b/src/webenginewidgets/printer_worker.cpp
index 3a670ad49..94a862cda 100644
--- a/src/webenginewidgets/printer_worker.cpp
+++ b/src/webenginewidgets/printer_worker.cpp
@@ -65,8 +65,7 @@ void PrinterWorker::print()
return;
}
- QSize pageSize = m_printer->pageRect().size();
- PdfiumDocumentWrapperQt pdfiumWrapper(m_data->constData(), m_data->size(), pageSize);
+ PdfiumDocumentWrapperQt pdfiumWrapper(m_data->constData(), m_data->size());
int toPage = m_printer->toPage();
int fromPage = m_printer->fromPage();
@@ -95,6 +94,10 @@ void PrinterWorker::print()
documentCopies = 1;
}
+ bool isLandscape = pdfiumWrapper.pageIsLandscape(0);
+ QPageLayout::Orientation prevOrientation = m_printer->pageLayout().orientation();
+ m_printer->setPageOrientation(isLandscape ? QPageLayout::Landscape : QPageLayout::Portrait);
+
QPainter painter;
if (!painter.begin(m_printer)) {
qWarning("Failure to print on printer %ls: Could not open printer for painting.",
@@ -104,8 +107,21 @@ void PrinterWorker::print()
}
for (int printedDocuments = 0; printedDocuments < documentCopies; printedDocuments++) {
+ if (printedDocuments > 0)
+ m_printer->newPage();
+
int currentPageIndex = fromPage;
- while (true) {
+
+ for (int i = 0; true; i++) {
+ prevOrientation = m_printer->pageLayout().orientation();
+ isLandscape = pdfiumWrapper.pageIsLandscape(currentPageIndex - 1);
+ m_printer->setPageOrientation(isLandscape ? QPageLayout::Landscape : QPageLayout::Portrait);
+
+ QSize pageSize = m_printer->pageRect().size();
+
+ if (i > 0)
+ m_printer->newPage();
+
for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
if (m_printer->printerState() == QPrinter::Aborted
|| m_printer->printerState() == QPrinter::Error) {
@@ -113,16 +129,24 @@ void PrinterWorker::print()
return;
}
+ if (printedPages > 0)
+ m_printer->newPage();
+
QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1);
if (currentImage.isNull()) {
Q_EMIT resultReady(false);
return;
}
+ QRect targetRect = currentImage.rect();
+ // Scale down currentImage by both width and height to fit into the drawable area of the page.
+ float scaleFactor = (float)pageSize.width() / (float)targetRect.width();
+ targetRect = QRect(0, 0, targetRect.width() * scaleFactor, targetRect.height() * scaleFactor);
+ scaleFactor = (float)pageSize.height() / (float)targetRect.height();
+ targetRect = QRect(0, 0, targetRect.width() * scaleFactor, targetRect.height() * scaleFactor);
+
// 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)
- m_printer->newPage();
+ painter.drawImage(targetRect, currentImage, currentImage.rect());
}
if (currentPageIndex == toPage)
@@ -133,10 +157,8 @@ void PrinterWorker::print()
else
currentPageIndex--;
- m_printer->newPage();
+ m_printer->setPageOrientation(prevOrientation);
}
- if (printedDocuments < documentCopies - 1)
- m_printer->newPage();
}
painter.end();