diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-12-23 07:34:16 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2020-01-30 15:50:44 +0100 |
commit | 4f5f0705bc161ff95899fdb2c5fcdb4581bf15bb (patch) | |
tree | 39e1f225a24d893176b9d22bc46bddacaadfca38 | |
parent | d1749c375ea924390d19225b40ef2631b524849b (diff) |
QPdfDocument and QPdfIOHandler: add scale and clip features
Like some other image plugins, the PDF plugin now supports
ImageOption::ScaledClipRect and ScaledSize.
Change-Id: Ie7278752e49c885cc4580f30af1ec5e6310f8334
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r-- | src/pdf/api/qpdfdocumentrenderoptions.h | 12 | ||||
-rw-r--r-- | src/pdf/qpdfdocument.cpp | 34 | ||||
-rw-r--r-- | src/plugins/imageformats/pdf/qpdfiohandler.cpp | 10 |
3 files changed, 51 insertions, 5 deletions
diff --git a/src/pdf/api/qpdfdocumentrenderoptions.h b/src/pdf/api/qpdfdocumentrenderoptions.h index 99a5db2e3..873be0085 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 4c4f8f24e..728bf1245 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 9df85cf08..739e8b34c 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(); } |