diff --git a/src/Gui/BitmapFactory.cpp b/src/Gui/BitmapFactory.cpp index 8333807dea..73383d2e13 100644 --- a/src/Gui/BitmapFactory.cpp +++ b/src/Gui/BitmapFactory.cpp @@ -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 { diff --git a/tests/src/Gui/BitmapFactory.cpp b/tests/src/Gui/BitmapFactory.cpp new file mode 100644 index 0000000000..c8e3eec9ee --- /dev/null +++ b/tests/src/Gui/BitmapFactory.cpp @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace +{ + +// Minimal valid SVG used as test icon +constexpr const char* kTestSvg = + R"()"; + +} // 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(64 * expectedDpr); + EXPECT_EQ(px.width(), expectedPhysical); + EXPECT_EQ(px.height(), expectedPhysical); + + Gui::BitmapFactory().removePath(tmpDir.path()); +} diff --git a/tests/src/Gui/CMakeLists.txt b/tests/src/Gui/CMakeLists.txt index aa7ed73357..bcf8b5d9f6 100644 --- a/tests/src/Gui/CMakeLists.txt +++ b/tests/src/Gui/CMakeLists.txt @@ -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