0022847: DrawTrSurf: provide interface for configuring visualization properties in...
[occt.git] / src / OSD / OSD_FontMgr.cxx
CommitLineData
7fd59977 1// Copyright: OpenCASCADE
2
3// File: OSD_FontMgr.cxx
4// Created: 20.01.2008
5// Author: Alexander A. BORODIN
6// Updated:
7
8#include <OSD_FontMgr.ixx>
9#ifdef WNT
10# include <windows.h>
11# include <stdlib.h>
12#else //WNT
13# include <dirent.h>
14# include <X11/Xlib.h>
15#endif //WNT
16
17#include <NCollection_List.hxx>
18#include <TCollection_HAsciiString.hxx>
19#include <Standard_Stream.hxx>
20
21
22#ifndef WNT
23#include <TCollection_AsciiString.hxx>
24
25#include <NCollection_DefineList.hxx>
26#include <NCollection_List.hxx>
27
28#include <OSD_Path.hxx>
29#include <OSD_FileIterator.hxx>
30#include <OSD_DirectoryIterator.hxx>
31#include <OSD_File.hxx>
32#include <OSD_FileNode.hxx>
33#include <OSD_OpenMode.hxx>
34#include <OSD_Protection.hxx>
35#include <OSD_NListOfSystemFont.hxx>
36
37const Standard_Integer font_service_conf_size = 3;
38static Standard_Character font_service_conf[font_service_conf_size][64] = { {"/etc/X11/fs/config"},
39 {"/usr/X11R6/lib/X11/fs/config"},
40 {"/usr/X11/lib/X11/fs/config"}
41 };
42
43DEFINE_LIST( StringList, NCollection_List, TCollection_HAsciiString );
44
45void find_path_with_font_dir( const TCollection_AsciiString& dir,StringList& dirs )
46{
47 if( !dir.IsEmpty() )
48 {
49 TCollection_AsciiString PathName( dir );
50
51 Standard_Integer rem = PathName.Length();
52
53 if ( PathName.SearchFromEnd("/") == rem )
54 PathName.Remove( rem, 1 );
55
56 Standard_Boolean need_to_append = Standard_True;
57
58 StringList::Iterator it( dirs );
59 for( ; it.More(); it.Next() )
60 {
61 if ( PathName.IsEqual(it.Value().ToCString()) ) {
62 need_to_append = Standard_False;
63 break;
64 }
65 }
66 if ( need_to_append )
67 dirs.Append( PathName );
68
69 OSD_DirectoryIterator osd_dir(PathName,"*");
70 while(osd_dir.More())
71 {
72 OSD_Path path_file;
73 osd_dir.Values().Path( path_file );
74 if( path_file.Name().Length() < 1 )
75 {
76 osd_dir.Next();
77 continue;
78 }
79
80 TCollection_AsciiString full_path_name = PathName + "/" + path_file.Name();
81 rem = full_path_name.Length();
82 if ( full_path_name.SearchFromEnd("/") == rem )
83 full_path_name.Remove( rem, 1 );
84 find_path_with_font_dir( full_path_name, dirs );
85 osd_dir.Next();
86 }
87 }
88}
89
90#endif //WNT
91
92
93Handle(OSD_FontMgr) OSD_FontMgr::GetInstance() {
94
95 static Handle(OSD_FontMgr) _mgr;
96 if ( _mgr.IsNull() )
97 _mgr = new OSD_FontMgr();
98
99 return _mgr;
100
101}
102
103OSD_FontMgr::OSD_FontMgr() {
104
105 InitFontDataBase();
106
107}
108
109
110void OSD_FontMgr::InitFontDataBase() {
111
112 MyListOfFonts.Clear();
113
114#ifdef WNT
115 //detect font directory
116
117 Standard_Character* windir_var;
118 Standard_Size req_size;
119 req_size = strlen( getenv("windir") );
120
5b181c62 121 windir_var = new Standard_Character[req_size + 1];
7fd59977 122
123 strcpy( windir_var, getenv("windir") );
124
125 Standard_Character *font_dir = new Standard_Character[ req_size + strlen("\\Fonts\\") + 1 ] ;
126
127 if( !strcpy( font_dir, windir_var ) )
128 return ;
129 if( !strcat( font_dir, "\\Fonts\\" ) )
130 return ;
131
132 Handle(TCollection_HAsciiString) HFontDir = new TCollection_HAsciiString(font_dir);
133
134#ifdef TRACE
135 cout << "System font directory: " << font_dir << "\n";
136#endif TRACE
137
138 //read registry
139 HKEY fonts_hkey;
140 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
141 TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"),
142 0,
143 KEY_READ,
144 &fonts_hkey )
145 != ERROR_SUCCESS )
146 {
147 return;
148 }
149 Standard_Integer id = 0;
150 Standard_Character buf_name[100];
151 Standard_Byte buf_data[100];
152 DWORD size_name = 100,
153 size_data = 100;
154
155 while ( true )
156 {
157 //detect file name
158 DWORD type;
159 size_name = 100,
160 size_data = 100;
161 OSD_FontAspect aspect;
162 if( RegEnumValue( fonts_hkey,
163 id,
164 buf_name,
165 &size_name,
166 NULL,
167 &type,
168 buf_data,
169 &size_data) == ERROR_NO_MORE_ITEMS ) {
170 break;
171 }
172 Handle(TCollection_HAsciiString) fname =
173 new TCollection_HAsciiString(buf_name);
174 fname->RightAdjust();
175 fname->LeftAdjust();
176 //remove construction like (TrueType....
177 Standard_Integer anIndexTT = fname->SearchFromEnd( new TCollection_HAsciiString( " (" ) );
178 Standard_Boolean aTruncate = Standard_False;
179 if ( anIndexTT > 1 )
180 fname->Trunc( anIndexTT );
181 Standard_Integer anIndex = 0;
182 fname->RightAdjust();
183 if ( ( anIndex = fname->SearchFromEnd( new TCollection_HAsciiString("Bold Italic") ) ) > 0 ) {
184 aTruncate = ( anIndex > 1 ) && ( fname->Value(anIndex - 1 ) == ' ' );
185 aspect = OSD_FA_BoldItalic;
186 } else if ( ( anIndex = fname->SearchFromEnd( new TCollection_HAsciiString("Bold") ) ) > 0 ) {
187 aTruncate = ( anIndex > 1 ) && ( fname->Value(anIndex - 1 ) == ' ' );
188 aspect = OSD_FA_Bold;
189 } else if ( ( anIndex = fname->SearchFromEnd( new TCollection_HAsciiString("Italic") ) ) > 0 ) {
190 aTruncate = ( anIndex > 1 ) && ( fname->Value(anIndex - 1 ) == ' ' );
191 aspect = OSD_FA_Italic;
192 } else {
193 aspect = OSD_FA_Regular;
194 }
195 if( aTruncate )
196 fname->Trunc( anIndex - 1 );
197 fname->RightAdjust();
198 Handle(TCollection_HAsciiString) file_path =
199 new TCollection_HAsciiString( (Standard_Character*)buf_data );
200 if ( strchr( (Standard_Character*)buf_data, '\\' ) == NULL ) {
201 file_path->Insert( 1, HFontDir );
202 }
203 Handle(TCollection_HAsciiString) HFontDir = new TCollection_HAsciiString(font_dir);
204
205 if( ( ( file_path->Search(".ttf") > 0 ) || ( file_path->Search(".TTF") > 0 ) ||
206 ( file_path->Search(".otf") > 0 ) || ( file_path->Search(".OTF") > 0 ) ||
207 ( file_path->Search(".ttc") > 0 ) || ( file_path->Search(".TTC") > 0 ) ) ){
208 MyListOfFonts.Append( new OSD_SystemFont( fname, aspect, file_path ) );
209#ifdef TRACE
210 cout << "Adding font...\n"
211 << " font name: " << fname->ToCString() << "\n"
212 << " font file: " << file_path->ToCString() << "\n"
213 << " font aspect: ";
214 switch( aspect ) {
215 case OSD_FA_Bold:
216 cout << "OSD_FA_Bold\n";
217 break;
218 case OSD_FA_BoldItalic:
219 cout << "OSD_FA_BoldItalic\n";
220 break;
221 case OSD_FA_Italic:
222 cout << "OSD_FA_Italic\n";
223 break;
224 default:
225 cout << "OSD_FA_Regular\n";
226 break;
227 }
228#endif
229 }
230 id++;
231 }
232 //close registry
233 RegCloseKey( fonts_hkey );
234#endif //WNT
235
236#ifndef WNT
237 StringList dirs;
238 Handle(TCollection_HAsciiString) str = new TCollection_HAsciiString;
239 Display * disp = XOpenDisplay("localhost:0.0");
240
c3d89486 241 if (!disp)
7fd59977 242 {
c3d89486 243 // let the X server find the available connection
244 disp = XOpenDisplay(":0.0");
245 if (!disp)
246 {
247 cout << "Display is NULL!" << endl;
248 return ;
249 }
7fd59977 250 }
251
252 Standard_Integer npaths = 0;
253
254 Standard_Character** fontpath = XGetFontPath(disp, &npaths);
255#ifdef TRACE
256 cout << "NPATHS = " << npaths << endl ;
257#endif
258 for (Standard_Integer i = 0; i < npaths; i++ )
259 {
260#ifdef TRACE
261 cout << "Font Path: " << fontpath[i] << endl;
262#endif
263 if ( fontpath[i][0] == '/' ) {
264 TCollection_AsciiString aFontPath( fontpath[i] );
265 find_path_with_font_dir( aFontPath, dirs );
266 }
267 else
268 {
269 TCollection_AsciiString aFontPath( fontpath[i] );
270 TCollection_AsciiString aCutFontPath;
271 Standard_Integer location = -1 ;
272 location = aFontPath.Location( "/",1,aFontPath.Length() );
273 if( location > 0 )
274 aCutFontPath.AssignCat( aFontPath.SubString(location, aFontPath.Length() ) );
275 find_path_with_font_dir( aCutFontPath, dirs );
276 }
277 }
278 XFreeFontPath(fontpath);
279
280
281 OSD_OpenMode aMode = OSD_ReadOnly;
282 OSD_Protection aProtect( OSD_R, OSD_R, OSD_R, OSD_R );
283
284 for( Standard_Integer j = 0 ; j < font_service_conf_size; j++ )
285 {
286 TCollection_AsciiString fileOfFontServiceName( font_service_conf[j] );
287 OSD_File aFile( fileOfFontServiceName );
288
289 if( aFile.Exists() )
290 aFile.Open( aMode, aProtect );
291
292 if( aFile.IsOpen() )//font service
293 {
294 Standard_Integer aNByte = 256;
295 Standard_Integer aNbyteRead;
296 TCollection_AsciiString aStr( aNByte );//read string with information
297 TCollection_AsciiString aStrCut( aNByte );//cut of string
298 TCollection_AsciiString endStr;//cutting string
299
300 Standard_Boolean read_dirs = Standard_False;
301 Standard_Integer location =- 1; //disposition of necessary literals
302 Standard_Integer begin =- 1; //first left entry in string
303 Standard_Integer end =- 1; //first right entry in string
304 while( !aFile.IsAtEnd() )
305 {
306 aFile.ReadLine( aStr, aNByte, aNbyteRead );//reading 1 lines(256 bytes)
307 location = aStr.Location( "catalogue = ", 1, aStr.Length() );
308 if(location == 0)
309 location = aStr.Location( "catalogue=", 1, aStr.Length() );
310 if(location == 0)
311 location = aStr.Location( "catalogue= ", 1, aStr.Length() );
312 if(location == 0)
313 location = aStr.Location( "catalogue = ", 1, aStr.Length() );
314 if( location > 0 )
315 {
316#ifdef TRACE
317 cout << " Font config find!!" << endl;
318#endif
319 read_dirs = Standard_True;
320 }
321
322 if( read_dirs )
323 {
324 begin = aStr.Location( "/", 1, aStr.Length() );//begin of path name
325 end = aStr.Location( ":", 1, aStr.Length() );//end of path name
326 if( end < 1 )
327 end = aStr.Location( ",", 1, aStr.Length() );//also end of path name
328 end -= 1;
329 if( begin > 0 && end > 0 )
330 {
331 if( ( end - begin ) > 0 )
332 endStr.AssignCat( aStr.SubString ( begin, end ) );//cutting necessary literals for string
333 dirs.Append( TCollection_HAsciiString ( endStr ) );
334 endStr.Clear();
335 }
336 else
337 if( begin > 0 && end == -1 )
338 {
339 //if end of string don't have "," or ":"
340 //it is possible last sentence in block of word
341 endStr.AssignCat( aStr.SubString( begin, aStr.Length() - 1 ) );
342 dirs.Append( TCollection_HAsciiString( endStr ) );
343 endStr.Clear();
344 }
345 }
346
347 }
348 aFile.Close();
349 }
350 }
351
352 if( dirs.Size() > 0 )
353 {
354 //if dirs list contains elements
355 OSD_OpenMode aModeRead = OSD_ReadOnly;
356 OSD_Protection aProtectRead( OSD_R, OSD_R , OSD_R , OSD_R );
357
358 TCollection_AsciiString fileFontsDir;
359 StringList::Iterator it( dirs );
360 for( ; it.More(); it.Next() )
361 {
362 fileFontsDir.AssignCat( it.Value().ToCString() );
363 fileFontsDir.AssignCat( "/fonts.dir" );//append file name in path way
364
365 OSD_File readFile( fileFontsDir );
366 readFile.Open( aModeRead, aProtectRead );
367
368 Standard_Integer aNbyteRead, aNByte = 256;
369 if( readFile.IsOpen ( ) )
370 {
371 TCollection_AsciiString aLine( aNByte );
372 Standard_Integer countOfString = 0 ;
373 while( ! readFile.IsAtEnd() )//return true if EOF
374 {
375 if( countOfString > 1 )
376 {
377 readFile.ReadLine( aLine , aNByte , aNbyteRead );
378 if( ( ( aLine.Search(".pfa") > 0 ) || ( aLine.Search(".PFA") > 0 ) ||
379 ( aLine.Search(".pfb") > 0 ) || ( aLine.Search(".PFB") > 0 ) ||
380 ( aLine.Search(".ttf") > 0 ) || ( aLine.Search(".TTF") > 0 ) ||
381 ( aLine.Search(".otf") > 0 ) || ( aLine.Search(".OTF") > 0 ) ||
382 ( aLine.Search(".ttc") > 0 ) || ( aLine.Search(".TTC") > 0 ) )
383 && ( aLine.Search( "iso8859-1\n" ) > 0 ) )
384 {
385
386 // In current implementation use fonts with ISO-8859-1 coding page.
387 // OCCT not give to manage coding page by means of programm interface.
388 // TODO: make high level interface for
389 // choosing necessary coding page.
390 TCollection_AsciiString aXLFD;
391 Standard_Integer leftXLFD = aLine.SearchFromEnd(" ");
392 Standard_Integer rightXLFD = aLine.Length();
393 if( leftXLFD && rightXLFD )
394 aXLFD.AssignCat(aLine.SubString( leftXLFD + 1, rightXLFD ) );
395
396 TCollection_AsciiString aPath;
397 TCollection_AsciiString aTemp( it.Value().ToCString() );
398 if ( aTemp.SearchFromEnd("/") == aTemp.Length() )
399 {
400 //this branch intend to SUN
401 aPath.AssignCat( aTemp.ToCString() );
402 aPath.AssignCat( aLine.Token( " ", 1 ) );
403 }
404 else {
405 //this branch intend to Linux
406 aPath.AssignCat( aTemp.ToCString( ) );
407 aPath.AssignCat( "/" );
408 aPath.AssignCat( aLine.Token( " ", 1 ) );
409 }
410 MyListOfFonts.Append( new OSD_SystemFont( new TCollection_HAsciiString( aXLFD ),
411 new TCollection_HAsciiString( aPath ) ) );
412 }
413
414 }
415 else
416 readFile.ReadLine( aLine, aNByte, aNbyteRead );
417 countOfString++;
418 }
419 readFile.Close();
420 }
421 fileFontsDir.Clear();
422 }
423 }
424#endif
425}
426
427OSD_NListOfSystemFont OSD_FontMgr::GetAvalableFonts() const
428{
429 return MyListOfFonts;
430}
431
432