From a8e4ad7726f1aa52624a0367558650cd4d899c79 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge <shawn.rutledge@qt.io> Date: Thu, 28 Nov 2019 11:51:07 +0100 Subject: [PATCH] PdfPageView: Add zoom-to-fit and zoom-to-width features Change-Id: I40b92000a4def105d22a3bd10d0544b0b0f0fe1e Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> --- .../pdf/pdfviewer/resources/zoom-fit-best.svg | 13 +++++ .../pdfviewer/resources/zoom-fit-width.svg | 13 +++++ examples/pdf/pdfviewer/viewer.qml | 14 ++++- examples/pdf/pdfviewer/viewer.qrc | 2 + src/pdf/quick/qml/PdfPageView.qml | 57 ++++++++++++++++++- 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 examples/pdf/pdfviewer/resources/zoom-fit-best.svg create mode 100644 examples/pdf/pdfviewer/resources/zoom-fit-width.svg diff --git a/examples/pdf/pdfviewer/resources/zoom-fit-best.svg b/examples/pdf/pdfviewer/resources/zoom-fit-best.svg new file mode 100644 index 000000000..adf302621 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/zoom-fit-best.svg @@ -0,0 +1,13 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <defs id="defs3051"> + <style type="text/css" id="current-color-scheme"> + .ColorScheme-Text { + color:#4d4d4d; + } + </style> + </defs> + <path style="fill:currentColor;fill-opacity:1;stroke:none" + d="M 4 4 L 4 5 L 4 8 L 5 8 L 5 5 L 8 5 L 8 4 L 5 4 L 4 4 z M 12 4 L 10 6 L 14 6 L 12 4 z M 16 4 L 16 5 L 19 5 L 19 8 L 20 8 L 20 5 L 20 4 L 19 4 L 16 4 z M 7 7 L 7 17 L 17 17 L 17 7 L 7 7 z M 8 8 L 16 8 L 16 16 L 8 16 L 8 8 z M 6 10 L 4 12 L 6 14 L 6 10 z M 18 10 L 18 14 L 20 12 L 18 10 z M 4 16 L 4 19 L 4 20 L 8 20 L 8 19 L 5 19 L 5 16 L 4 16 z M 19 16 L 19 19 L 16 19 L 16 20 L 20 20 L 20 19 L 20 16 L 19 16 z M 10 18 L 12 20 L 14 18 L 10 18 z " + class="ColorScheme-Text" + /> +</svg> diff --git a/examples/pdf/pdfviewer/resources/zoom-fit-width.svg b/examples/pdf/pdfviewer/resources/zoom-fit-width.svg new file mode 100644 index 000000000..985ee5205 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/zoom-fit-width.svg @@ -0,0 +1,13 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <defs id="defs3051"> + <style type="text/css" id="current-color-scheme"> + .ColorScheme-Text { + color:#4d4d4d; + } + </style> + </defs> + <path style="fill:currentColor;fill-opacity:1;stroke:none" + d="M 7 7 L 7 17 L 17 17 L 17 7 L 7 7 z M 8 8 L 16 8 L 16 16 L 8 16 L 8 8 z M 6 10 L 4 12 L 6 14 L 6 10 z M 18 10 L 18 14 L 20 12 L 18 10 z " + class="ColorScheme-Text" + /> +</svg> diff --git a/examples/pdf/pdfviewer/viewer.qml b/examples/pdf/pdfviewer/viewer.qml index 99d9b8ed0..1cf0b432b 100644 --- a/examples/pdf/pdfviewer/viewer.qml +++ b/examples/pdf/pdfviewer/viewer.qml @@ -92,11 +92,23 @@ ApplicationWindow { onTriggered: pageView.renderScale /= root.scaleStep } } + ToolButton { + action: Action { + icon.source: "resources/zoom-fit-width.svg" + onTriggered: pageView.scaleToWidth(root.contentItem.width, root.contentItem.height) + } + } + ToolButton { + action: Action { + icon.source: "resources/zoom-fit-best.svg" + onTriggered: pageView.scaleToPage(root.contentItem.width, root.contentItem.height) + } + } ToolButton { action: Action { shortcut: "Ctrl+0" icon.source: "resources/zoom-original.svg" - onTriggered: pageView.renderScale = 1 + onTriggered: pageView.resetScale() } } ToolButton { diff --git a/examples/pdf/pdfviewer/viewer.qrc b/examples/pdf/pdfviewer/viewer.qrc index c376803c2..fa3561caf 100644 --- a/examples/pdf/pdfviewer/viewer.qrc +++ b/examples/pdf/pdfviewer/viewer.qrc @@ -8,6 +8,8 @@ <file>resources/rotate-left.svg</file> <file>resources/rotate-right.svg</file> <file>resources/zoom-in.svg</file> + <file>resources/zoom-fit-best.svg</file> + <file>resources/zoom-fit-width.svg</file> <file>resources/zoom-original.svg</file> <file>resources/zoom-out.svg</file> <file>resources/document-open.svg</file> diff --git a/src/pdf/quick/qml/PdfPageView.qml b/src/pdf/quick/qml/PdfPageView.qml index 556cf1b7a..e20ebd1b4 100644 --- a/src/pdf/quick/qml/PdfPageView.qml +++ b/src/pdf/quick/qml/PdfPageView.qml @@ -56,6 +56,51 @@ Rectangle { property real __pageScale: image.paintedWidth / document.pagePointSize(image.currentFrame).width + function resetScale() { + image.sourceSize.width = 0 + image.sourceSize.height = 0 + paper.x = 0 + paper.y = 0 + paper.scale = 1 + } + + function scaleToWidth(width, height) { + var halfRotation = Math.abs(paper.rotation % 180) + image.sourceSize = Qt.size((halfRotation > 45 && halfRotation < 135) ? height : width, 0) + paper.x = 0 + paper.y = 0 + image.centerInSize = Qt.size(width, height) + image.centerOnLoad = true + image.vCenterOnLoad = (halfRotation > 45 && halfRotation < 135) + paper.scale = 1 + } + + function scaleToPage(width, height) { + var windowAspect = width / height + var halfRotation = Math.abs(paper.rotation % 180) + var pagePointSize = document.pagePointSize(image.currentFrame) + if (halfRotation > 45 && halfRotation < 135) { + // rotated 90 or 270º + var pageAspect = pagePointSize.height / pagePointSize.width + if (windowAspect > pageAspect) { + image.sourceSize = Qt.size(height, 0) + } else { + image.sourceSize = Qt.size(0, width) + } + } else { + var pageAspect = pagePointSize.width / pagePointSize.height + if (windowAspect > pageAspect) { + image.sourceSize = Qt.size(0, height) + } else { + image.sourceSize = Qt.size(width, 0) + } + } + image.centerInSize = Qt.size(width, height) + image.centerOnLoad = true + image.vCenterOnLoad = true + paper.scale = 1 + } + PdfSelection { id: selection document: paper.document @@ -79,13 +124,23 @@ Rectangle { source: document.status === PdfDocument.Ready ? document.source : "" asynchronous: true fillMode: Image.PreserveAspectFit + property bool centerOnLoad: false + property bool vCenterOnLoad: false + property size centerInSize + onStatusChanged: + if (status == Image.Ready && centerOnLoad) { + paper.x = (centerInSize.width - image.implicitWidth) / 2 + paper.y = vCenterOnLoad ? (centerInSize.height - image.implicitHeight) / 2 : 0 + centerOnLoad = false + vCenterOnLoad = false + } } function reRenderIfNecessary() { var newSourceWidth = image.sourceSize.width * paper.scale var ratio = newSourceWidth / image.sourceSize.width if (ratio > 1.1 || ratio < 0.9) { image.sourceSize.width = newSourceWidth - image.sourceSize.height = 1 + image.sourceSize.height = 0 paper.scale = 1 } } -- GitLab