summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/pdfwriter_impl.cxx
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2020-06-20 08:43:58 +0200
committerTomaž Vajngerl <quikee@gmail.com>2020-06-22 08:13:31 +0200
commit51d529c18dadb05754590a01ce4c1f06f41cf412 (patch)
tree11f0e024fada00d11bc36399a5f2c3cbdc8b35a0 /vcl/source/gdi/pdfwriter_impl.cxx
parentd91dba41d283db9bc83789ca258b1a6001d761ae (diff)
pdf export: support pop-up annotation for notes / comments
This changes pdf export for annotation, so the comments are exported as "text" annotation with an child "pop-up" annotations. This seems to be more common what PDF readers do (even when text annotation only should be enough). Also changes the test, so that it now works as expected. Change-Id: I95bc12939f490effe7759dad54e136c44e44a2f8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96765 Tested-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl/source/gdi/pdfwriter_impl.cxx')
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx128
1 files changed, 96 insertions, 32 deletions
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 04fcb70a152f..c7e56544f58a 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -3418,50 +3418,111 @@ we check in the following sequence:
return true;
}
+namespace
+{
+
+void appendAnnotationRect(tools::Rectangle const & rRectangle, OStringBuffer & aLine)
+{
+ aLine.append("/Rect[");
+ appendFixedInt(rRectangle.Left(), aLine);
+ aLine.append(' ');
+ appendFixedInt(rRectangle.Top(), aLine);
+ aLine.append(' ');
+ appendFixedInt(rRectangle.Right(), aLine);
+ aLine.append(' ');
+ appendFixedInt(rRectangle.Bottom(), aLine);
+ aLine.append("] ");
+}
+
+void appendObjectID(sal_Int32 nObjectID, OStringBuffer & aLine)
+{
+ aLine.append(nObjectID);
+ aLine.append(" 0 obj\n");
+}
+
+void appendObjectReference(sal_Int32 nObjectID, OStringBuffer & aLine)
+{
+ aLine.append(nObjectID);
+ aLine.append(" 0 R ");
+}
+
+} // end anonymous namespace
+
+void PDFWriterImpl::emitTextAnnotationLine(OStringBuffer & aLine, PDFNoteEntry const & rNote)
+{
+ appendObjectID(rNote.m_nObject, aLine);
+
+ aLine.append("<</Type /Annot /Subtype /Text ");
+
+// i59651: key /F set bits Print to 1 rest to 0. We don't set NoZoom NoRotate to 1, since it's a 'should'
+// see PDF 8.4.2 and ISO 19005-1:2005 6.5.3
+ if (m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3)
+ aLine.append("/F 4 ");
+
+ appendAnnotationRect(rNote.m_aRect, aLine);
+
+ aLine.append("/Popup ");
+ appendObjectReference(rNote.m_aPopUpAnnotation.m_nObject, aLine);
+
+ // contents of the note (type text string)
+ aLine.append("/Contents ");
+ appendUnicodeTextStringEncrypt(rNote.m_aContents.Contents, rNote.m_nObject, aLine);
+ aLine.append("\n");
+
+ // optional title
+ if (!rNote.m_aContents.Title.isEmpty())
+ {
+ aLine.append("/T ");
+ appendUnicodeTextStringEncrypt(rNote.m_aContents.Title, rNote.m_nObject, aLine);
+ aLine.append("\n");
+ }
+ aLine.append(">>\n");
+ aLine.append("endobj\n\n");
+}
+
+void PDFWriterImpl::emitPopupAnnotationLine(OStringBuffer & aLine, PDFPopupAnnotation const & rPopUp)
+{
+ appendObjectID(rPopUp.m_nObject, aLine);
+ aLine.append("<</Type /Annot /Subtype /Popup ");
+ aLine.append("/Parent ");
+ appendObjectReference(rPopUp.m_nParentObject, aLine);
+ aLine.append(">>\n");
+ aLine.append("endobj\n\n");
+}
+
bool PDFWriterImpl::emitNoteAnnotations()
{
// emit note annotations
int nAnnots = m_aNotes.size();
for( int i = 0; i < nAnnots; i++ )
{
- const PDFNoteEntry& rNote = m_aNotes[i];
- if( ! updateObject( rNote.m_nObject ) )
- return false;
+ const PDFNoteEntry& rNote = m_aNotes[i];
+ const PDFPopupAnnotation& rPopUp = rNote.m_aPopUpAnnotation;
- OStringBuffer aLine( 1024 );
- aLine.append( rNote.m_nObject );
- aLine.append( " 0 obj\n" );
-// i59651: key /F set bits Print to 1 rest to 0. We don't set NoZoom NoRotate to 1, since it's a 'should'
-// see PDF 8.4.2 and ISO 19005-1:2005 6.5.3
- aLine.append( "<</Type/Annot" );
- if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3 )
- aLine.append( "/F 4" );
- aLine.append( "/Subtype/Text/Rect[" );
+ {
+ if (!updateObject(rNote.m_nObject))
+ return false;
- appendFixedInt( rNote.m_aRect.Left(), aLine );
- aLine.append( ' ' );
- appendFixedInt( rNote.m_aRect.Top(), aLine );
- aLine.append( ' ' );
- appendFixedInt( rNote.m_aRect.Right(), aLine );
- aLine.append( ' ' );
- appendFixedInt( rNote.m_aRect.Bottom(), aLine );
- aLine.append( "]" );
+ OStringBuffer aLine(1024);
- // contents of the note (type text string)
- aLine.append( "/Contents\n" );
- appendUnicodeTextStringEncrypt( rNote.m_aContents.Contents, rNote.m_nObject, aLine );
- aLine.append( "\n" );
+ emitTextAnnotationLine(aLine, rNote);
- // optional title
- if( !rNote.m_aContents.Title.isEmpty() )
- {
- aLine.append( "/T" );
- appendUnicodeTextStringEncrypt( rNote.m_aContents.Title, rNote.m_nObject, aLine );
- aLine.append( "\n" );
+ if (!writeBuffer(aLine.getStr(), aLine.getLength()))
+ return false;
}
- aLine.append( ">>\nendobj\n\n" );
- CHECK_RETURN( writeBuffer( aLine.getStr(), aLine.getLength() ) );
+ {
+
+ if (!updateObject(rPopUp.m_nObject))
+ return false;
+
+ OStringBuffer aLine(1024);
+
+ emitPopupAnnotationLine(aLine, rPopUp);
+
+ if (!writeBuffer(aLine.getStr(), aLine.getLength()))
+ return false;
+ }
}
return true;
}
@@ -9658,6 +9719,8 @@ void PDFWriterImpl::createNote( const tools::Rectangle& rRect, const PDFNote& rN
m_aNotes.emplace_back();
auto & rNoteEntry = m_aNotes.back();
rNoteEntry.m_nObject = createObject();
+ rNoteEntry.m_aPopUpAnnotation.m_nObject = createObject();
+ rNoteEntry.m_aPopUpAnnotation.m_nParentObject = rNoteEntry.m_nObject;
rNoteEntry.m_aContents = rNote;
rNoteEntry.m_aRect = rRect;
// convert to default user space now, since the mapmode may change
@@ -9665,6 +9728,7 @@ void PDFWriterImpl::createNote( const tools::Rectangle& rRect, const PDFNote& rN
// insert note to page's annotation list
m_aPages[nPageNr].m_aAnnotations.push_back(rNoteEntry.m_nObject);
+ m_aPages[nPageNr].m_aAnnotations.push_back(rNoteEntry.m_aPopUpAnnotation.m_nObject);
}
sal_Int32 PDFWriterImpl::createLink( const tools::Rectangle& rRect, sal_Int32 nPageNr )