diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-04-07 12:06:27 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-04-08 21:29:19 +0200 |
commit | 3e5863605881c6de6ad130fe06883c176ca1c69f (patch) | |
tree | 9e7863107a162eba8952710af00c281b91a12633 | |
parent | 53fe4a26c7c4691fcf9d07d022adfd45247d176b (diff) |
use just one shared global SalLayoutGlyphsCache
Now the cache should be capable of detecting what needs
to stay the same for having the same result, so it should
be enough to have just one cache that can reuse results
even between callers from different places.
Change-Id: Ibdc0303f5b727d1a1d7be91d61db9465ed95e1c5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132673
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 3 | ||||
-rw-r--r-- | editeng/source/editeng/impedit2.cxx | 2 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 28 | ||||
-rw-r--r-- | editeng/source/items/svxfont.cxx | 27 | ||||
-rw-r--r-- | include/editeng/svxfont.hxx | 10 | ||||
-rw-r--r-- | include/vcl/glyphitemcache.hxx | 10 | ||||
-rw-r--r-- | sc/source/ui/view/output2.cxx | 5 | ||||
-rw-r--r-- | svx/source/inc/StylesPreviewWindow.hxx | 2 | ||||
-rw-r--r-- | svx/source/tbxctrls/StylesPreviewWindow.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/docnode/ndtbl.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/inc/fntcache.hxx | 45 | ||||
-rw-r--r-- | sw/source/core/layout/layact.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/txtnode/fntcache.cxx | 126 | ||||
-rw-r--r-- | vcl/inc/pdf/pdfwriter_impl.hxx | 3 | ||||
-rw-r--r-- | vcl/source/gdi/impglyphitem.cxx | 20 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 10 |
16 files changed, 81 insertions, 217 deletions
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index 36480f26bc1c..894bb822f676 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -36,7 +36,6 @@ #include <vcl/idle.hxx> #include <vcl/commandevent.hxx> #include <vcl/ptrstyle.hxx> -#include <vcl/glyphitemcache.hxx> #include <vcl/dndhelp.hxx> #include <svl/ondemand.hxx> @@ -608,8 +607,6 @@ private: bool mbNbspRunNext; // can't be a bitfield as it is passed as bool& - SalLayoutGlyphsCache mGlyphsCache; - // Methods... diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index 402d606d8b57..4b7b3490d138 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -3439,7 +3439,7 @@ sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, aTmpFont.SetPhysFont(*GetRefDevice()); ImplInitDigitMode(*GetRefDevice(), aTmpFont.GetLanguage()); nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), - pPortion->GetNode()->GetString(), nPos, rTextPortion.GetLen(), nullptr, &mGlyphsCache ).Width(); + pPortion->GetNode()->GetString(), nPos, rTextPortion.GetLen(), nullptr ).Width(); } } break; diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index 4f341fd65959..cdcc05100730 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -997,7 +997,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) // Height needed... SeekCursor( pNode, nTmpPos+1, aTmpFont ); pPortion->GetSize().setHeight( - aTmpFont.QuickGetTextSize( GetRefDevice(), OUString(), 0, 0, nullptr, &mGlyphsCache ).Height() ); + aTmpFont.QuickGetTextSize( GetRefDevice(), OUString(), 0, 0, nullptr ).Height() ); DBG_ASSERT( pPortion->GetSize().Width() >= 0, "Tab incorrectly calculated!" ); @@ -1043,7 +1043,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) // get size, but also DXArray to allow length information in line breaking below std::vector<sal_Int32> aTmpDXArray; pPortion->GetSize() = aTmpFont.QuickGetTextSize(GetRefDevice(), - aFieldValue, 0, aFieldValue.getLength(), &aTmpDXArray, &mGlyphsCache); + aFieldValue, 0, aFieldValue.getLength(), &aTmpDXArray); // So no scrolling for oversized fields if ( pPortion->GetSize().Width() > nXWidth ) @@ -1148,7 +1148,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) if (bContinueLastPortion) { Size aSize( aTmpFont.QuickGetTextSize( GetRefDevice(), - rParaPortion.GetNode()->GetString(), nTmpPos, nPortionLen, &aBuf, &mGlyphsCache )); + rParaPortion.GetNode()->GetString(), nTmpPos, nPortionLen, &aBuf )); pPortion->GetSize().AdjustWidth(aSize.Width() ); if (pPortion->GetSize().Height() < aSize.Height()) pPortion->GetSize().setHeight( aSize.Height() ); @@ -1156,7 +1156,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) else { pPortion->GetSize() = aTmpFont.QuickGetTextSize( GetRefDevice(), - rParaPortion.GetNode()->GetString(), nTmpPos, nPortionLen, &aBuf, &mGlyphsCache ); + rParaPortion.GetNode()->GetString(), nTmpPos, nPortionLen, &aBuf ); } // #i9050# Do Kerning also behind portions... @@ -1225,7 +1225,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) { nW -= rParaPortion.GetTextPortions()[nTmpPortion].GetSize().Width(); nW += aTmpFont.QuickGetTextSize( GetRefDevice(), rParaPortion.GetNode()->GetString(), - nTmpPos, nDecPos, nullptr, &mGlyphsCache ).Width(); + nTmpPos, nDecPos, nullptr ).Width(); aCurrentTab.bValid = false; } } @@ -2371,7 +2371,7 @@ sal_Int32 ImpEditEngine::SplitTextPortion( ParaPortion* pPortion, sal_Int32 nPos GetRefDevice()->Push( vcl::PushFlags::TEXTLANGUAGE ); ImplInitDigitMode(*GetRefDevice(), aTmpFont.GetLanguage()); Size aSz = aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString(), - nTxtPortionStart, pTextPortion->GetLen(), nullptr, &mGlyphsCache ); + nTxtPortionStart, pTextPortion->GetLen(), nullptr ); GetRefDevice()->Pop(); pTextPortion->GetExtraInfos()->nOrgWidth = aSz.Width(); } @@ -3301,7 +3301,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po if ( 0x200B == cChar || 0x2060 == cChar ) { tools::Long nHalfBlankWidth = aTmpFont.QuickGetTextSize( &rOutDev, - " ", 0, 1, nullptr, &mGlyphsCache ).Width() / 2; + " ", 0, 1, nullptr ).Width() / 2; const tools::Long nAdvanceX = ( nTmpIdx == nTmpEnd ? rTextPortion.GetSize().Width() : @@ -3338,13 +3338,13 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po aTmpFont.SetPhysFont(rOutDev); const Size aSlashSize = aTmpFont.QuickGetTextSize( &rOutDev, - aSlash, 0, 1, nullptr, &mGlyphsCache ); + aSlash, 0, 1, nullptr ); Point aSlashPos( aTmpPos ); const tools::Long nAddX = nHalfBlankWidth - aSlashSize.Width() / 2; setXDirectionAwareFrom(aSlashPos, aTopLeftRectPos); adjustXDirectionAware(aSlashPos, nAddX); - aTmpFont.QuickDrawText( &rOutDev, aSlashPos, aSlash, 0, 1, {}, &mGlyphsCache ); + aTmpFont.QuickDrawText( &rOutDev, aSlashPos, aSlash, 0, 1, {} ); aTmpFont.SetEscapement( nOldEscapement ); aTmpFont.SetPropr( nOldPropr ); @@ -3406,7 +3406,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po aTmpFont.SetPhysFont(*GetRefDevice()); aTmpFont.QuickGetTextSize( GetRefDevice(), aText, nTextStart, nTextLen, - &aTmpDXArray, &mGlyphsCache ); + &aTmpDXArray ); pDXArray = aTmpDXArray; // add a meta file comment if we record to a metafile @@ -3433,7 +3433,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po // crash when accessing 0 pointer in pDXArray aTmpFont.SetPhysFont(*GetRefDevice()); aTmpFont.QuickGetTextSize( GetRefDevice(), aText, 0, aText.getLength(), - &aTmpDXArray, &mGlyphsCache ); + &aTmpDXArray ); pDXArray = aTmpDXArray; } @@ -3634,7 +3634,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po --nTextLen; // output directly - aTmpFont.QuickDrawText( &rOutDev, aRealOutPos, aText, nTextStart, nTextLen, pDXArray, &mGlyphsCache ); + aTmpFont.QuickDrawText( &rOutDev, aRealOutPos, aText, nTextStart, nTextLen, pDXArray ); if ( bDrawFrame ) { @@ -3725,7 +3725,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po aTmpFont.SetEscapement( 0 ); aTmpFont.SetPhysFont(rOutDev); tools::Long nCharWidth = aTmpFont.QuickGetTextSize( &rOutDev, - OUString(rTextPortion.GetExtraValue()), 0, 1, {}, &mGlyphsCache ).Width(); + OUString(rTextPortion.GetExtraValue()), 0, 1, {} ).Width(); sal_Int32 nChars = 2; if( nCharWidth ) nChars = rTextPortion.GetSize().Width() / nCharWidth; @@ -3737,7 +3737,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po OUStringBuffer aBuf(nChars); comphelper::string::padToLength(aBuf, nChars, rTextPortion.GetExtraValue()); OUString aText(aBuf.makeStringAndClear()); - aTmpFont.QuickDrawText( &rOutDev, aTmpPos, aText, 0, aText.getLength(), {}, &mGlyphsCache ); + aTmpFont.QuickDrawText( &rOutDev, aTmpPos, aText, 0, aText.getLength(), {} ); rOutDev.DrawStretchText( aTmpPos, rTextPortion.GetSize().Width(), aText ); if ( bStripOnly ) diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx index 7c73d0c9d628..4b549d49d711 100644 --- a/editeng/source/items/svxfont.cxx +++ b/editeng/source/items/svxfont.cxx @@ -454,27 +454,26 @@ Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut ) } static tools::Long GetTextArray( const OutputDevice* pOut, const OUString& rStr, std::vector<sal_Int32>* pDXAry, - sal_Int32 nIndex, sal_Int32 nLen, SalLayoutGlyphsCache* cache ) + sal_Int32 nIndex, sal_Int32 nLen ) { - const SalLayoutGlyphs* layoutGlyphs = cache ? cache->GetLayoutGlyphs(pOut, rStr, nIndex, nLen) : nullptr; + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen); return pOut->GetTextArray( rStr, pDXAry, nIndex, nLen, nullptr, layoutGlyphs); } Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, - const sal_Int32 nIdx, const sal_Int32 nLen, std::vector<sal_Int32>* pDXArray, - SalLayoutGlyphsCache* cache ) const + const sal_Int32 nIdx, const sal_Int32 nLen, std::vector<sal_Int32>* pDXArray ) const { if ( !IsCaseMap() && !IsKern() ) - return Size( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen, cache ), + return Size( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen ), pOut->GetTextHeight() ); Size aTxtSize; aTxtSize.setHeight( pOut->GetTextHeight() ); if ( !IsCaseMap() ) - aTxtSize.setWidth( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen, cache ) ); + aTxtSize.setWidth( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen ) ); else aTxtSize.setWidth( GetTextArray( pOut, CalcCaseMap( rTxt ), - pDXArray, nIdx, nLen, cache ) ); + pDXArray, nIdx, nLen ) ); if( IsKern() && ( nLen > 1 ) ) { @@ -510,23 +509,21 @@ Size SvxFont::GetTextSize(const OutputDevice& rOut, const OUString &rTxt, static void DrawTextArray( OutputDevice* pOut, const Point& rStartPt, const OUString& rStr, o3tl::span<const sal_Int32> pDXAry, - sal_Int32 nIndex, sal_Int32 nLen, - SalLayoutGlyphsCache* cache ) + sal_Int32 nIndex, sal_Int32 nLen ) { - const SalLayoutGlyphs* layoutGlyphs = cache ? cache->GetLayoutGlyphs(pOut, rStr, nIndex, nLen) : nullptr; + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen); pOut->DrawTextArray(rStartPt, rStr, pDXAry, nIndex, nLen, SalLayoutFlags::NONE, layoutGlyphs); } void SvxFont::QuickDrawText( OutputDevice *pOut, const Point &rPos, const OUString &rTxt, - const sal_Int32 nIdx, const sal_Int32 nLen, o3tl::span<const sal_Int32> pDXArray, - SalLayoutGlyphsCache* cache ) const + const sal_Int32 nIdx, const sal_Int32 nLen, o3tl::span<const sal_Int32> pDXArray ) const { // Font has to be selected in OutputDevice... if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() ) { - DrawTextArray( pOut, rPos, rTxt, pDXArray, nIdx, nLen, cache ); + DrawTextArray( pOut, rPos, rTxt, pDXArray, nIdx, nLen ); return; } @@ -563,9 +560,9 @@ void SvxFont::QuickDrawText( OutputDevice *pOut, else { if ( !IsCaseMap() ) - DrawTextArray( pOut, aPos, rTxt, pDXArray, nIdx, nLen, cache ); + DrawTextArray( pOut, aPos, rTxt, pDXArray, nIdx, nLen ); else - DrawTextArray( pOut, aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen, cache ); + DrawTextArray( pOut, aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen ); } } } diff --git a/include/editeng/svxfont.hxx b/include/editeng/svxfont.hxx index a3db7b2a8936..e0f92c57289d 100644 --- a/include/editeng/svxfont.hxx +++ b/include/editeng/svxfont.hxx @@ -36,8 +36,6 @@ class Printer; class Point; namespace tools { class Rectangle; } class Size; -class SalLayoutGlyphsCache; - class EDITENG_DLLPUBLIC SvxFont : public vcl::Font { SvxCaseMap eCaseMap; // Text Markup @@ -97,12 +95,12 @@ public: const sal_Int32 nIdx = 0, const sal_Int32 nLen = SAL_MAX_INT32) const; void QuickDrawText( OutputDevice *pOut, const Point &rPos, const OUString &rTxt, - const sal_Int32 nIdx = 0, const sal_Int32 nLen = SAL_MAX_INT32, o3tl::span<const sal_Int32> pDXArray = {}, - SalLayoutGlyphsCache* cache = nullptr ) const; + const sal_Int32 nIdx = 0, const sal_Int32 nLen = SAL_MAX_INT32, + o3tl::span<const sal_Int32> pDXArray = {} ) const; Size QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, - const sal_Int32 nIdx, const sal_Int32 nLen, std::vector<sal_Int32>* pDXArray = nullptr, - SalLayoutGlyphsCache* cache = nullptr ) const; + const sal_Int32 nIdx, const sal_Int32 nLen, + std::vector<sal_Int32>* pDXArray = nullptr ) const; void DrawPrev( OutputDevice* pOut, Printer* pPrinter, const Point &rPos, const OUString &rTxt, diff --git a/include/vcl/glyphitemcache.hxx b/include/vcl/glyphitemcache.hxx index fca8e9f12575..34a5b51d6c1b 100644 --- a/include/vcl/glyphitemcache.hxx +++ b/include/vcl/glyphitemcache.hxx @@ -40,10 +40,6 @@ If something more changes, call clear(). class VCL_DLLPUBLIC SalLayoutGlyphsCache final { public: - SalLayoutGlyphsCache(int size = 1000) - : mCachedGlyphs(size) - { - } const SalLayoutGlyphs* GetLayoutGlyphs(VclPtr<const OutputDevice> outputDevice, const OUString& text, const vcl::text::TextLayoutCache* layoutCache = nullptr) const @@ -56,6 +52,12 @@ public: const vcl::text::TextLayoutCache* layoutCache = nullptr) const; void clear() { mCachedGlyphs.clear(); } + static SalLayoutGlyphsCache* self(); + SalLayoutGlyphsCache(int size) // needs to be public for vcl::DeleteOnDeinit + : mCachedGlyphs(size) + { + } + private: struct CachedGlyphsKey { diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 90f6fdacf91e..ea35193dc24b 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -121,7 +121,6 @@ class ScDrawStringsVars tools::Long nExpWidth; ScRefCellValue maLastCell; - mutable SalLayoutGlyphsCache mCachedGlyphs; sal_uLong nValueFormat; bool bLineBreak; bool bRepeat; @@ -189,7 +188,7 @@ public: // to lay out the text, which is relatively slow, so cache that operation. const SalLayoutGlyphs* GetLayoutGlyphs(const OUString& rString) const { - return mCachedGlyphs.GetLayoutGlyphs(pOutput->pFmtDevice, rString); + return SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOutput->pFmtDevice, rString); } private: @@ -307,7 +306,6 @@ void ScDrawStringsVars::SetPattern( nSignWidth = 0; nDotWidth = 0; nExpWidth = 0; - mCachedGlyphs.clear(); pPattern = pNew; pCondSet = pSet; @@ -462,7 +460,6 @@ void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxIt nSignWidth = 0; nDotWidth = 0; nExpWidth = 0; - mCachedGlyphs.clear(); // Is called, when the font variables do not change (!StringDiffer) diff --git a/svx/source/inc/StylesPreviewWindow.hxx b/svx/source/inc/StylesPreviewWindow.hxx index b59ad94041e7..3b652dcfb0d0 100644 --- a/svx/source/inc/StylesPreviewWindow.hxx +++ b/svx/source/inc/StylesPreviewWindow.hxx @@ -24,7 +24,6 @@ #include <svl/style.hxx> #include <com/sun/star/frame/XDispatchProvider.hpp> #include <sfx2/sfxstatuslistener.hxx> -#include <vcl/glyphitemcache.hxx> class StylesPreviewWindow_Base; @@ -60,7 +59,6 @@ class StyleItemController SfxStyleFamily m_eStyleFamily; std::pair<OUString, OUString> m_aStyleName; - SalLayoutGlyphsCache m_GlyphsCache; public: StyleItemController(const std::pair<OUString, OUString>& aStyleName); diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx b/svx/source/tbxctrls/StylesPreviewWindow.cxx index 8ad09344aa0f..ffd6d1e9b0ed 100644 --- a/svx/source/tbxctrls/StylesPreviewWindow.cxx +++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx @@ -27,6 +27,7 @@ #include <sfx2/sfxsids.hrc> #include <sfx2/tplpitem.hxx> #include <sfx2/viewsh.hxx> +#include <vcl/glyphitemcache.hxx> #include <vcl/virdev.hxx> #include <vcl/settings.hxx> @@ -354,7 +355,7 @@ void StyleItemController::DrawHighlight(vcl::RenderContext& rRenderContext, Colo void StyleItemController::DrawText(vcl::RenderContext& rRenderContext) { const SalLayoutGlyphs* layoutGlyphs - = m_GlyphsCache.GetLayoutGlyphs(&rRenderContext, m_aStyleName.second); + = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&rRenderContext, m_aStyleName.second); tools::Rectangle aTextRect; rRenderContext.GetTextBoundRect(aTextRect, m_aStyleName.second, 0, 0, -1, 0, {}, layoutGlyphs); diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx index 601de8d62fd9..90e9626c9805 100644 --- a/sw/source/core/docnode/ndtbl.cxx +++ b/sw/source/core/docnode/ndtbl.cxx @@ -2886,7 +2886,6 @@ void SwDoc::SetTabCols(SwTable& rTab, const SwTabCols &rNew, const SwTabCols &rO } rTab.SetTabCols( rNew, rOld, pStart, bCurRowOnly ); ::ClearFEShellTabCols(*this, nullptr); - SwClearFntCacheTextGlyphs(); getIDocumentState().SetModified(); } diff --git a/sw/source/core/inc/fntcache.hxx b/sw/source/core/inc/fntcache.hxx index 9a38a68b63a1..3b8934013059 100644 --- a/sw/source/core/inc/fntcache.hxx +++ b/sw/source/core/inc/fntcache.hxx @@ -53,37 +53,10 @@ public: void Flush(); }; -/// Clears the pre-calculated text glyphs in all SwFntObj instances. -void SwClearFntCacheTextGlyphs(); - // Font cache, global variable, created/destroyed in txtinit.cxx extern SwFntCache *pFntCache; extern SwFntObj *pLastFont; -/** - * Defines a substring on a given output device, to be used as an std::unordered_map<> - * key. - */ -struct SwTextGlyphsKey -{ - VclPtr<const OutputDevice> m_pOutputDevice; - OUString m_aText; - sal_Int32 m_nIndex; - sal_Int32 m_nLength; - size_t mnHashCode; - - SwTextGlyphsKey(const OutputDevice* pOutputDevice, const OUString & sText, sal_Int32 nIndex, sal_Int32 nLength); - bool operator==(SwTextGlyphsKey const & rhs) const; -}; -struct SwTextGlyphsKeyHash -{ - size_t operator()(SwTextGlyphsKey const & rKey) const { return rKey.mnHashCode; } -}; -/** - * Glyphs for the given SwTextGlyphsKey. - */ -typedef std::unordered_map<SwTextGlyphsKey, SalLayoutGlyphs, SwTextGlyphsKeyHash> SwTextGlyphsMap; - class SwFntObj final : public SwCacheObj { friend class SwFntAccess; @@ -105,15 +78,12 @@ class SwFntObj final : public SwCacheObj bool m_bSymbol : 1; bool m_bPaintBlank : 1; - /// Cache of already calculated layout glyphs and text widths. - SwTextGlyphsMap m_aTextGlyphs; - - void GetTextArray(const OutputDevice& rOutputDevice, const OUString& rStr, - std::vector<sal_Int32>& rDXAry, sal_Int32 nIndex, sal_Int32 nLen, - bool bCaching, const vcl::text::TextLayoutCache* layoutCache = nullptr); - void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry, - sal_Int32 nLen); - void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry); + static void GetTextArray(const OutputDevice& rOutputDevice, const OUString& rStr, + std::vector<sal_Int32>& rDXAry, sal_Int32 nIndex, sal_Int32 nLen, + const vcl::text::TextLayoutCache* layoutCache = nullptr); + static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry, + sal_Int32 nLen); + static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry); static tools::Long s_nPixWidth; static MapMode *s_pPixMap; @@ -143,9 +113,6 @@ public: sal_uInt16 GetPropWidth() const { return m_nPropWidth; } bool IsSymbol() const { return m_bSymbol; } - SalLayoutGlyphs* GetCachedSalLayoutGlyphs(const SwTextGlyphsKey& key, const vcl::text::TextLayoutCache* layoutCache); - void ClearCachedTextGlyphs(); - void DrawText( SwDrawTextInfo &rInf ); /// determine the TextSize (of the printer) Size GetTextSize( SwDrawTextInfo &rInf ); diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx index bb46c23e11a3..4a9ca92f52a2 100644 --- a/sw/source/core/layout/layact.cxx +++ b/sw/source/core/layout/layact.cxx @@ -2397,9 +2397,6 @@ SwLayIdle::SwLayIdle( SwRootFrame *pRt, SwViewShellImp *pI ) : m_pRoot->ResetIdleFormat(); SfxObjectShell* pDocShell = m_pImp->GetShell()->GetDoc()->GetDocShell(); pDocShell->Broadcast( SfxEventHint( SfxEventHintId::SwEventLayoutFinished, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) ); - // Limit lifetime of the text glyphs cache to a single run of the - // layout. - SwClearFntCacheTextGlyphs(); } } diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx index e4009930bfbb..0176332889d7 100644 --- a/sw/source/core/txtnode/fntcache.cxx +++ b/sw/source/core/txtnode/fntcache.cxx @@ -26,11 +26,11 @@ #include <vcl/metric.hxx> #include <vcl/svapp.hxx> #include <vcl/lazydelete.hxx> +#include <vcl/glyphitemcache.hxx> #include <com/sun/star/i18n/CharacterIteratorMode.hpp> #include <com/sun/star/i18n/WordType.hpp> #include <com/sun/star/i18n/XBreakIterator.hpp> #include <breakit.hxx> -#include <config_fuzzers.h> #include <paintfrm.hxx> #include <viewsh.hxx> #include <viewopt.hxx> @@ -71,34 +71,6 @@ tools::Long SwFntObj::s_nPixWidth; MapMode* SwFntObj::s_pPixMap = nullptr; static vcl::DeleteOnDeinit< VclPtr<OutputDevice> > s_pFntObjPixOut {}; -/** - * Defines a substring on a given output device, to be used as an std::unordered_map<> - * key. - */ -SwTextGlyphsKey::SwTextGlyphsKey(const OutputDevice* pOutputDevice, const OUString & sText, sal_Int32 nIndex, sal_Int32 nLength) - : m_pOutputDevice(pOutputDevice), m_aText(sText), m_nIndex(nIndex), m_nLength(nLength) -{ - mnHashCode = 0; - o3tl::hash_combine(mnHashCode, pOutputDevice); - o3tl::hash_combine(mnHashCode, m_nIndex); - o3tl::hash_combine(mnHashCode, m_nLength); - if(m_nLength >= 0 && m_nIndex >= 0 && m_nIndex + m_nLength <= m_aText.getLength()) - o3tl::hash_combine(mnHashCode, m_aText.getStr() + m_nIndex, m_nLength); -} -bool SwTextGlyphsKey::operator==(SwTextGlyphsKey const & rhs) const -{ - bool b = m_pOutputDevice.get() == rhs.m_pOutputDevice.get() - && m_nIndex == rhs.m_nIndex - && m_nLength == rhs.m_nLength - && m_aText.getLength() == rhs.m_aText.getLength(); - if (!b) - return false; - if(m_nLength >= 0 && m_nIndex >= 0 && m_nIndex + m_nLength <= m_aText.getLength()) - return m_aText.subView(m_nIndex,m_nLength) == rhs.m_aText.subView(m_nIndex, m_nLength); - return m_aText == rhs.m_aText; -} - - namespace { @@ -188,66 +160,6 @@ void SwFntObj::CreatePrtFont( const OutputDevice& rPrt ) } -#if !ENABLE_FUZZERS -const SalLayoutFlags eGlyphItemsOnlyLayout = SalLayoutFlags::GlyphItemsOnly; -#else -// ofz#39150 skip detecting bidi directions -const SalLayoutFlags eGlyphItemsOnlyLayout = SalLayoutFlags::GlyphItemsOnly | SalLayoutFlags::BiDiStrong; -#endif - -/** - * Pre-calculates glyph items for the rendered subset of rKey's text, assuming - * outdev state does not change between the outdev calls. - */ -static SalLayoutGlyphs* lcl_CreateLayout(const SwTextGlyphsKey& rKey, SwTextGlyphsMap::iterator it, - const vcl::text::TextLayoutCache* layoutCache) -{ - assert (!it->second.IsValid()); - - if (rKey.m_nIndex >= rKey.m_aText.getLength()) - // Same as in OutputDevice::GetTextArray(). - return nullptr; - - // Calculate glyph items. - std::unique_ptr<SalLayout> pLayout - = rKey.m_pOutputDevice->ImplLayout(rKey.m_aText, rKey.m_nIndex, rKey.m_nLength, Point(0, 0), 0, - {}, eGlyphItemsOnlyLayout, layoutCache); - if (!pLayout) - return nullptr; - - // Remember the calculation result. - it->second = pLayout->GetGlyphs(); - - return &it->second; -} - -SalLayoutGlyphs* SwFntObj::GetCachedSalLayoutGlyphs(const SwTextGlyphsKey& key, const vcl::text::TextLayoutCache* layoutCache) -{ - SwTextGlyphsMap::iterator it = m_aTextGlyphs.find(key); - if(it != m_aTextGlyphs.end()) - { - if( it->second.IsValid()) - return &it->second; - // Do not try to create the layout here. If a cache item exists, it's already - // been attempted and the layout was invalid (this happens with MultiSalLayout). - // So in that case this is a cached failure. - return nullptr; - } - it = m_aTextGlyphs.insert_or_assign( it, key, SalLayoutGlyphs()); - std::shared_ptr<const vcl::text::TextLayoutCache> tmpLayoutCache; - if( layoutCache == nullptr ) - { - tmpLayoutCache = OutputDevice::CreateTextLayoutCache( key.m_aText ); - layoutCache = tmpLayoutCache.get(); - } - return lcl_CreateLayout(key, it, layoutCache); -} - -void SwFntObj::ClearCachedTextGlyphs() -{ - m_aTextGlyphs.clear(); -} - /* * returns whether we have to adjust the output font to resemble * the formatting font @@ -845,33 +757,23 @@ static void lcl_DrawLineForWrongListData( } void SwFntObj::GetTextArray(const OutputDevice& rDevice, const OUString& rStr, std::vector<sal_Int32>& rDXAry, - sal_Int32 nIndex, sal_Int32 nLen, bool bCaching, const vcl::text::TextLayoutCache* layoutCache) + sal_Int32 nIndex, sal_Int32 nLen, const vcl::text::TextLayoutCache* layoutCache) { - SalLayoutGlyphs* pLayoutCache = nullptr; - std::shared_ptr<const vcl::text::TextLayoutCache> tmpLayoutCache; - if (bCaching) - { - SwTextGlyphsKey aGlyphsKey{&rDevice, rStr, nIndex, nLen}; - pLayoutCache = GetCachedSalLayoutGlyphs(aGlyphsKey, layoutCache); - if(pLayoutCache == nullptr) - { // Try to create at least the lower-level cache if possible. - tmpLayoutCache = OutputDevice::CreateTextLayoutCache( rStr ); - layoutCache = tmpLayoutCache.get(); - } - } + const SalLayoutGlyphs* pLayoutCache = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&rDevice, rStr, nIndex, nLen, + 0, layoutCache); rDevice.GetTextArray(rStr, &rDXAry, nIndex, nLen, layoutCache, pLayoutCache); } void SwFntObj::GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry) { - return GetTextArray(rOutputDevice, rInf.GetText(), rDXAry, rInf.GetIdx().get(), rInf.GetLen().get(), true, rInf.GetVclCache()); + return GetTextArray(rOutputDevice, rInf.GetText(), rDXAry, rInf.GetIdx().get(), rInf.GetLen().get(), rInf.GetVclCache()); } void SwFntObj::GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry, sal_Int32 nLen) { // Substring is fine. assert( nLen <= rInf.GetLen().get()); - return GetTextArray(rOutputDevice, rInf.GetText(), rDXAry, rInf.GetIdx().get(), nLen, true, rInf.GetVclCache()); + return GetTextArray(rOutputDevice, rInf.GetText(), rDXAry, rInf.GetIdx().get(), nLen, rInf.GetVclCache()); } void SwFntObj::DrawText( SwDrawTextInfo &rInf ) @@ -1818,8 +1720,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) sal_Int32 nTmpIdx = bBullet ? (rInf.GetIdx() ? 1 : 0) : sal_Int32(rInf.GetIdx()); - SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, nLen }; - SalLayoutGlyphs* pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey, nullptr); + const SalLayoutGlyphs* pGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&rInf.GetOut(), + *pStr, nTmpIdx, nLen); rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, aKernArray, nTmpIdx , nLen, SalLayoutFlags::NONE, pGlyphs ); if (bBullet) @@ -1982,7 +1884,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) rInf.GetOut().SetFont( *m_pScrFont ); GetTextArray(*m_pPrinter, rInf.GetText(), aKernArray, - sal_Int32(rInf.GetIdx()), sal_Int32(nLn), false); + sal_Int32(rInf.GetIdx()), sal_Int32(nLn)); } else { @@ -2449,8 +2351,8 @@ TextFrameIndex SwFont::GetTextBreak(SwDrawTextInfo const & rInf, tools::Long nTe { SwFntAccess aFntAccess(m_aSub[m_nActual].m_nFontCacheId, m_aSub[m_nActual].m_nFontIndex, &m_aSub[m_nActual], rInf.GetShell()); - SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), *pTmpText, sal_Int32(nTmpIdx), sal_Int32(nTmpLen) }; - SalLayoutGlyphs* pGlyphs = aFntAccess.Get()->GetCachedSalLayoutGlyphs(aGlyphsKey, nullptr); + const SalLayoutGlyphs* pGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&rInf.GetOut(), + *pTmpText, nTmpIdx.get(), nTmpLen.get(), 0, rInf.GetVclCache()); nTextBreak = TextFrameIndex(rInf.GetOut().GetTextBreak( *pTmpText, nTextWidth, sal_Int32(nTmpIdx), sal_Int32(nTmpLen), @@ -2645,10 +2547,4 @@ bool SwDrawTextInfo::ApplyAutoColor( vcl::Font* pFont ) return false; } -void SwClearFntCacheTextGlyphs() -{ - for (SwFntObj* pFntObj = pFntCache->First(); pFntObj; pFntObj = SwFntCache::Next(pFntObj)) - pFntObj->ClearCachedTextGlyphs(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx index 69570fa84afb..b8bdc3825eee 100644 --- a/vcl/inc/pdf/pdfwriter_impl.hxx +++ b/vcl/inc/pdf/pdfwriter_impl.hxx @@ -53,7 +53,6 @@ #include <comphelper/hash.hxx> #include <tools/stream.hxx> #include <vcl/BinaryDataContainer.hxx> -#include <vcl/glyphitemcache.hxx> #include <vcl/filter/pdfobjectcontainer.hxx> #include <pdf/ExternalPDFStreams.hxx> @@ -765,8 +764,6 @@ private: ::comphelper::Hash m_DocDigest; - SalLayoutGlyphsCache m_layoutGlyphsCache; - /* variables for PDF security i12626 diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx index 01654cfddcbc..86284c256e64 100644 --- a/vcl/source/gdi/impglyphitem.cxx +++ b/vcl/source/gdi/impglyphitem.cxx @@ -20,8 +20,10 @@ #include <impglyphitem.hxx> #include <vcl/glyphitemcache.hxx> #include <vcl/vcllayout.hxx> +#include <vcl/lazydelete.hxx> #include <tools/stream.hxx> #include <TextLayoutCache.hxx> +#include <config_fuzzers.h> SalLayoutGlyphs::SalLayoutGlyphs() {} @@ -95,6 +97,12 @@ bool SalLayoutGlyphsImpl::IsValid() const return true; } +SalLayoutGlyphsCache* SalLayoutGlyphsCache::self() +{ + static vcl::DeleteOnDeinit<SalLayoutGlyphsCache> cache(1000); + return cache.get(); +} + const SalLayoutGlyphs* SalLayoutGlyphsCache::GetLayoutGlyphs(VclPtr<const OutputDevice> outputDevice, const OUString& text, sal_Int32 nIndex, sal_Int32 nLen, tools::Long nLogicWidth, @@ -119,9 +127,15 @@ SalLayoutGlyphsCache::GetLayoutGlyphs(VclPtr<const OutputDevice> outputDevice, c tmpLayoutCache = OutputDevice::CreateTextLayoutCache(text); layoutCache = tmpLayoutCache.get(); } - std::unique_ptr<SalLayout> layout - = outputDevice->ImplLayout(text, nIndex, nLen, Point(0, 0), nLogicWidth, {}, - SalLayoutFlags::GlyphItemsOnly, layoutCache); +#if !ENABLE_FUZZERS + const SalLayoutFlags glyphItemsOnlyLayout = SalLayoutFlags::GlyphItemsOnly; +#else + // ofz#39150 skip detecting bidi directions + const SalLayoutFlags glyphItemsOnlyLayout + = SalLayoutFlags::GlyphItemsOnly | SalLayoutFlags::BiDiStrong; +#endif + std::unique_ptr<SalLayout> layout = outputDevice->ImplLayout( + text, nIndex, nLen, Point(0, 0), nLogicWidth, {}, glyphItemsOnlyLayout, layoutCache); if (layout) { mCachedGlyphs.insert(std::make_pair(key, layout->GetGlyphs())); diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 1853fe544eeb..7e01ed70dc58 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -61,6 +61,7 @@ #include <vcl/canvastools.hxx> #include <vcl/cvtgrf.hxx> #include <vcl/fontcharmap.hxx> +#include <vcl/glyphitemcache.hxx> #include <vcl/lineinfo.hxx> #include <vcl/metric.hxx> #include <vcl/settings.hxx> @@ -6499,7 +6500,8 @@ void PDFWriterImpl::drawText( const Point& rPos, const OUString& rText, sal_Int3 // get a layout from the OutputDevice's SalGraphics // this also enforces font substitution and sets the font on SalGraphics - const SalLayoutGlyphs* layoutGlyphs = m_layoutGlyphsCache.GetLayoutGlyphs( this, rText, nIndex, nLen ); + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()-> + GetLayoutGlyphs( this, rText, nIndex, nLen ); std::unique_ptr<SalLayout> pLayout = ImplLayout( rText, nIndex, nLen, rPos, 0, {}, SalLayoutFlags::NONE, nullptr, layoutGlyphs ); if( pLayout ) @@ -6516,7 +6518,8 @@ void PDFWriterImpl::drawTextArray( const Point& rPos, const OUString& rText, o3t // get a layout from the OutputDevice's SalGraphics // this also enforces font substitution and sets the font on SalGraphics - const SalLayoutGlyphs* layoutGlyphs = m_layoutGlyphsCache.GetLayoutGlyphs( this, rText, nIndex, nLen ); + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()-> + GetLayoutGlyphs( this, rText, nIndex, nLen ); std::unique_ptr<SalLayout> pLayout = ImplLayout( rText, nIndex, nLen, rPos, 0, pDXArray, SalLayoutFlags::NONE, nullptr, layoutGlyphs ); if( pLayout ) @@ -6533,7 +6536,8 @@ void PDFWriterImpl::drawStretchText( const Point& rPos, sal_uLong nWidth, const // get a layout from the OutputDevice's SalGraphics // this also enforces font substitution and sets the font on SalGraphics - const SalLayoutGlyphs* layoutGlyphs = m_layoutGlyphsCache.GetLayoutGlyphs( this, rText, nIndex, nLen, nWidth ); + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()-> + GetLayoutGlyphs( this, rText, nIndex, nLen, nWidth ); std::unique_ptr<SalLayout> pLayout = ImplLayout( rText, nIndex, nLen, rPos, nWidth, {}, SalLayoutFlags::NONE, nullptr, layoutGlyphs ); if( pLayout ) |