0030439: Visualization - extend fonts search within Font_FontMgr::FindFont() on Linux
authorkgv <kgv@opencascade.com>
Thu, 10 Jan 2019 20:10:51 +0000 (23:10 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 21 Jan 2019 13:15:33 +0000 (16:15 +0300)
Font_FontMgr has been redesigned to:
- Store fonts in a map instead a list.
- Allow mapping multiple fonts to a single alias.
- Log informative message about usage of non-requested font (fallback).
- Register all font files within standard folders on Linux when "fonts.dir" is not found.
- Prefer specific alias ("serif") as default fallback font instead of arbitrary one in a system.

A couple of obsolete and broken font aliases have been removed;
instead, new aliases of fonts popular on Linux platform have been added.

Font_NameOfFont.hxx has been extended with more neutral aliases
"monospace", "serif", "sans-serif", "cjk" and "korean".

Font_FontAspect enumeration values have been renamed Font_FA_ -> Font_FontAspect_
with old values preserved as alias.

Font_SystemFont has been extended with a list of paths to Font_FontAspect styles,
so that entire Font Family is now defined within a single Font_SystemFont instance.
Non-resizable fonts are now ignored by Font Manager.

16 files changed:
src/Font/Font_FTFont.cxx
src/Font/Font_FontAspect.hxx
src/Font/Font_FontMgr.cxx
src/Font/Font_FontMgr.hxx
src/Font/Font_NameOfFont.hxx
src/Font/Font_SystemFont.cxx
src/Font/Font_SystemFont.hxx
src/OpenGl/OpenGl_Text.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
tests/3rdparty/fonts/A2
tests/3rdparty/fonts/A6
tests/3rdparty/fonts/A8
tests/3rdparty/fonts/B1
tests/3rdparty/fonts/B2
tests/bugs/vis/bug22149
tests/demo/draw/bug23745

index 6d97511..87ab2b7 100755 (executable)
@@ -117,11 +117,12 @@ bool Font_FTFont::Init (const NCollection_String& theFontName,
                         const unsigned int        theResolution)
 {
   Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
-  const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
-  if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize))
+  const TCollection_AsciiString aFontName (theFontName.ToCString());
+  Font_FontAspect aFontAspect = theFontAspect;
+  if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, aFontAspect))
   {
     myIsSingleLine = aRequestedFont->IsSingleStrokeFont();
-    return Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
+    return Font_FTFont::Init (aRequestedFont->FontPathAny (aFontAspect).ToCString(), thePointSize, theResolution);
   }
   return false;
 }
index 269bf3e..c20ab70 100644 (file)
 //! Specifies aspect of system font.
 enum Font_FontAspect
 {
-Font_FA_Undefined,
-Font_FA_Regular,
-Font_FA_Bold,
-Font_FA_Italic,
-Font_FA_BoldItalic
+  Font_FontAspect_UNDEFINED = -1, //!< special value reserved for undefined aspect
+  Font_FontAspect_Regular   =  0, //!< normal (regular) aspect
+  Font_FontAspect_Bold,           //!< bold aspect
+  Font_FontAspect_Italic,         //!< italic aspect
+  Font_FontAspect_BoldItalic,     //!< bold+italic aspect
+
+  // old aliases
+  Font_FA_Undefined  = Font_FontAspect_UNDEFINED,
+  Font_FA_Regular    = Font_FontAspect_Regular,
+  Font_FA_Bold       = Font_FontAspect_Bold,
+  Font_FA_Italic     = Font_FontAspect_Italic,
+  Font_FA_BoldItalic = Font_FontAspect_BoldItalic
 };
+enum { Font_FontAspect_NB = Font_FontAspect_BoldItalic + 1 };
 
 #endif // _Font_FontAspect_HeaderFile
index d49a676..ae3a215 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <Font_FontMgr.hxx>
+
+#include <Font_NameOfFont.hxx>
 #include <Font_FTLibrary.hxx>
 #include <Font_SystemFont.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
 #include <NCollection_List.hxx>
 #include <NCollection_Map.hxx>
 #include <OSD_Environment.hxx>
 #include FT_FREETYPE_H
 IMPLEMENT_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
 
-struct Font_FontMgr_FontAliasMapNode
-{
-  const char *    EnumName;
-  const char *    FontName;
-  Font_FontAspect FontAspect;
-};
-
-static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
-{
-
-#if defined(_WIN32) || defined(__APPLE__)
-
-  { "Courier"                  , "Courier New"    , Font_FA_Regular },
-  { "Times-Roman"              , "Times New Roman", Font_FA_Regular  },
-  { "Times-Bold"               , "Times New Roman", Font_FA_Bold },
-  { "Times-Italic"             , "Times New Roman", Font_FA_Italic  },
-  { "Times-BoldItalic"         , "Times New Roman", Font_FA_BoldItalic  },
-  { "ZapfChancery-MediumItalic", "Script"         , Font_FA_Regular  },
-  { "Symbol"                   , "Symbol"         , Font_FA_Regular  },
-  { "ZapfDingbats"             , "WingDings"      , Font_FA_Regular  },
-  { "Rock"                     , "Arial"          , Font_FA_Regular  },
-  { "Iris"                     , "Lucida Console" , Font_FA_Regular  },
-  { "NSimSun"                  , "SimSun"         , Font_FA_Regular  }
-
-#elif defined(__ANDROID__)
-
-  { "Courier"                  , "Droid Sans Mono", Font_FA_Regular },
-  { "Times-Roman"              , "Droid Serif"    , Font_FA_Regular  },
-  { "Times-Bold"               , "Droid Serif"    , Font_FA_Bold },
-  { "Times-Italic"             , "Droid Serif"    , Font_FA_Italic  },
-  { "Times-BoldItalic"         , "Droid Serif"    , Font_FA_BoldItalic  },
-  { "Arial"                    , "Roboto"         , Font_FA_Regular  },
-
-#else   //X11
-
-  { "Courier"                  , "Courier"      , Font_FA_Regular },
-  { "Times-Roman"              , "Times"        , Font_FA_Regular  },
-  { "Times-Bold"               , "Times"        , Font_FA_Bold },
-  { "Times-Italic"             , "Times"        , Font_FA_Italic  },
-  { "Times-BoldItalic"         , "Times"        , Font_FA_BoldItalic  },
-  { "Arial"                    , "Helvetica"    , Font_FA_Regular  },
-  { "ZapfChancery-MediumItalic", "-adobe-itc zapf chancery-medium-i-normal--*-*-*-*-*-*-iso8859-1"              , Font_FA_Regular  },
-  { "Symbol"                   , "-adobe-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific"                , Font_FA_Regular  },
-  { "ZapfDingbats"             , "-adobe-itc zapf dingbats-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific"     , Font_FA_Regular  },
-  { "Rock"                     , "-sgi-rock-medium-r-normal--*-*-*-*-p-*-iso8859-1"                             , Font_FA_Regular  },
-  { "Iris"                     , "--iris-medium-r-normal--*-*-*-*-m-*-iso8859-1"                                , Font_FA_Regular  }
-#endif
-
-};
-
-#define NUM_FONT_ENTRIES (int)(sizeof(Font_FontMgr_MapOfFontsAliases)/sizeof(Font_FontMgr_FontAliasMapNode))
-
 #if defined(_WIN32)
 
   #include <windows.h>
@@ -216,11 +167,10 @@ static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib
   if (aFontFace->family_name != NULL                           // skip broken fonts (error in FreeType?)
    && FT_Select_Charmap (aFontFace, ft_encoding_unicode) == 0) // Font_FTFont supports only UNICODE fonts
   {
-    Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aFontFace->family_name);
-    Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (theFontPath);
-    aResult = new Font_SystemFont (aFontName, anAspect, aFontPath);
+    aResult = new Font_SystemFont (aFontFace->family_name);
+    aResult->SetFontPath (anAspect, theFontPath);
     // automatically identify some known single-line fonts
-    aResult->SetSingleStrokeFont (aFontName->String().StartsWith ("OLF "));
+    aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
   }
 
   FT_Done_Face (aFontFace);
@@ -244,11 +194,125 @@ Handle(Font_FontMgr) Font_FontMgr::GetInstance()
 }
 
 // =======================================================================
+// function : addFontAlias
+// purpose  :
+// =======================================================================
+void Font_FontMgr::addFontAlias (const TCollection_AsciiString& theAliasName,
+                                 const Handle(Font_FontAliasSequence)& theAliases,
+                                 Font_FontAspect theAspect)
+{
+  if (theAliases.IsNull()
+   || theAliases->IsEmpty())
+  {
+    return;
+  }
+
+  Handle(Font_FontAliasSequence) anAliases = theAliases;
+  if (theAspect != Font_FA_Undefined)
+  {
+    anAliases = new Font_FontAliasSequence();
+    for (Font_FontAliasSequence::Iterator anAliasIter (*theAliases); anAliasIter.More(); anAliasIter.Next())
+    {
+      const TCollection_AsciiString& aName = anAliasIter.Value().FontName;
+      anAliases->Append (Font_FontAlias (aName, theAspect));
+    }
+  }
+
+  TCollection_AsciiString anAliasName (theAliasName);
+  anAliasName.LowerCase();
+  myFontAliases.Bind (anAliasName, anAliases);
+}
+
+// =======================================================================
 // function : Font_FontMgr
 // purpose  :
 // =======================================================================
 Font_FontMgr::Font_FontMgr()
+: myToTraceAliases (Standard_False)
 {
+  Handle(Font_FontAliasSequence) aMono   = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) aSerif  = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) aSans   = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) aSymbol = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) aScript = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) aWinDin = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) anIris  = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) aCJK    = new Font_FontAliasSequence();
+  Handle(Font_FontAliasSequence) aKorean = new Font_FontAliasSequence();
+
+  // best matches - pre-installed on Windows, some of them are pre-installed on macOS,
+  // and sometimes them can be found installed on other systems (by user)
+  aMono  ->Append (Font_FontAlias ("courier new"));
+  aSerif ->Append (Font_FontAlias ("times new roman"));
+  aSans  ->Append (Font_FontAlias ("arial"));
+  aSymbol->Append (Font_FontAlias ("symbol"));
+  aScript->Append (Font_FontAlias ("script"));
+  aWinDin->Append (Font_FontAlias ("wingdings"));
+  anIris ->Append (Font_FontAlias ("lucida console"));
+
+#if defined(__ANDROID__)
+  // Noto font family is usually installed on Android 6+ devices
+  aMono  ->Append (Font_FontAlias ("noto mono"));
+  aSerif ->Append (Font_FontAlias ("noto serif"));
+  // Droid font family is usually installed on Android 4+ devices
+  aMono  ->Append (Font_FontAlias ("droid sans mono"));
+  aSerif ->Append (Font_FontAlias ("droid serif"));
+  aSans  ->Append (Font_FontAlias ("roboto")); // actually DroidSans.ttf
+#elif !defined(_WIN32) && !defined(__APPLE__) //X11
+  aSerif ->Append (Font_FontAlias ("times"));
+  aSans  ->Append (Font_FontAlias ("helvetica"));
+  // GNU FreeFonts family is usually installed on Linux
+  aMono  ->Append (Font_FontAlias ("freemono"));
+  aSerif ->Append (Font_FontAlias ("freeserif"));
+  aSans  ->Append (Font_FontAlias ("freesans"));
+  // DejaVu font family is usually installed on Linux
+  aMono  ->Append (Font_FontAlias ("dejavu sans mono"));
+  aSerif ->Append (Font_FontAlias ("dejavu serif"));
+  aSans  ->Append (Font_FontAlias ("dejavu sans"));
+#endif
+
+  // default CJK (Chinese/Japanese/Korean) fonts
+  aCJK   ->Append (Font_FontAlias ("simsun"));        // Windows
+  aCJK   ->Append (Font_FontAlias ("droid sans fallback")); // Android, Linux
+  aCJK   ->Append (Font_FontAlias ("noto sans sc"));  // Android
+
+#if defined(_WIN32)
+  aKorean->Append (Font_FontAlias ("malgun gothic")); // introduced since Vista
+  aKorean->Append (Font_FontAlias ("gulim"));         // used on older systems (Windows XP)
+#elif defined(__APPLE__)
+  aKorean->Append (Font_FontAlias ("applegothic"));
+  aKorean->Append (Font_FontAlias ("stfangsong"));
+#endif
+  aKorean->Append (Font_FontAlias ("nanumgothic"));   // Android, Linux
+  aKorean->Append (Font_FontAlias ("noto sans kr"));  // Android
+  aKorean->Append (Font_FontAlias ("nanummyeongjo")); // Linux
+  aKorean->Append (Font_FontAlias ("noto serif cjk jp")); // Linux
+  aKorean->Append (Font_FontAlias ("noto sans cjk jp")); // Linux
+
+  addFontAlias ("mono",              aMono);
+  addFontAlias ("courier",           aMono);                      // Font_NOF_ASCII_MONO
+  addFontAlias ("monospace",         aMono);                      // Font_NOF_MONOSPACE
+  addFontAlias ("rock",              aSans);                      // Font_NOF_CARTOGRAPHIC_SIMPLEX
+  addFontAlias ("sansserif",         aSans);                      // Font_NOF_SANS_SERIF
+  addFontAlias ("sans-serif",        aSans);
+  addFontAlias ("sans",              aSans);
+  addFontAlias ("arial",             aSans);
+  addFontAlias ("times",             aSerif);
+  addFontAlias ("serif",             aSerif);                     // Font_NOF_SERIF
+  addFontAlias ("times-roman",       aSerif);                     // Font_NOF_ASCII_SIMPLEX
+  addFontAlias ("times-bold",        aSerif, Font_FA_Bold);       // Font_NOF_ASCII_DUPLEX
+  addFontAlias ("times-italic",      aSerif, Font_FA_Italic);     // Font_NOF_ASCII_ITALIC_COMPLEX
+  addFontAlias ("times-bolditalic",  aSerif, Font_FA_BoldItalic); // Font_NOF_ASCII_ITALIC_TRIPLEX
+  addFontAlias ("symbol",            aSymbol);                    // Font_NOF_GREEK_MONO
+  addFontAlias ("iris",              anIris);                     // Font_NOF_KANJI_MONO
+  addFontAlias ("korean",            aKorean);                    // Font_NOF_KOREAN
+  addFontAlias ("cjk",               aCJK);                       // Font_NOF_CJK
+  addFontAlias ("nsimsun",           aCJK);
+  addFontAlias (Font_NOF_SYMBOL_MONO,          aWinDin);
+  addFontAlias (Font_NOF_ASCII_SCRIPT_SIMPLEX, aScript);
+
+  myFallbackAlias = aSans;
+
   InitFontDataBase();
 }
 
@@ -274,39 +338,30 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
     return Standard_False;
   }
 
-  for (Font_NListOfSystemFont::Iterator aFontIter (myListOfFonts);
-       aFontIter.More(); aFontIter.Next())
+  const Standard_Integer anOldIndex = myFontMap.FindIndex (theFont);
+  if (anOldIndex == 0)
+  {
+    myFontMap.Add (theFont);
+    return Standard_True;
+  }
+
+  Handle(Font_SystemFont) anOldFont = myFontMap.FindKey (anOldIndex);
+  for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
   {
-    if (!aFontIter.Value()->FontName()->IsSameString (theFont->FontName(), Standard_False))
+    if (anOldFont->FontPath ((Font_FontAspect )anAspectIter).IsEqual (theFont->FontPath ((Font_FontAspect )anAspectIter)))
     {
       continue;
     }
-
-    if (theFont->FontAspect() != Font_FA_Undefined
-     && aFontIter.Value()->FontAspect() != theFont->FontAspect())
+    else if (theToOverride
+         || !anOldFont->HasFontAspect ((Font_FontAspect )anAspectIter))
     {
-      continue;
+      anOldFont->SetFontPath ((Font_FontAspect )anAspectIter, theFont->FontPath ((Font_FontAspect )anAspectIter));
     }
-
-    if (theFont->FontHeight() == -1 || aFontIter.Value()->FontHeight() == -1
-     || theFont->FontHeight() ==       aFontIter.Value()->FontHeight())
+    else if (theFont->HasFontAspect ((Font_FontAspect )anAspectIter))
     {
-      if (theFont->FontPath()->String() == aFontIter.Value()->FontPath()->String())
-      {
-        return Standard_True;
-      }
-      else if (theToOverride)
-      {
-        myListOfFonts.Remove (aFontIter);
-      }
-      else
-      {
-        return Standard_False;
-      }
+      return Standard_False;
     }
   }
-
-  myListOfFonts.Append (theFont);
   return Standard_True;
 }
 
@@ -316,7 +371,7 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
 // =======================================================================
 void Font_FontMgr::InitFontDataBase()
 {
-  myListOfFonts.Clear();
+  myFontMap.Clear();
   Handle(Font_FTLibrary) aFtLibrary;
 
 #if defined(OCCT_UWP)
@@ -333,8 +388,8 @@ void Font_FontMgr::InitFontDataBase()
 
   char* aWinDir = new char[aStrLength];
   GetSystemWindowsDirectoryA (aWinDir, aStrLength);
-  Handle(TCollection_HAsciiString) aFontsDir = new TCollection_HAsciiString (aWinDir);
-  aFontsDir->AssignCat ("\\Fonts\\");
+  TCollection_AsciiString aFontsDir (aWinDir);
+  aFontsDir.AssignCat ("\\Fonts\\");
   delete[] aWinDir;
 
   // read fonts list from registry
@@ -366,25 +421,23 @@ void Font_FontMgr::InitFontDataBase()
   {
     aPathBuff[(aPathSize < aBufferSize) ? aPathSize : (aBufferSize - 1)] = '\0'; // ensure string is NULL-terminated
 
-    Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aNameBuff);
-    Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (aPathBuff);
-    if (aFontPath->Search ("\\") == -1)
+    TCollection_AsciiString aFontName (aNameBuff), aFontPath (aPathBuff);
+    if (aFontPath.Search ("\\") == -1)
     {
-      aFontPath->Insert (1, aFontsDir); // make absolute path
+      aFontPath.Insert (1, aFontsDir); // make absolute path
     }
 
     // check file extension is in list of supported
-    const Standard_Integer anExtensionPosition = aFontPath->SearchFromEnd (".") + 1;
-    if (anExtensionPosition > 0 && anExtensionPosition < aFontPath->Length())
+    const Standard_Integer anExtensionPosition = aFontPath.SearchFromEnd (".") + 1;
+    if (anExtensionPosition > 0 && anExtensionPosition < aFontPath.Length())
     {
-      Handle(TCollection_HAsciiString) aFontExtension = aFontPath->SubString (anExtensionPosition, aFontPath->Length());
-      aFontExtension->LowerCase();
-      if (aSupportedExtensions.Contains (aFontExtension->String()))
+      TCollection_AsciiString aFontExtension = aFontPath.SubString (anExtensionPosition, aFontPath.Length());
+      aFontExtension.LowerCase();
+      if (aSupportedExtensions.Contains (aFontExtension))
       {
-        Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
-        if (!aNewFont.IsNull())
+        if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
         {
-          myListOfFonts.Append (aNewFont);
+          RegisterFont (aNewFont, false);
         }
       }
     }
@@ -475,28 +528,29 @@ void Font_FontMgr::InitFontDataBase()
   for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
        anIter.More(); anIter.Next())
   {
-  #if defined(__ANDROID__) || defined(__APPLE__)
-    OSD_Path aFolderPath (anIter.Value());
-    for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
+  #if !defined(__ANDROID__) && !defined(__APPLE__)
+    OSD_File aReadFile (anIter.Value() + "/fonts.dir");
+    if (!aReadFile.Exists())
     {
-      OSD_Path aFontFilePath;
-      aFileIter.Values().Path (aFontFilePath);
+  #endif
+      OSD_Path aFolderPath (anIter.Value());
+      for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
+      {
+        OSD_Path aFontFilePath;
+        aFileIter.Values().Path (aFontFilePath);
 
-      TCollection_AsciiString aFontFileName;
-      aFontFilePath.SystemName (aFontFileName);
-      aFontFileName = anIter.Value() + "/" + aFontFileName;
+        TCollection_AsciiString aFontFileName;
+        aFontFilePath.SystemName (aFontFileName);
+        aFontFileName = anIter.Value() + "/" + aFontFileName;
 
-      Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString());
-      if (!aNewFont.IsNull())
-      {
-        myListOfFonts.Append (aNewFont);
+        if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString()))
+        {
+          RegisterFont (aNewFont, false);
+        }
       }
-    }
-  #else
-    OSD_File aReadFile (anIter.Value() + "/fonts.dir");
-    if (!aReadFile.Exists())
-    {
-      continue; // invalid fonts directory
+
+  #if !defined(__ANDROID__) && !defined(__APPLE__)
+      continue;
     }
 
     aReadFile.Open (OSD_ReadOnly, aProtectRead);
@@ -539,34 +593,45 @@ void Font_FontMgr::InitFontDataBase()
         // In current implementation use fonts with ISO-8859-1 coding page.
         // OCCT not give to manage coding page by means of programm interface.
         // TODO: make high level interface for choosing necessary coding page.
-        Handle(TCollection_HAsciiString) aXLFD =
-          new TCollection_HAsciiString (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
-        Handle(TCollection_HAsciiString) aFontPath =
-          new TCollection_HAsciiString (anIter.Value().ToCString());
-        if (aFontPath->SearchFromEnd ("/") != aFontPath->Length())
-        {
-          aFontPath->AssignCat ("/");
-        }
-        Handle(TCollection_HAsciiString) aFontFileName =
-        new TCollection_HAsciiString (aLine.SubString (1, anEndOfFileName));
-        aFontPath->AssignCat (aFontFileName);
-
-        Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (aXLFD, aFontPath);
-        Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
-
-        if (aNewFontFromXLFD->IsValid() && !aNewFont.IsNull() &&
-           !aNewFont->IsEqual (aNewFontFromXLFD))
+        TCollection_AsciiString aXLFD (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
+        TCollection_AsciiString aFontPath (anIter.Value().ToCString());
+        if (aFontPath.SearchFromEnd ("/") != aFontPath.Length())
         {
-          myListOfFonts.Append (aNewFont);
-          myListOfFonts.Append (aNewFontFromXLFD);
+          aFontPath.AssignCat ("/");
         }
-        else if (!aNewFont.IsNull())
+        TCollection_AsciiString aFontFileName (aLine.SubString (1, anEndOfFileName));
+        aFontPath.AssignCat (aFontFileName);
+        if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
         {
-          myListOfFonts.Append (aNewFont);
-        }
-        else if (aNewFontFromXLFD->IsValid())
-        {
-          myListOfFonts.Append (aNewFontFromXLFD);
+          RegisterFont (aNewFont, false);
+          if (!aXLFD.IsEmpty()
+            && aXLFD.Search ("-0-0-0-0-") != -1) // ignore non-resizable fonts
+          {
+            const TCollection_AsciiString anXName = aXLFD.Token ("-", 2);
+            Font_FontAspect anXAspect = Font_FA_Regular;
+            if (aXLFD.Token ("-", 3).IsEqual ("bold")
+             && (aXLFD.Token ("-", 4).IsEqual ("i")
+              || aXLFD.Token ("-", 4).IsEqual ("o")))
+            {
+              anXAspect = Font_FA_BoldItalic;
+            }
+            else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
+            {
+              anXAspect = Font_FA_Bold;
+            }
+            else if (aXLFD.Token ("-", 4).IsEqual ("i")
+                  || aXLFD.Token ("-", 4).IsEqual ("o"))
+            {
+              anXAspect = Font_FA_Italic;
+            }
+
+            Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (anXName);
+            aNewFontFromXLFD->SetFontPath (anXAspect, aFontPath);
+            if (!aNewFont->IsEqual (aNewFontFromXLFD))
+            {
+              RegisterFont (aNewFontFromXLFD, false);
+            }
+          }
         }
       }
     }
@@ -577,24 +642,17 @@ void Font_FontMgr::InitFontDataBase()
 }
 
 // =======================================================================
-// function : GetAvailableFonts
-// purpose  :
-// =======================================================================
-const Font_NListOfSystemFont& Font_FontMgr::GetAvailableFonts() const
-{
-  return myListOfFonts;
-}
-
-// =======================================================================
 // function : GetAvailableFontsNames
 // purpose  :
 // =======================================================================
 void Font_FontMgr::GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const
 {
   theFontsNames.Clear();
-  for (Font_NListOfSystemFont::Iterator anIter(myListOfFonts); anIter.More(); anIter.Next())
+  for (NCollection_IndexedMap<Handle(Font_SystemFont), Font_SystemFont>::Iterator aFontIter (myFontMap);
+       aFontIter.More(); aFontIter.Next())
   {
-    theFontsNames.Append (anIter.Value()->FontName());
+    const Handle(Font_SystemFont)& aFont = aFontIter.Value();
+    theFontsNames.Append (new TCollection_HAsciiString(aFont->FontName()));
   }
 }
 
@@ -606,101 +664,149 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiSt
                                                const Font_FontAspect  theFontAspect,
                                                const Standard_Integer theFontSize) const
 {
-  if ( (theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
+  if ((theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
   {
-    return NULL;
+    return Handle(Font_SystemFont)();
   }
 
-  for (Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts);
-       aFontsIterator.More(); aFontsIterator.Next())
-  {
-    if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False))
-    {
-      continue;
-    }
-
-    if (theFontAspect != Font_FA_Undefined && aFontsIterator.Value()->FontAspect() != theFontAspect)
-    {
-      continue;
-    }
-
-    if (theFontSize == -1 || aFontsIterator.Value()->FontHeight() == -1 ||
-        theFontSize == aFontsIterator.Value()->FontHeight())
-    {
-      return aFontsIterator.Value();
-    }
-  }
+  Handle(Font_SystemFont) aFont = myFontMap.Find (theFontName->String());
+  return (aFont.IsNull()
+       || theFontAspect == Font_FontAspect_UNDEFINED
+       || aFont->HasFontAspect (theFontAspect))
+       ? aFont
+       : Handle(Font_SystemFont)();
+}
 
-  return NULL;
+// =======================================================================
+// function : GetFont
+// purpose  :
+// =======================================================================
+Handle(Font_SystemFont) Font_FontMgr::GetFont (const TCollection_AsciiString& theFontName) const
+{
+  return myFontMap.Find (theFontName);
 }
 
 // =======================================================================
 // function : FindFont
 // purpose  :
 // =======================================================================
-Handle(Font_SystemFont) Font_FontMgr::FindFont (const Handle(TCollection_HAsciiString)& theFontName,
-                                                const Font_FontAspect  theFontAspect,
-                                                const Standard_Integer theFontSize) const
+Handle(Font_SystemFont) Font_FontMgr::FindFont (const TCollection_AsciiString& theFontName,
+                                                Font_FontAspect& theFontAspect) const
 {
-  Handle(TCollection_HAsciiString) aFontName   = theFontName;
-  Font_FontAspect                  aFontAspect = theFontAspect;
-  Standard_Integer                 aFontSize   = theFontSize;
-
-  Handle(Font_SystemFont) aFont = GetFont (aFontName, aFontAspect, aFontSize);
+  TCollection_AsciiString aFontName (theFontName);
+  aFontName.LowerCase();
+  Handle(Font_SystemFont) aFont = myFontMap.Find (aFontName);
   if (!aFont.IsNull())
   {
     return aFont;
   }
 
   // Trying to use font names mapping
-  for (Standard_Integer anIter = 0; anIter < NUM_FONT_ENTRIES; ++anIter)
+  Handle(Font_FontAliasSequence) anAliases;
+  const Standard_Boolean hasAliases  = myFontAliases.Find (aFontName, anAliases)
+                                   && !anAliases.IsNull()
+                                   && !anAliases->IsEmpty();
+  if (!hasAliases
+    && aFont.IsNull())
   {
-    Handle(TCollection_HAsciiString) aFontAlias =
-      new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].EnumName);
-
-    if (aFontAlias->IsSameString (aFontName, Standard_False))
-    {
-      aFontName = new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].FontName);
-      aFontAspect = Font_FontMgr_MapOfFontsAliases[anIter].FontAspect;
-      break;
-    }
+    anAliases = myFallbackAlias;
   }
 
-  // check font family alias with specified font aspect
-  if (theFontAspect != Font_FA_Undefined
-   && theFontAspect != Font_FA_Regular
-   && theFontAspect != aFontAspect)
+  bool isAliasUsed = false, isBestAlias = false;
+  if (!anAliases.IsNull()
+   && !anAliases->IsEmpty())
   {
-    aFont = GetFont (aFontName, theFontAspect, aFontSize);
-    if (!aFont.IsNull())
+    for (Font_FontAliasSequence::Iterator anAliasIter (*anAliases); anAliasIter.More(); anAliasIter.Next())
     {
-      return aFont;
+      const Font_FontAlias& anAlias = anAliasIter.Value();
+      if (Handle(Font_SystemFont) aFont2 = myFontMap.Find (anAlias.FontName))
+      {
+        if (aFont.IsNull())
+        {
+          aFont = aFont2;
+          isAliasUsed = true;
+        }
+
+        if ((anAlias.FontAspect != Font_FontAspect_UNDEFINED
+          && aFont2->HasFontAspect (anAlias.FontAspect)))
+        {
+          // special case - alias refers to styled font (e.g. "times-bold")
+          isBestAlias = true;
+          theFontAspect = anAlias.FontAspect;
+          break;
+        }
+        else if (anAlias.FontAspect == Font_FontAspect_UNDEFINED
+              && (theFontAspect == Font_FontAspect_UNDEFINED
+               || aFont2->HasFontAspect (theFontAspect)))
+        {
+          isBestAlias = true;
+          break;
+        }
+      }
+    }
+    if (hasAliases)
+    {
+      if (isAliasUsed && myToTraceAliases)
+      {
+        Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, using font alias '") + aFont->FontName() + "'"
+                                           " instead of requested '" + theFontName +"'", Message_Trace);
+      }
+      if (isBestAlias)
+      {
+        return aFont;
+      }
     }
   }
 
-  // check font alias with aspect in the name
-  aFont = GetFont (aFontName, aFontAspect, aFontSize);
-  if (!aFont.IsNull())
+  if (aFont.IsNull())
   {
-    return aFont;
+    // try finding ANY font in case if even default fallback alias myFallbackAlias cannot be found
+    aFont = myFontMap.Find (TCollection_AsciiString());
+  }
+  if (aFont.IsNull())
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, error: unable to find any font!", Message_Fail));
+    return Handle(Font_SystemFont)();
   }
 
-  // Requested family name not found -> search for any font family with given aspect and height
-  aFontName = new TCollection_HAsciiString ("");
-  aFont = GetFont (aFontName, aFontAspect, aFontSize);
-  if (!aFont.IsNull())
+  if ((theFontAspect != Font_FA_Undefined
+    && !aFont->HasFontAspect (theFontAspect))
+   || (!aFontName.IsEmpty()
+    && !aFontName.IsEqual (aFont->FontKey())))
   {
-    return aFont;
+    TCollection_AsciiString aDesc = TCollection_AsciiString() + "'" + theFontName + "'"
+                                  + TCollection_AsciiString() + " [" + Font_FontMgr::FontAspectToString (theFontAspect) + "]";
+    Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, warning: unable to find font ")
+                                     + aDesc + "; " + aFont->ToString() + " is used instead");
   }
+  return aFont;
+}
 
-  // The last resort: trying to use ANY font available in the system
-  aFontAspect = Font_FA_Undefined;
-  aFontSize = -1;
-  aFont = GetFont (aFontName, aFontAspect, aFontSize);
-  if (!aFont.IsNull())
+// =======================================================================
+// function : Font_FontMap::Find
+// purpose  :
+// =======================================================================
+Handle(Font_SystemFont) Font_FontMgr::Font_FontMap::Find (const TCollection_AsciiString& theFontName) const
+{
+  if (IsEmpty())
   {
-    return aFont;
+    return Handle(Font_SystemFont)();
+  }
+  else if (theFontName.IsEmpty())
+  {
+    return FindKey (1); // return any font
   }
 
-  return NULL; // Fonts are not found in the system.
+  TCollection_AsciiString aFontName (theFontName);
+  aFontName.LowerCase();
+  for (IndexedMapNode* aNodeIter = (IndexedMapNode* )myData1[::HashCode (aFontName, NbBuckets())];
+       aNodeIter != NULL; aNodeIter = (IndexedMapNode* )aNodeIter->Next())
+  {
+    const Handle(Font_SystemFont)& aKey = aNodeIter->Key1();
+    if (aKey->FontKey().IsEqual (aFontName))
+    {
+      return aKey;
+    }
+  }
+  return Handle(Font_SystemFont)();
 }
index cfb1934..37e2aaa 100644 (file)
 #define _Font_FontMgr_HeaderFile
 
 #include <Standard.hxx>
+#include <Standard_Transient.hxx>
 #include <Standard_Type.hxx>
-
+#include <Font_FontAspect.hxx>
 #include <Font_NListOfSystemFont.hxx>
-#include <Standard_Transient.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <NCollection_Shared.hxx>
 #include <TColStd_SequenceOfHAsciiString.hxx>
-#include <Font_FontAspect.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_CString.hxx>
-#include <Standard_Boolean.hxx>
+
 class Font_SystemFont;
 class TCollection_HAsciiString;
 
-
 class Font_FontMgr;
 DEFINE_STANDARD_HANDLE(Font_FontMgr, Standard_Transient)
 
 //! Collects and provides information about available fonts in system.
 class Font_FontMgr : public Standard_Transient
 {
-
+  DEFINE_STANDARD_RTTIEXT(Font_FontMgr, Standard_Transient)
 public:
 
-  
+  //! Return global instance of font manager.
   Standard_EXPORT static Handle(Font_FontMgr) GetInstance();
-  
-  Standard_EXPORT const Font_NListOfSystemFont& GetAvailableFonts() const;
-  
+
+  //! Return font aspect as string.
+  static const char* FontAspectToString (Font_FontAspect theAspect)
+  {
+    switch (theAspect)
+    {
+      case Font_FontAspect_UNDEFINED:  return "undefined";
+      case Font_FontAspect_Regular:    return "regular";
+      case Font_FontAspect_Bold:       return "bold";
+      case Font_FontAspect_Italic:     return "italic";
+      case Font_FontAspect_BoldItalic: return "bold-italic";
+    }
+    return "invalid";
+  }
+
+public:
+
+  //! Return the list of available fonts.
+  void AvailableFonts (Font_NListOfSystemFont& theList) const
+  {
+    for (Font_FontMap::Iterator aFontIter (myFontMap); aFontIter.More(); aFontIter.Next())
+    {
+      theList.Append (aFontIter.Value());
+    }
+  }
+
+  //! Return the list of available fonts.
+  Font_NListOfSystemFont GetAvailableFonts() const
+  {
+    Font_NListOfSystemFont aList;
+    AvailableFonts (aList);
+    return aList;
+  }
+
   //! Returns sequence of available fonts names
   Standard_EXPORT void GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const;
   
@@ -52,51 +82,103 @@ public:
   //! If theFontAspect is Font_FA_Undefined returned font can have any FontAspect.
   //! If theFontSize is "-1" returned font can have any FontSize.
   Standard_EXPORT Handle(Font_SystemFont) GetFont (const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Standard_Integer theFontSize) const;
-  
+
+  //! Returns font that match given name or NULL if such font family is NOT registered.
+  //! Note that unlike FindFont(), this method ignores font aliases and does not look for fall-back.
+  Standard_EXPORT Handle(Font_SystemFont) GetFont (const TCollection_AsciiString& theFontName) const;
+
   //! Tries to find font by given parameters.
   //! If the specified font is not found tries to use font names mapping.
-  //! If the requested family name not found -> search for any font family
-  //! with given aspect and height. If the font is still not found, returns
-  //! any font available in the system. Returns NULL in case when the fonts
-  //! are not found in the system.
-  Standard_EXPORT Handle(Font_SystemFont) FindFont (const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Standard_Integer theFontSize) const;
+  //! If the requested family name not found -> search for any font family with given aspect and height.
+  //! If the font is still not found, returns any font available in the system.
+  //! Returns NULL in case when the fonts are not found in the system.
+  //! @param theFontName   [in]       font family to find or alias name
+  //! @param theFontAspect [in] [out] font aspect to find (considered only if family name is not found);
+  //!                                 can be modified if specified font alias refers to another style (compatibility with obsolete aliases)
+  Standard_EXPORT Handle(Font_SystemFont) FindFont (const TCollection_AsciiString& theFontName,
+                                                    Font_FontAspect& theFontAspect) const;
   
   //! Read font file and retrieve information from it.
   Standard_EXPORT Handle(Font_SystemFont) CheckFont (const Standard_CString theFontPath) const;
   
   //! Register new font.
   //! If there is existing entity with the same name and properties but different path
-  //! then font will will be overridden or ignored depending on theToOverride flag.
+  //! then font will be overridden or ignored depending on theToOverride flag.
   Standard_EXPORT Standard_Boolean RegisterFont (const Handle(Font_SystemFont)& theFont, const Standard_Boolean theToOverride);
 
+  //! Return flag for tracing font aliases usage via Message_Trace messages; TRUE by default.
+  Standard_Boolean ToTraceAliases() const { return myToTraceAliases; }
 
-
-
-  DEFINE_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
-
-protected:
-
-
-
+  //! Set flag for tracing font alias usage; useful to trace which fonts are actually used.
+  //! Can be disabled to avoid redundant messages with Message_Trace level.
+  void SetTraceAliases (Standard_Boolean theToTrace) { myToTraceAliases = theToTrace; }
 
 private:
-
   
-  //! Creates empty font object
+  //! Creates empty font manager object
   Standard_EXPORT Font_FontMgr();
   
   //! Collects available fonts paths.
   Standard_EXPORT void InitFontDataBase();
 
-  Font_NListOfSystemFont myListOfFonts;
-
-
-};
-
-
+private:
 
+  //! Map storing registered fonts.
+  class Font_FontMap : public NCollection_IndexedMap<Handle(Font_SystemFont), Font_SystemFont>
+  {
+  public:
+    //! Empty constructor.
+    Font_FontMap() {}
+
+    //! Try finding font with specified parameters or the closest one.
+    //! @param theFontName [in] font family to find (or empty string if family name can be ignored)
+    //! @return best match font or NULL if not found
+    Handle(Font_SystemFont) Find (const TCollection_AsciiString& theFontName) const;
+
+  public:
+
+    //! Hash value, for Map interface.
+    //! Based on Font Family, so that the whole family with different aspects can be found within the same bucket.
+    static Standard_Integer HashCode (const Handle(Font_SystemFont)& theFont,
+                                      const Standard_Integer theUpper)
+    {
+      return ::HashCode (theFont->FontKey(), theUpper);
+    }
+
+    //! Matching two instances, for Map interface.
+    static bool IsEqual (const Handle(Font_SystemFont)& theFont1,
+                         const Handle(Font_SystemFont)& theFont2)
+    {
+      return theFont1->IsEqual (theFont2);
+    }
+
+  };
+
+  //! Structure defining font alias.
+  struct Font_FontAlias
+  {
+    TCollection_AsciiString FontName;
+    Font_FontAspect         FontAspect;
+
+    Font_FontAlias (const TCollection_AsciiString& theFontName, Font_FontAspect theFontAspect = Font_FontAspect_UNDEFINED) : FontName (theFontName), FontAspect (theFontAspect) {}
+    Font_FontAlias() : FontAspect (Font_FontAspect_UNDEFINED) {}
+  };
+
+  //! Sequence of font aliases.
+  typedef NCollection_Shared< NCollection_Sequence<Font_FontAlias> > Font_FontAliasSequence;
+
+  //! Register font alias.
+  void addFontAlias (const TCollection_AsciiString& theAliasName,
+                     const Handle(Font_FontAliasSequence)& theAliases,
+                     Font_FontAspect theAspect = Font_FontAspect_UNDEFINED);
 
+private:
 
+  Font_FontMap myFontMap;
+  NCollection_DataMap<TCollection_AsciiString, Handle(Font_FontAliasSequence)> myFontAliases;
+  Handle(Font_FontAliasSequence) myFallbackAlias;
+  Standard_Boolean myToTraceAliases;
 
+};
 
 #endif // _Font_FontMgr_HeaderFile
index 0b86f40..c63d869 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#define  Font_NOF_ASCII_MONO            "Courier" 
+#define  Font_NOF_MONOSPACE             "monospace"
+#define  Font_NOF_SERIF                 "serif"
+#define  Font_NOF_SANS_SERIF            "sans-serif"
+#define  Font_NOF_CJK                   "cjk"
+#define  Font_NOF_KOREAN                "korean"
+
+#define  Font_NOF_ASCII_MONO            "Courier"
 #define  Font_NOF_ASCII_SIMPLEX         "Times-Roman"
 #define  Font_NOF_ASCII_COMPLEX         "Times-Roman"
 #define  Font_NOF_ASCII_DUPLEX          "Times-Bold"
index 19c3c16..fd37e90 100644 (file)
@@ -15,9 +15,8 @@
 
 #include <Font_SystemFont.hxx>
 
+#include <Font_FontMgr.hxx>
 #include <OSD_Path.hxx>
-#include <Standard_Type.hxx>
-#include <TCollection_HAsciiString.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
 
@@ -25,101 +24,85 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
 // function : Font_SystemFont
 // purpose  :
 // =======================================================================
-Font_SystemFont::Font_SystemFont()
-: myFontAspect (Font_FA_Undefined),
-  myFaceSize (-1),
-  myIsSingleLine (Standard_False),
-  myIsDefined (Standard_False)
+Font_SystemFont::Font_SystemFont (const TCollection_AsciiString& theFontName)
+: myFontKey (theFontName),
+  myFontName (theFontName),
+  myIsSingleLine (Standard_False)
 {
-  //
+  if (theFontName.IsEmpty()) { throw Standard_ProgramError ("Font_SystemFont constructor called with empty font name"); }
+  myFontKey.LowerCase();
 }
 
 // =======================================================================
-// function : Font_SystemFont
+// function : SetFontPath
 // purpose  :
 // =======================================================================
-Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theFontName,
-                                  const Font_FontAspect theFontAspect,
-                                  const Handle(TCollection_HAsciiString)& theFilePath)
-: myFontName (theFontName),
-  myFontAspect (theFontAspect),
-  myFaceSize (-1),
-  myFilePath (theFilePath),
-  myIsSingleLine (Standard_False),
-  myIsDefined (Standard_True)
+void Font_SystemFont::SetFontPath (Font_FontAspect theAspect,
+                                   const TCollection_AsciiString& thePath)
 {
-  //
+  if (theAspect == Font_FontAspect_UNDEFINED) { throw Standard_ProgramError ("Font_SystemFont::SetFontPath() called with UNDEFINED aspect"); }
+  myFilePaths[theAspect] = thePath;
 }
 
 // =======================================================================
-// function : Font_SystemFont
+// function : IsEqual
 // purpose  :
 // =======================================================================
-Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD,
-                                  const Handle(TCollection_HAsciiString)& theFilePath)
-: myFontAspect (Font_FA_Regular),
-  myFaceSize (-1),
-  myFilePath (theFilePath),
-  myIsSingleLine (Standard_False),
-  myIsDefined (Standard_True)
+Standard_Boolean Font_SystemFont::IsEqual (const Handle(Font_SystemFont)& theOtherFont) const
 {
-  if (theXLFD.IsNull()
-   || theXLFD->IsEmpty())
-  {
-    myIsDefined = Standard_False;
-    return;
-  }
-
-  myFontName = theXLFD->Token ("-", 2);
-  const TCollection_AsciiString& aXLFD = theXLFD->String();
-
-  // Getting font size for fixed size fonts
-  if (aXLFD.Search ("-0-0-0-0-") >= 0)
-  {
-    myFaceSize = -1; // Scalable font
-  }
-  else
-  {
-    myFaceSize = aXLFD.Token ("-", 7).IntegerValue();
-  }
-
-  // Detect font aspect
-  if (aXLFD.Token ("-", 3).IsEqual ("bold")
-   && (aXLFD.Token ("-", 4).IsEqual ("i")
-    || aXLFD.Token ("-", 4).IsEqual ("o")))
-  {
-    myFontAspect = Font_FA_BoldItalic;
-  }
-  else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
-  {
-    myFontAspect = Font_FA_Bold;
-  }
-  else if (aXLFD.Token ("-", 4).IsEqual ("i")
-        || aXLFD.Token ("-", 4).IsEqual ("o"))
-  {
-    myFontAspect = Font_FA_Italic;
-  }
+  return theOtherFont.get() == this
+      || myFontKey.IsEqual (theOtherFont->myFontKey);
 }
 
 // =======================================================================
-// function : IsValid
+// function : ToString
 // purpose  :
 // =======================================================================
-Standard_Boolean Font_SystemFont::IsValid() const
+TCollection_AsciiString Font_SystemFont::ToString() const
 {
-  return myIsDefined
-     &&  myFontAspect != Font_FA_Undefined
-     && !myFontName->IsEmpty()
-     &&  OSD_Path::IsValid (myFilePath->String());
-}
+  TCollection_AsciiString aDesc;
+  aDesc += TCollection_AsciiString() + "'" + myFontName + "'";
 
-// =======================================================================
-// function : IsEqual
-// purpose  :
-// =======================================================================
-Standard_Boolean Font_SystemFont::IsEqual (const Handle(Font_SystemFont)& theOtherFont) const
-{
-  return myFontName->IsSameString (myFontName, Standard_False)
-      && myFontAspect == theOtherFont->myFontAspect
-      && myFaceSize   == theOtherFont->myFaceSize;
+  bool isFirstAspect = true;
+  aDesc += " [aspects: ";
+  for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
+  {
+    if (!HasFontAspect ((Font_FontAspect )anAspectIter))
+    {
+      continue;
+    }
+
+    if (!isFirstAspect)
+    {
+      aDesc += ",";
+    }
+    else
+    {
+      isFirstAspect = false;
+    }
+    aDesc += Font_FontMgr::FontAspectToString ((Font_FontAspect )anAspectIter);
+  }
+  aDesc += "]";
+
+  isFirstAspect = true;
+  aDesc += " [paths: ";
+  for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
+  {
+    if (!HasFontAspect ((Font_FontAspect )anAspectIter))
+    {
+      continue;
+    }
+
+    if (!isFirstAspect)
+    {
+      aDesc += ";";
+    }
+    else
+    {
+      isFirstAspect = false;
+    }
+    aDesc += FontPath ((Font_FontAspect )anAspectIter);
+  }
+  aDesc += "]";
+  return aDesc;
 }
index 7cb13e2..b9ae8a0 100644 (file)
 #ifndef _Font_SystemFont_HeaderFile
 #define _Font_SystemFont_HeaderFile
 
+#include <Font_FontAspect.hxx>
 #include <Standard.hxx>
 #include <Standard_Type.hxx>
-
-#include <Font_FontAspect.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_Boolean.hxx>
 #include <Standard_Transient.hxx>
-class TCollection_HAsciiString;
+#include <TCollection_AsciiString.hxx>
 
 //! This class stores information about the font, which is merely a file path and cached metadata about the font.
 class Font_SystemFont : public Standard_Transient
@@ -31,33 +28,53 @@ class Font_SystemFont : public Standard_Transient
   DEFINE_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
 public:
 
-  //! Creates an empty font object.
-  Standard_EXPORT Font_SystemFont();
-
   //! Creates a new font object.
-  Standard_EXPORT Font_SystemFont (const Handle(TCollection_HAsciiString)& theFontName,
-                                   const Font_FontAspect theFontAspect,
-                                   const Handle(TCollection_HAsciiString)& theFilePath);
+  Standard_EXPORT Font_SystemFont (const TCollection_AsciiString& theFontName);
 
-  //! Creates a font object and initialize class fields with values taken from XLFD (X Logical Font Description)
-  Standard_EXPORT Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD,
-                                   const Handle(TCollection_HAsciiString)& theFilePath);
+  //! Returns font family name (lower-cased).
+  const TCollection_AsciiString& FontKey() const { return myFontKey; }
 
   //! Returns font family name.
-  const Handle(TCollection_HAsciiString)& FontName() const { return myFontName; }
+  const TCollection_AsciiString& FontName() const { return myFontName; }
   
   //! Returns font file path.
-  const Handle(TCollection_HAsciiString)& FontPath() const { return myFilePath; }
-  
-  //! Returns font aspect.
-  Font_FontAspect FontAspect() const { return myFontAspect; }
-  
-  //! Returns font height.
-  //! If returned value is equal -1 it means that font is resizable.
-  Standard_Integer FontHeight() const { return myFaceSize; }
+  const TCollection_AsciiString& FontPath (Font_FontAspect theAspect) const
+  {
+    return myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular];
+  }
+
+  //! Sets font file path for specific aspect.
+  Standard_EXPORT void SetFontPath (Font_FontAspect theAspect,
+                                    const TCollection_AsciiString& thePath);
+
+  //! Returns TRUE if dedicated file for specified font aspect has been defined.
+  bool HasFontAspect (Font_FontAspect theAspect) const
+  {
+    return !myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular].IsEmpty();
+  }
+
+  //! Returns any defined font file path.
+  const TCollection_AsciiString& FontPathAny (Font_FontAspect theAspect) const
+  {
+    const TCollection_AsciiString& aPath = myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular];
+    if (!aPath.IsEmpty())
+    {
+      return aPath;
+    }
+    else if (!myFilePaths[Font_FontAspect_Regular].IsEmpty())
+    {
+      return myFilePaths[Font_FontAspect_Regular];
+    }
+    for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
+    {
+      if (!myFilePaths[anAspectIter].IsEmpty())
+      {
+        return myFilePaths[anAspectIter];
+      }
+    }
+    return myFilePaths[Font_FontAspect_Regular];
+  }
 
-  Standard_EXPORT Standard_Boolean IsValid() const;
-  
   //! Return true if the FontName, FontAspect and FontSize are the same.
   Standard_EXPORT Standard_Boolean IsEqual (const Handle(Font_SystemFont)& theOtherFont) const;
 
@@ -68,14 +85,32 @@ public:
   //! Set if this font should be rendered as single-stroke (one-line).
   void SetSingleStrokeFont (Standard_Boolean theIsSingleLine) { myIsSingleLine = theIsSingleLine; }
 
+  //! Format font description.
+  Standard_EXPORT TCollection_AsciiString ToString() const;
+
+public:
+
+  //! Hash value, for Map interface.
+  //! Based on Font Family, so that the whole family with different aspects can be found within the same bucket.
+  static Standard_Integer HashCode (const Handle(Font_SystemFont)& theFont,
+                                    const Standard_Integer theUpper)
+  {
+    return ::HashCode (theFont->FontKey(), theUpper);
+  }
+
+  //! Matching two instances, for Map interface.
+  static bool IsEqual (const Handle(Font_SystemFont)& theFont1,
+                       const Handle(Font_SystemFont)& theFont2)
+  {
+    return theFont1->IsEqual (theFont2);
+  }
+
 private:
 
-  Handle(TCollection_HAsciiString) myFontName;
-  Font_FontAspect                  myFontAspect;
-  Standard_Integer                 myFaceSize;
-  Handle(TCollection_HAsciiString) myFilePath;
-  Standard_Boolean                 myIsSingleLine; //!< single stroke font flag, FALSE by default
-  Standard_Boolean                 myIsDefined;
+  TCollection_AsciiString myFilePaths[Font_FontAspect_NB]; //!< paths to the font file
+  TCollection_AsciiString myFontKey;      //!< font family name, lower cased
+  TCollection_AsciiString myFontName;     //!< font family name
+  Standard_Boolean        myIsSingleLine; //!< single stroke font flag, FALSE by default
 
 };
 
index 70cd2fb..3ca3e6a 100644 (file)
@@ -567,17 +567,16 @@ Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
   if (!theCtx->GetResource (theKey, aFont))
   {
     Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
-    const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.Aspect()->Font());
-    const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
-                                   ? theAspect.Aspect()->GetTextFontAspect()
-                                   : Font_FA_Regular;
-    Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
+    const TCollection_AsciiString& aFontName = theAspect.Aspect()->Font();
+    Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
+                             ? theAspect.Aspect()->GetTextFontAspect()
+                             : Font_FA_Regular;
     Handle(Font_FTFont) aFontFt;
-    if (!aRequestedFont.IsNull())
+    if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect))
     {
       aFontFt = new Font_FTFont (Handle(Font_FTLibrary)());
 
-      if (aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight, theResolution))
+      if (aFontFt->Init (aRequestedFont->FontPathAny (anAspect).ToCString(), theHeight, theResolution))
       {
         aFont = new OpenGl_Font (aFontFt, theKey);
         if (!aFont->Init (theCtx))
@@ -598,7 +597,7 @@ Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
         aMsg += "Font '";
         aMsg += theAspect.Aspect()->Font();
         aMsg += "' is broken or has incompatible format! File path: ";
-        aMsg += aRequestedFont->FontPath()->ToCString();
+        aMsg += aRequestedFont->FontPathAny (anAspect);
         theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
         aFontFt.Nullify();
         aFont = new OpenGl_Font (aFontFt, theKey);
index 85be129..d3713c1 100644 (file)
@@ -509,6 +509,39 @@ namespace
     }
     return Standard_True;
   }
+
+  //! Auxiliary function to parse font aspect style argument
+  static Standard_Boolean parseFontStyle (const TCollection_AsciiString& theArg,
+                                          Font_FontAspect&               theAspect)
+  {
+    if (theArg == "regular"
+     || *theArg.ToCString() == 'r')
+    {
+      theAspect = Font_FA_Regular;
+      return Standard_True;
+    }
+    else if (theArg == "bolditalic"
+          || theArg == "bold-italic"
+          || theArg == "italic-bold"
+          || theArg == "italicbold")
+    {
+      theAspect = Font_FA_BoldItalic;
+      return Standard_True;
+    }
+    else if (theArg == "bold"
+          || *theArg.ToCString() == 'b')
+    {
+      theAspect = Font_FA_Bold;
+      return Standard_True;
+    }
+    else if (theArg == "italic"
+          || *theArg.ToCString() == 'i')
+    {
+      theAspect = Font_FA_Italic;
+      return Standard_True;
+    }
+    return Standard_False;
+  }
 }
 
 //==============================================================================
@@ -2464,22 +2497,13 @@ static int VDrawText (Draw_Interpretor& theDI,
 
       TCollection_AsciiString anOption (theArgVec[anArgIt]);
       anOption.LowerCase();
-      if (anOption.IsEqual ("regular"))
-      {
-        aTextPrs->SetFontAspect (Font_FA_Regular);
-      }
-      else if (anOption.IsEqual ("bold"))
-      {
-        aTextPrs->SetFontAspect (Font_FA_Bold);
-      }
-      else if (anOption.IsEqual ("italic"))
+      Font_FontAspect aFontAspect = Font_FA_Undefined;
+      if (!parseFontStyle (anOption, aFontAspect))
       {
-        aTextPrs->SetFontAspect (Font_FA_Italic);
-      }
-      else if (anOption.IsEqual ("bolditalic"))
-      {
-        aTextPrs->SetFontAspect (Font_FA_BoldItalic);
+        std::cout << "Error: unknown font aspect '" << anOption << "'.\n";
+        return 1;
       }
+      aTextPrs->SetFontAspect (aFontAspect);
     }
     else if (aParam == "-font")
     {
@@ -5191,49 +5215,6 @@ static Standard_Integer VMarkersTest (Draw_Interpretor&,
   return 0;
 }
 
-//! Auxiliary function to parse font aspect style argument
-static Standard_Boolean parseFontStyle (const TCollection_AsciiString& theArg,
-                                        Font_FontAspect&               theAspect)
-{
-  if (theArg == "regular"
-   || *theArg.ToCString() == 'r')
-  {
-    theAspect = Font_FA_Regular;
-    return Standard_True;
-  }
-  else if (theArg == "bolditalic")
-  {
-    theAspect = Font_FA_BoldItalic;
-    return Standard_True;
-  }
-  else if (theArg == "bold"
-        || *theArg.ToCString() == 'b')
-  {
-    theAspect = Font_FA_Bold;
-    return Standard_True;
-  }
-  else if (theArg == "italic"
-        || *theArg.ToCString() == 'i')
-  {
-    theAspect = Font_FA_Italic;
-    return Standard_True;
-  }
-  return Standard_False;
-}
-
-//! Auxiliary function
-static TCollection_AsciiString fontStyleString (const Font_FontAspect theAspect)
-{
-  switch (theAspect)
-  {
-    case Font_FA_Regular:    return "regular";
-    case Font_FA_BoldItalic: return "bolditalic";
-    case Font_FA_Bold:       return "bold";
-    case Font_FA_Italic:     return "italic";
-    default:                 return "undefined";
-  }
-}
-
 //=======================================================================
 //function : TextToBrep
 //purpose  : Tool for conversion text to occt-shapes
@@ -5364,26 +5345,9 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
 
       TCollection_AsciiString anOption (theArgVec[anArgIt]);
       anOption.LowerCase();
-
-      if (anOption.IsEqual ("regular"))
-      {
-        aFontAspect = Font_FA_Regular;
-      }
-      else if (anOption.IsEqual ("bold"))
-      {
-        aFontAspect = Font_FA_Bold;
-      }
-      else if (anOption.IsEqual ("italic"))
-      {
-        aFontAspect = Font_FA_Italic;
-      }
-      else if (anOption.IsEqual ("bolditalic"))
+      if (!parseFontStyle (anOption, aFontAspect))
       {
-        aFontAspect = Font_FA_BoldItalic;
-      }
-      else
-      {
-        std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
+        std::cout << "Error: unknown font aspect '" << anOption << "'.\n";
         return 1;
       }
     }
@@ -5459,8 +5423,8 @@ static int VFont (Draw_Interpretor& theDI,
   {
     // just print the list of available fonts
     Standard_Boolean isFirst = Standard_True;
-    for (Font_NListOfSystemFont::Iterator anIter (aMgr->GetAvailableFonts());
-         anIter.More(); anIter.Next())
+    const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
+    for (Font_NListOfSystemFont::Iterator anIter (aFonts); anIter.More(); anIter.Next())
     {
       const Handle(Font_SystemFont)& aFont = anIter.Value();
       if (!isFirst)
@@ -5468,9 +5432,7 @@ static int VFont (Draw_Interpretor& theDI,
         theDI << "\n";
       }
 
-      theDI << aFont->FontName()->String()
-            << " " << fontStyleString (aFont->FontAspect())
-            << " " << aFont->FontPath()->String();
+      theDI << aFont->ToString();
       isFirst = Standard_False;
     }
     return 0;
@@ -5481,15 +5443,11 @@ static int VFont (Draw_Interpretor& theDI,
     const TCollection_AsciiString anArg (theArgVec[anArgIter]);
     TCollection_AsciiString anArgCase (anArg);
     anArgCase.LowerCase();
-    if (anArgCase == "find")
+    if (anArgIter + 1 < theArgNb
+     && (anArgCase == "-find"
+      || anArgCase == "find"))
     {
-      if (++anArgIter >= theArgNb)
-      {
-        std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
-        return 1;
-      }
-
-      Standard_CString aFontName   = theArgVec[anArgIter];
+      Standard_CString aFontName   = theArgVec[++anArgIter];
       Font_FontAspect  aFontAspect = Font_FA_Undefined;
       if (++anArgIter < theArgNb)
       {
@@ -5500,26 +5458,23 @@ static int VFont (Draw_Interpretor& theDI,
           --anArgIter;
         }
       }
-      Handle(Font_SystemFont) aFont = aMgr->FindFont (new TCollection_HAsciiString (aFontName), aFontAspect, -1);
-      if (aFont.IsNull())
+
+      if (Handle(Font_SystemFont) aFont = aMgr->FindFont (aFontName, aFontAspect))
+      {
+        theDI << aFont->ToString();
+      }
+      else
       {
         std::cerr << "Error: font '" << aFontName << "' is not found!\n";
-        continue;
       }
-
-      theDI << aFont->FontName()->String()
-            << " " << fontStyleString (aFont->FontAspect())
-            << " " << aFont->FontPath()->String();
     }
-    else if (anArgCase == "add"
-          || anArgCase == "register")
+    else if (anArgIter + 1 < theArgNb
+          && (anArgCase == "-add"
+           || anArgCase == "add"
+           || anArgCase == "-register"
+           || anArgCase == "register"))
     {
-      if (++anArgIter >= theArgNb)
-      {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'!\n";
-        return 1;
-      }
-
+      ++anArgIter;
       Standard_CString aFontPath = theArgVec[anArgIter++];
       TCollection_AsciiString aFontName;
       Font_FontAspect  aFontAspect = Font_FA_Undefined;
@@ -5528,7 +5483,7 @@ static int VFont (Draw_Interpretor& theDI,
       {
         anArgCase = theArgVec[anArgIter];
         anArgCase.LowerCase();
-        if (aFontAspect == Font_FA_Undefined
+        if (aFontAspect == Font_FontAspect_UNDEFINED
          && parseFontStyle (anArgCase, aFontAspect))
         {
           continue;
@@ -5557,19 +5512,27 @@ static int VFont (Draw_Interpretor& theDI,
         continue;
       }
 
-      if (aFontAspect != Font_FA_Undefined
+      if (aFontAspect != Font_FontAspect_UNDEFINED
       || !aFontName.IsEmpty())
       {
-        if (aFontAspect == Font_FA_Undefined)
+        TCollection_AsciiString aName = aFont->FontName();
+        if (!aFontName.IsEmpty())
         {
-          aFontAspect = aFont->FontAspect();
+          aName = aFontName;
         }
-        Handle(TCollection_HAsciiString) aName = aFont->FontName();
-        if (!aFontName.IsEmpty())
+        Handle(Font_SystemFont) aFont2 = new Font_SystemFont (aName);
+        if (aFontAspect != Font_FontAspect_UNDEFINED)
+        {
+          aFont2->SetFontPath (aFontAspect, aFontPath);
+        }
+        else
         {
-          aName = new TCollection_HAsciiString (aFontName);
+          for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
+          {
+            aFont2->SetFontPath ((Font_FontAspect )anAspectIter, aFont->FontPath ((Font_FontAspect )anAspectIter));
+          }
         }
-        aFont = new Font_SystemFont (aName, aFontAspect, new TCollection_HAsciiString (aFontPath));
+        aFont = aFont2;
       }
       if (isSingelStroke != -1)
       {
@@ -5577,9 +5540,18 @@ static int VFont (Draw_Interpretor& theDI,
       }
 
       aMgr->RegisterFont (aFont, Standard_True);
-      theDI << aFont->FontName()->String()
-            << " " << fontStyleString (aFont->FontAspect())
-            << " " << aFont->FontPath()->String();
+      theDI << aFont->ToString();
+    }
+    else if (anArgCase == "-verbose"
+          || anArgCase == "-trace")
+    {
+      bool toEnable = true;
+      if (anArgIter + 1 < theArgNb
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
+      {
+        ++anArgIter;
+      }
+      aMgr->SetTraceAliases (toEnable);
     }
     else
     {
@@ -6501,7 +6473,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
                    "\n\t\t: [-angle angle=0]"
                    "\n\t\t: [-zoom {0|1}=0]"
                    "\n\t\t: [-height height=16]"
-                   "\n\t\t: [-aspect {regular|bold|italic|bolditalic}=regular]"
+                   "\n\t\t: [-aspect {regular|bold|italic|boldItalic}=regular]"
                    "\n\t\t: [-font font=Times]"
                    "\n\t\t: [-2d]"
                    "\n\t\t: [-perspos {X Y Z}=0 0 0], where"
@@ -6658,14 +6630,14 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
                    "\n\t\t: [-halign {left|center|right}=left]"
                    "\n\t\t: [-valign {top|center|bottom|topfirstline}=bottom}]"
                    "\n\t\t: [-height height=16]"
-                   "\n\t\t: [-aspect {regular|bold|italic|bolditalic}=regular]"
+                   "\n\t\t: [-aspect {regular|bold|italic|boldItalic}=regular]"
                    "\n\t\t: [-font font=Courier]"
                    "\n\t\t: [-composite {on|off}=off]"
                    "\n\t\t: [-plane NormX NormY NormZ DirX DirY DirZ]",
                    __FILE__, TextToBRep, group);
   theCommands.Add ("vfont",
-                            "vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined] [singleStroke]]"
-                   "\n\t\t:        [find fontName [regular,bold,italic,bolditalic=undefined]]",
+                            "vfont [-add pathToFont [fontName] [regular,bold,italic,boldItalic=undefined] [singleStroke]]"
+                   "\n\t\t:        [-find fontName [regular,bold,italic,boldItalic=undefined]] [-verbose {on|off}]",
                    __FILE__, VFont, group);
   
   theCommands.Add ("vsetedgetype",
index f846bca..f900c6a 100755 (executable)
@@ -3,43 +3,14 @@ puts "OCC21091"
 puts "OCC21450"
 puts "============"
 puts ""
-#vdrawtext: vdrawtext name text [-pos X Y Z] [-color R G B] [-align hor_align ver_align] [-angle angle] [-zoom zoomable]
-#           [-height height] [-aspect aspect] [-font font] [-mb isMultiByte]
-#------------------------------------------------------
-# X\Y\Z - Position Of Text
-#------------------------------------------------------
-# R\G\B - Color Of Text
-#------------------------------------------------------
-# hor_align 0 to 3
-# HorizontalTextAlignment is   HTA_LEFT        0
-#                              HTA_CENTER      1
-#                              HTA_RIGHT       2
-#
-# ver_align 0 to 4
-# VerticalTextAlignment is     VTA_BOTTOM      0
-#                              VTA_CENTER      1
-#                              VTA_TOP         2   
-#------------------------------------------------------
-# angle - angle turn of text. this variable in degrees
-#------------------------------------------------------
-# zoomable - if this variable "0" text not zoomable
-#           if this variable "1" text zoomable as object in DrawCommands  
-#------------------------------------------------------
-# height - Font Height
-#------------------------------------------------------
-# Aspect - Aspect Font 0 to 4
-# If in list of textfont, not find font with necessary aspect, will be used default font "Courier" with  OSD_FA_Regular aspect
-# FontAspect is FA_Undefined, FA_Regular, FA_Bold, FA_Italic, FA_BoldItalic
-#                   - 0 -      - 1 -      - 2 -     - 3 -         - 4 -      
-#------------------------------------------------------
-# FONT - font name of font
-# If in list of textfont, not find font with necessary Name, will be used default font "Courier"
-#
 
 vfont add [locate_data_file DejaVuSansMono.ttf] MonoFont
 vfont add [locate_data_file DejaVuSans.ttf] SansFont
 vfont add [locate_data_file DejaVuSerif.ttf] SerifFont
 
+dtracelevel trace
+vfont -verbose 1
+
 vtrihedron trihedr
 
 vpoint p1  100  100 -400
@@ -88,11 +59,11 @@ vdrawtext OC14 OpenCascade -pos -100 -300 -300 -color 0.0 1.0 0.0 -halign left -
 vdrawtext OC15 OpenCascade -pos -300 -100 -100 -color 0.0 1.0 0.0 -halign left -valign bottom -angle 000 -zoom 0 -height 15 -aspect regular -font SerifFont
 vdrawtext OC16 OpenCascade -pos -100 -300 -100 -color 0.0 1.0 0.0 -halign left -valign bottom -angle 000 -zoom 0 -height 15 -aspect regular -font SerifFont
 
-vdrawtext OC17 OpenCascade -pos -200 -200 100 -color 1.0 0.0 1.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font SansFont
-vdrawtext OC18 OpenCascade -pos -200 -200 150 -color 0.0 1.0 1.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font SerifFont
-vdrawtext OC19 OpenCascade -pos -200 -200 200 -color 1.0 1.0 0.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect italic -font SerifFont
-vdrawtext OC20 OpenCascade -pos -200 -200 250 -color 0.0 1.0 0.02 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect bolditalic -font MonoFont
-vdrawtext OC21 OpenCascade -pos -200 -200 300 -color 1.0 0.0 0.02 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font MonoFont
+vdrawtext OC17 OpenCascade -pos -200 -200 100 -color 1.0 0.0 1.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font sans-serif
+vdrawtext OC18 OpenCascade -pos -200 -200 150 -color 0.0 1.0 1.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font serif
+vdrawtext OC19 OpenCascade -pos -200 -200 200 -color 1.0 1.0 0.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect italic -font serif
+vdrawtext OC20 OpenCascade -pos -200 -200 250 -color 0.0 1.0 0.02 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect bolditalic -font monospace
+vdrawtext OC21 OpenCascade -pos -200 -200 300 -color 1.0 0.0 0.02 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font monospace
 
 vglinfo
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
index 14b6e98..e431576 100644 (file)
@@ -4,40 +4,40 @@ puts "Test case prints 3D labels with different text alignment styles and extra
 puts "============"
 puts ""
 
-vfont add [locate_data_file DejaVuSans.ttf] SansFont
+set THE_FONT_NAME sans-serif
+dtracelevel trace
+vfont -verbose 1
 
 vtrihedron trihedr
 
 vpoint pTL  -700  100 600
-vdrawtext Text0 "  Top-Left\nFirst line  \nLion   The Second\n  3rd  " -pos -700  100  600 -color 0.0 1.0 1.0 -halign left -valign top -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text0 "  Top-Left\nFirst line  \nLion   The Second\n  3rd  " -pos -700  100  600 -color 0.0 1.0 1.0 -halign left -valign top -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pTC  0  100 600
-vdrawtext Text1 "  Top-Center\nFirst line  \nLion   The Second\n  3rd  " -pos 0  100  600 -color 0.0 1.0 1.0 -halign center -valign top -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text1 "  Top-Center\nFirst line  \nLion   The Second\n  3rd  " -pos 0  100  600 -color 0.0 1.0 1.0 -halign center -valign top -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pTR  700  100 600
-vdrawtext Text2 "  Top-Right\nFirst line  \nLion   The Second\n  3rd  " -pos 700  100  600 -color 0.0 1.0 1.0 -halign right -valign top -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text2 "  Top-Right\nFirst line  \nLion   The Second\n  3rd  " -pos 700  100  600 -color 0.0 1.0 1.0 -halign right -valign top -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pCL  -700  100 -100
-vdrawtext Text3 "  Center-Left\nFirst line  \nLion   The Second\n  3rd  " -pos -700  100 -100 -color 1.0 1.0 1.0 -halign left -valign center -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text3 "  Center-Left\nFirst line  \nLion   The Second\n  3rd  " -pos -700  100 -100 -color 1.0 1.0 1.0 -halign left -valign center -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pCC  0  100 -100
-vdrawtext Text4 "  Center-Center\nFirst line  \nLion   The Second\n  3rd  " -pos 0  100 -100 -color 1.0 1.0 1.0 -halign center -valign center -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text4 "  Center-Center\nFirst line  \nLion   The Second\n  3rd  " -pos 0  100 -100 -color 1.0 1.0 1.0 -halign center -valign center -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pCR  700  100 -100
-vdrawtext Text5 "  Center-Right\nFirst line  \nLion   The Second\n  3rd  " -pos 700  100 -100 -color 1.0 1.0 1.0 -halign right -valign center -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text5 "  Center-Right\nFirst line  \nLion   The Second\n  3rd  " -pos 700  100 -100 -color 1.0 1.0 1.0 -halign right -valign center -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pBL  -700  100 -700
-vdrawtext Text6 "  Bottom-Left\nFirst line  \nLion   The Second\n  3rd  " -pos -700  100 -700 -color 1.0 1.0 0.0 -halign left -valign bottom -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text6 "  Bottom-Left\nFirst line  \nLion   The Second\n  3rd  " -pos -700  100 -700 -color 1.0 1.0 0.0 -halign left -valign bottom -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pBC  0  100 -700
-vdrawtext Text7 "  Bottom-Center\nFirst line  \nLion   The Second\n  3rd  " -pos 0  100 -700 -color 1.0 1.0 0.0 -halign center -valign bottom -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
+vdrawtext Text7 "  Bottom-Center\nFirst line  \nLion   The Second\n  3rd  " -pos 0  100 -700 -color 1.0 1.0 0.0 -halign center -valign bottom -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vpoint pBR  700  100 -700
-vdrawtext Text8 "  Bottom-Right\nFirst line  \nLion   The Second\n  3rd  " -pos 700  100 -700 -color 1.0 1.0 0.0 -halign right -valign bottom -angle 000 -zoom 0 -height 14 -aspect bold -font SansFont
-
+vdrawtext Text8 "  Bottom-Right\nFirst line  \nLion   The Second\n  3rd  " -pos 700  100 -700 -color 1.0 1.0 0.0 -halign right -valign bottom -angle 000 -zoom 0 -height 14 -aspect bold -font $THE_FONT_NAME
 
 vfit
-
 vfps
 
 vglinfo
index 8cf798e..1098e7f 100644 (file)
@@ -6,6 +6,9 @@ puts ""
 # Draw the text with different fonts.
 #################################################
 
+dtracelevel trace
+vfont -verbose 1
+
 vtrihedron trihedr
 
 vpoint p1  100  100 -400
@@ -55,9 +58,9 @@ vdrawtext OC15 OpenCascade -pos -300 -100 -100 -color 0.0 1.0 0.0 -halign left -
 vdrawtext OC16 OpenCascade -pos -100 -300 -100 -color 0.0 1.0 0.0 -halign left -valign bottom -angle 000 -zoom 0 -height 15 -aspect regular -font Courier
 
 vdrawtext OC17 OpenCascade -pos -200 -200 100 -color 1.0 0.0 1.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font Times-Roman
-vdrawtext OC18 OpenCascade -pos -200 -200 150 -color 0.0 1.0 1.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font Arbat
-vdrawtext OC19 OpenCascade -pos -200 -200 200 -color 1.0 1.0 0.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect italic -font Elephant
-vdrawtext OC20 OpenCascade -pos -200 -200 250 -color 0.0 1.0 0.02 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect bolditalic -font RockWell
+vdrawtext OC18 OpenCascade -pos -200 -200 150 -color 0.0 1.0 1.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font sans-serif
+vdrawtext OC19 OpenCascade -pos -200 -200 200 -color 1.0 1.0 0.0 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect italic -font sans-serif
+vdrawtext OC20 OpenCascade -pos -200 -200 250 -color 0.0 1.0 0.02 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect bolditalic -font sans-serif
 vdrawtext OC21 OpenCascade -pos -200 -200 300 -color 1.0 0.0 0.02 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font Arial
 
 vglinfo
index 8fc41e1..e10559e 100644 (file)
@@ -5,15 +5,16 @@ puts ""
 pload MODELING
 pload VISUALIZATION
 
-vfont add [locate_data_file DejaVuSans.ttf] SansFont
-
 set THE_TEXT "The quick brown fox\njumps over the lazy dog!"
-set THE_FONT_NAME SansFont
+set THE_FONT_NAME sans-serif
 set THE_FONT_SIZES {12 18 24}
 
 vsetdispmode 1
 vtop
 
+dtracelevel trace
+vfont -verbose 1
+
 set aLine 0
 set aLineId 0
 foreach aSize $THE_FONT_SIZES {
index bc78e64..0d49dac 100644 (file)
@@ -5,15 +5,16 @@ puts ""
 pload MODELING
 pload VISUALIZATION
 
-vfont add [locate_data_file DejaVuSans.ttf] SansFont
-
 set THE_TEXT "The quick brown fox\njumps over the lazy dog!"
-set THE_FONT_NAME SansFont
+set THE_FONT_NAME sans-serif
 set THE_FONT_SIZES {12 18 24}
 
 vsetdispmode 1
 vtop
 
+dtracelevel trace
+vfont -verbose 1
+
 set aLine 0
 set aLineId 0
 foreach aSize $THE_FONT_SIZES {
index 07bd70d..9a26be5 100755 (executable)
@@ -1,16 +1,19 @@
 puts "================"
-puts "OCC22149"
+puts "0022149: Strings with Japanese characters can not be displayed in 3D viewer"
 puts "================"
 puts ""
-#######################################################################
-# Strings with Japanese characters can not be displayed in 3D viewer
-#######################################################################
 
 set BugNumber OCC22149
 
+dtracelevel trace
+vfont -verbose 1
 vfont add [locate_data_file bug22149_mona.ttf] Mona
-vinit
+vclear
+vinit View1
+vaxo
 vdrawtext text0 HELLO -pos 0 0 0 -color 0.0 1.0 0.0 -halign left -valign bottom -angle 0 -zoom 0 -height 50 -aspect regular
 vdrawtext text1 [encoding convertfrom unicode \x42\x30] -pos 0 0 200 -color 1.0 0.0 0.0 -halign left -valign bottom -angle 0 -zoom 0 -height 50 -aspect regular -font Mona
+vdrawtext text2 [encoding convertfrom unicode \x42\x30] -pos 0 0 400 -color 0.0 0.0 1.0 -halign left -valign bottom -angle 0 -zoom 0 -height 50 -aspect regular -font cjk
+vdrawtext text3 [encoding convertfrom unicode \x5C\xD5\x6D\xAD\xB4\xC5] -pos 0 0 -200 -color 1.0 0.0 1.0 -halign left -valign bottom -angle 0 -zoom 0 -height 50 -aspect regular -font korean
 
-checkview -screenshot -3d -path ${imagedir}/${test_image}.png
+vdump $imagedir/${casename}.png
index 3390d9e..bec43d4 100644 (file)
@@ -1,18 +1,17 @@
 puts "============"
-puts "OCC23745"
+puts "0023745: Draw Harness, ViewerText - vdrawtext command should not modify global text aspect"
 puts "============"
 puts ""
-######################################################
-# Draw Harness, ViewerText - vdrawtext command should not modify global text aspect
-######################################################
 
 pload QAcommands
 pload VISUALIZATION
 
 vfont add [locate_data_file DejaVuSans.ttf] SansFont
 
-vinit
-vdrawtext text0 "ANOTHERBUG" -pos 100 100 100 -color 1.0 0.0 0.0 -halign left -valign bottom -angle 0 -zoom 1 -height 50 -aspect SansFont
+vclear
+vinit View1
+vaxo
+vdrawtext text0 "ANOTHERBUG" -pos 100 100 100 -color 1.0 0.0 0.0 -halign left -valign bottom -angle 0 -zoom 1 -height 50 -font SansFont
 vtrihedron trihedron
 
 set x 239