vcl/source/filter/ipdf/pdfdocument.cxx | 55 ++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-)
New commits: commit 9b7a890fd59744459692d7f66402c6bdd25acec4 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Jun 19 14:08:44 2020 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Jun 19 15:27:46 2020 +0200 sd signature line: include shape in the appearance widget With this, finally the following works: 1) file -> digital signatures -> sign existing pdf 2) file -> digital signatures -> signature line 3) draw a rectangle 4) popup appears, select signing certificate 5) click on the "finish signing" button on the infobar The resulting pdf will have a signature on it, together with the pdf export of the signature line shape. Change-Id: Icef701aaa6fd4a625acb37094ad34b88283caf42 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96730 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx index 09439604996d..06324f22b4fd 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -28,6 +28,8 @@ #include <vcl/pdfwriter.hxx> #include <o3tl/safeint.hxx> +#include <pdf/objectcopier.hxx> + using namespace com::sun::star; namespace vcl::filter @@ -269,6 +271,10 @@ sal_Int32 PDFDocument::WriteSignatureObject(const OUString& rDescription, bool b sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectangle) { + PDFDocument aPDFDocument; + filter::PDFObjectElement* pPage = nullptr; + std::vector<filter::PDFObjectElement*> aContentStreams; + if (!m_aSignatureLine.empty()) { // Parse the PDF data of signature line: we can set the signature rectangle to non-empty @@ -276,7 +282,6 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang SvMemoryStream aPDFStream; aPDFStream.WriteBytes(m_aSignatureLine.data(), m_aSignatureLine.size()); aPDFStream.Seek(0); - filter::PDFDocument aPDFDocument; if (!aPDFDocument.Read(aPDFStream)) { SAL_WARN("vcl.filter", @@ -291,7 +296,7 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang return -1; } - filter::PDFObjectElement* pPage = aPages[0]; + pPage = aPages[0]; if (!pPage) { SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: no page"); @@ -322,6 +327,17 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang return -1; } rSignatureRectangle.setHeight(pHeight->GetValue()); + + if (PDFObjectElement* pContentStream = pPage->LookupObject("Contents")) + { + aContentStreams.push_back(pContentStream); + } + + if (aContentStreams.empty()) + { + SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: no content stream"); + return -1; + } } m_aSignatureLine.clear(); @@ -334,14 +350,45 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang aEditBuffer.WriteUInt32AsString(nAppearanceId); aEditBuffer.WriteCharPtr(" 0 obj\n"); aEditBuffer.WriteCharPtr("<</Type/XObject\n/Subtype/Form\n"); + + PDFObjectCopier aCopier(*this); + if (!aContentStreams.empty()) + { + OStringBuffer aBuffer; + aCopier.copyPageResources(pPage, aBuffer); + aEditBuffer.WriteOString(aBuffer.makeStringAndClear()); + } + aEditBuffer.WriteCharPtr("/BBox[0 0 "); aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getWidth())); aEditBuffer.WriteCharPtr(" "); aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getHeight())); - aEditBuffer.WriteCharPtr("]\n/Length 0\n>>\n"); - aEditBuffer.WriteCharPtr("stream\n\nendstream\nendobj\n\n"); + aEditBuffer.WriteCharPtr("]\n/Length "); // Add the object to the doc-level edit buffer and update the offset. + SvMemoryStream aStream; + bool bCompressed = false; + sal_Int32 nLength = 0; + if (!aContentStreams.empty()) + { + nLength = PDFObjectCopier::copyPageStreams(aContentStreams, aStream, bCompressed); + } + aEditBuffer.WriteOString(OString::number(nLength)); + if (bCompressed) + { + aEditBuffer.WriteOString(" /Filter/FlateDecode"); + } + + aEditBuffer.WriteCharPtr("\n>>\n"); + + aEditBuffer.WriteCharPtr("stream\n"); + + // Copy the original page streams to the form XObject stream. + aStream.Seek(0); + aEditBuffer.WriteStream(aStream); + + aEditBuffer.WriteCharPtr("\nendstream\nendobj\n\n"); + aEditBuffer.Seek(0); XRefEntry aAppearanceEntry; aAppearanceEntry.SetOffset(m_aEditBuffer.Tell()); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits