[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - include/vcl vcl/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Mon Jun 29 07:09:14 UTC 2020
include/vcl/filter/pdfdocument.hxx | 10 +++-
vcl/source/filter/ipdf/pdfdocument.cxx | 77 ++++++++++++++++++++++++++++++---
2 files changed, 79 insertions(+), 8 deletions(-)
New commits:
commit 20af2146c786d90b8d9626195a2e7abaa8371750
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Jun 17 16:05:36 2020 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Jun 29 09:08:40 2020 +0200
sd signature line: implement non-empty geometry during pdf sign
Parse the pdf output which contains just the signature line shape on a
page, take the same from it and use it at both places where previously
the position / size was just a stub.
(cherry picked from commit 4db25ccc736185c304f1bd090b8539868932700a)
Conflicts:
include/vcl/filter/pdfdocument.hxx
Change-Id: Ifb2e0ebf7b3514ee027701b9bf360a0c996cdc82
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97246
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
diff --git a/include/vcl/filter/pdfdocument.hxx b/include/vcl/filter/pdfdocument.hxx
index e95fb25a7408..10ce81afa5be 100644
--- a/include/vcl/filter/pdfdocument.hxx
+++ b/include/vcl/filter/pdfdocument.hxx
@@ -47,6 +47,11 @@ template <class interface_type> class Reference;
}
}
+namespace tools
+{
+class Rectangle;
+}
+
namespace vcl
{
namespace filter
@@ -373,10 +378,11 @@ class VCL_DLLPUBLIC PDFDocument
sal_Int32 WriteSignatureObject(const OUString& rDescription, bool bAdES,
sal_uInt64& rLastByteRangeOffset, sal_Int64& rContentOffset);
/// Write the appearance object as part of signing.
- sal_Int32 WriteAppearanceObject();
+ sal_Int32 WriteAppearanceObject(tools::Rectangle& rSignatureRectangle);
/// Write the annot object as part of signing.
sal_Int32 WriteAnnotObject(PDFObjectElement const& rFirstPage, sal_Int32 nSignatureId,
- sal_Int32 nAppearanceId);
+ sal_Int32 nAppearanceId,
+ const tools::Rectangle& rSignatureRectangle);
/// Write the updated Page object as part of signing.
bool WritePageObject(PDFObjectElement& rFirstPage, sal_Int32 nAnnotId);
/// Write the updated Catalog object as part of signing.
diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx
index 0a02fe34bc48..2d98250bf3ae 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -232,8 +232,62 @@ sal_Int32 PDFDocument::WriteSignatureObject(const OUString& rDescription, bool b
return nSignatureId;
}
-sal_Int32 PDFDocument::WriteAppearanceObject()
+sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectangle)
{
+ if (!m_aSignatureLine.empty())
+ {
+ // Parse the PDF data of signature line: we can set the signature rectangle to non-empty
+ // based on it.
+ SvMemoryStream aPDFStream;
+ aPDFStream.WriteBytes(m_aSignatureLine.data(), m_aSignatureLine.size());
+ aPDFStream.Seek(0);
+ filter::PDFDocument aPDFDocument;
+ if (!aPDFDocument.Read(aPDFStream))
+ {
+ SAL_WARN("vcl.filter",
+ "PDFDocument::WriteAppearanceObject: failed to read the PDF document");
+ return -1;
+ }
+
+ std::vector<filter::PDFObjectElement*> aPages = aPDFDocument.GetPages();
+ if (aPages.empty())
+ {
+ SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: no pages");
+ return -1;
+ }
+
+ filter::PDFObjectElement* pPage = aPages[0];
+ if (!pPage)
+ {
+ SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: no page");
+ return -1;
+ }
+
+ // Calculate the bounding box.
+ PDFElement* pMediaBox = pPage->Lookup("MediaBox");
+ auto pMediaBoxArray = dynamic_cast<PDFArrayElement*>(pMediaBox);
+ if (!pMediaBoxArray || pMediaBoxArray->GetElements().size() < 4)
+ {
+ SAL_WARN("vcl.filter",
+ "PDFDocument::WriteAppearanceObject: MediaBox is not an array of 4");
+ return -1;
+ }
+ const std::vector<PDFElement*>& rMediaBoxElements = pMediaBoxArray->GetElements();
+ auto pWidth = dynamic_cast<PDFNumberElement*>(rMediaBoxElements[2]);
+ if (!pWidth)
+ {
+ SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: MediaBox has no width");
+ return -1;
+ }
+ rSignatureRectangle.setWidth(pWidth->GetValue());
+ auto pHeight = dynamic_cast<PDFNumberElement*>(rMediaBoxElements[3]);
+ if (!pHeight)
+ {
+ SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: MediaBox has no height");
+ return -1;
+ }
+ rSignatureRectangle.setHeight(pHeight->GetValue());
+ }
m_aSignatureLine.clear();
// Write appearance object.
@@ -245,14 +299,19 @@ sal_Int32 PDFDocument::WriteAppearanceObject()
m_aEditBuffer.WriteUInt32AsString(nAppearanceId);
m_aEditBuffer.WriteCharPtr(" 0 obj\n");
m_aEditBuffer.WriteCharPtr("<</Type/XObject\n/Subtype/Form\n");
- m_aEditBuffer.WriteCharPtr("/BBox[0 0 0 0]\n/Length 0\n>>\n");
+ m_aEditBuffer.WriteCharPtr("/BBox[0 0 ");
+ m_aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getWidth()));
+ m_aEditBuffer.WriteCharPtr(" ");
+ m_aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getHeight()));
+ m_aEditBuffer.WriteCharPtr("]\n/Length 0\n>>\n");
m_aEditBuffer.WriteCharPtr("stream\n\nendstream\nendobj\n\n");
return nAppearanceId;
}
sal_Int32 PDFDocument::WriteAnnotObject(PDFObjectElement const& rFirstPage, sal_Int32 nSignatureId,
- sal_Int32 nAppearanceId)
+ sal_Int32 nAppearanceId,
+ const tools::Rectangle& rSignatureRectangle)
{
// Decide what identifier to use for the new signature.
sal_uInt32 nNextSignature = GetNextSignature();
@@ -266,7 +325,11 @@ sal_Int32 PDFDocument::WriteAnnotObject(PDFObjectElement const& rFirstPage, sal_
m_aEditBuffer.WriteUInt32AsString(nAnnotId);
m_aEditBuffer.WriteCharPtr(" 0 obj\n");
m_aEditBuffer.WriteCharPtr("<</Type/Annot/Subtype/Widget/F 132\n");
- m_aEditBuffer.WriteCharPtr("/Rect[0 0 0 0]\n");
+ m_aEditBuffer.WriteCharPtr("/Rect[0 0 ");
+ m_aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getWidth()));
+ m_aEditBuffer.WriteCharPtr(" ");
+ m_aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getHeight()));
+ m_aEditBuffer.WriteCharPtr("]\n");
m_aEditBuffer.WriteCharPtr("/FT/Sig\n");
m_aEditBuffer.WriteCharPtr("/P ");
m_aEditBuffer.WriteUInt32AsString(rFirstPage.GetObjectValue());
@@ -803,7 +866,8 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
sal_Int32 nSignatureId = WriteSignatureObject(
rDescription, bAdES, nSignatureLastByteRangeOffset, nSignatureContentOffset);
- sal_Int32 nAppearanceId = WriteAppearanceObject();
+ tools::Rectangle aSignatureRectangle;
+ sal_Int32 nAppearanceId = WriteAppearanceObject(aSignatureRectangle);
std::vector<PDFObjectElement*> aPages = GetPages();
if (aPages.empty() || !aPages[0])
@@ -813,7 +877,8 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
}
PDFObjectElement& rFirstPage = *aPages[0];
- sal_Int32 nAnnotId = WriteAnnotObject(rFirstPage, nSignatureId, nAppearanceId);
+ sal_Int32 nAnnotId
+ = WriteAnnotObject(rFirstPage, nSignatureId, nAppearanceId, aSignatureRectangle);
if (!WritePageObject(rFirstPage, nAnnotId))
{
More information about the Libreoffice-commits
mailing list