vcl/inc/unx/fontmanager.hxx                |    1 
 vcl/unx/generic/fontmanager/fontconfig.cxx |  116 +++++++++++++++++++++++++++--
 vcl/unx/generic/gdi/freetypetextrender.cxx |    1 
 3 files changed, 113 insertions(+), 5 deletions(-)

New commits:
commit a199e4ea389c934d169a178433f4b94033e60f93
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Wed Apr 14 12:25:36 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Wed Apr 14 14:37:08 2021 +0200

    add pitch to the pattern
    
    Change-Id: Ic32527feabb0405f17bd59779cf19553afaa1e7b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114086
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/unx/generic/fontmanager/fontconfig.cxx 
b/vcl/unx/generic/fontmanager/fontconfig.cxx
index 748fbf2d7b9a..689c4816e174 100644
--- a/vcl/unx/generic/fontmanager/fontconfig.cxx
+++ b/vcl/unx/generic/fontmanager/fontconfig.cxx
@@ -63,6 +63,7 @@ struct FontOptionsKey
     FontItalic m_eItalic;
     FontWeight m_eWeight;
     FontWidth m_eWidth;
+    FontPitch m_ePitch;
 
     bool operator==(const FontOptionsKey& rOther) const
     {
@@ -70,7 +71,8 @@ struct FontOptionsKey
                m_nFontSize == rOther.m_nFontSize &&
                m_eItalic == rOther.m_eItalic &&
                m_eWeight == rOther.m_eWeight &&
-               m_eWidth == rOther.m_eWidth;
+               m_eWidth == rOther.m_eWidth &&
+               m_ePitch == rOther.m_ePitch;
     }
 };
 
@@ -88,6 +90,7 @@ template <> struct hash<FontOptionsKey>
         boost::hash_combine(seed, k.m_eItalic);
         boost::hash_combine(seed, k.m_eWeight);
         boost::hash_combine(seed, k.m_eWidth);
+        boost::hash_combine(seed, k.m_ePitch);
         return seed;
     }
 };
@@ -1188,7 +1191,8 @@ void FontConfigFontOptions::SyncPattern(const OString& 
rFileName, sal_uInt32 nIn
 
 std::unique_ptr<FontConfigFontOptions> PrintFontManager::getFontOptions(const 
FontAttributes& rInfo, int nSize)
 {
-    FontOptionsKey aKey{ rInfo.GetFamilyName(), nSize, rInfo.GetItalic(), 
rInfo.GetWeight(), rInfo.GetWidthType() };
+    FontOptionsKey aKey{ rInfo.GetFamilyName(), nSize, rInfo.GetItalic(),
+                         rInfo.GetWeight(), rInfo.GetWidthType(), 
rInfo.GetPitch() };
 
     FontCfgWrapper& rWrapper = FontCfgWrapper::get();
 
@@ -1207,8 +1211,7 @@ std::unique_ptr<FontConfigFontOptions> 
PrintFontManager::getFontOptions(const Fo
     if( !sFamily.isEmpty() )
         FcPatternAddString(pPattern, FC_FAMILY, reinterpret_cast<FcChar8 const 
*>(sFamily.getStr()));
 
-    // TODO: ePitch argument of always PITCH_DONTKNOW is suspicious
-    addtopattern(pPattern, aKey.m_eItalic, aKey.m_eWeight, aKey.m_eWidth, 
PITCH_DONTKNOW);
+    addtopattern(pPattern, aKey.m_eItalic, aKey.m_eWeight, aKey.m_eWidth, 
aKey.m_ePitch);
     FcPatternAddDouble(pPattern, FC_PIXEL_SIZE, nSize);
 
     FcConfigSubstitute(pConfig, pPattern, FcMatchPattern);
commit 3a933fddfdbbe158caac47b9957fb3c8d92506fb
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Wed Apr 14 10:28:36 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Wed Apr 14 14:36:51 2021 +0200

    tdf#140639 cache FcPattern for font options
    
    Change-Id: Ibb1b1e06630e505924e05ea4b5b454e58738d743
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114083
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/inc/unx/fontmanager.hxx b/vcl/inc/unx/fontmanager.hxx
index 0f5a85d61153..9ae95d0493af 100644
--- a/vcl/inc/unx/fontmanager.hxx
+++ b/vcl/inc/unx/fontmanager.hxx
@@ -313,6 +313,7 @@ public:
     void matchFont( FastPrintFontInfo& rInfo, const css::lang::Locale& rLocale 
);
 
     static std::unique_ptr<FontConfigFontOptions> getFontOptions(const 
FontAttributes& rFontAttributes, int nSize);
+    static void clearFontOptionsCache();
 
     void Substitute(FontSelectPattern &rPattern, OUString& rMissingCodes);
 
diff --git a/vcl/unx/generic/fontmanager/fontconfig.cxx 
b/vcl/unx/generic/fontmanager/fontconfig.cxx
index 1ebe39ca4b98..748fbf2d7b9a 100644
--- a/vcl/unx/generic/fontmanager/fontconfig.cxx
+++ b/vcl/unx/generic/fontmanager/fontconfig.cxx
@@ -20,6 +20,7 @@
 #include <memory>
 #include <string_view>
 
+#include <o3tl/lru_map.hxx>
 #include <unx/fontmanager.hxx>
 #include <unx/helper.hxx>
 #include <comphelper/sequence.hxx>
@@ -46,6 +47,7 @@ using namespace psp;
 
 #include <osl/process.h>
 
+#include <boost/functional/hash.hpp>
 #include <utility>
 #include <algorithm>
 
@@ -53,7 +55,92 @@ using namespace osl;
 
 namespace
 {
-    typedef std::pair<FcChar8*, FcChar8*> lang_and_element;
+
+struct FontOptionsKey
+{
+    OUString m_sFamilyName;
+    int m_nFontSize;
+    FontItalic m_eItalic;
+    FontWeight m_eWeight;
+    FontWidth m_eWidth;
+
+    bool operator==(const FontOptionsKey& rOther) const
+    {
+        return m_sFamilyName == rOther.m_sFamilyName &&
+               m_nFontSize == rOther.m_nFontSize &&
+               m_eItalic == rOther.m_eItalic &&
+               m_eWeight == rOther.m_eWeight &&
+               m_eWidth == rOther.m_eWidth;
+    }
+};
+
+}
+
+namespace std
+{
+
+template <> struct hash<FontOptionsKey>
+{
+    std::size_t operator()(const FontOptionsKey& k) const noexcept
+    {
+        std::size_t seed = k.m_sFamilyName.hashCode();
+        boost::hash_combine(seed, k.m_nFontSize);
+        boost::hash_combine(seed, k.m_eItalic);
+        boost::hash_combine(seed, k.m_eWeight);
+        boost::hash_combine(seed, k.m_eWidth);
+        return seed;
+    }
+};
+
+} // end std namespace
+
+namespace
+{
+
+struct FcPatternDeleter
+{
+    void operator()(FcPattern* pPattern) const
+    {
+        FcPatternDestroy(pPattern);
+    }
+};
+
+typedef std::unique_ptr<FcPattern, FcPatternDeleter> FcPatternUniquePtr;
+
+class CachedFontConfigFontOptions
+{
+private:
+    FontOptionsKey m_aKey;
+    std::unique_ptr<FontConfigFontOptions> m_xLastFontOptions;
+
+    o3tl::lru_map<FontOptionsKey, FcPatternUniquePtr> lru_options_cache;
+
+public:
+    CachedFontConfigFontOptions()
+        : lru_options_cache(10) // arbitrary cache size of 10
+    {
+    }
+
+    std::unique_ptr<FontConfigFontOptions> lookup(const FontOptionsKey& rKey)
+    {
+        auto it = lru_options_cache.find(rKey);
+        if (it != lru_options_cache.end())
+            return 
std::make_unique<FontConfigFontOptions>(FcPatternDuplicate(it->second.get()));
+        return nullptr;
+    }
+
+    void cache(const FontOptionsKey& rKey, const FcPattern* pPattern)
+    {
+        lru_options_cache.insert(std::make_pair(rKey, 
FcPatternUniquePtr(FcPatternDuplicate(pPattern))));
+    }
+
+    void clear()
+    {
+        m_xLastFontOptions.reset();
+    }
+};
+
+typedef std::pair<FcChar8*, FcChar8*> lang_and_element;
 
 class FontCfgWrapper
 {
@@ -78,6 +165,7 @@ public:
 //to-do, make private and add some cleaner accessor methods
     std::unordered_map< OString, OString > m_aFontNameToLocalized;
     std::unordered_map< OString, OString > m_aLocalizedToCanonical;
+    CachedFontConfigFontOptions m_aCachedFontOptions;
 private:
     void cacheLocalizedFontNames(const FcChar8 *origfontname, const FcChar8 
*bestfontname, const std::vector< lang_and_element > &lang_and_elements);
 
@@ -369,6 +457,7 @@ void FontCfgWrapper::clear()
         m_pFontSet = nullptr;
     }
     m_pLanguageTag.reset();
+    m_aCachedFontOptions.clear();
 }
 
 /*
@@ -1099,13 +1188,18 @@ void FontConfigFontOptions::SyncPattern(const OString& 
rFileName, sal_uInt32 nIn
 
 std::unique_ptr<FontConfigFontOptions> PrintFontManager::getFontOptions(const 
FontAttributes& rInfo, int nSize)
 {
+    FontOptionsKey aKey{ rInfo.GetFamilyName(), nSize, rInfo.GetItalic(), 
rInfo.GetWeight(), rInfo.GetWidthType() };
+
     FontCfgWrapper& rWrapper = FontCfgWrapper::get();
 
-    std::unique_ptr<FontConfigFontOptions> pOptions;
+    std::unique_ptr<FontConfigFontOptions> pOptions = 
rWrapper.m_aCachedFontOptions.lookup(aKey);
+    if (pOptions)
+        return pOptions;
+
     FcConfig* pConfig = FcConfigGetCurrent();
     FcPattern* pPattern = FcPatternCreate();
 
-    OString sFamily = OUStringToOString( rInfo.GetFamilyName(), 
RTL_TEXTENCODING_UTF8 );
+    OString sFamily = OUStringToOString(aKey.m_sFamilyName, 
RTL_TEXTENCODING_UTF8);
 
     std::unordered_map< OString, OString >::const_iterator aI = 
rWrapper.m_aLocalizedToCanonical.find(sFamily);
     if (aI != rWrapper.m_aLocalizedToCanonical.end())
@@ -1114,7 +1208,7 @@ std::unique_ptr<FontConfigFontOptions> 
PrintFontManager::getFontOptions(const Fo
         FcPatternAddString(pPattern, FC_FAMILY, reinterpret_cast<FcChar8 const 
*>(sFamily.getStr()));
 
     // TODO: ePitch argument of always PITCH_DONTKNOW is suspicious
-    addtopattern(pPattern, rInfo.GetItalic(), rInfo.GetWeight(), 
rInfo.GetWidthType(), PITCH_DONTKNOW);
+    addtopattern(pPattern, aKey.m_eItalic, aKey.m_eWeight, aKey.m_eWidth, 
PITCH_DONTKNOW);
     FcPatternAddDouble(pPattern, FC_PIXEL_SIZE, nSize);
 
     FcConfigSubstitute(pConfig, pPattern, FcMatchPattern);
@@ -1124,7 +1218,10 @@ std::unique_ptr<FontConfigFontOptions> 
PrintFontManager::getFontOptions(const Fo
     FcResult eResult = FcResultNoMatch;
     FcFontSet* pFontSet = rWrapper.getFontSet();
     if (FcPattern* pResult = FcFontSetMatch(pConfig, &pFontSet, 1, pPattern, 
&eResult))
+    {
+        rWrapper.m_aCachedFontOptions.cache(aKey, pResult);
         pOptions.reset(new FontConfigFontOptions(pResult));
+    }
 
     // cleanup
     FcPatternDestroy( pPattern );
@@ -1132,6 +1229,12 @@ std::unique_ptr<FontConfigFontOptions> 
PrintFontManager::getFontOptions(const Fo
     return pOptions;
 }
 
+void PrintFontManager::clearFontOptionsCache()
+{
+    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
+    rWrapper.m_aCachedFontOptions.clear();
+}
+
 void PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const 
css::lang::Locale& rLocale )
 {
     FontCfgWrapper& rWrapper = FontCfgWrapper::get();
diff --git a/vcl/unx/generic/gdi/freetypetextrender.cxx 
b/vcl/unx/generic/gdi/freetypetextrender.cxx
index 0e6556b24588..5f28ebdb91fe 100644
--- a/vcl/unx/generic/gdi/freetypetextrender.cxx
+++ b/vcl/unx/generic/gdi/freetypetextrender.cxx
@@ -101,6 +101,7 @@ bool FreeTypeTextRenderImpl::AddTempDevFont( 
PhysicalFontCollection* pFontCollec
 void FreeTypeTextRenderImpl::ClearDevFontCache()
 {
     FreetypeManager::get().ClearFontCache();
+    psp::PrintFontManager::clearFontOptionsCache();
 }
 
 void FreeTypeTextRenderImpl::GetDevFontList( PhysicalFontCollection* 
pFontCollection )
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to