sw/inc/calbck.hxx | 34 +++++++++++++++++++++++++++++++++- sw/source/core/inc/cellfrm.hxx | 1 + sw/source/core/inc/rowfrm.hxx | 1 + sw/source/core/inc/tabfrm.hxx | 1 + 4 files changed, 36 insertions(+), 1 deletion(-)
New commits: commit 69e0567e118f00f299b6aac645c249521eb0629f Author: Noel Grandin <n...@peralex.com> AuthorDate: Sat Aug 28 12:21:13 2021 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Sat Aug 28 15:13:01 2021 +0200 tdf#135683 speed up layout of large writer tables by making dynamic_cast to some SwTable* types faster Change-Id: I5c5b2525ecfcdf3c0f648f32b4ccc21ba5ac40fc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121193 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/calbck.hxx b/sw/inc/calbck.hxx index 2d873107e069..7f2224671813 100644 --- a/sw/inc/calbck.hxx +++ b/sw/inc/calbck.hxx @@ -36,6 +36,9 @@ class SwModify; class SwFormat; class SfxPoolItem; class SwAttrSet; +class SwCellFrame; +class SwTabFrame; +class SwRowFrame; /* SwModify and SwClient cooperate in propagating attribute changes. @@ -118,6 +121,9 @@ namespace sw virtual void SwClientNotify( const SwModify&, const SfxHint& rHint) =0; public: bool IsLast() const { return !m_pLeft && !m_pRight; } + virtual const SwCellFrame* DynCastCellFrame() const { return nullptr; } + virtual const SwTabFrame* DynCastTabFrame() const { return nullptr; } + virtual const SwRowFrame* DynCastRowFrame() const { return nullptr; } }; enum class IteratorMode { Exact, UnwrapMulti }; } @@ -313,6 +319,32 @@ namespace sw }; } +namespace sw::detail +{ + // Dynamic casting can be expensive when used a lot, so for certain type combinations, + // we have faster routines. + template<typename CastDest> + inline const CastDest * internal_dyn_cast(const sw::WriterListener * pSource) + { + return dynamic_cast<const CastDest *>(pSource); + } + template<> + inline const SwCellFrame* internal_dyn_cast(const sw::WriterListener * pSource) + { + return pSource->DynCastCellFrame(); + } + template<> + inline const SwTabFrame* internal_dyn_cast(const sw::WriterListener * pSource) + { + return pSource->DynCastTabFrame(); + } + template<> + inline const SwRowFrame* internal_dyn_cast(const sw::WriterListener * pSource) + { + return pSource->DynCastRowFrame(); + } +} // namespace sw::detail + template<typename TElementType, typename TSource, sw::IteratorMode eMode = sw::IteratorMode::Exact> class SwIterator final : private sw::ClientIteratorBase @@ -344,7 +376,7 @@ public: pCurrent = pLE->m_pToTell; } } - if (dynamic_cast<const TElementType *>(pCurrent) == nullptr) + if (sw::detail::internal_dyn_cast<TElementType>(pCurrent) == nullptr) { m_pPosition = GetRightOfPos(); pCurrent = m_pPosition; diff --git a/sw/source/core/inc/cellfrm.hxx b/sw/source/core/inc/cellfrm.hxx index 7a3f393880df..2e34b8a2fddf 100644 --- a/sw/source/core/inc/cellfrm.hxx +++ b/sw/source/core/inc/cellfrm.hxx @@ -36,6 +36,7 @@ class SwCellFrame final : public SwLayoutFrame virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override; virtual void SwClientNotify(const SwModify&, const SfxHint&) override; + virtual const SwCellFrame* DynCastCellFrame() const override { return this; } public: SwCellFrame( const SwTableBox &, SwFrame*, bool bInsertContent ); diff --git a/sw/source/core/inc/rowfrm.hxx b/sw/source/core/inc/rowfrm.hxx index 99c12107c64b..ebaae2e1dbc9 100644 --- a/sw/source/core/inc/rowfrm.hxx +++ b/sw/source/core/inc/rowfrm.hxx @@ -52,6 +52,7 @@ class SwRowFrame final : public SwLayoutFrame virtual void MakeAll(vcl::RenderContext* pRenderContext) override; virtual void SwClientNotify(const SwModify&, const SfxHint&) override; + virtual const SwRowFrame* DynCastRowFrame() const override { return this; } public: SwRowFrame(const SwTableLine&, SwFrame*, bool bInsertContent = true); diff --git a/sw/source/core/inc/tabfrm.hxx b/sw/source/core/inc/tabfrm.hxx index 11e61f7c5b31..9df5aac42571 100644 --- a/sw/source/core/inc/tabfrm.hxx +++ b/sw/source/core/inc/tabfrm.hxx @@ -124,6 +124,7 @@ class SwTabFrame final: public SwLayoutFrame, public SwFlowFrame virtual void SwClientNotify(const SwModify&, const SfxHint&) override; // only changes the Framesize, not the PrtArea size virtual SwTwips GrowFrame ( SwTwips, bool bTst = false, bool bInfo = false ) override; + virtual const SwTabFrame* DynCastTabFrame() const override { return this; } public: SwTabFrame( SwTable &, SwFrame* ); // calling RegistFlys always after creation _and_pasting!