sw/inc/fmtcol.hxx | 32 ++++++------------------ sw/inc/shellio.hxx | 1 sw/source/core/doc/fmtcol.cxx | 31 ++++++++++++++++++++++- sw/source/core/inc/swfntcch.hxx | 47 ++++-------------------------------- sw/source/core/layout/ftnfrm.cxx | 4 +-- sw/source/core/layout/pagechg.cxx | 4 +-- sw/source/core/text/atrhndl.hxx | 2 - sw/source/core/text/atrstck.cxx | 2 - sw/source/core/text/frmcrsr.cxx | 4 +-- sw/source/core/text/frmpaint.cxx | 4 +-- sw/source/core/text/porrst.cxx | 4 +-- sw/source/core/text/redlnitr.cxx | 8 +++--- sw/source/core/text/txtinit.cxx | 2 - sw/source/core/txtnode/swfntcch.cxx | 35 ++------------------------ sw/source/filter/html/swhtml.cxx | 13 --------- sw/source/filter/ww8/ww8par.cxx | 13 --------- 16 files changed, 63 insertions(+), 143 deletions(-)
New commits: commit ba462fddf5acb4db510aecb014614ff89aa433f0 Author: Noel Grandin <[email protected]> AuthorDate: Thu Oct 9 16:27:12 2025 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Thu Feb 12 12:09:56 2026 +0100 remove SwFontObj cache makes approx no difference to memory consumption when loading a 100+ page document, and shaves 5% off the load time. Change-Id: I72a19338ea52e806cc763e5cd9d2bb1c2dfd7033 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192107 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> diff --git a/sw/inc/fmtcol.hxx b/sw/inc/fmtcol.hxx index 4a9e5ea739fa..4e09f0aefb8b 100644 --- a/sw/inc/fmtcol.hxx +++ b/sw/inc/fmtcol.hxx @@ -31,6 +31,8 @@ #include <memory> class SwAttrPool; +class SwViewShell; +class SwFontObj; namespace sw{ class DocumentStylePoolManager; } /// SwFormatColl is just an SwFormat subclass that defaults to m_bAutoFormat=false, expressing that @@ -63,23 +65,17 @@ class SW_DLLPUBLIC SwTextFormatColl bool mbAssignedToOutlineStyle; - bool m_bInSwFntCache; - SwTextFormatColl *mpNextTextFormatColl; SwCharFormat* mpLinkedCharFormat = nullptr; + /** cached/temporary font layout information */ + mutable std::unique_ptr<SwFontObj> mxFontObj; + protected: SwTextFormatColl( SwAttrPool& rPool, const UIName &rFormatCollName, SwTextFormatColl* pDerFrom = nullptr, - sal_uInt16 nFormatWh = RES_TXTFMTCOLL ) - : SwFormatColl(rPool, rFormatCollName, aTextFormatCollSetRange, pDerFrom, nFormatWh) - , mbStayAssignedToListLevelOfOutlineStyle(false) - , mbAssignedToOutlineStyle(false) - , m_bInSwFntCache(false) - { - mpNextTextFormatColl = this; - } + sal_uInt16 nFormatWh = RES_TXTFMTCOLL ); /// To get UL- / LR- / FontHeight-changes. virtual void SwClientNotify(const SwModify&, const SfxHint&) override; @@ -136,19 +132,9 @@ public: if(HasWriterListeners() && !IsModifyLocked()) CallSwClientNotify(sw::LegacyModifyHint(&rDrop, &rDrop)); }; - bool IsInSwFntCache() const { return m_bInSwFntCache; }; - void SetInSwFntCache() { m_bInSwFntCache = true; }; - virtual void InvalidateInSwFntCache(sal_uInt16 nWhich) override - { - if(isCHRATR(nWhich)) - { - m_bInSwFntCache = false; - } - }; - virtual void InvalidateInSwFntCache() override - { - m_bInSwFntCache = false; - } + virtual void InvalidateInSwFntCache(sal_uInt16 nWhich) override; + virtual void InvalidateInSwFntCache() override; + const SwFontObj & GetFontObj(SwViewShell *pSh) const; }; class SwGrfFormatColl final : public SwFormatColl diff --git a/sw/inc/shellio.hxx b/sw/inc/shellio.hxx index f7c7cb3b292b..064a0d0f5741 100644 --- a/sw/inc/shellio.hxx +++ b/sw/inc/shellio.hxx @@ -206,7 +206,6 @@ extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportDOCX(SvStream &rStream); extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportRTF(SvStream &rStream); extern "C" SAL_DLLPUBLIC_EXPORT bool TestPDFExportRTF(SvStream &rStream); extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportHTML(SvStream &rStream); -SAL_DLLPUBLIC_EXPORT void FlushFontCache(); class SW_DLLPUBLIC Reader { diff --git a/sw/source/core/doc/fmtcol.cxx b/sw/source/core/doc/fmtcol.cxx index 32d76a11cae3..7463f6e3dc34 100644 --- a/sw/source/core/doc/fmtcol.cxx +++ b/sw/source/core/doc/fmtcol.cxx @@ -108,10 +108,19 @@ namespace TextFormatCollFunc } } // end of namespace TextFormatCollFunc +SwTextFormatColl::SwTextFormatColl( SwAttrPool& rPool, const UIName &rFormatCollName, + SwTextFormatColl* pDerFrom, + sal_uInt16 nFormatWh ) +: SwFormatColl(rPool, rFormatCollName, aTextFormatCollSetRange, pDerFrom, nFormatWh) +, mbStayAssignedToListLevelOfOutlineStyle(false) +, mbAssignedToOutlineStyle(false) +{ + mpNextTextFormatColl = this; +} + SwTextFormatColl::~SwTextFormatColl() { - if(m_bInSwFntCache) - pSwFontCache->Delete( this ); + mxFontObj.reset(); if (GetDoc().IsInDtor()) { @@ -723,4 +732,22 @@ void SwTextFormatColl::DeleteAssignmentToListLevelOfOutlineStyle() ResetFormatAttr(RES_PARATR_OUTLINELEVEL); } +void SwTextFormatColl::InvalidateInSwFntCache(sal_uInt16 nWhich) +{ + if(isCHRATR(nWhich)) + mxFontObj.reset(); +}; + +void SwTextFormatColl::InvalidateInSwFntCache() +{ + mxFontObj.reset(); +} + +const SwFontObj & SwTextFormatColl::GetFontObj(SwViewShell *pSh) const +{ + if (!mxFontObj) + mxFontObj = std::make_unique<SwFontObj>(this, pSh); + return *mxFontObj; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/inc/swfntcch.hxx b/sw/source/core/inc/swfntcch.hxx index 844e9f3590a2..43c4c0e43e80 100644 --- a/sw/source/core/inc/swfntcch.hxx +++ b/sw/source/core/inc/swfntcch.hxx @@ -16,62 +16,27 @@ * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_SW_SOURCE_CORE_INC_SWFNTCCH_HXX -#define INCLUDED_SW_SOURCE_CORE_INC_SWFNTCCH_HXX +#pragma once #define NUM_DEFAULT_VALUES 40 -#include "swcache.hxx" #include "swfont.hxx" class SwViewShell; class SfxPoolItem; class SwTextFormatColl; -class SwFontCache : public SwCache +class SwFontObj { public: + SwFontObj( const SwTextFormatColl *pOwner, SwViewShell *pSh ); + ~SwFontObj(); - SwFontCache() : SwCache(50 -#ifdef DBG_UTIL - , "Global AttributeSet/Font-Cache pSwFontCache"_ostr -#endif - ) {} - -}; - -// AttributeSet/Font-Cache, globale Variable, in FontCache.Cxx angelegt -extern SwFontCache *pSwFontCache; - -class SwFontObj final : public SwCacheObj -{ - friend class SwFontAccess; - + const SwFont& GetFont() const { return m_aSwFont; } + const SfxPoolItem* const* GetDefault() const { return m_pDefaultArray; } private: SwFont m_aSwFont; const SfxPoolItem* m_pDefaultArray[ NUM_DEFAULT_VALUES ]; - -public: - SwFontObj( const SwTextFormatColl* pOwner, SwViewShell *pSh ); - - virtual ~SwFontObj() override; - - SwFont& GetFont() { return m_aSwFont; } - const SwFont& GetFont() const { return m_aSwFont; } - const SfxPoolItem** GetDefault() { return m_pDefaultArray; } -}; - -class SwFontAccess final : public SwCacheAccess -{ - SwViewShell *m_pShell; - - virtual SwCacheObj *NewObj( ) override; - -public: - SwFontAccess( const SwTextFormatColl *pOwner, SwViewShell *pSh ); - SwFontObj *Get(); }; -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx index 210b6e23f4ba..df069300105d 100644 --- a/sw/source/core/layout/ftnfrm.cxx +++ b/sw/source/core/layout/ftnfrm.cxx @@ -69,8 +69,8 @@ bool FootnoteSeparatorHeightFromParagraph(SwDoc& rDoc, SwTwips& rHeight) return false; } - SwFontAccess aFontAccess(pDefaultParaFormat, pSh); - SwFont aFont(aFontAccess.Get()->GetFont()); + const SwFontObj& rFontAccess = pDefaultParaFormat->GetFontObj(pSh); + SwFont aFont(rFontAccess.GetFont()); OutputDevice& rOut = pSh->GetRefDev(); rHeight = aFont.GetHeight(pSh, rOut); return true; diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index de760fbe6bac..a3559a4785e3 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -1120,8 +1120,8 @@ void SwPageFrame::ComputeRegister(const SwTextFormatColl* pFormat, sal_uInt16& r else { SwViewShell *pSh = getRootFrame()->GetCurrShell(); - SwFontAccess aFontAccess( pFormat, pSh ); - SwFont aFnt( aFontAccess.Get()->GetFont() ); + const SwFontObj& rFontAccess = pFormat->GetFontObj(pSh); + SwFont aFnt( rFontAccess.GetFont() ); OutputDevice *pOut = nullptr; if(pSh) diff --git a/sw/source/core/text/atrhndl.hxx b/sw/source/core/text/atrhndl.hxx index 6330857deb18..979b99800124 100644 --- a/sw/source/core/text/atrhndl.hxx +++ b/sw/source/core/text/atrhndl.hxx @@ -73,7 +73,7 @@ public: // set default attributes to values in rAttrSet or from cache void Init( const SwAttrSet& rAttrSet, const IDocumentSettingAccess& rIDocumentSettingAccess ); - void Init( const SfxPoolItem** pPoolItem, const SwAttrSet* pAttrSet, + void Init( const SfxPoolItem* const* pPoolItem, const SwAttrSet* pAttrSet, const IDocumentSettingAccess& rIDocumentSettingAccess, const SwViewShell* pShell, SwFont& rFnt, bool bVertLayout, bool bVertLayoutLRBT ); diff --git a/sw/source/core/text/atrstck.cxx b/sw/source/core/text/atrstck.cxx index 1af5e50d8550..82cec27250fc 100644 --- a/sw/source/core/text/atrstck.cxx +++ b/sw/source/core/text/atrstck.cxx @@ -287,7 +287,7 @@ void SwAttrHandler::Init( const SwAttrSet& rAttrSet, m_pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i ); } -void SwAttrHandler::Init( const SfxPoolItem** pPoolItem, const SwAttrSet* pAS, +void SwAttrHandler::Init( const SfxPoolItem* const* pPoolItem, const SwAttrSet* pAS, const IDocumentSettingAccess& rIDocumentSettingAcces, const SwViewShell* pSh, SwFont& rFnt, bool bVL, bool bVertLayoutLRBT ) diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx index 8ccf62981872..24dfeb49af1f 100644 --- a/sw/source/core/text/frmcrsr.cxx +++ b/sw/source/core/text/frmcrsr.cxx @@ -1424,8 +1424,8 @@ void SwTextFrame::FillCursorPos( SwFillData& rFill ) const } else { - SwFontAccess aFontAccess( pColl, pSh ); - pFnt.reset(new SwFont( aFontAccess.Get()->GetFont() )); + const SwFontObj& rFontAccess = pColl->GetFontObj(pSh); + pFnt.reset(new SwFont( rFontAccess.GetFont() )); pFnt->CheckFontCacheId( pSh, pFnt->GetActual() ); } OutputDevice* pOut = pSh->GetOut(); diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx index 007e0dfda7d3..eaad242df740 100644 --- a/sw/source/core/text/frmpaint.cxx +++ b/sw/source/core/text/frmpaint.cxx @@ -537,8 +537,8 @@ bool SwTextFrame::PaintEmpty( const SwRect &rRect, bool bCheck ) const } else { - SwFontAccess aFontAccess( &rTextNode.GetTextFormatColl(), pSh ); - pFnt.reset(new SwFont( aFontAccess.Get()->GetFont() )); + const SwFontObj& rFontAccess = rTextNode.GetTextFormatColl().GetFontObj(pSh); + pFnt.reset(new SwFont( rFontAccess.GetFont() )); } const IDocumentRedlineAccess& rIDRA = rTextNode.getIDocumentRedlineAccess(); diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx index aa278dd71fde..984de976225d 100644 --- a/sw/source/core/text/porrst.cxx +++ b/sw/source/core/text/porrst.cxx @@ -372,8 +372,8 @@ SwTwips SwTextFrame::EmptyHeight() const } else { - SwFontAccess aFontAccess( &rTextNode.GetTextFormatColl(), pSh); - pFnt.reset(new SwFont( aFontAccess.Get()->GetFont() )); + const SwFontObj& rFontAccess = rTextNode.GetTextFormatColl().GetFontObj(pSh); + pFnt.reset(new SwFont( rFontAccess.GetFont() )); pFnt->CheckFontCacheId( pSh, pFnt->GetActual() ); } diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index 0cebaa0a83f9..90e05b183ca9 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -629,18 +629,18 @@ void SwAttrIter::InitFontAndAttrHandler( bool const*const pbVertLayoutLRBT) { // Build a font matching the default paragraph style: - SwFontAccess aFontAccess( &rPropsNode.GetTextFormatColl(), m_pViewShell ); + const SwFontObj& rFontAccess = rPropsNode.GetTextFormatColl().GetFontObj(m_pViewShell); // It is possible that Init is called more than once, e.g., in a // SwTextFrame::FormatOnceMore situation or (since sw_redlinehide) // from SwAttrIter::Seek(); in the latter case SwTextSizeInfo::m_pFnt // is an alias of m_pFont so it must not be deleted! if (m_pFont) { - *m_pFont = aFontAccess.Get()->GetFont(); + *m_pFont = rFontAccess.GetFont(); } else { - m_pFont = new SwFont( aFontAccess.Get()->GetFont() ); + m_pFont = new SwFont( rFontAccess.GetFont() ); } // set font to vertical if frame layout is vertical @@ -658,7 +658,7 @@ void SwAttrIter::InitFontAndAttrHandler( // If any further attributes for the paragraph are given in pAttrSet // consider them during construction of the default array, and apply // them to the font - m_aAttrHandler.Init(aFontAccess.Get()->GetDefault(), rTextNode.GetpSwAttrSet(), + m_aAttrHandler.Init(rFontAccess.GetDefault(), rTextNode.GetpSwAttrSet(), *rTextNode.getIDocumentSettingAccess(), m_pViewShell, *m_pFont, pbVertLayout ? *pbVertLayout : m_aAttrHandler.IsVertLayout(), bVertLayoutLRBT ); diff --git a/sw/source/core/text/txtinit.cxx b/sw/source/core/text/txtinit.cxx index 98d85f9ebe8b..fbb5c70dd1e3 100644 --- a/sw/source/core/text/txtinit.cxx +++ b/sw/source/core/text/txtinit.cxx @@ -36,14 +36,12 @@ SwDropCapCache *pDropCapCache = nullptr; void TextInit_() { pFntCache = new SwFntCache; // Cache for SwSubFont -> SwFntObj = { Font aFont, Font* pScrFont, Font* pPrtFont, OutputDevice* pPrinter, ... } - pSwFontCache = new SwFontCache; // Cache for SwTextFormatColl -> SwFontObj = { SwFont aSwFont, SfxPoolItem* pDefaultArray } PROTOCOL_INIT } void TextFinit() { PROTOCOL_STOP - delete pSwFontCache; delete pFntCache; delete pContourCache; SwDropPortion::DeleteDropCapCache(); diff --git a/sw/source/core/txtnode/swfntcch.cxx b/sw/source/core/txtnode/swfntcch.cxx index 34c796d4fbd0..0f1b8eb8a322 100644 --- a/sw/source/core/txtnode/swfntcch.cxx +++ b/sw/source/core/txtnode/swfntcch.cxx @@ -29,15 +29,11 @@ // from atrstck.cxx extern const sal_uInt8 StackPos[]; -// FontCache is created in txtinit.cxx TextInit_ and deleted in TextFinit -SwFontCache *pSwFontCache = nullptr; - -SwFontObj::SwFontObj( const SwTextFormatColl *pOwn, SwViewShell *pSh ) : - SwCacheObj( pOwn ), - m_aSwFont( &pOwn->GetAttrSet(), pSh ? &pSh->getIDocumentSettingAccess() : nullptr ) +SwFontObj::SwFontObj( const SwTextFormatColl *pOwner, SwViewShell *pSh ) : + m_aSwFont( &pOwner->GetAttrSet(), pSh ? &pSh->getIDocumentSettingAccess() : nullptr ) { m_aSwFont.AllocFontCacheId( pSh, m_aSwFont.GetActual() ); - const SwAttrSet& rAttrSet = pOwn->GetAttrSet(); + const SwAttrSet& rAttrSet = pOwner->GetAttrSet(); for (sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++) m_pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i ); } @@ -46,29 +42,4 @@ SwFontObj::~SwFontObj() { } -SwFontAccess::SwFontAccess( const SwTextFormatColl *pOwn, SwViewShell *pSh ) : - SwCacheAccess( *pSwFontCache, pOwn, pOwn->IsInSwFntCache() ), - m_pShell( pSh ) -{ -} - -SwFontObj *SwFontAccess::Get( ) -{ - return static_cast<SwFontObj *>( SwCacheAccess::Get( ) ); -} - -SwCacheObj *SwFontAccess::NewObj( ) -{ - const_cast<SwTextFormatColl*>(static_cast<const SwTextFormatColl*>(m_pOwner))->SetInSwFntCache(); - return new SwFontObj( static_cast<const SwTextFormatColl*>(m_pOwner), m_pShell ); -} - -SAL_DLLPUBLIC_EXPORT void FlushFontCache() -{ - if (pSwFontCache) - pSwFontCache->Flush(); - if (pFntCache) - pFntCache->Flush(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx index bbad5e302d3b..626ed1e19ac5 100644 --- a/sw/source/filter/html/swhtml.cxx +++ b/sw/source/filter/html/swhtml.cxx @@ -5651,21 +5651,8 @@ void HTMLReader::SetupFilterOptions() m_aNamespace = aNamespace; } -namespace -{ - class FontCacheGuard - { - public: - ~FontCacheGuard() - { - FlushFontCache(); - } - }; -} - bool TestImportHTML(SvStream &rStream) { - FontCacheGuard aFontCacheGuard; HTMLReader aReader; aReader.m_pStream = &rStream; diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 2c641edaac32..f16fcb74e26c 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -6175,21 +6175,8 @@ extern "C" SAL_DLLPUBLIC_EXPORT Reader* ImportDOC() return new WW8Reader; } -namespace -{ - class FontCacheGuard - { - public: - ~FontCacheGuard() - { - FlushFontCache(); - } - }; -} - bool TestImportDOC(SvStream &rStream, const OUString &rFltName) { - FontCacheGuard aFontCacheGuard; std::unique_ptr<Reader> xReader(ImportDOC()); rtl::Reference<SotStorage> xStorage;
