[Fresco-devel] Font chooser patch

Neil Pilgrim <[email protected]>
Newsgroups gmane.comp.video.fresco.devel
Message-ID <[email protected]>
Attached mini-patch:
- tidies libart font-chooser code
- update to explicitly using Prague::getenv
- (-> have "?" ask for a font, "<n>" pick font number <n>, "" or no-env
uses default) [because of Prague::getenv behaviour - perhaps change
this?]
- removes tabs
- checks we have at least one font

The default-font code path doesn't seem to work quite right, at least it
doesn't do what I intended :(

FWIW, getenv, setenv, unsetenv all seem to be posix standard (ta njs),
so I'm not sure we actually need Prague equivalents - but perhaps this
is a good idea just because not every platform a) has posix b)
implements it correctly.

Apply as appropriate,

-- 
Neil
FontChooser.4.diff (text/plain, 7.1 KB)
Index: FTFont.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/modules/Drawing/libArt/FTFont.cc,v
retrieving revision 1.28
diff -u -r1.28 FTFont.cc
--- FTFont.cc	24 Nov 2002 22:15:57 -0000	1.28
+++ FTFont.cc	25 Nov 2002 03:08:57 -0000
@@ -22,6 +22,7 @@
 
 #include <Prague/Sys/Directory.hh>
 #include <Prague/Sys/Path.hh>
+#include <Prague/Sys/Env.hh>
 #include <Berlin/Logger.hh>
 #include <Berlin/RCManager.hh>
 #include "FTFont.hh"
@@ -42,22 +43,25 @@
 using namespace libArt;
 
 bool libArt::FTFont::chooseFaceInteractively(const std::map<FamStyle,FT_Face> &faces,
-					   const char *env, 
-					   Babylon::String &fam,
-					   Babylon::String &style)
+                                             std::string const & env, 
+                                             Babylon::String &fam,
+                                             Babylon::String &style)
 {
   int idx = -1;
-  if (env[0] == '\0')
-    {
+  if (env == "?")
+  {
       std::cout << "list of available fonts :\n";
       unsigned int i = 0;
-      for (std::map<FamStyle,FT_Face>::const_iterator j = faces.begin(); j != faces.end(); ++i, ++j)
-	{
-	  std::cout << i << ' ' << (*j).second->family_name << ' ' << (*j).second->style_name << std::endl;
-	}
+      for (std::map<FamStyle,FT_Face>::const_iterator j = faces.begin(); 
+           j != faces.end(); ++i, ++j)
+      {
+          std::cout << i << ' ' << (*j).second->family_name << ' ' 
+                    << (*j).second->style_name << std::endl;
+      }
       std::cout << "please choose a number :"; std::cin >> idx;
-    }
-  else idx = atoi(env);
+  }
+  else idx = atoi(env.c_str());
+
   std::map<FamStyle,FT_Face>::const_iterator j = faces.begin();
   for (int i = 0; i != idx && j != faces.end(); ++i, ++j);
   if (j == faces.end()) return false;
@@ -86,44 +90,70 @@
   _matrix.yy = 0x10000;
 
   if (FT_Init_FreeType(&_library))
-    {
+  {
       std::cerr << "failed to open freetype library" << std::endl;
       exit(-1);    
-    }
+  }
+  Logger::log(Logger::text) << "freetype initialised" << std::endl;
+  
   Prague::Path path = RCManager::get_path("fontpath");
   for (Prague::Path::iterator i = path.begin(); i != path.end(); ++i)
-    {
+  {
       Directory directory(*i, Directory::alpha);
-      Logger::log(Logger::text) << "libArt::FTFont: scanning font dir " << *i << std::endl;
+      Logger::log(Logger::text) << "libArt::FTFont: scanning font dir " 
+                                << *i << std::endl;
       for (Directory::iterator j = directory.begin(); j != directory.end(); ++j)
-	{
-	  if ((*j)->name() == "." || (*j)->name() == "..") continue;	  
-	  std::string file = (*j)->long_name();
-	  if (FT_New_Face(_library, file.c_str(), 0, &_face))
-	    {
-	      Logger::log(Logger::text) << "libArt::FTFont: can't open font " << file << std::endl;
-	      continue;
-	    }
-	  _familyStr = Babylon::String(_face->family_name);
-	  _styleStr = Babylon::String(_face->style_name);
-	  _family = atomize(_familyStr);
-	  _style = atomize(_styleStr);
-	  Logger::log(Logger::text) << "found FT-readable font "
-				    << _face->family_name << " (" << _family << ") " << _face->style_name << " (" << _style << ") in "
-				    << *i << std::endl;
-	  _faces[FamStyle(_family, _style)] = _face;
-	}
-    }
-  Logger::log(Logger::text) << "completed scaning font directories" << std::endl;
-  char *env = getenv("BERLIN_FONT_CHOOSER");
+      {
+          if ((*j)->name() == "." || (*j)->name() == "..") continue;  
+          std::string file = (*j)->long_name();
+          if (FT_New_Face(_library, file.c_str(), 0, &_face))
+          {
+              Logger::log(Logger::text) << "libArt::FTFont: can't open font " 
+                                        << file << std::endl;
+              continue;
+          }
+          _familyStr = Babylon::String(_face->family_name);
+          _styleStr = Babylon::String(_face->style_name);
+          _family = atomize(_familyStr);
+          _style = atomize(_styleStr);
+
+          Logger::log(Logger::text) << "found FT-readable font "
+                                    << _face->family_name << " (" 
+                                    << _family << ") " << _face->style_name 
+                                    << " (" << _style << ") in "
+                                    << *i << std::endl;
+          _faces[FamStyle(_family, _style)] = _face;
+      }
+  }
+  Logger::log(Logger::text) << "completed scanning font directories" 
+                            << std::endl;
+
+  std::string const env_value(Prague::getenv("BERLIN_FONT_CHOOSER"));
   Babylon::String tmpFam, tmpStyle;
-  if (env && chooseFaceInteractively(_faces, env, tmpFam, tmpStyle))
-    {
+  if (_faces.size()<1)
+  {   // no fonts available: error!
+      std::cerr << "ERROR: no fonts found." << std::endl
+                << "Ensure the fontpath is set correctly." << std::endl;
+      exit(1);
+  }
+  else if (env_value != "" &&
+      chooseFaceInteractively(_faces, env_value, tmpFam, tmpStyle))
+  {   // get font choice from environment
       _familyStr = tmpFam;
       _family = atomize(_familyStr);
       _styleStr = tmpStyle;
       _style = atomize(_styleStr);
-    }
+      Logger::log(Logger::text) << "Chose font interactively" << std::endl;
+  }
+  else
+  {   // use default font choice
+      _familyStr = _faces.begin()->first.first;
+      _family = atomize(_familyStr);
+      _styleStr = _faces.begin()->first.second;
+      _style = atomize(_styleStr);
+      Logger::log(Logger::text) << "Picked default font" << std::endl;
+  }
+  Logger::log(Logger::text) << "chosen font to use" << std::endl;
 }
 
 
@@ -216,19 +246,19 @@
   FT_CharMap  found = 0;
   FT_CharMap  charmap;  
   for (int n = 0; n < f->num_charmaps; n++)
-    {
+  {
       charmap = f->charmaps[n];
       if (charmap->encoding == ft_encoding_unicode)
-	{	
-	  found = charmap;
-	  break;
-	}
-    }
+      {
+          found = charmap;
+          break;
+      }
+  }
   if (!found)
-    { 
+  { 
       //     no way of translating!
       return false; 
-    }
+  }
   /* now, select the charmap for the face object */
   if (FT_Set_Charmap( f, found)) return false;
   int idx = FT_Get_Char_Index(f, (unsigned char)c);
@@ -252,10 +282,10 @@
 {
   std::map<Babylon::String, atom>::iterator i = _atoms.find(u);
   if (i == _atoms.end())
-    {
+  {
       _atoms[u] = ++_atom;
       return _atom;
-    }
+  }
   else return i->second;
 }
 
Index: FTFont.hh
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/modules/Drawing/libArt/FTFont.hh,v
retrieving revision 1.20
diff -u -r1.20 FTFont.hh
--- FTFont.hh	29 May 2002 06:49:39 -0000	1.20
+++ FTFont.hh	25 Nov 2002 03:08:58 -0000
@@ -157,7 +157,7 @@
   LRUCache<TGlyphSpec, Fresco::DrawingKit::GlyphMetrics, GlyphMetricsFactory,
 	   std::map<TGlyphSpec, Fresco::DrawingKit::GlyphMetrics,TGlyphSpec_cmp> > _glyphMetricsCache;
 private:
-  bool chooseFaceInteractively(const std::map<FamStyle, FT_Face> &, const char *, Babylon::String &, Babylon::String &);
+  static bool chooseFaceInteractively(const std::map<FamStyle, FT_Face> &, std::string const &, Babylon::String &, Babylon::String &);
 };
 
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.