nss: upgrade to release 3.73
[LibreOffice.git] / sd / qa / unit / SdrPdfImportTest.cxx
blob3125663d19081ab8228244adf05e2a4cfacfe83c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <test/bootstrapfixture.hxx>
11 #include <unotest/macros_test.hxx>
13 #include <svdpdf.hxx>
15 #include <config_features.h>
17 #include <comphelper/scopeguard.hxx>
18 #include <comphelper/processfactory.hxx>
19 #include <comphelper/propertysequence.hxx>
21 #include <unotools/tempfile.hxx>
22 #include <unotools/mediadescriptor.hxx>
23 #include <tools/stream.hxx>
24 #include <svx/svdograf.hxx>
25 #include <editeng/outlobj.hxx>
26 #include <editeng/editobj.hxx>
28 #include <DrawDocShell.hxx>
29 #include <DrawController.hxx>
30 #include <ViewShell.hxx>
31 #include <drawdoc.hxx>
32 #include <sdpage.hxx>
33 #include <unomodel.hxx>
35 #include <com/sun/star/frame/Desktop.hpp>
37 using namespace css;
39 class SdrPdfImportTest : public test::BootstrapFixture, public unotest::MacrosTest
41 protected:
42 uno::Reference<lang::XComponent> mxComponent;
44 public:
45 virtual void setUp() override;
46 virtual void tearDown() override;
49 void SdrPdfImportTest::setUp()
51 test::BootstrapFixture::setUp();
53 mxDesktop.set(frame::Desktop::create(mxComponentContext));
56 void SdrPdfImportTest::tearDown()
58 if (mxComponent.is())
59 mxComponent->dispose();
61 test::BootstrapFixture::tearDown();
64 // Load the PDF in Draw, which will load the PDF as an Graphic, then
65 // mark the graphic object and trigger "break" function. This should
66 // convert the PDF content into objects/shapes.
67 CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, testImportSimpleText)
69 #if HAVE_FEATURE_PDFIUM && !defined(_WIN32)
70 // We need to enable PDFium import (and make sure to disable after the test)
71 bool bResetEnvVar = false;
72 if (getenv("LO_IMPORT_USE_PDFIUM") == nullptr)
74 bResetEnvVar = true;
75 setenv("LO_IMPORT_USE_PDFIUM", "1", false);
77 comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() {
78 if (bResetEnvVar)
79 unsetenv("LO_IMPORT_USE_PDFIUM");
80 });
82 mxComponent = loadFromDesktop(m_directories.getURLFromSrc("sd/qa/unit/data/SimplePDF.pdf"));
83 auto pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
84 sd::ViewShell* pViewShell = pImpressDocument->GetDocShell()->GetViewShell();
85 CPPUNIT_ASSERT(pViewShell);
87 // Get the first page - there should be only one.
88 SdPage* pPage = pViewShell->GetActualPage();
89 CPPUNIT_ASSERT(pPage);
91 // Check there is one object on the page only
92 CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
94 // Get the first object - there should be only one.
95 SdrObject* pObject = pPage->GetObj(0);
96 CPPUNIT_ASSERT(pObject);
98 // Check the object is a graphic object
99 SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
100 CPPUNIT_ASSERT(pGraphicObject);
101 // Check the graphic is a vector graphic and that it is PDF
102 Graphic aGraphic = pGraphicObject->GetGraphic();
103 auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
104 CPPUNIT_ASSERT(pVectorGraphicData);
105 CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf,
106 pVectorGraphicData->getVectorGraphicDataType());
108 // Mark the object
109 SdrView* pView = pViewShell->GetView();
110 pView->MarkObj(pObject, pView->GetSdrPageView());
112 // Execute the break operation - to turn the PDF into shapes/objects
113 pViewShell->GetDrawView()->DoImportMarkedMtf();
115 // Check there is one object on the page only
116 CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
118 // Get the object
119 SdrObject* pImportedObject = pPage->GetObj(0);
120 CPPUNIT_ASSERT(pImportedObject);
122 // Check the object position
123 CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(2011, 2098), Size(2106 + 1, 302 + 1)),
124 pImportedObject->GetLogicRect());
126 // Object should be a text object containing one paragraph with
127 // content "This is PDF!"
129 SdrTextObj* pTextObject = dynamic_cast<SdrTextObj*>(pImportedObject);
130 CPPUNIT_ASSERT(pTextObject);
131 OutlinerParaObject* pOutlinerParagraphObject = pTextObject->GetOutlinerParaObject();
132 const EditTextObject& aEdit = pOutlinerParagraphObject->GetTextObject();
133 OUString sText = aEdit.GetText(0);
134 CPPUNIT_ASSERT_EQUAL(OUString("This is PDF!"), sText);
136 #endif // HAVE_FEATURE_PDFIUM
139 CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, testAnnotationsImportExport)
141 #if HAVE_FEATURE_PDFIUM && !defined(_WIN32)
142 // We need to enable PDFium import (and make sure to disable after the test)
143 bool bResetEnvVar = false;
144 if (getenv("LO_IMPORT_USE_PDFIUM") == nullptr)
146 bResetEnvVar = true;
147 setenv("LO_IMPORT_USE_PDFIUM", "1", false);
149 comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() {
150 if (bResetEnvVar)
151 unsetenv("LO_IMPORT_USE_PDFIUM");
154 bool bPDFCompressorResetEnvVar = false;
155 if (getenv("VCL_DEBUG_DISABLE_PDFCOMPRESSION") == nullptr)
157 bPDFCompressorResetEnvVar = true;
158 setenv("VCL_DEBUG_DISABLE_PDFCOMPRESSION", "1", false);
160 comphelper::ScopeGuard aPDFCompressorEnvVarGuard([&]() {
161 if (bPDFCompressorResetEnvVar)
162 unsetenv("VCL_DEBUG_DISABLE_PDFCOMPRESSION");
165 auto pPdfiumLibrary = vcl::pdf::PDFiumLibrary::get();
167 mxComponent
168 = loadFromDesktop(m_directories.getURLFromSrc("sd/qa/unit/data/PdfWithAnnotation.pdf"));
169 auto pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
170 sd::ViewShell* pViewShell = pImpressDocument->GetDocShell()->GetViewShell();
171 CPPUNIT_ASSERT(pViewShell);
173 const void* pData = nullptr;
174 int nLength = 0;
177 // Get the first page - there should be only one.
178 SdPage* pPage = pViewShell->GetActualPage();
179 CPPUNIT_ASSERT(pPage);
181 // Check the number of annotations
182 CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->getAnnotations().size());
184 // Get the first object - there should be only one.
185 SdrObject* pObject = pPage->GetObj(0);
186 CPPUNIT_ASSERT(pObject);
188 // Check the object is a graphic object
189 SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
190 CPPUNIT_ASSERT(pGraphicObject);
192 // Check the graphic is a vector graphic and that it is PDF
193 Graphic aGraphic = pGraphicObject->GetGraphic();
194 auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
195 CPPUNIT_ASSERT(pVectorGraphicData);
196 CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf,
197 pVectorGraphicData->getVectorGraphicDataType());
199 // Write the PDF
200 pData = pVectorGraphicData->getVectorGraphicDataArray().getConstArray();
201 nLength = pVectorGraphicData->getVectorGraphicDataArrayLength();
204 { // check graphic PDF has annotations
206 auto pPDFDocument = pPdfiumLibrary->openDocument(pData, nLength);
207 auto pPDFPage = pPDFDocument->openPage(0);
209 CPPUNIT_ASSERT_EQUAL(2, pPDFPage->getAnnotationCount());
211 auto pPDFAnnotation1 = pPDFPage->getAnnotation(0);
212 CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Text,
213 pPDFAnnotation1->getSubType()); // Text annotation
215 auto pPDFAnnotation2 = pPDFPage->getAnnotation(1);
216 CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Popup,
217 pPDFAnnotation2->getSubType()); // Pop-up annotation
220 { // save as PDF and check annotations
221 utl::TempFile aTempFile;
222 aTempFile.EnableKillingFile();
224 uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
225 utl::MediaDescriptor aMediaDescriptor;
226 aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
227 uno::Sequence<beans::PropertyValue> aFilterData(
228 comphelper::InitPropertySequence({ { "ExportBookmarks", uno::Any(true) } }));
229 aMediaDescriptor["FilterData"] <<= aFilterData;
230 xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
231 mxComponent->dispose();
233 SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ);
234 SvMemoryStream aMemory;
235 aMemory.WriteStream(aFile);
237 // Check PDF for annotations
238 auto pPDFDocument = pPdfiumLibrary->openDocument(aMemory.GetData(), aMemory.GetSize());
239 CPPUNIT_ASSERT(pPDFDocument);
240 CPPUNIT_ASSERT_EQUAL(1, pPDFDocument->getPageCount());
242 auto pPDFPage = pPDFDocument->openPage(0);
243 CPPUNIT_ASSERT(pPDFPage);
245 CPPUNIT_ASSERT_EQUAL(2, pPDFPage->getAnnotationCount());
247 auto pPDFAnnotation1 = pPDFPage->getAnnotation(0);
248 CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Text,
249 pPDFAnnotation1->getSubType()); // Text annotation
251 auto pPDFAnnotation2 = pPDFPage->getAnnotation(1);
252 CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Popup,
253 pPDFAnnotation2->getSubType()); // Pop-up annotation
255 // Load document again
256 mxComponent = loadFromDesktop(aTempFile.GetURL());
257 auto pNewImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
258 sd::ViewShell* pNewViewShell = pNewImpressDocument->GetDocShell()->GetViewShell();
259 CPPUNIT_ASSERT(pNewViewShell);
261 SdPage* pPage = pNewViewShell->GetActualPage();
262 CPPUNIT_ASSERT(pPage);
264 // We expect only 1 annotation in the document because the PDF
265 // annotations are dependent on each-other:
266 // parent annotation "Text" and the child annotation "Pop-up"
268 CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->getAnnotations().size());
270 // check annotation
271 auto xAnnotation = pPage->getAnnotations().at(0);
273 CPPUNIT_ASSERT_DOUBLES_EQUAL(90.33, xAnnotation->getPosition().X, 1E-3);
274 CPPUNIT_ASSERT_DOUBLES_EQUAL(12.07, xAnnotation->getPosition().Y, 1E-3);
276 CPPUNIT_ASSERT_EQUAL(OUString("TheAuthor"), xAnnotation->getAuthor());
277 CPPUNIT_ASSERT_EQUAL(OUString(), xAnnotation->getInitials());
279 auto xText = xAnnotation->getTextRange();
281 CPPUNIT_ASSERT_EQUAL(OUString("This is the annotation text!"), xText->getString());
283 auto aDateTime = xAnnotation->getDateTime();
284 CPPUNIT_ASSERT_EQUAL(sal_Int16(2020), aDateTime.Year);
285 CPPUNIT_ASSERT_EQUAL(sal_uInt16(6), aDateTime.Month);
286 CPPUNIT_ASSERT_EQUAL(sal_uInt16(18), aDateTime.Day);
287 CPPUNIT_ASSERT_EQUAL(sal_uInt16(12), aDateTime.Hours);
288 CPPUNIT_ASSERT_EQUAL(sal_uInt16(11), aDateTime.Minutes);
289 CPPUNIT_ASSERT_EQUAL(sal_uInt16(53), aDateTime.Seconds);
290 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), aDateTime.NanoSeconds);
291 CPPUNIT_ASSERT_EQUAL(false, bool(aDateTime.IsUTC));
294 #endif // HAVE_FEATURE_PDFIUM
297 CPPUNIT_PLUGIN_IMPLEMENT();
299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */