0031728: Visualization, Font_FontMgr - provide function to register fallback fonts...
authorkgv <kgv@opencascade.com>
Mon, 31 Aug 2020 10:03:32 +0000 (13:03 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 2 Sep 2020 16:38:48 +0000 (19:38 +0300)
Added public method Font_FontMgr::AddFontAlias() for registering custom aliases and fallback fonts.
vfont command has been extended with arguments -aliases, -addAlias, -removeAlias, -clearAlias and -clearAliases.

src/Font/Font_FontMgr.cxx
src/Font/Font_FontMgr.hxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx

index 60a1862..fabb06d 100644 (file)
@@ -310,6 +310,114 @@ Standard_Boolean& Font_FontMgr::ToUseUnicodeSubsetFallback()
   return TheToUseUnicodeSubsetFallback;
 }
 
+// =======================================================================
+// function : AddFontAlias
+// purpose  :
+// =======================================================================
+bool Font_FontMgr::AddFontAlias (const TCollection_AsciiString& theAliasName,
+                                 const TCollection_AsciiString& theFontName)
+{
+  TCollection_AsciiString anAliasName (theAliasName);
+  anAliasName.LowerCase();
+  Handle(Font_FontAliasSequence) anAliases;
+  if (!myFontAliases.Find (anAliasName, anAliases))
+  {
+    anAliases = new Font_FontAliasSequence();
+    myFontAliases.Bind (anAliasName, anAliases);
+  }
+
+  for (Font_FontAliasSequence::Iterator anAliasIter (*anAliases); anAliasIter.More(); anAliasIter.Next())
+  {
+    if (anAliasIter.Value().FontName.IsEqual (anAliasName))
+    {
+      return false;
+    }
+  }
+
+  anAliases->Append (Font_FontAlias (theFontName));
+  return true;
+}
+
+// =======================================================================
+// function : RemoveFontAlias
+// purpose  :
+// =======================================================================
+bool Font_FontMgr::RemoveFontAlias (const TCollection_AsciiString& theAliasName,
+                                    const TCollection_AsciiString& theFontName)
+{
+  if (theAliasName.IsEmpty())
+  {
+    if (myFontAliases.IsEmpty())
+    {
+      return false;
+    }
+    myFontAliases.Clear();
+    return true;
+  }
+
+  TCollection_AsciiString anAliasName (theAliasName);
+  anAliasName.LowerCase();
+  Handle(Font_FontAliasSequence) anAliases;
+  if (!myFontAliases.Find (anAliasName, anAliases))
+  {
+    return false;
+  }
+
+  if (theFontName.IsEmpty())
+  {
+    myFontAliases.UnBind (anAliasName);
+    return true;
+  }
+
+  for (Font_FontAliasSequence::Iterator aFontIter (*anAliases); aFontIter.More(); aFontIter.Next())
+  {
+    if (aFontIter.Value().FontName.IsEqual (theFontName))
+    {
+      anAliases->Remove (aFontIter);
+      if (anAliases->IsEmpty())
+      {
+        myFontAliases.UnBind (anAliasName);
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+// =======================================================================
+// function : GetAllAliases
+// purpose  :
+// =======================================================================
+void Font_FontMgr::GetAllAliases (TColStd_SequenceOfHAsciiString& theAliases) const
+{
+  for (NCollection_DataMap<TCollection_AsciiString, Handle(Font_FontAliasSequence)>::Iterator anAliasIter (myFontAliases);
+       anAliasIter.More(); anAliasIter.Next())
+  {
+    theAliases.Append (new TCollection_HAsciiString (anAliasIter.Key()));
+  }
+}
+
+// =======================================================================
+// function : GetFontAliases
+// purpose  :
+// =======================================================================
+void Font_FontMgr::GetFontAliases (TColStd_SequenceOfHAsciiString& theFontNames,
+                                   const TCollection_AsciiString& theAliasName) const
+{
+  TCollection_AsciiString anAliasName (theAliasName);
+  anAliasName.LowerCase();
+  Handle(Font_FontAliasSequence) anAliases;
+  if (!myFontAliases.Find (anAliasName, anAliases))
+  {
+    return;
+  }
+
+  for (Font_FontAliasSequence::Iterator aFontIter (*anAliases); aFontIter.More(); aFontIter.Next())
+  {
+    theFontNames.Append (new TCollection_HAsciiString (aFontIter.Value().FontName));
+  }
+}
+
 // =======================================================================
 // function : addFontAlias
 // purpose  :
index 410bbf9..dc53819 100644 (file)
@@ -146,6 +146,8 @@ public:
     return isRegistered;
   }
 
+public:
+
   //! Return flag for tracing font aliases usage via Message_Trace messages; TRUE by default.
   Standard_Boolean ToTraceAliases() const { return myToTraceAliases; }
 
@@ -153,6 +155,44 @@ public:
   //! Can be disabled to avoid redundant messages with Message_Trace level.
   void SetTraceAliases (Standard_Boolean theToTrace) { myToTraceAliases = theToTrace; }
 
+  //! Return font names with defined aliases.
+  //! @param theAliases [out] alias names
+  Standard_EXPORT void GetAllAliases (TColStd_SequenceOfHAsciiString& theAliases) const;
+
+  //! Return aliases to specified font name.
+  //! @param theFontNames [out] font names associated with alias name
+  //! @param theAliasName [in]  alias name
+  Standard_EXPORT void GetFontAliases (TColStd_SequenceOfHAsciiString& theFontNames,
+                                       const TCollection_AsciiString& theAliasName) const;
+
+  //! Register font alias.
+  //!
+  //! Font alias allows using predefined short-cuts like Font_NOF_MONOSPACE or Font_NOF_SANS_SERIF,
+  //! and defining several fallback fonts like Font_NOF_CJK ("cjk") or "courier" for fonts,
+  //! which availability depends on system.
+  //!
+  //! By default, Font_FontMgr registers standard aliases, which could be extended or replaced by application
+  //! basing on better knowledge of the system or basing on additional fonts packaged with application itself.
+  //! Aliases are defined "in advance", so that they could point to non-existing fonts,
+  //! and they are resolved dynamically on request - first existing font is returned in case of multiple aliases to the same name.
+  //!
+  //! @param theAliasName [in] alias name or name of another font to be used as alias
+  //! @param theFontName  [in] font to be used as substitution for alias
+  //! @return FALSE if alias has been already registered
+  Standard_EXPORT bool AddFontAlias (const TCollection_AsciiString& theAliasName,
+                                     const TCollection_AsciiString& theFontName);
+
+  //! Unregister font alias.
+  //! @param theAliasName [in] alias name or name of another font to be used as alias;
+  //!                          all aliases will be removed in case of empty name
+  //! @param theFontName  [in] font to be used as substitution for alias;
+  //!                          all fonts will be removed in case of empty name
+  //! @return TRUE if alias has been removed
+  Standard_EXPORT bool RemoveFontAlias (const TCollection_AsciiString& theAliasName,
+                                        const TCollection_AsciiString& theFontName);
+
+public:
+
   //! Collects available fonts paths.
   Standard_EXPORT void InitFontDataBase();
 
index b853fba..b8dec84 100644 (file)
@@ -5742,6 +5742,52 @@ static int VFont (Draw_Interpretor& theDI,
       aMgr->RegisterFont (aFont, Standard_True);
       theDI << aFont->ToString();
     }
+    else if (anArgCase == "-aliases")
+    {
+      TCollection_AsciiString anAliasName;
+      TColStd_SequenceOfHAsciiString aNames;
+      if (anArgIter + 1 < theArgNb
+      && *theArgVec[anArgIter + 1] != '-')
+      {
+        anAliasName = theArgVec[++anArgIter];
+      }
+      if (!anAliasName.IsEmpty())
+      {
+        aMgr->GetFontAliases (aNames, anAliasName);
+      }
+      else
+      {
+        aMgr->GetAllAliases (aNames);
+      }
+      for (TColStd_SequenceOfHAsciiString::Iterator aNameIter (aNames); aNameIter.More(); aNameIter.Next())
+      {
+        theDI << "{" << aNameIter.Value()->String() << "} ";
+      }
+    }
+    else if (anArgIter + 2 < theArgNb
+          && anArgCase == "-addalias")
+    {
+      TCollection_AsciiString anAliasName(theArgVec[++anArgIter]);
+      TCollection_AsciiString aFontName  (theArgVec[++anArgIter]);
+      aMgr->AddFontAlias (anAliasName, aFontName);
+    }
+    else if (anArgIter + 2 < theArgNb
+          && anArgCase == "-removealias")
+    {
+      TCollection_AsciiString anAliasName(theArgVec[++anArgIter]);
+      TCollection_AsciiString aFontName  (theArgVec[++anArgIter]);
+      aMgr->RemoveFontAlias (anAliasName, aFontName);
+    }
+    else if (anArgIter + 1 < theArgNb
+          && anArgCase == "-clearalias")
+    {
+      TCollection_AsciiString anAliasName(theArgVec[++anArgIter]);
+      aMgr->RemoveFontAlias (anAliasName, "");
+    }
+    else if (anArgCase == "-clearaliases")
+    {
+      aMgr->RemoveFontAlias ("", "");
+    }
     else if (anArgCase == "-verbose"
           || anArgCase == "-trace")
     {
@@ -6755,6 +6801,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
                    "\n\t\t:        [-findAll fontNameMask] [-findInfo fontName]"
                    "\n\t\t:        [-unicodeFallback {on|off}]"
                    "\n\t\t:        [-clear] [-init] [-list] [-names]"
+                   "\n\t\t:        [-aliases [aliasName]] [-addAlias Alias FontName] [-removeAlias Alias FontName] [-clearAlias Alias] [-clearAliases]"
                    "\n\t\t: Work with font registry - register font, list available fonts, find font."
                    "\n\t\t: -findAll  is same as -find, but can print more than one font when mask is passed."
                    "\n\t\t: -findInfo is same as -find, but prints complete font information instead of family name.",