Restructure GUI code, isolate PLIB in source files, to ease future refactoring and alternative GUI layers.
This commit is contained in:
parent
4b2506d709
commit
a05ea36acb
18 changed files with 469 additions and 371 deletions
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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}")
|
||||
|
|
54
src/GUI/FGColor.cxx
Normal file
54
src/GUI/FGColor.cxx
Normal file
|
@ -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;
|
||||
}
|
||||
|
49
src/GUI/FGColor.hxx
Normal file
49
src/GUI/FGColor.hxx
Normal file
|
@ -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
|
223
src/GUI/FGFontCache.cxx
Normal file
223
src/GUI/FGFontCache.cxx
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
96
src/GUI/FGFontCache.hxx
Normal file
96
src/GUI/FGFontCache.hxx
Normal file
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
#include "fg_os.hxx"
|
||||
#include "WindowSystemAdapter.hxx"
|
||||
#include <Main/viewer.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
using namespace flightgear;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue