#i87970# use UCS4+weight as GFB-result cache keys

This commit is contained in:
Herbert Duerr [hdu] 2010-02-26 17:22:21 +01:00
parent baab9baa6a
commit c98d05242a
2 changed files with 24 additions and 15 deletions

View file

@ -335,15 +335,17 @@ public: // TODO: make data members private
short mnOrientation; // text angle in 3600 system
bool mbInit; // true if maMetric member is valid
void AddFallbackForUnicode( sal_UCS4, const String& rFontName );
bool GetFallbackForUnicode( sal_UCS4, String* pFontName ) const;
void IgnoreFallbackForUnicode( sal_UCS4, const String& rFontName );
void AddFallbackForUnicode( sal_UCS4, FontWeight eWeight, const String& rFontName );
bool GetFallbackForUnicode( sal_UCS4, FontWeight eWeight, String* pFontName ) const;
void IgnoreFallbackForUnicode( sal_UCS4, FontWeight eWeight, const String& rFontName );
private:
// cache of Unicode characters and replacement font names
// TODO: a fallback map can be shared with many other ImplFontEntries
// TODO: at least the ones which just differ in orientation, stretching or height
typedef ::std::hash_map<sal_UCS4,String> UnicodeFallbackList;
typedef ::std::pair<sal_UCS4,FontWeight> GFBCacheKey;
struct GFBCacheKey_Hash{ size_t operator()( const GFBCacheKey& ) const; };
typedef ::std::hash_map<GFBCacheKey,String,GFBCacheKey_Hash> UnicodeFallbackList;
UnicodeFallbackList* mpUnicodeFallbackList;
};

View file

@ -998,21 +998,28 @@ ImplFontEntry::~ImplFontEntry()
// -----------------------------------------------------------------------
inline void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, const String& rFontName )
size_t ImplFontEntry::GFBCacheKey_Hash::operator()( const GFBCacheKey& rData ) const
{
std::hash<sal_UCS4> a;
std::hash<int > b;
return a(rData.first) ^ b(rData.second);
}
inline void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const String& rFontName )
{
if( !mpUnicodeFallbackList )
mpUnicodeFallbackList = new UnicodeFallbackList;
(*mpUnicodeFallbackList)[cChar] = rFontName;
(*mpUnicodeFallbackList)[ GFBCacheKey(cChar,eWeight) ] = rFontName;
}
// -----------------------------------------------------------------------
inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, String* pFontName ) const
inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, String* pFontName ) const
{
if( !mpUnicodeFallbackList )
return false;
UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( cChar );
UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) );
if( it == mpUnicodeFallbackList->end() )
return false;
@ -1022,10 +1029,10 @@ inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, String* pFontN
// -----------------------------------------------------------------------
inline void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, const String& rFontName )
inline void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const String& rFontName )
{
// DBG_ASSERT( mpUnicodeFallbackList, "ImplFontEntry::IgnoreFallbackForUnicode no list" );
UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( cChar );
UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) );
// DBG_ASSERT( it != mpUnicodeFallbackList->end(), "ImplFontEntry::IgnoreFallbackForUnicode no match" );
if( it == mpUnicodeFallbackList->end() )
return;
@ -1420,7 +1427,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData&
while( nStrIndex < rMissingCodes.getLength() )
{
cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &rFontSelData.maSearchName );
bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName );
// ignore entries which don't have a fallback
if( !bCached || (rFontSelData.maSearchName.Len() != 0) )
break;
@ -1436,7 +1443,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData&
while( nStrIndex < rMissingCodes.getLength() )
{
cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &aFontName );
bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &aFontName );
if( !bCached || (rFontSelData.maSearchName != aFontName) )
pRemainingCodes[ nRemainingLength++ ] = cChar;
}
@ -1455,8 +1462,8 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData&
// cache the result even if there was no match
for(;;)
{
if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &rFontSelData.maSearchName ) )
rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.maSearchName );
if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ) )
rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
if( nStrIndex >= aOldMissingCodes.getLength() )
break;
cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex );
@ -1467,7 +1474,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData&
for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
{
cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.maSearchName );
rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
}
}
}