QTextImageHandler: reduce code duplication
Refactor the getImage/Pixmap and getImageSize/PixmapSize functions into templates. The functions were practically identical, and the inconsistencies between them seem to be rather bugs or omissions than intentional. E.g. maintaining the aspect ratio if width/height are not specified was only implemented for the pixmap case. Task-number: QTBUG-109212 Change-Id: Ic0de0a2d7f883c4efac97111e2c1e438f278d70d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
This commit is contained in:
parent
2d87c4d881
commit
7c84a0cd29
@ -41,132 +41,68 @@ static inline QUrl fromLocalfileOrResources(QString path)
|
|||||||
return QUrl(path);
|
return QUrl(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
|
template<typename T>
|
||||||
|
static T getAs(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
|
||||||
{
|
{
|
||||||
qreal sourcePixelRatio = 1.0;
|
qreal sourcePixelRatio = 1.0;
|
||||||
const QString name = findAtNxFileOrResource(format.name(), devicePixelRatio, &sourcePixelRatio);
|
const QString name = findAtNxFileOrResource(format.name(), devicePixelRatio, &sourcePixelRatio);
|
||||||
const QUrl url = fromLocalfileOrResources(name);
|
const QUrl url = fromLocalfileOrResources(name);
|
||||||
|
|
||||||
QPixmap pm;
|
|
||||||
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
|
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
|
||||||
if (data.userType() == QMetaType::QPixmap || data.userType() == QMetaType::QImage) {
|
T result;
|
||||||
pm = qvariant_cast<QPixmap>(data);
|
if (data.userType() == QMetaType::QPixmap || data.userType() == QMetaType::QImage)
|
||||||
} else if (data.userType() == QMetaType::QByteArray) {
|
result = data.value<T>();
|
||||||
pm.loadFromData(data.toByteArray());
|
else if (data.metaType() == QMetaType::fromType<QByteArray>())
|
||||||
}
|
result.loadFromData(data.toByteArray());
|
||||||
|
|
||||||
if (pm.isNull()) {
|
if (result.isNull()) {
|
||||||
QImage img;
|
if (name.isEmpty() || !result.load(name))
|
||||||
if (name.isEmpty() || !img.load(name))
|
return T(":/qt-project.org/styles/commonstyle/images/file-16.png"_L1);
|
||||||
return QPixmap(":/qt-project.org/styles/commonstyle/images/file-16.png"_L1);
|
doc->addResource(QTextDocument::ImageResource, url, result);
|
||||||
|
|
||||||
pm = QPixmap::fromImage(img);
|
|
||||||
doc->addResource(QTextDocument::ImageResource, url, pm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name.contains("@2x"_L1))
|
|
||||||
pm.setDevicePixelRatio(sourcePixelRatio);
|
|
||||||
|
|
||||||
return pm;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format)
|
|
||||||
{
|
|
||||||
QPixmap pm;
|
|
||||||
|
|
||||||
const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
|
|
||||||
const int width = qRound(format.width());
|
|
||||||
const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
|
|
||||||
const int height = qRound(format.height());
|
|
||||||
|
|
||||||
QSize size(width, height);
|
|
||||||
if (!hasWidth || !hasHeight) {
|
|
||||||
pm = getPixmap(doc, format);
|
|
||||||
const QSizeF pmSize = pm.deviceIndependentSize();
|
|
||||||
|
|
||||||
if (!hasWidth) {
|
|
||||||
if (!hasHeight)
|
|
||||||
size.setWidth(pmSize.width());
|
|
||||||
else
|
|
||||||
size.setWidth(qRound(height * (pmSize.width() / (qreal) pmSize.height())));
|
|
||||||
}
|
|
||||||
if (!hasHeight) {
|
|
||||||
if (!hasWidth)
|
|
||||||
size.setHeight(pmSize.height());
|
|
||||||
else
|
|
||||||
size.setHeight(qRound(width * (pmSize.height() / (qreal) pmSize.width())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal scale = 1.0;
|
|
||||||
QPaintDevice *pdev = doc->documentLayout()->paintDevice();
|
|
||||||
if (pdev) {
|
|
||||||
if (pm.isNull())
|
|
||||||
pm = getPixmap(doc, format);
|
|
||||||
if (!pm.isNull())
|
|
||||||
scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
|
|
||||||
}
|
|
||||||
size *= scale;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QImage getImage(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
|
|
||||||
{
|
|
||||||
qreal sourcePixelRatio = 1.0;
|
|
||||||
const QString name = findAtNxFileOrResource(format.name(), devicePixelRatio, &sourcePixelRatio);
|
|
||||||
const QUrl url = fromLocalfileOrResources(name);
|
|
||||||
|
|
||||||
QImage image;
|
|
||||||
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
|
|
||||||
if (data.userType() == QMetaType::QImage) {
|
|
||||||
image = qvariant_cast<QImage>(data);
|
|
||||||
} else if (data.userType() == QMetaType::QByteArray) {
|
|
||||||
image.loadFromData(data.toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image.isNull()) {
|
|
||||||
if (name.isEmpty() || !image.load(name))
|
|
||||||
return QImage(":/qt-project.org/styles/commonstyle/images/file-16.png"_L1);
|
|
||||||
|
|
||||||
doc->addResource(QTextDocument::ImageResource, url, image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourcePixelRatio != 1.0)
|
if (sourcePixelRatio != 1.0)
|
||||||
image.setDevicePixelRatio(sourcePixelRatio);
|
result.setDevicePixelRatio(sourcePixelRatio);
|
||||||
|
return result;
|
||||||
return image;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QSize getImageSize(QTextDocument *doc, const QTextImageFormat &format)
|
template<typename T>
|
||||||
|
static QSize getSize(QTextDocument *doc, const QTextImageFormat &format)
|
||||||
{
|
{
|
||||||
QImage image;
|
|
||||||
|
|
||||||
const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
|
const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
|
||||||
const int width = qRound(format.width());
|
const int width = qRound(format.width());
|
||||||
const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
|
const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
|
||||||
const int height = qRound(format.height());
|
const int height = qRound(format.height());
|
||||||
|
|
||||||
|
T source;
|
||||||
QSize size(width, height);
|
QSize size(width, height);
|
||||||
if (!hasWidth || !hasHeight) {
|
if (!hasWidth || !hasHeight) {
|
||||||
image = getImage(doc, format);
|
source = getAs<T>(doc, format);
|
||||||
QSizeF imageSize = image.deviceIndependentSize();
|
const QSizeF sourceSize = source.deviceIndependentSize();
|
||||||
if (!hasWidth)
|
|
||||||
size.setWidth(imageSize.width());
|
if (!hasWidth) {
|
||||||
if (!hasHeight)
|
if (!hasHeight)
|
||||||
size.setHeight(imageSize.height());
|
size.setWidth(sourceSize.width());
|
||||||
|
else
|
||||||
|
size.setWidth(qRound(height * (sourceSize.width() / qreal(sourceSize.height()))));
|
||||||
|
}
|
||||||
|
if (!hasHeight) {
|
||||||
|
if (!hasWidth)
|
||||||
|
size.setHeight(sourceSize.height());
|
||||||
|
else
|
||||||
|
size.setHeight(qRound(width * (sourceSize.height() / qreal(sourceSize.width()))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal scale = 1.0;
|
qreal scale = 1.0;
|
||||||
QPaintDevice *pdev = doc->documentLayout()->paintDevice();
|
QPaintDevice *pdev = doc->documentLayout()->paintDevice();
|
||||||
if (pdev) {
|
if (pdev) {
|
||||||
if (image.isNull())
|
if (source.isNull())
|
||||||
image = getImage(doc, format);
|
source = getAs<T>(doc, format);
|
||||||
if (!image.isNull())
|
if (!source.isNull())
|
||||||
scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
|
scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
|
||||||
}
|
}
|
||||||
size *= scale;
|
size *= scale;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,15 +117,15 @@ QSizeF QTextImageHandler::intrinsicSize(QTextDocument *doc, int posInDocument, c
|
|||||||
const QTextImageFormat imageFormat = format.toImageFormat();
|
const QTextImageFormat imageFormat = format.toImageFormat();
|
||||||
|
|
||||||
if (QCoreApplication::instance()->thread() != QThread::currentThread())
|
if (QCoreApplication::instance()->thread() != QThread::currentThread())
|
||||||
return getImageSize(doc, imageFormat);
|
return getSize<QImage>(doc, imageFormat);
|
||||||
return getPixmapSize(doc, imageFormat);
|
return getSize<QPixmap>(doc, imageFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QTextImageHandler::image(QTextDocument *doc, const QTextImageFormat &imageFormat)
|
QImage QTextImageHandler::image(QTextDocument *doc, const QTextImageFormat &imageFormat)
|
||||||
{
|
{
|
||||||
Q_ASSERT(doc != nullptr);
|
Q_ASSERT(doc != nullptr);
|
||||||
|
|
||||||
return getImage(doc, imageFormat);
|
return getAs<QImage>(doc, imageFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format)
|
void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format)
|
||||||
@ -198,10 +134,10 @@ void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocumen
|
|||||||
const QTextImageFormat imageFormat = format.toImageFormat();
|
const QTextImageFormat imageFormat = format.toImageFormat();
|
||||||
|
|
||||||
if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
|
if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
|
||||||
const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatio());
|
const QImage image = getAs<QImage>(doc, imageFormat, p->device()->devicePixelRatio());
|
||||||
p->drawImage(rect, image, image.rect());
|
p->drawImage(rect, image, image.rect());
|
||||||
} else {
|
} else {
|
||||||
const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatio());
|
const QPixmap pixmap = getAs<QPixmap>(doc, imageFormat, p->device()->devicePixelRatio());
|
||||||
p->drawPixmap(rect, pixmap, pixmap.rect());
|
p->drawPixmap(rect, pixmap, pixmap.rect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user