diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-01-11 11:03:55 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-01-11 14:13:32 +0000 |
commit | 44cf768131e8a06ff688ddfa8b53f144ffb9e4a0 (patch) | |
tree | 4c9aa7008dc88b28ef038a78eb1e8779069819a6 /vcl | |
parent | 42aeb8d9e163361c1b489916370eab7c2a3a391b (diff) |
adapt findFontFileID to know about multiple font faces in a font file
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/generic/fontmanager/fontconfig.cxx | 6 | ||||
-rw-r--r-- | vcl/generic/fontmanager/fontmanager.cxx | 122 | ||||
-rw-r--r-- | vcl/inc/vcl/fontmanager.hxx | 18 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi3.cxx | 30 |
4 files changed, 122 insertions, 54 deletions
diff --git a/vcl/generic/fontmanager/fontconfig.cxx b/vcl/generic/fontmanager/fontconfig.cxx index 0c3655ccb543..d3b1f2b91922 100644 --- a/vcl/generic/fontmanager/fontconfig.cxx +++ b/vcl/generic/fontmanager/fontconfig.cxx @@ -1019,12 +1019,16 @@ bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star //extract the closest match FcChar8* file = NULL; FcResult eFileRes = FcPatternGetString(pSet->fonts[0], FC_FILE, 0, &file); + int nCollectionEntry = 0; + FcResult eIndexRes = FcPatternGetInteger(pSet->fonts[0], FC_INDEX, 0, &nCollectionEntry); + if (eIndexRes != FcResultMatch) + nCollectionEntry = 0; if( eFileRes == FcResultMatch ) { OString aDir, aBase, aOrgPath( (sal_Char*)file ); splitPath( aOrgPath, aDir, aBase ); int nDirID = getDirectoryAtom( aDir, true ); - fontID aFont = findFontFileID( nDirID, aBase ); + fontID aFont = findFontFileID( nDirID, aBase, nCollectionEntry ); if( aFont > 0 ) bSuccess = getFontFastInfo( aFont, rInfo ); } diff --git a/vcl/generic/fontmanager/fontmanager.cxx b/vcl/generic/fontmanager/fontmanager.cxx index 6f57f4b08d34..5ca8694704e8 100644 --- a/vcl/generic/fontmanager/fontmanager.cxx +++ b/vcl/generic/fontmanager/fontmanager.cxx @@ -1253,7 +1253,7 @@ int PrintFontManager::getDirectoryAtom( const OString& rDirectory, bool bCreate // ------------------------------------------------------------------------- -int PrintFontManager::addFontFile( const ::rtl::OString& rFileName ) +std::vector<fontID> PrintFontManager::addFontFile( const ::rtl::OString& rFileName ) { rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); INetURLObject aPath( OStringToOUString( rFileName, aEncoding ), INET_PROT_FILE, INetURLObject::ENCODE_ALL ); @@ -1261,8 +1261,8 @@ int PrintFontManager::addFontFile( const ::rtl::OString& rFileName ) OString aDir( OUStringToOString( aPath.GetPath(), aEncoding ) ); int nDirID = getDirectoryAtom( aDir, true ); - fontID nFontId = findFontFileID( nDirID, aName ); - if( !nFontId ) + std::vector<fontID> aFontIds = findFontFileIDs( nDirID, aName ); + if( aFontIds.empty() ) { ::std::list< PrintFont* > aNewFonts; if( analyzeFontFile( nDirID, aName, ::std::list<OString>(), aNewFonts ) ) @@ -1270,13 +1270,15 @@ int PrintFontManager::addFontFile( const ::rtl::OString& rFileName ) for( ::std::list< PrintFont* >::iterator it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) { - m_aFonts[ nFontId = m_nNextFontID++ ] = *it; + fontID nFontId = m_nNextFontID++; + m_aFonts[nFontId] = *it; m_aFontFileToFontID[ aName ].insert( nFontId ); m_pFontCache->updateFontCacheEntry( *it, true ); + aFontIds.push_back(nFontId); } } } - return nFontId; + return aFontIds; } enum fontFormat @@ -1454,50 +1456,98 @@ fontID PrintFontManager::findFontBuiltinID( int nPSNameAtom ) const // ------------------------------------------------------------------------- -fontID PrintFontManager::findFontFileID( int nDirID, const OString& rFontFile ) const +fontID PrintFontManager::findFontFileID( int nDirID, const OString& rFontFile, int nFaceIndex ) const { fontID nID = 0; ::boost::unordered_map< OString, ::std::set< fontID >, OStringHash >::const_iterator set_it = m_aFontFileToFontID.find( rFontFile ); - if( set_it != m_aFontFileToFontID.end() ) + if( set_it == m_aFontFileToFontID.end() ) + return nID; + + for( ::std::set< fontID >::const_iterator font_it = set_it->second.begin(); font_it != set_it->second.end() && ! nID; ++font_it ) { - for( ::std::set< fontID >::const_iterator font_it = set_it->second.begin(); font_it != set_it->second.end() && ! nID; ++font_it ) + ::boost::unordered_map< fontID, PrintFont* >::const_iterator it = m_aFonts.find( *font_it ); + if( it == m_aFonts.end() ) + continue; + switch( it->second->m_eType ) { - ::boost::unordered_map< fontID, PrintFont* >::const_iterator it = m_aFonts.find( *font_it ); - if( it != m_aFonts.end() ) + case fonttype::Type1: { - switch( it->second->m_eType ) + Type1FontFile* const pFont = static_cast< Type1FontFile* const >((*it).second); + if( pFont->m_nDirectory == nDirID && + pFont->m_aFontFile == rFontFile ) + nID = it->first; + } + break; + case fonttype::TrueType: + { + TrueTypeFontFile* const pFont = static_cast< TrueTypeFontFile* const >((*it).second); + if( pFont->m_nDirectory == nDirID && + pFont->m_aFontFile == rFontFile ) { - case fonttype::Type1: - { - Type1FontFile* const pFont = static_cast< Type1FontFile* const >((*it).second); - if( pFont->m_nDirectory == nDirID && - pFont->m_aFontFile == rFontFile ) - nID = it->first; - } - break; - case fonttype::TrueType: - { - TrueTypeFontFile* const pFont = static_cast< TrueTypeFontFile* const >((*it).second); - if( pFont->m_nDirectory == nDirID && - pFont->m_aFontFile == rFontFile ) - nID = it->first; - } - break; - case fonttype::Builtin: - if( static_cast<const BuiltinFont*>((*it).second)->m_nDirectory == nDirID && - static_cast<const BuiltinFont*>((*it).second)->m_aMetricFile == rFontFile ) - nID = it->first; - break; - default: - break; + fprintf(stderr, "candidate %d vs %d\n", pFont->m_nCollectionEntry, nFaceIndex); + if (pFont->m_nCollectionEntry == nFaceIndex) + nID = it->first; } } + break; + case fonttype::Builtin: + if( static_cast<const BuiltinFont*>((*it).second)->m_nDirectory == nDirID && + static_cast<const BuiltinFont*>((*it).second)->m_aMetricFile == rFontFile ) + nID = it->first; + break; + default: + break; } } + return nID; } +std::vector<fontID> PrintFontManager::findFontFileIDs( int nDirID, const OString& rFontFile ) const +{ + std::vector<fontID> aIds; + + ::boost::unordered_map< OString, ::std::set< fontID >, OStringHash >::const_iterator set_it = m_aFontFileToFontID.find( rFontFile ); + if( set_it == m_aFontFileToFontID.end() ) + return aIds; + + for( ::std::set< fontID >::const_iterator font_it = set_it->second.begin(); font_it != set_it->second.end(); ++font_it ) + { + ::boost::unordered_map< fontID, PrintFont* >::const_iterator it = m_aFonts.find( *font_it ); + if( it == m_aFonts.end() ) + continue; + switch( it->second->m_eType ) + { + case fonttype::Type1: + { + Type1FontFile* const pFont = static_cast< Type1FontFile* const >((*it).second); + if( pFont->m_nDirectory == nDirID && + pFont->m_aFontFile == rFontFile ) + aIds.push_back(it->first); + } + break; + case fonttype::TrueType: + { + TrueTypeFontFile* const pFont = static_cast< TrueTypeFontFile* const >((*it).second); + if( pFont->m_nDirectory == nDirID && + pFont->m_aFontFile == rFontFile ) + aIds.push_back(it->first); + } + break; + case fonttype::Builtin: + if( static_cast<const BuiltinFont*>((*it).second)->m_nDirectory == nDirID && + static_cast<const BuiltinFont*>((*it).second)->m_aMetricFile == rFontFile ) + aIds.push_back(it->first); + break; + default: + break; + } + } + + return aIds; +} + // ------------------------------------------------------------------------- bool PrintFontManager::parseXLFD( const OString& rXLFD, XLFDEntry& rEntry ) @@ -2288,7 +2338,7 @@ void PrintFontManager::initialize() if( ! stat( aFilePath.getStr(), &aStat ) && S_ISREG( aStat.st_mode ) ) { - if( findFontFileID( nDirID, aFileName ) == 0 ) + if (!knownFontFile(nDirID, aFileName)) { ::std::list<OString> aXLFDs; ::boost::unordered_map< OString, ::std::list<OString>, OStringHash >::const_iterator it = @@ -3313,7 +3363,7 @@ int PrintFontManager::importFonts( const ::std::list< OString >& rFiles, bool bL ++current; } - DBG_ASSERT( !findFontFileID( nDirID, aFileName ), "not all fonts removed for file" ); + DBG_ASSERT( !knownFontFile( nDirID, aFileName ), "not all fonts removed for file" ); nSuccess++; for( it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) diff --git a/vcl/inc/vcl/fontmanager.hxx b/vcl/inc/vcl/fontmanager.hxx index b6329083bb0c..f9708c316a64 100644 --- a/vcl/inc/vcl/fontmanager.hxx +++ b/vcl/inc/vcl/fontmanager.hxx @@ -337,9 +337,18 @@ class VCL_PLUGIN_PUBLIC PrintFontManager rtl::OUString convertTrueTypeName( void* pNameRecord ) const; // actually a NameRecord* formt font subsetting code void analyzeTrueTypeFamilyName( void* pTTFont, std::list< rtl::OUString >& rnames ) const; // actually a TrueTypeFont* from font subsetting code bool analyzeTrueTypeFile( PrintFont* pFont ) const; - // finds the FIRST id for this font file; there may be more - // for TrueType collections - fontID findFontFileID( int nDirID, const rtl::OString& rFile ) const; + // finds the font id for the nFaceIndex face in this font file + // There may be multiple font ids for TrueType collections + fontID findFontFileID( int nDirID, const rtl::OString& rFile, int nFaceIndex ) const; + + // There may be multiple font ids for TrueType collections + std::vector<fontID> findFontFileIDs( int nDirID, const rtl::OString& rFile ) const; + + bool knownFontFile( int nDirID, const rtl::OString& rFile ) const + { + return findFontFileID(nDirID, rFile, 0) != 0; + } + fontID findFontBuiltinID( int nPSNameAtom ) const; FontFamily matchFamilyName( const rtl::OUString& rFamily ) const; @@ -390,7 +399,8 @@ class VCL_PLUGIN_PUBLIC PrintFontManager public: static PrintFontManager& get(); // one instance only - int addFontFile( const rtl::OString& rFileName ); + // There may be multiple font ids for TrueType collections + std::vector<fontID> addFontFile( const rtl::OString& rFileName ); void initialize(); diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx index 671e20ed1352..d492df229f52 100644 --- a/vcl/unx/generic/gdi/salgdi3.cxx +++ b/vcl/unx/generic/gdi/salgdi3.cxx @@ -537,24 +537,28 @@ bool X11SalGraphics::AddTempDevFont( ImplDevFontList* pFontList, rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); OString aOFileName( OUStringToOString( aUSystemPath, aEncoding ) ); psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); - int nFontId = rMgr.addFontFile( aOFileName ); - if( !nFontId ) + std::vector<psp::fontID> aFontIds = rMgr.addFontFile( aOFileName ); + if( aFontIds.empty() ) return false; - // prepare font data - psp::FastPrintFontInfo aInfo; - rMgr.getFontFastInfo( nFontId, aInfo ); - aInfo.m_aFamilyName = rFontName; + GlyphCache& rGC = X11GlyphCache::GetInstance(); - // inform glyph cache of new font - ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo ); - aDFA.mnQuality += 5800; + for (std::vector<psp::fontID>::iterator aI = aFontIds.begin(), aEnd = aFontIds.end(); aI != aEnd; ++aI) + { + // prepare font data + psp::FastPrintFontInfo aInfo; + rMgr.getFontFastInfo( *aI, aInfo ); + aInfo.m_aFamilyName = rFontName; - int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID ); + // inform glyph cache of new font + ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo ); + aDFA.mnQuality += 5800; - GlyphCache& rGC = X11GlyphCache::GetInstance(); - const rtl::OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID ); - rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA ); + int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID ); + + const rtl::OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID ); + rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA ); + } // announce new font to device's font list rGC.AnnounceFonts( pFontList ); |