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
qtextimagehandler.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
6
7#include <qguiapplication.h>
8#include <qtextformat.h>
9#include <qpainter.h>
10#include <qdebug.h>
11#include <qfile.h>
12#include <private/qtextengine_p.h>
13#include <qpalette.h>
14#include <qthread.h>
15#include <limits>
16
18
19using namespace Qt::StringLiterals;
20
21static inline QString findAtNxFileOrResource(const QString &baseFileName,
22 qreal targetDevicePixelRatio,
23 qreal *sourceDevicePixelRatio)
24{
25 // qt_findAtNxFile expects a file name that can be tested with QFile::exists.
26 // so if the format.name() is a file:/ or qrc:/ URL, then we need to strip away the schema.
27 QString localFile;
28 const QUrl url(baseFileName);
29 if (url.isLocalFile())
30 localFile = url.toLocalFile();
31 else if (baseFileName.startsWith("qrc:/"_L1))
32 localFile = baseFileName.sliced(3);
33 else
34 localFile = baseFileName;
35 extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
36 qreal *sourceDevicePixelRatio);
37 return qt_findAtNxFile(localFile, targetDevicePixelRatio, sourceDevicePixelRatio);
38}
39
41{
42 if (path.startsWith(":/"_L1)) // auto-detect resources and convert them to url
43 path = path.prepend("qrc"_L1);
44 return QUrl(path);
45}
46
47template<typename T>
48static T getAs(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
49{
50 qreal sourcePixelRatio = 1.0;
51 const QString name = findAtNxFileOrResource(format.name(), devicePixelRatio, &sourcePixelRatio);
53
55 T result;
56 if (data.userType() == QMetaType::QPixmap || data.userType() == QMetaType::QImage)
57 result = data.value<T>();
58 else if (data.metaType() == QMetaType::fromType<QByteArray>())
59 result.loadFromData(data.toByteArray());
60
61 if (result.isNull()) {
62 if (name.isEmpty() || !result.load(name))
63 return T(":/qt-project.org/styles/commonstyle/images/file-16.png"_L1);
65 }
66
67 if (sourcePixelRatio != 1.0)
68 result.setDevicePixelRatio(sourcePixelRatio);
69 return result;
70}
71
72template<typename T>
74{
75 const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
76 int width = qRound(format.width());
77 const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
78 const int height = qRound(format.height());
79
80 const bool hasMaxWidth = format.hasProperty(QTextFormat::ImageMaxWidth);
81 const auto maxWidth = format.maximumWidth();
82
83 int effectiveMaxWidth = std::numeric_limits<int>::max();
84 if (hasMaxWidth) {
85 if (maxWidth.type() == QTextLength::PercentageLength)
86 effectiveMaxWidth = (doc->pageSize().width() - 2 * doc->documentMargin()) * maxWidth.value(100) / 100;
87 else
88 effectiveMaxWidth = maxWidth.rawValue();
89
90 width = qMin(effectiveMaxWidth, width);
91 }
92
93 T source;
95 if (!hasWidth || !hasHeight) {
96 source = getAs<T>(doc, format);
97 QSizeF sourceSize = source.deviceIndependentSize();
98
99 if (sourceSize.width() > effectiveMaxWidth) {
100 // image is bigger than effectiveMaxWidth, scale it down
101 sourceSize.setHeight(effectiveMaxWidth * (sourceSize.height() / qreal(sourceSize.width())));
102 sourceSize.setWidth(effectiveMaxWidth);
103 }
104
105 if (!hasWidth) {
106 if (!hasHeight)
107 size.setWidth(sourceSize.width());
108 else
109 size.setWidth(qMin(effectiveMaxWidth, qRound(height * (sourceSize.width() / qreal(sourceSize.height())))));
110 }
111 if (!hasHeight) {
112 if (!hasWidth)
113 size.setHeight(sourceSize.height());
114 else
115 size.setHeight(qRound(width * (sourceSize.height() / qreal(sourceSize.width()))));
116 }
117 }
118
119 qreal scale = 1.0;
120 QPaintDevice *pdev = doc->documentLayout()->paintDevice();
121 if (pdev) {
122 if (source.isNull())
123 source = getAs<T>(doc, format);
124 if (!source.isNull())
125 scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
126 }
127 size *= scale;
128 return size;
129}
130
132 : QObject(parent)
133{
134}
135
137{
138 Q_UNUSED(posInDocument);
139 const QTextImageFormat imageFormat = format.toImageFormat();
140
142 return getSize<QImage>(doc, imageFormat);
143 return getSize<QPixmap>(doc, imageFormat);
144}
145
147{
148 Q_ASSERT(doc != nullptr);
149
150 return getAs<QImage>(doc, imageFormat);
151}
152
153void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format)
154{
155 Q_UNUSED(posInDocument);
156 const QTextImageFormat imageFormat = format.toImageFormat();
157
159 const QImage image = getAs<QImage>(doc, imageFormat, p->device()->devicePixelRatio());
160 p->drawImage(rect, image, image.rect());
161 } else {
162 const QPixmap pixmap = getAs<QPixmap>(doc, imageFormat, p->device()->devicePixelRatio());
163 p->drawPixmap(rect, pixmap, pixmap.rect());
164 }
165}
166
168
169#include "moc_qtextimagehandler_p.cpp"
QPaintDevice * paintDevice() const
Returns the paint device used to render the document's layout.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
\inmodule QtGui
Definition qimage.h:37
\inmodule QtCore
Definition qobject.h:103
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
int logicalDpiY() const
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore
Definition qsize.h:208
constexpr void setHeight(qreal h) noexcept
Sets the height to the given finite height.
Definition qsize.h:341
constexpr void setWidth(qreal w) noexcept
Sets the width to the given finite width.
Definition qsize.h:338
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
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString sliced(qsizetype pos) const &
Definition qstring.h:394
\reentrant \inmodule QtGui
QAbstractTextDocumentLayout * documentLayout() const
Returns the document layout for this document.
QSizeF pageSize
the page size that should be used for laying out the document
QVariant resource(int type, const QUrl &name) const
Returns data of the specified type from the resource with the given name.
void addResource(int type, const QUrl &name, const QVariant &resource)
Adds the resource resource to the resource cache, using type and name as identifiers.
\reentrant
Definition qtextformat.h:90
QTextImageFormat toImageFormat() const
Returns this format as an image format.
virtual void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) override
Draws this text object using the specified painter.
virtual QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) override
The intrinsicSize() function returns the size of the text object represented by format in the given d...
QTextImageHandler(QObject *parent=nullptr)
QImage image(QTextDocument *doc, const QTextImageFormat &imageFormat)
static QThread * currentThread()
Definition qthread.cpp:1039
\inmodule QtCore
Definition qurl.h:94
bool isLocalFile() const
Definition qurl.cpp:3445
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition qurl.cpp:3425
\inmodule QtCore
Definition qvariant.h:65
rect
[4]
Combined button and popup list for selecting options.
Definition image.cpp:4
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
Q_GUI_EXPORT int qt_defaultDpi()
Definition qfont.cpp:140
QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio, qreal *sourceDevicePixelRatio)
Definition qicon.cpp:1984
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei width
GLuint name
GLint GLsizei GLsizei GLenum format
GLsizei GLsizei GLchar * source
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLenum GLenum GLenum GLenum GLenum scale
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QSize getSize(QTextDocument *doc, const QTextImageFormat &format)
static QUrl fromLocalfileOrResources(QString path)
static T getAs(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio=1.0)
static QString findAtNxFileOrResource(const QString &baseFileName, qreal targetDevicePixelRatio, qreal *sourceDevicePixelRatio)
#define Q_UNUSED(x)
double qreal
Definition qtypes.h:187
QUrl url("example.com")
[constructor-url-reference]
widget render & pixmap