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