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 QSizeF &size, qreal dpr) {
77 return QLatin1String(
"qt_textimagehandler_") % HexString<
int>(size.width())
78 % HexString<
int>(size.height())
79 % HexString<qint16>(qRound(dpr * 1000));
81 const QString cacheKey = canUsePixmapCache
82 ? buildCacheKey(size * devicePixelRatio, sourcePixelRatio)
85 if (canUsePixmapCache) {
87 if (QPixmapCache::find(cacheKey, &pm))
91 const auto readImage = [&](
auto &&content) {
92 QImageReader imgReader(content);
93 if (imgReader.canRead()) {
94 const bool supportsScaledSize = imgReader.supportsOption(QImageIOHandler::ScaledSize);
95 if (size.isValid() && supportsScaledSize)
96 imgReader.setScaledSize((size * devicePixelRatio).toSize());
97 QImage result = imgReader.read();
98 result.setDevicePixelRatio(sourcePixelRatio);
99 if (!supportsScaledSize)
100 doc->addResource(QTextDocument::ImageResource, url, result);
101 else if (canUsePixmapCache)
102 QPixmapCache::insert(cacheKey, QPixmap::fromImage(result));
109 if (data.metaType() == QMetaType::fromType<QByteArray>()) {
110 QByteArray ba(data.toByteArray());
112 result = readImage(&buf);
115 result = readImage(name);
118 result = QImage(
":/qt-project.org/styles/commonstyle/images/file-16.png"_L1);
122static QSize
getSize(QTextDocument *doc,
const QTextImageFormat &format)
124 const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
125 int width = qRound(format.width());
126 const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
127 const int height = qRound(format.height());
129 const bool hasMaxWidth = format.hasProperty(QTextFormat::ImageMaxWidth);
130 const auto maxWidth = format.maximumWidth();
132 int effectiveMaxWidth =
std::numeric_limits<
int>::max();
134 if (maxWidth.type() == QTextLength::PercentageLength)
135 effectiveMaxWidth = (doc->pageSize().width() - 2 * doc->documentMargin()) * maxWidth.value(100) / 100;
137 effectiveMaxWidth = maxWidth.rawValue();
139 width = qMin(effectiveMaxWidth, width);
143 QSize size(width, height);
144 if (!hasWidth || !hasHeight) {
145 source = getImage(doc, format);
146 QSizeF sourceSize = source.deviceIndependentSize();
148 if (sourceSize.width() > effectiveMaxWidth) {
150 sourceSize.setHeight(effectiveMaxWidth * (sourceSize.height() / qreal(sourceSize.width())));
151 sourceSize.setWidth(effectiveMaxWidth);
156 size.setWidth(sourceSize.width());
158 size.setWidth(qMin(effectiveMaxWidth, qRound(height * (sourceSize.width() / qreal(sourceSize.height())))));
162 size.setHeight(sourceSize.height());
164 size.setHeight(qRound(width * (sourceSize.height() / qreal(sourceSize.width()))));
168 const QPaintDevice *pdev = doc->documentLayout()->paintDevice();
170 size *= qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
195void QTextImageHandler::drawObject(QPainter *p,
const QRectF &rect, QTextDocument *doc,
int posInDocument,
const QTextFormat &format)
197 Q_UNUSED(posInDocument);
198 const QTextImageFormat imageFormat = format.toImageFormat();
200 const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatio(), rect.size());
201 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={})