From a05ea36acb143e1d50c70f5af444e3ffe50b5222 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 19 Nov 2011 20:25:51 +0000
Subject: [PATCH] Restructure GUI code, isolate PLIB in source files, to ease
 future refactoring and alternative GUI layers.

---
 src/ATC/atcdialog.cxx           |   1 +
 src/ATCDCL/ATCDialogOld.cxx     |   1 +
 src/Cockpit/panel.cxx           |   2 +-
 src/GUI/CMakeLists.txt          |   4 +
 src/GUI/FGColor.cxx             |  54 +++++++
 src/GUI/FGColor.hxx             |  49 +++++++
 src/GUI/FGFontCache.cxx         | 223 ++++++++++++++++++++++++++++
 src/GUI/FGFontCache.hxx         |  96 +++++++++++++
 src/GUI/dialog.cxx              |   4 +
 src/GUI/gui.cxx                 |   1 +
 src/GUI/new_gui.cxx             | 248 +-------------------------------
 src/GUI/new_gui.hxx             | 118 +--------------
 src/Instrumentation/HUD/HUD.cxx |   3 +
 src/Main/globals.cxx            |   4 +-
 src/Main/main.cxx               |   2 +-
 src/Main/splash.cxx             |   5 +-
 utils/fgpanel/FGFontCache.cxx   |  15 +-
 utils/fgpanel/FGFontCache.hxx   |  10 +-
 18 files changed, 469 insertions(+), 371 deletions(-)
 create mode 100644 src/GUI/FGColor.cxx
 create mode 100644 src/GUI/FGColor.hxx
 create mode 100644 src/GUI/FGFontCache.cxx
 create mode 100644 src/GUI/FGFontCache.hxx

diff --git a/src/ATC/atcdialog.cxx b/src/ATC/atcdialog.cxx
index 912f35446..5185ee0c0 100644
--- a/src/ATC/atcdialog.cxx
+++ b/src/ATC/atcdialog.cxx
@@ -24,6 +24,7 @@
 
 #include <Main/fg_commands.hxx>
 #include <Main/globals.hxx>
+#include <Main/fg_props.hxx>
 
 #include <simgear/constants.h>
 #include <simgear/structure/commands.hxx>
diff --git a/src/ATCDCL/ATCDialogOld.cxx b/src/ATCDCL/ATCDialogOld.cxx
index 20e2f1f83..b1824180c 100644
--- a/src/ATCDCL/ATCDialogOld.cxx
+++ b/src/ATCDCL/ATCDialogOld.cxx
@@ -30,6 +30,7 @@
 #include <Main/globals.hxx>
 #include <GUI/gui.h>		// mkDialog
 #include <GUI/new_gui.hxx>
+#include <Main/fg_props.hxx>
 
 #include "ATCDialogOld.hxx"
 #include "ATC.hxx"
diff --git a/src/Cockpit/panel.cxx b/src/Cockpit/panel.cxx
index 916771726..6cdce3d70 100644
--- a/src/Cockpit/panel.cxx
+++ b/src/Cockpit/panel.cxx
@@ -57,7 +57,7 @@
 #include <Main/fg_props.hxx>
 #include <Main/viewmgr.hxx>
 #include <Time/light.hxx>
-#include <GUI/new_gui.hxx>	// FGFontCache
+#include <GUI/FGFontCache.hxx>	
 #include <Main/viewer.hxx>
 #include <Instrumentation/dclgps.hxx>
 
diff --git a/src/GUI/CMakeLists.txt b/src/GUI/CMakeLists.txt
index 428cdcb9e..eee0fcd41 100644
--- a/src/GUI/CMakeLists.txt
+++ b/src/GUI/CMakeLists.txt
@@ -14,6 +14,8 @@ set(SOURCES
 	menubar.cxx
 	new_gui.cxx
 	property_list.cxx
+	FGFontCache.cxx
+	FGColor.cxx
 	)
 
 set(HEADERS
@@ -27,6 +29,8 @@ set(HEADERS
 	menubar.hxx
 	new_gui.hxx
 	property_list.hxx
+	FGFontCache.hxx
+	FGColor.hxx
 	)
     		
 flightgear_component(GUI "${SOURCES}" "${HEADERS}")
diff --git a/src/GUI/FGColor.cxx b/src/GUI/FGColor.cxx
new file mode 100644
index 000000000..e808af662
--- /dev/null
+++ b/src/GUI/FGColor.cxx
@@ -0,0 +1,54 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "FGColor.hxx"
+
+#include <iostream>
+
+#include <simgear/props/props.hxx>
+
+////////////////////////////////////////////////////////////////////////
+// FGColor class.
+////////////////////////////////////////////////////////////////////////
+
+void
+FGColor::print() const {
+    std::cerr << "red=" << _red << ", green=" << _green
+              << ", blue=" << _blue << ", alpha=" << _alpha << std::endl;
+}
+
+bool
+FGColor::merge(const SGPropertyNode *node)
+{
+    if (!node)
+        return false;
+
+    bool dirty = false;
+    const SGPropertyNode * n;
+    if ((n = node->getNode("red")))
+        _red = n->getFloatValue(), dirty = true;
+    if ((n = node->getNode("green")))
+        _green = n->getFloatValue(), dirty = true;
+    if ((n = node->getNode("blue")))
+        _blue = n->getFloatValue(), dirty = true;
+    if ((n = node->getNode("alpha")))
+        _alpha = n->getFloatValue(), dirty = true;
+    return dirty;
+}
+
+bool
+FGColor::merge(const FGColor *color)
+{
+    bool dirty = false;
+    if (color && color->_red >= 0.0)
+        _red = color->_red, dirty = true;
+    if (color && color->_green >= 0.0)
+        _green = color->_green, dirty = true;
+    if (color && color->_blue >= 0.0)
+        _blue = color->_blue, dirty = true;
+    if (color && color->_alpha >= 0.0)
+        _alpha = color->_alpha, dirty = true;
+    return dirty;
+}
+
diff --git a/src/GUI/FGColor.hxx b/src/GUI/FGColor.hxx
new file mode 100644
index 000000000..3a8e4d6a9
--- /dev/null
+++ b/src/GUI/FGColor.hxx
@@ -0,0 +1,49 @@
+#ifndef FG_GUI_COLOR_HXX
+#define FG_GUI_COLOR_HXX
+
+// forward decls
+class SGPropertyNode;
+
+class FGColor {
+public:
+    FGColor() { clear(); }
+    FGColor(float r, float g, float b, float a = 1.0f) { set(r, g, b, a); }
+    FGColor(const SGPropertyNode *prop) { set(prop); }
+    FGColor(FGColor *c) { 
+        if (c) set(c->_red, c->_green, c->_blue, c->_alpha);
+    }
+
+    inline void clear() { _red = _green = _blue = _alpha = -1.0f; }
+    // merges in non-negative components from property with children <red> etc.
+    bool merge(const SGPropertyNode *prop);
+    bool merge(const FGColor *color);
+
+    bool set(const SGPropertyNode *prop) { clear(); return merge(prop); };
+    bool set(const FGColor *color) { clear(); return merge(color); }
+    bool set(float r, float g, float b, float a = 1.0f) {
+        _red = r, _green = g, _blue = b, _alpha = a;
+        return true;
+    }
+    bool isValid() const {
+        return _red >= 0.0 && _green >= 0.0 && _blue >= 0.0;
+    }
+    void print() const;
+
+    inline void setRed(float red) { _red = red; }
+    inline void setGreen(float green) { _green = green; }
+    inline void setBlue(float blue) { _blue = blue; }
+    inline void setAlpha(float alpha) { _alpha = alpha; }
+
+    inline float red() const { return clamp(_red); }
+    inline float green() const { return clamp(_green); }
+    inline float blue() const { return clamp(_blue); }
+    inline float alpha() const { return _alpha < 0.0 ? 1.0 : clamp(_alpha); }
+
+protected:
+    float _red, _green, _blue, _alpha;
+
+private:
+    float clamp(float f) const { return f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f; }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/GUI/FGFontCache.cxx b/src/GUI/FGFontCache.cxx
new file mode 100644
index 000000000..1f01c045b
--- /dev/null
+++ b/src/GUI/FGFontCache.cxx
@@ -0,0 +1,223 @@
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License as
+//  published by the Free Software Foundation; either version 2 of the
+//  License, or (at your option) any later version.
+// 
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#include "FGFontCache.hxx"
+
+#include <plib/fnt.h>
+#include <plib/pu.h>
+
+#include <simgear/props/props.hxx>
+
+#include <Main/globals.hxx>
+
+////////////////////////////////////////////////////////////////////////
+// FGFontCache class.
+////////////////////////////////////////////////////////////////////////
+
+extern puFont FONT_HELVETICA_14;
+extern puFont FONT_SANS_12B;
+
+namespace
+{
+struct GuiFont
+{
+    const char *name;
+    puFont *font;
+    struct Predicate
+        : public std::unary_function<const GuiFont, bool>
+    {
+        Predicate(const char* name_) : name(name_) {}
+        bool operator() (const GuiFont& f1) const
+        {
+            return ::strcmp(f1.name, name) == 0;
+        }
+        const char* name;
+    };
+};
+
+const GuiFont guifonts[] = {
+    { "default",      &PUFONT_HELVETICA_12 },
+    { "FIXED_8x13",   &PUFONT_8_BY_13 },
+    { "FIXED_9x15",   &PUFONT_9_BY_15 },
+    { "TIMES_10",     &PUFONT_TIMES_ROMAN_10 },
+    { "TIMES_24",     &PUFONT_TIMES_ROMAN_24 },
+    { "HELVETICA_10", &PUFONT_HELVETICA_10 },
+    { "HELVETICA_12", &PUFONT_HELVETICA_12 },
+    { "HELVETICA_14", &FONT_HELVETICA_14 },
+    { "HELVETICA_18", &PUFONT_HELVETICA_18 },
+    { "SANS_12B",     &FONT_SANS_12B }
+};
+
+const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])];
+}
+
+FGFontCache::FGFontCache() :
+    _initialized(false)
+{
+}
+
+FGFontCache::~FGFontCache()
+{
+   PuFontMap::iterator it, end = _puFonts.end();
+   for (it = _puFonts.begin(); it != end; ++it)
+       delete it->second;
+}
+
+inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1,
+                                                   const FntParams& f2) const
+{
+    int comp = f1.name.compare(f2.name);
+    if (comp < 0)
+        return true;
+    else if (comp > 0)
+        return false;
+    if (f1.size < f2.size)
+        return true;
+    else if (f1.size > f2.size)
+        return false;
+    return f1.slant < f2.slant;
+}
+
+struct FGFontCache::fnt *
+FGFontCache::getfnt(const char *name, float size, float slant)
+{
+    std::string fontName(name);
+    FntParams fntParams(fontName, size, slant);
+    PuFontMap::iterator i = _puFonts.find(fntParams);
+    if (i != _puFonts.end())
+        return i->second;
+    // fntTexFont s are all preloaded into the _texFonts map
+    TexFontMap::iterator texi = _texFonts.find(fontName);
+    fntTexFont* texfont = 0;
+    puFont* pufont = 0;
+    if (texi != _texFonts.end()) {
+        texfont = texi->second;
+    } else {
+        const GuiFont* guifont = std::find_if(&guifonts[0], guifontsEnd,
+                                              GuiFont::Predicate(name));
+        if (guifont != guifontsEnd) {
+            pufont = guifont->font;
+        }
+    }
+    fnt* f = new fnt;
+    if (pufont) {
+        f->pufont = pufont;
+    } else if (texfont) {
+        f->texfont = texfont;
+        f->pufont = new puFont;
+        f->pufont->initialize(static_cast<fntFont *>(f->texfont), size, slant);
+    } else {
+        f->pufont = guifonts[0].font;
+    }
+    _puFonts[fntParams] = f;
+    return f;
+}
+
+puFont *
+FGFontCache::get(const char *name, float size, float slant)
+{
+    return getfnt(name, size, slant)->pufont;
+}
+
+fntTexFont *
+FGFontCache::getTexFont(const char *name, float size, float slant)
+{
+    init();
+    return getfnt(name, size, slant)->texfont;
+}
+
+puFont *
+FGFontCache::get(SGPropertyNode *node)
+{
+    if (!node)
+        return get("Helvetica.txf", 15.0, 0.0);
+
+    const char *name = node->getStringValue("name", "Helvetica.txf");
+    float size = node->getFloatValue("size", 15.0);
+    float slant = node->getFloatValue("slant", 0.0);
+
+    return get(name, size, slant);
+}
+
+void FGFontCache::init()
+{
+    if (!_initialized) {
+        char *envp = ::getenv("FG_FONTS");
+        if (envp != NULL) {
+            _path.set(envp);
+        } else {
+            _path.set(globals->get_fg_root());
+            _path.append("Fonts");
+        }
+        _initialized = true;
+    }
+}
+
+SGPath
+FGFontCache::getfntpath(const char *name)
+{
+    init();
+    SGPath path(_path);
+    if (name && std::string(name) != "") {
+        path.append(name);
+        if (path.exists())
+            return path;
+    }
+
+    path = SGPath(_path);
+    path.append("Helvetica.txf");
+    
+    return path;
+}
+
+bool FGFontCache::initializeFonts()
+{
+    static std::string fontext("txf");
+    init();
+    ulDir* fontdir = ulOpenDir(_path.c_str());
+    if (!fontdir)
+        return false;
+    const ulDirEnt *dirEntry;
+    while ((dirEntry = ulReadDir(fontdir)) != 0) {
+        SGPath path(_path);
+        path.append(dirEntry->d_name);
+        if (path.extension() == fontext) {
+            fntTexFont* f = new fntTexFont;
+            if (f->load((char *)path.c_str()))
+                _texFonts[std::string(dirEntry->d_name)] = f;
+            else
+                delete f;
+        }
+    }
+    ulCloseDir(fontdir);
+    return true;
+}
+
+FGFontCache::fnt::~fnt()
+{
+    if (texfont) { 
+        delete pufont; 
+        delete texfont;
+    }
+}
+
diff --git a/src/GUI/FGFontCache.hxx b/src/GUI/FGFontCache.hxx
new file mode 100644
index 000000000..c9d12c7a3
--- /dev/null
+++ b/src/GUI/FGFontCache.hxx
@@ -0,0 +1,96 @@
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License as
+//  published by the Free Software Foundation; either version 2 of the
+//  License, or (at your option) any later version.
+// 
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+#ifndef __FGFONTCACHE_HXX
+#define __FGFONTCACHE_HXX
+
+#include <simgear/math/SGMath.hxx>
+#include <simgear/misc/sg_path.hxx>
+
+#include <map>
+#include <algorithm>
+
+// forward decls
+class SGPropertyNode;
+class puFont;
+class fntTexFont;
+
+/**
+ * A class to keep all fonts available for future use.
+ * This also assures a font isn't resident more than once.
+ */
+class FGFontCache {
+private:
+    // The parameters of a request to the cache.
+    struct FntParams
+    {
+        const std::string name;
+        const float size;
+        const float slant;
+        FntParams() : size(0.0f), slant(0.0f) {}
+        FntParams(const FntParams& rhs)
+            : name(rhs.name), size(rhs.size), slant(rhs.slant)
+        {
+        }
+        FntParams(const std::string& name_, float size_, float slant_)
+            : name(name_), size(size_), slant(slant_)
+        {
+        }
+    };
+    struct FntParamsLess
+        : public std::binary_function<const FntParams, const FntParams, bool>
+    {
+        bool operator() (const FntParams& f1, const FntParams& f2) const;
+    };
+    struct fnt {
+        fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
+        ~fnt();
+        
+        // Font used by plib GUI code
+        puFont *pufont;
+        // TXF font
+        fntTexFont *texfont;
+    };
+    // Path to the font directory
+    SGPath _path;
+
+    typedef std::map<const std::string, fntTexFont*> TexFontMap;
+    typedef std::map<const FntParams, fnt*, FntParamsLess> PuFontMap;
+    TexFontMap _texFonts;
+    PuFontMap _puFonts;
+
+    bool _initialized;
+    struct fnt *getfnt(const char *name, float size, float slant);
+    void init();
+
+public:
+    FGFontCache();
+    ~FGFontCache();
+
+    puFont *get(const char *name, float size=15.0, float slant=0.0);
+    puFont *get(SGPropertyNode *node);
+
+    fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
+
+    SGPath getfntpath(const char *name);
+    /**
+     * Preload all the fonts in the FlightGear font directory. It is
+     * important to load the font textures early, with the proper
+     * graphics context current, so that no plib (or our own) code
+     * tries to load a font from disk when there's no current graphics
+     * context.
+     */
+    bool initializeFonts();
+};
+#endif
diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx
index 4af5b8a68..539002992 100644
--- a/src/GUI/dialog.cxx
+++ b/src/GUI/dialog.cxx
@@ -9,6 +9,8 @@
 
 #include <Scripting/NasalSys.hxx>
 #include <Main/fg_os.hxx>
+#include <Main/globals.hxx>
+#include <Main/fg_props.hxx>
 
 #include "dialog.hxx"
 #include "new_gui.hxx"
@@ -17,6 +19,8 @@
 #include "layout.hxx"
 #include "WaypointList.hxx"
 #include "MapWidget.hxx"
+#include "FGFontCache.hxx"
+#include "FGColor.hxx"
 
 enum format_type { f_INVALID, f_INT, f_LONG, f_FLOAT, f_DOUBLE, f_STRING };
 static const int FORMAT_BUFSIZE = 255;
diff --git a/src/GUI/gui.cxx b/src/GUI/gui.cxx
index 1ae94dbb0..f659d325a 100644
--- a/src/GUI/gui.cxx
+++ b/src/GUI/gui.cxx
@@ -44,6 +44,7 @@
 #include <Main/fg_props.hxx>
 #include <Main/WindowSystemAdapter.hxx>
 #include <GUI/new_gui.hxx>
+#include <GUI/FGFontCache.hxx>
 
 #include "gui.h"
 #include "layout.hxx"
diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx
index 220d4c3fc..5f05a8f0e 100644
--- a/src/GUI/new_gui.cxx
+++ b/src/GUI/new_gui.cxx
@@ -28,9 +28,8 @@
 
 #include "menubar.hxx"
 #include "dialog.hxx"
-
-extern puFont FONT_HELVETICA_14;
-extern puFont FONT_SANS_12B;
+#include "FGFontCache.hxx"
+#include "FGColor.hxx"
 
 using std::map;
 using std::string;
@@ -326,247 +325,4 @@ NewGUI::setupFont (SGPropertyNode *node)
     return;
 }
 
-
-
-
-////////////////////////////////////////////////////////////////////////
-// FGColor class.
-////////////////////////////////////////////////////////////////////////
-
-void
-FGColor::print() const {
-    std::cerr << "red=" << _red << ", green=" << _green
-              << ", blue=" << _blue << ", alpha=" << _alpha << std::endl;
-}
-
-bool
-FGColor::merge(const SGPropertyNode *node)
-{
-    if (!node)
-        return false;
-
-    bool dirty = false;
-    const SGPropertyNode * n;
-    if ((n = node->getNode("red")))
-        _red = n->getFloatValue(), dirty = true;
-    if ((n = node->getNode("green")))
-        _green = n->getFloatValue(), dirty = true;
-    if ((n = node->getNode("blue")))
-        _blue = n->getFloatValue(), dirty = true;
-    if ((n = node->getNode("alpha")))
-        _alpha = n->getFloatValue(), dirty = true;
-    return dirty;
-}
-
-bool
-FGColor::merge(const FGColor *color)
-{
-    bool dirty = false;
-    if (color && color->_red >= 0.0)
-        _red = color->_red, dirty = true;
-    if (color && color->_green >= 0.0)
-        _green = color->_green, dirty = true;
-    if (color && color->_blue >= 0.0)
-        _blue = color->_blue, dirty = true;
-    if (color && color->_alpha >= 0.0)
-        _alpha = color->_alpha, dirty = true;
-    return dirty;
-}
-
-
-
-
-////////////////////////////////////////////////////////////////////////
-// FGFontCache class.
-////////////////////////////////////////////////////////////////////////
-
-namespace
-{
-struct GuiFont
-{
-    const char *name;
-    puFont *font;
-    struct Predicate
-        : public std::unary_function<const GuiFont, bool>
-    {
-        Predicate(const char* name_) : name(name_) {}
-        bool operator() (const GuiFont& f1) const
-        {
-            return std::strcmp(f1.name, name) == 0;
-        }
-        const char* name;
-    };
-};
-
-const GuiFont guifonts[] = {
-    { "default",      &FONT_HELVETICA_14 },
-    { "FIXED_8x13",   &PUFONT_8_BY_13 },
-    { "FIXED_9x15",   &PUFONT_9_BY_15 },
-    { "TIMES_10",     &PUFONT_TIMES_ROMAN_10 },
-    { "TIMES_24",     &PUFONT_TIMES_ROMAN_24 },
-    { "HELVETICA_10", &PUFONT_HELVETICA_10 },
-    { "HELVETICA_12", &PUFONT_HELVETICA_12 },
-    { "HELVETICA_14", &FONT_HELVETICA_14 },
-    { "HELVETICA_18", &PUFONT_HELVETICA_18 },
-    { "SANS_12B",     &FONT_SANS_12B }
-};
-
-const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])];
-}
-
-FGFontCache::FGFontCache() :
-    _initialized(false)
-{
-}
-
-FGFontCache::~FGFontCache()
-{
-#if defined(SG_UNIX) && !defined(SG_MAC) 
-   // Ugly workaround for a crash on exit with multiple screens configured
-   if (!glXGetCurrentContext())
-      return;
-#endif
-   PuFontMap::iterator it, end = _puFonts.end();
-   for (it = _puFonts.begin(); it != end; ++it)
-       delete it->second;
-}
-
-inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1,
-                                                   const FntParams& f2) const
-{
-    int comp = f1.name.compare(f2.name);
-    if (comp < 0)
-        return true;
-    else if (comp > 0)
-        return false;
-    if (f1.size < f2.size)
-        return true;
-    else if (f1.size > f2.size)
-        return false;
-    return f1.slant < f2.slant;
-}
-
-struct FGFontCache::fnt *
-FGFontCache::getfnt(const char *name, float size, float slant)
-{
-    string fontName = boost::to_lower_copy(string(name));
-    FntParams fntParams(fontName, size, slant);
-    PuFontMap::iterator i = _puFonts.find(fntParams);
-    if (i != _puFonts.end()) {
-        // found in the puFonts map, all done
-        return i->second;
-    }
-    
-    // fntTexFont s are all preloaded into the _texFonts map
-    TexFontMap::iterator texi = _texFonts.find(fontName);
-    fntTexFont* texfont = NULL;
-    puFont* pufont = NULL;
-    if (texi != _texFonts.end()) {
-        texfont = texi->second;
-    } else {
-        // check the built-in PUI fonts (in guifonts array)
-        const GuiFont* guifont = std::find_if(&guifonts[0], guifontsEnd,
-                                              GuiFont::Predicate(name));
-        if (guifont != guifontsEnd) {
-            pufont = guifont->font;
-        }
-    }
-    
-    fnt* f = new fnt;
-    if (pufont) {
-        f->pufont = pufont;
-    } else if (texfont) {
-        f->texfont = texfont;
-        f->pufont = new puFont;
-        f->pufont->initialize(static_cast<fntFont *>(f->texfont), size, slant);
-    } else {
-        f->pufont = guifonts[0].font;
-    }
-    _puFonts[fntParams] = f;
-    return f;
-}
-
-puFont *
-FGFontCache::get(const char *name, float size, float slant)
-{
-    return getfnt(name, size, slant)->pufont;
-}
-
-fntTexFont *
-FGFontCache::getTexFont(const char *name, float size, float slant)
-{
-    return getfnt(name, size, slant)->texfont;
-}
-
-puFont *
-FGFontCache::get(SGPropertyNode *node)
-{
-    if (!node)
-        return get("Helvetica.txf", 15.0, 0.0);
-
-    const char *name = node->getStringValue("name", "Helvetica.txf");
-    float size = node->getFloatValue("size", 15.0);
-    float slant = node->getFloatValue("slant", 0.0);
-
-    return get(name, size, slant);
-}
-
-void FGFontCache::init()
-{
-    if (_initialized) {
-        return;
-    }
-    
-    char *envp = ::getenv("FG_FONTS");
-    if (envp != NULL) {
-        _path.set(envp);
-    } else {
-        _path.set(globals->get_fg_root());
-        _path.append("Fonts");
-    }
-    _initialized = true;
-}
-
-SGPath
-FGFontCache::getfntpath(const char *name)
-{
-    init();
-    SGPath path(_path);
-    if (name && std::string(name) != "") {
-        path.append(name);
-        if (path.exists())
-            return path;
-    }
-
-    path = SGPath(_path);
-    path.append("Helvetica.txf");
-    SG_LOG(SG_GENERAL, SG_WARN, "Unknown font name '" << name << "', defaulting to Helvetica");
-    return path;
-}
-
-bool FGFontCache::initializeFonts()
-{
-    static string fontext("txf");
-    init();
-    ulDir* fontdir = ulOpenDir(_path.c_str());
-    if (!fontdir)
-        return false;
-    const ulDirEnt *dirEntry;
-    while ((dirEntry = ulReadDir(fontdir)) != 0) {
-        SGPath path(_path);
-        path.append(dirEntry->d_name);
-        if (path.extension() == fontext) {
-            fntTexFont* f = new fntTexFont;
-            if (f->load((char *)path.c_str())) {
-                // convert font names in the map to lowercase for matching
-                string fontName = boost::to_lower_copy(string(dirEntry->d_name));
-                _texFonts[fontName] = f;
-            } else
-                delete f;
-        }
-    }
-    ulCloseDir(fontdir);
-    return true;
-}
-
 // end of new_gui.cxx
diff --git a/src/GUI/new_gui.hxx b/src/GUI/new_gui.hxx
index 53590173e..422503a1a 100644
--- a/src/GUI/new_gui.hxx
+++ b/src/GUI/new_gui.hxx
@@ -3,8 +3,6 @@
 #ifndef __NEW_GUI_HXX
 #define __NEW_GUI_HXX 1
 
-#include <plib/pu.h>
-
 #include <simgear/props/props.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/misc/sg_path.hxx>
@@ -13,15 +11,13 @@
 #include <vector>
 #include <map>
 
-#include <Main/fg_props.hxx>
-
 class SGBinding;
 
 class FGMenuBar;
 class FGDialog;
 class FGColor;
 class FGFontCache;
-
+class puFont;
 
 /**
  * XML-configured GUI subsystem.
@@ -230,117 +226,5 @@ private:
 };
 
 
-class FGColor {
-public:
-    FGColor() { clear(); }
-    FGColor(float r, float g, float b, float a = 1.0f) { set(r, g, b, a); }
-    FGColor(const SGPropertyNode *prop) { set(prop); }
-    FGColor(FGColor *c) { 
-        if (c) set(c->_red, c->_green, c->_blue, c->_alpha);
-    }
-
-    inline void clear() { _red = _green = _blue = _alpha = -1.0f; }
-    // merges in non-negative components from property with children <red> etc.
-    bool merge(const SGPropertyNode *prop);
-    bool merge(const FGColor *color);
-
-    bool set(const SGPropertyNode *prop) { clear(); return merge(prop); };
-    bool set(const FGColor *color) { clear(); return merge(color); }
-    bool set(float r, float g, float b, float a = 1.0f) {
-        _red = r, _green = g, _blue = b, _alpha = a;
-        return true;
-    }
-    bool isValid() const {
-        return _red >= 0.0 && _green >= 0.0 && _blue >= 0.0;
-    }
-    void print() const;
-
-    inline void setRed(float red) { _red = red; }
-    inline void setGreen(float green) { _green = green; }
-    inline void setBlue(float blue) { _blue = blue; }
-    inline void setAlpha(float alpha) { _alpha = alpha; }
-
-    inline float red() const { return clamp(_red); }
-    inline float green() const { return clamp(_green); }
-    inline float blue() const { return clamp(_blue); }
-    inline float alpha() const { return _alpha < 0.0 ? 1.0 : clamp(_alpha); }
-
-protected:
-    float _red, _green, _blue, _alpha;
-
-private:
-    float clamp(float f) const { return f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f; }
-};
-
-
-
-/**
- * A class to keep all fonts available for future use.
- * This also assures a font isn't resident more than once.
- */
-class FGFontCache {
-private:
-    // The parameters of a request to the cache.
-    struct FntParams
-    {
-        const std::string name;
-        const float size;
-        const float slant;
-        FntParams() : size(0.0f), slant(0.0f) {}
-        FntParams(const FntParams& rhs)
-            : name(rhs.name), size(rhs.size), slant(rhs.slant)
-        {
-        }
-        FntParams(const std::string& name_, float size_, float slant_)
-            : name(name_), size(size_), slant(slant_)
-        {
-        }
-    };
-    struct FntParamsLess
-        : public std::binary_function<const FntParams, const FntParams, bool>
-    {
-        bool operator() (const FntParams& f1, const FntParams& f2) const;
-    };
-    struct fnt {
-        fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
-        ~fnt() { if (texfont) { delete pufont; delete texfont; } }
-        // Font used by plib GUI code
-        puFont *pufont;
-        // TXF font
-        fntTexFont *texfont;
-    };
-    // Path to the font directory
-    SGPath _path;
-
-    typedef std::map<const std::string, fntTexFont*> TexFontMap;
-    typedef std::map<const FntParams, fnt*, FntParamsLess> PuFontMap;
-    TexFontMap _texFonts;
-    PuFontMap _puFonts;
-
-    bool _initialized;
-    struct fnt *getfnt(const char *name, float size, float slant);
-    void init();
-
-public:
-    FGFontCache();
-    ~FGFontCache();
-
-    puFont *get(const char *name, float size=15.0, float slant=0.0);
-    puFont *get(SGPropertyNode *node);
-
-    fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
-
-    SGPath getfntpath(const char *name);
-    /**
-     * Preload all the fonts in the FlightGear font directory. It is
-     * important to load the font textures early, with the proper
-     * graphics context current, so that no plib (or our own) code
-     * tries to load a font from disk when there's no current graphics
-     * context.
-     */
-    bool initializeFonts();
-};
-
-
 #endif // __NEW_GUI_HXX
 
diff --git a/src/Instrumentation/HUD/HUD.cxx b/src/Instrumentation/HUD/HUD.cxx
index 2f130ae96..8cbb2e513 100644
--- a/src/Instrumentation/HUD/HUD.cxx
+++ b/src/Instrumentation/HUD/HUD.cxx
@@ -34,9 +34,12 @@
 #include <simgear/props/props_io.hxx>
 #include <osg/GLU>
 
+#include <plib/fnt.h>
+
 #include <Main/globals.hxx>
 #include <Main/viewmgr.hxx>
 #include <Main/viewer.hxx>
+#include <GUI/FGFontCache.hxx>
 
 #include "HUD.hxx"
 
diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx
index dc48bd846..e2ea2954b 100644
--- a/src/Main/globals.cxx
+++ b/src/Main/globals.cxx
@@ -47,7 +47,7 @@
 #include <ATCDCL/ATCmgr.hxx>
 #include <Autopilot/route_mgr.hxx>
 #include <Cockpit/panel.hxx>
-#include <GUI/new_gui.hxx>
+#include <GUI/FGFontCache.hxx>
 #include <Model/acmodel.hxx>
 #include <Model/modelmgr.hxx>
 #include <MultiPlayer/multiplaymgr.hxx>
@@ -220,7 +220,7 @@ void FGGlobals::set_fg_root (const string &root) {
     SGPath tmp( fg_root );
     tmp.append( "data" );
     tmp.append( "version" );
-    if ( ulFileExists( tmp.c_str() ) ) {
+    if ( tmp.exists() ) {
         fgGetNode("BAD_FG_ROOT", true)->setStringValue(fg_root);
         fg_root += "/data";
         fgGetNode("GOOD_FG_ROOT", true)->setStringValue(fg_root);
diff --git a/src/Main/main.cxx b/src/Main/main.cxx
index 3afaeceae..1cfdd7dbf 100644
--- a/src/Main/main.cxx
+++ b/src/Main/main.cxx
@@ -82,7 +82,7 @@
 #include "fg_os.hxx"
 #include "WindowSystemAdapter.hxx"
 #include <Main/viewer.hxx>
-
+#include <Main/fg_props.hxx>
 
 using namespace flightgear;
 
diff --git a/src/Main/splash.cxx b/src/Main/splash.cxx
index 5708c72e1..c3a0a7d9b 100644
--- a/src/Main/splash.cxx
+++ b/src/Main/splash.cxx
@@ -46,7 +46,10 @@
 #include <simgear/math/sg_random.h>
 #include <simgear/misc/sg_path.hxx>
 
-#include <GUI/new_gui.hxx>
+#include <plib/fnt.h>
+
+#include "GUI/FGFontCache.hxx"
+#include "GUI/FGColor.hxx"
 
 #include "globals.hxx"
 #include "fg_props.hxx"
diff --git a/utils/fgpanel/FGFontCache.cxx b/utils/fgpanel/FGFontCache.cxx
index 19a1b3746..b3bbdd6b9 100644
--- a/utils/fgpanel/FGFontCache.cxx
+++ b/utils/fgpanel/FGFontCache.cxx
@@ -22,11 +22,16 @@
 #include <windows.h>
 #endif
 
-
 #include <map>
 #include <algorithm>
+
+#include <plib/fnt.h>
+#include <plib/pu.h>
+
 #include "ApplicationProperties.hxx"
 #include "FGFontCache.hxx"
+
+
 ////////////////////////////////////////////////////////////////////////
 // FGFontCache class.
 ////////////////////////////////////////////////////////////////////////
@@ -68,6 +73,14 @@ const GuiFont guifonts[] = {
 const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])];
 }
 
+FGFontCache::fnt::~fnt()
+{
+    if (texfont) { 
+        delete pufont; 
+        delete texfont;
+    }
+}
+
 FGFontCache::FGFontCache() :
     _initialized(false)
 {
diff --git a/utils/fgpanel/FGFontCache.hxx b/utils/fgpanel/FGFontCache.hxx
index 2fd03d8ed..c2ff03d15 100644
--- a/utils/fgpanel/FGFontCache.hxx
+++ b/utils/fgpanel/FGFontCache.hxx
@@ -14,10 +14,16 @@
 //
 #ifndef __FGFONTCACHE_HXX
 #define __FGFONTCACHE_HXX
+
 #include <simgear/math/SGMath.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
-#include <plib/pu.h>
+
+
+// forward declare only!
+class puFont;
+class fntTexFont;
+
 /**
  * A class to keep all fonts available for future use.
  * This also assures a font isn't resident more than once.
@@ -47,7 +53,7 @@ private:
     };
     struct fnt {
         fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
-        ~fnt() { if (texfont) { delete pufont; delete texfont; } }
+        ~fnt();
         // Font used by plib GUI code
         puFont *pufont;
         // TXF font