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 0000000000000000000000000000000000000000..adf3026212b438a1ce92de7c67f389f88bc204e7
--- /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 0000000000000000000000000000000000000000..985ee5205ced8ebeb5ecfd9d661caaa95fe16465
--- /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 99d9b8ed0e5df0ee9d212dc513080f9f0b820a35..1cf0b432b26628d5256c1652e313576f9c5f857c 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 c376803c28db3bf4270ab5d3ce88d225e282326a..fa3561caf0a857175c02157a2262294c43c32b61 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 556cf1b7a3a9db1bc34853dee61d85910608c172..e20ebd1b487ca05ff2f0fd208251b37d65a927f0 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
         }
     }