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