0024386: Provide high-level API to specify font by user-defined path for AIS (Prs3d...
authorkgv <kgv@opencascade.com>
Wed, 20 Nov 2013 09:40:36 +0000 (13:40 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 21 Nov 2013 13:19:33 +0000 (17:19 +0400)
Add new command vfont to access font manager.

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

index 616f095..33f807d 100644 (file)
@@ -78,6 +78,18 @@ is
   ---         are not found in the system.
   ---Level: Public
 
+  CheckFont (me; theFontPath : CString from Standard) returns SystemFont;
+  ---Purpose: Read font file and retrieve information from it.
+  ---Level: Public
+
+  RegisterFont (me            : mutable;
+                theFont       : SystemFont;
+                theToOverride : Boolean from Standard) returns Boolean from Standard;
+  ---Purpose: 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.
+  ---Level: Public
+
   --- Private methods
 
   Create returns FontMgr is private;
index 9f71400..4f64e23 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <Font_FontMgr.ixx>
 
+#include <Font_FTLibrary.hxx>
 #include <OSD_Environment.hxx>
 #include <NCollection_List.hxx>
 #include <NCollection_Map.hxx>
@@ -170,11 +171,11 @@ static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
 // function : checkFont
 // purpose  :
 // =======================================================================
-static Handle(Font_SystemFont) checkFont (FT_Library             theFTLib,
-                                          const Standard_CString theFontPath)
+static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib,
+                                          const Standard_CString        theFontPath)
 {
   FT_Face aFontFace;
-  FT_Error aFaceError = FT_New_Face (theFTLib, theFontPath, 0, &aFontFace);
+  FT_Error aFaceError = FT_New_Face (theFTLib->Instance(), theFontPath, 0, &aFontFace);
   if (aFaceError != FT_Err_Ok)
   {
     return NULL;
@@ -227,6 +228,64 @@ Font_FontMgr::Font_FontMgr()
   InitFontDataBase();
 }
 
+// =======================================================================
+// function : CheckFont
+// purpose  :
+// =======================================================================
+Handle(Font_SystemFont) Font_FontMgr::CheckFont (Standard_CString theFontPath) const
+{
+  Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
+  return checkFont (aFtLibrary, theFontPath);
+}
+
+// =======================================================================
+// function : RegisterFont
+// purpose  :
+// =======================================================================
+Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theFont,
+                                             const Standard_Boolean         theToOverride)
+{
+  if (theFont.IsNull())
+  {
+    return Standard_False;
+  }
+
+  for (Font_NListOfSystemFont::Iterator aFontIter (myListOfFonts);
+       aFontIter.More(); aFontIter.Next())
+  {
+    if (!aFontIter.Value()->FontName()->IsSameString (theFont->FontName(), Standard_False))
+    {
+      continue;
+    }
+
+    if (theFont->FontAspect() != Font_FA_Undefined
+     && aFontIter.Value()->FontAspect() != theFont->FontAspect())
+    {
+      continue;
+    }
+
+    if (theFont->FontHeight() == -1 || aFontIter.Value()->FontHeight() == -1
+     || theFont->FontHeight() ==       aFontIter.Value()->FontHeight())
+    {
+      if (theFont->FontPath()->String() == aFontIter.Value()->FontPath()->String())
+      {
+        return Standard_True;
+      }
+      else if (theToOverride)
+      {
+        myListOfFonts.Remove (aFontIter);
+      }
+      else
+      {
+        return Standard_False;
+      }
+    }
+  }
+
+  myListOfFonts.Append (theFont);
+  return Standard_True;
+}
+
 // =======================================================================
 // function : InitFontDataBase
 // purpose  :
@@ -234,9 +293,9 @@ Font_FontMgr::Font_FontMgr()
 void Font_FontMgr::InitFontDataBase()
 {
   myListOfFonts.Clear();
-  FT_Library aFtLibrary = NULL;
+  Handle(Font_FTLibrary) aFtLibrary;
 
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
 
   // font directory is placed in "C:\Windows\Fonts\"
   UINT aStrLength = GetSystemWindowsDirectoryA (NULL, 0);
@@ -266,7 +325,7 @@ void Font_FontMgr::InitFontDataBase()
     aSupportedExtensions.Add (TCollection_AsciiString (anExt));
   }
 
-  FT_Init_FreeType (&aFtLibrary);
+  aFtLibrary = new Font_FTLibrary();
   static const DWORD aBufferSize = 256;
   char aNameBuff[aBufferSize];
   char aPathBuff[aBufferSize];
@@ -383,7 +442,7 @@ void Font_FontMgr::InitFontDataBase()
     aSupportedExtensions.Add (TCollection_AsciiString (anExt));
   }
 
-  FT_Init_FreeType (&aFtLibrary);
+  aFtLibrary = new Font_FTLibrary();
   for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
        anIter.More(); anIter.Next())
   {
@@ -468,7 +527,6 @@ void Font_FontMgr::InitFontDataBase()
     aReadFile.Close();
   }
 #endif
-  FT_Done_FreeType (aFtLibrary);
 }
 
 // =======================================================================
@@ -506,9 +564,8 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiSt
     return NULL; 
   }
 
-  Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts);
-
-  for (; aFontsIterator.More(); aFontsIterator.Next())
+  for (Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts);
+       aFontsIterator.More(); aFontsIterator.Next())
   {
     if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False))
     {
index fe6aa73..2dab667 100755 (executable)
@@ -33,6 +33,7 @@
 #include <DBRep.hxx>
 
 #include <Font_BRepFont.hxx>
+#include <Font_FontMgr.hxx>
 #include <OSD_Chronometer.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <Visual3d_View.hxx>
@@ -76,6 +77,7 @@
 #include <Geom_Plane.hxx>
 #include <gp_Pln.hxx>
 #include <TCollection_ExtendedString.hxx>
+#include <TCollection_HAsciiString.hxx>
 #include <GC_MakePlane.hxx>
 #include <gp_Circ.hxx>
 #include <AIS_Axis.hxx>
@@ -4671,6 +4673,49 @@ 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
@@ -4701,37 +4746,27 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
   while (anArgIter < theArgNb)
   {
     const TCollection_AsciiString anArg (theArgVec[anArgIter++]);
-    if (anArg.Search ("x=") > -1)
+    TCollection_AsciiString anArgCase (anArg);
+    anArgCase.LowerCase();
+    if (anArgCase.Search ("x=") > -1)
     {
       aPenLoc.SetX (anArg.Token ("=", 2).RealValue());
     }
-    else if (anArg.Search ("y=") > -1)
+    else if (anArgCase.Search ("y=") > -1)
     {
       aPenLoc.SetY (anArg.Token ("=", 2).RealValue());
     }
-    else if (anArg.Search ("z=") > -1)
+    else if (anArgCase.Search ("z=") > -1)
     {
       aPenLoc.SetZ (anArg.Token ("=", 2).RealValue());
     }
-    else if (anArg.Search ("composite=") > -1)
+    else if (anArgCase.Search ("composite=") > -1)
     {
       isCompositeCurve = (anArg.Token ("=", 2).IntegerValue() == 1);
     }
-    else if (anArg.Search ("regular") > -1)
-    {
-      aFontAspect = Font_FA_Regular;
-    }
-    else if (anArg.Search ("bolditalic") > -1)
+    else if (parseFontStyle (anArgCase, aFontAspect))
     {
-      aFontAspect = Font_FA_BoldItalic;
-    }
-    else if (anArg.Search ("bold") > -1)
-    {
-      aFontAspect = Font_FA_Bold;
-    }
-    else if (anArg.Search ("italic") > -1)
-    {
-      aFontAspect = Font_FA_Italic;
+      //
     }
     else
     {
@@ -4751,6 +4786,136 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
   return 0;
 }
 
+//=======================================================================
+//function : VFont
+//purpose  : Font management
+//=======================================================================
+
+static int VFont (Draw_Interpretor& theDI,
+                  Standard_Integer  theArgNb,
+                  const char**      theArgVec)
+{
+  Handle(Font_FontMgr) aMgr = Font_FontMgr::GetInstance();
+  if (theArgNb < 2)
+  {
+    // just print the list of available fonts
+    Standard_Boolean isFirst = Standard_True;
+    for (Font_NListOfSystemFont::Iterator anIter (aMgr->GetAvailableFonts());
+         anIter.More(); anIter.Next())
+    {
+      const Handle(Font_SystemFont)& aFont = anIter.Value();
+      if (!isFirst)
+      {
+        theDI << "\n";
+      }
+
+      theDI << aFont->FontName()->String()
+            << " " << fontStyleString (aFont->FontAspect())
+            << " " << aFont->FontPath()->String();
+      isFirst = Standard_False;
+    }
+    return 0;
+  }
+
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+  {
+    const TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    TCollection_AsciiString anArgCase (anArg);
+    anArgCase.LowerCase();
+    if (anArgCase == "find")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
+        return 1;
+      }
+
+      Standard_CString aFontName   = theArgVec[anArgIter];
+      Font_FontAspect  aFontAspect = Font_FA_Undefined;
+      if (++anArgIter < theArgNb)
+      {
+        anArgCase = theArgVec[anArgIter];
+        anArgCase.LowerCase();
+        if (!parseFontStyle (anArgCase, aFontAspect))
+        {
+          --anArgIter;
+        }
+      }
+      Handle(Font_SystemFont) aFont = aMgr->FindFont (new TCollection_HAsciiString (aFontName), aFontAspect, -1);
+      if (aFont.IsNull())
+      {
+        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")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
+        return 1;
+      }
+      Standard_CString aFontPath   = theArgVec[anArgIter];
+      Standard_CString aFontName   = NULL;
+      Font_FontAspect  aFontAspect = Font_FA_Undefined;
+      if (++anArgIter < theArgNb)
+      {
+        if (!parseFontStyle (anArgCase, aFontAspect))
+        {
+          aFontName = theArgVec[anArgIter];
+        }
+        if (++anArgIter < theArgNb)
+        {
+          anArgCase = theArgVec[anArgIter];
+          anArgCase.LowerCase();
+          if (!parseFontStyle (anArgCase, aFontAspect))
+          {
+            --anArgIter;
+          }
+        }
+      }
+
+      Handle(Font_SystemFont) aFont = aMgr->CheckFont (aFontPath);
+      if (aFont.IsNull())
+      {
+        std::cerr << "Error: font '" << aFontPath << "' is not found!\n";
+        continue;
+      }
+
+      if (aFontAspect != Font_FA_Undefined
+       || aFontName   != NULL)
+      {
+        if (aFontAspect == Font_FA_Undefined)
+        {
+          aFontAspect = aFont->FontAspect();
+        }
+        Handle(TCollection_HAsciiString) aName = aFont->FontName();
+        if (aFontName != NULL)
+        {
+          aName = new TCollection_HAsciiString (aFontName);
+        }
+        aFont = new Font_SystemFont (aName, aFontAspect, new TCollection_HAsciiString (aFontPath));
+      }
+
+      aMgr->RegisterFont (aFont, Standard_True);
+      theDI << aFont->FontName()->String()
+            << " " << fontStyleString (aFont->FontAspect())
+            << " " << aFont->FontPath()->String();
+    }
+    else
+    {
+      std::cerr << "Warning! Unknown argument '" << anArg.ToCString() << "'\n";
+    }
+  }
+
+  return 0;
+}
+
 //=======================================================================
 //function : ObjectsCommands
 //purpose  :
@@ -4890,4 +5055,8 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
   theCommands.Add ("text2brep",
                    "text2brep: res text fontName fontSize [x=0.0 y=0.0 z=0.0 composite=1 {regular,bold,italic,bolditalic=regular}]\n",
                    __FILE__, TextToBRep, group);
+  theCommands.Add ("vfont",
+                            "vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined]]"
+                   "\n\t\t:        [find fontName [regular,bold,italic,bolditalic=undefined]]",
+                   __FILE__, VFont, group);
 }