]> OCCT Git - occt-copy.git/commitdiff
0030706: Visualization - fetch font folder list from fontconfig library on Linux... CR0_720_FixS_vis
authorkgv <kgv@opencascade.com>
Thu, 21 Nov 2019 09:32:56 +0000 (12:32 +0300)
committerkgv <kgv@opencascade.com>
Thu, 21 Nov 2019 09:55:53 +0000 (12:55 +0300)
vfont command now prints fonts in alphabetical order.

# Conflicts:
# adm/qmake/OccToolkit.pri

adm/cmake/occt_csf.cmake
adm/genproj.tcl
src/Font/Font_FontMgr.cxx
src/TKService/EXTERNLIB
src/ViewerTest/ViewerTest_ObjectCommands.cxx

index c62425da80807859d62534facc81086bcf51e991..07fe2ead2364d4e2c9ff492dac33a2dbde31fde1 100644 (file)
@@ -79,7 +79,7 @@ if (WIN32)
     set (CSF_OpenGlLibs  "opengl32.lib")
   endif()
 
-  else()
+else()
 
   if (APPLE)
     set (CSF_objc        "objc")
@@ -112,5 +112,6 @@ if (WIN32)
     set (CSF_OpenGlLibs  "GL")
     set (CSF_XwLibs      "X11 Xext Xmu Xi")
     set (CSF_dl          "dl")
+    set (CSF_fontconfig  "fontconfig")
   endif()
 endif()
index 2bc4f3884421ea49ca0208d00ad97e2253224378..d0cc0b1f8aa58cea3fe3acf7b5db44714b8da0ba 100644 (file)
@@ -1375,6 +1375,7 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
       set aLibsMap(CSF_TclTkLibs)  ""
       set aLibsMap(CSF_QT)         "QtCore QtGui"
     } else {
+      set aLibsMap(CSF_fontconfig) "fontconfig"
       if { "$theOS" == "qnx" } {
         # CSF_ThreadLibs - pthread API is part of libc on QNX
         set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
index 3fef8bdb7761d3e57127b3b409961927ed9922a7..4fad2f6d7609be7a48b3149b11e521d4ba8b9405 100644 (file)
@@ -88,6 +88,10 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
                                                    "/usr/X11/lib/X11/fs/config",
                                                    NULL
                                                   };
+
+    // Although fontconfig library can be built for various platforms,
+    // practically it is useful only on desktop Linux distributions, where it is always packaged.
+    #include <fontconfig/fontconfig.h>
   #endif
 
   #ifdef __APPLE__
@@ -393,7 +397,7 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
 void Font_FontMgr::InitFontDataBase()
 {
   myFontMap.Clear();
-  Handle(Font_FTLibrary) aFtLibrary;
+  Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
 
 #if defined(OCCT_UWP)
   // system font files are not accessible
@@ -428,7 +432,6 @@ void Font_FontMgr::InitFontDataBase()
     aSupportedExtensions.Add (TCollection_AsciiString (anExt));
   }
 
-  aFtLibrary = new Font_FTLibrary();
   static const DWORD aBufferSize = 256;
   char aNameBuff[aBufferSize];
   char aPathBuff[aBufferSize];
@@ -471,61 +474,86 @@ void Font_FontMgr::InitFontDataBase()
 
   NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
 #if !defined(__ANDROID__) && !defined(__APPLE__)
-  const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
-
-  // read fonts directories from font service config file (obsolete)
-  for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
+  if (FcConfig* aFcCfg = FcInitLoadConfig())
   {
-    const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
-    OSD_File aFile (aFileOfFontsPath);
-    if (!aFile.Exists())
+    if (FcStrList* aFcFontDir = FcConfigGetFontDirs (aFcCfg))
     {
-      continue;
-    }
+      for (;;)
+      {
+        FcChar8* aFcFolder = FcStrListNext (aFcFontDir);
+        if (aFcFolder == NULL)
+        {
+          break;
+        }
 
-    aFile.Open (OSD_ReadOnly, aProtectRead);
-    if (!aFile.IsOpen())
-    {
-      continue;
+        TCollection_AsciiString aPathStr ((const char* )aFcFolder);
+        OSD_Path aPath (aPathStr);
+        addDirsRecursively (aPath, aMapOfFontsDirs);
+      }
+      FcStrListDone (aFcFontDir);
     }
+    FcConfigDestroy (aFcCfg);
+  }
 
-    Standard_Integer aNByte = 256;
-    Standard_Integer aNbyteRead;
-    TCollection_AsciiString aStr; // read string with information
-    while (!aFile.IsAtEnd())
+  const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
+  if (aMapOfFontsDirs.IsEmpty())
+  {
+    Message::DefaultMessenger()->Send ("Font_FontMgr, fontconfig library returns an empty folder list", Message_Alarm);
+
+    // read fonts directories from font service config file (obsolete)
+    for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
     {
-      Standard_Integer aLocation = -1;
-      Standard_Integer aPathLocation = -1;
+      const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
+      OSD_File aFile (aFileOfFontsPath);
+      if (!aFile.Exists())
+      {
+        continue;
+      }
 
-      aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
-      aLocation = aStr.Search ("catalogue=");
-      if (aLocation < 0)
+      aFile.Open (OSD_ReadOnly, aProtectRead);
+      if (!aFile.IsOpen())
       {
-        aLocation = aStr.Search ("catalogue =");
+        continue;
       }
 
-      aPathLocation = aStr.Search ("/");
-      if (aLocation > 0 && aPathLocation > 0)
+      Standard_Integer aNByte = 256;
+      Standard_Integer aNbyteRead;
+      TCollection_AsciiString aStr; // read string with information
+      while (!aFile.IsAtEnd())
       {
-        aStr = aStr.Split (aPathLocation - 1);
-        TCollection_AsciiString aFontPath;
-        Standard_Integer aPathNumber = 1;
-        do
+        Standard_Integer aLocation = -1;
+        Standard_Integer aPathLocation = -1;
+
+        aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
+        aLocation = aStr.Search ("catalogue=");
+        if (aLocation < 0)
+        {
+          aLocation = aStr.Search ("catalogue =");
+        }
+
+        aPathLocation = aStr.Search ("/");
+        if (aLocation > 0 && aPathLocation > 0)
         {
-          // Getting directory paths, which can be splitted by "," or ":"
-          aFontPath = aStr.Token (":,", aPathNumber);
-          aFontPath.RightAdjust();
-          if (!aFontPath.IsEmpty())
+          aStr = aStr.Split (aPathLocation - 1);
+          TCollection_AsciiString aFontPath;
+          Standard_Integer aPathNumber = 1;
+          do
           {
-            OSD_Path aPath(aFontPath);
-            addDirsRecursively (aPath, aMapOfFontsDirs);
+            // Getting directory paths, which can be splitted by "," or ":"
+            aFontPath = aStr.Token (":,", aPathNumber);
+            aFontPath.RightAdjust();
+            if (!aFontPath.IsEmpty())
+            {
+              OSD_Path aPath(aFontPath);
+              addDirsRecursively (aPath, aMapOfFontsDirs);
+            }
+            aPathNumber++;
           }
-          aPathNumber++;
+          while (!aFontPath.IsEmpty());
         }
-        while (!aFontPath.IsEmpty());
       }
+      aFile.Close();
     }
-    aFile.Close();
   }
 #endif
 
@@ -545,7 +573,6 @@ void Font_FontMgr::InitFontDataBase()
     aSupportedExtensions.Add (TCollection_AsciiString (anExt));
   }
 
-  aFtLibrary = new Font_FTLibrary();
   for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
        anIter.More(); anIter.Next())
   {
index 32aba57c23d7e894badbaf04a9d7cc7eae70cc24..5bf60ae72fcd4a8addd8d8a22cbef4356528cea6 100755 (executable)
@@ -10,6 +10,7 @@ CSF_OpenGlLibs
 CSF_XwLibs
 CSF_dpsLibs
 CSF_XmuLibs
+CSF_fontconfig
 CSF_objc
 CSF_Appkit
 CSF_IOKit
index 78b69eefe027c061befe3b592fe7e3d6d621e01e..4161bab034f9b4443e79004425de159baa63b530 100644 (file)
@@ -5526,6 +5526,14 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
 //function : VFont
 //purpose  : Font management
 //=======================================================================
+struct FontComparator
+{
+  bool operator() (const Handle(Font_SystemFont)& theFontA,
+                   const Handle(Font_SystemFont)& theFontB)
+  {
+    return theFontA->FontKey().IsLess (theFontB->FontKey());
+  }
+};
 
 static int VFont (Draw_Interpretor& theDI,
                   Standard_Integer  theArgNb,
@@ -5537,9 +5545,16 @@ static int VFont (Draw_Interpretor& theDI,
     // just print the list of available fonts
     Standard_Boolean isFirst = Standard_True;
     const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
-    for (Font_NListOfSystemFont::Iterator anIter (aFonts); anIter.More(); anIter.Next())
+    std::vector<Handle(Font_SystemFont)> aFontsSorted;
+    aFontsSorted.reserve (aFonts.Size());
+    for (Font_NListOfSystemFont::Iterator aFontIter (aFonts); aFontIter.More(); aFontIter.Next())
+    {
+      aFontsSorted.push_back (aFontIter.Value());
+    }
+    std::stable_sort (aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
+    for (std::vector<Handle(Font_SystemFont)>::iterator aFontIter = aFontsSorted.begin(); aFontIter != aFontsSorted.end(); ++aFontIter)
     {
-      const Handle(Font_SystemFont)& aFont = anIter.Value();
+      const Handle(Font_SystemFont)& aFont = *aFontIter;
       if (!isFirst)
       {
         theDI << "\n";