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?= <caol...@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?= <caol...@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
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice