summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-04-07 12:06:27 +0200
committerLuboš Luňák <l.lunak@collabora.com>2022-04-08 21:29:19 +0200
commit3e5863605881c6de6ad130fe06883c176ca1c69f (patch)
tree9e7863107a162eba8952710af00c281b91a12633
parent53fe4a26c7c4691fcf9d07d022adfd45247d176b (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.hxx3
-rw-r--r--editeng/source/editeng/impedit2.cxx2
-rw-r--r--editeng/source/editeng/impedit3.cxx28
-rw-r--r--editeng/source/items/svxfont.cxx27
-rw-r--r--include/editeng/svxfont.hxx10
-rw-r--r--include/vcl/glyphitemcache.hxx10
-rw-r--r--sc/source/ui/view/output2.cxx5
-rw-r--r--svx/source/inc/StylesPreviewWindow.hxx2
-rw-r--r--svx/source/tbxctrls/StylesPreviewWindow.cxx3
-rw-r--r--sw/source/core/docnode/ndtbl.cxx1
-rw-r--r--sw/source/core/inc/fntcache.hxx45
-rw-r--r--sw/source/core/layout/layact.cxx3
-rw-r--r--sw/source/core/txtnode/fntcache.cxx126
-rw-r--r--vcl/inc/pdf/pdfwriter_impl.hxx3
-rw-r--r--vcl/source/gdi/impglyphitem.cxx20
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx10
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 )