Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
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_doc.isNull() || 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 if (!m_doc.isNull()) {
114 QImage pageImage = m_doc->render(m_page, finalSize, options);
115 p.drawImage(0, 0, pageImage);
116 p.end();
117 }
118 }
119 return true;
120 }
121
122 return false;
123}
124
126{
127 switch (option) {
128 case ImageFormat:
130 case Size:
131 const_cast<QPdfIOHandler *>(this)->load(device());
132 return m_doc->pagePointSize(qMax(0, m_page));
133 case ClipRect:
134 return m_clipRect;
135 case ScaledSize:
136 return m_scaledSize;
137 case ScaledClipRect:
138 return m_scaledClipRect;
139 case BackgroundColor:
140 return m_backColor;
141 case Name:
143 default:
144 break;
145 }
146 return QVariant();
147}
148
150{
151 switch (option) {
152 case ClipRect:
153 m_clipRect = value.toRect();
154 break;
155 case ScaledSize:
156 m_scaledSize = value.toSize();
157 break;
158 case ScaledClipRect:
159 m_scaledClipRect = value.toRect();
160 break;
161 case BackgroundColor:
162 m_backColor = value.value<QColor>();
163 break;
164 default:
165 break;
166 }
167}
168
170{
171 switch (option)
172 {
173 case ImageFormat:
174 case Size:
175 case ClipRect:
176 case ScaledSize:
177 case ScaledClipRect:
178 case BackgroundColor:
179 case Name:
180 return true;
181 default:
182 break;
183 }
184 return false;
185}
186
188{
189 qCDebug(qLcPdf) << frame;
190 if (frame < 0 || frame >= imageCount())
191 return false;
192 m_page = frame;
193 return true;
194}
195
197{
198 return jumpToImage(m_page + 1);
199}
200
201bool QPdfIOHandler::load(QIODevice *device)
202{
203 if (m_loaded)
204 return true;
205 if (format().isEmpty())
206 if (!canRead())
207 return false;
208
209 QPdfFile *pdfFile = qobject_cast<QPdfFile *>(device);
210 if (pdfFile) {
211 m_doc = pdfFile->document();
212 m_ownsDocument = false;
213 qCDebug(qLcPdf) << "loading via QPdfFile, reusing document instance" << m_doc;
214 } else {
215 m_doc = new QPdfDocument();
216 m_ownsDocument = true;
217 m_doc->load(device);
218 qCDebug(qLcPdf) << "loading via new document instance" << m_doc;
219 }
220 m_loaded = (m_doc->error() == QPdfDocument::Error::None);
221
222 return m_loaded;
223}
224
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).
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:217
\inmodule QtCore\reentrant
Definition qpoint.h:25
bool isNull() const noexcept
Definition qpointer.h:84
\inmodule QtCore\reentrant
Definition qrect.h:484
\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:170
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:221
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
\inmodule QtCore
Definition qsize.h:208
constexpr QSize toSize() const noexcept
Returns an integer based copy of this size.
Definition qsize.h:401
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:332
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:335
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
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:127
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
\inmodule QtCore
Definition qvariant.h:65
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:166
#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:187
QFrame frame
[0]