include/vcl/pdfextoutdevdata.hxx                |    5 +
 include/vcl/pdfwriter.hxx                       |    8 ++-
 sw/source/core/text/EnhancedPDFExportHelper.cxx |   61 +++++++++++++++++++++++
 vcl/inc/pdf/pdfwriter_impl.hxx                  |    5 +
 vcl/qa/cppunit/pdfexport/data/tdf162359.odt     |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx          |   62 ++++++++++++++++++++++++
 vcl/source/gdi/pdfextoutdevdata.cxx             |   14 +++--
 vcl/source/gdi/pdfwriter.cxx                    |    5 +
 vcl/source/gdi/pdfwriter_impl.cxx               |   58 +++++++++++++++++++++-
 9 files changed, 205 insertions(+), 13 deletions(-)

New commits:
commit 43549566f3785065375cdf345993bd91c14e749d
Author:     Tibor Nagy <tibor.nagy.ext...@allotropia.de>
AuthorDate: Thu Sep 5 00:25:19 2024 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Sep 20 12:32:50 2024 +0200

    tdf#162359 sw: fix the export of comments as PDF annotations
    
    Change-Id: If4a8a1a73c382f496b2c6dd4d52271dc6bc87dda
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172877
    Tested-by: Jenkins
    Reviewed-by: Nagy Tibor <tibor.nagy.ext...@allotropia.de>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173671
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx
index e6bf7e5aed08..6ffd88ddce15 100644
--- a/include/vcl/pdfextoutdevdata.hxx
+++ b/include/vcl/pdfextoutdevdata.hxx
@@ -342,11 +342,14 @@ public:
     @param rNote
     specifies the contents of the note
 
+    @param rPopupRect
+    specifies the rectangle of the popup window for the note
+
     @param nPageNr
     number of page the note is on (as returned by NewPage)
     or -1 in which case the current page is used
     */
-    void CreateNote( const tools::Rectangle& rRect, const vcl::pdf::PDFNote& 
rNote, sal_Int32 nPageNr = -1 );
+    sal_Int32 CreateNote(const tools::Rectangle& rRect, const 
vcl::pdf::PDFNote& rNote, const tools::Rectangle& rPopupRect = 
tools::Rectangle(), sal_Int32 nPageNr = -1);
 
     /** begin a new logical structure element
 
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 044d18dece10..90d1a48754d1 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -148,6 +148,9 @@ public:
         // case the arbitrary id has to be passed again when the
         // actual link annotation is created via SetLinkPropertyID
         LinkAnnotation,
+        // note destination is an artificial attribute that sets
+        // the note annotation ID of a Note element
+        NoteAnnotation,
         // Language currently sets a LanguageType (see i18nlangtag/lang.h)
         // which will be internally changed to a corresponding locale
         Language
@@ -1042,6 +1045,9 @@ The following structure describes the permissions used in 
PDF security
     active rectangle of the note (that is the area that has to be
     hit to popup the annotation)
 
+    @param rPopupRect
+    specifies the rectangle of the popup window for the note
+
     @param rNote
     specifies the contents of the note
 
@@ -1049,7 +1055,7 @@ The following structure describes the permissions used in 
PDF security
     number of page the note is on (as returned by NewPage)
     or -1 in which case the current page is used
     */
-    void CreateNote( const tools::Rectangle& rRect, const vcl::pdf::PDFNote& 
rNote, sal_Int32 nPageNr );
+    sal_Int32 CreateNote( const tools::Rectangle& rRect, const 
tools::Rectangle& rPopupRect, const vcl::pdf::PDFNote& rNote, sal_Int32 nPageNr 
);
 
     /** begin a new logical structure element
 
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx 
b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index cbbc083228a0..c95a84fb9e92 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -87,6 +87,8 @@
 #include <tblafmt.hxx>
 #include <authfld.hxx>
 #include <dcontact.hxx>
+#include <PostItMgr.hxx>
+#include <AnnotationWin.hxx>
 
 #include <tools/globname.hxx>
 #include <svx/svdobj.hxx>
@@ -130,6 +132,7 @@ void lcl_DBGCheckStack()
 typedef std::set< tools::Long, lt_TableColumn > TableColumnsMapEntry;
 typedef std::pair< SwRect, sal_Int32 > IdMapEntry;
 typedef std::vector< IdMapEntry > LinkIdMap;
+typedef std::vector< IdMapEntry > NoteIdMap;
 typedef std::map< const SwTable*, TableColumnsMapEntry > TableColumnsMap;
 typedef std::map< const SwNumberTreeNode*, sal_Int32 > NumListIdMap;
 typedef std::map< const SwNumberTreeNode*, sal_Int32 > NumListBodyIdMap;
@@ -139,6 +142,7 @@ struct SwEnhancedPDFState
 {
     TableColumnsMap m_TableColumnsMap;
     LinkIdMap m_LinkIdMap;
+    NoteIdMap m_NoteIdMap;
     NumListIdMap m_NumListIdMap;
     NumListBodyIdMap m_NumListBodyIdMap;
     FrameTagSet m_FrameTagSet;
@@ -212,6 +216,7 @@ constexpr OUStringLiteral aFigureString = u"Figure";
 constexpr OUStringLiteral aFormulaString = u"Formula";
 constexpr OUString aLinkString = u"Link"_ustr;
 constexpr OUStringLiteral aNoteString = u"Note";
+constexpr OUStringLiteral aAnnotString = u"Annot";
 
 // returns true if first paragraph in cell frame has 'table heading' style
 bool lcl_IsHeadlineCell( const SwCellFrame& rCellFrame )
@@ -946,6 +951,7 @@ void SwTaggedPDFHelper::SetAttributes( 
vcl::PDFWriter::StructElement eType )
         bool bBaselineShift = false;
         bool bTextDecorationType = false;
         bool bLinkAttribute = false;
+        bool bAnnotAttribute = false;
         bool bLanguage = false;
 
         // Check which attributes to set:
@@ -1025,6 +1031,11 @@ void SwTaggedPDFHelper::SetAttributes( 
vcl::PDFWriter::StructElement eType )
                 }
                 break;
 
+            case vcl::PDFWriter::Annot:
+                bAnnotAttribute =
+                bLanguage = true;
+                break;
+
             default:
                 break;
         }
@@ -1081,6 +1092,23 @@ void SwTaggedPDFHelper::SetAttributes( 
vcl::PDFWriter::StructElement eType )
             rInf.CalcRect( *pPor, &aPorRect );
             LinkLinkLink(*mpPDFExtOutDevData, aPorRect);
         }
+
+        if (bAnnotAttribute)
+        {
+            SwRect aPorRect;
+            rInf.CalcRect(*pPor, &aPorRect);
+            const NoteIdMap& 
rNoteIdMap(mpPDFExtOutDevData->GetSwPDFState()->m_NoteIdMap);
+            const Point aCenter = aPorRect.Center();
+            auto aIter = std::find_if(rNoteIdMap.begin(), rNoteIdMap.end(),
+                                      [&aCenter](const IdMapEntry& rEntry)
+                                      { return rEntry.first.Contains(aCenter); 
});
+            if (aIter != rNoteIdMap.end())
+            {
+                sal_Int32 nNoteId = (*aIter).second;
+                
mpPDFExtOutDevData->SetStructureAttributeNumerical(vcl::PDFWriter::NoteAnnotation,
+                                                                   nNoteId);
+            }
+        }
     }
     else if (mpNumInfo && eType == vcl::PDFWriter::List)
     {
@@ -1844,6 +1872,14 @@ void SwTaggedPDFHelper::BeginInlineStructureElements()
 
     switch ( pPor->GetWhichPor() )
     {
+        case PortionType::PostIts:
+            if (!mpPDFExtOutDevData->GetSwPDFState()->m_NoteIdMap.empty())
+            {
+                nPDFType = vcl::PDFWriter::Annot;
+                aPDFType = aAnnotString;
+            }
+            break;
+
         case PortionType::Hyphen :
         case PortionType::SoftHyphen :
         // Check for alternative spelling:
@@ -2200,9 +2236,32 @@ void 
SwEnhancedPDFExportHelper::EnhancedPDFExport(LanguageType const eLanguageDe
                     // Guess what the contents contains...
                     aNote.maContents = pField->GetText();
 
+                    tools::Rectangle aPopupRect(0, 0);
+                    SwPostItMgr* pPostItMgr = 
pDoc->GetEditShell()->GetPostItMgr();
+                    for (auto it = pPostItMgr->begin(); it != 
pPostItMgr->end(); ++it)
+                    {
+                        sw::annotation::SwAnnotationWin* pWin = 
it->get()->mpPostIt;
+                        if (pWin)
+                        {
+                            const SwRect& aAnnotRect = pWin->GetAnchorRect();
+                            if (aAnnotRect.Contains(rNoteRect))
+                            {
+                                Point 
aPt(pDoc->GetEditShell()->GetWin()->PixelToLogic(pWin->GetPosPixel()));
+                                Size 
aSize(pDoc->GetEditShell()->GetWin()->PixelToLogic(pWin->GetSizePixel()));
+                                aPopupRect = tools::Rectangle(aPt, aSize);
+                            }
+                        }
+                    }
+
                     // Link Export
                     tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, 
rNoteRect.SVRect()));
-                    pPDFExtOutDevData->CreateNote(aRect, aNote, aNotePageNum);
+                    sal_Int32 nNoteId = pPDFExtOutDevData->CreateNote(aRect, 
aNote, aPopupRect, aNotePageNum);
+
+                    if (mrPrintData.GetPrintPostIts() != 
SwPostItMode::InMargins)
+                    {
+                        const IdMapEntry aNoteEntry(aRect, nNoteId);
+                        
pPDFExtOutDevData->GetSwPDFState()->m_NoteIdMap.push_back(aNoteEntry);
+                    }
                 }
                 mrSh.SwCursorShell::ClearMark();
             }
diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index 9b2db532e6c0..b92be41c9622 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -463,7 +463,10 @@ struct PDFNoteEntry : public PDFAnnotation
 
     PDFPopupAnnotation m_aPopUpAnnotation;
 
+    sal_Int32 m_nStructParent;
+
     PDFNoteEntry()
+        : m_nStructParent(-1)
     {}
 };
 
@@ -1337,7 +1340,7 @@ public:
     void      setOutlineItemDest( sal_Int32 nItem, sal_Int32 nDestID );
 
     // notes
-    void createNote( const tools::Rectangle& rRect, const PDFNote& rNote, 
sal_Int32 nPageNr );
+    sal_Int32 createNote(const tools::Rectangle& rRect, const 
tools::Rectangle& rPopupRect, const PDFNote& rNote, sal_Int32 nPageNr);
     // structure elements
     sal_Int32 ensureStructureElement();
     void initStructureElement(sal_Int32 id, PDFWriter::StructElement eType, 
std::u16string_view rAlias);
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf162359.odt 
b/vcl/qa/cppunit/pdfexport/data/tdf162359.odt
new file mode 100644
index 000000000000..b92290df9e54
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf162359.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 2e047f27fdff..d114103c1f07 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -66,6 +66,68 @@ void PdfExportTest::load(std::u16string_view rFile, 
vcl::filter::PDFDocument& rD
     CPPUNIT_ASSERT(rDocument.Read(aStream));
 }
 
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testCommentAnnotation)
+{
+    // Enable PDF/UA and Comment as PDF annotations
+    uno::Sequence<beans::PropertyValue> 
aFilterData(comphelper::InitPropertySequence(
+        { { "PDFUACompliance", uno::Any(true) }, { "ExportNotes", 
uno::Any(true) } }));
+    aMediaDescriptor[u"FilterData"_ustr] <<= aFilterData;
+
+    vcl::filter::PDFDocument aDocument;
+    load(u"tdf162359.odt", aDocument);
+
+    // The document has one page.
+    std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+    vcl::filter::PDFObjectElement* pAnnot(nullptr);
+    for (const auto& aElement : aDocument.GetElements())
+    {
+        auto pObject = 
dynamic_cast<vcl::filter::PDFObjectElement*>(aElement.get());
+        if (!pObject)
+            continue;
+        auto pType = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("Type"_ostr));
+        if (pType && pType->GetValue() == "StructElem")
+        {
+            auto pS = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("S"_ostr));
+            if (pS && pS->GetValue() == "Annot")
+            {
+                pAnnot = pObject;
+            }
+        }
+    }
+    CPPUNIT_ASSERT(pAnnot);
+    auto pKids = 
dynamic_cast<vcl::filter::PDFArrayElement*>(pAnnot->Lookup("K"_ostr));
+    CPPUNIT_ASSERT(pKids);
+    auto pObj = 
dynamic_cast<vcl::filter::PDFDictionaryElement*>(pKids->GetElement(0));
+    CPPUNIT_ASSERT(pObj);
+    auto pOType = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObj->LookupElement("Type"_ostr));
+    CPPUNIT_ASSERT_EQUAL("OBJR"_ostr, pOType->GetValue());
+
+    // Parse the export result with pdfium.
+    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
+    std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = 
pPdfDocument->openPage(/*nIndex=*/0);
+    CPPUNIT_ASSERT(pPdfPage);
+
+    // The page has two annotation.
+    CPPUNIT_ASSERT_EQUAL(2, pPdfPage->getAnnotationCount());
+    // Text annotation
+    {
+        auto pAnnotation = pPdfPage->getAnnotation(0);
+        CPPUNIT_ASSERT(pAnnotation);
+        CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Text, 
pAnnotation->getSubType());
+        CPPUNIT_ASSERT(pAnnotation->hasKey("StructParent"_ostr));
+    }
+
+    // Popup annotation
+    {
+        auto pAnnotation = pPdfPage->getAnnotation(1);
+        CPPUNIT_ASSERT(pAnnotation);
+        CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Popup, 
pAnnotation->getSubType());
+        CPPUNIT_ASSERT(!pAnnotation->getRectangle().isEmpty());
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(PdfExportTest, testFigurePlacement)
 {
     aMediaDescriptor[u"FilterName"_ustr] <<= u"impress_pdf_Export"_ustr;
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx 
b/vcl/source/gdi/pdfextoutdevdata.cxx
index c81868c97a59..ab8875990e05 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -94,6 +94,7 @@ struct CreateNote {
     MapMode maParaMapMode;
     vcl::pdf::PDFNote maParaPDFNote;
     tools::Rectangle maParaRect;
+    tools::Rectangle maPopupRect;
     sal_Int32 mnPage;
 };
 
@@ -306,7 +307,9 @@ void GlobalSyncData::PlayGlobalActions( PDFWriter& rWriter )
             const vcl::CreateNote& rCreateNote = std::get<CreateNote>(action);
             rWriter.Push( PushFlags::MAPMODE );
             rWriter.SetMapMode( rCreateNote.maParaMapMode );
-            rWriter.CreateNote( rCreateNote.maParaRect, 
rCreateNote.maParaPDFNote, rCreateNote.mnPage );
+            mParaIds.push_back(rWriter.CreateNote(rCreateNote.maParaRect, 
rCreateNote.maPopupRect, rCreateNote.maParaPDFNote, rCreateNote.mnPage));
+            rWriter.SetLinkPropertyID(mParaIds.back(), 
sal_Int32(mParaIds.size() - 1));
+            rWriter.Pop();
         }
         else if (std::holds_alternative<SetPageTransition>(action)) {
             const vcl::SetPageTransition& rSetPageTransition = 
std::get<SetPageTransition>(action);
@@ -723,10 +726,13 @@ sal_Int32 PDFExtOutDevData::CreateOutlineItem( sal_Int32 
nParent, const OUString
     mpGlobalSyncData->mActions.push_back( vcl::CreateOutlineItem{ rText, 
nParent, nDestID } );
     return mpGlobalSyncData->mCurId++;
 }
-void PDFExtOutDevData::CreateNote( const tools::Rectangle& rRect, const 
vcl::pdf::PDFNote& rNote, sal_Int32 nPageNr )
+sal_Int32 PDFExtOutDevData::CreateNote(const tools::Rectangle& rRect,
+                                       const vcl::pdf::PDFNote& rNote,
+                                       const tools::Rectangle& rPopupRect, 
sal_Int32 nPageNr)
 {
-    mpGlobalSyncData->mActions.push_back(
-        vcl::CreateNote{ mrOutDev.GetMapMode(), rNote, rRect, nPageNr == -1 ? 
mnPage : nPageNr } );
+    mpGlobalSyncData->mActions.push_back(vcl::CreateNote{
+        mrOutDev.GetMapMode(), rNote, rRect, rPopupRect, nPageNr == -1 ? 
mnPage : nPageNr });
+    return mpGlobalSyncData->mCurId++;
 }
 void PDFExtOutDevData::SetPageTransition( PDFWriter::PageTransition eType, 
sal_uInt32 nMilliSec )
 {
diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx
index 3fb8b6015570..999e8a7b708e 100644
--- a/vcl/source/gdi/pdfwriter.cxx
+++ b/vcl/source/gdi/pdfwriter.cxx
@@ -382,9 +382,10 @@ sal_Int32 PDFWriter::CreateOutlineItem( sal_Int32 nParent, 
std::u16string_view r
     return xImplementation->createOutlineItem( nParent, rText, nDestID );
 }
 
-void PDFWriter::CreateNote( const tools::Rectangle& rRect, const PDFNote& 
rNote, sal_Int32 nPageNr )
+sal_Int32 PDFWriter::CreateNote(const tools::Rectangle& rRect, const 
tools::Rectangle& rPopupRect,
+                                const PDFNote& rNote, sal_Int32 nPageNr)
 {
-    xImplementation->createNote( rRect, rNote, nPageNr );
+    return xImplementation->createNote(rRect, rPopupRect, rNote, nPageNr);
 }
 
 sal_Int32 PDFWriter::EnsureStructureElement()
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 8439ec124229..9b8775a15faa 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -1887,7 +1887,8 @@ const char* PDFWriterImpl::getAttributeTag( 
PDFWriter::StructAttribute eAttr )
         { PDFWriter::RubyPosition,      "RubyPosition" },
         { PDFWriter::Type,              "Type" },
         { PDFWriter::Subtype,           "Subtype" },
-        { PDFWriter::LinkAnnotation,    "LinkAnnotation" }
+        { PDFWriter::LinkAnnotation,    "LinkAnnotation" },
+        { PDFWriter::NoteAnnotation,    "NoteAnnotation" }
     });
 
     auto it = aAttributeStrings.find( eAttr );
@@ -2036,6 +2037,28 @@ OString PDFWriterImpl::emitStructureAttributes( 
PDFStructureElement& i_rEle )
                 }
             }
         }
+        else if (attribute.first == PDFWriter::NoteAnnotation)
+        {
+            sal_Int32 nNote = attribute.second.nValue;
+            std::map<sal_Int32, sal_Int32>::const_iterator link_it = 
m_aLinkPropertyMap.find(nNote);
+            if (link_it != m_aLinkPropertyMap.end())
+                nNote = link_it->second;
+            if (nNote >= 0 && o3tl::make_unsigned(nNote) < m_aNotes.size())
+            {
+                AppendAnnotKid(i_rEle, m_aNotes[nNote]);
+            }
+            else
+            {
+                OSL_FAIL("unresolved note id for Note structure");
+                SAL_INFO("vcl.pdfwriter", "unresolved note id " << nNote << " 
for Note structure");
+                if (g_bDebugDisableCompression)
+                {
+                    OString aLine
+                        = "unresolved note id " + OString::number(nNote) + " 
for Note structure";
+                    emitComment(aLine.getStr());
+                }
+            }
+        }
         else
             appendStructureAttributeLine( attribute.first, attribute.second, 
aLayout, true );
     }
@@ -4067,6 +4090,14 @@ void PDFWriterImpl::emitTextAnnotationLine(OStringBuffer 
& aLine, PDFNoteEntry c
         appendUnicodeTextStringEncrypt(rNote.m_aContents.maTitle, 
rNote.m_nObject, aLine);
         aLine.append("
");
     }
+
+    if (-1 != rNote.m_nStructParent)
+    {
+        aLine.append("/StructParent ");
+        aLine.append(rNote.m_nStructParent);
+        aLine.append("
");
+    }
+
     aLine.append(">>
");
     aLine.append("endobj

");
 }
@@ -4075,6 +4106,15 @@ void 
PDFWriterImpl::emitPopupAnnotationLine(OStringBuffer & aLine, PDFPopupAnnot
 {
     appendObjectID(rPopUp.m_nObject, aLine);
     aLine.append("<</Type /Annot /Subtype /Popup ");
+    aLine.append("/Rect[");
+    appendFixedInt(rPopUp.m_aRect.Left(), aLine);
+    aLine.append(' ');
+    appendFixedInt(rPopUp.m_aRect.Top(), aLine);
+    aLine.append(' ');
+    appendFixedInt(rPopUp.m_aRect.Right(), aLine);
+    aLine.append(' ');
+    appendFixedInt(rPopUp.m_aRect.Bottom(), aLine);
+    aLine.append("]");
     aLine.append("/Parent ");
     appendObjectReference(rPopUp.m_nParentObject, aLine);
     aLine.append(">>
");
@@ -10477,28 +10517,36 @@ void PDFWriterImpl::intersectClipRegion( const 
basegfx::B2DPolyPolygon& rRegion
     }
 }
 
-void PDFWriterImpl::createNote( const tools::Rectangle& rRect, const 
pdf::PDFNote& rNote, sal_Int32 nPageNr )
+sal_Int32 PDFWriterImpl::createNote(const tools::Rectangle& rRect,
+                                    const tools::Rectangle& rPopupRect, const 
pdf::PDFNote& rNote,
+                                    sal_Int32 nPageNr)
 {
     if (nPageNr < 0)
         nPageNr = m_nCurrentPage;
 
     if (nPageNr < 0 || o3tl::make_unsigned(nPageNr) >= m_aPages.size())
-        return;
+        return -1;
+
+    sal_Int32 nRet = m_aNotes.size();
 
     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_aPopUpAnnotation.m_aRect = rPopupRect;
     rNoteEntry.m_aContents = rNote;
     rNoteEntry.m_aRect = rRect;
     rNoteEntry.m_nPage = nPageNr;
     // convert to default user space now, since the mapmode may change
     m_aPages[nPageNr].convertRect(rNoteEntry.m_aRect);
+    m_aPages[nPageNr].convertRect(rNoteEntry.m_aPopUpAnnotation.m_aRect);
 
     // 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);
+
+    return nRet;
 }
 
 sal_Int32 PDFWriterImpl::createLink(const tools::Rectangle& rRect, sal_Int32 
nPageNr, OUString const& rAltText)
@@ -11586,6 +11634,10 @@ bool PDFWriterImpl::setStructureAttributeNumerical( 
enum PDFWriter::StructAttrib
                 if( eType == PDFWriter::Link )
                     bInsert = true;
                 break;
+            case PDFWriter::NoteAnnotation:
+                if (eType == PDFWriter::Annot)
+                    bInsert = true;
+                break;
             default: break;
         }
     }

Reply via email to