sw/source/core/layout/trvlfrm.cxx | 51 +++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 28 deletions(-)
New commits: commit 7d924018f3ea58050081936bde067391714a8bb5 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Fri Jul 19 10:44:10 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Jul 19 17:26:30 2024 +0200 don't use GetItemSurrogates in SwFrame::GetVirtPageNum So lets implement this just by walking the document node structure. I have tried to limit how much of the document this method now scans, to avoid it also turning into an O(n^2) problem, but I might have missed something, so (a) the loop might be too conservative, in which case performance could be better. (b) the loop might not go far enough, in which case we might see bugs with virtual page numbers. This shaves 10% off the rendering time of large complex docx documents. Change-Id: I69711c65197caf278bd3ad2931c4817e72b28c5e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170451 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index 9a609321ac17..38d0248e4e9e 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -1868,49 +1868,44 @@ sal_uInt16 SwFrame::GetVirtPageNum() const return 0; sal_uInt16 nPhyPage = pPage->GetPhyPageNum(); - if ( !static_cast<const SwRootFrame*>(pPage->GetUpper())->IsVirtPageNum() ) + const SwRootFrame* pRootFrame = static_cast<const SwRootFrame*>(pPage->GetUpper()); + if ( !pRootFrame->IsVirtPageNum() ) return nPhyPage; //Search the nearest section using the virtual page number. - //Because searching backwards needs a lot of time we search specific using - //the dependencies. From the PageDescs we get the attributes and from the - //attributes we get the sections. - const SwPageFrame *pVirtPage = nullptr; - const SwFrame *pFrame = nullptr; - const SfxItemPool &rPool = pPage->GetFormat()->GetDoc()->GetAttrPool(); - ItemSurrogates aSurrogates; - rPool.GetItemSurrogates(aSurrogates, RES_PAGEDESC); - for (const SfxPoolItem* pItem : aSurrogates) - { - const SwFormatPageDesc *pDesc = dynamic_cast<const SwFormatPageDesc*>(pItem); - if ( !pDesc ) - continue; - - if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() ) - { - auto pMod = pDesc->GetDefinedIn(); - sw::VirtPageNumHint aHint(pPage); - pMod->CallSwClientNotify(aHint); - if(aHint.GetPage()) + const SwFrame *pFoundFrame = nullptr; + const SwPageFrame* pPageFrameIter = pPage; + while (pPageFrameIter) + { + const SwContentFrame* pContentFrame = pPageFrameIter->FindFirstBodyContent(); + if (pContentFrame) + { + const SwFormatPageDesc& rFormatPageDesc = pContentFrame->GetPageDescItem(); + + if ( rFormatPageDesc.GetNumOffset() && rFormatPageDesc.GetDefinedIn() ) { - if(!pVirtPage || aHint.GetPage()->GetPhyPageNum() > pVirtPage->GetPhyPageNum()) + const sw::BroadcastingModify* pMod = rFormatPageDesc.GetDefinedIn(); + sw::VirtPageNumHint aHint(pPage); + pMod->CallSwClientNotify(aHint); + if(aHint.GetPage()) { - pVirtPage = aHint.GetPage(); - pFrame = aHint.GetFrame(); + pFoundFrame = aHint.GetFrame(); + break; } } } + pPageFrameIter = static_cast<const SwPageFrame*>(pPageFrameIter->GetPrev()); } - if ( pFrame ) + if ( pFoundFrame ) { - ::std::optional<sal_uInt16> oNumOffset = pFrame->GetPageDescItem().GetNumOffset(); + ::std::optional<sal_uInt16> oNumOffset = pFoundFrame->GetPageDescItem().GetNumOffset(); if (oNumOffset) { - return nPhyPage - pFrame->GetPhyPageNum() + *oNumOffset; + return nPhyPage - pFoundFrame->GetPhyPageNum() + *oNumOffset; } else { - return nPhyPage - pFrame->GetPhyPageNum(); + return nPhyPage - pFoundFrame->GetPhyPageNum(); } } return nPhyPage;