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