1 // Created on: 2008-01-20
2 // Created by: Alexander A. BORODIN
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Font_FontMgr.hxx>
18 #include <Font_NameOfFont.hxx>
19 #include <Font_FTLibrary.hxx>
20 #include <Font_SystemFont.hxx>
21 #include <Message.hxx>
22 #include <Message_Messenger.hxx>
23 #include <NCollection_List.hxx>
24 #include <NCollection_Map.hxx>
25 #include <OSD_Environment.hxx>
26 #include <Standard_Stream.hxx>
27 #include <Standard_Type.hxx>
28 #include <TCollection_HAsciiString.hxx>
31 #include FT_FREETYPE_H
32 IMPLEMENT_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
40 #pragma comment (lib, "freetype.lib")
46 // list of supported extensions
47 static Standard_CString Font_FontMgr_Extensions[] =
59 #include <OSD_DirectoryIterator.hxx>
60 #include <OSD_FileIterator.hxx>
61 #include <OSD_Path.hxx>
62 #include <OSD_File.hxx>
63 #include <OSD_OpenMode.hxx>
64 #include <OSD_Protection.hxx>
69 // list of supported extensions
70 static Standard_CString Font_FontMgr_Extensions[] =
78 // Datafork TrueType (OS X), obsolete
84 #if !defined(__ANDROID__) && !defined(__APPLE__)
85 // X11 configuration file in plain text format (obsolete - doesn't exists in modern distributives)
86 static Standard_CString myFontServiceConf[] = {"/etc/X11/fs/config",
87 "/usr/X11R6/lib/X11/fs/config",
88 "/usr/X11/lib/X11/fs/config",
94 // default fonts paths in Mac OS X
95 static Standard_CString myDefaultFontsDirs[] = {"/System/Library/Fonts",
100 // default fonts paths in most Unix systems (Linux and others)
101 static Standard_CString myDefaultFontsDirs[] = {"/system/fonts", // Android
103 "/usr/local/share/fonts",
108 static void addDirsRecursively (const OSD_Path& thePath,
109 NCollection_Map<TCollection_AsciiString>& theDirsMap)
111 TCollection_AsciiString aDirName;
112 thePath.SystemName (aDirName);
113 if (!theDirsMap.Add (aDirName))
118 for (OSD_DirectoryIterator aDirIterator (thePath, "*"); aDirIterator.More(); aDirIterator.Next())
120 OSD_Path aChildDirPath;
121 aDirIterator.Values().Path (aChildDirPath);
123 TCollection_AsciiString aChildDirName;
124 aChildDirPath.SystemName (aChildDirName);
125 if (!aChildDirName.IsEqual (".") && !aChildDirName.IsEqual (".."))
127 aChildDirName = aDirName + "/" + aChildDirName;
128 OSD_Path aPath (aChildDirName);
129 addDirsRecursively (aPath, theDirsMap);
134 } // anonymous namespace
138 // =======================================================================
139 // function : checkFont
141 // =======================================================================
142 static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib,
143 const Standard_CString theFontPath)
146 FT_Error aFaceError = FT_New_Face (theFTLib->Instance(), theFontPath, 0, &aFontFace);
147 if (aFaceError != FT_Err_Ok)
152 Font_FontAspect anAspect = Font_FA_Regular;
153 if (aFontFace->style_flags == (FT_STYLE_FLAG_ITALIC | FT_STYLE_FLAG_BOLD))
155 anAspect = Font_FA_BoldItalic;
157 else if (aFontFace->style_flags == FT_STYLE_FLAG_ITALIC)
159 anAspect = Font_FA_Italic;
161 else if (aFontFace->style_flags == FT_STYLE_FLAG_BOLD)
163 anAspect = Font_FA_Bold;
166 Handle(Font_SystemFont) aResult;
167 if (aFontFace->family_name != NULL // skip broken fonts (error in FreeType?)
168 && FT_Select_Charmap (aFontFace, ft_encoding_unicode) == 0) // Font_FTFont supports only UNICODE fonts
170 aResult = new Font_SystemFont (aFontFace->family_name);
171 aResult->SetFontPath (anAspect, theFontPath);
172 // automatically identify some known single-line fonts
173 aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
176 FT_Done_Face (aFontFace);
181 // =======================================================================
182 // function : GetInstance
184 // =======================================================================
185 Handle(Font_FontMgr) Font_FontMgr::GetInstance()
187 static Handle(Font_FontMgr) _mgr;
190 _mgr = new Font_FontMgr();
196 // =======================================================================
197 // function : addFontAlias
199 // =======================================================================
200 void Font_FontMgr::addFontAlias (const TCollection_AsciiString& theAliasName,
201 const Handle(Font_FontAliasSequence)& theAliases,
202 Font_FontAspect theAspect)
204 if (theAliases.IsNull()
205 || theAliases->IsEmpty())
210 Handle(Font_FontAliasSequence) anAliases = theAliases;
211 if (theAspect != Font_FA_Undefined)
213 anAliases = new Font_FontAliasSequence();
214 for (Font_FontAliasSequence::Iterator anAliasIter (*theAliases); anAliasIter.More(); anAliasIter.Next())
216 const TCollection_AsciiString& aName = anAliasIter.Value().FontName;
217 anAliases->Append (Font_FontAlias (aName, theAspect));
221 TCollection_AsciiString anAliasName (theAliasName);
222 anAliasName.LowerCase();
223 myFontAliases.Bind (anAliasName, anAliases);
226 // =======================================================================
227 // function : Font_FontMgr
229 // =======================================================================
230 Font_FontMgr::Font_FontMgr()
231 : myToTraceAliases (Standard_False)
233 Handle(Font_FontAliasSequence) aMono = new Font_FontAliasSequence();
234 Handle(Font_FontAliasSequence) aSerif = new Font_FontAliasSequence();
235 Handle(Font_FontAliasSequence) aSans = new Font_FontAliasSequence();
236 Handle(Font_FontAliasSequence) aSymbol = new Font_FontAliasSequence();
237 Handle(Font_FontAliasSequence) aScript = new Font_FontAliasSequence();
238 Handle(Font_FontAliasSequence) aWinDin = new Font_FontAliasSequence();
239 Handle(Font_FontAliasSequence) anIris = new Font_FontAliasSequence();
240 Handle(Font_FontAliasSequence) aCJK = new Font_FontAliasSequence();
241 Handle(Font_FontAliasSequence) aKorean = new Font_FontAliasSequence();
243 // best matches - pre-installed on Windows, some of them are pre-installed on macOS,
244 // and sometimes them can be found installed on other systems (by user)
245 aMono ->Append (Font_FontAlias ("courier new"));
246 aSerif ->Append (Font_FontAlias ("times new roman"));
247 aSans ->Append (Font_FontAlias ("arial"));
248 aSymbol->Append (Font_FontAlias ("symbol"));
249 aScript->Append (Font_FontAlias ("script"));
250 aWinDin->Append (Font_FontAlias ("wingdings"));
251 anIris ->Append (Font_FontAlias ("lucida console"));
253 #if defined(__ANDROID__)
254 // Noto font family is usually installed on Android 6+ devices
255 aMono ->Append (Font_FontAlias ("noto mono"));
256 aSerif ->Append (Font_FontAlias ("noto serif"));
257 // Droid font family is usually installed on Android 4+ devices
258 aMono ->Append (Font_FontAlias ("droid sans mono"));
259 aSerif ->Append (Font_FontAlias ("droid serif"));
260 aSans ->Append (Font_FontAlias ("roboto")); // actually DroidSans.ttf
261 #elif !defined(_WIN32) && !defined(__APPLE__) //X11
262 aSerif ->Append (Font_FontAlias ("times"));
263 aSans ->Append (Font_FontAlias ("helvetica"));
264 // GNU FreeFonts family is usually installed on Linux
265 aMono ->Append (Font_FontAlias ("freemono"));
266 aSerif ->Append (Font_FontAlias ("freeserif"));
267 aSans ->Append (Font_FontAlias ("freesans"));
268 // DejaVu font family is usually installed on Linux
269 aMono ->Append (Font_FontAlias ("dejavu sans mono"));
270 aSerif ->Append (Font_FontAlias ("dejavu serif"));
271 aSans ->Append (Font_FontAlias ("dejavu sans"));
274 // default CJK (Chinese/Japanese/Korean) fonts
275 aCJK ->Append (Font_FontAlias ("simsun")); // Windows
276 aCJK ->Append (Font_FontAlias ("droid sans fallback")); // Android, Linux
277 aCJK ->Append (Font_FontAlias ("noto sans sc")); // Android
280 aKorean->Append (Font_FontAlias ("malgun gothic")); // introduced since Vista
281 aKorean->Append (Font_FontAlias ("gulim")); // used on older systems (Windows XP)
282 #elif defined(__APPLE__)
283 aKorean->Append (Font_FontAlias ("applegothic"));
284 aKorean->Append (Font_FontAlias ("stfangsong"));
286 aKorean->Append (Font_FontAlias ("nanumgothic")); // Android, Linux
287 aKorean->Append (Font_FontAlias ("noto sans kr")); // Android
288 aKorean->Append (Font_FontAlias ("nanummyeongjo")); // Linux
289 aKorean->Append (Font_FontAlias ("noto serif cjk jp")); // Linux
290 aKorean->Append (Font_FontAlias ("noto sans cjk jp")); // Linux
292 addFontAlias ("mono", aMono);
293 addFontAlias ("courier", aMono); // Font_NOF_ASCII_MONO
294 addFontAlias ("monospace", aMono); // Font_NOF_MONOSPACE
295 addFontAlias ("rock", aSans); // Font_NOF_CARTOGRAPHIC_SIMPLEX
296 addFontAlias ("sansserif", aSans); // Font_NOF_SANS_SERIF
297 addFontAlias ("sans-serif", aSans);
298 addFontAlias ("sans", aSans);
299 addFontAlias ("arial", aSans);
300 addFontAlias ("times", aSerif);
301 addFontAlias ("serif", aSerif); // Font_NOF_SERIF
302 addFontAlias ("times-roman", aSerif); // Font_NOF_ASCII_SIMPLEX
303 addFontAlias ("times-bold", aSerif, Font_FA_Bold); // Font_NOF_ASCII_DUPLEX
304 addFontAlias ("times-italic", aSerif, Font_FA_Italic); // Font_NOF_ASCII_ITALIC_COMPLEX
305 addFontAlias ("times-bolditalic", aSerif, Font_FA_BoldItalic); // Font_NOF_ASCII_ITALIC_TRIPLEX
306 addFontAlias ("symbol", aSymbol); // Font_NOF_GREEK_MONO
307 addFontAlias ("iris", anIris); // Font_NOF_KANJI_MONO
308 addFontAlias ("korean", aKorean); // Font_NOF_KOREAN
309 addFontAlias ("cjk", aCJK); // Font_NOF_CJK
310 addFontAlias ("nsimsun", aCJK);
311 addFontAlias (Font_NOF_SYMBOL_MONO, aWinDin);
312 addFontAlias (Font_NOF_ASCII_SCRIPT_SIMPLEX, aScript);
314 myFallbackAlias = aSans;
319 // =======================================================================
320 // function : CheckFont
322 // =======================================================================
323 Handle(Font_SystemFont) Font_FontMgr::CheckFont (Standard_CString theFontPath) const
325 Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
326 return checkFont (aFtLibrary, theFontPath);
329 // =======================================================================
330 // function : RegisterFont
332 // =======================================================================
333 Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theFont,
334 const Standard_Boolean theToOverride)
336 if (theFont.IsNull())
338 return Standard_False;
341 const Standard_Integer anOldIndex = myFontMap.FindIndex (theFont);
344 myFontMap.Add (theFont);
345 return Standard_True;
348 Handle(Font_SystemFont) anOldFont = myFontMap.FindKey (anOldIndex);
349 for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
351 if (anOldFont->FontPath ((Font_FontAspect )anAspectIter).IsEqual (theFont->FontPath ((Font_FontAspect )anAspectIter)))
355 else if (theToOverride
356 || !anOldFont->HasFontAspect ((Font_FontAspect )anAspectIter))
358 anOldFont->SetFontPath ((Font_FontAspect )anAspectIter, theFont->FontPath ((Font_FontAspect )anAspectIter));
360 else if (theFont->HasFontAspect ((Font_FontAspect )anAspectIter))
362 return Standard_False;
365 return Standard_True;
368 // =======================================================================
369 // function : InitFontDataBase
371 // =======================================================================
372 void Font_FontMgr::InitFontDataBase()
375 Handle(Font_FTLibrary) aFtLibrary;
377 #if defined(OCCT_UWP)
378 // system font files are not accessible
380 #elif defined(_WIN32)
382 // font directory is placed in "C:\Windows\Fonts\"
383 UINT aStrLength = GetSystemWindowsDirectoryA (NULL, 0);
389 char* aWinDir = new char[aStrLength];
390 GetSystemWindowsDirectoryA (aWinDir, aStrLength);
391 TCollection_AsciiString aFontsDir (aWinDir);
392 aFontsDir.AssignCat ("\\Fonts\\");
395 // read fonts list from registry
397 if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
398 0, KEY_READ, &aFontsKey) != ERROR_SUCCESS)
403 NCollection_Map<TCollection_AsciiString> aSupportedExtensions;
404 for (Standard_Integer anIter = 0; Font_FontMgr_Extensions[anIter] != NULL; ++anIter)
406 Standard_CString anExt = Font_FontMgr_Extensions[anIter];
407 aSupportedExtensions.Add (TCollection_AsciiString (anExt));
410 aFtLibrary = new Font_FTLibrary();
411 static const DWORD aBufferSize = 256;
412 char aNameBuff[aBufferSize];
413 char aPathBuff[aBufferSize];
414 DWORD aNameSize = aBufferSize;
415 DWORD aPathSize = aBufferSize;
416 for (DWORD anIter = 0;
417 RegEnumValueA (aFontsKey, anIter,
418 aNameBuff, &aNameSize, NULL, NULL,
419 (LPBYTE )aPathBuff, &aPathSize) != ERROR_NO_MORE_ITEMS;
420 ++anIter, aNameSize = aBufferSize, aPathSize = aBufferSize)
422 aPathBuff[(aPathSize < aBufferSize) ? aPathSize : (aBufferSize - 1)] = '\0'; // ensure string is NULL-terminated
424 TCollection_AsciiString aFontName (aNameBuff), aFontPath (aPathBuff);
425 if (aFontPath.Search ("\\") == -1)
427 aFontPath.Insert (1, aFontsDir); // make absolute path
430 // check file extension is in list of supported
431 const Standard_Integer anExtensionPosition = aFontPath.SearchFromEnd (".") + 1;
432 if (anExtensionPosition > 0 && anExtensionPosition < aFontPath.Length())
434 TCollection_AsciiString aFontExtension = aFontPath.SubString (anExtensionPosition, aFontPath.Length());
435 aFontExtension.LowerCase();
436 if (aSupportedExtensions.Contains (aFontExtension))
438 if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
440 RegisterFont (aNewFont, false);
446 // close registry key
447 RegCloseKey (aFontsKey);
451 NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
452 #if !defined(__ANDROID__) && !defined(__APPLE__)
453 const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
455 // read fonts directories from font service config file (obsolete)
456 for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
458 const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
459 OSD_File aFile (aFileOfFontsPath);
465 aFile.Open (OSD_ReadOnly, aProtectRead);
471 Standard_Integer aNByte = 256;
472 Standard_Integer aNbyteRead;
473 TCollection_AsciiString aStr; // read string with information
474 while (!aFile.IsAtEnd())
476 Standard_Integer aLocation = -1;
477 Standard_Integer aPathLocation = -1;
479 aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
480 aLocation = aStr.Search ("catalogue=");
483 aLocation = aStr.Search ("catalogue =");
486 aPathLocation = aStr.Search ("/");
487 if (aLocation > 0 && aPathLocation > 0)
489 aStr = aStr.Split (aPathLocation - 1);
490 TCollection_AsciiString aFontPath;
491 Standard_Integer aPathNumber = 1;
494 // Getting directory paths, which can be splitted by "," or ":"
495 aFontPath = aStr.Token (":,", aPathNumber);
496 aFontPath.RightAdjust();
497 if (!aFontPath.IsEmpty())
499 OSD_Path aPath(aFontPath);
500 addDirsRecursively (aPath, aMapOfFontsDirs);
504 while (!aFontPath.IsEmpty());
511 // append default directories
512 for (Standard_Integer anIter = 0; myDefaultFontsDirs[anIter] != NULL; ++anIter)
514 Standard_CString anItem = myDefaultFontsDirs[anIter];
515 TCollection_AsciiString aPathStr (anItem);
516 OSD_Path aPath (aPathStr);
517 addDirsRecursively (aPath, aMapOfFontsDirs);
520 NCollection_Map<TCollection_AsciiString> aSupportedExtensions;
521 for (Standard_Integer anIter = 0; Font_FontMgr_Extensions[anIter] != NULL; ++anIter)
523 Standard_CString anExt = Font_FontMgr_Extensions[anIter];
524 aSupportedExtensions.Add (TCollection_AsciiString (anExt));
527 aFtLibrary = new Font_FTLibrary();
528 for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
529 anIter.More(); anIter.Next())
531 #if !defined(__ANDROID__) && !defined(__APPLE__)
532 OSD_File aReadFile (anIter.Value() + "/fonts.dir");
533 if (!aReadFile.Exists())
536 OSD_Path aFolderPath (anIter.Value());
537 for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
539 OSD_Path aFontFilePath;
540 aFileIter.Values().Path (aFontFilePath);
542 TCollection_AsciiString aFontFileName;
543 aFontFilePath.SystemName (aFontFileName);
544 aFontFileName = anIter.Value() + "/" + aFontFileName;
546 if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString()))
548 RegisterFont (aNewFont, false);
552 #if !defined(__ANDROID__) && !defined(__APPLE__)
556 aReadFile.Open (OSD_ReadOnly, aProtectRead);
557 if (!aReadFile.IsOpen())
559 continue; // invalid fonts directory
562 Standard_Integer aNbyteRead, aNByte = 256;
563 TCollection_AsciiString aLine (aNByte);
564 Standard_Boolean isFirstLine = Standard_True;
565 const TCollection_AsciiString anEncoding ("iso8859-1\n");
566 while (!aReadFile.IsAtEnd())
568 aReadFile.ReadLine (aLine, aNByte, aNbyteRead);
571 // first line contains the number of fonts in this file
572 // just ignoring it...
573 isFirstLine = Standard_False;
577 Standard_Integer anExtensionPosition = aLine.Search (".") + 1;
578 if (anExtensionPosition == 0)
580 continue; // can't find extension position in the font description
583 Standard_Integer anEndOfFileName = aLine.Location (" ", anExtensionPosition, aLine.Length()) - 1;
584 if (anEndOfFileName < 0 || anEndOfFileName < anExtensionPosition)
586 continue; // font description have empty extension
589 TCollection_AsciiString aFontExtension = aLine.SubString (anExtensionPosition, anEndOfFileName);
590 aFontExtension.LowerCase();
591 if (aSupportedExtensions.Contains (aFontExtension) && (aLine.Search (anEncoding) > 0))
593 // In current implementation use fonts with ISO-8859-1 coding page.
594 // OCCT not give to manage coding page by means of programm interface.
595 // TODO: make high level interface for choosing necessary coding page.
596 TCollection_AsciiString aXLFD (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
597 TCollection_AsciiString aFontPath (anIter.Value().ToCString());
598 if (aFontPath.SearchFromEnd ("/") != aFontPath.Length())
600 aFontPath.AssignCat ("/");
602 TCollection_AsciiString aFontFileName (aLine.SubString (1, anEndOfFileName));
603 aFontPath.AssignCat (aFontFileName);
604 if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
606 RegisterFont (aNewFont, false);
608 && aXLFD.Search ("-0-0-0-0-") != -1) // ignore non-resizable fonts
610 const TCollection_AsciiString anXName = aXLFD.Token ("-", 2);
611 Font_FontAspect anXAspect = Font_FA_Regular;
612 if (aXLFD.Token ("-", 3).IsEqual ("bold")
613 && (aXLFD.Token ("-", 4).IsEqual ("i")
614 || aXLFD.Token ("-", 4).IsEqual ("o")))
616 anXAspect = Font_FA_BoldItalic;
618 else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
620 anXAspect = Font_FA_Bold;
622 else if (aXLFD.Token ("-", 4).IsEqual ("i")
623 || aXLFD.Token ("-", 4).IsEqual ("o"))
625 anXAspect = Font_FA_Italic;
628 Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (anXName);
629 aNewFontFromXLFD->SetFontPath (anXAspect, aFontPath);
630 if (!aNewFont->IsEqual (aNewFontFromXLFD))
632 RegisterFont (aNewFontFromXLFD, false);
644 // =======================================================================
645 // function : GetAvailableFontsNames
647 // =======================================================================
648 void Font_FontMgr::GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const
650 theFontsNames.Clear();
651 for (NCollection_IndexedMap<Handle(Font_SystemFont), Font_SystemFont>::Iterator aFontIter (myFontMap);
652 aFontIter.More(); aFontIter.Next())
654 const Handle(Font_SystemFont)& aFont = aFontIter.Value();
655 theFontsNames.Append (new TCollection_HAsciiString(aFont->FontName()));
659 // =======================================================================
660 // function : GetFont
662 // =======================================================================
663 Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiString)& theFontName,
664 const Font_FontAspect theFontAspect,
665 const Standard_Integer theFontSize) const
667 if ((theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
669 return Handle(Font_SystemFont)();
672 Handle(Font_SystemFont) aFont = myFontMap.Find (theFontName->String());
673 return (aFont.IsNull()
674 || theFontAspect == Font_FontAspect_UNDEFINED
675 || aFont->HasFontAspect (theFontAspect))
677 : Handle(Font_SystemFont)();
680 // =======================================================================
681 // function : GetFont
683 // =======================================================================
684 Handle(Font_SystemFont) Font_FontMgr::GetFont (const TCollection_AsciiString& theFontName) const
686 return myFontMap.Find (theFontName);
689 // =======================================================================
690 // function : FindFont
692 // =======================================================================
693 Handle(Font_SystemFont) Font_FontMgr::FindFont (const TCollection_AsciiString& theFontName,
694 Font_FontAspect& theFontAspect) const
696 TCollection_AsciiString aFontName (theFontName);
697 aFontName.LowerCase();
698 Handle(Font_SystemFont) aFont = myFontMap.Find (aFontName);
704 // Trying to use font names mapping
705 Handle(Font_FontAliasSequence) anAliases;
706 const Standard_Boolean hasAliases = myFontAliases.Find (aFontName, anAliases)
707 && !anAliases.IsNull()
708 && !anAliases->IsEmpty();
712 anAliases = myFallbackAlias;
715 bool isAliasUsed = false, isBestAlias = false;
716 if (!anAliases.IsNull()
717 && !anAliases->IsEmpty())
719 for (Font_FontAliasSequence::Iterator anAliasIter (*anAliases); anAliasIter.More(); anAliasIter.Next())
721 const Font_FontAlias& anAlias = anAliasIter.Value();
722 if (Handle(Font_SystemFont) aFont2 = myFontMap.Find (anAlias.FontName))
730 if ((anAlias.FontAspect != Font_FontAspect_UNDEFINED
731 && aFont2->HasFontAspect (anAlias.FontAspect)))
733 // special case - alias refers to styled font (e.g. "times-bold")
735 theFontAspect = anAlias.FontAspect;
738 else if (anAlias.FontAspect == Font_FontAspect_UNDEFINED
739 && (theFontAspect == Font_FontAspect_UNDEFINED
740 || aFont2->HasFontAspect (theFontAspect)))
749 if (isAliasUsed && myToTraceAliases)
751 Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, using font alias '") + aFont->FontName() + "'"
752 " instead of requested '" + theFontName +"'", Message_Trace);
763 // try finding ANY font in case if even default fallback alias myFallbackAlias cannot be found
764 aFont = myFontMap.Find (TCollection_AsciiString());
768 Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, error: unable to find any font!", Message_Fail));
769 return Handle(Font_SystemFont)();
772 if ((theFontAspect != Font_FA_Undefined
773 && !aFont->HasFontAspect (theFontAspect))
774 || (!aFontName.IsEmpty()
775 && !aFontName.IsEqual (aFont->FontKey())))
777 TCollection_AsciiString aDesc = TCollection_AsciiString() + "'" + theFontName + "'"
778 + TCollection_AsciiString() + " [" + Font_FontMgr::FontAspectToString (theFontAspect) + "]";
779 Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, warning: unable to find font ")
780 + aDesc + "; " + aFont->ToString() + " is used instead");
785 // =======================================================================
786 // function : Font_FontMap::Find
788 // =======================================================================
789 Handle(Font_SystemFont) Font_FontMgr::Font_FontMap::Find (const TCollection_AsciiString& theFontName) const
793 return Handle(Font_SystemFont)();
795 else if (theFontName.IsEmpty())
797 return FindKey (1); // return any font
800 TCollection_AsciiString aFontName (theFontName);
801 aFontName.LowerCase();
802 for (IndexedMapNode* aNodeIter = (IndexedMapNode* )myData1[::HashCode (aFontName, NbBuckets())];
803 aNodeIter != NULL; aNodeIter = (IndexedMapNode* )aNodeIter->Next())
805 const Handle(Font_SystemFont)& aKey = aNodeIter->Key1();
806 if (aKey->FontKey().IsEqual (aFontName))
811 return Handle(Font_SystemFont)();