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 | |
37 | const Standard_Integer font_service_conf_size = 3; |
38 | static 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 | |
43 | DEFINE_LIST( StringList, NCollection_List, TCollection_HAsciiString ); |
44 | |
45 | void 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 | |
93 | Handle(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 | |
103 | OSD_FontMgr::OSD_FontMgr() { |
104 | |
105 | InitFontDataBase(); |
106 | |
107 | } |
108 | |
109 | |
110 | void 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 | |
427 | OSD_NListOfSystemFont OSD_FontMgr::GetAvalableFonts() const |
428 | { |
429 | return MyListOfFonts; |
430 | } |
431 | |
432 | |