sc/source/ui/view/output2.cxx |   40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

New commits:
commit 6ee4ce119b55d6e415696b23432fe65eabc94c17
Author:     Luboš Luňák <[email protected]>
AuthorDate: Tue Oct 19 11:56:15 2021 +0200
Commit:     Luboš Luňák <[email protected]>
CommitDate: Tue Oct 19 16:08:45 2021 +0200

    consider font when caching SalLayoutGlyphs in calc (tdf#143978)
    
    d62ad3efe3c8778cfd added the caching, but did not consider that
    the used OutputDevice (its font) may change.
    
    Change-Id: I291999d3613b7ba161e3d82348f621aa84a93067
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123809
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <[email protected]>

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 8f4a0c14eb36..d1238009fa89 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -57,6 +57,7 @@
 #include <sal/log.hxx>
 #include <unotools/charclass.hxx>
 #include <osl/diagnose.h>
+#include <tools/stream.hxx>
 
 #include <output.hxx>
 #include <document.hxx>
@@ -78,6 +79,7 @@
 #include <memory>
 #include <vector>
 #include <o3tl/lru_map.hxx>
+#include <o3tl/hash_combine.hxx>
 
 #include <math.h>
 
@@ -117,7 +119,19 @@ class ScDrawStringsVars
     tools::Long                nExpWidth;
 
     ScRefCellValue      maLastCell;
-    mutable o3tl::lru_map<OUString, SalLayoutGlyphs> mCachedGlyphs;
+    struct CachedGlyphsKey
+    {
+        OUString text;
+        VclPtr<OutputDevice> outputDevice;
+        size_t hashValue;
+        CachedGlyphsKey( const OUString& t, const VclPtr<OutputDevice>& dev );
+        bool operator==( const CachedGlyphsKey& other ) const;
+    };
+    struct CachedGlyphsHash
+    {
+        size_t operator()( const CachedGlyphsKey& key ) const { return 
key.hashValue; }
+    };
+    mutable o3tl::lru_map<CachedGlyphsKey, SalLayoutGlyphs, CachedGlyphsHash> 
mCachedGlyphs;
     sal_uLong           nValueFormat;
     bool                bLineBreak;
     bool                bRepeat;
@@ -773,17 +787,35 @@ tools::Long ScDrawStringsVars::GetExpWidth()
     return nExpWidth;
 }
 
+inline ScDrawStringsVars::CachedGlyphsKey::CachedGlyphsKey( const OUString& t, 
const VclPtr<OutputDevice>& d )
+    : text( t )
+    , outputDevice( d )
+{
+    hashValue = 0;
+    o3tl::hash_combine( hashValue, outputDevice.get());
+    SvMemoryStream stream;
+    WriteFont( stream, outputDevice->GetFont());
+    o3tl::hash_combine( hashValue, static_cast<const char*>(stream.GetData()), 
stream.GetSize());
+    o3tl::hash_combine( hashValue, text );
+}
+
+inline bool ScDrawStringsVars::CachedGlyphsKey::operator==( const 
CachedGlyphsKey& other ) const
+{
+    return hashValue == other.hashValue && outputDevice == other.outputDevice 
&& text == other.text;
+}
+
 const SalLayoutGlyphs* ScDrawStringsVars::GetLayoutGlyphs(const OUString& 
rString) const
 {
-    auto it = mCachedGlyphs.find( rString );
+    const CachedGlyphsKey key( rString, pOutput->pFmtDevice );
+    auto it = mCachedGlyphs.find( key );
     if( it != mCachedGlyphs.end() && it->second.IsValid())
         return &it->second;
     std::unique_ptr<SalLayout> layout = pOutput->pFmtDevice->ImplLayout( 
rString, 0, rString.getLength(),
         Point( 0, 0 ), 0, nullptr, SalLayoutFlags::GlyphItemsOnly );
     if( layout )
     {
-        mCachedGlyphs.insert( std::make_pair( rString, layout->GetGlyphs()));
-        assert(mCachedGlyphs.find( rString ) == mCachedGlyphs.begin()); // 
newly inserted item is first
+        mCachedGlyphs.insert( std::make_pair( key, layout->GetGlyphs()));
+        assert(mCachedGlyphs.find( key ) == mCachedGlyphs.begin()); // newly 
inserted item is first
         return &mCachedGlyphs.begin()->second;
     }
     return nullptr;

Reply via email to