From 5e4487c2d9c72c54269db5fe8f333c75479ccb5f Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Mon, 21 Oct 2019 16:54:26 +0200 Subject: Redo scale handling of pdf when printing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 7f89bad our printer handling produces low quality images, the reason for that is the we first render with pdfium to bitmap which is fixed to twice size of pdf document in points, then it is downscaled/upscaled by qpainter. This issue is even more visible when print preview is requested on hdpi screen. Simplify the code and do the "scaling" already when rendering bitmap with pdfium. Task-number: QTBUG-75092 Fixes: QTBUG-78161 Change-Id: I616ad1f371e7d3457a04b0a254603ed235c387bc Reviewed-by: Michael BrĂ¼ning --- src/core/printing/pdfium_document_wrapper_qt.cpp | 89 ++++++------------------ src/core/printing/pdfium_document_wrapper_qt.h | 5 +- src/webenginewidgets/printer_worker.cpp | 42 +++++------ 3 files changed, 40 insertions(+), 96 deletions(-) diff --git a/src/core/printing/pdfium_document_wrapper_qt.cpp b/src/core/printing/pdfium_document_wrapper_qt.cpp index 6f415b50b..dae6ec44b 100644 --- a/src/core/printing/pdfium_document_wrapper_qt.cpp +++ b/src/core/printing/pdfium_document_wrapper_qt.cpp @@ -48,64 +48,6 @@ namespace QtWebEngineCore { int PdfiumDocumentWrapperQt::m_libraryUsers = 0; -class PdfiumPageWrapperQt { -public: - 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()) - { - } - - PdfiumPageWrapperQt() - : m_pageData(nullptr) - , m_width(-1) - , m_height(-1) - , m_image(QImage()) - { - } - - virtual ~PdfiumPageWrapperQt() - { - FPDF_ClosePage(m_pageData); - } - - QImage image() - { - return m_image; - } - -private: - QImage createImage() - { - Q_ASSERT(m_pageData); - - QImage image(m_width * 2, m_height * 2, QImage::Format_ARGB32); - Q_ASSERT(!image.isNull()); - image.fill(0xFFFFFFFF); - - FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(image.width(), image.height(), - FPDFBitmap_BGRA, - image.scanLine(0), image.bytesPerLine()); - Q_ASSERT(bitmap); - - FPDF_RenderPageBitmap(bitmap, m_pageData, - 0, 0, image.width(), image.height(), - 0, 0); - FPDFBitmap_Destroy(bitmap); - bitmap = nullptr; - return image; - } - -private: - FPDF_PAGE m_pageData; - int m_width; - int m_height; - QImage m_image; -}; - - PdfiumDocumentWrapperQt::PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const char *password) { @@ -118,27 +60,41 @@ PdfiumDocumentWrapperQt::PdfiumDocumentWrapperQt(const void *pdfData, size_t siz m_pageCount = FPDF_GetPageCount((FPDF_DOCUMENT)m_documentHandle); } -QImage PdfiumDocumentWrapperQt::pageAsQImage(size_t index) +QImage PdfiumDocumentWrapperQt::pageAsQImage(size_t pageIndex,int width , int height) { if (!m_documentHandle || !m_pageCount) { qWarning("Failure to generate QImage from invalid or empty PDF document."); return QImage(); } - if (static_cast(index) >= m_pageCount) { + if (static_cast(pageIndex) >= m_pageCount) { qWarning("Failure to generate QImage from PDF data: index out of bounds."); return QImage(); } - PdfiumPageWrapperQt pageWrapper((FPDF_DOCUMENT)m_documentHandle, index); - return pageWrapper.image(); + FPDF_PAGE pageData(FPDF_LoadPage((FPDF_DOCUMENT)m_documentHandle, pageIndex)); + QImage image(width, height, QImage::Format_ARGB32); + Q_ASSERT(!image.isNull()); + image.fill(0xFFFFFFFF); + + FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(width, height, + FPDFBitmap_BGRA, + image.scanLine(0), image.bytesPerLine()); + Q_ASSERT(bitmap); + FPDF_RenderPageBitmap(bitmap, pageData, + 0, 0, width, height, + 0, 0); + FPDFBitmap_Destroy(bitmap); + bitmap = nullptr; + FPDF_ClosePage(pageData); + return image; } -bool PdfiumDocumentWrapperQt::pageIsLandscape(size_t index) +QSizeF PdfiumDocumentWrapperQt::pageSize(size_t index) { - double width = 0, height = 0; - FPDF_GetPageSizeByIndex((FPDF_DOCUMENT)m_documentHandle, index, &width, &height); - return (width > height); + QSizeF size; + FPDF_GetPageSizeByIndex((FPDF_DOCUMENT)m_documentHandle, index, &size.rwidth(), &size.rheight()); + return size; } PdfiumDocumentWrapperQt::~PdfiumDocumentWrapperQt() @@ -147,5 +103,4 @@ PdfiumDocumentWrapperQt::~PdfiumDocumentWrapperQt() if (--m_libraryUsers == 0) FPDF_DestroyLibrary(); } - } diff --git a/src/core/printing/pdfium_document_wrapper_qt.h b/src/core/printing/pdfium_document_wrapper_qt.h index 121742aa3..e0778c32b 100644 --- a/src/core/printing/pdfium_document_wrapper_qt.h +++ b/src/core/printing/pdfium_document_wrapper_qt.h @@ -56,15 +56,14 @@ #include namespace QtWebEngineCore { -class PdfiumPageWrapperQt; class Q_WEBENGINECORE_PRIVATE_EXPORT PdfiumDocumentWrapperQt { public: PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const char *password = nullptr); virtual ~PdfiumDocumentWrapperQt(); - QImage pageAsQImage(size_t index); - bool pageIsLandscape(size_t index); + QImage pageAsQImage(size_t index, int width , int height); + QSizeF pageSize(size_t index); int pageCount() const { return m_pageCount; } private: diff --git a/src/webenginewidgets/printer_worker.cpp b/src/webenginewidgets/printer_worker.cpp index 94a862cda..8e1c2a985 100644 --- a/src/webenginewidgets/printer_worker.cpp +++ b/src/webenginewidgets/printer_worker.cpp @@ -94,17 +94,9 @@ 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); + qreal resolution = m_printer->resolution() / 72.0; // pdfium uses points so 1/72 inch QPainter painter; - if (!painter.begin(m_printer)) { - qWarning("Failure to print on printer %ls: Could not open printer for painting.", - qUtf16Printable(m_printer->printerName())); - Q_EMIT resultReady(false); - return; - } for (int printedDocuments = 0; printedDocuments < documentCopies; printedDocuments++) { if (printedDocuments > 0) @@ -113,11 +105,20 @@ void PrinterWorker::print() int currentPageIndex = fromPage; for (int i = 0; true; i++) { - prevOrientation = m_printer->pageLayout().orientation(); - isLandscape = pdfiumWrapper.pageIsLandscape(currentPageIndex - 1); + QSizeF documentSize = (pdfiumWrapper.pageSize(currentPageIndex - 1) * resolution); + bool isLandscape = documentSize.width() > documentSize.height(); m_printer->setPageOrientation(isLandscape ? QPageLayout::Landscape : QPageLayout::Portrait); - - QSize pageSize = m_printer->pageRect().size(); + QRectF pageRect = m_printer->pageRect(QPrinter::DevicePixel); + documentSize = documentSize.scaled(pageRect.size(), Qt::KeepAspectRatio); + + // setPageOrientation has to be called before qpainter.begin() or before qprinter.newPage() so correct metrics is used, + // therefore call begin now for only first page + if (!painter.isActive() && !painter.begin(m_printer)) { + qWarning("Failure to print on printer %ls: Could not open printer for painting.", + qUtf16Printable(m_printer->printerName())); + Q_EMIT resultReady(false); + return; + } if (i > 0) m_printer->newPage(); @@ -132,21 +133,12 @@ void PrinterWorker::print() if (printedPages > 0) m_printer->newPage(); - QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1); + QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1,documentSize.width(),documentSize.height()); 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(targetRect, currentImage, currentImage.rect()); + painter.drawImage(0,0, currentImage); } if (currentPageIndex == toPage) @@ -156,8 +148,6 @@ void PrinterWorker::print() currentPageIndex++; else currentPageIndex--; - - m_printer->setPageOrientation(prevOrientation); } } painter.end(); -- cgit v1.2.3 From 56bff7a32faa978c9f22b0576de691cc1ca7e2a5 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 8 Nov 2019 14:13:36 +0100 Subject: Update Chromium MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: da37c1e0c517 [Backport] CVE-2019-13662 d6e5fc10e417 [Backport] Fix for CVE-2019-13720 Change-Id: Iea896b1cef9cc582654d0112408fc63539ee9a1a Reviewed-by: Michael BrĂ¼ning --- src/3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty b/src/3rdparty index 843d70ac8..d6e5fc10e 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 843d70ac87de7482c1c1195aa73899bc05efc8f3 +Subproject commit d6e5fc10e417efdf8665d9fba57c269f0534072f -- cgit v1.2.3 From b746ecdba38ce4ca302e1fd117b86092484da045 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 11 Nov 2019 11:24:39 +0100 Subject: Doc: Add missing section title to list of features Change-Id: Ic4951c1b033306dab51e99c9dfca9f8381bb85e5 Reviewed-by: Michal Klocek --- src/webengine/doc/src/qtwebengine-features.qdoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index 00b9cb496..8744f312a 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -37,6 +37,7 @@ \li \l{Audio and Video Codecs} \li \l{Chromium DevTools} \li \l{Client Certificates} + \li \l{Custom Schemes} \li \l{Drag and Drop} \li \l{Fullscreen} \li \l{HTML5 DRM} -- cgit v1.2.3 From 6e79d033a30f9d56b72a5aa4cc9a02cf656e2fe5 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 12 Nov 2019 09:53:36 +0100 Subject: Fix compilation on CI Add include based on error log from CI. Task-number: QTBUG-79930 Change-Id: Id74615182376c4bd4dd506239c9c2dbda75292c2 Reviewed-by: Allan Sandfeld Jensen --- src/core/net/url_request_notification.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/net/url_request_notification.cpp b/src/core/net/url_request_notification.cpp index 9d309e314..b59339441 100644 --- a/src/core/net/url_request_notification.cpp +++ b/src/core/net/url_request_notification.cpp @@ -49,6 +49,7 @@ #include "profile_io_data_qt.h" #include "qwebengineurlrequestinfo_p.h" #include "type_conversion.h" +#include namespace QtWebEngineCore { -- cgit v1.2.3 From ce72a40e91095dd5e1e46713fb94de493ee48d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Mon, 18 Nov 2019 13:36:30 +0100 Subject: Update Chromium This pulls in the following changes: 7e3ec623081 [Backport] Fix for CVE-2019-13720 59d24cbd63e Fix QRC cookies for tests with network-service 42c122dcb80 Fix Windows sandbox for heterogeneous executables 4d310ae5bc3 [Backport] CVE-2019-13700 d9cbe788437 [Backport] CVE-2019-13701 30dfb122e96 [Backport] CVE-2019-13704 51fdc9e9dc6 [Backport] CVE-2019-13706 9ea3feb658c [Backport] CVE-2019-13711 1/2 6ab99196115 [Backport] CVE-2019-13711 2/2 394da2e8dd7 [Backport] CVE-2019-15903 929d812ae1d [Backport] CVE-2019-13714 6c31ac36355 [Backport] CVE-2019-13715 bf4615cbfa1 [Backport] CVE-2019-13718 35fb44f1bdc [macOS] Fix build error with new deployment target 03e611b862a Revert "[Backport] CVE-2019-13701" 948c21d2163 Support GPU service on UI thread with viz 147452f856e Fix previous fix for new macOS deployment target cf3564f25ee FIXUP: Support GPU service on UI thread with viz 040ccbbef2d Fix pdfium build on macOS Task-number: QTBUG-79940 Change-Id: I6e3046b3b5d855cbfd8657dcaa816649938f73a5 Reviewed-by: Michal Klocek --- src/3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty b/src/3rdparty index 88a931558..040ccbbef 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 88a931558e2e960eacccb32483713fcc4bbaf433 +Subproject commit 040ccbbef2dbecdb33041a8c444467a72ad5ea4a -- cgit v1.2.3 From aca2a6df402d6454c7bbe8b0e9816645fcec8342 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Sat, 9 Nov 2019 00:44:37 +0100 Subject: Doc: Fix documentation warnings Remove links to example files, as QDoc no longer treats them as linkable targets. Fix linking to WebEngineView.selectClientCertificate(). Fix missing parameter documentation in WebEngineView.tooltipRequested(). Fixes: QTBUG-79815 Change-Id: I9090d3cfb1b698a545ae54a7426bb0a4eef892e9 Reviewed-by: Paul Wicking Reviewed-by: Leena Miettinen --- examples/webengine/customdialogs/doc/src/customdialogs.qdoc | 9 ++++----- examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc | 2 +- src/webengine/doc/src/qtwebengine-features.qdoc | 2 +- src/webengine/doc/src/webengineview_lgpl.qdoc | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/webengine/customdialogs/doc/src/customdialogs.qdoc b/examples/webengine/customdialogs/doc/src/customdialogs.qdoc index 6319ce53b..16eab0b6c 100644 --- a/examples/webengine/customdialogs/doc/src/customdialogs.qdoc +++ b/examples/webengine/customdialogs/doc/src/customdialogs.qdoc @@ -57,11 +57,10 @@ \section1 Triggering Dialogs - As mentioned, the \l {webengine/customdialogs/index.html}{index.html} file - is responsible for triggering the dialogs from the side of HTML and - JavaScript. Additionally, the example program starts a localhost TCP server - returning the mocked HTTP responses needed to trigger proxy and HTTP - authentication dialogs. + As mentioned, the \c index.html file is responsible for triggering the + dialogs from the side of HTML and JavaScript. Additionally, the example + program starts a localhost TCP server returning the mocked HTTP responses + needed to trigger proxy and HTTP authentication dialogs. \section1 Custom Dialogs diff --git a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc index 5c455345b..256a69baf 100644 --- a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc +++ b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc @@ -113,7 +113,7 @@ request will be denied. Finally, we load some HTML (see - \l{webenginewidgets/videoplayer/data/index.html}{index.html} included with + \c webenginewidgets/videoplayer/data/index.html included with the example) into our \l QWebEngineView: \printline load diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index d761e910c..954992de1 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -129,7 +129,7 @@ To activate support for client certificates, an application needs to listen to the QWebEnginePage::selectClientCertificate or - \l{WebEnginePage::selectClientCertificate}{WebEnginePage.selectClientCertificate} + \l{WebEngineView::selectClientCertificate}{WebEngineView.selectClientCertificate} signals and select one of the offered certificates. For applications that can navigate to untrusted web sites, it is recommended to always give the user a choice before uniquely identifying them diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc index df956f03e..6e349dfb3 100644 --- a/src/webengine/doc/src/webengineview_lgpl.qdoc +++ b/src/webengine/doc/src/webengineview_lgpl.qdoc @@ -1520,7 +1520,7 @@ \qmlsignal WebEngineView::tooltipRequested(TooltipRequest request) \since QtWebEngine 1.10 - This signal is emitted when the web page wants to show a tooltip at + This signal is emitted when the web page sends a \a request to show a tooltip at a specified position. \note Signal handlers need to call \c{request.accepted = true} to prevent a default tooltip from showing up. -- cgit v1.2.3