diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sd/qa/unit/SdrPdfImportTest.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sd/qa/unit/SdrPdfImportTest.cxx')
-rw-r--r-- | sd/qa/unit/SdrPdfImportTest.cxx | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/sd/qa/unit/SdrPdfImportTest.cxx b/sd/qa/unit/SdrPdfImportTest.cxx new file mode 100644 index 0000000000..52388678df --- /dev/null +++ b/sd/qa/unit/SdrPdfImportTest.cxx @@ -0,0 +1,282 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <test/unoapi_test.hxx> + +#include <comphelper/scopeguard.hxx> +#include <comphelper/propertysequence.hxx> + +#include <unotools/tempfile.hxx> +#include <unotools/mediadescriptor.hxx> +#include <svx/svdograf.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <vcl/filter/PDFiumLibrary.hxx> +#include <vcl/pdf/PDFAnnotationSubType.hxx> + +#include <Annotation.hxx> +#include <DrawDocShell.hxx> +#include <ViewShell.hxx> +#include <sdpage.hxx> +#include <unomodel.hxx> + +using namespace css; + +namespace +{ +class EnvVarGuard +{ +public: + EnvVarGuard(const char* var, const char* val) + { + if (getenv(var) == nullptr) + { + sVar = var; + SetEnv(sVar, val); + } + } + ~EnvVarGuard() + { + if (sVar) + SetEnv(sVar, nullptr); + } + +private: + static void SetEnv(const char* var, const char* val) + { +#ifdef _WIN32 + if (!val) + val = ""; // remove + _putenv_s(var, val); +#else + if (val) + setenv(var, val, false); + else + unsetenv(var); +#endif + } + + const char* sVar = nullptr; +}; +} + +class SdrPdfImportTest : public UnoApiTest +{ +public: + SdrPdfImportTest() + : UnoApiTest("/sd/qa/unit/data/") + { + } +}; + +// Load the PDF in Draw, which will load the PDF as an Graphic, then +// mark the graphic object and trigger "break" function. This should +// convert the PDF content into objects/shapes. +CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, testImportSimpleText) +{ + auto pPdfium = vcl::pdf::PDFiumLibrary::get(); + if (!pPdfium) + { + return; + } + + // We need to enable PDFium import (and make sure to disable after the test) + EnvVarGuard UsePDFiumGuard("LO_IMPORT_USE_PDFIUM", "1"); + + loadFromFile(u"SimplePDF.pdf"); + auto pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + sd::ViewShell* pViewShell = pImpressDocument->GetDocShell()->GetViewShell(); + CPPUNIT_ASSERT(pViewShell); + + // Get the first page - there should be only one. + SdPage* pPage = pViewShell->GetActualPage(); + CPPUNIT_ASSERT(pPage); + + // Check there is one object on the page only + CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount()); + + // Get the first object - there should be only one. + SdrObject* pObject = pPage->GetObj(0); + CPPUNIT_ASSERT(pObject); + + // Check the object is a graphic object + SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject); + CPPUNIT_ASSERT(pGraphicObject); + // Check the graphic is a vector graphic and that it is PDF + Graphic aGraphic = pGraphicObject->GetGraphic(); + auto const& pVectorGraphicData = aGraphic.getVectorGraphicData(); + CPPUNIT_ASSERT(pVectorGraphicData); + CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType()); + + // Mark the object + SdrView* pView = pViewShell->GetView(); + pView->MarkObj(pObject, pView->GetSdrPageView()); + + // Execute the break operation - to turn the PDF into shapes/objects + pViewShell->GetDrawView()->DoImportMarkedMtf(); + + // Check there is one object on the page only + CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount()); + + // Get the object + SdrObject* pImportedObject = pPage->GetObj(0); + CPPUNIT_ASSERT(pImportedObject); + + // Check the object position + CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(2011, 2102), Size(2106 + 1, 298 + 1)), + pImportedObject->GetLogicRect()); + + // Object should be a text object containing one paragraph with + // content "This is PDF!" + + SdrTextObj* pTextObject = DynCastSdrTextObj(pImportedObject); + CPPUNIT_ASSERT(pTextObject); + OutlinerParaObject* pOutlinerParagraphObject = pTextObject->GetOutlinerParaObject(); + const EditTextObject& aEdit = pOutlinerParagraphObject->GetTextObject(); + OUString sText = aEdit.GetText(0); + CPPUNIT_ASSERT_EQUAL(OUString("This is PDF!"), sText); +} + +CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, testAnnotationsImportExport) +{ + auto pPdfium = vcl::pdf::PDFiumLibrary::get(); + if (!pPdfium) + { + return; + } + + // We need to enable PDFium import (and make sure to disable after the test) + EnvVarGuard UsePDFiumGuard("LO_IMPORT_USE_PDFIUM", "1"); + + EnvVarGuard DisablePDFCompressionGuard("VCL_DEBUG_DISABLE_PDFCOMPRESSION", "1"); + + auto pPdfiumLibrary = vcl::pdf::PDFiumLibrary::get(); + + loadFromFile(u"PdfWithAnnotation.pdf"); + auto pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + sd::ViewShell* pViewShell = pImpressDocument->GetDocShell()->GetViewShell(); + CPPUNIT_ASSERT(pViewShell); + + BinaryDataContainer aContainer; + + { + // Get the first page - there should be only one. + SdPage* pPage = pViewShell->GetActualPage(); + CPPUNIT_ASSERT(pPage); + + // Check the number of annotations + CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->getAnnotations().size()); + + // Get the first object - there should be only one. + SdrObject* pObject = pPage->GetObj(0); + CPPUNIT_ASSERT(pObject); + + // Check the object is a graphic object + SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject); + CPPUNIT_ASSERT(pGraphicObject); + + // Check the graphic is a vector graphic and that it is PDF + Graphic aGraphic = pGraphicObject->GetGraphic(); + auto const& pVectorGraphicData = aGraphic.getVectorGraphicData(); + CPPUNIT_ASSERT(pVectorGraphicData); + CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType()); + + // Write the PDF + aContainer = pVectorGraphicData->getBinaryDataContainer(); + } + + { // check graphic PDF has annotations + + CPPUNIT_ASSERT_EQUAL(false, aContainer.isEmpty()); + + auto pPDFDocument + = pPdfiumLibrary->openDocument(aContainer.getData(), aContainer.getSize(), OString()); + auto pPDFPage = pPDFDocument->openPage(0); + + CPPUNIT_ASSERT_EQUAL(2, pPDFPage->getAnnotationCount()); + + auto pPDFAnnotation1 = pPDFPage->getAnnotation(0); + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Text, + pPDFAnnotation1->getSubType()); // Text annotation + + auto pPDFAnnotation2 = pPDFPage->getAnnotation(1); + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Popup, + pPDFAnnotation2->getSubType()); // Pop-up annotation + } + + { // save as PDF and check annotations + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); + uno::Sequence<beans::PropertyValue> aFilterData( + comphelper::InitPropertySequence({ { "ExportBookmarks", uno::Any(true) } })); + aMediaDescriptor["FilterData"] <<= aFilterData; + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + + // Check PDF for annotations + auto pPDFDocument = parsePDFExport(); + CPPUNIT_ASSERT(pPDFDocument); + CPPUNIT_ASSERT_EQUAL(1, pPDFDocument->getPageCount()); + + auto pPDFPage = pPDFDocument->openPage(0); + CPPUNIT_ASSERT(pPDFPage); + + CPPUNIT_ASSERT_EQUAL(2, pPDFPage->getAnnotationCount()); + + auto pPDFAnnotation1 = pPDFPage->getAnnotation(0); + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Text, + pPDFAnnotation1->getSubType()); // Text annotation + + auto pPDFAnnotation2 = pPDFPage->getAnnotation(1); + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Popup, + pPDFAnnotation2->getSubType()); // Pop-up annotation + + // Load document again + mxComponent = loadFromDesktop(maTempFile.GetURL()); + auto pNewImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + sd::ViewShell* pNewViewShell = pNewImpressDocument->GetDocShell()->GetViewShell(); + CPPUNIT_ASSERT(pNewViewShell); + + SdPage* pPage = pNewViewShell->GetActualPage(); + CPPUNIT_ASSERT(pPage); + + // We expect only 1 annotation in the document because the PDF + // annotations are dependent on each-other: + // parent annotation "Text" and the child annotation "Pop-up" + + CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->getAnnotations().size()); + + // check annotation + auto xAnnotation = pPage->getAnnotations().at(0); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(90.33, xAnnotation->getPosition().X, 1E-3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.07, xAnnotation->getPosition().Y, 1E-3); + + CPPUNIT_ASSERT_EQUAL(OUString("TheAuthor"), xAnnotation->getAuthor()); + CPPUNIT_ASSERT_EQUAL(OUString(), xAnnotation->getInitials()); + + auto xText = xAnnotation->getTextRange(); + + CPPUNIT_ASSERT_EQUAL(OUString("This is the annotation text!"), xText->getString()); + + auto aDateTime = xAnnotation->getDateTime(); + CPPUNIT_ASSERT_EQUAL(sal_Int16(2020), aDateTime.Year); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(6), aDateTime.Month); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(18), aDateTime.Day); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(12), aDateTime.Hours); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(11), aDateTime.Minutes); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(53), aDateTime.Seconds); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), aDateTime.NanoSeconds); + CPPUNIT_ASSERT_EQUAL(false, bool(aDateTime.IsUTC)); + } +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |