diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/inc/fntcache.hxx | 20 | ||||
-rw-r--r-- | sw/source/core/txtnode/fntcache.cxx | 56 |
2 files changed, 60 insertions, 16 deletions
diff --git a/sw/source/core/inc/fntcache.hxx b/sw/source/core/inc/fntcache.hxx index 9edfd6d0e17b..9bf8024c9f72 100644 --- a/sw/source/core/inc/fntcache.hxx +++ b/sw/source/core/inc/fntcache.hxx @@ -20,8 +20,11 @@ #ifndef INCLUDED_SW_SOURCE_CORE_INC_FNTCACHE_HXX #define INCLUDED_SW_SOURCE_CORE_INC_FNTCACHE_HXX +#include <map> + #include <vcl/font.hxx> #include <vcl/vclptr.hxx> +#include <vcl/vcllayout.hxx> #include <swtypes.hxx> #include "swcache.hxx" #include "TextFrameIndex.hxx" @@ -54,6 +57,20 @@ extern SwFntCache *pFntCache; extern SwFntObj *pLastFont; extern sal_uInt8 *pMagicNo; +/** + * Defines a substring on a given output device, to be used as an std::map<> + * key. + */ +struct SwTextGlyphsKey +{ + VclPtr<OutputDevice> m_pOutputDevice; + OUString m_aText; + sal_Int32 m_nIndex; + sal_Int32 m_nLength; + +}; +bool operator<(const SwTextGlyphsKey& l, const SwTextGlyphsKey& r); + class SwFntObj : public SwCacheObj { friend class SwFntAccess; @@ -75,6 +92,9 @@ class SwFntObj : public SwCacheObj bool m_bSymbol : 1; bool m_bPaintBlank : 1; + /// Cache of already calculated layout glyphs. + std::map<SwTextGlyphsKey, SalLayoutGlyphs> m_aTextGlyphs; + static long nPixWidth; static MapMode *pPixMap; diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx index 49b1224501ed..2845d223db86 100644 --- a/sw/source/core/txtnode/fntcache.cxx +++ b/sw/source/core/txtnode/fntcache.cxx @@ -98,23 +98,23 @@ long EvalGridWidthAdd( const SwTextGridItem *const pGrid, const SwDrawTextInfo & } /** - * Pre-calculates glyph items for the rendered subset of rInf's text, assuming + * Pre-calculates glyph items for the rendered subset of rKey's text, assuming * outdev state does not change between the outdev calls. */ -SalLayoutGlyphs* lcl_CreateLayout(SwDrawTextInfo& rInf, const OUString& rText, sal_Int32 nIdx, - sal_Int32 nLen, SalLayoutGlyphs& rTextGlyphs) +SalLayoutGlyphs* lcl_CreateLayout(SwTextGlyphsKey& rKey, SalLayoutGlyphs& rTextGlyphs) { - // Not the string we want to pre-calculate. - if (rText != rInf.GetText() || nIdx != rInf.GetIdx() || nLen != rInf.GetLen()) - return nullptr; - // Use pre-calculated result. if (!rTextGlyphs.empty()) return &rTextGlyphs; + if (rKey.m_nIndex >= rKey.m_aText.getLength()) + // Same as in OutputDevice::GetTextArray(). + return nullptr; + // Calculate glyph items. - std::unique_ptr<SalLayout> pLayout = rInf.GetOut().ImplLayout( - rText, nIdx, nLen, Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly); + std::unique_ptr<SalLayout> pLayout + = rKey.m_pOutputDevice->ImplLayout(rKey.m_aText, rKey.m_nIndex, rKey.m_nLength, Point(0, 0), 0, + nullptr, SalLayoutFlags::GlyphItemsOnly); if (!pLayout) return nullptr; @@ -129,6 +129,27 @@ SalLayoutGlyphs* lcl_CreateLayout(SwDrawTextInfo& rInf, const OUString& rText, s } } +bool operator<(const SwTextGlyphsKey& l, const SwTextGlyphsKey& r) +{ + if (l.m_pOutputDevice.get() < r.m_pOutputDevice.get()) + return true; + if (l.m_pOutputDevice.get() > r.m_pOutputDevice.get()) + return false; + if (l.m_aText < r.m_aText) + return true; + if (l.m_aText > r.m_aText) + return false; + if (l.m_nIndex < r.m_nIndex) + return true; + if (l.m_nIndex > r.m_nIndex) + return false; + if (l.m_nLength < r.m_nLength) + return true; + if (l.m_nLength > r.m_nLength) + return false; + return false; +}; + void SwFntCache::Flush( ) { if ( pLastFont ) @@ -810,8 +831,6 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) vcl::Font* pTmpFont = bUseScrFont ? m_pScrFont : m_pPrtFont; - SalLayoutGlyphs aTextGlyphs; - // bDirectPrint and bUseScrFont should have these values: // Outdev / RefDef | Printer | VirtPrinter | Window @@ -1426,8 +1445,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) // get screen array std::unique_ptr<long[]> pScrArray(new long[sal_Int32(rInf.GetLen())]); - SalLayoutGlyphs* pGlyphs = lcl_CreateLayout(rInf, rInf.GetText(), sal_Int32(rInf.GetIdx()), - sal_Int32(rInf.GetLen()), aTextGlyphs); + SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), rInf.GetText(), rInf.GetIdx(), rInf.GetLen() }; + SalLayoutGlyphs* pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]); rInf.GetOut().GetTextArray( rInf.GetText(), pScrArray.get(), sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), nullptr, pGlyphs); @@ -1441,8 +1460,10 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) if( !m_pPrtFont->IsSameInstance( m_pPrinter->GetFont() ) ) m_pPrinter->SetFont( *m_pPrtFont ); } + aGlyphsKey = SwTextGlyphsKey{ m_pPrinter, rInf.GetText(), rInf.GetIdx(), rInf.GetLen() }; + pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]); m_pPrinter->GetTextArray(rInf.GetText(), pKernArray.get(), - sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen())); + sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), nullptr, pGlyphs); } else { @@ -1778,7 +1799,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) sal_Int32 nTmpIdx = bBullet ? (rInf.GetIdx() ? 1 : 0) : sal_Int32(rInf.GetIdx()); - pGlyphs = lcl_CreateLayout(rInf, *pStr, nTmpIdx, nLen, aTextGlyphs); + aGlyphsKey = SwTextGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, nLen }; + pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]); rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, pKernArray.get(), nTmpIdx , nLen, SalLayoutFlags::NONE, nullptr, pGlyphs ); if (bBullet) @@ -2012,9 +2034,11 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) } else { + SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), rInf.GetText(), rInf.GetIdx(), nLn }; + SalLayoutGlyphs* pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]); aTextSize.setWidth( rInf.GetOut().GetTextWidth( rInf.GetText(), sal_Int32(rInf.GetIdx()), sal_Int32(nLn), - rInf.GetVclCache()) ); + rInf.GetVclCache(), pGlyphs) ); rInf.SetKanaDiff( 0 ); } |