[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - include/vcl vcl/CppunitTest_vcl_pdfium_library_test.mk vcl/Module_vcl.mk vcl/qa vcl/source
Tomaž Vajngerl (via logerrit)
logerrit at kemper.freedesktop.org
Mon Jun 29 18:35:54 UTC 2020
include/vcl/filter/PDFiumLibrary.hxx | 59 +++++++++++++++-
vcl/CppunitTest_vcl_pdfium_library_test.mk | 45 ++++++++++++
vcl/Module_vcl.mk | 1
vcl/qa/cppunit/PDFiumLibraryTest.cxx | 105 +++++++++++++++++++++++++++++
vcl/source/pdf/PDFiumLibrary.cxx | 82 ++++++++++++++++++++++
5 files changed, 289 insertions(+), 3 deletions(-)
New commits:
commit 046a23fd473bd497f08d35d9588a09aa192b9763
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Mon Jun 15 13:50:18 2020 +0200
Commit: Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Mon Jun 29 20:35:21 2020 +0200
vcl: wrap PDFium types in c++ classes to ease lifecycle management
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96753
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
(cherry picked from commit 526b09604399a71c17b15ee80bab48967563bfb6)
Change-Id: Idd33dfe752a22b6628750c06f02e9467a69802bc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97435
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
diff --git a/include/vcl/filter/PDFiumLibrary.hxx b/include/vcl/filter/PDFiumLibrary.hxx
index bc7912c17e81..6dde31f2927b 100644
--- a/include/vcl/filter/PDFiumLibrary.hxx
+++ b/include/vcl/filter/PDFiumLibrary.hxx
@@ -14,24 +14,79 @@
#if HAVE_FEATURE_PDFIUM
+#include <vcl/dllapi.h>
+
#include <memory>
#include <rtl/instance.hxx>
-#include <vcl/dllapi.h>
+#include <basegfx/vector/b2dsize.hxx>
+#include <rtl/ustring.hxx>
+
+#include <fpdf_doc.h>
namespace vcl::pdf
{
+class PDFiumDocument;
+
class VCL_DLLPUBLIC PDFium final
{
private:
PDFium(const PDFium&) = delete;
PDFium& operator=(const PDFium&) = delete;
+ OUString maLastError;
+
public:
PDFium();
~PDFium();
+
+ OUString getLastError() { return maLastError; }
+
+ std::unique_ptr<PDFiumDocument> openDocument(const void* pData, int nSize);
+};
+
+class VCL_DLLPUBLIC PDFiumPage final
+{
+private:
+ FPDF_PAGE mpPage;
+
+private:
+ PDFiumPage(const PDFiumPage&) = delete;
+ PDFiumPage& operator=(const PDFiumPage&) = delete;
+
+public:
+ PDFiumPage(FPDF_PAGE pPage)
+ : mpPage(pPage)
+ {
+ }
+
+ ~PDFiumPage()
+ {
+ if (mpPage)
+ FPDF_ClosePage(mpPage);
+ }
+};
+
+class VCL_DLLPUBLIC PDFiumDocument final
+{
+private:
+ FPDF_DOCUMENT mpPdfDocument;
+
+private:
+ PDFiumDocument(const PDFiumDocument&) = delete;
+ PDFiumDocument& operator=(const PDFiumDocument&) = delete;
+
+public:
+ PDFiumDocument(FPDF_DOCUMENT pPdfDocument);
+ ~PDFiumDocument();
+
+ // Page size in points
+ basegfx::B2DSize getPageSize(int nIndex);
+ int getPageCount();
+
+ std::unique_ptr<PDFiumPage> openPage(int nIndex);
};
-struct PDFiumLibrary : public rtl::StaticWithInit<std::shared_ptr<PDFium>, PDFiumLibrary>
+struct PDFiumLibrary final : public rtl::StaticWithInit<std::shared_ptr<PDFium>, PDFiumLibrary>
{
std::shared_ptr<PDFium> operator()() { return std::make_shared<PDFium>(); }
};
diff --git a/vcl/CppunitTest_vcl_pdfium_library_test.mk b/vcl/CppunitTest_vcl_pdfium_library_test.mk
new file mode 100644
index 000000000000..0f4a480c8254
--- /dev/null
+++ b/vcl/CppunitTest_vcl_pdfium_library_test.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,vcl_pdfium_library_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,vcl_pdfium_library_test, \
+ vcl/qa/cppunit/PDFiumLibraryTest \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,vcl_pdfium_library_test))
+
+$(eval $(call gb_CppunitTest_use_libraries,vcl_pdfium_library_test, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ sal \
+ test \
+ unotest \
+ utl \
+ tl \
+ vcl \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,vcl_pdfium_library_test, \
+ boost_headers \
+ $(if $(filter PDFIUM,$(BUILD_TYPE)),pdfium) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,vcl_pdfium_library_test))
+
+$(eval $(call gb_CppunitTest_use_ure,vcl_pdfium_library_test))
+$(eval $(call gb_CppunitTest_use_vcl,vcl_pdfium_library_test))
+
+$(eval $(call gb_CppunitTest_use_rdb,vcl_pdfium_library_test,services))
+
+$(eval $(call gb_CppunitTest_use_configuration,vcl_pdfium_library_test))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index a67a38c96b8a..8f4fa5adf6d6 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -204,6 +204,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\
CppunitTest_vcl_png_test \
CppunitTest_vcl_widget_definition_reader_test \
CppunitTest_vcl_backend_test \
+ CppunitTest_vcl_pdfium_library_test \
))
ifeq ($(USING_X11),TRUE)
diff --git a/vcl/qa/cppunit/PDFiumLibraryTest.cxx b/vcl/qa/cppunit/PDFiumLibraryTest.cxx
new file mode 100644
index 000000000000..422325aa9b1d
--- /dev/null
+++ b/vcl/qa/cppunit/PDFiumLibraryTest.cxx
@@ -0,0 +1,105 @@
+/* -*- 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 <config_features.h>
+
+#if HAVE_FEATURE_PDFIUM
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <unotest/bootstrapfixturebase.hxx>
+#include <unotest/directories.hxx>
+
+#include <vcl/graph.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <tools/stream.hxx>
+
+#include <vcl/filter/PDFiumLibrary.hxx>
+
+class PDFiumLibraryTest : public test::BootstrapFixtureBase
+{
+ OUString getFullUrl(const OUString& sFileName)
+ {
+ return m_directories.getURLFromSrc("/vcl/qa/cppunit/data/") + sFileName;
+ }
+
+ void testDocument();
+ void testPages();
+
+ CPPUNIT_TEST_SUITE(PDFiumLibraryTest);
+ CPPUNIT_TEST(testDocument);
+ CPPUNIT_TEST(testPages);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void PDFiumLibraryTest::testDocument()
+{
+ OUString aURL = getFullUrl("Pangram.pdf");
+ SvFileStream aStream(aURL, StreamMode::READ);
+ GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
+ Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
+ aGraphic.makeAvailable();
+
+ auto pVectorGraphicData = aGraphic.getVectorGraphicData();
+ CPPUNIT_ASSERT(pVectorGraphicData);
+ CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf,
+ pVectorGraphicData->getVectorGraphicDataType());
+
+ const void* pData = pVectorGraphicData->getVectorGraphicDataArray().getConstArray();
+ int nLength = pVectorGraphicData->getVectorGraphicDataArrayLength();
+
+ auto pPdfium = vcl::pdf::PDFiumLibrary::get();
+ CPPUNIT_ASSERT(pPdfium);
+ auto pDocument = pPdfium->openDocument(pData, nLength);
+ CPPUNIT_ASSERT(pDocument);
+
+ CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
+
+ auto aSize = pDocument->getPageSize(0);
+ CPPUNIT_ASSERT_EQUAL(612.0, aSize.getX());
+ CPPUNIT_ASSERT_EQUAL(792.0, aSize.getY());
+
+ auto pPage = pDocument->openPage(0);
+ CPPUNIT_ASSERT(pPage);
+}
+
+void PDFiumLibraryTest::testPages()
+{
+ OUString aURL = getFullUrl("Pangram.pdf");
+ SvFileStream aStream(aURL, StreamMode::READ);
+ GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
+ Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
+ aGraphic.makeAvailable();
+
+ auto pVectorGraphicData = aGraphic.getVectorGraphicData();
+ CPPUNIT_ASSERT(pVectorGraphicData);
+ CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf,
+ pVectorGraphicData->getVectorGraphicDataType());
+
+ const void* pData = pVectorGraphicData->getVectorGraphicDataArray().getConstArray();
+ int nLength = pVectorGraphicData->getVectorGraphicDataArrayLength();
+
+ auto pPdfium = vcl::pdf::PDFiumLibrary::get();
+ auto pDocument = pPdfium->openDocument(pData, nLength);
+ CPPUNIT_ASSERT(pDocument);
+
+ CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
+
+ auto pPage = pDocument->openPage(0);
+ CPPUNIT_ASSERT(pPage);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(PDFiumLibraryTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
index 604807524bf9..3ea7e5b49c4a 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -13,7 +13,7 @@
#if HAVE_FEATURE_PDFIUM
#include <vcl/filter/PDFiumLibrary.hxx>
-#include <fpdf_doc.h>
+#include <fpdf_edit.h>
namespace vcl::pdf
{
@@ -29,6 +29,86 @@ PDFium::PDFium()
PDFium::~PDFium() { FPDF_DestroyLibrary(); }
+std::unique_ptr<PDFiumDocument> PDFium::openDocument(const void* pData, int nSize)
+{
+ maLastError = OUString();
+ std::unique_ptr<PDFiumDocument> pPDFiumDocument;
+
+ FPDF_DOCUMENT pDocument = FPDF_LoadMemDocument(pData, nSize, /*password=*/nullptr);
+
+ if (!pDocument)
+ {
+ switch (FPDF_GetLastError())
+ {
+ case FPDF_ERR_SUCCESS:
+ maLastError = "Success";
+ break;
+ case FPDF_ERR_UNKNOWN:
+ maLastError = "Unknown error";
+ break;
+ case FPDF_ERR_FILE:
+ maLastError = "File not found";
+ break;
+ case FPDF_ERR_FORMAT:
+ maLastError = "Input is not a PDF format";
+ break;
+ case FPDF_ERR_PASSWORD:
+ maLastError = "Incorrect password or password is required";
+ break;
+ case FPDF_ERR_SECURITY:
+ maLastError = "Security error";
+ break;
+ case FPDF_ERR_PAGE:
+ maLastError = "Content error";
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ pPDFiumDocument = std::make_unique<PDFiumDocument>(pDocument);
+ }
+
+ return pPDFiumDocument;
+}
+
+PDFiumDocument::PDFiumDocument(FPDF_DOCUMENT pPdfDocument)
+ : mpPdfDocument(pPdfDocument)
+{
+}
+
+PDFiumDocument::~PDFiumDocument()
+{
+ if (mpPdfDocument)
+ FPDF_CloseDocument(mpPdfDocument);
+}
+
+std::unique_ptr<PDFiumPage> PDFiumDocument::openPage(int nIndex)
+{
+ std::unique_ptr<PDFiumPage> pPDFiumPage;
+ FPDF_PAGE pPage = FPDF_LoadPage(mpPdfDocument, nIndex);
+ if (pPage)
+ {
+ pPDFiumPage = std::make_unique<PDFiumPage>(pPage);
+ }
+ return pPDFiumPage;
+}
+
+basegfx::B2DSize PDFiumDocument::getPageSize(int nIndex)
+{
+ basegfx::B2DSize aSize;
+ double fPageWidth = 0;
+ double fPageHeight = 0;
+ if (FPDF_GetPageSizeByIndex(mpPdfDocument, nIndex, &fPageWidth, &fPageHeight))
+ {
+ aSize = basegfx::B2DSize(fPageWidth, fPageHeight);
+ }
+ return aSize;
+}
+
+int PDFiumDocument::getPageCount() { return FPDF_GetPageCount(mpPdfDocument); }
+
} // end vcl::pdf
#endif // HAVE_FEATURE_PDFIUM
More information about the Libreoffice-commits
mailing list