forked from qt-creator/qt-creator
QmlDesigner: Show ktx texture dimensions in tooltips
Tooltips in assets and material browser views now show correct dimensions for ktx files. Dimensions are read from ktx file header. Task-number: QDS-8851 Change-Id: Ia9ce195eba43e7a8d4fc9e4a980c3c56e75108b4 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -23,6 +23,7 @@ add_qtc_library(QmlDesignerUtils STATIC
|
||||
filedownloader.cpp filedownloader.h
|
||||
fileextractor.cpp fileextractor.h
|
||||
hdrimage.cpp hdrimage.h
|
||||
ktximage.cpp ktximage.h
|
||||
imageutils.cpp imageutils.h
|
||||
qmldesignerutils_global.h
|
||||
)
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <theme.h>
|
||||
#include <utils/hdrimage.h>
|
||||
#include <utils/ktximage.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -43,13 +44,16 @@ Thumbnail AssetsLibraryIconProvider::createThumbnail(const QString &id, const QS
|
||||
{
|
||||
auto [pixmap, fileSize] = fetchPixmap(id, requestedSize);
|
||||
QSize originalSize = pixmap.size();
|
||||
Asset::Type assetType = Asset(id).type();
|
||||
Asset asset(id);
|
||||
Asset::Type assetType = asset.type();
|
||||
|
||||
if (pixmap.isNull()) {
|
||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/AssetsLibrary/images/assets_default.png");
|
||||
|
||||
if (assetType == Asset::Image)
|
||||
assetType = Asset::MissingImage;
|
||||
else if (asset.isKtxFile())
|
||||
originalSize = KtxImage(id).dimensions();
|
||||
}
|
||||
|
||||
if (requestedSize.isValid())
|
||||
@@ -86,6 +90,10 @@ QPair<QPixmap, qint64> AssetsLibraryIconProvider::fetchPixmap(const QString &id,
|
||||
qint64 size = QFileInfo(id).size();
|
||||
QPixmap pixmap = HdrImage{id}.toPixmap();
|
||||
return {pixmap, size};
|
||||
} else if (asset.isKtxFile()) {
|
||||
qint64 size = QFileInfo(id).size();
|
||||
// TODO: Return ktx specific default image once available (QDS-9140)
|
||||
return {{}, size};
|
||||
} else {
|
||||
QString type;
|
||||
if (asset.isShader())
|
||||
@@ -129,12 +137,5 @@ qint64 AssetsLibraryIconProvider::fileSize(const QString &id)
|
||||
return m_thumbnails.contains(id) ? m_thumbnails[id].fileSize : 0;
|
||||
}
|
||||
|
||||
bool AssetsLibraryIconProvider::assetIsImage(const QString &id)
|
||||
{
|
||||
return m_thumbnails.contains(id)
|
||||
? (m_thumbnails[id].assetType == Asset::Type::Image || Asset(id).isHdrFile())
|
||||
: false;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
|
@@ -29,7 +29,6 @@ public:
|
||||
void invalidateThumbnail(const QString &id);
|
||||
QSize imageSize(const QString &id);
|
||||
qint64 fileSize(const QString &id);
|
||||
bool assetIsImage(const QString &id);
|
||||
|
||||
private:
|
||||
QPixmap generateFontIcons(const QString &filePath, const QSize &requestedSize) const;
|
||||
|
@@ -251,7 +251,8 @@ QString AssetsLibraryWidget::assetFileSize(const QString &id)
|
||||
|
||||
bool AssetsLibraryWidget::assetIsImage(const QString &id)
|
||||
{
|
||||
return m_assetsIconProvider->assetIsImage(id);
|
||||
Asset asset(id);
|
||||
return asset.isImage() || asset.isTexture3D();
|
||||
}
|
||||
|
||||
QList<QToolButton *> AssetsLibraryWidget::createToolBarWidgets()
|
||||
|
@@ -161,6 +161,11 @@ bool Asset::isHdrFile() const
|
||||
return m_suffix == "*.hdr";
|
||||
}
|
||||
|
||||
bool Asset::isKtxFile() const
|
||||
{
|
||||
return m_suffix == "*.ktx";
|
||||
}
|
||||
|
||||
bool Asset::isEffect() const
|
||||
{
|
||||
return type() == Asset::Type::Effect;
|
||||
|
@@ -35,6 +35,7 @@ public:
|
||||
bool isVideo() const;
|
||||
bool isTexture3D() const;
|
||||
bool isHdrFile() const;
|
||||
bool isKtxFile() const;
|
||||
bool isEffect() const;
|
||||
bool isSupported() const;
|
||||
|
||||
|
@@ -21,7 +21,7 @@ typedef unsigned char RGBE[4];
|
||||
|
||||
constexpr float GAMMA = 1.f / 2.2f;
|
||||
|
||||
QByteArray fileToByteArray(QString const &filename)
|
||||
static QByteArray fileToByteArray(QString const &filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
QFileInfo info(file);
|
||||
|
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "imageutils.h"
|
||||
|
||||
#include "ktximage.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QImageReader>
|
||||
@@ -17,7 +19,8 @@ QString QmlDesigner::ImageUtils::imageInfo(const QString &path)
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
if (info.suffix() == "hdr") {
|
||||
const QString suffix = info.suffix();
|
||||
if (suffix == "hdr") {
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return {};
|
||||
@@ -27,6 +30,10 @@ QString QmlDesigner::ImageUtils::imageInfo(const QString &path)
|
||||
if (sscanf(line.constData(), "-Y %d +X %d", &height, &width))
|
||||
break;
|
||||
}
|
||||
} else if (suffix == "ktx") {
|
||||
KtxImage ktx(path);
|
||||
width = ktx.dimensions().width();
|
||||
height = ktx.dimensions().height();
|
||||
} else {
|
||||
QSize size = QImageReader(path).size();
|
||||
width = size.width();
|
||||
|
100
src/plugins/qmldesigner/utils/ktximage.cpp
Normal file
100
src/plugins/qmldesigner/utils/ktximage.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "ktximage.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
// Ktx images currently support only image metadata
|
||||
|
||||
static QByteArray fileToByteArray(QString const &filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
QFileInfo info(file);
|
||||
|
||||
if (info.exists() && file.open(QFile::ReadOnly)) {
|
||||
// Read data until we have what we need
|
||||
// Content is:
|
||||
// Byte[12] identifier
|
||||
// UInt32 endianness
|
||||
// UInt32
|
||||
// UInt32
|
||||
// UInt32
|
||||
// Uint32
|
||||
// Uint32
|
||||
// UInt32 pixelWidth
|
||||
// UInt32 pixelHeight
|
||||
// ...
|
||||
return file.read(44);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
KtxImage::KtxImage(const QString &fileName)
|
||||
: m_fileName(fileName)
|
||||
{
|
||||
loadKtx();
|
||||
}
|
||||
|
||||
QSize KtxImage::dimensions() const
|
||||
{
|
||||
return m_dim;
|
||||
}
|
||||
|
||||
void KtxImage::loadKtx()
|
||||
{
|
||||
QByteArray buf(fileToByteArray(m_fileName));
|
||||
|
||||
auto handleError = [this](const QString &error) {
|
||||
qWarning() << QStringLiteral("Failed to load KTX image '%1': %2.").arg(m_fileName, error).toUtf8();
|
||||
};
|
||||
|
||||
if (buf.isEmpty()) {
|
||||
handleError("File open failed");
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr char ktxIdentifier[12] = {
|
||||
'\xAB', 'K', 'T', 'X', ' ', '1',
|
||||
'1', '\xBB', '\r', '\n', '\x1A', '\n'
|
||||
};
|
||||
|
||||
if (!buf.startsWith(ktxIdentifier)) {
|
||||
handleError("Non-KTX file");
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf.size() < 44) {
|
||||
handleError("Missing metadata");
|
||||
return;
|
||||
}
|
||||
|
||||
quint32 w = 0;
|
||||
quint32 h = 0;
|
||||
|
||||
if (*reinterpret_cast<const quint32 *>(buf.data() + 12) == 0x01020304) {
|
||||
// File endianness is different from our endianness
|
||||
QByteArray convBuf(4, 0);
|
||||
auto convertEndianness = [&convBuf, &buf](int idx) -> quint32 {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
convBuf[i] = buf[idx + 3 - i];
|
||||
return *reinterpret_cast<const quint32 *>(convBuf.data());
|
||||
};
|
||||
w = convertEndianness(36);
|
||||
h = convertEndianness(40);
|
||||
} else {
|
||||
w = *reinterpret_cast<const quint32 *>(buf.data() + 36);
|
||||
h = *reinterpret_cast<const quint32 *>(buf.data() + 40);
|
||||
}
|
||||
|
||||
m_dim = QSize(w, h);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
29
src/plugins/qmldesigner/utils/ktximage.h
Normal file
29
src/plugins/qmldesigner/utils/ktximage.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
#pragma once
|
||||
|
||||
#include "qmldesignerutils_global.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class QMLDESIGNERUTILS_EXPORT KtxImage
|
||||
{
|
||||
public:
|
||||
KtxImage(const QString &fileName);
|
||||
|
||||
QString fileName() const { return m_fileName; }
|
||||
QSize dimensions() const;
|
||||
|
||||
private:
|
||||
void loadKtx();
|
||||
|
||||
QString m_fileName;
|
||||
QSize m_dim;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
Reference in New Issue
Block a user