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