Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


So 8c023fd645c8b83637ffcde4055886b2e4f94393 should fix a performance
regression with font fallback under fontconfig using platforms when a
font is missing.

This may be a duplicate of MAB fdo#44719. Fontconfig is fairly slow on
finding a replacement font so proposed solution is to cache the results.

We used to cache the results, but we cached only on missing fontname ->
replacement fontname in the past which means we would run into a range
of other problems e.g. fontconfig can suggest as a replacement for an
upright font the *italic* face of an existing font and other
combinations. fdo#41556

So new solution basically restores the cache, but refactors out the font
attributes we know about and use that as the thing to map rather than
just the name.

3.5 and 3.6 patches to fix merge conflicts attached

C.
From fad03eaf8870b7ca2f679e5351cbf451a802cdd9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Tue, 19 Jun 2012 22:23:33 +0100
Subject: [PATCH] Resolves: fdo#47636 cache fontconfig font substitutions

But this time cache on *all* properties, not just the name, which doesn't cut
it, given the things fontconfig can do, e.g. fdo#41556

(cherry picked from commit 8c023fd645c8b83637ffcde4055886b2e4f94393)

Conflicts:
        vcl/inc/outfont.hxx
        vcl/source/gdi/outdev3.cxx

Change-Id: Idfc1dbac67b6912e4985570a0b7c6ccdf47fa4a5
---
 vcl/generic/fontmanager/fontsubst.cxx |   59 ++++++++++--
 vcl/inc/outfont.hxx                   |   38 ++++++--
 vcl/source/gdi/outdev3.cxx            |  165 +++++++++++++++++++++++++--------
 3 files changed, 210 insertions(+), 52 deletions(-)

diff --git a/vcl/generic/fontmanager/fontsubst.cxx b/vcl/generic/fontmanager/fontsubst.cxx
index 4f3ec48..3f51fe5 100644
--- a/vcl/generic/fontmanager/fontsubst.cxx
+++ b/vcl/generic/fontmanager/fontsubst.cxx
@@ -42,15 +42,27 @@
 #include "salprn.hxx"
 #include "region.h"
 
+#include <list>
+
 // ===========================================================================
 // platform specific font substitution hooks
 // ===========================================================================
 
+struct FontSelectPatternAttributesHash
+{
+    size_t operator()(const FontSelectPatternAttributes& rAttributes) const
+        { return rAttributes.hashCode(); }
+};
+
 class FcPreMatchSubstititution
 :   public ImplPreMatchFontSubstitution
 {
 public:
     bool FindFontSubstitute( FontSelectPattern& ) const;
+    typedef ::std::pair<FontSelectPatternAttributes, FontSelectPatternAttributes> value_type;
+private:
+    typedef ::std::list<value_type> CachedFontMapType;
+    mutable CachedFontMapType maCachedFontMap;
 };
 
 class FcGlyphFallbackSubstititution
@@ -135,6 +147,19 @@ namespace
             rOrig.meWidthType == rNew.meWidthType
           );
     }
+
+    class equal
+    {
+    private:
+        const FontSelectPatternAttributes& mrAttributes;
+    public:
+        equal(const FontSelectPatternAttributes& rAttributes)
+            : mrAttributes(rAttributes)
+        {
+        }
+        bool operator()(const FcPreMatchSubstititution::value_type& rOther) const
+            { return rOther.first == mrAttributes; }
+    };
 }
 
 //--------------------------------------------------------------------------
@@ -149,11 +174,26 @@ bool FcPreMatchSubstititution::FindFontSubstitute( FontSelectPattern 
&rFontSelDa
     ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
         return false;
 
-    //Note: see fdo#41556 if you feel compelled to cache the results here,
-    //remember that fontconfig can return e.g. an italic font for a non-italic
-    //input and/or different fonts depending on fontsize, bold, etc settings so
-    //don't cache just on the name, cache on all the input and don't just
-    //return the original selection data with the fontname updated
+    //see fdo#41556 and fdo#47636
+    //fontconfig can return e.g. an italic font for a non-italic input and/or
+    //different fonts depending on fontsize, bold, etc settings so don't cache
+    //just on the name, cache map all the input and all the output not just map
+    //from original selection to output fontname
+    FontSelectPatternAttributes& rPatternAttributes = rFontSelData;
+    CachedFontMapType &rCachedFontMap = const_cast<CachedFontMapType &>(maCachedFontMap);
+    CachedFontMapType::iterator itr = std::find_if(rCachedFontMap.begin(), rCachedFontMap.end(), 
equal(rPatternAttributes));
+    if (itr != rCachedFontMap.end())
+    {
+        // Cached substitution
+        rFontSelData.copyAttributes(itr->second);
+        if (itr != rCachedFontMap.begin())
+        {
+            // MRU, move it to the front
+            rCachedFontMap.splice(rCachedFontMap.begin(), rCachedFontMap, itr);
+        }
+        return true;
+    }
+
     rtl::OUString aDummy;
     const FontSelectPattern aOut = GetFcSubstitute( rFontSelData, aDummy );
 
@@ -178,7 +218,14 @@ bool FcPreMatchSubstititution::FindFontSubstitute( FontSelectPattern 
&rFontSelDa
 #endif
 
     if( bHaveSubstitute )
+    {
+        rCachedFontMap.push_front(value_type(rFontSelData, aOut));
+        //fairly arbitrary limit in this case, but I recall measuring max 8
+        //fonts as the typical max amount of fonts in medium sized documents
+        if (rCachedFontMap.size() > 8)
+            rCachedFontMap.pop_back();
         rFontSelData = aOut;
+    }
 
     return bHaveSubstitute;
 }
@@ -190,7 +237,7 @@ bool FcGlyphFallbackSubstititution::FindFontSubstitute( FontSelectPattern& rFont
 {
     // We dont' actually want to talk to Fontconfig at all for symbol fonts
     if( rFontSelData.IsSymbolFont() )
-    return false;
+        return false;
     // StarSymbol is a unicode font, but it still deserves the symbol flag
     if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10)
     ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
diff --git a/vcl/inc/outfont.hxx b/vcl/inc/outfont.hxx
index 19c2c3a..0702778 100644
--- a/vcl/inc/outfont.hxx
+++ b/vcl/inc/outfont.hxx
@@ -71,6 +71,12 @@ public: // TODO: create matching interface class
     FontWidth       GetWidthType() const    { return meWidthType; }
     bool            IsSymbolFont() const    { return mbSymbolFlag; }
 
+    bool operator==(const ImplFontAttributes& rOther) const;
+    bool operator!=(const ImplFontAttributes& rOther) const
+    {
+        return !(*this == rOther);
+    }
+
 public: // TODO: hide members behind accessor methods
     String          maName;         // Font Family Name
     String          maStyleName;    // Font Style Name
@@ -152,24 +158,27 @@ friend class ImplDevFontListData;
     ImplFontData*           mpNext;
 };
 
-// ----------------------
-// - FontSelectPattern -
-// ----------------------
-
-class FontSelectPattern : public ImplFontAttributes
+class FontSelectPatternAttributes : public ImplFontAttributes
 {
 public:
-                        FontSelectPattern( const Font&, const String& rSearchName,
+                        FontSelectPatternAttributes( const Font&, const String& rSearchName,
                             const Size&, float fExactHeight );
-                        FontSelectPattern( const ImplFontData&, const Size&,
+                        FontSelectPatternAttributes( const ImplFontData&, const Size&,
                             float fExactHeight, int nOrientation, bool bVertical );
 
-public: // TODO: change to private
+    size_t              hashCode() const;
+    bool operator==(const FontSelectPatternAttributes& rOther) const;
+    bool operator!=(const FontSelectPatternAttributes& rOther) const
+    {
+        return !(*this == rOther);
+    }
+
+public:
     String              maTargetName;       // name of the font name token that is chosen
     String              maSearchName;       // name of the font that matches best
     int                 mnWidth;            // width of font in pixel units
     int                 mnHeight;           // height of font in pixel units
-    float               mfExactHeight;       // requested height (in pixels with subpixel details)
+    float               mfExactHeight;      // requested height (in pixels with subpixel details)
     int                 mnOrientation;      // text orientation in 3600 system
     LanguageType        meLanguage;         // text language
     bool                mbVertical;         // vertical mode of requested font
@@ -177,9 +186,20 @@ public: // TODO: change to private
 
     bool                mbEmbolden;         // Force emboldening
     ItalicMatrix        maItalicMatrix;     // Force matrix for slant
+};
 
+class FontSelectPattern : public FontSelectPatternAttributes
+{
+public:
+                        FontSelectPattern( const Font&, const String& rSearchName,
+                            const Size&, float fExactHeight );
+                        FontSelectPattern( const ImplFontData&, const Size&,
+                            float fExactHeight, int nOrientation, bool bVertical );
+
+public: // TODO: change to private
     const ImplFontData* mpFontData;         // a matching ImplFontData object
     ImplFontEntry*      mpFontEntry;        // pointer to the resulting FontCache entry
+    void copyAttributes(const FontSelectPatternAttributes &rAttributes);
 };
 
 // -------------------
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index 06d04cc..261f14a 100644
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -2139,21 +2139,17 @@ ImplGetDevSizeList* ImplDevFontList::GetDevSizeList( const String& 
rFontName ) c
     return pGetDevSizeList;
 }
 
-// =======================================================================
-
-FontSelectPattern::FontSelectPattern( const Font& rFont,
-    const String& rSearchName, const Size& rSize, float fExactHeight)
-:   maSearchName( rSearchName ),
-    mnWidth( rSize.Width() ),
-    mnHeight( rSize.Height() ),
-    mfExactHeight( fExactHeight),
-    mnOrientation( rFont.GetOrientation() ),
-    meLanguage( rFont.GetLanguage() ),
-    mbVertical( rFont.IsVertical() ),
-    mbNonAntialiased( false ),
-    mbEmbolden( false ),
-    mpFontData( NULL ),
-    mpFontEntry( NULL )
+FontSelectPatternAttributes::FontSelectPatternAttributes( const Font& rFont,
+    const String& rSearchName, const Size& rSize, float fExactHeight )
+    : maSearchName( rSearchName )
+    , mnWidth( rSize.Width() )
+    , mnHeight( rSize.Height() )
+    , mfExactHeight( fExactHeight)
+    , mnOrientation( rFont.GetOrientation() )
+    , meLanguage( rFont.GetLanguage() )
+    , mbVertical( rFont.IsVertical() )
+    , mbNonAntialiased( false )
+    , mbEmbolden( false )
 {
     maTargetName = maName;
 
@@ -2175,51 +2171,115 @@ FontSelectPattern::FontSelectPattern( const Font& rFont,
         mnWidth = -mnWidth;
 }
 
-// -----------------------------------------------------------------------
+FontSelectPattern::FontSelectPattern( const Font& rFont,
+    const String& rSearchName, const Size& rSize, float fExactHeight)
+    : FontSelectPatternAttributes(rFont, rSearchName, rSize, fExactHeight)
+    , mpFontData( NULL )
+    , mpFontEntry( NULL )
+{
+}
+
 // NOTE: this ctor is still used on Windows. Do not remove.
-FontSelectPattern::FontSelectPattern( const ImplFontData& rFontData,
+FontSelectPatternAttributes::FontSelectPatternAttributes( const ImplFontData& rFontData,
     const Size& rSize, float fExactHeight, int nOrientation, bool bVertical )
-:   ImplFontAttributes( rFontData ),
-    mnWidth( rSize.Width() ),
-    mnHeight( rSize.Height() ),
-    mfExactHeight( fExactHeight ),
-    mnOrientation( nOrientation ),
-    meLanguage( 0 ),
-    mbVertical( bVertical ),
-    mbNonAntialiased( false ),
-    mbEmbolden( false ),
-    mpFontData( &rFontData ),
-    mpFontEntry( NULL )
+    : ImplFontAttributes( rFontData )
+    , mnWidth( rSize.Width() )
+    , mnHeight( rSize.Height() )
+    , mfExactHeight( fExactHeight )
+    , mnOrientation( nOrientation )
+    , meLanguage( 0 )
+    , mbVertical( bVertical )
+    , mbNonAntialiased( false )
+    , mbEmbolden( false )
 {
     maTargetName = maSearchName = maName;
     // NOTE: no normalization for width/height/orientation
 }
 
+FontSelectPattern::FontSelectPattern( const ImplFontData& rFontData,
+    const Size& rSize, float fExactHeight, int nOrientation, bool bVertical )
+    : FontSelectPatternAttributes(rFontData, rSize, fExactHeight, nOrientation, bVertical)
+    , mpFontData( &rFontData )
+    , mpFontEntry( NULL )
+{
+}
+
+void FontSelectPattern::copyAttributes(const FontSelectPatternAttributes &rAttributes)
+{
+    static_cast<FontSelectPatternAttributes&>(*this) = rAttributes;
+}
+
 // =======================================================================
 
 size_t ImplFontCache::IFSD_Hash::operator()( const FontSelectPattern& rFSD ) const
 {
+    return rFSD.hashCode();
+}
+
+size_t FontSelectPatternAttributes::hashCode() const
+{
     // TODO: does it pay off to improve this hash function?
     static FontNameHash aFontNameHash;
-    size_t nHash = aFontNameHash( rFSD.maSearchName );
+    size_t nHash = aFontNameHash( maSearchName );
 #ifdef ENABLE_GRAPHITE
     // check for features and generate a unique hash if necessary
-    if (rFSD.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX)
+    if (maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX)
         != STRING_NOTFOUND)
     {
-        nHash = aFontNameHash( rFSD.maTargetName );
+        nHash = aFontNameHash( maTargetName );
     }
 #endif
-    nHash += 11 * rFSD.mnHeight;
-    nHash += 19 * rFSD.meWeight;
-    nHash += 29 * rFSD.meItalic;
-    nHash += 37 * rFSD.mnOrientation;
-    nHash += 41 * rFSD.meLanguage;
-    if( rFSD.mbVertical )
+    nHash += 11 * mnHeight;
+    nHash += 19 * meWeight;
+    nHash += 29 * meItalic;
+    nHash += 37 * mnOrientation;
+    nHash += 41 * meLanguage;
+    if( mbVertical )
         nHash += 53;
     return nHash;
 }
 
+bool FontSelectPatternAttributes::operator==(const FontSelectPatternAttributes& rOther) const
+{
+    if (static_cast<const ImplFontAttributes&>(*this) != static_cast<const 
ImplFontAttributes&>(rOther))
+        return false;
+
+    if (maTargetName != rOther.maTargetName)
+        return false;
+
+    if (maSearchName != rOther.maSearchName)
+        return false;
+
+    if (mnWidth != rOther.mnWidth)
+        return false;
+
+    if (mnHeight != rOther.mnHeight)
+        return false;
+
+    if (mfExactHeight != rOther.mfExactHeight)
+        return false;
+
+    if (mnOrientation != rOther.mnOrientation)
+        return false;
+
+    if (meLanguage != rOther.meLanguage)
+        return false;
+
+    if (mbVertical != rOther.mbVertical)
+        return false;
+
+    if (mbNonAntialiased != rOther.mbNonAntialiased)
+        return false;
+
+    if (mbEmbolden != rOther.mbEmbolden)
+        return false;
+
+    if (maItalicMatrix != rOther.maItalicMatrix)
+        return false;
+
+    return true;
+}
+
 // -----------------------------------------------------------------------
 
 bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const FontSelectPattern& 
rB) const
@@ -3345,6 +3405,37 @@ void OutputDevice::ImplInitAboveTextLineSize()
 
 // -----------------------------------------------------------------------
 
+bool ImplFontAttributes::operator==(const ImplFontAttributes& rOther) const
+{
+    if (maName != rOther.maName)
+        return false;
+
+    if (maStyleName != rOther.maStyleName)
+        return false;
+
+    if (meWeight != rOther.meWeight)
+        return false;
+
+    if (meItalic != rOther.meItalic)
+        return false;
+
+    if (meFamily != rOther.meFamily)
+        return false;
+
+    if (mePitch != rOther.mePitch)
+        return false;
+
+    if (meWidthType != rOther.meWidthType)
+        return false;
+
+    if (mbSymbolFlag != rOther.mbSymbolFlag)
+        return false;
+
+    return true;
+}
+
+// -----------------------------------------------------------------------
+
 ImplFontMetricData::ImplFontMetricData( const FontSelectPattern& rFontSelData )
 :   ImplFontAttributes( rFontSelData )
 {
-- 
1.7.10.2

From b460bc682f8f0fb5faf972c7bf02b684e1b4c0b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Tue, 19 Jun 2012 22:23:33 +0100
Subject: [PATCH] Resolves: fdo#47636 cache fontconfig font substitutions

But this time cache on *all* properties, not just the name, which doesn't cut
it, given the things fontconfig can do, e.g. fdo#41556

(cherry picked from commit 8c023fd645c8b83637ffcde4055886b2e4f94393)

Conflicts:
        vcl/generic/fontmanager/fontsubst.cxx
        vcl/inc/outfont.hxx
        vcl/source/gdi/outdev3.cxx

Change-Id: Idfc1dbac67b6912e4985570a0b7c6ccdf47fa4a5
---
 vcl/generic/fontmanager/fontsubst.cxx |   59 ++++++++++--
 vcl/inc/outfont.hxx                   |   38 ++++++--
 vcl/source/gdi/outdev3.cxx            |  165 +++++++++++++++++++++++++--------
 3 files changed, 210 insertions(+), 52 deletions(-)

diff --git a/vcl/generic/fontmanager/fontsubst.cxx b/vcl/generic/fontmanager/fontsubst.cxx
index 3e1cafc..188e628 100644
--- a/vcl/generic/fontmanager/fontsubst.cxx
+++ b/vcl/generic/fontmanager/fontsubst.cxx
@@ -42,15 +42,27 @@
 #include "salprn.hxx"
 #include "region.h"
 
+#include <list>
+
 // ===========================================================================
 // platform specific font substitution hooks
 // ===========================================================================
 
+struct FontSelectPatternAttributesHash
+{
+    size_t operator()(const FontSelectPatternAttributes& rAttributes) const
+        { return rAttributes.hashCode(); }
+};
+
 class FcPreMatchSubstititution
 :   public ImplPreMatchFontSubstitution
 {
 public:
     bool FindFontSubstitute( FontSelectPattern& ) const;
+    typedef ::std::pair<FontSelectPatternAttributes, FontSelectPatternAttributes> value_type;
+private:
+    typedef ::std::list<value_type> CachedFontMapType;
+    mutable CachedFontMapType maCachedFontMap;
 };
 
 class FcGlyphFallbackSubstititution
@@ -135,6 +147,19 @@ namespace
             rOrig.meWidthType == rNew.meWidthType
           );
     }
+
+    class equal
+    {
+    private:
+        const FontSelectPatternAttributes& mrAttributes;
+    public:
+        equal(const FontSelectPatternAttributes& rAttributes)
+            : mrAttributes(rAttributes)
+        {
+        }
+        bool operator()(const FcPreMatchSubstititution::value_type& rOther) const
+            { return rOther.first == mrAttributes; }
+    };
 }
 
 //--------------------------------------------------------------------------
@@ -149,11 +174,26 @@ bool FcPreMatchSubstititution::FindFontSubstitute( FontSelectPattern 
&rFontSelDa
     ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
         return false;
 
-    //Note: see fdo#41556 if you feel compelled to cache the results here,
-    //remember that fontconfig can return e.g. an italic font for a non-italic
-    //input and/or different fonts depending on fontsize, bold, etc settings so
-    //don't cache just on the name, cache on all the input and be don't just
-    //return the original selection data with the fontname updated
+    //see fdo#41556 and fdo#47636
+    //fontconfig can return e.g. an italic font for a non-italic input and/or
+    //different fonts depending on fontsize, bold, etc settings so don't cache
+    //just on the name, cache map all the input and all the output not just map
+    //from original selection to output fontname
+    FontSelectPatternAttributes& rPatternAttributes = rFontSelData;
+    CachedFontMapType &rCachedFontMap = const_cast<CachedFontMapType &>(maCachedFontMap);
+    CachedFontMapType::iterator itr = std::find_if(rCachedFontMap.begin(), rCachedFontMap.end(), 
equal(rPatternAttributes));
+    if (itr != rCachedFontMap.end())
+    {
+        // Cached substitution
+        rFontSelData.copyAttributes(itr->second);
+        if (itr != rCachedFontMap.begin())
+        {
+            // MRU, move it to the front
+            rCachedFontMap.splice(rCachedFontMap.begin(), rCachedFontMap, itr);
+        }
+        return true;
+    }
+
     rtl::OUString aDummy;
     const FontSelectPattern aOut = GetFcSubstitute( rFontSelData, aDummy );
 
@@ -176,7 +216,14 @@ bool FcPreMatchSubstititution::FindFontSubstitute( FontSelectPattern 
&rFontSelDa
 #endif
 
     if( bHaveSubstitute )
+    {
+        rCachedFontMap.push_front(value_type(rFontSelData, aOut));
+        //fairly arbitrary limit in this case, but I recall measuring max 8
+        //fonts as the typical max amount of fonts in medium sized documents
+        if (rCachedFontMap.size() > 8)
+            rCachedFontMap.pop_back();
         rFontSelData = aOut;
+    }
 
     return bHaveSubstitute;
 }
@@ -188,7 +235,7 @@ bool FcGlyphFallbackSubstititution::FindFontSubstitute( FontSelectPattern& rFont
 {
     // We dont' actually want to talk to Fontconfig at all for symbol fonts
     if( rFontSelData.IsSymbolFont() )
-    return false;
+        return false;
     // StarSymbol is a unicode font, but it still deserves the symbol flag
     if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10)
     ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
diff --git a/vcl/inc/outfont.hxx b/vcl/inc/outfont.hxx
index 75871da..3145210 100644
--- a/vcl/inc/outfont.hxx
+++ b/vcl/inc/outfont.hxx
@@ -71,6 +71,12 @@ public: // TODO: create matching interface class
     FontWidth       GetWidthType() const    { return meWidthType; }
     bool            IsSymbolFont() const    { return mbSymbolFlag; }
 
+    bool operator==(const ImplFontAttributes& rOther) const;
+    bool operator!=(const ImplFontAttributes& rOther) const
+    {
+        return !(*this == rOther);
+    }
+
 public: // TODO: hide members behind accessor methods
     String          maName;         // Font Family Name
     String          maStyleName;    // Font Style Name
@@ -152,24 +158,27 @@ friend class ImplDevFontListData;
     ImplFontData*           mpNext;
 };
 
-// ----------------------
-// - FontSelectPattern -
-// ----------------------
-
-class FontSelectPattern : public ImplFontAttributes
+class FontSelectPatternAttributes : public ImplFontAttributes
 {
 public:
-                        FontSelectPattern( const Font&, const String& rSearchName,
+                        FontSelectPatternAttributes( const Font&, const String& rSearchName,
                             const Size&, float fExactHeight );
-                        FontSelectPattern( const ImplFontData&, const Size&,
+                        FontSelectPatternAttributes( const ImplFontData&, const Size&,
                             float fExactHeight, int nOrientation, bool bVertical );
 
-public: // TODO: change to private
+    size_t              hashCode() const;
+    bool operator==(const FontSelectPatternAttributes& rOther) const;
+    bool operator!=(const FontSelectPatternAttributes& rOther) const
+    {
+        return !(*this == rOther);
+    }
+
+public:
     String              maTargetName;       // name of the font name token that is chosen
     String              maSearchName;       // name of the font that matches best
     int                 mnWidth;            // width of font in pixel units
     int                 mnHeight;           // height of font in pixel units
-    float               mfExactHeight;       // requested height (in pixels with subpixel details)
+    float               mfExactHeight;      // requested height (in pixels with subpixel details)
     int                 mnOrientation;      // text orientation in 3600 system
     LanguageType        meLanguage;         // text language
     bool                mbVertical;         // vertical mode of requested font
@@ -177,9 +186,20 @@ public: // TODO: change to private
 
     bool                mbEmbolden;         // Force emboldening
     ItalicMatrix        maItalicMatrix;     // Force matrix for slant
+};
 
+class FontSelectPattern : public FontSelectPatternAttributes
+{
+public:
+                        FontSelectPattern( const Font&, const String& rSearchName,
+                            const Size&, float fExactHeight );
+                        FontSelectPattern( const ImplFontData&, const Size&,
+                            float fExactHeight, int nOrientation, bool bVertical );
+
+public: // TODO: change to private
     const ImplFontData* mpFontData;         // a matching ImplFontData object
     ImplFontEntry*      mpFontEntry;        // pointer to the resulting FontCache entry
+    void copyAttributes(const FontSelectPatternAttributes &rAttributes);
 };
 
 // -------------------
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index e359281..2e2f373 100755
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -2151,21 +2151,17 @@ ImplGetDevSizeList* ImplDevFontList::GetDevSizeList( const String& 
rFontName ) c
     return pGetDevSizeList;
 }
 
-// =======================================================================
-
-FontSelectPattern::FontSelectPattern( const Font& rFont,
-    const String& rSearchName, const Size& rSize, float fExactHeight)
-:   maSearchName( rSearchName ),
-    mnWidth( rSize.Width() ),
-    mnHeight( rSize.Height() ),
-    mfExactHeight( fExactHeight),
-    mnOrientation( rFont.GetOrientation() ),
-    meLanguage( rFont.GetLanguage() ),
-    mbVertical( rFont.IsVertical() ),
-    mbNonAntialiased( false ),
-    mbEmbolden( false ),
-    mpFontData( NULL ),
-    mpFontEntry( NULL )
+FontSelectPatternAttributes::FontSelectPatternAttributes( const Font& rFont,
+    const String& rSearchName, const Size& rSize, float fExactHeight )
+    : maSearchName( rSearchName )
+    , mnWidth( rSize.Width() )
+    , mnHeight( rSize.Height() )
+    , mfExactHeight( fExactHeight)
+    , mnOrientation( rFont.GetOrientation() )
+    , meLanguage( rFont.GetLanguage() )
+    , mbVertical( rFont.IsVertical() )
+    , mbNonAntialiased( false )
+    , mbEmbolden( false )
 {
     maTargetName = maName;
 
@@ -2187,51 +2183,115 @@ FontSelectPattern::FontSelectPattern( const Font& rFont,
         mnWidth = -mnWidth;
 }
 
-// -----------------------------------------------------------------------
+FontSelectPattern::FontSelectPattern( const Font& rFont,
+    const String& rSearchName, const Size& rSize, float fExactHeight)
+    : FontSelectPatternAttributes(rFont, rSearchName, rSize, fExactHeight)
+    , mpFontData( NULL )
+    , mpFontEntry( NULL )
+{
+}
 
-FontSelectPattern::FontSelectPattern( const ImplFontData& rFontData,
+// NOTE: this ctor is still used on Windows. Do not remove.
+FontSelectPatternAttributes::FontSelectPatternAttributes( const ImplFontData& rFontData,
     const Size& rSize, float fExactHeight, int nOrientation, bool bVertical )
-:   ImplFontAttributes( rFontData ),
-    mnWidth( rSize.Width() ),
-    mnHeight( rSize.Height() ),
-    mfExactHeight( fExactHeight ),
-    mnOrientation( nOrientation ),
-    meLanguage( 0 ),
-    mbVertical( bVertical ),
-    mbNonAntialiased( false ),
-    mbEmbolden( false ),
-    mpFontData( &rFontData ),
-    mpFontEntry( NULL )
+    : ImplFontAttributes( rFontData )
+    , mnWidth( rSize.Width() )
+    , mnHeight( rSize.Height() )
+    , mfExactHeight( fExactHeight )
+    , mnOrientation( nOrientation )
+    , meLanguage( 0 )
+    , mbVertical( bVertical )
+    , mbNonAntialiased( false )
+    , mbEmbolden( false )
 {
     maTargetName = maSearchName = maName;
     // NOTE: no normalization for width/height/orientation
 }
 
+FontSelectPattern::FontSelectPattern( const ImplFontData& rFontData,
+    const Size& rSize, float fExactHeight, int nOrientation, bool bVertical )
+    : FontSelectPatternAttributes(rFontData, rSize, fExactHeight, nOrientation, bVertical)
+    , mpFontData( &rFontData )
+    , mpFontEntry( NULL )
+{
+}
+
+void FontSelectPattern::copyAttributes(const FontSelectPatternAttributes &rAttributes)
+{
+    static_cast<FontSelectPatternAttributes&>(*this) = rAttributes;
+}
+
 // =======================================================================
 
 size_t ImplFontCache::IFSD_Hash::operator()( const FontSelectPattern& rFSD ) const
 {
+    return rFSD.hashCode();
+}
+
+size_t FontSelectPatternAttributes::hashCode() const
+{
     // TODO: does it pay off to improve this hash function?
     static FontNameHash aFontNameHash;
-    size_t nHash = aFontNameHash( rFSD.maSearchName );
+    size_t nHash = aFontNameHash( maSearchName );
 #ifdef ENABLE_GRAPHITE
     // check for features and generate a unique hash if necessary
-    if (rFSD.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX)
+    if (maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX)
         != STRING_NOTFOUND)
     {
-        nHash = aFontNameHash( rFSD.maTargetName );
+        nHash = aFontNameHash( maTargetName );
     }
 #endif
-    nHash += 11 * rFSD.mnHeight;
-    nHash += 19 * rFSD.meWeight;
-    nHash += 29 * rFSD.meItalic;
-    nHash += 37 * rFSD.mnOrientation;
-    nHash += 41 * rFSD.meLanguage;
-    if( rFSD.mbVertical )
+    nHash += 11 * mnHeight;
+    nHash += 19 * meWeight;
+    nHash += 29 * meItalic;
+    nHash += 37 * mnOrientation;
+    nHash += 41 * meLanguage;
+    if( mbVertical )
         nHash += 53;
     return nHash;
 }
 
+bool FontSelectPatternAttributes::operator==(const FontSelectPatternAttributes& rOther) const
+{
+    if (static_cast<const ImplFontAttributes&>(*this) != static_cast<const 
ImplFontAttributes&>(rOther))
+        return false;
+
+    if (maTargetName != rOther.maTargetName)
+        return false;
+
+    if (maSearchName != rOther.maSearchName)
+        return false;
+
+    if (mnWidth != rOther.mnWidth)
+        return false;
+
+    if (mnHeight != rOther.mnHeight)
+        return false;
+
+    if (mfExactHeight != rOther.mfExactHeight)
+        return false;
+
+    if (mnOrientation != rOther.mnOrientation)
+        return false;
+
+    if (meLanguage != rOther.meLanguage)
+        return false;
+
+    if (mbVertical != rOther.mbVertical)
+        return false;
+
+    if (mbNonAntialiased != rOther.mbNonAntialiased)
+        return false;
+
+    if (mbEmbolden != rOther.mbEmbolden)
+        return false;
+
+    if (maItalicMatrix != rOther.maItalicMatrix)
+        return false;
+
+    return true;
+}
+
 // -----------------------------------------------------------------------
 
 bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const FontSelectPattern& 
rB) const
@@ -3290,6 +3350,37 @@ void OutputDevice::ImplInitAboveTextLineSize()
 
 // -----------------------------------------------------------------------
 
+bool ImplFontAttributes::operator==(const ImplFontAttributes& rOther) const
+{
+    if (maName != rOther.maName)
+        return false;
+
+    if (maStyleName != rOther.maStyleName)
+        return false;
+
+    if (meWeight != rOther.meWeight)
+        return false;
+
+    if (meItalic != rOther.meItalic)
+        return false;
+
+    if (meFamily != rOther.meFamily)
+        return false;
+
+    if (mePitch != rOther.mePitch)
+        return false;
+
+    if (meWidthType != rOther.meWidthType)
+        return false;
+
+    if (mbSymbolFlag != rOther.mbSymbolFlag)
+        return false;
+
+    return true;
+}
+
+// -----------------------------------------------------------------------
+
 ImplFontMetricData::ImplFontMetricData( const FontSelectPattern& rFontSelData )
 :   ImplFontAttributes( rFontSelData )
 {
-- 
1.7.10.2


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.