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