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 #include #include -#include #include #include @@ -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 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* 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* pDXArray, - SalLayoutGlyphsCache* cache ) const + const sal_Int32 nIdx, const sal_Int32 nLen, std::vector* 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 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 pDXArray, - SalLayoutGlyphsCache* cache ) const + const sal_Int32 nIdx, const sal_Int32 nLen, o3tl::span 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 pDXArray = {}, - SalLayoutGlyphsCache* cache = nullptr ) const; + const sal_Int32 nIdx = 0, const sal_Int32 nLen = SAL_MAX_INT32, + o3tl::span pDXArray = {} ) const; Size QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, - const sal_Int32 nIdx, const sal_Int32 nLen, std::vector* pDXArray = nullptr, - SalLayoutGlyphsCache* cache = nullptr ) const; + const sal_Int32 nIdx, const sal_Int32 nLen, + std::vector* 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 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 #include #include -#include class StylesPreviewWindow_Base; @@ -60,7 +59,6 @@ class StyleItemController SfxStyleFamily m_eStyleFamily; std::pair m_aStyleName; - SalLayoutGlyphsCache m_GlyphsCache; public: StyleItemController(const std::pair& 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 #include #include +#include #include #include @@ -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 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 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& 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& rDXAry, - sal_Int32 nLen); - void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector& rDXAry); + static void GetTextArray(const OutputDevice& rOutputDevice, const OUString& rStr, + std::vector& rDXAry, sal_Int32 nIndex, sal_Int32 nLen, + const vcl::text::TextLayoutCache* layoutCache = nullptr); + static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector& rDXAry, + sal_Int32 nLen); + static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector& 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 #include #include +#include #include #include #include #include -#include #include #include #include @@ -71,34 +71,6 @@ tools::Long SwFntObj::s_nPixWidth; MapMode* SwFntObj::s_pPixMap = nullptr; static vcl::DeleteOnDeinit< VclPtr > 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 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 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& 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 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& 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& 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 #include #include -#include #include #include @@ -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 #include #include +#include #include #include +#include SalLayoutGlyphs::SalLayoutGlyphs() {} @@ -95,6 +97,12 @@ bool SalLayoutGlyphsImpl::IsValid() const return true; } +SalLayoutGlyphsCache* SalLayoutGlyphsCache::self() +{ + static vcl::DeleteOnDeinit cache(1000); + return cache.get(); +} + const SalLayoutGlyphs* SalLayoutGlyphsCache::GetLayoutGlyphs(VclPtr outputDevice, const OUString& text, sal_Int32 nIndex, sal_Int32 nLen, tools::Long nLogicWidth, @@ -119,9 +127,15 @@ SalLayoutGlyphsCache::GetLayoutGlyphs(VclPtr outputDevice, c tmpLayoutCache = OutputDevice::CreateTextLayoutCache(text); layoutCache = tmpLayoutCache.get(); } - std::unique_ptr 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 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 #include #include +#include #include #include #include @@ -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 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 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 pLayout = ImplLayout( rText, nIndex, nLen, rPos, nWidth, {}, SalLayoutFlags::NONE, nullptr, layoutGlyphs ); if( pLayout )