[Libreoffice-commits] core.git: writerfilter/source

László Németh (via logerrit) logerrit at kemper.freedesktop.org
Thu Feb 18 12:31:49 UTC 2021


 writerfilter/source/dmapper/DomainMapper.cxx          |   24 +
 writerfilter/source/dmapper/DomainMapper_Impl.cxx     |  224 +++++++++---------
 writerfilter/source/dmapper/DomainMapper_Impl.hxx     |   26 +-
 writerfilter/source/dmapper/PropertyMap.cxx           |    2 
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx       |    6 
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |    2 
 6 files changed, 157 insertions(+), 127 deletions(-)

New commits:
commit 7dd8f8aace536a8e60e87e61ee1d90d61fba15eb
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Wed Feb 17 09:47:43 2021 +0100
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Thu Feb 18 13:30:55 2021 +0100

    tdf#120351 DOCX import: fix slow endnote import
    
    by parsing endnotes.xml only once instead
    of parsing again and again for every endnotes.
    This was a serious performance problem for
    documents with hundreds of endnotes, where the
    endnote import took minutes instead of seconds.
    
    Note: switch off CHECK_NOTMERGED in a debug build
    to measure realistic speed-up, e.g. 98 s -> 18 s
    for a document with thousand of endnotes.
    
    Follow-up of commit 9b39ce0e66acfe812e1d50e530dc2ccdef3e1357
    "tdf#76260 DOCX import: fix slow footnote import".
    
    Change-Id: I88cdc5101c25041f985fdc23739a0dadf24a13e0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111030
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 4f58670aefb5..a3b04a014ca8 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3249,7 +3249,9 @@ void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
                         m_pImpl->SetFieldLocked();
                     return;
                 case 0x0c: //page break
-                    m_pImpl->deferBreak(PAGE_BREAK);
+                    // page breaks aren't supported in footnotes and endnotes
+                    if (!m_pImpl->IsInFootOrEndnote())
+                        m_pImpl->deferBreak(PAGE_BREAK);
                     return;
                 case 0x0e: //column break
                     m_pImpl->deferBreak(COLUMN_BREAK);
@@ -3373,12 +3375,24 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
         // preload all footnotes in separated footnotes
         if (sText[0] == 0x5)
         {
-            if (m_pImpl->GetFootnoteCount() > -1)
+            if (m_pImpl->IsInFootnote())
             {
-                m_pImpl->PopFootOrEndnote(/*bIsFootnote=*/true);
-                m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/true);
+                if (m_pImpl->GetFootnoteCount() > -1)
+                {
+                    m_pImpl->PopFootOrEndnote();
+                    m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/true);
+                }
+                m_pImpl->IncrementFootnoteCount();
+            }
+            else
+            {
+                if (m_pImpl->GetEndnoteCount() > -1)
+                {
+                    m_pImpl->PopFootOrEndnote();
+                    m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/false);
+                }
+                m_pImpl->IncrementEndnoteCount();
             }
-            m_pImpl->IncrementFootnoteCount();
         }
 
         // If the footnote contains a Footnote Reference Mark, it can't be a custom footnote
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index ebfe9d625bd2..d0ddb431c4d7 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -304,10 +304,12 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_eInHeaderFooterImport( HeaderFooterImportState::none ),
         m_bDiscardHeaderFooter( false ),
         m_bInFootOrEndnote(false),
+        m_bInFootnote(false),
         m_bHasFootnoteStyle(false),
         m_bCheckFootnoteStyle(false),
         m_eSkipFootnoteState(SkipFootnoteSeparator::OFF),
         m_nFootnotes(-1),
+        m_nEndnotes(-1),
         m_bLineNumberingSet( false ),
         m_bIsInFootnoteProperties( false ),
         m_bIsParaMarkerChange( false ),
@@ -2614,6 +2616,7 @@ void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote )
 {
     SAL_WARN_IF(m_bInFootOrEndnote, "writerfilter.dmapper", "PushFootOrEndnote() is called from another foot or endnote");
     m_bInFootOrEndnote = true;
+    m_bInFootnote = bIsFootnote;
     m_bCheckFirstFootnoteTab = true;
     m_bSaveFirstParagraphInCell = m_bFirstParagraphInCell;
     try
@@ -2703,24 +2706,25 @@ void DomainMapper_Impl::CreateRedline(uno::Reference<text::XTextRange> const& xR
         pRedlineProperties[1].Value <<= ConversionHelper::ConvertDateStringToDateTime( pRedline->m_sDate );
         pRedlineProperties[2].Name = getPropertyName( PROP_REDLINE_REVERT_PROPERTIES );
         pRedlineProperties[2].Value <<= pRedline->m_aRevertProperties;
-        // TODO: add !IsInFootOrEndnote(), if loading of endnotes is optimized
         if (!m_bIsActualParagraphFramed)
         {
             uno::Reference < text::XRedline > xRedline( xRange, uno::UNO_QUERY_THROW );
             xRedline->makeRedline( sType, aRedlineProperties );
         }
         // store frame and (possible floating) table redline data for restoring them after frame conversion
+        enum StoredRedlines eType;
         if (m_bIsActualParagraphFramed || (hasTableManager() && getTableManager().isInTable()))
-        {
-            aFramedRedlines.push_back( uno::makeAny(xRange) );
-            aFramedRedlines.push_back( uno::makeAny(sType) );
-            aFramedRedlines.push_back( uno::makeAny(aRedlineProperties) );
-        }
+            eType = StoredRedlines::FRAME;
         else if (IsInFootOrEndnote())
+            eType = IsInFootnote() ? StoredRedlines::FOOTNOTE : StoredRedlines::ENDNOTE;
+        else
+            eType = StoredRedlines::NONE;
+
+        if (eType != StoredRedlines::NONE)
         {
-            aFootnoteRedlines.push_back( uno::makeAny(xRange) );
-            aFootnoteRedlines.push_back( uno::makeAny(sType) );
-            aFootnoteRedlines.push_back( uno::makeAny(aRedlineProperties) );
+            m_aStoredRedlines[eType].push_back( uno::makeAny(xRange) );
+            m_aStoredRedlines[eType].push_back( uno::makeAny(sType) );
+            m_aStoredRedlines[eType].push_back( uno::makeAny(aRedlineProperties) );
         }
     }
     catch( const uno::Exception & )
@@ -2832,23 +2836,101 @@ void DomainMapper_Impl::PushAnnotation()
     }
 }
 
+static void lcl_CopyRedlines(
+                uno::Reference< text::XText > const& xSrc,
+                std::deque<css::uno::Any>& rRedlines,
+                std::vector<sal_Int32>& redPos,
+                std::vector<sal_Int32>& redLen,
+                sal_Int32& redIdx)
+{
+    redIdx = -1;
+    for( size_t i = 0; i < rRedlines.size(); i+=3)
+    {
+        uno::Reference< text::XTextRange > xRange;
+        rRedlines[i] >>= xRange;
+
+        // is this a redline of the temporary footnote?
+        uno::Reference<text::XTextCursor> xRangeCursor;
+        try
+        {
+            xRangeCursor = xSrc->createTextCursorByRange( xRange );
+        }
+        catch( const uno::Exception& )
+        {
+        }
+        if (xRangeCursor.is())
+        {
+            redIdx = i;
+            sal_Int32 nLen = xRange->getString().getLength();
+            redLen.push_back(nLen);
+            xRangeCursor->gotoRange(xSrc->getStart(), true);
+            redPos.push_back(xRangeCursor->getString().getLength() - nLen);
+        }
+        else
+        {
+            // we have already found all redlines of the footnote,
+            // skip checking the redlines of the other footnotes
+            if (redIdx > -1)
+                break;
+            // failed createTextCursorByRange(), for example, table inside the frame
+            redLen.push_back(-1);
+            redPos.push_back(-1);
+        }
+    }
+}
+
+static void lcl_PasteRedlines(
+                uno::Reference< text::XText > const& xDest,
+                std::deque<css::uno::Any>& rRedlines,
+                std::vector<sal_Int32>& redPos,
+                std::vector<sal_Int32>& redLen,
+                sal_Int32& redIdx)
+{
+    // create redlines in the copied footnote
+    for( size_t i = 0; redIdx > -1 && i <= sal::static_int_cast<size_t>(redIdx); i+=3)
+    {
+        OUString sType;
+        beans::PropertyValues aRedlineProperties( 3 );
+        // skip failed createTextCursorByRange()
+        if (redPos[i/3] == -1)
+            continue;
+        rRedlines[i+1] >>= sType;
+        rRedlines[i+2] >>= aRedlineProperties;
+        uno::Reference< text::XTextCursor > xCrsr = xDest->getText()->createTextCursor();
+        xCrsr->goRight(redPos[i/3], false);
+        xCrsr->goRight(redLen[i/3], true);
+        uno::Reference < text::XRedline > xRedline( xCrsr, uno::UNO_QUERY_THROW );
+        xRedline->makeRedline( sType, aRedlineProperties );
+    }
+}
 
-void DomainMapper_Impl::PopFootOrEndnote( bool bIsFootnote )
+void DomainMapper_Impl::PopFootOrEndnote()
 {
     // content of the footnotes were inserted after the first footnote in temporary footnotes,
     // restore the content of the actual footnote by copying its content from the first
     // (remaining) temporary footnote and remove the temporary footnote.
     // FIXME: add footnote IDs to handle possible differences in footnote serialization
     uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( GetTextDocument(), uno::UNO_QUERY );
-    if ( bIsFootnote && GetFootnoteCount() > -1 && xFootnotesSupplier.is() )
+    uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( GetTextDocument(), uno::UNO_QUERY );
+    if ( IsInFootOrEndnote() && ( ( IsInFootnote() && GetFootnoteCount() > -1 && xFootnotesSupplier.is() ) ||
+         ( !IsInFootnote() && GetEndnoteCount() > -1 && xEndnotesSupplier.is() ) ) )
     {
-        auto xFootnotes = xFootnotesSupplier->getFootnotes();
         uno::Reference< text::XFootnote > xFootnoteFirst, xFootnoteLast;
-        xFootnotes->getByIndex(xFootnotes->getCount()-1) >>= xFootnoteLast;
-        if ( xFootnotes->getCount() > 1 && xFootnoteLast->getLabel().isEmpty() )
+        auto xFootnotes = xFootnotesSupplier->getFootnotes();
+        auto xEndnotes = xEndnotesSupplier->getEndnotes();
+        if (IsInFootnote())
+            xFootnotes->getByIndex(xFootnotes->getCount()-1) >>= xFootnoteLast;
+        else
+            xEndnotes->getByIndex(xEndnotes->getCount()-1) >>= xFootnoteLast;
+        if ( ( ( IsInFootnote() && xFootnotes->getCount() > 1 ) ||
+             ( !IsInFootnote() && xEndnotes->getCount() > 1 ) ) &&
+                        xFootnoteLast->getLabel().isEmpty() )
         {
             // copy content of the first remaining temporary footnote
-            xFootnotes->getByIndex(1) >>= xFootnoteFirst;
+            if ( IsInFootnote() )
+                xFootnotes->getByIndex(1) >>= xFootnoteFirst;
+            else
+                xEndnotes->getByIndex(1) >>= xFootnoteFirst;
             uno::Reference< text::XText > xSrc( xFootnoteFirst, uno::UNO_QUERY_THROW );
             uno::Reference< text::XText > xDest( xFootnoteLast, uno::UNO_QUERY_THROW );
             uno::Reference< text::XTextCopy > xTxt, xTxt2;
@@ -2858,61 +2940,14 @@ void DomainMapper_Impl::PopFootOrEndnote( bool bIsFootnote )
 
             // copy its redlines
             std::vector<sal_Int32> redPos, redLen;
-            sal_Int32 nFirstRedline = -1;
-            for( size_t i = 0; i < aFootnoteRedlines.size(); i+=3)
-            {
-                uno::Reference< text::XTextRange > xRange;
-                aFootnoteRedlines[i] >>= xRange;
-
-                // is this a redline of the temporary footnote?
-                uno::Reference<text::XTextCursor> xRangeCursor;
-                try
-                {
-                    xRangeCursor = xSrc->createTextCursorByRange( xRange );
-                }
-                catch( const uno::Exception& )
-                {
-                }
-                if (xRangeCursor.is())
-                {
-                    nFirstRedline = i;
-                    sal_Int32 nLen = xRange->getString().getLength();
-                    redLen.push_back(nLen);
-                    xRangeCursor->gotoRange(xSrc->getStart(), true);
-                    redPos.push_back(xRangeCursor->getString().getLength() - nLen);
-                }
-                else
-                {
-                    // we have already found all redlines of the footnote,
-                    // skip checking the redlines of the other footnotes
-                    if (nFirstRedline > -1)
-                        break;
-                    // failed createTextCursorByRange(), for example, table inside the frame
-                    redLen.push_back(-1);
-                    redPos.push_back(-1);
-                }
-            }
-
-            // create redlines in the copied footnote
-            for( size_t i = 0; nFirstRedline > -1 && i <= sal::static_int_cast<size_t>(nFirstRedline); i+=3)
-            {
-                OUString sType;
-                beans::PropertyValues aRedlineProperties( 3 );
-                // skip failed createTextCursorByRange()
-                if (redPos[i/3] == -1)
-                    continue;
-                aFootnoteRedlines[i+1] >>= sType;
-                aFootnoteRedlines[i+2] >>= aRedlineProperties;
-                uno::Reference< text::XTextCursor > xCrsr = xDest->getText()->createTextCursor();
-                xCrsr->goRight(redPos[i/3], false);
-                xCrsr->goRight(redLen[i/3], true);
-                uno::Reference < text::XRedline > xRedline( xCrsr, uno::UNO_QUERY_THROW );
-                xRedline->makeRedline( sType, aRedlineProperties );
-            }
+            sal_Int32 redIdx;
+            enum StoredRedlines eType = IsInFootnote() ? StoredRedlines::FOOTNOTE : StoredRedlines::ENDNOTE;
+            lcl_CopyRedlines(xSrc, m_aStoredRedlines[eType], redPos, redLen, redIdx);
+            lcl_PasteRedlines(xDest, m_aStoredRedlines[eType], redPos, redLen, redIdx);
 
             // remove processed redlines
-            for( size_t i = 0; nFirstRedline > -1 && i <= sal::static_int_cast<size_t>(nFirstRedline) + 2; i++)
-                aFootnoteRedlines.pop_front();
+            for( size_t i = 0; redIdx > -1 && i <= sal::static_int_cast<size_t>(redIdx) + 2; i++)
+                m_aStoredRedlines[eType].pop_front();
 
             // remove temporary footnote
             xFootnoteFirst->getAnchor()->setString("");
@@ -7055,49 +7090,16 @@ void DomainMapper_Impl::ExecuteFrameConversion()
         {
             uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( GetTopTextAppend(), uno::UNO_QUERY_THROW );
             // convert redline ranges to cursor movement and character length
-
-            for( size_t i = 0; i < aFramedRedlines.size(); i+=3)
-            {
-                uno::Reference< text::XTextRange > xRange;
-                aFramedRedlines[i] >>= xRange;
-                uno::Reference<text::XTextCursor> xRangeCursor = GetTopTextAppend()->createTextCursorByRange( xRange );
-                if (xRangeCursor.is())
-                {
-                    sal_Int32 nLen = xRange->getString().getLength();
-                    redLen.push_back(nLen);
-                    xRangeCursor->gotoRange(m_xFrameStartRange, true);
-                    redPos.push_back(xRangeCursor->getString().getLength() - nLen);
-                }
-                else
-                {
-                    // failed createTextCursorByRange(), for example, table inside the frame
-                    redLen.push_back(-1);
-                    redPos.push_back(-1);
-                }
-            }
+            sal_Int32 redIdx;
+            lcl_CopyRedlines(GetTopTextAppend(), m_aStoredRedlines[StoredRedlines::FRAME], redPos, redLen, redIdx);
 
             const uno::Reference< text::XTextContent >& xTextContent = xTextAppendAndConvert->convertToTextFrame(
                 m_xFrameStartRange,
                 m_xFrameEndRange,
                 comphelper::containerToSequence(m_aFrameProperties) );
 
-            // create redlines in the previous frame
-            for( size_t i = 0; i < aFramedRedlines.size(); i+=3)
-            {
-                OUString sType;
-                beans::PropertyValues aRedlineProperties( 3 );
-                // skip failed createTextCursorByRange()
-                if (redPos[i/3] == -1)
-                    continue;
-                aFramedRedlines[i+1] >>= sType;
-                aFramedRedlines[i+2] >>= aRedlineProperties;
-                uno::Reference< text::XTextFrame > xFrame( xTextContent, uno::UNO_QUERY_THROW );
-                uno::Reference< text::XTextCursor > xCrsr = xFrame->getText()->createTextCursor();
-                xCrsr->goRight(redPos[i/3], false);
-                xCrsr->goRight(redLen[i/3], true);
-                uno::Reference < text::XRedline > xRedline( xCrsr, uno::UNO_QUERY_THROW );
-                xRedline->makeRedline( sType, aRedlineProperties );
-            }
+            uno::Reference< text::XText > xDest( xTextContent, uno::UNO_QUERY_THROW );
+            lcl_PasteRedlines(xDest, m_aStoredRedlines[StoredRedlines::FRAME], redPos, redLen, redIdx);
         }
         catch( const uno::Exception&)
         {
@@ -7106,19 +7108,19 @@ void DomainMapper_Impl::ExecuteFrameConversion()
 
         m_bIsActualParagraphFramed = false;
 
-        if (redPos.size() == aFramedRedlines.size()/3)
+        if (redPos.size() == m_aStoredRedlines[StoredRedlines::FRAME].size()/3)
         {
-            for( sal_Int32 i = aFramedRedlines.size() - 1; i >= 0; --i)
+            for( sal_Int32 i = m_aStoredRedlines[StoredRedlines::FRAME].size() - 1; i >= 0; --i)
             {
                 // keep redlines of floating tables to process them in CloseSectionGroup()
                 if ( redPos[i/3] != -1 )
                 {
-                    aFramedRedlines.erase(aFramedRedlines.begin() + i);
+                    m_aStoredRedlines[StoredRedlines::FRAME].erase(m_aStoredRedlines[StoredRedlines::FRAME].begin() + i);
                 }
             }
         }
         else
-            aFramedRedlines.clear();
+            m_aStoredRedlines[StoredRedlines::FRAME].clear();
     }
     m_xFrameStartRange = nullptr;
     m_xFrameEndRange = nullptr;
@@ -7229,7 +7231,7 @@ void DomainMapper_Impl::RemoveTopRedline( )
 {
     if (m_aRedlines.top().empty())
     {
-        if (GetFootnoteCount() > -1)
+        if (GetFootnoteCount() > -1 || GetEndnoteCount() > -1)
             return;
         SAL_WARN("writerfilter.dmapper", "RemoveTopRedline called with empty stack");
         throw uno::Exception("RemoveTopRedline failed", nullptr);
@@ -7610,7 +7612,7 @@ void DomainMapper_Impl::substream(Id rName,
     break;
     case NS_ooxml::LN_footnote:
     case NS_ooxml::LN_endnote:
-        PopFootOrEndnote( NS_ooxml::LN_footnote == rName );
+        PopFootOrEndnote();
     break;
     case NS_ooxml::LN_annotation :
         PopAnnotation();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 8441b4012152..58cf59b0852c 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -125,6 +125,15 @@ enum class SkipFootnoteSeparator
     SKIPPING
 };
 
+// type of stored redlines
+enum StoredRedlines
+{
+    FRAME = 0,
+    FOOTNOTE,
+    ENDNOTE,
+    NONE
+};
+
 /**
  * Storage for state that is relevant outside a header/footer, but not inside it.
  *
@@ -520,13 +529,15 @@ private:
     }                               m_eInHeaderFooterImport;
     bool                            m_bDiscardHeaderFooter;
     bool                            m_bInFootOrEndnote;
+    bool                            m_bInFootnote;
     PropertyMapPtr m_pFootnoteContext;
     bool m_bHasFootnoteStyle;
     bool m_bCheckFootnoteStyle;
     /// Skip paragraphs from the <w:separator/> footnote
     SkipFootnoteSeparator           m_eSkipFootnoteState;
-    /// preload footnotes
+    /// preload footnotes and endnotes
     sal_Int32                       m_nFootnotes;
+    sal_Int32                       m_nEndnotes;
 
     bool                            m_bLineNumberingSet;
     bool                            m_bIsInFootnoteProperties;
@@ -708,6 +719,7 @@ public:
     void    PopProperties(ContextType eId);
 
     ContextType GetTopContextType() const { return m_aContextStack.top(); }
+    int GetCContext() const { return m_aContextStack.size(); }
     const PropertyMapPtr& GetTopContext() const
     {
         return m_pTopContext;
@@ -792,8 +804,9 @@ public:
     bool IsInTOC() const { return m_bStartTOC; }
 
     void PushFootOrEndnote( bool bIsFootnote );
-    void PopFootOrEndnote( bool bIsFootnote );
+    void PopFootOrEndnote();
     bool IsInFootOrEndnote() const { return m_bInFootOrEndnote; }
+    bool IsInFootnote() const { return m_bInFootnote; }
 
     void StartCustomFootnote(const PropertyMapPtr pContext);
     void EndCustomFootnote();
@@ -808,6 +821,8 @@ public:
     void SetSkipFootnoteState(SkipFootnoteSeparator eId) { m_eSkipFootnoteState =  eId; }
     sal_Int32 GetFootnoteCount() const { return m_nFootnotes; }
     void IncrementFootnoteCount() { ++m_nFootnotes; }
+    sal_Int32 GetEndnoteCount() const { return m_nEndnotes; }
+    void IncrementEndnoteCount() { ++m_nEndnotes; }
 
     void PushAnnotation();
     void PopAnnotation();
@@ -1091,11 +1106,10 @@ public:
     /// start/end node.
     void ClearPreviousParagraph();
 
-    /// Handle redline text portions in frames:
-    /// store their data, and create them after frame creation
+    /// Handle redline text portions in a frame, footnotes and redlines:
+    /// store their data, and create them after frame creation or footnote/endnote copying
     bool m_bIsActualParagraphFramed;
-    std::vector<css::uno::Any> aFramedRedlines;
-    std::deque<css::uno::Any> aFootnoteRedlines;
+    std::deque<css::uno::Any> m_aStoredRedlines[StoredRedlines::NONE];
 
     bool IsParaWithInlineObject() const { return m_bParaWithInlineObject; }
 
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 6f8f8d5a9b1e..50af6463fcf1 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -1374,7 +1374,7 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl )
         rInfo.m_nBreakType = m_nBreakType;
         if ( FloatingTableConversion( rDM_Impl, rInfo ) )
         {
-            std::vector<css::uno::Any> aFramedRedlines = rDM_Impl.aFramedRedlines;
+            std::deque<css::uno::Any> aFramedRedlines = rDM_Impl.m_aStoredRedlines[StoredRedlines::FRAME];
             try
             {
                 // convert redline ranges to cursor movement and character length
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index 938d977d3348..d8b520cb2e1a 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -293,8 +293,8 @@ void OOXMLDocumentImpl::resolveEndnote(Stream & rStream,
                                        Id aType,
                                        const sal_Int32 nNoteId)
 {
-    writerfilter::Reference<Stream>::Pointer_t pStream =
-        getXNoteStream(OOXMLStream::ENDNOTES, nNoteId);
+    if (!mpXNoteStream)
+        mpXNoteStream = getXNoteStream(OOXMLStream::ENDNOTES, nNoteId);
 
     Id nId;
     switch (aType)
@@ -308,7 +308,7 @@ void OOXMLDocumentImpl::resolveEndnote(Stream & rStream,
         break;
     }
 
-    resolveFastSubStreamWithId(rStream, pStream, nId);
+    resolveFastSubStreamWithId(rStream, mpXNoteStream, nId);
 }
 
 void OOXMLDocumentImpl::resolveComment(Stream & rStream,
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index fe02597775bd..f04391bd95db 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -166,7 +166,7 @@ void SAL_CALL OOXMLFastContextHandler::startFastElement
         mbPreserveSpace = Attribs->getValue(oox::NMSP_xml | oox::XML_space) == "preserve";
         mbPreserveSpaceSet = true;
     }
-    if (Element == W_TOKEN(footnote))
+    if (Element == W_TOKEN(footnote) || Element == W_TOKEN(endnote))
     {
         // send uFtnSep to sign new footnote content, but skip footnote separators
         if (!Attribs->hasAttribute(W_TOKEN(type)) ||


More information about the Libreoffice-commits mailing list