include/svx/svdobj.hxx | 4 ++++ svx/source/svdraw/svdobj.cxx | 30 ++++++++++++++++++++++++++++++ sw/source/core/doc/textboxhelper.cxx | 9 +-------- 3 files changed, 35 insertions(+), 8 deletions(-)
New commits: commit edbe0f79abb869b671ee551a92834a53fabee616 Author: Noel Grandin <[email protected]> AuthorDate: Sat Jul 13 18:50:34 2024 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Mon Jul 15 08:24:41 2024 +0200 remove RecalcObjOrdNums in DoTextBoxZOrderCorrection (1) We already do this recalculation automatically using a dirty flag. (2) Add a custom method so we don't trigger that recalculation here Speeds up display of a complex DOCX file load by 10% Change-Id: I2a8c975ba0711172bc3e0c20c0e89f08351b6126 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170364 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx index 1907e3e78ea8..431d851fced2 100644 --- a/include/svx/svdobj.hxx +++ b/include/svx/svdobj.hxx @@ -396,6 +396,10 @@ public: /// SdrObjects in the SdrObjList. sal_uInt32 GetOrdNum() const; + /// Ensure this object is sorted immediatedly after rFirst + /// ie. rFirst.GetOrdNum() + 1 == this->GetOrdNum() + void ensureSortedImmediatelyAfter(const SdrObject& rFirst); + // setting the order number should only happen from the model or from the page void SetOrdNum(sal_uInt32 nNum); diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index e650828473f2..eadccae5b3a4 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -918,6 +918,36 @@ void SdrObject::SetOrdNum(sal_uInt32 nNum) m_nOrdNum = nNum; } +/// Try to ensure the desired result __without__ triggering RecalcObjOrdNums +void SdrObject::ensureSortedImmediatelyAfter(const SdrObject& rFirst) +{ + SdrObjList* pParentList = getParentSdrObjListFromSdrObject(); + assert(pParentList == rFirst.getParentSdrObjListFromSdrObject()); + bool bDirty = pParentList->IsObjOrdNumsDirty(); + if (!bDirty) + { + pParentList->SetObjectOrdNum(GetOrdNum(), rFirst.GetOrdNum() + 1); + } + else + { + std::optional<decltype(pParentList->begin())> itFound1, itFound2; + for (auto it = pParentList->begin(), itEnd = pParentList->end(); it != itEnd; ++it) + { + if (*it == this) + itFound1 = it; + else if (*it == &rFirst) + itFound2 = it; + if (itFound1 && itFound2) + { + auto ord1 = std::distance(pParentList->begin(), *itFound1); + auto ord2 = std::distance(pParentList->begin(), *itFound2); + pParentList->SetObjectOrdNum(ord1, ord2 + 1); + break; + } + } + } +} + void SdrObject::GetGrabBagItem(css::uno::Any& rVal) const { if (m_pGrabBagItem != nullptr) diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index d662a6881512..9cf8ca06759f 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -1533,17 +1533,10 @@ bool SwTextBoxHelper::DoTextBoxZOrderCorrection(SwFrameFormat* pShape, const Sdr if (pDrawModel) { // Not really sure this will work on all pages, but it seems it will. - auto pPage = pDrawModel->GetPage(0); - // Recalc all Z-orders - pPage->RecalcObjOrdNums(); // If the shape is behind the frame, is good, but if there are some objects // between of them that is wrong so put the frame exactly one level higher // than the shape. - if (pFrmObj->GetOrdNum() != pShpObj->GetOrdNum() + 1) - { - pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pShpObj->GetOrdNum() + 1); - pPage->RecalcObjOrdNums(); - } + pFrmObj->ensureSortedImmediatelyAfter(*pShpObj); return true; // Success } SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
