27 qreal targetDevicePixelRatio,
28 qreal *sourceDevicePixelRatio,
34 const QUrl url(baseFileName);
35 bool hasFileScheme =
false;
36 bool isResource =
false;
37 if (url.isLocalFile()) {
38 localFile = url.toLocalFile();
40 }
else if (baseFileName.startsWith(
"qrc:/"_L1)) {
42 localFile = baseFileName.sliced(3);
45 localFile = baseFileName;
46 isResource = baseFileName.startsWith(
":/"_L1);
48 *name = qt_findAtNxFile(localFile, targetDevicePixelRatio, sourceDevicePixelRatio);
51 return QUrl::fromLocalFile(*name);
53 return QUrl(
"qrc"_L1 + *name);
58 const qreal devicePixelRatio = 1.0,
const QSizeF &size = {})
60 qreal sourcePixelRatio = 1.0;
62 const QUrl url = findAtNxFileOrResource(format.name(), devicePixelRatio, &sourcePixelRatio, &name);
63 const QVariant data = doc->resource(QTextDocument::ImageResource, url);
66 if (data.userType() == QMetaType::QPixmap || data.userType() == QMetaType::QImage)
67 return data.value<QImage>();
73 const bool canUsePixmapCache = (QThread::isMainThread()
74 || QGuiApplicationPrivate::platformIntegration()->hasCapability(
75 QPlatformIntegration::ThreadedPixmaps));
76 const auto buildCacheKey = [](
const QString &name,
const QSizeF &size, qreal dpr) -> QString {
77 return QLatin1String(
"qt_textimagehandler_") % name
78 % HexString<
int>(size.width())
79 % HexString<
int>(size.height())
80 % HexString<qint16>(qRound(dpr * 1000));
82 const QString cacheKey = canUsePixmapCache
83 ? buildCacheKey(name, size * devicePixelRatio, sourcePixelRatio)
86 if (canUsePixmapCache) {
88 if (QPixmapCache::find(cacheKey, &pm))
92 const auto readImage = [&](
auto &&content) {
93 QImageReader imgReader(content);
94 if (imgReader.canRead()) {
95 const bool supportsScaledSize = imgReader.supportsOption(QImageIOHandler::ScaledSize);
96 if (size.isValid() && supportsScaledSize)
97 imgReader.setScaledSize((size * devicePixelRatio).toSize());
98 QImage result = imgReader.read();
99 result.setDevicePixelRatio(sourcePixelRatio);
100 if (!supportsScaledSize)
101 doc->addResource(QTextDocument::ImageResource, url, result);
102 else if (canUsePixmapCache)
103 QPixmapCache::insert(cacheKey, QPixmap::fromImage(result));
110 if (data.metaType() == QMetaType::fromType<QByteArray>()) {
111 QByteArray ba(data.toByteArray());
113 result = readImage(&buf);
116 result = readImage(name);
119 result = QImage(
":/qt-project.org/styles/commonstyle/images/file-16.png"_L1);
123static QSize
getSize(QTextDocument *doc,
const QTextImageFormat &format)
125 const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
126 int width = qRound(format.width());
127 const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
128 const int height = qRound(format.height());
130 const bool hasMaxWidth = format.hasProperty(QTextFormat::ImageMaxWidth);
131 const auto maxWidth = format.maximumWidth();
133 int effectiveMaxWidth =
std::numeric_limits<
int>::max();
135 if (maxWidth.type() == QTextLength::PercentageLength)
136 effectiveMaxWidth = (doc->pageSize().width() - 2 * doc->documentMargin()) * maxWidth.value(100) / 100;
138 effectiveMaxWidth = maxWidth.rawValue();
140 width = qMin(effectiveMaxWidth, width);
144 QSize size(width, height);
145 if (!hasWidth || !hasHeight) {
146 source = getImage(doc, format);
147 QSizeF sourceSize = source.deviceIndependentSize();
149 if (sourceSize.width() > effectiveMaxWidth) {
151 sourceSize.setHeight(effectiveMaxWidth * (sourceSize.height() / qreal(sourceSize.width())));
152 sourceSize.setWidth(effectiveMaxWidth);
157 size.setWidth(sourceSize.width());
159 size.setWidth(qMin(effectiveMaxWidth, qRound(height * (sourceSize.width() / qreal(sourceSize.height())))));
163 size.setHeight(sourceSize.height());
165 size.setHeight(qRound(width * (sourceSize.height() / qreal(sourceSize.width()))));
169 const QPaintDevice *pdev = doc->documentLayout()->paintDevice();
171 size *= qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
196void QTextImageHandler::drawObject(QPainter *p,
const QRectF &rect, QTextDocument *doc,
int posInDocument,
const QTextFormat &format)
198 Q_UNUSED(posInDocument);
199 const QTextImageFormat imageFormat = format.toImageFormat();
201 const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatio(), rect.size());
202 p->drawImage(rect, image, image.rect());
static QUrl findAtNxFileOrResource(const QString &baseFileName, qreal targetDevicePixelRatio, qreal *sourceDevicePixelRatio, QString *name)
static QSize getSize(QTextDocument *doc, const QTextImageFormat &format)
static QImage getImage(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio=1.0, const QSizeF &size={})