Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qpdfiohandler.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qpdfiohandler_p.h"
5#include <QLoggingCategory>
6#include <QPainter>
7#include <QtPdf/private/qpdffile_p.h>
8
10
11Q_LOGGING_CATEGORY(qLcPdf, "qt.imageformat.pdf")
12
14{
15}
16
18{
19 if (m_ownsDocument)
20 delete m_doc;
21}
22
24{
25 if (!device())
26 return false;
27 if (m_loaded)
28 return true;
30 setFormat("pdf");
31 return true;
32 }
33 return false;
34}
35
37{
38 char buf[6];
39 device->peek(buf, 6);
40 return (!qstrncmp(buf, "%PDF-", 5) || Q_UNLIKELY(!qstrncmp(buf, "\012%PDF-", 6)));
41}
42
44{
45 return m_page;
46}
47
49{
50 return QRect(QPoint(0, 0), m_doc->pagePointSize(m_page).toSize());
51}
52
54{
55 int ret = 0;
56 if (const_cast<QPdfIOHandler *>(this)->load(device()))
57 ret = m_doc->pageCount();
58 qCDebug(qLcPdf) << ret;
59 return ret;
60}
61
63{
64 if (load(device())) {
65 if (m_page >= m_doc->pageCount())
66 return false;
67 if (m_page < 0)
68 m_page = 0;
69 const bool xform = (m_clipRect.isValid() || m_scaledSize.isValid() || m_scaledClipRect.isValid());
70 QSize pageSize = m_doc->pagePointSize(m_page).toSize();
71 QSize finalSize = pageSize;
72 QRectF bounds;
73 if (xform && !finalSize.isEmpty()) {
74 bounds = QRectF(QPointF(0,0), QSizeF(finalSize));
75 QPoint tr1, tr2;
76 QSizeF sc(1, 1);
77 if (m_clipRect.isValid()) {
78 tr1 = -m_clipRect.topLeft();
79 finalSize = m_clipRect.size();
80 }
81 if (m_scaledSize.isValid()) {
82 sc = QSizeF(qreal(m_scaledSize.width()) / finalSize.width(),
83 qreal(m_scaledSize.height()) / finalSize.height());
84 finalSize = m_scaledSize;
85 pageSize = m_scaledSize;
86 }
87 if (m_scaledClipRect.isValid()) {
88 tr2 = -m_scaledClipRect.topLeft();
89 finalSize = m_scaledClipRect.size();
90 }
92 t.translate(tr2.x(), tr2.y());
93 t.scale(sc.width(), sc.height());
94 t.translate(tr1.x(), tr1.y());
95 bounds = t.mapRect(bounds);
96 }
97 qCDebug(qLcPdf) << m_page << finalSize;
98 if (image->size() != finalSize || !image->reinterpretAsFormat(QImage::Format_ARGB32_Premultiplied)) {
100 if (!finalSize.isEmpty() && image->isNull()) {
101 // avoid QTBUG-68229
102 qWarning("QPdfIOHandler: QImage allocation failed (size %i x %i)", finalSize.width(), finalSize.height());
103 return false;
104 }
105 }
106 if (!finalSize.isEmpty()) {
108 if (m_scaledClipRect.isValid())
109 options.setScaledClipRect(m_scaledClipRect);
110 options.setScaledSize(pageSize);
111 image->fill(m_backColor.rgba());
113 QImage pageImage = m_doc->render(m_page, finalSize, options);
114 p.drawImage(0, 0, pageImage);
115 p.end();
116 }
117 return true;
118 }
119
120 return false;
121}
122
124{
125 switch (option) {
126 case ImageFormat:
128 case Size:
129 const_cast<QPdfIOHandler *>(this)->load(device());
130 return m_doc->pagePointSize(qMax(0, m_page));
131 case ClipRect:
132 return m_clipRect;
133 case ScaledSize:
134 return m_scaledSize;
135 case ScaledClipRect:
136 return m_scaledClipRect;
137 case BackgroundColor:
138 return m_backColor;
139 case Name:
141 default:
142 break;
143 }
144 return QVariant();
145}
146
148{
149 switch (option) {
150 case ClipRect:
151 m_clipRect = value.toRect();
152 break;
153 case ScaledSize:
154 m_scaledSize = value.toSize();
155 break;
156 case ScaledClipRect:
157 m_scaledClipRect = value.toRect();
158 break;
159 case BackgroundColor:
160 m_backColor = value.value<QColor>();
161 break;
162 default:
163 break;
164 }
165}
166
168{
169 switch (option)
170 {
171 case ImageFormat:
172 case Size:
173 case ClipRect:
174 case ScaledSize:
175 case ScaledClipRect:
176 case BackgroundColor:
177 case Name:
178 return true;
179 default:
180 break;
181 }
182 return false;
183}
184
186{
187 qCDebug(qLcPdf) << frame;
188 if (frame < 0 || frame >= imageCount())
189 return false;
190 m_page = frame;
191 return true;
192}
193
195{
196 return jumpToImage(m_page + 1);
197}
198
199bool QPdfIOHandler::load(QIODevice *device)
200{
201 if (m_loaded)
202 return true;
203 if (format().isEmpty())
204 if (!canRead())
205 return false;
206
207 QPdfFile *pdfFile = qobject_cast<QPdfFile *>(device);
208 if (pdfFile) {
209 m_doc = pdfFile->document();
210 m_ownsDocument = false;
211 qCDebug(qLcPdf) << "loading via QPdfFile, reusing document instance" << m_doc;
212 } else {
213 m_doc = new QPdfDocument();
214 m_ownsDocument = true;
215 m_doc->load(device);
216 qCDebug(qLcPdf) << "loading via new document instance" << m_doc;
217 }
218 m_loaded = (m_doc->error() == QPdfDocument::Error::None);
219
220 return m_loaded;
221}
222
IOBluetoothDevice * device
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
QRgb rgba() const noexcept
Returns the RGB value of the color, including its alpha.
Definition qcolor.cpp:1376
int value() const noexcept
Returns the value color component of this color.
Definition qcolor.cpp:1756
\inmodule QtCore \reentrant
Definition qiodevice.h:34
qint64 peek(char *data, qint64 maxlen)
ImageOption
This enum describes the different options supported by QImageIOHandler.
QByteArray format() const
Returns the format that is currently assigned to QImageIOHandler.
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
\inmodule QtGui
Definition qimage.h:37
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
constexpr void setScaledClipRect(const QRect &r) noexcept
constexpr void setScaledSize(const QSize &s) noexcept
The QPdfDocument class loads a PDF document and renders pages from it.
Error error() const
Returns the type of error if \l status is Error, or NoError if there is no error.
QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options=QPdfDocumentRenderOptions())
Renders the page into a QImage of size imageSize according to the provided renderOptions.
int pageCount
This property holds the number of pages in the loaded document or 0 if no document is loaded.
QVariant metaData(MetaDataField field) const
Returns the meta data of the document for the given field.
Error load(const QString &fileName)
Loads the document contents from fileName.
Q_INVOKABLE QSizeF pagePointSize(int page) const
Returns the size of page page in points (1/72 of an inch).
QPdfDocument * document()
Definition qpdffile_p.h:29
bool supportsOption(ImageOption option) const override
Returns true if the QImageIOHandler supports the option option; otherwise returns false.
bool canRead() const override
Returns true if an image can be read from the device (i.e., the image format is supported,...
bool jumpToNextImage() override
For image formats that support animation, this function jumps to the next image.
bool jumpToImage(int frame) override
For image formats that support animation, this function jumps to the image whose sequence number is i...
QVariant option(ImageOption option) const override
Returns the value assigned to option as a QVariant.
~QPdfIOHandler() override
int currentImageNumber() const override
For image formats that support animation, this function returns the sequence number of the current im...
int imageCount() const override
For image formats that support animation, this function returns the number of images in the animation...
bool read(QImage *image) override
Read an image from the device, and stores it in image.
QRect currentImageRect() const override
Returns the rect of the current image.
void setOption(ImageOption option, const QVariant &value) override
Sets the option option with the value value.
\inmodule QtCore\reentrant
Definition qpoint.h:214
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
\inmodule QtCore\reentrant
Definition qrect.h:483
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
Definition qrect.h:169
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:220
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:241
\inmodule QtCore
Definition qsize.h:207
constexpr QSize toSize() const noexcept
Returns an integer based copy of this size.
Definition qsize.h:390
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:321
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:324
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:123
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
Definition qsize.h:126
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
\inmodule QtCore
Definition qvariant.h:64
Combined button and popup list for selecting options.
Definition image.cpp:4
int qstrncmp(const char *str1, const char *str2, size_t len)
#define Q_UNLIKELY(x)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:162
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
return ret
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLenum GLuint GLenum GLsizei const GLchar * buf
GLdouble GLdouble t
Definition qopenglext.h:243
GLfloat GLfloat p
[1]
GLuint GLenum option
double qreal
Definition qtypes.h:92
QFrame frame
[0]