include/vcl/glyphitemcache.hxx  |    3 +-
 include/vcl/metric.hxx          |    9 ++++++++
 vcl/source/font/fontmetric.cxx  |   44 +++++++++++++++++++++++++++++++++++++---
 vcl/source/gdi/impglyphitem.cxx |    6 ++---
 4 files changed, 55 insertions(+), 7 deletions(-)

New commits:
commit be441f1a8c40ecbd99653043aa443fc1130d91c2
Author:     Luboš Luňák <[email protected]>
AuthorDate: Mon May 16 13:11:17 2022 +0200
Commit:     Luboš Luňák <[email protected]>
CommitDate: Mon May 16 21:14:47 2022 +0200

    use FontMetric as SalLayoutGlyphsCache key rather than vcl::Font
    
    Apparently even calling OutputDevice::GetFontMetric() rather than
    GetFont() makes a difference with e.g. tdf#65046-1, when only
    vcl::Font is used it triggers the assert in checkGlyphsEqual()
    because of the fonts actually being different.
    
    Change-Id: I2a2aba6bf6d4bf78b7449ccdb16be0746663ee87
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134401
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <[email protected]>

diff --git a/include/vcl/glyphitemcache.hxx b/include/vcl/glyphitemcache.hxx
index 138adb7bb40a..28c38d42ed07 100644
--- a/include/vcl/glyphitemcache.hxx
+++ b/include/vcl/glyphitemcache.hxx
@@ -26,6 +26,7 @@
 #include <o3tl/lru_map.hxx>
 #include <o3tl/hash_combine.hxx>
 #include <vcl/glyphitem.hxx>
+#include <vcl/metric.hxx>
 #include <vcl/outdev.hxx>
 #include <vcl/vclptr.hxx>
 #include <tools/gen.hxx>
@@ -69,7 +70,7 @@ private:
         sal_Int32 index;
         sal_Int32 len;
         tools::Long logicWidth;
-        vcl::Font font;
+        FontMetric fontMetric;
         double fontScaleX;
         double fontScaleY;
         MapMode mapMode;
diff --git a/include/vcl/metric.hxx b/include/vcl/metric.hxx
index b08403da81a3..c8d95f88d6ef 100644
--- a/include/vcl/metric.hxx
+++ b/include/vcl/metric.hxx
@@ -68,7 +68,16 @@ public:
     bool                operator==( const FontMetric& rMetric ) const;
     bool                operator!=( const FontMetric& rMetric ) const
                             { return !operator==( rMetric ); }
+
+    bool                EqualIgnoreColor( const FontMetric& ) const;
+
+    // Compute value usable as hash.
+    size_t              GetHashValue() const;
+    size_t              GetHashValueIgnoreColor() const;
+
 private:
+    bool                EqualNoBase( const FontMetric& ) const;
+    size_t              GetHashValueNoBase() const;
     tools::Long                mnAscent;                      // Ascent
     tools::Long                mnDescent;                     // Descent
     tools::Long                mnIntLeading;                  // Internal 
Leading
diff --git a/vcl/source/font/fontmetric.cxx b/vcl/source/font/fontmetric.cxx
index dfc005b6a9d6..1fddb1195ab7 100644
--- a/vcl/source/font/fontmetric.cxx
+++ b/vcl/source/font/fontmetric.cxx
@@ -78,10 +78,8 @@ FontMetric& FontMetric::operator=(const FontMetric& 
rFontMetric) = default;
 
 FontMetric& FontMetric::operator=(FontMetric&& rFontMetric) = default;
 
-bool FontMetric::operator==( const FontMetric& r ) const
+bool FontMetric::EqualNoBase( const FontMetric& r ) const
 {
-    if( Font::operator!=(r) )
-        return false;
     if (mbFullstopCentered != r.mbFullstopCentered)
         return false;
     if( mnAscent     != r.mnAscent )
@@ -98,6 +96,46 @@ bool FontMetric::operator==( const FontMetric& r ) const
     return true;
 }
 
+bool FontMetric::operator==( const FontMetric& r ) const
+{
+    if( Font::operator!=(r) )
+        return false;
+    return EqualNoBase(r);
+}
+
+bool FontMetric::EqualIgnoreColor( const FontMetric& r ) const
+{
+    if( !Font::EqualIgnoreColor(r) )
+        return false;
+    return EqualNoBase(r);
+}
+
+size_t FontMetric::GetHashValueNoBase() const
+{
+    size_t hash = 0;
+    o3tl::hash_combine( hash, mbFullstopCentered );
+    o3tl::hash_combine( hash, mnAscent );
+    o3tl::hash_combine( hash, mnDescent );
+    o3tl::hash_combine( hash, mnIntLeading );
+    o3tl::hash_combine( hash, mnExtLeading );
+    o3tl::hash_combine( hash, mnSlant );
+    return hash;
+}
+
+size_t FontMetric::GetHashValue() const
+{
+    size_t hash = GetHashValueNoBase();
+    o3tl::hash_combine( hash, Font::GetHashValue());
+    return hash;
+}
+
+size_t FontMetric::GetHashValueIgnoreColor() const
+{
+    size_t hash = GetHashValueNoBase();
+    o3tl::hash_combine( hash, Font::GetHashValueIgnoreColor());
+    return hash;
+}
+
 ImplFontMetricData::ImplFontMetricData( const vcl::font::FontSelectPattern& 
rFontSelData )
     : FontAttributes( rFontSelData )
     , mnHeight ( rFontSelData.mnHeight )
diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx
index 648696a55107..6ab5663ddef6 100644
--- a/vcl/source/gdi/impglyphitem.cxx
+++ b/vcl/source/gdi/impglyphitem.cxx
@@ -450,7 +450,7 @@ SalLayoutGlyphsCache::CachedGlyphsKey::CachedGlyphsKey(
     , logicWidth(w)
     // we also need to save things used in 
OutputDevice::ImplPrepareLayoutArgs(), in case they
     // change in the output device, plus mapMode affects the sizes.
-    , font(outputDevice->GetFont())
+    , fontMetric(outputDevice->GetFontMetric())
     // TODO It would be possible to get a better hit ratio if mapMode wasn't 
part of the key
     // and results that differ only in mapmode would have coordinates adjusted 
based on that.
     // That would occasionally lead to rounding errors (at least differences 
that would
@@ -471,7 +471,7 @@ SalLayoutGlyphsCache::CachedGlyphsKey::CachedGlyphsKey(
     o3tl::hash_combine(hashValue, outputDevice.get());
     // Need to use IgnoreColor, because sometimes the color changes, but it's 
irrelevant
     // for text layout (and also obsolete in vcl::Font).
-    o3tl::hash_combine(hashValue, font.GetHashValueIgnoreColor());
+    o3tl::hash_combine(hashValue, fontMetric.GetHashValueIgnoreColor());
     // For some reason font scale may differ even if vcl::Font is the same,
     // so explicitly check it too.
     o3tl::hash_combine(hashValue, fontScaleX);
@@ -488,7 +488,7 @@ inline bool 
SalLayoutGlyphsCache::CachedGlyphsKey::operator==(const CachedGlyphs
            && logicWidth == other.logicWidth && mapMode == other.mapMode && 
rtl == other.rtl
            && layoutMode == other.layoutMode && digitLanguage == 
other.digitLanguage
            && fontScaleX == other.fontScaleX && fontScaleY == other.fontScaleY
-           && font.EqualIgnoreColor(other.font)
+           && fontMetric.EqualIgnoreColor(other.fontMetric)
            && vcl::text::FastStringCompareEqual()(text, other.text);
     // Slower things last in the comparison.
 }

Reply via email to