SFont *FontServer::OpenFont( const std::string & cFamily, const std::string & cStyle ) { FontFamily *pcFamily; SFont *pcFont = NULL; if( Lock() ) { if( ( pcFamily = FindFamily( cFamily ) ) ) { pcFont = pcFamily->FindStyle( cStyle ); } Unlock(); } return ( pcFont ); }
SFontInstance *FontServer::OpenInstance( const std::string & cFamily, const std::string & cStyle, const FontProperty & cFP ) { FontFamily *pcFamily; g_cFontLock.Lock(); if( ( pcFamily = FindFamily( cFamily ) ) ) { SFont *pcFont = pcFamily->FindStyle( cStyle ); if( pcFont != NULL ) { SFontInstance *pcInstance = pcFont->OpenInstance( cFP ); if( pcInstance != NULL ) { g_cFontLock.Unlock(); return ( pcInstance ); } } } g_cFontLock.Unlock(); return ( NULL ); }
void FontServer::ScanDirectory( const char *pzPath ) { DIR *hDir; dirent *psEntry; g_cFontLock.Lock(); std::map <std::string, FontFamily * >::iterator cFamIter; for( cFamIter = m_cFamilies.begin(); cFamIter != m_cFamilies.end( ); ++cFamIter ) { std::map <std::string, SFont * >::iterator cStyleIter; for( cStyleIter = ( *cFamIter ).second->m_cFonts.begin(); cStyleIter != ( *cFamIter ).second->m_cFonts.end( ); ++cStyleIter ) { ( *cStyleIter ).second->SetDeletedFlag( true ); } } if( ( hDir = opendir( pzPath ) ) ) { int nCount = 0; while( ( psEntry = readdir( hDir ) ) ) { FT_Face psFace; FT_Error nError; char zFullPath[PATH_MAX]; if( strcmp( psEntry->d_name, "." ) == 0 || strcmp( psEntry->d_name, ".." ) == 0 ) { continue; } strcpy( zFullPath, pzPath ); pathcat( zFullPath, psEntry->d_name ); nError = FT_New_Face( m_hFTLib, zFullPath, 0, &psFace ); if( nError != 0 ) { continue; } FT_CharMap psCharMap; int i; for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 3 && psCharMap->encoding_id == 1 ) { // Windows unicode goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 1 && psCharMap->encoding_id == 0 ) { // Apple unicode goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 3 && psCharMap->encoding_id == 0 ) { // Windows symbol goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 0 && psCharMap->encoding_id == 0 ) { // Apple roman goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; dbprintf( "platform=%d, encoding=%d\n", psCharMap->platform_id, psCharMap->encoding_id ); } FT_Done_Face( psFace ); dbprintf( "Error: failed to find character map\n" ); continue; found: psFace->charmap = psCharMap; FontFamily *pcFamily = FindFamily( psFace->family_name ); if( NULL == pcFamily ) { try { pcFamily = new FontFamily( psFace->family_name ); } catch( ... ) { continue; } m_cFamilies[psFace->family_name] = pcFamily; } SFont *pcFont = pcFamily->FindStyle( psFace->style_name ); if( pcFont != NULL ) { pcFont->SetDeletedFlag( false ); FT_Done_Face( psFace ); continue; } else { try { pcFont = new SFont( pcFamily, psFace ); } catch( ... ) { continue; } } __assertw( NULL != pcFont ); #if 0 dbprintf( "Font : '%s'-'%s' (%d) added\n", psFace->family_name, psFace->style_name, psFace->num_fixed_sizes ); if( psFace->num_fixed_sizes > 0 ) { for( int j = 0; j < psFace->num_fixed_sizes; ++j ) { dbprintf( " Size %d : %dx%d\n", j, psFace->available_sizes[j].width, psFace->available_sizes[j].height ); } } #endif nCount++; } dbprintf( "Directory '%s' scanned %d fonts found\n", pzPath, nCount ); closedir( hDir ); } restart: for( cFamIter = m_cFamilies.begin(); cFamIter != m_cFamilies.end( ); ++cFamIter ) { std::map <std::string, SFont * >::iterator cStyleIter; for( cStyleIter = ( *cFamIter ).second->m_cFonts.begin(); cStyleIter != ( *cFamIter ).second->m_cFonts.end( ); ++cStyleIter ) { SFont *pcStyle = ( *cStyleIter ).second; if( pcStyle->IsDeleted() && pcStyle->GetInstanceCount( ) == 0 ) { dbprintf( "Deleting font %s:%s\n", pcStyle->GetFamily()->GetName( ).c_str( ), pcStyle->GetStyle( ).c_str( ) ); delete pcStyle; goto restart; } } } g_cFontLock.Unlock(); }