fix(gui): make SVG icon rasterization DPI-aware in loadPixmap (#189) #266
@@ -217,7 +217,9 @@ bool BitmapFactoryInst::loadPixmap(const QString& filename, QPixmap& icon) const
|
||||
QFile svgFile(fi.filePath());
|
||||
if (svgFile.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QByteArray content = svgFile.readAll();
|
||||
icon = pixmapFromSvg(content, QSize(64, 64));
|
||||
static qreal dpr = getMaximumDPR();
|
||||
icon = pixmapFromSvg(content, QSize(64, 64) * dpr);
|
||||
icon.setDevicePixelRatio(dpr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
92
tests/src/Gui/BitmapFactory.cpp
Normal file
92
tests/src/Gui/BitmapFactory.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
#include <Gui/BitmapFactory.h>
|
||||
|
||||
#include <src/App/InitApplication.h>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Minimal valid SVG used as test icon
|
||||
constexpr const char* kTestSvg =
|
||||
R"(<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64")"
|
||||
R"( viewBox="0 0 64 64"><rect width="64" height="64" fill="#ff0000"/></svg>)";
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
class BitmapFactoryTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
static void SetUpTestSuite()
|
||||
{
|
||||
tests::initApplication();
|
||||
|
||||
// QPixmap and QSvgRenderer require a QGuiApplication.
|
||||
// gtest_main does not create one, so we construct it here.
|
||||
if (!QApplication::instance()) {
|
||||
static int argc = 1;
|
||||
static char arg0[] = "Gui_tests_run";
|
||||
static char* argv[] = {arg0, nullptr};
|
||||
static QApplication app(argc, argv);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// pixmapFromSvg(content, size) renders at the exact requested size
|
||||
TEST_F(BitmapFactoryTest, PixmapFromSvgContentRendersAtRequestedSize)
|
||||
{
|
||||
QByteArray svg(kTestSvg);
|
||||
QSize requested(48, 48);
|
||||
QPixmap px = Gui::BitmapFactory().pixmapFromSvg(svg, requested);
|
||||
|
||||
ASSERT_FALSE(px.isNull());
|
||||
EXPECT_EQ(px.width(), 48);
|
||||
EXPECT_EQ(px.height(), 48);
|
||||
}
|
||||
|
||||
// getMaximumDPR returns at least 1.0
|
||||
TEST_F(BitmapFactoryTest, MaximumDPRIsAtLeastOne)
|
||||
{
|
||||
qreal dpr = Gui::BitmapFactoryInst::getMaximumDPR();
|
||||
EXPECT_GE(dpr, 1.0);
|
||||
}
|
||||
|
||||
// pixmap() loaded from an SVG file has correct devicePixelRatio and physical size
|
||||
TEST_F(BitmapFactoryTest, PixmapFromSvgFileHasCorrectDPR)
|
||||
{
|
||||
// Write a test SVG to a temporary directory
|
||||
QTemporaryDir tmpDir;
|
||||
ASSERT_TRUE(tmpDir.isValid());
|
||||
|
||||
QString svgPath = tmpDir.path() + QDir::separator() + "test-dpi-icon.svg";
|
||||
QFile file(svgPath);
|
||||
ASSERT_TRUE(file.open(QFile::WriteOnly | QFile::Text));
|
||||
file.write(kTestSvg);
|
||||
file.close();
|
||||
|
||||
// Add the temp dir as a search path and load via pixmap()
|
||||
Gui::BitmapFactory().addPath(tmpDir.path());
|
||||
QPixmap px = Gui::BitmapFactory().pixmap("test-dpi-icon");
|
||||
|
||||
ASSERT_FALSE(px.isNull());
|
||||
|
||||
qreal expectedDpr = Gui::BitmapFactoryInst::getMaximumDPR();
|
||||
EXPECT_DOUBLE_EQ(px.devicePixelRatio(), expectedDpr);
|
||||
|
||||
// Physical size should be 64 * dpr
|
||||
int expectedPhysical = static_cast<int>(64 * expectedDpr);
|
||||
EXPECT_EQ(px.width(), expectedPhysical);
|
||||
EXPECT_EQ(px.height(), expectedPhysical);
|
||||
|
||||
Gui::BitmapFactory().removePath(tmpDir.path());
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
# Standard C++ GTest tests
|
||||
add_executable(Gui_tests_run
|
||||
Assistant.cpp
|
||||
BitmapFactory.cpp
|
||||
Camera.cpp
|
||||
StyleParameters/StyleParametersApplicationTest.cpp
|
||||
StyleParameters/ParserTest.cpp
|
||||
|
||||
Reference in New Issue
Block a user