sw/inc/unotextrange.hxx            |    3 +
 sw/source/core/unocore/unoobj2.cxx |   58 +++++++++++++++++++++++++++++++++++++
 sw/source/core/unocore/unotext.cxx |    4 ++
 3 files changed, 65 insertions(+)

New commits:
commit 04c1a93f8b718f6cd824696f9ffac10acfd32731
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Sat Jun 15 14:17:04 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Jun 15 15:24:14 2024 +0200

    tdf#144208 speedup doc with lots of redline (12)
    
    Avoid a bunch of allocation/deallocation work in
    SwXText::compareRegionStarts
    
    Change-Id: I18398ab0e281da11ac3539e8e114574a0005dc1b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168905
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Jenkins

diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx
index 1d2265ddfec1..c87510f73b18 100644
--- a/sw/inc/unotextrange.hxx
+++ b/sw/inc/unotextrange.hxx
@@ -102,6 +102,7 @@ private:
     void    DeleteAndInsert(
                 std::u16string_view aText, ::sw::DeleteAndInsertMode eMode);
     void    Invalidate();
+    void    GetStartPaM(std::optional<SwPaM>& roPaM);
 
     virtual ~SwXTextRange() override;
 
@@ -128,6 +129,8 @@ public:
     bool GetPositions(SwPaM & rToFill,
         ::sw::TextRangeMode eMode = ::sw::TextRangeMode::RequireTextNode) 
const;
 
+    sal_Int16 compareRegionStarts(SwXTextRange& rhs);
+
     static rtl::Reference< SwXTextRange > CreateXTextRange(
             SwDoc & rDoc,
             const SwPosition& rPos, const SwPosition *const pMark);
diff --git a/sw/source/core/unocore/unoobj2.cxx 
b/sw/source/core/unocore/unoobj2.cxx
index 8867f49c22dd..500ecf0411d6 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -1116,6 +1116,64 @@ bool SwXTextRange::GetPositions(SwPaM& rToFill, 
::sw::TextRangeMode const eMode)
     return false;
 }
 
+sal_Int16 SwXTextRange::compareRegionStarts(SwXTextRange& rhs)
+{
+    std::optional<SwPaM> oPam1, oPam2;
+    GetStartPaM(oPam1);
+    rhs.GetStartPaM(oPam2);
+
+    sal_Int16 nCompare = 0;
+    SwPosition const*const pStart1 = oPam1->Start();
+    SwPosition const*const pStart2 = oPam2->Start();
+    if (*pStart1 < *pStart2)
+    {
+        nCompare = 1;
+    }
+    else if (*pStart1 > *pStart2)
+    {
+        nCompare = -1;
+    }
+    else
+    {
+        OSL_ENSURE(*pStart1 == *pStart2,
+                "SwPositions should be equal here");
+        nCompare = 0;
+    }
+
+    return nCompare;
+}
+
+void SwXTextRange::GetStartPaM(std::optional<SwPaM>& roPaM)
+{
+    ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
+    if (!m_pImpl->m_xParentText.is())
+    {
+        getText();
+    }
+    if(pBkmk)
+    {
+        roPaM.emplace(pBkmk->GetMarkStart());
+    }
+    else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
+    {
+        // start and end are this, if it's a table
+        roPaM.emplace(GetDoc().GetNodes());
+        GetPositions(*roPaM, sw::TextRangeMode::RequireTextNode);
+    }
+    else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition
+            && m_pImpl->m_pTableOrSectionFormat)
+    {
+        auto const pSectFormat(static_cast<SwSectionFormat 
const*>(m_pImpl->m_pTableOrSectionFormat));
+        roPaM.emplace(*pSectFormat->GetContent().GetContentIdx());
+        roPaM->Move( fnMoveForward, GoInContent );
+        assert(roPaM->GetPoint()->GetNode() < 
*pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode());
+    }
+    else
+    {
+        throw uno::RuntimeException(u"disposed?"_ustr);
+    }
+}
+
 namespace sw {
 
 bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
diff --git a/sw/source/core/unocore/unotext.cxx 
b/sw/source/core/unocore/unotext.cxx
index 21088bc255df..42165b110e68 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1009,6 +1009,10 @@ SwXText::compareRegionStarts(
     {
         throw lang::IllegalArgumentException();
     }
+    SwXTextRange* pSwXTextRange1 = dynamic_cast<SwXTextRange*>(xRange1.get());
+    SwXTextRange* pSwXTextRange2 = dynamic_cast<SwXTextRange*>(xRange2.get());
+    if (pSwXTextRange1 && pSwXTextRange2)
+        return pSwXTextRange1->compareRegionStarts(*pSwXTextRange2);
     const uno::Reference<text::XTextRange> xStart1 = xRange1->getStart();
     const uno::Reference<text::XTextRange> xStart2 = xRange2->getStart();
 

Reply via email to