// Copyright: OpenCASCADE // File: OSD_FontMgr.cxx // Created: 20.01.2008 // Author: Alexander A. BORODIN // Updated: #include #ifdef WNT # include # include #endif //WNT #include #include #include #ifndef WNT #include #include #include #include #include #include #include #include #include #include #include const Standard_Integer font_service_conf_size = 3; static Standard_Character font_service_conf[font_service_conf_size][64] = { {"/etc/X11/fs/config"}, {"/usr/X11R6/lib/X11/fs/config"}, {"/usr/X11/lib/X11/fs/config"} }; #ifdef X11_FONT_PATH # define stringify(s) #s # define tostring(s) stringify(s) # define X11_FONT_PATH_STR tostring(X11_FONT_PATH) #else # define X11_FONT_PATH_STR "" #endif DEFINE_LIST( StringList, NCollection_List, TCollection_HAsciiString ); void find_path_with_font_dir( const TCollection_AsciiString& dir,StringList& dirs ) { if( !dir.IsEmpty() ) { TCollection_AsciiString PathName( dir ); Standard_Integer rem = PathName.Length(); if ( PathName.SearchFromEnd("/") == rem ) PathName.Remove( rem, 1 ); Standard_Boolean need_to_append = Standard_True; StringList::Iterator it( dirs ); for( ; it.More(); it.Next() ) { if ( PathName.IsEqual(it.Value().ToCString()) ) { need_to_append = Standard_False; break; } } if ( need_to_append ) dirs.Append( PathName ); OSD_DirectoryIterator osd_dir(PathName,"*"); while(osd_dir.More()) { OSD_Path path_file; osd_dir.Values().Path( path_file ); if( path_file.Name().Length() < 1 ) { osd_dir.Next(); continue; } TCollection_AsciiString full_path_name = PathName + "/" + path_file.Name(); rem = full_path_name.Length(); if ( full_path_name.SearchFromEnd("/") == rem ) full_path_name.Remove( rem, 1 ); find_path_with_font_dir( full_path_name, dirs ); osd_dir.Next(); } } } #endif //WNT Handle(OSD_FontMgr) OSD_FontMgr::GetInstance() { static Handle(OSD_FontMgr) _mgr; if ( _mgr.IsNull() ) _mgr = new OSD_FontMgr(); return _mgr; } OSD_FontMgr::OSD_FontMgr() { InitFontDataBase(); } #ifndef WNT static void process_paths_with_font_dir(const Standard_Character* paths, StringList& dirs) { TCollection_AsciiString fontpath(paths); while (fontpath.Length() > 0) { TCollection_AsciiString next_fontpath(""); Standard_Integer position = fontpath.Search(";"); if (position >= 0) { next_fontpath = fontpath.Split(position); fontpath.Trunc(fontpath.Length() - 1); } #ifdef TRACE cout << "Font Path: " << fontpath << endl; #endif if ( fontpath.Value(1) == '/' ) { find_path_with_font_dir( fontpath, dirs ); } else { TCollection_AsciiString aFontPath( fontpath ); TCollection_AsciiString aCutFontPath; Standard_Integer location = aFontPath.Location( "/",1,aFontPath.Length() ); if( location > 0 ) aCutFontPath.AssignCat( aFontPath.SubString(location, aFontPath.Length() ) ); find_path_with_font_dir( aCutFontPath, dirs ); } fontpath = next_fontpath; } } #endif void OSD_FontMgr::InitFontDataBase() { MyListOfFonts.Clear(); #ifdef WNT //detect font directory Standard_Character* windir_var; Standard_Size req_size; req_size = strlen( getenv("windir") ); windir_var = new Standard_Character[req_size + 1]; strcpy( windir_var, getenv("windir") ); Standard_Character *font_dir = new Standard_Character[ req_size + strlen("\\Fonts\\") + 1 ] ; if( !strcpy( font_dir, windir_var ) ) { delete [] windir_var; delete [] font_dir; return ; } if( !strcat( font_dir, "\\Fonts\\" ) ) { delete [] windir_var; delete [] font_dir; return ; } Handle(TCollection_HAsciiString) HFontDir = new TCollection_HAsciiString(font_dir); #ifdef TRACE cout << "System font directory: " << font_dir << "\n"; #endif //read registry HKEY fonts_hkey; if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), 0, KEY_READ, &fonts_hkey ) != ERROR_SUCCESS ) { return; } Standard_Integer id = 0; Standard_Character buf_name[100]; Standard_Byte buf_data[100]; DWORD size_name = 100, size_data = 100; while ( true ) { //detect file name DWORD type; size_name = 100, size_data = 100; OSD_FontAspect aspect; if( RegEnumValue( fonts_hkey, id, buf_name, &size_name, NULL, &type, buf_data, &size_data) == ERROR_NO_MORE_ITEMS ) { break; } Handle(TCollection_HAsciiString) fname = new TCollection_HAsciiString(buf_name); fname->RightAdjust(); fname->LeftAdjust(); //remove construction like (TrueType.... Standard_Integer anIndexTT = fname->SearchFromEnd( new TCollection_HAsciiString( " (" ) ); Standard_Boolean aTruncate = Standard_False; if ( anIndexTT > 1 ) fname->Trunc( anIndexTT ); Standard_Integer anIndex = 0; fname->RightAdjust(); if ( ( anIndex = fname->SearchFromEnd( new TCollection_HAsciiString("Bold Italic") ) ) > 0 ) { aTruncate = ( anIndex > 1 ) && ( fname->Value(anIndex - 1 ) == ' ' ); aspect = OSD_FA_BoldItalic; } else if ( ( anIndex = fname->SearchFromEnd( new TCollection_HAsciiString("Bold") ) ) > 0 ) { aTruncate = ( anIndex > 1 ) && ( fname->Value(anIndex - 1 ) == ' ' ); aspect = OSD_FA_Bold; } else if ( ( anIndex = fname->SearchFromEnd( new TCollection_HAsciiString("Italic") ) ) > 0 ) { aTruncate = ( anIndex > 1 ) && ( fname->Value(anIndex - 1 ) == ' ' ); aspect = OSD_FA_Italic; } else { aspect = OSD_FA_Regular; } if( aTruncate ) fname->Trunc( anIndex - 1 ); fname->RightAdjust(); Handle(TCollection_HAsciiString) file_path = new TCollection_HAsciiString( (Standard_Character*)buf_data ); if ( strchr( (Standard_Character*)buf_data, '\\' ) == NULL ) { file_path->Insert( 1, HFontDir ); } Handle(TCollection_HAsciiString) HFontDir = new TCollection_HAsciiString(font_dir); if( ( ( file_path->Search(".ttf") > 0 ) || ( file_path->Search(".TTF") > 0 ) || ( file_path->Search(".otf") > 0 ) || ( file_path->Search(".OTF") > 0 ) || ( file_path->Search(".ttc") > 0 ) || ( file_path->Search(".TTC") > 0 ) ) ){ MyListOfFonts.Append( new OSD_SystemFont( fname, aspect, file_path ) ); #ifdef TRACE cout << "Adding font...\n" << " font name: " << fname->ToCString() << "\n" << " font file: " << file_path->ToCString() << "\n" << " font aspect: "; switch( aspect ) { case OSD_FA_Bold: cout << "OSD_FA_Bold\n"; break; case OSD_FA_BoldItalic: cout << "OSD_FA_BoldItalic\n"; break; case OSD_FA_Italic: cout << "OSD_FA_Italic\n"; break; default: cout << "OSD_FA_Regular\n"; break; } #endif } id++; } //close registry RegCloseKey( fonts_hkey ); #endif //WNT #ifndef WNT StringList dirs; Standard_Character* font_path_env = getenv("FONTPATH"); if (font_path_env != NULL) process_paths_with_font_dir( font_path_env, dirs ); else process_paths_with_font_dir( X11_FONT_PATH_STR, dirs ); OSD_OpenMode aMode = OSD_ReadOnly; OSD_Protection aProtect( OSD_R, OSD_R, OSD_R, OSD_R ); for( Standard_Integer j = 0 ; j < font_service_conf_size; j++ ) { TCollection_AsciiString fileOfFontServiceName( font_service_conf[j] ); OSD_File aFile( fileOfFontServiceName ); if( aFile.Exists() ) aFile.Open( aMode, aProtect ); if( aFile.IsOpen() )//font service { Standard_Integer aNByte = 256; Standard_Integer aNbyteRead; TCollection_AsciiString aStr( aNByte );//read string with information TCollection_AsciiString aStrCut( aNByte );//cut of string TCollection_AsciiString endStr;//cutting string Standard_Boolean read_dirs = Standard_False; Standard_Integer location =- 1; //disposition of necessary literals Standard_Integer begin =- 1; //first left entry in string Standard_Integer end =- 1; //first right entry in string while( !aFile.IsAtEnd() ) { aFile.ReadLine( aStr, aNByte, aNbyteRead );//reading 1 lines(256 bytes) location = aStr.Location( "catalogue = ", 1, aStr.Length() ); if(location == 0) location = aStr.Location( "catalogue=", 1, aStr.Length() ); if(location == 0) location = aStr.Location( "catalogue= ", 1, aStr.Length() ); if(location == 0) location = aStr.Location( "catalogue = ", 1, aStr.Length() ); if( location > 0 ) { #ifdef TRACE cout << " Font config find!!" << endl; #endif read_dirs = Standard_True; } if( read_dirs ) { begin = aStr.Location( "/", 1, aStr.Length() );//begin of path name end = aStr.Location( ":", 1, aStr.Length() );//end of path name if( end < 1 ) end = aStr.Location( ",", 1, aStr.Length() );//also end of path name end -= 1; if( begin > 0 && end > 0 ) { if( ( end - begin ) > 0 ) endStr.AssignCat( aStr.SubString ( begin, end ) );//cutting necessary literals for string dirs.Append( TCollection_HAsciiString ( endStr ) ); endStr.Clear(); } else if( begin > 0 && end == -1 ) { //if end of string don't have "," or ":" //it is possible last sentence in block of word endStr.AssignCat( aStr.SubString( begin, aStr.Length() - 1 ) ); dirs.Append( TCollection_HAsciiString( endStr ) ); endStr.Clear(); } } } aFile.Close(); } } if( dirs.Size() > 0 ) { //if dirs list contains elements OSD_OpenMode aModeRead = OSD_ReadOnly; OSD_Protection aProtectRead( OSD_R, OSD_R , OSD_R , OSD_R ); TCollection_AsciiString fileFontsDir; StringList::Iterator it( dirs ); for( ; it.More(); it.Next() ) { fileFontsDir.AssignCat( it.Value().ToCString() ); fileFontsDir.AssignCat( "/fonts.dir" );//append file name in path way OSD_File readFile( fileFontsDir ); readFile.Open( aModeRead, aProtectRead ); Standard_Integer aNbyteRead, aNByte = 256; if( readFile.IsOpen ( ) ) { TCollection_AsciiString aLine( aNByte ); Standard_Integer countOfString = 0 ; while( ! readFile.IsAtEnd() )//return true if EOF { if( countOfString > 1 ) { readFile.ReadLine( aLine , aNByte , aNbyteRead ); if( ( ( aLine.Search(".pfa") > 0 ) || ( aLine.Search(".PFA") > 0 ) || ( aLine.Search(".pfb") > 0 ) || ( aLine.Search(".PFB") > 0 ) || ( aLine.Search(".ttf") > 0 ) || ( aLine.Search(".TTF") > 0 ) || ( aLine.Search(".otf") > 0 ) || ( aLine.Search(".OTF") > 0 ) || ( aLine.Search(".ttc") > 0 ) || ( aLine.Search(".TTC") > 0 ) ) && ( aLine.Search( "iso8859-1\n" ) > 0 ) ) { // In current implementation use fonts with ISO-8859-1 coding page. // OCCT not give to manage coding page by means of programm interface. // TODO: make high level interface for // choosing necessary coding page. TCollection_AsciiString aXLFD; Standard_Integer leftXLFD = aLine.SearchFromEnd(" "); Standard_Integer rightXLFD = aLine.Length(); if( leftXLFD && rightXLFD ) aXLFD.AssignCat(aLine.SubString( leftXLFD + 1, rightXLFD ) ); TCollection_AsciiString aPath; TCollection_AsciiString aTemp( it.Value().ToCString() ); if ( aTemp.SearchFromEnd("/") == aTemp.Length() ) { //this branch intend to SUN aPath.AssignCat( aTemp.ToCString() ); aPath.AssignCat( aLine.Token( " ", 1 ) ); } else { //this branch intend to Linux aPath.AssignCat( aTemp.ToCString( ) ); aPath.AssignCat( "/" ); aPath.AssignCat( aLine.Token( " ", 1 ) ); } MyListOfFonts.Append( new OSD_SystemFont( new TCollection_HAsciiString( aXLFD ), new TCollection_HAsciiString( aPath ) ) ); } } else readFile.ReadLine( aLine, aNByte, aNbyteRead ); countOfString++; } readFile.Close(); } fileFontsDir.Clear(); } } #endif } OSD_NListOfSystemFont OSD_FontMgr::GetAvalableFonts() const { return MyListOfFonts; }