include/svx/svdmodel.hxx | 8 +++--- sd/source/filter/pdf/sdpdffilter.cxx | 4 ++- svx/source/svdraw/svdmodel.cxx | 46 ++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 27 deletions(-)
New commits: commit e4251f16e8659b02d36a9b44215970e77a67ead5 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Fri Sep 6 12:55:26 2024 +0200 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Fri Sep 13 11:20:41 2024 +0200 reduce time spent in RecalcPageNums when importing PDF when we have lots of pages, we trigger a O(n^2) loop. Do two things to reduce this (a) be smarter about recalculating page numbers, so we only recalculate the set of page numbers that need recalculating (b) duplicate the last page repeatedly, instead of the first page, so we don't recalculate all the page numbers for each page we duplicate Change-Id: I40aca812b47a9551039c5855b1c8d26f5f171f41 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172950 Reviewed-by: Michael Meeks <michael.me...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx index 68565e264bc3..f037baf6fcc4 100644 --- a/include/svx/svdmodel.hxx +++ b/include/svx/svdmodel.hxx @@ -199,12 +199,12 @@ protected: std::deque<std::unique_ptr<SfxUndoAction>> m_aRedoStack; std::unique_ptr<SdrUndoGroup> m_pCurrentUndoGroup; // For multi-level sal_uInt16 m_nUndoLevel; // undo nesting + sal_uInt16 m_nPageNumsDirtyFrom = SAL_MAX_UINT16; + sal_uInt16 m_nMasterPageNumsDirtyFrom = SAL_MAX_UINT16; bool m_bIsWriter:1; // to clean up pMyPool from 303a bool m_bThemedControls:1; // If false UnoControls should not use theme colors bool mbUndoEnabled:1; // If false no undo is recorded or we are during the execution of an undo action bool mbChanged:1; - bool m_bPagNumsDirty:1; - bool m_bMPgNumsDirty:1; bool m_bTransportContainer:1; // doc is temporary object container, no display (e.g. clipboard) bool m_bReadOnly:1; bool m_bTransparentTextFrames:1; @@ -397,8 +397,8 @@ public: static OUString GetPercentString(const Fraction& rVal); // RecalcPageNums is ordinarily only called by the Page. - bool IsPagNumsDirty() const { return m_bPagNumsDirty; }; - bool IsMPgNumsDirty() const { return m_bMPgNumsDirty; }; + bool IsPagNumsDirty() const { return m_nPageNumsDirtyFrom != SAL_MAX_UINT16; } + bool IsMPgNumsDirty() const { return m_nMasterPageNumsDirtyFrom != SAL_MAX_UINT16; } void RecalcPageNums(bool bMaster); // After the Insert the Page belongs to the SdrModel. virtual void InsertPage(SdrPage* pPage, sal_uInt16 nPos=0xFFFF); diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index 22229e6597ce..068aca1fcce9 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -65,9 +65,11 @@ bool SdPdfFilter::Import() // Add as many pages as we need up-front. mrDocument.CreateFirstPages(); + sal_uInt16 nPageToDuplicate = 0; for (size_t i = 0; i < aGraphics.size() - 1; ++i) { - mrDocument.DuplicatePage(0); + // duplicating the last page is cheaper than repeatedly duplicating the first one + nPageToDuplicate = mrDocument.DuplicatePage(nPageToDuplicate); } for (vcl::PDFGraphicResult const& rPDFGraphicResult : aGraphics) diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx index 46497f398944..8101e7ac0b96 100644 --- a/svx/source/svdraw/svdmodel.cxx +++ b/svx/source/svdraw/svdmodel.cxx @@ -133,8 +133,6 @@ SdrModel::SdrModel(SfxItemPool* pPool, comphelper::IEmbeddedHelper* pEmbeddedHel , m_bThemedControls(true) , mbUndoEnabled(true) , mbChanged(false) - , m_bPagNumsDirty(false) - , m_bMPgNumsDirty(false) , m_bTransportContainer(false) , m_bReadOnly(false) , m_bTransparentTextFrames(false) @@ -1176,23 +1174,27 @@ void SdrModel::RecalcPageNums(bool bMaster) { if(bMaster) { - sal_uInt16 nCount=sal_uInt16(maMasterPages.size()); - sal_uInt16 i; - for (i=0; i<nCount; i++) { - SdrPage* pPg = maMasterPages[i].get(); - pPg->SetPageNum(i); + if (m_nMasterPageNumsDirtyFrom != SAL_MAX_UINT16) + { + sal_uInt16 nCount=sal_uInt16(maMasterPages.size()); + for (sal_uInt16 i=m_nMasterPageNumsDirtyFrom; i<nCount; i++) { + SdrPage* pPg = maMasterPages[i].get(); + pPg->SetPageNum(i); + } + m_nMasterPageNumsDirtyFrom = SAL_MAX_UINT16; } - m_bMPgNumsDirty=false; } else { - sal_uInt16 nCount=sal_uInt16(maPages.size()); - sal_uInt16 i; - for (i=0; i<nCount; i++) { - SdrPage* pPg = maPages[i].get(); - pPg->SetPageNum(i); + if (m_nPageNumsDirtyFrom != SAL_MAX_UINT16) + { + sal_uInt16 nCount=sal_uInt16(maPages.size()); + for (sal_uInt16 i = m_nPageNumsDirtyFrom; i<nCount; i++) { + SdrPage* pPg = maPages[i].get(); + pPg->SetPageNum(i); + } + m_nPageNumsDirtyFrom = SAL_MAX_UINT16; } - m_bPagNumsDirty=false; } } @@ -1210,7 +1212,7 @@ void SdrModel::InsertPage(SdrPage* pPage, sal_uInt16 nPos) if (mbMakePageObjectsNamesUnique) pPage->MakePageObjectsNamesUnique(); - if (nPos<nCount) m_bPagNumsDirty=true; + if (nPos<nCount) m_nPageNumsDirtyFrom = std::min(m_nPageNumsDirtyFrom, static_cast<sal_uInt16>(nPos + 1)); SetChanged(); SdrHint aHint(SdrHintKind::PageOrderChange, pPage); Broadcast(aHint); @@ -1229,7 +1231,7 @@ rtl::Reference<SdrPage> SdrModel::RemovePage(sal_uInt16 nPgNum) if (pPg) { pPg->SetInserted(false); } - m_bPagNumsDirty=true; + m_nPageNumsDirtyFrom = std::min(m_nPageNumsDirtyFrom, nPgNum); SetChanged(); SdrHint aHint(SdrHintKind::PageOrderChange, pPg.get()); Broadcast(aHint); @@ -1259,7 +1261,7 @@ void SdrModel::InsertMasterPage(SdrPage* pPage, sal_uInt16 nPos) pPage->SetPageNum(nPos); if (nPos<nCount) { - m_bMPgNumsDirty=true; + m_nMasterPageNumsDirtyFrom = std::min(m_nMasterPageNumsDirtyFrom, static_cast<sal_uInt16>(nPos + 1)); } SetChanged(); @@ -1291,7 +1293,7 @@ rtl::Reference<SdrPage> SdrModel::RemoveMasterPage(sal_uInt16 nPgNum) pRetPg->SetInserted(false); } - m_bMPgNumsDirty=true; + m_nMasterPageNumsDirtyFrom = std::min(m_nMasterPageNumsDirtyFrom, nPgNum); SetChanged(); SdrHint aHint(SdrHintKind::PageOrderChange, pRetPg.get()); Broadcast(aHint); @@ -1308,7 +1310,7 @@ void SdrModel::MoveMasterPage(sal_uInt16 nPgNum, sal_uInt16 nNewPos) maMasterPages.insert(maMasterPages.begin()+nNewPos,pPg); MasterPageListChanged(); } - m_bMPgNumsDirty=true; + m_nMasterPageNumsDirtyFrom = std::min(m_nMasterPageNumsDirtyFrom, std::min(nPgNum, nNewPos)); SetChanged(); SdrHint aHint(SdrHintKind::PageOrderChange, pPg.get()); Broadcast(aHint); @@ -1484,7 +1486,7 @@ void SdrModel::Merge(SdrModel& rSourceModel, maMasterPages.insert(maMasterPages.begin()+nDstMasterPageCnt, pPg); MasterPageListChanged(); pPg->SetInserted(); - m_bMPgNumsDirty=true; + m_nMasterPageNumsDirtyFrom = std::min(m_nMasterPageNumsDirtyFrom, nDstMasterPageCnt); if (bUndo) AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg)); } else { OSL_FAIL("SdrModel::Merge(): MasterPage not found in SourceModel."); @@ -1567,8 +1569,8 @@ void SdrModel::Merge(SdrModel& rSourceModel, pMasterMap.reset(); pMasterNeed.reset(); - m_bMPgNumsDirty=true; - m_bPagNumsDirty=true; + m_nMasterPageNumsDirtyFrom = 0; + m_nPageNumsDirtyFrom = 0; SetChanged(); // TODO: Missing: merging and mapping of layers