| #include <memory> |
| |
| #include <QtTest/QTest> |
| #include <QtCore/QDebug> |
| #include <QImage> |
| |
| #include <poppler-qt6.h> |
| |
| // Unit tests for rendering axial shadings without full opacity |
| class TestStrokeOpacity : public QObject |
| { |
| Q_OBJECT |
| public: |
| explicit TestStrokeOpacity(QObject *parent = nullptr) : QObject(parent) { } |
| private slots: |
| void checkStrokeOpacity_data(); |
| void checkStrokeOpacity(); |
| }; |
| |
| void TestStrokeOpacity::checkStrokeOpacity_data() |
| { |
| QTest::addColumn<int>("backendType"); |
| |
| QTest::newRow("splash") << (int)Poppler::Document::SplashBackend; |
| QTest::newRow("qpainter") << (int)Poppler::Document::QPainterBackend; |
| } |
| |
| void TestStrokeOpacity::checkStrokeOpacity() |
| { |
| QFETCH(int, backendType); |
| |
| std::unique_ptr<Poppler::Document> doc = Poppler::Document::load(TESTDATADIR "/unittestcases/stroke-alpha-pattern.pdf"); |
| QVERIFY(doc != nullptr); |
| |
| doc->setRenderBackend((Poppler::Document::RenderBackend)backendType); |
| |
| // BUG: For some reason splash gets the opacity wrong when antialiasing is switched off |
| if (backendType == (int)Poppler::Document::SplashBackend) { |
| doc->setRenderHint(Poppler::Document::Antialiasing, true); |
| } |
| |
| const auto page = std::unique_ptr<Poppler::Page>(doc->page(0)); |
| QVERIFY(page != nullptr); |
| |
| // Render (at low resolution and with cropped marging) |
| QImage image = page->renderToImage(36, 36, 40, 50, 200, 230); |
| |
| // The actual tests start here |
| |
| // Allow a tolerance. |
| int tolerance; |
| auto approximatelyEqual = [&tolerance](QRgb c0, const QColor &c1) { |
| return std::abs(qAlpha(c0) - c1.alpha()) <= tolerance && std::abs(qRed(c0) - c1.red()) <= tolerance && std::abs(qGreen(c0) - c1.green()) <= tolerance && std::abs(qBlue(c0) - c1.blue()) <= tolerance; |
| }; |
| |
| // At the lower left of the test document is a square with an axial shading, |
| // which should be rendered with opacity 0.25. |
| // Check that with a sample pixel |
| auto pixel = image.pixel(70, 160); |
| |
| // Splash and QPainter backends implement shadings slightly differently, |
| // hence we cannot expect to get precisely the same colors. |
| tolerance = 2; |
| QVERIFY(approximatelyEqual(pixel, QColor(253, 233, 196, 255))); |
| |
| // At the upper left of the test document is a stroked square with an axial shading. |
| // This is implemented by filling a clip region defined by a stroke outline. |
| // Check whether the backend really only renders the stroke, not the region |
| // surrounded by the stroke. |
| auto pixelUpperLeftInterior = image.pixel(70, 70); |
| |
| tolerance = 0; |
| QVERIFY(approximatelyEqual(pixelUpperLeftInterior, Qt::white)); |
| |
| // Now check whether that stroke is semi-transparent. |
| // Bug https://gitlab.freedesktop.org/poppler/poppler/-/issues/178 |
| auto pixelUpperLeftOnStroke = image.pixel(70, 20); |
| |
| tolerance = 2; |
| QVERIFY(approximatelyEqual(pixelUpperLeftOnStroke, QColor(253, 233, 196, 255))); |
| |
| // At the upper right there is a semi-transparent stroked red square |
| // a) Make sure that the color is correct. |
| auto pixelUpperRightOnStroke = image.pixel(130, 20); |
| |
| tolerance = 0; |
| QVERIFY(approximatelyEqual(pixelUpperRightOnStroke, QColor(246, 196, 206, 255))); |
| |
| // b) Make sure that it is really stroked, not filled |
| auto pixelUpperRightInterior = image.pixel(130, 50); |
| QVERIFY(approximatelyEqual(pixelUpperRightInterior, Qt::white)); |
| } |
| |
| QTEST_GUILESS_MAIN(TestStrokeOpacity) |
| |
| #include "check_stroke_opacity.moc" |