summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-06-19 14:08:44 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-06-19 15:27:46 +0200
commit9b7a890fd59744459692d7f66402c6bdd25acec4 (patch)
tree615ad3ed0c67b5f3d02d4bf6ac43f5e333b7917a
parent7cd5cddce02a6e005c0fcd45b9b720c2ca877cfc (diff)
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 <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--vcl/source/filter/ipdf/pdfdocument.cxx55
1 files changed, 51 insertions, 4 deletions
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());