From 9bfe4bf9802281fabc5b9e607621ea4cb5e9bd39 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Mon, 22 Aug 2016 20:09:38 +0200 Subject: Add support for render rotation and flags Extend the QPdfDocument::render() method with a parameter of new type QPdfDocumentRenderOptions to specify the rotation and additional render flags. Change-Id: I354acc7fad4d094a96cefcea4dfa3513f4955c47 Reviewed-by: Marc Mutz --- examples/pdfwidgets/pdfviewer/pagerenderer.cpp | 2 +- src/pdf/pdf.pro | 2 + src/pdf/qpdfdocument.cpp | 49 +++++++++++- src/pdf/qpdfdocument.h | 8 +- src/pdf/qpdfdocumentrenderoptions.h | 88 +++++++++++++++++++++ src/pdf/qpdfdocumentrenderoptions.qdoc | 105 +++++++++++++++++++++++++ src/pdf/qpdfnamespace.h | 69 ++++++++++++++++ src/pdf/qpdfnamespace.qdoc | 74 +++++++++++++++++ 8 files changed, 390 insertions(+), 7 deletions(-) create mode 100644 src/pdf/qpdfdocumentrenderoptions.h create mode 100644 src/pdf/qpdfdocumentrenderoptions.qdoc create mode 100644 src/pdf/qpdfnamespace.h create mode 100644 src/pdf/qpdfnamespace.qdoc diff --git a/examples/pdfwidgets/pdfviewer/pagerenderer.cpp b/examples/pdfwidgets/pdfviewer/pagerenderer.cpp index c8f245640..8cb1ed69c 100644 --- a/examples/pdfwidgets/pdfviewer/pagerenderer.cpp +++ b/examples/pdfwidgets/pdfviewer/pagerenderer.cpp @@ -84,7 +84,7 @@ void PageRenderer::renderPage(int page, qreal zoom) QElapsedTimer timer; timer.start(); - const QImage &img = m_document->render(page, size); + const QImage &img = m_document->render(page, size.toSize()); const qreal secs = timer.nsecsElapsed() / 1000000000.0; if (secs < m_minRenderTime) diff --git a/src/pdf/pdf.pro b/src/pdf/pdf.pro index 9d0e1cbcc..606a2cb36 100644 --- a/src/pdf/pdf.pro +++ b/src/pdf/pdf.pro @@ -29,4 +29,6 @@ HEADERS += \ qpdfbookmarkmodel.h \ qpdfdocument.h \ qpdfdocument_p.h \ + qpdfdocumentrenderoptions.h \ + qpdfnamespace.h \ qtpdfglobal.h diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp index c737ca036..1dd6f4027 100644 --- a/src/pdf/qpdfdocument.cpp +++ b/src/pdf/qpdfdocument.cpp @@ -546,7 +546,17 @@ QSizeF QPdfDocument::pageSize(int page) const return result; } -QImage QPdfDocument::render(int page, const QSizeF &pageSize) +/*! + Renders the \a page into a QImage of size \a imageSize according to the + provided \a renderOptions. + + Returns the rendered page or an empty image in case of an error. + + Note: If the \a imageSize does not match the aspect ratio of the page in the + PDF document, the page is rendered scaled, so that it covers the + complete \a imageSize. +*/ +QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions renderOptions) { if (!d->doc) return QImage(); @@ -557,11 +567,44 @@ QImage QPdfDocument::render(int page, const QSizeF &pageSize) if (!pdfPage) return QImage(); - QImage result(pageSize.toSize(), QImage::Format_ARGB32); + QImage result(imageSize, QImage::Format_ARGB32); result.fill(Qt::transparent); FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(result.width(), result.height(), FPDFBitmap_BGRA, result.bits(), result.bytesPerLine()); - FPDF_RenderPageBitmap(bitmap, pdfPage, 0, 0, result.width(), result.height(), 0, 0); + int rotation = 0; + switch (renderOptions.rotation()) { + case QPdf::Rotate0: + rotation = 0; + break; + case QPdf::Rotate90: + rotation = 1; + break; + case QPdf::Rotate180: + rotation = 2; + break; + case QPdf::Rotate270: + rotation = 3; + break; + } + + const QPdf::RenderFlags renderFlags = renderOptions.renderFlags(); + int flags = 0; + if (renderFlags & QPdf::RenderAnnotations) + flags |= FPDF_ANNOT; + if (renderFlags & QPdf::RenderOptimizedForLcd) + flags |= FPDF_LCD_TEXT; + if (renderFlags & QPdf::RenderGrayscale) + flags |= FPDF_GRAYSCALE; + if (renderFlags & QPdf::RenderForceHalftone) + flags |= FPDF_RENDER_FORCEHALFTONE; + if (renderFlags & QPdf::RenderTextAliased) + flags |= FPDF_RENDER_NO_SMOOTHTEXT; + if (renderFlags & QPdf::RenderImageAliased) + flags |= FPDF_RENDER_NO_SMOOTHIMAGE; + if (renderFlags & QPdf::RenderPathAliased) + flags |= FPDF_RENDER_NO_SMOOTHPATH; + + FPDF_RenderPageBitmap(bitmap, pdfPage, 0, 0, result.width(), result.height(), rotation, flags); FPDFBitmap_Destroy(bitmap); diff --git a/src/pdf/qpdfdocument.h b/src/pdf/qpdfdocument.h index 751c1b31b..63532b3d5 100644 --- a/src/pdf/qpdfdocument.h +++ b/src/pdf/qpdfdocument.h @@ -37,10 +37,12 @@ #ifndef QPDFDOCUMENT_H #define QPDFDOCUMENT_H -#include -#include #include "qtpdfglobal.h" +#include +#include +#include + QT_BEGIN_NAMESPACE class QPdfDocumentPrivate; @@ -107,7 +109,7 @@ public: QSizeF pageSize(int page) const; - QImage render(int page, const QSizeF &pageSize); + QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions()); Q_SIGNALS: void passwordChanged(); diff --git a/src/pdf/qpdfdocumentrenderoptions.h b/src/pdf/qpdfdocumentrenderoptions.h new file mode 100644 index 000000000..b602bb00e --- /dev/null +++ b/src/pdf/qpdfdocumentrenderoptions.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPDFDOCUMENTRENDEROPTIONS_H +#define QPDFDOCUMENTRENDEROPTIONS_H + +#include "qpdfnamespace.h" + +#include + +QT_BEGIN_NAMESPACE + +class QPdfDocumentRenderOptions +{ +public: + Q_DECL_CONSTEXPR QPdfDocumentRenderOptions() Q_DECL_NOTHROW : data(0) {} + + Q_DECL_CONSTEXPR QPdf::Rotation rotation() const Q_DECL_NOTHROW { return static_cast(bits.rotation); } + Q_DECL_RELAXED_CONSTEXPR void setRotation(QPdf::Rotation _rotation) Q_DECL_NOTHROW { bits.rotation = _rotation; } + + Q_DECL_CONSTEXPR QPdf::RenderFlags renderFlags() const Q_DECL_NOTHROW { return static_cast(bits.renderFlags); } + Q_DECL_RELAXED_CONSTEXPR void setRenderFlags(QPdf::RenderFlags _renderFlags) Q_DECL_NOTHROW { bits.renderFlags = _renderFlags; } + +private: + friend Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW; + + + struct Bits { + quint32 renderFlags : 8; + quint32 rotation : 3; + quint32 reserved : 21; + quint32 reserved2 : 32; + }; + + union { + Bits bits; + quint64 data; + }; +}; + +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; +} + +Q_DECL_CONSTEXPR inline bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW +{ + return !operator==(lhs, rhs); +} + +QT_END_NAMESPACE + +#endif // QPDFDOCUMENTRENDEROPTIONS_H diff --git a/src/pdf/qpdfdocumentrenderoptions.qdoc b/src/pdf/qpdfdocumentrenderoptions.qdoc new file mode 100644 index 000000000..cafb0afc1 --- /dev/null +++ b/src/pdf/qpdfdocumentrenderoptions.qdoc @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpdfdocumentrenderoptions.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QPdfDocumentRenderOptions + \since 5.10 + \inmodule QtPdf + + \brief The QPdfDocumentRenderOptions class holds the options to render a page from a PDF document. + + \sa QPdfDocument +*/ + +/*! + \fn QPdfDocumentRenderOptions::QPdfDocumentRenderOptions() + + Constructs a QPdfDocumentRenderOptions object. +*/ + +/*! + \fn QPdf::Rotation QPdfDocumentRenderOptions::rotation() const + + Returns the rotation used for rendering a page from a PDF document. + + \sa setRotation() +*/ + +/*! + \fn void QPdfDocumentRenderOptions::setRotation(QPdf::Rotation rotation) + + Sets the \a rotation used for rendering a page from a PDF document. + + \sa rotation() +*/ + +/*! + \fn QPdf::RenderFlags QPdfDocumentRenderOptions::renderFlags() const + + Returns the special flags used for rendering a page from a PDF document. + + \sa setRenderFlags() +*/ + +/*! + \fn void QPdfDocumentRenderOptions::setRenderFlags(QPdf::RenderFlags flags) + + Sets the special \a flags used for rendering a page from a PDF document. + + \sa renderFlags() +*/ + +/*! + \fn bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) + \relates QPdfDocumentRenderOptions + + Returns \c true if the options \a lhs and \a rhs are different, otherwise + returns \c false. +*/ + +/*! + \fn bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) + \relates QPdfDocumentRenderOptions + + Returns \c true if the options \a lhs and \a rhs are equal, + otherwise returns \c false. +*/ + +QT_END_NAMESPACE diff --git a/src/pdf/qpdfnamespace.h b/src/pdf/qpdfnamespace.h new file mode 100644 index 000000000..a8e7dc0e5 --- /dev/null +++ b/src/pdf/qpdfnamespace.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPDFNAMESPACE_H +#define QPDFNAMESPACE_H + +#include + +namespace QPdf { + Q_NAMESPACE + + enum Rotation { + Rotate0, + Rotate90, + Rotate180, + Rotate270 + }; + Q_ENUM_NS(Rotation) + + enum RenderFlag { + NoRenderFlags = 0x000, + RenderAnnotations = 0x001, + RenderOptimizedForLcd = 0x002, + RenderGrayscale = 0x004, + RenderForceHalftone = 0x008, + RenderTextAliased = 0x010, + RenderImageAliased = 0x020, + RenderPathAliased = 0x040 + }; + Q_FLAG_NS(RenderFlag) + Q_DECLARE_FLAGS(RenderFlags, RenderFlag) +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(QPdf::RenderFlags) + +#endif diff --git a/src/pdf/qpdfnamespace.qdoc b/src/pdf/qpdfnamespace.qdoc new file mode 100644 index 000000000..96bb090e9 --- /dev/null +++ b/src/pdf/qpdfnamespace.qdoc @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \namespace QPdf + \inmodule QtPdf + \keyword QPdf Namespace + + \brief The QPdf namespace contains miscellaneous identifiers + used throughout the QtPdf module. +*/ + +/*! + \enum QPdf::Rotation + + This enum describes the rotation of the page for rendering. + + \value Rotate0 Do not rotate (the default) + \value Rotate90 Rotate 90 degrees clockwise + \value Rotate180 Rotate 180 degrees + \value Rotate270 Rotate 270 degrees clockwise + + \sa QPdfDocument::render() +*/ +/*! + \enum QPdf::RenderFlag + + This enum is used to describe how a page should be rendered. + + \value NoRenderFlags The default value, representing no flags. + \value RenderAnnotations The page is rendered with annotations. + \value RenderOptimizedForLcd The text of the page is rendered optimized for LCD display. + \value RenderGrayscale The page is rendered grayscale. + \value RenderForceHalftone Always use halftones for rendering if the output image is stretched. + \value RenderTextAliased Anti-aliasing is disabled for rendering text. + \value RenderImageAliased Anti-aliasing is disabled for rendering images. + \value RenderPathAliased Anti-aliasing is disabled for rendering paths. + + \sa QPdfDocument::render() +*/ + -- cgit v1.2.3