GithubHelp home page GithubHelp logo

pdfmm / pdfmm Goto Github PK

View Code? Open in Web Editor NEW
58.0 58.0 15.0 8.8 MB

A C++ PDF manipulation library forked from PoDoFo

Home Page: https://pdfmm.github.io

License: GNU Lesser General Public License v2.1

CMake 1.29% C 0.19% C++ 98.50% Shell 0.01% Batchfile 0.01%
c-plus-plus cpp library pdf pdf-document pdf-files pdf-generation

pdfmm's Introduction

pdfmm build-linux build-mac build-win

Warning This project has been moved back to PoDoFo community. See you there

  1. What is pdfmm?
  2. Requirements
  3. String encoding
  4. API Stability
  5. TODO
  6. FAQ
  7. Licensing
  8. No warranty
  9. Contributions
  10. Authors

What is pdfmm?

pdfmm is a s a free portable C++ library to work with the PDF file format. pdfmm is a derivative work of the PoDoFo library, from which it forked at Rev@1999.

pdfmm provides classes to parse a PDF file and modify its content into memory. The changes can be written back to disk easily. Besides PDF parsing pdfmm also provides facilities to create your own PDF files from scratch. It currently does not support rendering PDF content.

Requirements

To build pdfmm lib you'll need a c++17 compiler, CMake 3.16 and the following libraries:

  • freetype2
  • fontconfig (required for Unix platforms, optional for Windows)
  • OpenSSL
  • LibXml2
  • zlib
  • libjpeg (optional)
  • libtiff (optional)
  • libpng (optional)
  • libidn (optional)

For the most polular toolchains, pdfmm requires the following minimum versions:

  • msvc++ 14.16 (VS 2017 15.9)
  • gcc 8.1
  • clang/llvm 7.0

It is regularly tested with the following IDE/toolchains versions:

  • Visual Studio 2017 15.9
  • Visual Studio 2019 16.11
  • gcc 9.3.1
  • XCode 13.3
  • NDK r23b

Licensing

Short version: LGPL 2.1.

Long version: while several source code files are still released under the old PoDoFo terms (LGPL 2.0 license or later), new files are expected to be licensed under the terms of the LGPL 2.1 license, so as a whole the library is licensed under this specific license version. See source headers for details. The tests and examples which are included in pdfmm are licensed under the GPL 2.0. This may change at a later stage. See all the COPYING files in the relevant folders for details.

Development quickstart

There's a playground area in the repository where you can find have access to pre-build dependencies for some popular architectures/operating systems. Have a look in the Readme there. Also the github workflow definition files are very useful as they provide booststrap commands to build pdfmm with latest packages from brew under mac and apt-get under ubuntu.

String encoding and buffer conventions

All std::strings or std::string_view in the library are inteded to hold UTF-8 encoded string content. PdfString and PdfName constructors accept UTF-8 encoded strings by default (PdfName accept only characters in the PdfDocEncoding char set, though). charbuff abd bufferview instead represent a generic octet buffer.

API stability

pdfmm has an unstable API that is the results of an extensive API review of PoDoFo. It may converge to a stable API as soon as the review process is completed. See API Stability for more details.

TODO

There's a TODO list in the wiki and a list of planned tasks in the issue tracker.

FAQ

Q: PdfMemDocument::SaveUpdate() or mm::SignDocument() write only a partial file: why so and why there's no mechanism to seamlessly handle the incremental update as it was in PoDoFo? What should be done to correctly update/sign the document?

A: The previous mechanism in PoDoFo required enablement of document for incremental updates, which is a decisional step which I believe should be not be necessary. Also:

  1. In case of file loaded document it still required to perform the update in the same file, and the check was performed on the path of the files being operated to, which is unsafe;
  2. In case of buffers worked for one update/signing operation but didn't work for following operations.

The idea is to implement a more explicit mehcanism that makes more clear and/or enforces the fact that the incremental update must be performed on the same file in case of file loaded documents or that underlying buffer will grow following subsequent operations in case of buffer loaded documents. Before that, as a workardound, a couple of examples showing the correct operation to either update or sign a document (file or buffer loaded) are presented. Save an update on a file loaded document, by copying the source to another destination:

    string inputPath;
    string outputPath;
    auto input = std::make_shared<FileStreamDevice>(inputPath);
    FileStreamDevice output(outputPath, FileMode::Create);
    input->CopyTo(output);

    PdfMemDocument doc;
    doc.LoadFromDevice(input);

    doc.SaveUpdate(output);

Sign a buffer loaded document:

    bufferview inputBuffer;
    charbuff outputBuffer;
    auto input = std::make_shared<SpanStreamDevice>(inputBuffer);
    BufferStreamDevice output(outputBuffer);
    input->CopyTo(output);

    PdfMemDocument doc;
    doc.LoadFromDevice(input);

    // Retrieve signature, create the signer, ...

    mm::SignDocument(doc, output, signer, signature);

No warranty

pdfmm may or may not work for your needs and comes with absolutely no warranty. Serious bugs, including security flaws, may be fixed at arbitrary timeframes, or not fixed at all.

Contributions

If you find a bug and know how to fix it, or you want to add a small feature, you're welcome to send a pull request, providing it follows the coding style of the project. Also, as a minimum requisite, any contribution should be valuable for a multitude of people, to avoid it to be only self relevant for the contributor. Other reasons for the rejection, or hold, of a pull request may be:

  • the change doesn't fit the scope of pdfmm;
  • the change shows lack of knowledge/mastery of the PDF specification and/or C++ language;
  • the change breaks automatic tests performed by the maintainer;
  • general lack of time in reviewing and merging the change.

If you need to implement a bigger feature or refactor, check first if it was already planned in the issue list. The feature may be up for grabs, meaning that it's open for external contributions. Please write in the relevant issue that you started to work on that, to receive some feedback/coordination. If it's not, it means that the refactor/feature is planned to be implemented later by the maintainer(s). If the feature is not listed in the issues, add it and/or create a discussion to receive some feedback and discuss some basic design choices.

Authors

pdfmm is currently developed and mantained by Francesco Pretto . pdfmm was forked from the PoDoFo library, which was written by Dominik Seichter, Leonard Rosenthol, Craig Ringer and others. See the file AUTHORS.md for more details.

pdfmm's People

Contributors

ceztko avatar ferencios avatar stephanecharette avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pdfmm's Issues

Tool: pdfbox

The task is to recreate the following old PoDoFo tool:

podofobox - set the media, crop, bleed, trim, and art box on pages of a PDF
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofobox.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofobox

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdfimg2pdf

The task is to recreate the following old PoDoFo tool:

podofoimg2pdf - Convert images to PDF files
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofoimg2pdf.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofoimg2pdf

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdftxt2pdf

The task is to recreate the following old PoDoFo tool:

podofotxt2pdf - convert plain text files into PDF files
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofotxt2pdf.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofotxt2pdf

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdfcountpages

The task is to recreate the following old PoDoFo tool:

podofocountpages - count the number of pages in a pdf file
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofocountpages.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofocountpages

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original functionality.

Library rendering support

pdfmm does not currently support rendering PDF content to a drawing/canvas surface. With the recent PdfEncoding work it should be much more easy to select the GID of the glyph to render, after having loaded the font with freetype. The rendering support should, as a minimum:

  1. Be based on cairo (the C library, not the C++ wrapper cairomm);
  2. Use the facilities in PdfEncoding/PdfFont to select the glyphs' GID;
  3. Use some common linear algebra primitives to perform mathematic transformations.

The primitives in (3) are not yet available but they will be after the API for text extraction is delivered, as said in this issue. Before that the task is not yet available for graps.

Example is failing for v0.9.22

Hi everyone!

pdfmm looks a very interesting project! thanks for working on that!

as I mentioned in a previous issue, I am packaging pdfmm on conda-forge.
Using that package I am not able to build the example at https://github.com/pdfmm/pdfmm/blob/v0.9.22/examples/helloworld/helloworld.cpp

This is the error that is rasing here::

bash ./scripts/optclean.sh
mkdir -p build
set -ex
meson setup \
	--prefix /home/xmn/mambaforge/envs/poc-pdfmm \
	--libdir /home/xmn/mambaforge/envs/poc-pdfmm/lib \
	--includedir /home/xmn/mambaforge/envs/poc-pdfmm/include \
	--includedir /home/xmn/mambaforge/envs/poc-pdfmm/include/pdfmm \
	--buildtype=release \
	--native-file meson.native  \
	build .
meson compile -C build
The Meson build system
Version: 0.63.2
Source dir: /mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm
Build dir: /mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm/build
Build type: native build
Project name: pocpdfmm
Project version: 1.0.0
C compiler for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-cc (gcc 10.4.0 "x86_64-conda-linux-gnu-cc (conda-forge gcc 10.4.0-16) 10.4.0")
C linker for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-cc ld.lld 14.0.4
C++ compiler for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-c++ (gcc 10.4.0 "x86_64-conda-linux-gnu-c++ (conda-forge gcc 10.4.0-16) 10.4.0")
C++ linker for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-c++ ld.lld 14.0.4
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: /home/xmn/mambaforge/envs/poc-pdfmm/bin/pkg-config (0.29.2)
Run-time dependency cli11 found: YES 2.2.0
Found CMake: /home/xmn/mambaforge/envs/poc-pdfmm/bin/cmake (3.24.2)
Run-time dependency glog found: YES 0.6.0
WARNING: You should add the boolean check kwarg to the run_command call.
         It currently defaults to false,
         but it will default to true in future releases of meson.
         See also: https://github.com/mesonbuild/meson/issues/9300
Dependency gtest skipped: feature dev disabled
Dependency gmock skipped: feature dev disabled
Program clang-tidy skipped: feature dev disabled
Build targets in project: 3

pocpdfmm 1.0.0

  User defined options
    Native files: meson.native
    buildtype   : release
    includedir  : /home/xmn/mambaforge/envs/poc-pdfmm/include/pdfmm
    libdir      : /home/xmn/mambaforge/envs/poc-pdfmm/lib
    prefix      : /home/xmn/mambaforge/envs/poc-pdfmm

Found ninja-1.11.0 at /home/xmn/mambaforge/envs/poc-pdfmm/bin/ninja
ninja: Entering directory `/mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm/build'
[0/1] Regenerating build files.
Cleaning... 0 files.
The Meson build system
Version: 0.63.2
Source dir: /mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm
Build dir: /mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm/build
Build type: native build
Project name: pocpdfmm
Project version: 1.0.0
C compiler for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-cc (gcc 10.4.0 "x86_64-conda-linux-gnu-cc (conda-forge gcc 10.4.0-16) 10.4.0")
C linker for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-cc ld.lld 14.0.4
C++ compiler for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-c++ (gcc 10.4.0 "x86_64-conda-linux-gnu-c++ (conda-forge gcc 10.4.0-16) 10.4.0")
C++ linker for the host machine: /home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-c++ ld.lld 14.0.4
Host machine cpu family: x86_64
Host machine cpu: x86_64
Dependency CLI11 found: YES 2.2.0 (cached)
Dependency glog found: YES 0.6.0 (cached)
WARNING: You should add the boolean check kwarg to the run_command call.
         It currently defaults to false,
         but it will default to true in future releases of meson.
         See also: https://github.com/mesonbuild/meson/issues/9300
Dependency gtest skipped: feature dev disabled
Dependency gmock skipped: feature dev disabled
Program clang-tidy skipped: feature dev disabled
Build targets in project: 3

pocpdfmm 1.0.0

  User defined options
    Native files: /mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm/meson.native
    backend     : ninja
    buildtype   : release
    includedir  : /home/xmn/mambaforge/envs/poc-pdfmm/include/pdfmm
    libdir      : /home/xmn/mambaforge/envs/poc-pdfmm/lib
    prefix      : /home/xmn/mambaforge/envs/poc-pdfmm

Found ninja-1.11.0 at /home/xmn/mambaforge/envs/poc-pdfmm/bin/ninja
[1/6] Linking static target liblibpdfmm.so.a
[2/6] Compiling C++ object libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o
[3/6] Linking target libpoc-pdfmm-lib.so
FAILED: libpoc-pdfmm-lib.so 
/home/xmn/mambaforge/envs/poc-pdfmm/bin/x86_64-conda-linux-gnu-c++  -o libpoc-pdfmm-lib.so libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o -L/home/xmn/mambaforge/envs/poc-pdfmm/lib -Wl,--as-needed -Wl,--no-undefined -fuse-ld=lld -Wl,-O1 -shared -fPIC -Wl,--start-group -Wl,-soname,libpoc-pdfmm-lib.so -Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections -Wl,--allow-shlib-undefined -Wl,-rpath,/home/xmn/mambaforge/envs/poc-pdfmm/lib -Wl,-rpath-link,/home/xmn/mambaforge/envs/poc-pdfmm/lib -fvisibility-inlines-hidden -std=c++17 -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /home/xmn/mambaforge/envs/poc-pdfmm/include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /home/xmn/mambaforge/envs/poc-pdfmm/include liblibpdfmm.so.a -lpthread /home/xmn/mambaforge/envs/poc-pdfmm/lib/libgflags.so.2.2.2 /home/xmn/mambaforge/envs/poc-pdfmm/lib/libglog.so.0.6.0 -Wl,--end-group
ld.lld: error: undefined symbol: vtable for mm::PdfString
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(mm::PdfString::~PdfString())
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(mm::PdfString::~PdfString())
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)

ld.lld: error: undefined symbol: mm::PdfDataProvider::~PdfDataProvider()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(mm::PdfString::~PdfString())
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(mm::PdfString::~PdfString())
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> referenced 4 more times

ld.lld: error: undefined symbol: mm::PdfError::PdfError(mm::PdfErrorCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&) (.cold))

ld.lld: error: undefined symbol: mm::PdfPainter::FinishDrawing()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&) (.cold))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfEncoding::~PdfEncoding()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&) (.cold))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfPainter::~PdfPainter()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&) (.cold))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfMemDocument::~PdfMemDocument()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&) (.cold))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfMemDocument::PdfMemDocument(bool)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfPainter::PdfPainter(mm::PdfPainterFlags)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfDocument::GetPages()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfPage::CreateStandardPageSize(mm::PdfPageSize, bool)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfPageCollection::CreatePage(mm::PdfRect const&)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfPainter::SetCanvas(mm::PdfCanvas*)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfEncoding::PdfEncoding()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfFontManager::GetFont(std::basic_string_view<char, std::char_traits<char> > const&, mm::PdfFontSearchParams const&, mm::PdfFontCreateParams const&)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfTextStateWrapper::SetFont(mm::PdfFont const*, double)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfPage::GetRect() const
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfPainter::DrawText(std::basic_string_view<char, std::char_traits<char> > const&, double, double)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))

ld.lld: error: undefined symbol: mm::PdfDocument::GetInfo()
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> referenced 2 more times

ld.lld: error: undefined symbol: mm::PdfString::PdfString(char const*)
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> referenced by example.cpp
>>>               libpoc-pdfmm-lib.so.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_example.cpp.o:(HelloWorld(std::basic_string_view<char, std::char_traits<char> > const&))
>>> referenced 2 more times

ld.lld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
collect2: error: ld returned 1 exit status
[4/6] Compiling C++ object pocpdfmm.p/_mnt_sda1_storage_dev_inlyse-projects_poc-pdfmm_poc-pdfmm_src_main.cpp.o
/mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm/poc-pdfmm/src/main.cpp: In function 'void show_version(int)':
/mnt/sda1/storage/dev/inlyse-projects/poc-pdfmm/poc-pdfmm/src/main.cpp:16:23: warning: unused parameter 'count' [-Wunused-parameter]
   16 | auto show_version(int count) -> void {
      |                   ~~~~^~~~~
ninja: build stopped: subcommand failed.

Another thing that I saw is that additionally to the include folder (that is really required), I need to specify "include/pdfmm" because in the headers files it is including "pdfmm_config.h". not sure if this is expected or if I am missing something. Normally I just need to point to my include folder from the (conda) environment and it is enough.

for instance, my code is here: https://github.com/xmnlab/poc-pdfmm
basically it just has infrastructure code (scripts, build system, etc) and the example from this repository. when I have it properly working, I will replace that by some code from my own.

Tool: pdfmerge

The task is to recreate the following old PoDoFo tool:

podofomerge - merge several PDF files
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofomerge.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofomerge

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Re-enable linearization

Linearization has not been recently tested and it may be broken. Review all the relevant code.

Tool: pdfcrop

The task is to recreate the following old PoDoFo tool:

podofocrop - crop all pages
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofocrop.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofocrop

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original functionality.

Build issue

Hi. I am trying to compile it on Linux x64. The compiler throws the following error:

[  1%] Building CXX object src/pdfmm/private/CMakeFiles/pdfmm_private.dir/FreetypePrivate.cpp.o
[  2%] Building CXX object src/pdfmm/private/CMakeFiles/pdfmm_private.dir/JpegCommon.cpp.o
[  2%] Building CXX object src/pdfmm/private/CMakeFiles/pdfmm_private.dir/PdfDeclarationsPrivate.cpp.o
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:12:
/home/gcode/pdfmm/src/pdfmm/private/charconv_compat.h:22:11: error: conflicting declaration โ€˜using chars_format = enum fast_float::chars_formatโ€™
   22 |     using chars_format = fast_float::chars_format;
      |           ^~~~~~~~~~~~
In file included from /home/gcode/pdfmm/src/pdfmm/private/charconv_compat.h:4,
                 from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:12:
/usr/include/c++/10/charconv:658:14: note: previous declaration as โ€˜enum class std::chars_formatโ€™
  658 |   enum class chars_format
      |              ^~~~~~~~~~~~
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:13:
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:165:31: error: โ€˜u16beoctetiterableโ€™ does not name a type
  165 |     using u16bechariterable = u16beoctetiterable<char>;
      |                               ^~~~~~~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:166:31: error: โ€˜u16leoctetiterableโ€™ does not name a type
  166 |     using u16lechariterable = u16leoctetiterable<char>;
      |                               ^~~~~~~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h: In function โ€˜word_iterator std::append16(uint32_t, word_iterator)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:172:19: error: there are no arguments to โ€˜invalid_code_pointโ€™ that depend on a template parameter, so a declaration of โ€˜invalid_code_pointโ€™ must be available [-fpermissive]
  172 |             throw invalid_code_point(cp);
      |                   ^~~~~~~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:172:19: note: (if you use โ€˜-fpermissiveโ€™, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h: In function โ€˜void std::append(char32_t, std::u16string&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:206:9: error: โ€˜append16โ€™ was not declared in this scope
  206 |         append16(uint32_t(cp), std::back_inserter(s));
      |         ^~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:206:9: note: suggested alternatives:
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:169:19: note:   โ€˜std::append16โ€™
  169 |     word_iterator append16(uint32_t cp, word_iterator result)
      |                   ^~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/utfcpp_extensions.h:189:23: note:   โ€˜std::append16โ€™
  189 |         word_iterator append16(uint32_t cp, word_iterator result)
      |                       ^~~~~~~~
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:15:
/home/gcode/pdfmm/src/pdfmm/base/PdfInputStream.h: At global scope:
/home/gcode/pdfmm/src/pdfmm/base/PdfInputStream.h:57:17: error: โ€˜OutputStreamโ€™ has not been declared
   57 |     void CopyTo(OutputStream& stream);
      |                 ^~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/base/PdfInputStream.h:59:17: error: โ€˜OutputStreamโ€™ has not been declared
   59 |     void CopyTo(OutputStream& stream, size_t size);
      |                 ^~~~~~~~~~~~
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:18:
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:212:9: error: โ€˜stringviewbufferโ€™ does not name a type
  212 |         stringviewbuffer<CharT> m_buf;
      |         ^~~~~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h: In constructor โ€˜cmn::basic_istringviewstream<CharT>::basic_istringviewstream()โ€™:
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:173:26: error: โ€˜m_bufโ€™ was not declared in this scope
  173 |             this->rdbuf(&m_buf);
      |                          ^~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h: In constructor โ€˜cmn::basic_istringviewstream<CharT>::basic_istringviewstream(const CharT*, std::size_t)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:176:51: error: class โ€˜cmn::basic_istringviewstream<CharT>โ€™ does not have any field named โ€˜m_bufโ€™
  176 |             : std::basic_istream<CharT>(nullptr), m_buf(buffer, size)
      |                                                   ^~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:178:26: error: โ€˜m_bufโ€™ was not declared in this scope
  178 |             this->rdbuf(&m_buf);
      |                          ^~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h: In constructor โ€˜cmn::basic_istringviewstream<CharT>::basic_istringviewstream(const std::basic_string_view<Char>&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:182:51: error: class โ€˜cmn::basic_istringviewstream<CharT>โ€™ does not have any field named โ€˜m_bufโ€™
  182 |             : std::basic_istream<CharT>(nullptr), m_buf(view)
      |                                                   ^~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:184:26: error: โ€˜m_bufโ€™ was not declared in this scope
  184 |             this->rdbuf(&m_buf);
      |                          ^~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h: In member function โ€˜void cmn::basic_istringviewstream<CharT>::str(const CharT*, std::size_t)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:197:13: error: โ€˜m_bufโ€™ was not declared in this scope
  197 |             m_buf.str(buffer, size);
      |             ^~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h: In member function โ€˜void cmn::basic_istringviewstream<CharT>::str(const std::basic_string_view<Char>&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:202:13: error: โ€˜m_bufโ€™ was not declared in this scope
  202 |             m_buf.str(view);
      |             ^~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h: At global scope:
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:215:31: error: โ€˜basic_istringviewstreamโ€™ does not name a type
  215 |     using istringviewstream = basic_istringviewstream<char>;
      |                               ^~~~~~~~~~~~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/istringviewstream.h:216:32: error: โ€˜basic_istringviewstreamโ€™ does not name a type
  216 |     using wistringviewstream = basic_istringviewstream<wchar_t>;
      |                                ^~~~~~~~~~~~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::ReadTo(mm::charbuff&, const string_view&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:302:5: error: โ€˜ReadToโ€™ was not declared in this scope; did you mean โ€˜utls::ReadToโ€™?
  302 |     ReadTo(str, istream);
      |     ^~~~~~
      |     utls::ReadTo
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:332:10: note: โ€˜utls::ReadToโ€™ declared here
  332 |     void ReadTo(mm::charbuff& str, std::istream& stream);
      |          ^~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::WriteTo(const string_view&, const bufferview&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:321:5: error: โ€˜WriteToโ€™ was not declared in this scope; did you mean โ€˜utls::WriteToโ€™?
  321 |     WriteTo(ostream, view);
      |     ^~~~~~~
      |     utls::WriteTo
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:334:10: note: โ€˜utls::WriteToโ€™ declared here
  334 |     void WriteTo(std::ostream& stream, const mm::bufferview& view);
      |          ^~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::WriteTo(std::ostream&, const bufferview&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:326:10: error: โ€˜istringviewstreamโ€™ is not a member of โ€˜cmnโ€™; did you mean โ€˜basic_istringviewstreamโ€™?
  326 |     cmn::istringviewstream istream(view.data(), view.size());
      |          ^~~~~~~~~~~~~~~~~
      |          basic_istringviewstream
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:327:27: error: expected primary-expression before โ€˜)โ€™ token
  327 |     CopyTo(stream, istream);
      |                           ^
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:327:5: error: โ€˜CopyToโ€™ was not declared in this scope; did you mean โ€˜utls::CopyToโ€™?
  327 |     CopyTo(stream, istream);
      |     ^~~~~~
      |     utls::CopyTo
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:285:6: note: โ€˜utls::CopyToโ€™ declared here
  285 | void utls::CopyTo(ostream& dst, istream& src)
      |      ^~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:324:55: warning: unused parameter โ€˜viewโ€™ [-Wunused-parameter]
  324 | void utls::WriteTo(ostream& stream, const bufferview& view)
      |                                     ~~~~~~~~~~~~~~~~~~^~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::WriteUtf16BETo(std::u16string&, char32_t)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:445:5: error: โ€˜ByteSwapโ€™ was not declared in this scope; did you mean โ€˜utls::ByteSwapโ€™?
  445 |     ByteSwap(str);
      |     ^~~~~~~~
      |     utls::ByteSwap
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:434:20: note: โ€˜utls::ByteSwapโ€™ declared here
  434 |     inline int64_t ByteSwap(int64_t n)
      |                    ^~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::ReadUtf16BEString(const bufferview&, std::string&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:451:11: error: โ€˜u16bechariterableโ€™ is not a member of โ€˜utf8โ€™; did you mean โ€˜u16beoctetiterableโ€™?
  451 |     utf8::u16bechariterable iterable(buffer.data(), buffer.size());
      |           ^~~~~~~~~~~~~~~~~
      |           u16beoctetiterable
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:452:20: error: โ€˜iterableโ€™ was not declared in this scope
  452 |     utf8::utf16to8(iterable.begin(), iterable.end(), std::back_inserter(utf8str));
      |                    ^~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:449:48: warning: unused parameter โ€˜bufferโ€™ [-Wunused-parameter]
  449 | void utls::ReadUtf16BEString(const bufferview& buffer, string& utf8str)
      |                              ~~~~~~~~~~~~~~~~~~^~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::ReadUtf16LEString(const bufferview&, std::string&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:457:11: error: โ€˜u16lechariterableโ€™ is not a member of โ€˜utf8โ€™; did you mean โ€˜u16leoctetiterableโ€™?
  457 |     utf8::u16lechariterable iterable(buffer.data(), buffer.size());
      |           ^~~~~~~~~~~~~~~~~
      |           u16leoctetiterable
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:458:20: error: โ€˜iterableโ€™ was not declared in this scope
  458 |     utf8::utf16to8(iterable.begin(), iterable.end(), std::back_inserter(utf8str));
      |                    ^~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:455:48: warning: unused parameter โ€˜bufferโ€™ [-Wunused-parameter]
  455 | void utls::ReadUtf16LEString(const bufferview& buffer, string& utf8str)
      |                              ~~~~~~~~~~~~~~~~~~^~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::WriteUInt32BE(mm::OutputStream&, uint32_t)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:584:5: error: โ€˜WriteUInt32BEโ€™ was not declared in this scope; did you mean โ€˜utls::WriteUInt32BEโ€™?
  584 |     WriteUInt32BE(buf, value);
      |     ^~~~~~~~~~~~~
      |     utls::WriteUInt32BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:359:10: note: โ€˜utls::WriteUInt32BEโ€™ declared here
  359 |     void WriteUInt32BE(char* buf, uint32_t value);
      |          ^~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::WriteInt32BE(mm::OutputStream&, int32_t)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:591:5: error: โ€˜WriteInt32BEโ€™ was not declared in this scope; did you mean โ€˜utls::WriteInt32BEโ€™?
  591 |     WriteInt32BE(buf, value);
      |     ^~~~~~~~~~~~
      |     utls::WriteInt32BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:360:10: note: โ€˜utls::WriteInt32BEโ€™ declared here
  360 |     void WriteInt32BE(char* buf, int32_t value);
      |          ^~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::WriteUInt16BE(mm::OutputStream&, uint16_t)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:598:5: error: โ€˜WriteUInt16BEโ€™ was not declared in this scope; did you mean โ€˜utls::WriteUInt16BEโ€™?
  598 |     WriteUInt16BE(buf, value);
      |     ^~~~~~~~~~~~~
      |     utls::WriteUInt16BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:361:10: note: โ€˜utls::WriteUInt16BEโ€™ declared here
  361 |     void WriteUInt16BE(char* buf, uint16_t value);
      |          ^~~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::WriteInt16BE(mm::OutputStream&, int16_t)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:605:5: error: โ€˜WriteInt16BEโ€™ was not declared in this scope; did you mean โ€˜utls::WriteInt16BEโ€™?
  605 |     WriteInt16BE(buf, value);
      |     ^~~~~~~~~~~~
      |     utls::WriteInt16BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:362:10: note: โ€˜utls::WriteInt16BEโ€™ declared here
  362 |     void WriteInt16BE(char* buf, int16_t value);
      |          ^~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::ReadUInt32BE(mm::InputStream&, uint32_t&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:645:5: error: โ€˜ReadUInt32BEโ€™ was not declared in this scope; did you mean โ€˜utls::ReadUInt32BEโ€™?
  645 |     ReadUInt32BE(buf, value);
      |     ^~~~~~~~~~~~
      |     utls::ReadUInt32BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:367:10: note: โ€˜utls::ReadUInt32BEโ€™ declared here
  367 |     void ReadUInt32BE(const char* buf, uint32_t& value);
      |          ^~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::ReadInt32BE(mm::InputStream&, int32_t&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:652:5: error: โ€˜ReadInt32BEโ€™ was not declared in this scope; did you mean โ€˜utls::ReadInt32BEโ€™?
  652 |     ReadInt32BE(buf, value);
      |     ^~~~~~~~~~~
      |     utls::ReadInt32BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:368:10: note: โ€˜utls::ReadInt32BEโ€™ declared here
  368 |     void ReadInt32BE(const char* buf, int32_t& value);
      |          ^~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::ReadUInt16BE(mm::InputStream&, uint16_t&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:659:5: error: โ€˜ReadUInt16BEโ€™ was not declared in this scope; did you mean โ€˜utls::ReadUInt16BEโ€™?
  659 |     ReadUInt16BE(buf, value);
      |     ^~~~~~~~~~~~
      |     utls::ReadUInt16BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:369:10: note: โ€˜utls::ReadUInt16BEโ€™ declared here
  369 |     void ReadUInt16BE(const char* buf, uint16_t& value);
      |          ^~~~~~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp: In function โ€˜void utls::ReadInt16BE(mm::InputStream&, int16_t&)โ€™:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:666:5: error: โ€˜ReadInt16BEโ€™ was not declared in this scope; did you mean โ€˜utls::ReadInt16BEโ€™?
  666 |     ReadInt16BE(buf, value);
      |     ^~~~~~~~~~~
      |     utls::ReadInt16BE
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:370:10: note: โ€˜utls::ReadInt16BEโ€™ declared here
  370 |     void ReadInt16BE(const char* buf, int16_t& value);
      |          ^~~~~~~~~~~
In file included from /usr/include/c++/10/algorithm:62,
                 from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:24,
                 from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/usr/include/c++/10/bits/stl_algo.h: At global scope:
/usr/include/c++/10/bits/stl_algo.h:4304:5: warning: โ€˜_OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; _OIter = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; _UnaryOperation = utls::ToLower(const string_view&)::<lambda(unsigned char)>]โ€™ used but never defined
 4304 |     transform(_InputIterator __first, _InputIterator __last,
      |     ^~~~~~~~~
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:27,
                 from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/Format.h:21:24: warning: โ€˜void utls::FormatTo(std::string&, const string_view&, const Args& ...) [with Args = {double, short unsigned int}; std::string = std::__cxx11::basic_string<char>; std::string_view = std::basic_string_view<char>]โ€™ used but never defined
   21 |     inline static void FormatTo(std::string& dst, const std::string_view& fmt, const Args&... args)
      |                        ^~~~~~~~
/home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:34:13: warning: โ€˜void std::removeTrailingZeroes(std::string&)โ€™ used but never defined
   34 | static void removeTrailingZeroes(string& str);
      |             ^~~~~~~~~~~~~~~~~~~~
In file included from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.h:27,
                 from /home/gcode/pdfmm/src/pdfmm/private/PdfDeclarationsPrivate.cpp:9:
/home/gcode/pdfmm/src/pdfmm/private/Format.h:21:24: warning: โ€˜void utls::FormatTo(std::string&, const string_view&, const Args& ...) [with Args = {float, short unsigned int}; std::string = std::__cxx11::basic_string<char>; std::string_view = std::basic_string_view<char>]โ€™ used but never defined
   21 |     inline static void FormatTo(std::string& dst, const std::string_view& fmt, const Args&... args)
      |                        ^~~~~~~~
cc1plus: note: unrecognized command-line option โ€˜-Wno-unknown-warning-optionโ€™ may have been intended to silence earlier diagnostics
make[2]: *** [src/pdfmm/private/CMakeFiles/pdfmm_private.dir/build.make:108: src/pdfmm/private/CMakeFiles/pdfmm_private.dir/PdfDeclarationsPrivate.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:308: src/pdfmm/private/CMakeFiles/pdfmm_private.dir/all] Error 2
make: *** [Makefile:160: all] Error 2

Tool: pdfencrypt

The task is to recreate the following old PoDoFo tool:

podofoencrypt - encrypt PDF files and set PDF security settings
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofoencrypt.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofoencrypt

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original functionality.

Tool: pdfimpose

The task is to recreate the following old PoDoFo tool:

podofoimpose - A powerful PDF imposition tool
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofoimpose.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofoimpose

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdfpages

The task is to recreate the following old PoDoFo tool:

podofopages - move and delete pages in a PDF document
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofopages.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofopages

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdfuncompress

The task is to recreate the following old PoDoFo tool:

podofouncompress - Uncompress PDF files
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofouncompress.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofouncompress

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Re-enable tests (with googletest)

Tests are currently disabled and unmaintained. pdfmm is currently running on a closed source test suite.
The idea would be to re-enable tests, also following ideas by Christopher Creutzig. The tests should be ported to googletest. Also a common fixture area with real world pdfs to test should be added.

Tool: pdfcolor

The task is to recreate the following old PoDoFo tool:

podofocolor - modify colors in a PDF file
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofocolor.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofocolor

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original functionality.

Tool: pdfincrementalupdates

The task is to recreate the following old PoDoFo tool:

podofoincrementalupdates - Provides information about incremental updates in Pdf files
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofoincrementalupdates.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofoincrementalupdates

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdfimgextract

The task is to recreate the following old PoDoFo tool:

podofoimgextract - Extract all images from a PDF file
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofoimgextract.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofoimgextract

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdfxmp

The task is to recreate the following old PoDoFo tool:

podofoxmp - Modify or extract XMP information from a PDF file
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofoxmp.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofoxmp

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Tool: pdfinfo

The task is to recreate the following old PoDoFo tool:

podofopdfinfo - provide information about a PDF file
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofopdfinfo.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofopdfinfo

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Unsatisfied link error on iOS

I built pdfmm for iOS as static library by using Xcode.

Then I imported the generated .a in an app project in Xcode and I integrated pdfmm in my code, but when I build the app I got several unsatisfied link error:

fmt::v8::detail::write
fmt::v8::detail::snprintf
fmt::v8::detail::format_float
fmt::v8::detail::snprintf_float
fmt::v8::detail::decimal_point_impl
fmt::v8::detail::thousands_sep_impl
fmt::v8::detail::thousands_sep_result

this errors log in Xcode:

 "int fmt::v8::detail::snprintf_ "int fmt::v8::detail::snprintf_float<long double>(long double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)
      ...
  "int fmt::v8::detail::format_float<long double>(long double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)
      ...
  "char fmt::v8::detail::decimal_point_impl<char>(fmt::v8::detail::locale_ref)", referenced from:
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)
      ...
  "int fmt::v8::detail::snprintf_float<double>(double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      ...
  "int fmt::v8::detail::format_float<double>(double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      ...
  "fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep_impl<char>(fmt::v8::detail::locale_ref)", referenced from:
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)float<long double>(long double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)
      ...
  "int fmt::v8::detail::format_float<long double>(long double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, long double, 0>(fmt::v8::appender, long double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)
      ...
  "char fmt::v8::detail::decimal_point_impl<char>(fmt::v8::detail::locale_ref)", referenced from:
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      char fmt::v8::detail::decimal_point<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)
      ...
  "int fmt::v8::detail::snprintf_float<double>(double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      ...
  "int fmt::v8::detail::format_float<double>(double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)", referenced from:
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, double, 0>(fmt::v8::appender, double, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, float, 0>(fmt::v8::appender, float, fmt::v8::basic_format_specs<char>, fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      ...
  "fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep_impl<char>(fmt::v8::detail::locale_ref)", referenced from:
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfElement.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfPainter.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfInputStream.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfAcroForm.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfEncoding.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfOutputStream.o)
      fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep<char>(fmt::v8::detail::locale_ref) in libpdfmm-static.a(PdfSignature.o)

Tool: pdfgc

The task is to recreate the following old PoDoFo tool:

podofogc - Garbage collection in a PDF file
https://github.com/pdfmm/pdfmm/blob/svntrunk/man/podofogc.1
https://github.com/pdfmm/pdfmm/tree/svntrunk/tools/podofogc

The tool should be licensed using a new non GPL license, probably Apache License 2.0 or MIT, as decided in this discussion. Because of this, the tool must be created from scratch to respect the GPL license. No copy and paste plus porting of the old code accepted. A peek on the old code should be fine, but you should write the code yourself as part of a creative process and be able to demonstrate it was your authentic rewriting of the functionalities of the old tool, possibly featuring some new original ones.

Clean/reactivate doxygen documentation

Doxygen documentation has not been checked/reviewed. Hope would be to remove all redundant/obvious parameters documentation. Also very appreciated would be to change documentation notation to something else like the doxygen triple slash notation /// or, if it works also for C++, xmldoc.

How to replace PoDoFo::PdfSignatureField with mm::PdfSignature

Basically I am trying to rewrite the podofosign tool

Currently I don't know how to write these portions of code

CASE 1 (PdfAnnotation already exists which needs an update)

            pTemporaryAnnot = new PdfAnnotation( pExistingSigField, pPage );
            if( !pTemporaryAnnot )
                PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "Cannot allocate annotation object for existing signature field" );

            pSignField = new PdfSignatureField( pTemporaryAnnot );
            if( !pSignField )
                PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "Cannot allocate existing signature field object" );

CASE 2 (PdfAnnotation which must be created from scratch)

            PdfAnnotation* pAnnot = pPage->CreateAnnotation( ePdfAnnotation_Widget, annot_rect );
            if( !pAnnot )
                PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "Cannot allocate annotation object" );

            if( annot_position && annot_print )
                pAnnot->SetFlags( ePdfAnnotationFlags_Print );
            else if( !annot_position && ( !field_name || !field_use_existing ) )
                pAnnot->SetFlags( ePdfAnnotationFlags_Invisible | ePdfAnnotationFlags_Hidden );

            pSignField = new PdfSignatureField( pAnnot, pAcroForm, &document );

CASE 3

                PdfRect annotSize( 0.0, 0.0, annot_rect.GetWidth(), annot_rect.GetHeight() );
                PdfXObject sigXObject( annotSize, &document );

What i am trying to write

ATTEMPT 1

        std::unique_ptr<PdfAnnotation> tempAnnot = std::make_unique<PdfAnnotation>(pTemporaryAnnot);
        
        if ( !PdfAnnotation::TryCreateFromObject<PdfAnnotation>(*pExistingSigField, tempAnnot) )
        {
            MM_RAISE_ERROR_INFO( PdfErrorCode::OutOfMemory, "Cannot allocate annotation object for existing signature field" );
        }
        
        if( !pExistingSigField->GetDictionary().HasKey( "V" ) )
        {
            MM_RAISE_ERROR_INFO( PdfErrorCode::InvalidKey, "Cannot find 'V' key" );
        }
        
        std::unique_ptr<PdfField> signField = std::make_unique<PdfField>(pSignField);
        
        PdfObject *obj = pExistingSigField->GetDictionary().FindKey( "V" );
        
        if ( !PdfSignature::TryCreateFromObject(*obj, signField) )
        {
            // TODO: raise error
        }

        if( !pSignField )
        {
            MM_RAISE_ERROR_INFO( PdfErrorCode::OutOfMemory, "Cannot allocate existing signature field object" );
        }

ATTEMPT 2
it seems paradoxical but I didn't understand how to create a PdfSignature from scratch (starting from a PdfRect annot_rect)

ATTEMPT 3


        PdfObject *rect_obj = pExistingSigField->GetDictionary().GetKey("Rect");
        
        PdfXObjectForm *sigXObject;
        std::unique_ptr<PdfXObjectForm> sigObject = std::make_unique<PdfXObjectForm>(sigXObject);

        if ( !PdfXObjectForm::TryCreateFromObject(*rect_obj, sigObject) )
        {
            // TODO: raise error
        }

I noticed that the utility constructors are all private, I guess for a precise choice, it seems that the idea is to use TryCreateFromObject.

Also I realized that a concrete class of the PdfSigner is missing.

Thanks for your help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.