Qt 6.x
The Qt SDK
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
17
18using namespace Qt::StringLiterals;
19
20static inline QString findAtNxFileOrResource(const QString &baseFileName,
21 qreal targetDevicePixelRatio,
22 qreal *sourceDevicePixelRatio)
23{
24 // qt_findAtNxFile expects a file name that can be tested with QFile::exists.
25 // so if the format.name() is a file:/ or qrc:/ URL, then we need to strip away the schema.
26 QString localFile = baseFileName;
27 if (localFile.startsWith("file:/"_L1))
28 localFile = localFile.sliced(6);
29 else if (localFile.startsWith("qrc:/"_L1))
30 localFile = localFile.sliced(3);
31
32 extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
33 qreal *sourceDevicePixelRatio);
34 return qt_findAtNxFile(localFile, targetDevicePixelRatio, sourceDevicePixelRatio);
35}
36
38{
39 if (path.startsWith(":/"_L1)) // auto-detect resources and convert them to url
40 path = path.prepend("qrc"_L1);
41 return QUrl(path);
42}
43
44template<typename T>
45static T getAs(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
46{
47 qreal sourcePixelRatio = 1.0;
48 const QString name = findAtNxFileOrResource(format.name(), devicePixelRatio, &sourcePixelRatio);
50
52 T result;
53 if (data.userType() == QMetaType::QPixmap || data.userType() == QMetaType::QImage)
54 result = data.value<T>();
55 else if (data.metaType() == QMetaType::fromType<QByteArray>())
56 result.loadFromData(data.toByteArray());
57
58 if (result.isNull()) {
59 if (name.isEmpty() || !result.load(name))
60 return T(":/qt-project.org/styles/commonstyle/images/file-16.png"_L1);
62 }
63
64 if (sourcePixelRatio != 1.0)
65 result.setDevicePixelRatio(sourcePixelRatio);
66 return result;
67}
68
69template<typename T>
71{
72 const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
73 const int width = qRound(format.width());
74 const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
75 const int height = qRound(format.height());
76
77 T source;
79 if (!hasWidth || !hasHeight) {
80 source = getAs<T>(doc, format);
81 const QSizeF sourceSize = source.deviceIndependentSize();
82
83 if (!hasWidth) {
84 if (!hasHeight)
85 size.setWidth(sourceSize.width());
86 else
87 size.setWidth(qRound(height * (sourceSize.width() / qreal(sourceSize.height()))));
88 }
89 if (!hasHeight) {
90 if (!hasWidth)
91 size.setHeight(sourceSize.height());
92 else
93 size.setHeight(qRound(width * (sourceSize.height() / qreal(sourceSize.width()))));
94 }
95 }
96
97 qreal scale = 1.0;
98 QPaintDevice *pdev = doc->documentLayout()->paintDevice();
99 if (pdev) {
100 if (source.isNull())
101 source = getAs<T>(doc, format);
102 if (!source.isNull())
103 scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
104 }
105 size *= scale;
106 return size;
107}
108
110 : QObject(parent)
111{
112}
113
115{
116 Q_UNUSED(posInDocument);
117 const QTextImageFormat imageFormat = format.toImageFormat();
118
120 return getSize<QImage>(doc, imageFormat);
121 return getSize<QPixmap>(doc, imageFormat);
122}
123
125{
126 Q_ASSERT(doc != nullptr);
127
128 return getAs<QImage>(doc, imageFormat);
129}
130
131void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format)
132{
133 Q_UNUSED(posInDocument);
134 const QTextImageFormat imageFormat = format.toImageFormat();
135
137 const QImage image = getAs<QImage>(doc, imageFormat, p->device()->devicePixelRatio());
138 p->drawImage(rect, image, image.rect());
139 } else {
140 const QPixmap pixmap = getAs<QPixmap>(doc, imageFormat, p->device()->devicePixelRatio());
141 p->drawPixmap(rect, pixmap, pixmap.rect());
142 }
143}
144
146
147#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:90
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1561
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:483
\inmodule QtCore
Definition qsize.h:207
constexpr void setWidth(qreal w) noexcept
Sets the width to the given finite width.
Definition qsize.h:327
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
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5299
QString sliced(qsizetype pos) const
Definition qstring.h:341
\reentrant \inmodule QtGui
QAbstractTextDocumentLayout * documentLayout() const
Returns the document layout for this 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:966
\inmodule QtCore
Definition qurl.h:94
\inmodule QtCore
Definition qvariant.h:64
rect
[4]
Combined button and popup list for selecting options.
Definition image.cpp:4
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
Q_GUI_EXPORT int qt_defaultDpi()
Definition qfont.cpp:137
QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio, qreal *sourceDevicePixelRatio)
Definition qicon.cpp:1528
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei width
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
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:92
QUrl url("example.com")
[constructor-url-reference]
widget render & pixmap
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent