From a20a52a2f47c67ab30bf764d420c663f7173f032 Mon Sep 17 00:00:00 2001 From: Chris Sherlock Date: Fri, 25 Dec 2015 00:40:38 +1100 Subject: [PATCH] vcl: PhysicalFontFamily now handles it's own list of font faces The internal linked list has now been removed from PhysicalFontFace and a std::vector is used within PhysicalFontFamily, which is the class that actually should be managing the storage of font face instances. Change-Id: I4f0c5f8831c3f3b60b81b814ca8ea8e2f2e1e7a9 Reviewed-on: https://gerrit.libreoffice.org/20922 Reviewed-by: Chris Sherlock Tested-by: Chris Sherlock --- vcl/inc/PhysicalFontFace.hxx | 2 - vcl/inc/PhysicalFontFamily.hxx | 5 +- vcl/source/font/PhysicalFontFace.cxx | 1 - vcl/source/font/PhysicalFontFamily.cxx | 123 +++++++++++++------------ 4 files changed, 65 insertions(+), 66 deletions(-) diff --git a/vcl/inc/PhysicalFontFace.hxx b/vcl/inc/PhysicalFontFace.hxx index 4c3f04b7c928..aed2f031b20a 100644 --- a/vcl/inc/PhysicalFontFace.hxx +++ b/vcl/inc/PhysicalFontFace.hxx @@ -60,7 +60,6 @@ public: int GetFontMagic() const { return mnMagic; } bool IsScalable() const { return (mnHeight == 0); } bool CheckMagic( int n ) const { return (n == mnMagic); } - PhysicalFontFace* GetNextFace() const { return mpNext; } bool IsBetterMatch( const FontSelectPattern&, FontMatchStatus& ) const; sal_Int32 CompareWithSize( const PhysicalFontFace& ) const; @@ -78,7 +77,6 @@ protected: private: friend class PhysicalFontFamily; const int mnMagic; // poor man's RTTI - PhysicalFontFace* mpNext; }; #endif // INCLUDED_VCL_INC_PHYSICALFONTFACE_HXX diff --git a/vcl/inc/PhysicalFontFamily.hxx b/vcl/inc/PhysicalFontFamily.hxx index 8c38586d40af..b3ba21b7ccc8 100644 --- a/vcl/inc/PhysicalFontFamily.hxx +++ b/vcl/inc/PhysicalFontFamily.hxx @@ -52,7 +52,7 @@ public: ImplFontAttrs GetMatchType() const { return mnMatchType ; } FontWeight GetMatchWeight() const { return meMatchWeight ; } FontWidth GetMatchWidth() const { return meMatchWidth ; } - bool IsScalable() const { return mpFirst->IsScalable(); } + bool IsScalable() const { return maFontFaces[0]->IsScalable(); } int GetMinQuality() const { return mnMinQuality; } int GetTypeFaces() const { return mnTypeFaces; } bool AddFontFace( PhysicalFontFace* ); @@ -69,7 +69,8 @@ static void CalcType( ImplFontAttrs& rType, FontWeight& rWeight, Fon FontFamily eFamily, const utl::FontNameAttr* pFontAttr ); private: - PhysicalFontFace* mpFirst; // linked list of physical font faces + std::vector< PhysicalFontFace* > maFontFaces; + OUString maName; // Fontname (original font family name) OUString maSearchName; // normalized font family name OUString maMapNames; // fontname aliases diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx index b93022333635..d263cf847a45 100644 --- a/vcl/source/font/PhysicalFontFace.cxx +++ b/vcl/source/font/PhysicalFontFace.cxx @@ -30,7 +30,6 @@ PhysicalFontFace::PhysicalFontFace( const ImplDevFontAttributes& rDFA, int nMagi , mnWidth(0) , mnHeight(0) , mnMagic( nMagic ) - , mpNext( nullptr ) { // StarSymbol is a unicode font, but it still deserves the symbol flag if( !IsSymbolFont() ) diff --git a/vcl/source/font/PhysicalFontFamily.cxx b/vcl/source/font/PhysicalFontFamily.cxx index 83f2ab07e99e..c58f38b5c64d 100644 --- a/vcl/source/font/PhysicalFontFamily.cxx +++ b/vcl/source/font/PhysicalFontFamily.cxx @@ -90,8 +90,7 @@ static ImplFontAttrs lcl_IsCJKFont( const OUString& rFontName ) } PhysicalFontFamily::PhysicalFontFamily( const OUString& rSearchName ) -: mpFirst( nullptr ), - maSearchName( rSearchName ), +: maSearchName( rSearchName ), mnTypeFaces( 0 ), mnMatchType( ImplFontAttrs::None ), meMatchWeight( WEIGHT_DONTKNOW ), @@ -104,96 +103,90 @@ PhysicalFontFamily::PhysicalFontFamily( const OUString& rSearchName ) PhysicalFontFamily::~PhysicalFontFamily() { // release all physical font faces - while( mpFirst ) + for( std::vector< PhysicalFontFace* >::iterator it=maFontFaces.begin(); it != maFontFaces.end(); ) { - PhysicalFontFace* pFace = mpFirst; - mpFirst = pFace->GetNextFace(); - delete pFace; + delete *it; + it = maFontFaces.erase( it ); } + } -bool PhysicalFontFamily::AddFontFace( PhysicalFontFace* pNewData ) +bool PhysicalFontFamily::AddFontFace( PhysicalFontFace* pNewFontFace ) { - pNewData->mpNext = nullptr; - - if( !mpFirst ) + if( maFontFaces.empty() ) { - maName = pNewData->GetFamilyName(); - maMapNames = pNewData->maMapNames; - meFamily = pNewData->GetFamilyType(); - mePitch = pNewData->GetPitch(); - mnMinQuality = pNewData->mnQuality; + maName = pNewFontFace->GetFamilyName(); + maMapNames = pNewFontFace->maMapNames; + meFamily = pNewFontFace->GetFamilyType(); + mePitch = pNewFontFace->GetPitch(); + mnMinQuality = pNewFontFace->mnQuality; } else { if( meFamily == FAMILY_DONTKNOW ) - meFamily = pNewData->GetFamilyType(); + meFamily = pNewFontFace->GetFamilyType(); if( mePitch == PITCH_DONTKNOW ) - mePitch = pNewData->GetPitch(); - if( mnMinQuality > pNewData->mnQuality ) - mnMinQuality = pNewData->mnQuality; + mePitch = pNewFontFace->GetPitch(); + if( mnMinQuality > pNewFontFace->mnQuality ) + mnMinQuality = pNewFontFace->mnQuality; } // set attributes for attribute based font matching - if( pNewData->IsScalable() ) + if( pNewFontFace->IsScalable() ) mnTypeFaces |= FONT_FAMILY_SCALABLE; - if( pNewData->IsSymbolFont() ) + if( pNewFontFace->IsSymbolFont() ) mnTypeFaces |= FONT_FAMILY_SYMBOL; else mnTypeFaces |= FONT_FAMILY_NONESYMBOL; - if( pNewData->GetWeight() != WEIGHT_DONTKNOW ) + if( pNewFontFace->GetWeight() != WEIGHT_DONTKNOW ) { - if( pNewData->GetWeight() >= WEIGHT_SEMIBOLD ) + if( pNewFontFace->GetWeight() >= WEIGHT_SEMIBOLD ) mnTypeFaces |= FONT_FAMILY_BOLD; - else if( pNewData->GetWeight() <= WEIGHT_SEMILIGHT ) + else if( pNewFontFace->GetWeight() <= WEIGHT_SEMILIGHT ) mnTypeFaces |= FONT_FAMILY_LIGHT; else mnTypeFaces |= FONT_FAMILY_NORMAL; } - if( pNewData->GetSlant() == ITALIC_NONE ) + if( pNewFontFace->GetSlant() == ITALIC_NONE ) mnTypeFaces |= FONT_FAMILY_NONEITALIC; - else if( (pNewData->GetSlant() == ITALIC_NORMAL) - || (pNewData->GetSlant() == ITALIC_OBLIQUE) ) + else if( (pNewFontFace->GetSlant() == ITALIC_NORMAL) + || (pNewFontFace->GetSlant() == ITALIC_OBLIQUE) ) mnTypeFaces |= FONT_FAMILY_ITALIC; // reassign name (sharing saves memory) - if( pNewData->GetFamilyName() == GetFamilyName() ) - pNewData->SetFamilyName( GetFamilyName() ); + if( pNewFontFace->GetFamilyName() == GetFamilyName() ) + pNewFontFace->SetFamilyName( GetFamilyName() ); // insert new physical font face into linked list // TODO: get rid of linear search? - PhysicalFontFace* pData; - PhysicalFontFace** ppHere = &mpFirst; - for(; (pData=*ppHere) != nullptr; ppHere=&pData->mpNext ) + for(std::vector< PhysicalFontFace* >::iterator it=maFontFaces.begin(); it != maFontFaces.end(); ++it ) { - sal_Int32 eComp = pNewData->CompareWithSize( *pData ); + PhysicalFontFace* pFoundFontFace = *it; + sal_Int32 eComp = pNewFontFace->CompareWithSize( *pFoundFontFace ); if( eComp > 0 ) continue; if( eComp < 0 ) break; // ignore duplicate if its quality is worse - if( pNewData->mnQuality < pData->mnQuality ) + if( pNewFontFace->mnQuality < pFoundFontFace->mnQuality ) return false; // keep the device font if its quality is good enough - if( (pNewData->mnQuality == pData->mnQuality) - && (pData->mbDevice || !pNewData->mbDevice) ) + if( (pNewFontFace->mnQuality == pFoundFontFace->mnQuality) && (pFoundFontFace->mbDevice || !pNewFontFace->mbDevice) ) return false; // replace existing font face with a better one - pNewData->mpNext = pData->mpNext; - *ppHere = pNewData; - delete pData; + delete pFoundFontFace; + it = maFontFaces.erase( it ); + maFontFaces.push_back( pNewFontFace ); return true; } - // insert into or append to list of physical font faces - pNewData->mpNext = pData; - *ppHere = pNewData; + maFontFaces.push_back( pNewFontFace ); return true; } @@ -218,16 +211,16 @@ void PhysicalFontFamily::InitMatchData( const utl::FontSubstConfiguration& rFont PhysicalFontFace* PhysicalFontFamily::FindBestFontFace( const FontSelectPattern& rFSD ) const { - if( !mpFirst ) + if( maFontFaces.empty() ) return nullptr; - if( !mpFirst->GetNextFace() ) - return mpFirst; + if( maFontFaces.size() == 1) + return maFontFaces[0]; // FontName+StyleName should map to FamilyName+StyleName const OUString& rSearchName = rFSD.maTargetName; OUString aTargetStyleName; const OUString* pTargetStyleName = nullptr; - if( (rSearchName.getLength() > maSearchName.getLength()) + if((rSearchName.getLength() > maSearchName.getLength()) && rSearchName.startsWith( maSearchName ) ) { aTargetStyleName = rSearchName.copy(maSearchName.getLength() + 1); @@ -235,12 +228,14 @@ PhysicalFontFace* PhysicalFontFamily::FindBestFontFace( const FontSelectPattern& } // TODO: linear search improve! - PhysicalFontFace* pFontFace = mpFirst; - PhysicalFontFace* pBestFontFace = pFontFace; + PhysicalFontFace* pBestFontFace = maFontFaces[0]; FontMatchStatus aFontMatchStatus = {0,0,0, pTargetStyleName}; - for(; pFontFace; pFontFace = pFontFace->GetNextFace() ) - if( pFontFace->IsBetterMatch( rFSD, aFontMatchStatus ) ) - pBestFontFace = pFontFace; + for( std::vector< PhysicalFontFace* >::const_iterator it=maFontFaces.begin(); it != maFontFaces.end(); ++it ) + { + PhysicalFontFace* pFoundFontFace = *it; + if( pFoundFontFace->IsBetterMatch( rFSD, aFontMatchStatus ) ) + pBestFontFace = pFoundFontFace; + } return pBestFontFace; } @@ -250,19 +245,23 @@ PhysicalFontFace* PhysicalFontFamily::FindBestFontFace( const FontSelectPattern& void PhysicalFontFamily::UpdateDevFontList( ImplDeviceFontList& rDevFontList ) const { PhysicalFontFace* pPrevFace = nullptr; - for( PhysicalFontFace* pFace = mpFirst; pFace; pFace = pFace->GetNextFace() ) + for(std::vector< PhysicalFontFace* >::const_iterator it=maFontFaces.begin(); it != maFontFaces.end(); ++it ) { - if( !pPrevFace || pFace->CompareIgnoreSize( *pPrevFace ) ) - rDevFontList.Add( pFace ); - pPrevFace = pFace; + PhysicalFontFace* pFoundFontFace = *it; + if( !pPrevFace || pFoundFontFace->CompareIgnoreSize( *pPrevFace ) ) + rDevFontList.Add( pFoundFontFace ); + pPrevFace = pFoundFontFace; } } void PhysicalFontFamily::GetFontHeights( std::set& rHeights ) const { // add all available font heights - for( const PhysicalFontFace* pFace = mpFirst; pFace; pFace = pFace->GetNextFace() ) - rHeights.insert( pFace->GetHeight() ); + for( std::vector< PhysicalFontFace* >::const_iterator it=maFontFaces.begin(); it != maFontFaces.end(); ++it ) + { + PhysicalFontFace *pFoundFontFace = *it; + rHeights.insert( pFoundFontFace->GetHeight() ); + } } void PhysicalFontFamily::UpdateCloneFontList( PhysicalFontCollection& rFontCollection, @@ -272,14 +271,16 @@ void PhysicalFontFamily::UpdateCloneFontList( PhysicalFontCollection& rFontColle OUString aFamilyName = GetEnglishSearchFontName( GetFamilyName() ); PhysicalFontFamily* pFamily = rFontCollection.FindOrCreateFontFamily( aFamilyName ); - for( PhysicalFontFace* pFace = mpFirst; pFace; pFace = pFace->GetNextFace() ) + for( std::vector< PhysicalFontFace* >::const_iterator it=maFontFaces.begin(); it != maFontFaces.end(); ++it ) { - if( bScalable && !pFace->IsScalable() ) + PhysicalFontFace *pFoundFontFace = *it; + + if( bScalable && !pFoundFontFace->IsScalable() ) continue; - if( bEmbeddable && !pFace->IsEmbeddable() && !pFace->IsSubsettable() ) + if( bEmbeddable && !pFoundFontFace->IsEmbeddable() && !pFoundFontFace->IsSubsettable() ) continue; - PhysicalFontFace* pClonedFace = pFace->Clone(); + PhysicalFontFace* pClonedFace = pFoundFontFace->Clone(); assert( pClonedFace->GetFamilyName().replaceAll("-", "").trim() == GetFamilyName().replaceAll("-", "").trim() ); assert( rFontCollection.FindOrCreateFontFamily( GetEnglishSearchFontName( pClonedFace->GetFamilyName() ) ) == pFamily );