{"id":13831318,"url":"https://github.com/podofo/podofo","last_synced_at":"2025-04-05T04:14:34.105Z","repository":{"id":40568747,"uuid":"481119304","full_name":"podofo/podofo","owner":"podofo","description":"A C++17 PDF manipulation library","archived":false,"fork":false,"pushed_at":"2023-12-19T21:22:32.000Z","size":7465,"stargazers_count":245,"open_issues_count":11,"forks_count":55,"subscribers_count":14,"default_branch":"master","last_synced_at":"2023-12-20T12:05:33.170Z","etag":null,"topics":["cplusplus","cpp","pdf","pdf-documents","pdf-files","pdf-generation"],"latest_commit_sha":null,"homepage":"https://podofo.github.io","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/podofo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md"}},"created_at":"2022-04-13T07:40:21.000Z","updated_at":"2023-12-21T19:16:43.788Z","dependencies_parsed_at":"2023-10-16T03:09:11.317Z","dependency_job_id":"cd3f58b1-0ef6-44c1-8971-422cd8486fd2","html_url":"https://github.com/podofo/podofo","commit_stats":null,"previous_names":[],"tags_count":53,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podofo%2Fpodofo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podofo%2Fpodofo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podofo%2Fpodofo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podofo%2Fpodofo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/podofo","download_url":"https://codeload.github.com/podofo/podofo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284953,"owners_count":20913704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cplusplus","cpp","pdf","pdf-documents","pdf-files","pdf-generation"],"created_at":"2024-08-04T10:01:24.501Z","updated_at":"2025-04-05T04:14:34.086Z","avatar_url":"https://github.com/podofo.png","language":"C++","readme":"# PoDoFo [![build-linux](https://github.com/podofo/podofo/actions/workflows/build-linux.yml/badge.svg)](https://github.com/podofo/podofo/actions/workflows/build-linux.yml) [![build-mac](https://github.com/podofo/podofo/actions/workflows/build-mac.yml/badge.svg)](https://github.com/podofo/podofo/actions/workflows/build-mac.yml) [![build-win](https://github.com/podofo/podofo/actions/workflows/build-win.yml/badge.svg)](https://github.com/podofo/podofo/actions/workflows/build-win.yml)\n\n1.  [What is PoDoFo?](#what-is-podofo)\n2.  [Requirements](#requirements)\n3.  [Licensing](#licensing)\n4.  [Development quickstart](#development-quickstart)\n5.  [Doxygen Documentation](#doxygen-documentation)\n6.  [String encoding and buffer conventions](#string-encoding-and-buffer-conventions)\n7.  [API Stability](#api-stability)\n8.  [PoDoFo tools](#podofo-tools)\n9.  [TODO](#todo)\n10.  [FAQ](#faq)\n11.  [No warranty](#no-warranty)\n12.  [Contributions](#contributions)\n13.  [Authors](#authors)\n\n## What is PoDoFo?\n\nPoDoFo is a free portable C++ library to work with the PDF file format.\n\nPoDoFo provides classes to parse a PDF file and modify its content\ninto memory. The changes can be written back to disk easily.\nBesides PDF parsing PoDoFo also provides facilities to create your\nown PDF files from scratch. It currently does not\nsupport rendering PDF content.\n\n## Requirements\n\nTo build PoDoFo lib you'll need a c++17 compiler,\nCMake 3.16 and the following libraries (tentative minimum versions indicated):\n\n* freetype2 (2.11)\n* fontconfig (2.13.94, required for Unix platforms, optional for Windows)\n* OpenSSL (1.1 and 3.0 are supported)\n* LibXml2 (2.9.12)\n* zlib\n* libjpeg (9d, optional)\n* libtiff (4.0.10, optional)\n* libpng (1.6.37, optional)\n\nFor the most popular toolchains, PoDoFo requires the following\nminimum versions:\n\n* msvc++ 14.16 (VS 2017 15.9)\n* gcc 9.0\n* clang/llvm 7.0\n\nIt is regularly tested with the following IDE/toolchains versions:\n\n* Visual Studio 2017 15.9\n* Visual Studio 2019 16.11\n* Visual Studio 2022 17.3\n* gcc 9.3.1\n* XCode 13.3\n* NDK r23b\n\nGCC 8.x support [broke](https://github.com/podofo/podofo/issues/116) recently, but it could be reinstanced.\n\n## Licensing\n\nPoDoFo library is licensed under the [LGPL 2.0](https://spdx.org/licenses/LGPL-2.0-or-later.html) or later terms.\nPoDoFo tools are licensed under the [GPL 2.0](https://spdx.org/licenses/GPL-2.0-or-later.html) or later terms.\n\n## Development quickstart\n\nPoDoFo is known to compile through a multitude of package managers (including `apt-get`, [brew](https://brew.sh/), [vcpkg](https://vcpkg.io/), [Conan](https://conan.io/)), and has public continuous integration working in [Ubuntu Linux](https://github.com/podofo/podofo/blob/master/.github/workflows/build-linux.yml), [MacOS](https://github.com/podofo/podofo/blob/master/.github/workflows/build-linux.yml) and\n[Windows](https://github.com/podofo/podofo/blob/master/.github/workflows/build-win.yml), bootstrapping the CMake project, building and testing the library. It's highly recommended to build PoDoFo using such package managers. \n\nThere's also a playground area in the repository where you can have\naccess to pre-build dependencies for some popular architectures/operating systems:\nthe playground is the recommended setting to develop the library and reproduce bugs,\nwhile it's not recommended for the deployment of your application using PoDoFo.\nHave a look to the [Readme](https://github.com/podofo/podofo/tree/master/playground) there.\n\n\u003e **Warning**: PoDoFo is known to be working in cross-compilation toolchains (eg. Android/iOS development), but support may not provided in such scenarios. If you decide to manually build dependencies you are assumed to know how to identity possible library clashes/mismatches and how to deal with compilation/linking problems that can arise in your system.\n\n### Build with apt-get\n\nFrom the source root run:\n\n```\nsudo apt-get install -y libfontconfig1-dev libfreetype-dev libxml2-dev libssl-dev libjpeg-dev libpng-dev libtiff-dev\nmkdir build\ncd build\ncmake -DCMAKE_BUILD_TYPE=Debug ..\ncmake --build . --config Debug\n```\n\n### Build with brew\n\nInstall [brew](https://brew.sh/), then from the source root run:\n\n```\nbrew install fontconfig freetype openssl libxml2 jpeg-turbo libpng libtiff cmake\nmkdir build\ncd build\ncmake  -DCMAKE_BUILD_TYPE=Debug -DCMAKE_FIND_FRAMEWORK=NEVER -DCMAKE_PREFIX_PATH=`brew --prefix` -DFontconfig_INCLUDE_DIR=`brew --prefix fontconfig`/include -DOPENSSL_ROOT_DIR=`brew --prefix openssl@3` ..\ncmake --build . --config Debug\n```\n\n### Build with Conan\n\nInstall [conan](https://docs.conan.io/1/installation.html), then from source root run:\n\n```\nmkdir build\ncd build\nconan install ..\ncmake -DCMAKE_BUILD_TYPE=Debug ..\ncmake --build . --config Debug\n```\n\n### Build with vcpkg\n\nFollow the vcpkg [quickstart](https://vcpkg.io/en/getting-started.html) guide to setup the package manager repository first.\nIn Windows, it may be also useful to set the environment variable `VCPKG_DEFAULT_TRIPLET` to `x64-windows` to default installing 64 bit dependencies\nand define a `VCPKG_INSTALLATION_ROOT` variable with the location of the repository as created in the quickstart.\n\nThen from source root run:\n\n```\nvcpkg install fontconfig freetype libxml2 openssl libjpeg-turbo libpng tiff zlib\nmkdir build\ncd build\ncmake -DCMAKE_TOOLCHAIN_FILE=C:\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug ..\ncmake --build . --config Debug\n```\n\n### CMake switches\n\n- `PODOFO_BUILD_TEST`: Build the unit tests, defaults to TRUE;\n\n- `PODOFO_BUILD_EXAMPLES`: Build the examples, defaults to TRUE;\n\n- `PODOFO_BUILD_UNSUPPORTED_TOOLS`: Build the PoDoFo tools, defaults to FALSE. See\nthe relevant [section](https://github.com/podofo/podofo/#podofo-tools) in the Readme;\n\n- `PODOFO_BUILD_LIB_ONLY`: If TRUE, it will build only the library component.\nThis unconditionally disable building tests, examples and tools;\n\n- `PODOFO_BUILD_STATIC`: If TRUE, build the library as a static object and use it in tests,\nexamples and tools. By default a shared library is built.\n\n### Static linking\n\nIf you want to use a static build of PoDoFo and you are including the PoDoFo cmake project it's very simple. Do something like the following in your CMake project:\n\n```\nset(PODOFO_BUILD_LIB_ONLY TRUE CACHE BOOL \"\" FORCE)\nset(PODOFO_BUILD_STATIC TRUE CACHE BOOL \"\" FORCE)\nadd_subdirectory(podofo)\n# ...\ntarget_link_libraries(MyTarget podofo::podofo)\n```\n\nIf you are linking against a precompiled static build of PoDoFo this is a scenario where the support is limited, as you are really supposed to be able to identify and fix linking errors. The general steps are:\n* Add `PODOFO_STATIC` compilation definition to your project, or before including `podofo.h`;\n* Link the libraries `podofo.a`, `podofo_private.a` (or `podofo.lib`, `podofo_private.lib` with MSVC) and all the [dependent](https://github.com/podofo/podofo/blob/5a07b90f24747a5aafe6f6fd062ee81f4783ab22/CMakeLists.txt#L203C5-L203C24) libraries.\n\n## Doxygen Documentation\n\nThe API documentation can be found at https://podofo.github.io/podofo/documentation/ .\n\n### Generate the doxygen documentation\n\n1. **Prerequisite**: Ensure you have Doxygen installed on your machine. If not, visit [Doxygen's official website](http://www.doxygen.nl/) to download and install it.\n\n2. **Generating Documentation**: After completing the build process detailed in the [Development quickstart](#development-quickstart) chapter, navigate to the root directory of PoDoFo's source code.\nOpen a terminal or command prompt and run the following command:\n    ```bash\n    doxygen build/Doxyfile\n    ```\n\n3. **Viewing the Documentation**: Once the documentation generation completes, you'll find a `documentation` directory that contains the generated documentation. Open `index.html` in your favorite web browser to view the API documentation.\n    ```bash\n    cd build/doxygen/documentation\n    open index.html\n    ```\n\n## String encoding and buffer conventions\n\nAll `std::strings` or `std::string_view` in the library are intended\nto hold UTF-8 encoded string content. `PdfString` and `PdfName` constructors\naccept UTF-8 encoded strings by default (`PdfName` accept only characters in the\n`PdfDocEncoding` char set, though). `charbuff` abd `bufferview`\ninstead represent a generic octet buffer.\n\n## API migration\n\nPoDoFo has an unstable API that is the result of an extensive API review of PoDoFo 0.9.x. At this [link](https://github.com/podofo/podofo/wiki/PoDoFo-API-migration-guide/#098---0100) you can find an incomplete guide on migrating 0.9.8 code to 0.10.0. It is expected PoDoFo will converge to a stable API as soon as the review process is completed. See [API Stability](https://github.com/podofo/podofo/wiki/API-Stability) for more details.\n\n## PoDoFo Tools\n\n\u003e **Warning**: Tools are currently **unsupported**, **untested** and **unmaintained**.\n\nPoDoFo tools are still available in the source [tree](https://github.com/podofo/podofo/)\nbut their compilation is disabled by default because they are unsted/unmaintained,\nand will not receive support until their status is cleared. It's not recommended to include them in software distributions.\nIf you want to build them make sure to bootstrap the CMake project with ```-DPODOFO_BUILD_UNSUPPORTED_TOOLS=TRUE```.\nTools are conveniently enabled in the [playground](https://github.com/podofo/podofo/tree/master/playground)\nat least to ensure library changes won't break their compilation.\n\n## TODO\n\nThere's a [TODO](https://github.com/podofo/podofo/blob/master/TODO.md) list, or look\nat the [issue](https://github.com/podofo/podofo/issues) tracker.\n\n## FAQ\n\n**Q: How do I sign a document?**\n\n**A:** PoDoFo HEAD now supplies a high level signing procedure which is very powerful\nand that allows to sign a document without having to supply a *CMS* structure manually.\nBy default, it supports signing a document with the modern [`PAdES-B`](https://en.wikipedia.org/wiki/PAdES)\ncompliance profiles, but there's also a support for the legacy PKCS7 signatures.\nProviding you have both ASN.1 encoded X509 certificate and RSA private key, you\ncan sign a document with the following code:\n\n```cpp\nauto inputOutput = std::make_shared\u003cFileStreamDevice\u003e(filepath, FileMode::Open);\n\nPdfMemDocument doc;\ndoc.Load(inputOutput);\n\nauto\u0026 page = doc.GetPages().GetPageAt(0);\nauto\u0026 signature = page.CreateField\u003cPdfSignature\u003e(\"Signature\", Rect());\n\nauto signer = PdfSignerCms(x509certbuffer, pkeybuffer);\nPoDoFo::SignDocument(doc, *inputOutput, signer, signature);\n```\n\nThere's also a support for external signing services and/or signing the document\nin memory buffers. See the various signing examples in the unit [tests](https://github.com/podofo/podofo/blob/master/test/unit/SignatureTest.cpp).\n\n**Q: Can I still use an event based procedure to sign the document?**\n\nYes, the old low level procedure hasn't changed and it's still available.\nTo describe the procedure briefly, one has to fully Implement a `PdfSigner`,\nretrieve or create a `PdfSignature` field, create an output device (see next question)\nand use `PoDoFo::SignDocument(doc, device, signer, signature)`. When signing,\nthe sequence of calls of `PdfSignature` works in this way: method `PdfSigner::Reset()`\nis called first, then  the `PdfSigner::ComputeSignature(buffer, dryrun)` is called with\nan empty buffer and the `dryrun` argument set to `true`. In this call one can just\nresize the buffer overestimating the required size for the signature, or just\ncompute a fake signature that must be saved on the buffer. Then a sequence of\n`PdfSigner::AppendData(buffer)` are called, receiving all the document data to\nbe signed. A final `PdfSigner::ComputeSignature(buffer, dryrun)` is called, with\nthe `dryrun` parameter set to `false`. The buffer on this call is cleared (capacity\nis not altered) or not accordingly to the value of `PdfSigner::SkipBufferClear()`.\n\n\n**Q: `PdfMemDocument::SaveUpdate()` or `PoDoFo::SignDocument()` write only a\npartial file: why there's no mechanism to seamlessly handle the incremental\nupdate as it was in PoDoFo 0.9.x? What should be done to correctly update/sign\nthe document?**\n\n**A:** The previous mechanism in PoDoFo 0.9.x required enablement of document\nfor incremental updates, which is a decision step which I believe should be\nunnecessary. Also:\n1. In case of file loaded document it still required to perform the update in\nthe same file, and the check was performed on the path of the files being\noperated to, which is unsafe;\n2. In case of buffers worked for one update/signing operation but didn't work\nfor following operations, meaning the mechanism was bugged/unreliable.\n\nAn alternative strategy that makes clearer the fact that the incremental update\nmust be performed on the same file from where the document was loaded, or that underlying\nbuffer will grow its mememory consumption following subsequent operations in case of\nbuffer loaded documents, is available. It follows a couple of examples showing the\ncorrect operations to update a document, loaded from file or buffer:\n\n1. Save an update on a file loaded document, by loading and saving the document on the same location:\n\n```cpp\nauto inputOutput = std::make_shared\u003cFileStreamDevice\u003e(filename, FileMode::Open);\n\nPdfMemDocument doc;\ndoc.Load(inputOutput);\n\ndoc.SaveUpdate(*inputOutput);\n```\n\n2. Save an update on a buffer, by copying the source first to the buffer\nthat will be also used to load the document:\n\n```cpp\ncharbuff outputBuffer;\nFileStreamDevice input(filepath);\nauto inputOutput = std::make_shared\u003cBufferStreamDevice\u003e(outputBuffer);\ninput.CopyTo(*inputOutput);\n\nPdfMemDocument doc;\ndoc.Load(inputOutput);\n\ndoc.SaveUpdate(*inputOutput);\n```\n\nSigning documents can be done with same technique, read the other questions for more examples.\n\n**Q: Can I sign a document a second time?**\n\n**A:** Yes, this is tested, but to make sure this will work you'll to re-parse the document a second time,\nas re-using the already loaded document is still untested (this may change later). For example you can\ndo as it follows:\n\n```cpp\nauto inputOutput = std::make_shared\u003cFileStreamDevice\u003e(filepath, FileMode::Open);\n\n{\n    PdfMemDocument doc;\n    doc.Load(inputOutput);\n    auto\u0026 page = doc.GetPages().GetPageAt(0);\n    auto\u0026 signature = page.CreateField\u003cPdfSignature\u003e(\"Signature1\", Rect());\n\n    PdfSignerCms signer(x509certbuffer, pkeybuffer);\n    PoDoFo::SignDocument(doc, *inputOutput, signer, signature);\n}\n\n{\n    PdfMemDocument doc;\n    doc.Load(inputOutput);\n    auto\u0026 page = doc.GetPages().GetPageAt(0);\n    auto\u0026 signature = page.CreateField\u003cPdfSignature\u003e(\"Signature2\", Rect());\n    PdfSignerCms signer(x509certbuffer, pkeybuffer);\n    PoDoFo::SignDocument(doc, *inputOutput, signer, signature);\n}\n```\n\n## No warranty\n\nPoDoFo may or may not work for your needs and comes with absolutely no\nwarranty. Serious bugs, including security flaws, may be fixed at arbitrary\ntimeframes, or not fixed at all. Priority of implementing new features\nand bug fixing are decided according to the interests and personal\npreferences of the maintainers. If you need PoDoFo to integrate a feature\nor bug fix that is critical to your workflow, the most welcome and fastest\napproach is to [contribute](https://github.com/podofo/podofo/edit/master/README.md#contributions)\nhigh-quality patches.\n\n## Contributions\n\nPlease subscribe to the project mailing [list](https://sourceforge.net/projects/podofo/lists/podofo-users)\nwhich is still followed by several of the original developers of PoDoFo.\nA gitter [community](https://gitter.im/podofo/community) has also been created to ease some more informal chatter.\nIf 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](https://github.com/podofo/podofo/pulls),\nproviding it follows the [coding style](https://github.com/podofo/podofo/blob/master/CODING-STYLE.md)\nof the project. As a minimum requisite, any contribution should be:\n* valuable for a multitude of people and not only self relevant for the contributor;\n* consistent with surrounding code and not result in unpredictable behavior and/or bugs.\n\nOther reasons for the rejection, or hold, of a pull request may be:\n\n* the proposed code is incomplete or hacky;\n* the change doesn't fit the scope of PoDoFo;\n* the change shows lack of knowledge/mastery of the PDF specification and/or C++ language;\n* the change breaks automatic tests performed by the maintainer;\n* general lack of time in reviewing and merging the change.\n\nIf you need to implement a bigger feature or refactor, ask first if\nit was already planned. The feature may be up for grabs, meaning that it's open for external contributions.\nPlease write in the relevant issue that you started to work on that, to receive some feedback/coordination.\nIf it's not, it means that the refactor/feature is planned to be implemented later by the maintainer(s).\nIf the feature is not listed in the issues, add it and/or create a [discussion](https://github.com/podofo/podofo/discussions)\nto receive some feedback and discuss some basic design choices.\n\n## Authors\n\n\u003e **Warning**: Please don't use personal email addresses for technical support inquries, but create\ngithub [issues](https://github.com/podofo/podofo/issues) instead.\n\nPoDoFo is currently developed and maintained by\n[Francesco Pretto](mailto:ceztko@gmail.com), together with Dominik Seichter and others. See the file\n[AUTHORS.md](https://github.com/podofo/podofo/blob/master/AUTHORS.md) for more details.\n\n","funding_links":[],"categories":["C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodofo%2Fpodofo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpodofo%2Fpodofo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodofo%2Fpodofo/lists"}