diff --git a/src/pdf/api/qpdfdocumentrenderoptions.h b/src/pdf/api/qpdfdocumentrenderoptions.h
index 99a5db2e3eb89ca623383444522080265bc10e81..873be0085aeec935ab6b5744646055176388d1a0 100644
--- a/src/pdf/api/qpdfdocumentrenderoptions.h
+++ b/src/pdf/api/qpdfdocumentrenderoptions.h
@@ -39,6 +39,7 @@
 
 #include <QtPdf/qpdfnamespace.h>
 #include <QtCore/QObject>
+#include <QtCore/QRect>
 
 QT_BEGIN_NAMESPACE
 
@@ -53,6 +54,12 @@ public:
     Q_DECL_CONSTEXPR QPdf::RenderFlags renderFlags() const Q_DECL_NOTHROW { return static_cast<QPdf::RenderFlags>(bits.renderFlags); }
     Q_DECL_RELAXED_CONSTEXPR void setRenderFlags(QPdf::RenderFlags _renderFlags) Q_DECL_NOTHROW { bits.renderFlags = _renderFlags; }
 
+    Q_DECL_CONSTEXPR QRect scaledClipRect() const Q_DECL_NOTHROW { return m_clipRect; }
+    Q_DECL_RELAXED_CONSTEXPR void setScaledClipRect(const QRect &r) Q_DECL_NOTHROW { m_clipRect = r; }
+
+    Q_DECL_CONSTEXPR QSize scaledSize() const Q_DECL_NOTHROW { return m_scaledSize; }
+    Q_DECL_RELAXED_CONSTEXPR void setScaledSize(const QSize &s) Q_DECL_NOTHROW { m_scaledSize = s; }
+
 private:
     friend Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW;
 
@@ -68,13 +75,16 @@ private:
         Bits bits;
         quint64 data;
     };
+
+    QRect m_clipRect;
+    QSize m_scaledSize;
 };
 
 Q_DECLARE_TYPEINFO(QPdfDocumentRenderOptions, Q_PRIMITIVE_TYPE);
 
 Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW
 {
-    return lhs.data == rhs.data;
+    return lhs.data == rhs.data && lhs.m_clipRect == rhs.m_clipRect && lhs.m_scaledSize == rhs.m_scaledSize;
 }
 
 Q_DECL_CONSTEXPR inline bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index 4c4f8f24eb21315d3a70e60418c5d9f086920237..728bf124584c69a1586007dfd4c646e8d203aede 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -46,6 +46,7 @@
 #include <QHash>
 #include <QLoggingCategory>
 #include <QMutex>
+#include <QVector2D>
 
 QT_BEGIN_NAMESPACE
 
@@ -675,12 +676,41 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
     if (renderFlags & QPdf::RenderPathAliased)
         flags |= FPDF_RENDER_NO_SMOOTHPATH;
 
-    FPDF_RenderPageBitmap(bitmap, pdfPage, 0, 0, result.width(), result.height(), rotation, flags);
+    if (renderOptions.scaledClipRect().isValid()) {
+        const QRect &clipRect = renderOptions.scaledClipRect();
+
+        // TODO take rotation into account, like cpdf_page.cpp lines 145-178
+        float x0 = clipRect.left();
+        float y0 = clipRect.top();
+        float x1 = clipRect.left();
+        float y1 = clipRect.bottom();
+        float x2 = clipRect.right();
+        float y2 = clipRect.top();
+        QSizeF origSize = pageSize(page);
+        QVector2D pageScale(1, 1);
+        if (!renderOptions.scaledSize().isNull()) {
+            pageScale = QVector2D(renderOptions.scaledSize().width() / float(origSize.width()),
+                                  renderOptions.scaledSize().height() / float(origSize.height()));
+        }
+        FS_MATRIX matrix {(x2 - x0) / result.width() * pageScale.x(),
+                          (y2 - y0) / result.width() * pageScale.x(),
+                          (x1 - x0) / result.height() * pageScale.y(),
+                          (y1 - y0) / result.height() * pageScale.y(), -x0, -y0};
+
+        FS_RECTF clipRectF { 0, 0, float(imageSize.width()), float(imageSize.height()) };
+
+        FPDF_RenderPageBitmapWithMatrix(bitmap, pdfPage, &matrix, &clipRectF, flags);
+        qCDebug(qLcDoc) << "matrix" << matrix.a << matrix.b << matrix.c << matrix.d << matrix.e << matrix.f;
+        qCDebug(qLcDoc) << "page" << page << "region" << renderOptions.scaledClipRect()
+                        << "size" << imageSize << "took" << timer.elapsed() << "ms";
+    } else {
+        FPDF_RenderPageBitmap(bitmap, pdfPage, 0, 0, result.width(), result.height(), rotation, flags);
+        qCDebug(qLcDoc) << "page" << page << "size" << imageSize << "took" << timer.elapsed() << "ms";
+    }
 
     FPDFBitmap_Destroy(bitmap);
 
     FPDF_ClosePage(pdfPage);
-    qCDebug(qLcDoc) << "page" << page << imageSize << "took" << timer.elapsed() << "ms";
     return result;
 }
 
diff --git a/src/plugins/imageformats/pdf/qpdfiohandler.cpp b/src/plugins/imageformats/pdf/qpdfiohandler.cpp
index 9df85cf086679d366fe87eff7f3c4ad4a00f77a3..739e8b34c233f4de67532bbe78c54ef355448779 100644
--- a/src/plugins/imageformats/pdf/qpdfiohandler.cpp
+++ b/src/plugins/imageformats/pdf/qpdfiohandler.cpp
@@ -98,7 +98,8 @@ bool QPdfIOHandler::read(QImage *image)
         if (m_page < 0)
             m_page = 0;
         const bool xform = (m_clipRect.isValid() || m_scaledSize.isValid() || m_scaledClipRect.isValid());
-        QSize finalSize = m_doc.pageSize(m_page).toSize();
+        QSize pageSize = m_doc.pageSize(m_page).toSize();
+        QSize finalSize = pageSize;
         QRectF bounds;
         if (xform && !finalSize.isEmpty()) {
             bounds = QRectF(QPointF(0,0), QSizeF(finalSize));
@@ -112,6 +113,7 @@ bool QPdfIOHandler::read(QImage *image)
                 sc = QSizeF(qreal(m_scaledSize.width()) / finalSize.width(),
                             qreal(m_scaledSize.height()) / finalSize.height());
                 finalSize = m_scaledSize;
+                pageSize = m_scaledSize;
             }
             if (m_scaledClipRect.isValid()) {
                 tr2 = -m_scaledClipRect.topLeft();
@@ -133,9 +135,13 @@ bool QPdfIOHandler::read(QImage *image)
             }
         }
         if (!finalSize.isEmpty()) {
+            QPdfDocumentRenderOptions options;
+            if (m_scaledClipRect.isValid())
+                options.setScaledClipRect(m_scaledClipRect);
+            options.setScaledSize(pageSize);
             image->fill(m_backColor.rgba());
             QPainter p(image);
-            QImage pageImage = m_doc.render(m_page, finalSize);
+            QImage pageImage = m_doc.render(m_page, finalSize, options);
             p.drawImage(0, 0, pageImage);
             p.end();
         }