diff options
author | Szabolcs David <davidsz@inf.u-szeged.hu> | 2019-05-14 17:02:45 +0200 |
---|---|---|
committer | Szabolcs David <davidsz@inf.u-szeged.hu> | 2019-06-04 15:34:48 +0200 |
commit | 7f89badd0e1b71dabb5a88d1330b08ce9d8b6eb7 (patch) | |
tree | cc4f7d878a60127c535804299d19e3e500d505dd | |
parent | 8b848e4aee238edb58dba0ded8d773c8b70392f6 (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.cpp | 25 | ||||
-rw-r--r-- | src/core/printing/pdfium_document_wrapper_qt.h | 5 | ||||
-rw-r--r-- | src/webenginewidgets/printer_worker.cpp | 40 |
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(); |