1#include <memory>
2
3#include <QtTest/QTest>
4#include <QtCore/QDebug>
5#include <QImage>
6
7#include <poppler-qt6.h>
8
9// Unit tests for rendering axial shadings without full opacity
10class TestStrokeOpacity : public QObject
11{
12 Q_OBJECT
13public:
14 explicit TestStrokeOpacity(QObject *parent = nullptr) : QObject(parent) { }
15private slots:
16 void checkStrokeOpacity_data();
17 void checkStrokeOpacity();
18};
19
20void TestStrokeOpacity::checkStrokeOpacity_data()
21{
22 QTest::addColumn<int>(name: "backendType");
23
24 QTest::newRow(dataTag: "splash") << (int)Poppler::Document::SplashBackend;
25 QTest::newRow(dataTag: "qpainter") << (int)Poppler::Document::QPainterBackend;
26}
27
28void TestStrokeOpacity::checkStrokeOpacity()
29{
30 QFETCH(int, backendType);
31
32 std::unique_ptr<Poppler::Document> doc = Poppler::Document::load(TESTDATADIR "/unittestcases/stroke-alpha-pattern.pdf");
33 QVERIFY(doc != nullptr);
34
35 doc->setRenderBackend((Poppler::Document::RenderBackend)backendType);
36
37 // BUG: For some reason splash gets the opacity wrong when antialiasing is switched off
38 if (backendType == (int)Poppler::Document::SplashBackend) {
39 doc->setRenderHint(hint: Poppler::Document::Antialiasing, on: true);
40 }
41
42 const auto page = std::unique_ptr<Poppler::Page>(doc->page(index: 0));
43 QVERIFY(page != nullptr);
44
45 // Render (at low resolution and with cropped marging)
46 QImage image = page->renderToImage(xres: 36, yres: 36, x: 40, y: 50, w: 200, h: 230);
47
48 // The actual tests start here
49
50 // Allow a tolerance.
51 int tolerance;
52 auto approximatelyEqual = [&tolerance](QRgb c0, const QColor &c1) {
53 return std::abs(x: qAlpha(rgb: c0) - c1.alpha()) <= tolerance && std::abs(x: qRed(rgb: c0) - c1.red()) <= tolerance && std::abs(x: qGreen(rgb: c0) - c1.green()) <= tolerance && std::abs(x: qBlue(rgb: c0) - c1.blue()) <= tolerance;
54 };
55
56 // At the lower left of the test document is a square with an axial shading,
57 // which should be rendered with opacity 0.25.
58 // Check that with a sample pixel
59 auto pixel = image.pixel(x: 70, y: 160);
60
61 // Splash and QPainter backends implement shadings slightly differently,
62 // hence we cannot expect to get precisely the same colors.
63 tolerance = 2;
64 QVERIFY(approximatelyEqual(pixel, QColor(253, 233, 196, 255)));
65
66 // At the upper left of the test document is a stroked square with an axial shading.
67 // This is implemented by filling a clip region defined by a stroke outline.
68 // Check whether the backend really only renders the stroke, not the region
69 // surrounded by the stroke.
70 auto pixelUpperLeftInterior = image.pixel(x: 70, y: 70);
71
72 tolerance = 0;
73 QVERIFY(approximatelyEqual(pixelUpperLeftInterior, Qt::white));
74
75 // Now check whether that stroke is semi-transparent.
76 // Bug https://gitlab.freedesktop.org/poppler/poppler/-/issues/178
77 auto pixelUpperLeftOnStroke = image.pixel(x: 70, y: 20);
78
79 tolerance = 2;
80 QVERIFY(approximatelyEqual(pixelUpperLeftOnStroke, QColor(253, 233, 196, 255)));
81
82 // At the upper right there is a semi-transparent stroked red square
83 // a) Make sure that the color is correct.
84 auto pixelUpperRightOnStroke = image.pixel(x: 130, y: 20);
85
86 tolerance = 0;
87 QVERIFY(approximatelyEqual(pixelUpperRightOnStroke, QColor(246, 196, 206, 255)));
88
89 // b) Make sure that it is really stroked, not filled
90 auto pixelUpperRightInterior = image.pixel(x: 130, y: 50);
91 QVERIFY(approximatelyEqual(pixelUpperRightInterior, Qt::white));
92}
93
94QTEST_GUILESS_MAIN(TestStrokeOpacity)
95
96#include "check_stroke_opacity.moc"
97

source code of poppler/qt6/tests/check_stroke_opacity.cpp