0025978: Visualization - setup font aliases for Android
[occt.git] / src / Font / Font_FontMgr.cxx
1 // Created on: 2008-01-20
2 // Created by: Alexander A. BORODIN
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Font_FontMgr.ixx>
17
18 #include <Font_FTLibrary.hxx>
19 #include <OSD_Environment.hxx>
20 #include <NCollection_List.hxx>
21 #include <NCollection_Map.hxx>
22 #include <Standard_Stream.hxx>
23 #include <TCollection_HAsciiString.hxx>
24
25 #include <ft2build.h>
26 #include FT_FREETYPE_H
27
28 struct Font_FontMgr_FontAliasMapNode
29 {
30   const char *    EnumName;
31   const char *    FontName;
32   Font_FontAspect FontAspect;
33 };
34
35 static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
36 {
37
38 #ifdef _WIN32
39
40   { "Courier"                  , "Courier New"    , Font_FA_Regular },
41   { "Times-Roman"              , "Times New Roman", Font_FA_Regular  },
42   { "Times-Bold"               , "Times New Roman", Font_FA_Bold },
43   { "Times-Italic"             , "Times New Roman", Font_FA_Italic  },
44   { "Times-BoldItalic"         , "Times New Roman", Font_FA_BoldItalic  },
45   { "ZapfChancery-MediumItalic", "Script"         , Font_FA_Regular  },
46   { "Symbol"                   , "Symbol"         , Font_FA_Regular  },
47   { "ZapfDingbats"             , "WingDings"      , Font_FA_Regular  },
48   { "Rock"                     , "Arial"          , Font_FA_Regular  },
49   { "Iris"                     , "Lucida Console" , Font_FA_Regular  }
50
51 #elif defined(__ANDROID__)
52
53   { "Courier"                  , "Droid Sans Mono", Font_FA_Regular },
54   { "Times-Roman"              , "Droid Serif"    , Font_FA_Regular  },
55   { "Times-Bold"               , "Droid Serif"    , Font_FA_Bold },
56   { "Times-Italic"             , "Droid Serif"    , Font_FA_Italic  },
57   { "Times-BoldItalic"         , "Droid Serif"    , Font_FA_BoldItalic  },
58   { "Arial"                    , "Roboto"         , Font_FA_Regular  },
59
60 #else   //X11
61
62   { "Courier"                  , "Courier"      , Font_FA_Regular },
63   { "Times-Roman"              , "Times"        , Font_FA_Regular  },
64   { "Times-Bold"               , "Times"        , Font_FA_Bold },
65   { "Times-Italic"             , "Times"        , Font_FA_Italic  },
66   { "Times-BoldItalic"         , "Times"        , Font_FA_BoldItalic  },
67   { "Arial"                    , "Helvetica"    , Font_FA_Regular  },
68   { "ZapfChancery-MediumItalic", "-adobe-itc zapf chancery-medium-i-normal--*-*-*-*-*-*-iso8859-1"              , Font_FA_Regular  },
69   { "Symbol"                   , "-adobe-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific"                , Font_FA_Regular  },
70   { "ZapfDingbats"             , "-adobe-itc zapf dingbats-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific"     , Font_FA_Regular  },
71   { "Rock"                     , "-sgi-rock-medium-r-normal--*-*-*-*-p-*-iso8859-1"                             , Font_FA_Regular  },
72   { "Iris"                     , "--iris-medium-r-normal--*-*-*-*-m-*-iso8859-1"                                , Font_FA_Regular  }
73 #endif
74
75 };
76
77 #define NUM_FONT_ENTRIES (int)(sizeof(Font_FontMgr_MapOfFontsAliases)/sizeof(Font_FontMgr_FontAliasMapNode))
78
79 #if defined(_WIN32)
80
81   #include <windows.h>
82   #include <stdlib.h>
83
84   #ifdef _MSC_VER
85     #pragma comment (lib, "freetype.lib")
86   #endif
87
88   namespace
89   {
90
91     // list of supported extensions
92     static Standard_CString Font_FontMgr_Extensions[] =
93     {
94       "ttf",
95       "otf",
96       "ttc",
97       NULL
98     };
99
100   };
101
102 #else
103
104   #include <OSD_DirectoryIterator.hxx>
105   #include <OSD_FileIterator.hxx>
106   #include <OSD_Path.hxx>
107   #include <OSD_File.hxx>
108   #include <OSD_OpenMode.hxx>
109   #include <OSD_Protection.hxx>
110
111   namespace
112   {
113
114     // list of supported extensions
115     static Standard_CString Font_FontMgr_Extensions[] =
116     {
117       "ttf",
118       "otf",
119       "ttc",
120       "pfa",
121       "pfb",
122       NULL
123     };
124
125     // X11 configuration file in plain text format (obsolete - doesn't exists in modern distributives)
126     static Standard_CString myFontServiceConf[] = {"/etc/X11/fs/config",
127                                                    "/usr/X11R6/lib/X11/fs/config",
128                                                    "/usr/X11/lib/X11/fs/config",
129                                                    NULL
130                                                   };
131
132   #ifdef __APPLE__
133     // default fonts paths in Mac OS X
134     static Standard_CString myDefaultFontsDirs[] = {"/System/Library/Fonts",
135                                                     "/Library/Fonts",
136                                                     NULL
137                                                    };
138   #else
139     // default fonts paths in most Unix systems (Linux and others)
140     static Standard_CString myDefaultFontsDirs[] = {"/system/fonts",         // Android
141                                                     "/usr/share/fonts",
142                                                     "/usr/local/share/fonts",
143                                                     NULL
144                                                    };
145   #endif
146
147     static void addDirsRecursively (const OSD_Path&                           thePath,
148                                     NCollection_Map<TCollection_AsciiString>& theDirsMap)
149     {
150       TCollection_AsciiString aDirName;
151       thePath.SystemName (aDirName);
152       if (!theDirsMap.Add (aDirName))
153       {
154         return;
155       }
156
157       for (OSD_DirectoryIterator aDirIterator (thePath, "*"); aDirIterator.More(); aDirIterator.Next())
158       {
159         OSD_Path aChildDirPath;
160         aDirIterator.Values().Path (aChildDirPath);
161
162         TCollection_AsciiString aChildDirName;
163         aChildDirPath.SystemName (aChildDirName);
164         if (!aChildDirName.IsEqual (".") && !aChildDirName.IsEqual (".."))
165         {
166           aChildDirName = aDirName + "/" + aChildDirName;
167           OSD_Path aPath (aChildDirName);
168           addDirsRecursively (aPath, theDirsMap);
169         }
170       }
171     }
172
173   };
174
175 #endif
176
177 // =======================================================================
178 // function : checkFont
179 // purpose  :
180 // =======================================================================
181 static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib,
182                                           const Standard_CString        theFontPath)
183 {
184   FT_Face aFontFace;
185   FT_Error aFaceError = FT_New_Face (theFTLib->Instance(), theFontPath, 0, &aFontFace);
186   if (aFaceError != FT_Err_Ok)
187   {
188     return NULL;
189   }
190
191   Font_FontAspect anAspect = Font_FA_Regular;
192   if (aFontFace->style_flags == (FT_STYLE_FLAG_ITALIC | FT_STYLE_FLAG_BOLD))
193   {
194     anAspect = Font_FA_BoldItalic;
195   }
196   else if (aFontFace->style_flags == FT_STYLE_FLAG_ITALIC)
197   {
198     anAspect = Font_FA_Italic;
199   }
200   else if (aFontFace->style_flags == FT_STYLE_FLAG_BOLD)
201   {
202     anAspect = Font_FA_Bold;
203   }
204
205   Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aFontFace->family_name);
206   Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (theFontPath);
207   Handle(Font_SystemFont) aResult = new Font_SystemFont (aFontName, anAspect, aFontPath);
208
209   FT_Done_Face (aFontFace);
210
211   return aResult;
212 }
213
214 // =======================================================================
215 // function : GetInstance
216 // purpose  :
217 // =======================================================================
218 Handle(Font_FontMgr) Font_FontMgr::GetInstance()
219 {
220   static Handle(Font_FontMgr) _mgr;
221   if (_mgr.IsNull())
222   {
223     _mgr = new Font_FontMgr();
224   }
225
226   return _mgr;
227 }
228
229 // =======================================================================
230 // function : Font_FontMgr
231 // purpose  :
232 // =======================================================================
233 Font_FontMgr::Font_FontMgr()
234 {
235   InitFontDataBase();
236 }
237
238 // =======================================================================
239 // function : CheckFont
240 // purpose  :
241 // =======================================================================
242 Handle(Font_SystemFont) Font_FontMgr::CheckFont (Standard_CString theFontPath) const
243 {
244   Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
245   return checkFont (aFtLibrary, theFontPath);
246 }
247
248 // =======================================================================
249 // function : RegisterFont
250 // purpose  :
251 // =======================================================================
252 Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theFont,
253                                              const Standard_Boolean         theToOverride)
254 {
255   if (theFont.IsNull())
256   {
257     return Standard_False;
258   }
259
260   for (Font_NListOfSystemFont::Iterator aFontIter (myListOfFonts);
261        aFontIter.More(); aFontIter.Next())
262   {
263     if (!aFontIter.Value()->FontName()->IsSameString (theFont->FontName(), Standard_False))
264     {
265       continue;
266     }
267
268     if (theFont->FontAspect() != Font_FA_Undefined
269      && aFontIter.Value()->FontAspect() != theFont->FontAspect())
270     {
271       continue;
272     }
273
274     if (theFont->FontHeight() == -1 || aFontIter.Value()->FontHeight() == -1
275      || theFont->FontHeight() ==       aFontIter.Value()->FontHeight())
276     {
277       if (theFont->FontPath()->String() == aFontIter.Value()->FontPath()->String())
278       {
279         return Standard_True;
280       }
281       else if (theToOverride)
282       {
283         myListOfFonts.Remove (aFontIter);
284       }
285       else
286       {
287         return Standard_False;
288       }
289     }
290   }
291
292   myListOfFonts.Append (theFont);
293   return Standard_True;
294 }
295
296 // =======================================================================
297 // function : InitFontDataBase
298 // purpose  :
299 // =======================================================================
300 void Font_FontMgr::InitFontDataBase()
301 {
302   myListOfFonts.Clear();
303   Handle(Font_FTLibrary) aFtLibrary;
304
305 #if defined(_WIN32)
306
307   // font directory is placed in "C:\Windows\Fonts\"
308   UINT aStrLength = GetSystemWindowsDirectoryA (NULL, 0);
309   if (aStrLength == 0)
310   {
311     return;
312   }
313
314   char* aWinDir = new char[aStrLength];
315   GetSystemWindowsDirectoryA (aWinDir, aStrLength);
316   Handle(TCollection_HAsciiString) aFontsDir = new TCollection_HAsciiString (aWinDir);
317   aFontsDir->AssignCat ("\\Fonts\\");
318   delete[] aWinDir;
319
320   // read fonts list from registry
321   HKEY aFontsKey;
322   if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
323                      0, KEY_READ, &aFontsKey) != ERROR_SUCCESS)
324   {
325     return;
326   }
327
328   NCollection_Map<TCollection_AsciiString> aSupportedExtensions;
329   for (Standard_Integer anIter = 0; Font_FontMgr_Extensions[anIter] != NULL; ++anIter)
330   {
331     Standard_CString anExt = Font_FontMgr_Extensions[anIter];
332     aSupportedExtensions.Add (TCollection_AsciiString (anExt));
333   }
334
335   aFtLibrary = new Font_FTLibrary();
336   static const DWORD aBufferSize = 256;
337   char aNameBuff[aBufferSize];
338   char aPathBuff[aBufferSize];
339   DWORD aNameSize = aBufferSize;
340   DWORD aPathSize = aBufferSize;
341   for (DWORD anIter = 0;
342        RegEnumValueA (aFontsKey, anIter,
343                       aNameBuff, &aNameSize, NULL, NULL,
344                       (LPBYTE )aPathBuff, &aPathSize) != ERROR_NO_MORE_ITEMS;
345       ++anIter, aNameSize = aBufferSize, aPathSize = aBufferSize)
346   {
347     aPathBuff[(aPathSize < aBufferSize) ? aPathSize : (aBufferSize - 1)] = '\0'; // ensure string is NULL-terminated
348
349     Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aNameBuff);
350     Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (aPathBuff);
351     if (aFontPath->Search ("\\") == -1)
352     {
353       aFontPath->Insert (1, aFontsDir); // make absolute path
354     }
355
356     // check file extension is in list of supported
357     const Standard_Integer anExtensionPosition = aFontPath->SearchFromEnd (".") + 1;
358     if (anExtensionPosition > 0 && anExtensionPosition < aFontPath->Length())
359     {
360       Handle(TCollection_HAsciiString) aFontExtension = aFontPath->SubString (anExtensionPosition, aFontPath->Length());
361       aFontExtension->LowerCase();
362       if (aSupportedExtensions.Contains (aFontExtension->String()))
363       {
364         Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
365         if (!aNewFont.IsNull())
366         {
367           myListOfFonts.Append (aNewFont);
368         }
369       }
370     }
371   }
372
373   // close registry key
374   RegCloseKey (aFontsKey);
375
376 #else
377
378   NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
379   const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
380
381   // read fonts directories from font service config file (obsolete)
382   for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
383   {
384     const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
385     OSD_File aFile (aFileOfFontsPath);
386     if (!aFile.Exists())
387     {
388       continue;
389     }
390
391     aFile.Open (OSD_ReadOnly, aProtectRead);
392     if (!aFile.IsOpen())
393     {
394       continue;
395     }
396
397     Standard_Integer aNByte = 256;
398     Standard_Integer aNbyteRead;
399     TCollection_AsciiString aStr; // read string with information
400     while (!aFile.IsAtEnd())
401     {
402       Standard_Integer aLocation = -1;
403       Standard_Integer aPathLocation = -1;
404
405       aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
406       aLocation = aStr.Search ("catalogue=");
407       if (aLocation < 0)
408       {
409         aLocation = aStr.Search ("catalogue =");
410       }
411
412       aPathLocation = aStr.Search ("/");
413       if (aLocation > 0 && aPathLocation > 0)
414       {
415         aStr = aStr.Split (aPathLocation - 1);
416         TCollection_AsciiString aFontPath;
417         Standard_Integer aPathNumber = 1;
418         do
419         {
420           // Getting directory paths, which can be splitted by "," or ":"
421           aFontPath = aStr.Token (":,", aPathNumber);
422           aFontPath.RightAdjust();
423           if (!aFontPath.IsEmpty())
424           {
425             OSD_Path aPath(aFontPath);
426             addDirsRecursively (aPath, aMapOfFontsDirs);
427           }
428           aPathNumber++;
429         }
430         while (!aFontPath.IsEmpty());
431       }
432     }
433     aFile.Close();
434   }
435
436   // append default directories
437   for (Standard_Integer anIter = 0; myDefaultFontsDirs[anIter] != NULL; ++anIter)
438   {
439     Standard_CString anItem = myDefaultFontsDirs[anIter];
440     TCollection_AsciiString aPathStr (anItem);
441     OSD_Path aPath (aPathStr);
442     addDirsRecursively (aPath, aMapOfFontsDirs);
443   }
444
445   NCollection_Map<TCollection_AsciiString> aSupportedExtensions;
446   for (Standard_Integer anIter = 0; Font_FontMgr_Extensions[anIter] != NULL; ++anIter)
447   {
448     Standard_CString anExt = Font_FontMgr_Extensions[anIter];
449     aSupportedExtensions.Add (TCollection_AsciiString (anExt));
450   }
451
452   aFtLibrary = new Font_FTLibrary();
453   for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
454        anIter.More(); anIter.Next())
455   {
456   #ifdef __ANDROID__
457     OSD_Path aFolderPath (anIter.Value());
458     for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
459     {
460       OSD_Path aFontFilePath;
461       aFileIter.Values().Path (aFontFilePath);
462
463       TCollection_AsciiString aFontFileName;
464       aFontFilePath.SystemName (aFontFileName);
465       aFontFileName = anIter.Value() + "/" + aFontFileName;
466
467       Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString());
468       if (!aNewFont.IsNull())
469       {
470         myListOfFonts.Append (aNewFont);
471       }
472     }
473   #else
474     OSD_File aReadFile (anIter.Value() + "/fonts.dir");
475     if (!aReadFile.Exists())
476     {
477       continue; // invalid fonts directory
478     }
479
480     aReadFile.Open (OSD_ReadOnly, aProtectRead);
481     if (!aReadFile.IsOpen())
482     {
483       continue; // invalid fonts directory
484     }
485
486     Standard_Integer aNbyteRead, aNByte = 256;
487     TCollection_AsciiString aLine (aNByte);
488     Standard_Boolean isFirstLine = Standard_True;
489     const TCollection_AsciiString anEncoding ("iso8859-1\n");
490     while (!aReadFile.IsAtEnd())
491     {
492       aReadFile.ReadLine (aLine, aNByte, aNbyteRead);
493       if (isFirstLine)
494       {
495         // first line contains the number of fonts in this file
496         // just ignoring it...
497         isFirstLine = Standard_False;
498         continue;
499       }
500
501       Standard_Integer anExtensionPosition = aLine.Search (".") + 1;
502       if (anExtensionPosition == 0)
503       {
504         continue; // can't find extension position in the font description
505       }
506
507       Standard_Integer anEndOfFileName = aLine.Location (" ", anExtensionPosition, aLine.Length()) - 1;
508       if (anEndOfFileName < 0 || anEndOfFileName < anExtensionPosition)
509       {
510         continue; // font description have empty extension
511       }
512
513       TCollection_AsciiString aFontExtension = aLine.SubString (anExtensionPosition, anEndOfFileName);
514       aFontExtension.LowerCase();
515       if (aSupportedExtensions.Contains (aFontExtension) && (aLine.Search (anEncoding) > 0))
516       {
517         // In current implementation use fonts with ISO-8859-1 coding page.
518         // OCCT not give to manage coding page by means of programm interface.
519         // TODO: make high level interface for choosing necessary coding page.
520         Handle(TCollection_HAsciiString) aXLFD =
521           new TCollection_HAsciiString (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
522         Handle(TCollection_HAsciiString) aFontPath =
523           new TCollection_HAsciiString (anIter.Value().ToCString());
524         if (aFontPath->SearchFromEnd ("/") != aFontPath->Length())
525         {
526           aFontPath->AssignCat ("/");
527         }
528         Handle(TCollection_HAsciiString) aFontFileName =
529         new TCollection_HAsciiString (aLine.SubString (1, anEndOfFileName));
530         aFontPath->AssignCat (aFontFileName);
531
532         Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (aXLFD, aFontPath);
533         Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
534
535         if (aNewFontFromXLFD->IsValid() && !aNewFont.IsNull() &&
536            !aNewFont->IsEqual (aNewFontFromXLFD))
537         {
538           myListOfFonts.Append (aNewFont);
539           myListOfFonts.Append (aNewFontFromXLFD);
540         }
541         else if (!aNewFont.IsNull())
542         {
543           myListOfFonts.Append (aNewFont);
544         }
545         else if (aNewFontFromXLFD->IsValid())
546         {
547           myListOfFonts.Append (aNewFontFromXLFD);
548         }
549       }
550     }
551     aReadFile.Close();
552   #endif
553   }
554 #endif
555 }
556
557 // =======================================================================
558 // function : GetAvailableFonts
559 // purpose  :
560 // =======================================================================
561 const Font_NListOfSystemFont& Font_FontMgr::GetAvailableFonts() const
562 {
563   return myListOfFonts;
564 }
565
566 // =======================================================================
567 // function : GetAvailableFontsNames
568 // purpose  :
569 // =======================================================================
570 void Font_FontMgr::GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const
571 {
572   theFontsNames.Clear();
573   for (Font_NListOfSystemFont::Iterator anIter(myListOfFonts); anIter.More(); anIter.Next())
574   {
575     theFontsNames.Append (anIter.Value()->FontName());
576   }
577 }
578
579 // =======================================================================
580 // function : GetFont
581 // purpose  :
582 // =======================================================================
583 Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiString)& theFontName,
584                                                const Font_FontAspect  theFontAspect,
585                                                const Standard_Integer theFontSize) const
586 {
587   if ( (theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
588   {
589     return NULL;
590   }
591
592   for (Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts);
593        aFontsIterator.More(); aFontsIterator.Next())
594   {
595     if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False))
596     {
597       continue;
598     }
599
600     if (theFontAspect != Font_FA_Undefined && aFontsIterator.Value()->FontAspect() != theFontAspect)
601     {
602       continue;
603     }
604
605     if (theFontSize == -1 || aFontsIterator.Value()->FontHeight() == -1 ||
606         theFontSize == aFontsIterator.Value()->FontHeight())
607     {
608       return aFontsIterator.Value();
609     }
610   }
611
612   return NULL;
613 }
614
615 // =======================================================================
616 // function : FindFont
617 // purpose  :
618 // =======================================================================
619 Handle(Font_SystemFont) Font_FontMgr::FindFont (const Handle(TCollection_HAsciiString)& theFontName,
620                                                 const Font_FontAspect  theFontAspect,
621                                                 const Standard_Integer theFontSize) const
622 {
623   Handle(TCollection_HAsciiString) aFontName   = theFontName;
624   Font_FontAspect                  aFontAspect = theFontAspect;
625   Standard_Integer                 aFontSize   = theFontSize;
626
627   Handle(Font_SystemFont) aFont = GetFont (aFontName, aFontAspect, aFontSize);
628   if (!aFont.IsNull())
629   {
630     return aFont;
631   }
632
633   // Trying to use font names mapping
634   for (Standard_Integer anIter = 0; anIter < NUM_FONT_ENTRIES; ++anIter)
635   {
636     Handle(TCollection_HAsciiString) aFontAlias =
637       new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].EnumName);
638
639     if (aFontAlias->IsSameString (aFontName, Standard_False))
640     {
641       aFontName = new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].FontName);
642       aFontAspect = Font_FontMgr_MapOfFontsAliases[anIter].FontAspect;
643       break;
644     }
645   }
646
647   // check font family alias with specified font aspect
648   if (theFontAspect != Font_FA_Undefined
649    && theFontAspect != Font_FA_Regular
650    && theFontAspect != aFontAspect)
651   {
652     aFont = GetFont (aFontName, theFontAspect, aFontSize);
653     if (!aFont.IsNull())
654     {
655       return aFont;
656     }
657   }
658
659   // check font alias with aspect in the name
660   aFont = GetFont (aFontName, aFontAspect, aFontSize);
661   if (!aFont.IsNull())
662   {
663     return aFont;
664   }
665
666   // Requested family name not found -> search for any font family with given aspect and height
667   aFontName = new TCollection_HAsciiString ("");
668   aFont = GetFont (aFontName, aFontAspect, aFontSize);
669   if (!aFont.IsNull())
670   {
671     return aFont;
672   }
673
674   // The last resort: trying to use ANY font available in the system
675   aFontAspect = Font_FA_Undefined;
676   aFontSize = -1;
677   aFont = GetFont (aFontName, aFontAspect, aFontSize);
678   if (!aFont.IsNull())
679   {
680     return aFont;
681   }
682
683   return NULL; // Fonts are not found in the system.
684 }