summaryrefslogtreecommitdiff
path: root/vcl/qa/cppunit/pdfexport/pdfexport.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/qa/cppunit/pdfexport/pdfexport.cxx')
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx111
1 files changed, 111 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index aa96ee8a0f99..fc7103fede47 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -38,6 +38,7 @@
#include <fpdfview.h>
#include <vcl/graphicfilter.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <rtl/math.hxx>
#include <vcl/filter/PDFiumLibrary.hxx>
@@ -147,6 +148,8 @@ public:
void testDefaultVersion();
void testMultiPagePDF();
void testPdfImageRotate180();
+ void testPdfImageHyperlink();
+ void testPdfImageAnnots();
CPPUNIT_TEST_SUITE(PdfExportTest);
@@ -191,6 +194,8 @@ public:
CPPUNIT_TEST(testDefaultVersion);
CPPUNIT_TEST(testMultiPagePDF);
CPPUNIT_TEST(testPdfImageRotate180);
+ CPPUNIT_TEST(testPdfImageHyperlink);
+ CPPUNIT_TEST(testPdfImageAnnots);
CPPUNIT_TEST_SUITE_END();
};
@@ -2252,6 +2257,112 @@ void PdfExportTest::testPdfImageRotate180()
CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.0, aScale.getX(), 0.01);
}
+void PdfExportTest::testPdfImageHyperlink()
+{
+ // Given a Draw file, containing a PDF image, which has a hyperlink in it:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf-image-hyperlink.odg";
+ mxComponent = loadFromDesktop(aURL);
+ CPPUNIT_ASSERT(mxComponent.is());
+
+ // When saving to PDF:
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("draw_pdf_Export");
+ xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+ // Then make sure that link is preserved:
+ SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
+ maMemory.WriteStream(aFile);
+ std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+ std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
+ = pPDFium->openDocument(maMemory.GetData(), maMemory.GetSize());
+ CPPUNIT_ASSERT(pPdfDocument);
+ CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
+ std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0);
+ CPPUNIT_ASSERT(pPdfPage);
+ int nStartPos = 0;
+ FPDF_LINK pLinkAnnot = nullptr;
+ // Without the accompanying fix in place, this test would have failed, the hyperlink of the PDF
+ // image was lost.
+ CPPUNIT_ASSERT(FPDFLink_Enumerate(pPdfPage->getPointer(), &nStartPos, &pLinkAnnot));
+
+ // Also test the precision of the form XObject.
+ // Given a full-page form XObject, page height is 27.94 cm (792 points):
+ // When writing the reciprocal of the object height to PDF:
+ std::unique_ptr<vcl::pdf::PDFiumPageObject> pFormObject;
+ for (int i = 0; i < pPdfPage->getObjectCount(); ++i)
+ {
+ std::unique_ptr<vcl::pdf::PDFiumPageObject> pObject = pPdfPage->getObject(i);
+ if (FPDFPageObj_GetType(pObject->getPointer()) == FPDF_PAGEOBJ_FORM)
+ {
+ pFormObject = std::move(pObject);
+ break;
+ }
+ }
+ CPPUNIT_ASSERT(pFormObject);
+ std::unique_ptr<vcl::pdf::PDFiumPageObject> pInnerFormObject;
+ for (int i = 0; i < pFormObject->getFormObjectCount(); ++i)
+ {
+ std::unique_ptr<vcl::pdf::PDFiumPageObject> pObject = pFormObject->getFormObject(i);
+ if (FPDFPageObj_GetType(pObject->getPointer()) == FPDF_PAGEOBJ_FORM)
+ {
+ pInnerFormObject = std::move(pObject);
+ break;
+ }
+ }
+ CPPUNIT_ASSERT(pInnerFormObject);
+ // Then make sure that enough digits are used, so the point size is unchanged:
+ basegfx::B2DHomMatrix aMatrix;
+ FS_MATRIX matrix;
+ if (FPDFFormObj_GetMatrix(pInnerFormObject->getPointer(), &matrix))
+ {
+ aMatrix = basegfx::B2DHomMatrix::abcdef(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e,
+ matrix.f);
+ }
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate{};
+ double fShearX{};
+ aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0.0012626264
+ // - Actual : 0.00126
+ // i.e. the rounded reciprocal was 794 points, not the original 792.
+ // FIXME macOS actual value is 0.0001578282, for unknown reasons.
+#if !defined MACOSX
+ CPPUNIT_ASSERT_EQUAL(0.0012626264, rtl::math::round(aScale.getY(), 10));
+#endif
+}
+
+void PdfExportTest::testPdfImageAnnots()
+{
+ // Given a document with a PDF image that has 2 comments (popup, text) and a hyperlink:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf-image-annots.odg";
+ mxComponent = loadFromDesktop(aURL);
+ CPPUNIT_ASSERT(mxComponent.is());
+
+ // When saving to PDF:
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("draw_pdf_Export");
+ xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+ // Then make sure only the hyperlink is kept, since Draw itself has its own comments:
+ SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
+ maMemory.WriteStream(aFile);
+ std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+ std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
+ = pPDFium->openDocument(maMemory.GetData(), maMemory.GetSize());
+ CPPUNIT_ASSERT(pPdfDocument);
+ CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
+ std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0);
+ CPPUNIT_ASSERT(pPdfPage);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 3
+ // i.e. not only the hyperlink but also the 2 comments were exported, leading to duplication.
+ CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getAnnotationCount());
+}
CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
}