qt5/src/poppler-page.cc | 8 ++++---- qt5/tests/CMakeLists.txt | 1 + qt5/tests/check_overprint.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ qt6/src/poppler-page.cc | 8 ++++---- qt6/tests/CMakeLists.txt | 1 + qt6/tests/check_overprint.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 8 deletions(-)
New commits: commit 6ebe45e8dceae11d02c74df47c34f4490a45a15e Author: Kevin Ottens <kevin.ott...@enioka.com> Date: Wed Jun 21 15:10:48 2023 +0200 Don't crash when overprint preview is enabled with the Qt bindings When overprint preview is enabled, the image data row size changes during conversion to XBGR. The Qt bindings were assuming this row size was constant which led to badly broken QImages at conversion time (generating garbage if displayed or even crashing). This commit simply add regression tests for the case and gets the row size after bitmap conversion. diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc index b2cea93b..43c7d9fd 100644 --- a/qt5/src/poppler-page.cc +++ b/qt5/src/poppler-page.cc @@ -129,10 +129,6 @@ public: { SplashBitmap *b = getBitmap(); - const int bw = b->getWidth(); - const int bh = b->getHeight(); - const int brs = b->getRowSize(); - // If we use DeviceN8, convert to XBGR8. // If requested, also transfer Splash's internal alpha channel. const SplashBitmap::ConversionMode mode = ignorePaperColor ? SplashBitmap::conversionAlphaPremultiplied : SplashBitmap::conversionOpaque; @@ -140,6 +136,10 @@ public: const QImage::Format format = ignorePaperColor ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; if (b->convertToXBGR(mode)) { + const int bw = b->getWidth(); + const int bh = b->getHeight(); + const int brs = b->getRowSize(); + SplashColorPtr data = takeImageData ? b->takeData() : b->getDataPtr(); if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { diff --git a/qt5/tests/CMakeLists.txt b/qt5/tests/CMakeLists.txt index 9de870ee..e610413a 100644 --- a/qt5/tests/CMakeLists.txt +++ b/qt5/tests/CMakeLists.txt @@ -74,6 +74,7 @@ qt5_add_qtest(check_qt5_signature_basics check_signature_basics.cpp) qt5_add_qtest(check_qt5_utf8document check_utf8document.cpp) qt5_add_qtest(check_qt5_distinguished_name_parser check_distinguished_name_parser.cpp) qt5_add_qtest(check_qt5_cidfontswidthsbuilder check_cidfontswidthsbuilder.cpp) +qt5_add_qtest(check_qt5_overprint check_overprint.cpp) if (NOT WIN32) qt5_add_qtest(check_qt5_pagelabelinfo check_pagelabelinfo.cpp) qt5_add_qtest(check_qt5_strings check_strings.cpp) diff --git a/qt5/tests/check_overprint.cpp b/qt5/tests/check_overprint.cpp new file mode 100644 index 00000000..3035c652 --- /dev/null +++ b/qt5/tests/check_overprint.cpp @@ -0,0 +1,41 @@ +#include <QtTest/QtTest> + +#include <poppler-qt5.h> + +#include <memory> + +class TestOverprint : public QObject +{ + Q_OBJECT +public: + explicit TestOverprint(QObject *parent = nullptr) : QObject(parent) { } +private slots: + void checkOverprintImageRendering(); +}; + +void TestOverprint::checkOverprintImageRendering() +{ + Poppler::Document *doc = Poppler::Document::load(TESTDATADIR "/tests/mask-seams.pdf"); + QVERIFY(doc); + + doc->setRenderHint(Poppler::Document::OverprintPreview, true); + + Poppler::Page *page = doc->page(0); + QVERIFY(page); + + constexpr int width = 600; + constexpr int height = 400; + + QImage img = page->renderToImage(300.0, 300.0, 0, 0, width, height); + QCOMPARE(img.format(), QImage::Format_RGB32); + QCOMPARE(img.width(), width); + QCOMPARE(img.height(), height); + QCOMPARE(img.bytesPerLine(), width * 4); + QCOMPARE(img.sizeInBytes(), width * height * 4); + + delete page; + delete doc; +} + +QTEST_GUILESS_MAIN(TestOverprint) +#include "check_overprint.moc" diff --git a/qt6/src/poppler-page.cc b/qt6/src/poppler-page.cc index dd1cb0e5..40062e81 100644 --- a/qt6/src/poppler-page.cc +++ b/qt6/src/poppler-page.cc @@ -128,10 +128,6 @@ public: { SplashBitmap *b = getBitmap(); - const int bw = b->getWidth(); - const int bh = b->getHeight(); - const int brs = b->getRowSize(); - // If we use DeviceN8, convert to XBGR8. // If requested, also transfer Splash's internal alpha channel. const SplashBitmap::ConversionMode mode = ignorePaperColor ? SplashBitmap::conversionAlphaPremultiplied : SplashBitmap::conversionOpaque; @@ -139,6 +135,10 @@ public: const QImage::Format format = ignorePaperColor ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; if (b->convertToXBGR(mode)) { + const int bw = b->getWidth(); + const int bh = b->getHeight(); + const int brs = b->getRowSize(); + SplashColorPtr data = takeImageData ? b->takeData() : b->getDataPtr(); if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { diff --git a/qt6/tests/CMakeLists.txt b/qt6/tests/CMakeLists.txt index 577aad7f..95fa89dd 100644 --- a/qt6/tests/CMakeLists.txt +++ b/qt6/tests/CMakeLists.txt @@ -66,6 +66,7 @@ qt6_add_qtest(check_qt6_signature_basics check_signature_basics.cpp) qt6_add_qtest(check_qt6_utf8document check_utf8document.cpp) qt6_add_qtest(check_qt6_distinguished_name_parser check_distinguished_name_parser.cpp) qt6_add_qtest(check_qt6_cidfontswidthsbuilder check_cidfontswidthsbuilder.cpp) +qt6_add_qtest(check_qt6_overprint check_overprint.cpp) if (NOT WIN32) qt6_add_qtest(check_qt6_pagelabelinfo check_pagelabelinfo.cpp) qt6_add_qtest(check_qt6_strings check_strings.cpp) diff --git a/qt6/tests/check_overprint.cpp b/qt6/tests/check_overprint.cpp new file mode 100644 index 00000000..1b551567 --- /dev/null +++ b/qt6/tests/check_overprint.cpp @@ -0,0 +1,38 @@ +#include <QtTest/QtTest> + +#include <poppler-qt6.h> + +#include <memory> + +class TestOverprint : public QObject +{ + Q_OBJECT +public: + explicit TestOverprint(QObject *parent = nullptr) : QObject(parent) { } +private slots: + void checkOverprintImageRendering(); +}; + +void TestOverprint::checkOverprintImageRendering() +{ + std::unique_ptr<Poppler::Document> doc = Poppler::Document::load(TESTDATADIR "/tests/mask-seams.pdf"); + QVERIFY(doc); + + doc->setRenderHint(Poppler::Document::OverprintPreview, true); + + std::unique_ptr<Poppler::Page> page = doc->page(0); + QVERIFY(page); + + constexpr int width = 600; + constexpr int height = 400; + + QImage img = page->renderToImage(300.0, 300.0, 0, 0, width, height); + QCOMPARE(img.format(), QImage::Format_RGB32); + QCOMPARE(img.width(), width); + QCOMPARE(img.height(), height); + QCOMPARE(img.bytesPerLine(), width * 4); + QCOMPARE(img.sizeInBytes(), width * height * 4); +} + +QTEST_GUILESS_MAIN(TestOverprint) +#include "check_overprint.moc"