diff --git a/source/ps/NPFont.cpp b/source/ps/NPFont.cpp new file mode 100755 index 0000000000..1a35211bba --- /dev/null +++ b/source/ps/NPFont.cpp @@ -0,0 +1,102 @@ +#include "NPFont.h" + +NPFont::NPFont() +{ +} + +NPFont::~NPFont() +{ +} + +NPFont* NPFont::create(const char* name) +{ + // try and open up the file + FILE* fp=fopen(name,"rb"); + if (!fp) return 0; + + // create a new font + NPFont* font=new NPFont; + + // read text metrics + if (fread(&font->_metrics,sizeof(font->_metrics),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read characters + if (fread(font->_chars,sizeof(CharData)*128,1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read number of rows, cols of characters + if (fread(&font->_numRows,sizeof(font->_numRows),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + if (fread(&font->_numCols,sizeof(font->_numCols),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read texture dimensions + if (fread(&font->_texwidth,sizeof(font->_texwidth),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + if (fread(&font->_texheight,sizeof(font->_texheight),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read texture name + unsigned int namelen; + if (fread(&namelen,sizeof(unsigned int),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + CStr texname("gui/fonts/"); + for (uint i=0;i_texture.SetName((const char*) texname); + + // store font name + font->_name=name; + + // return created font + return font; +} + +// GetOutputStringSize: return the rendered size of given font +void NPFont::GetOutputStringSize(const char* str,int& sx,int& sy) +{ + sx=0; + sy=_metrics._height; + + int i=0; + while (str && str[i]!='\0') { + const NPFont::CharData& cdata=chardata(str[i]); + const int* cw=&cdata._widthA; + + if (cw[0]>0) sx+=cw[0]; + sx+=cw[1]+1; + if (cw[2]>0) sx+=cw[2]; + + i++; + } +} + diff --git a/source/ps/NPFont.h b/source/ps/NPFont.h new file mode 100755 index 0000000000..1c7077a7e9 --- /dev/null +++ b/source/ps/NPFont.h @@ -0,0 +1,80 @@ +#ifndef _NPFONT_H +#define _NPFONT_H + +// necessary includes +#include "CStr.h" +#include "terrain/Texture.h" + +///////////////////////////////////////////////////////////////////////////////////////// +// NPFont: +class NPFont +{ +public: + struct CharData { + int _width; // total width in pixels + int _widthA,_widthB,_widthC; // ABC widths + }; + +public: + // create - create font from given font file + static NPFont* create(const char* fontfilename); + // destructor + ~NPFont(); + + // accessor for name (font file name) + const char* name() const { return (const char*) _name; } + + // accessors for font metrics + int width(int c) const { assert(c>=0 && c<128); return _chars[c]._width; } + int height() const { return _metrics._height; } + int descent() const { return _metrics._descent; } + int maxcharwidth() const { return _metrics._maxcharwidth; } + + // accessors for texture data + int textureWidth() const { return _texwidth; } + int textureHeight() const { return _texheight; } + CTexture& texture() { return _texture; } + + + + int numCols() const { return _numCols; } + int numRows() const { return _numRows; } + + // accessor for character data + const CharData& chardata(char c) const { + assert(c>=0 && c<128); + return _chars[c]; + } + + void GetOutputStringSize(const char* str,int& sx,int& sy); + +private: + // constructor (private - all fonts created through create()) + NPFont(); + + // font name + CStr _name; + // font texture width + int _texwidth; + // font texture height + int _texheight; + // font texture + CTexture _texture; + // font metrics + struct { + int _height; + int _descent; + int _maxcharwidth; + } _metrics; + // number of rows of characters + int _numRows; + // number of columns of characters + int _numCols; + // details about specific characters in this font + CharData _chars[128]; +}; +///////////////////////////////////////////////////////////////////////////////////////// + + +#endif + diff --git a/source/ps/NPFontManager.cpp b/source/ps/NPFontManager.cpp new file mode 100755 index 0000000000..bd7c472a38 --- /dev/null +++ b/source/ps/NPFontManager.cpp @@ -0,0 +1,102 @@ +#include "NPFontManager.h" +#include "NPFont.h" + +#include + +// the sole instance of the NPFontManager +NPFontManager* NPFontManager::_instance=0; + +/////////////////////////////////////////////////////////////////////////////// +// instance: return the sole font manager instance +NPFontManager& NPFontManager::instance() +{ + if (!_instance) { + _instance=new NPFontManager; + } + return *_instance; +} + +/////////////////////////////////////////////////////////////////////////////// +// NPFontManager constructor (hidden); access available only through instance() +NPFontManager::NPFontManager() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// NPFontManager destructor +NPFontManager::~NPFontManager() +{ + // delete all collected fonts + for (uint i=0;i<_fonts.size();++i) { + delete _fonts[i]; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// release this font manager +void NPFontManager::release() +{ + if (_instance) { + delete _instance; + _instance=0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// add a font; return the created font, or 0 if not found +NPFont* NPFontManager::add(const char* name) +{ + // try and find font first + NPFont* font=find(name); + if (font) { + // ok - already got this font, return it + return font; + } + + // try and create font + font=NPFont::create(name); + if (font) { + // success - add to list + _fonts.push_back(font); + return font; + } else { + // mark as bad? just return failure for the moment + return 0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// remove a font +bool NPFontManager::remove(const char* name) +{ + // try and find font first + NPFont* font=find(name); + if (!font) { + // font not present .. + return false; + } else { + typedef std::vector::iterator Iter; + Iter iter=std::find(_fonts.begin(),_fonts.end(),font); + assert(iter != _fonts.end()); + _fonts.erase(iter); + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// find a font (return 0 if not found) +NPFont* NPFontManager::find(const char* name) +{ + // scan through font list checking names + for (uint i=0;i<_fonts.size();++i) { + NPFont* font=_fonts[i]; + if (strcmp(name,font->name())==0) { + return font; + } + } + + // got this far, font not found + return 0; + +} diff --git a/source/ps/NPFontManager.h b/source/ps/NPFontManager.h new file mode 100755 index 0000000000..79a7c01dde --- /dev/null +++ b/source/ps/NPFontManager.h @@ -0,0 +1,39 @@ +#ifndef _FONTMANAGER_H +#define _FONTMANAGER_H + +// necessary includes +#include + +// necessary declaration +class NPFont; + +class NPFontManager +{ +public: + // accessor; return the font manager + static NPFontManager& instance(); + // release this font manager + static void release(); + + // destructor + ~NPFontManager(); + + // add a font; return the created font, or 0 if not found + NPFont* add(const char* name); + // remove a font + bool remove(const char* name); + // find a font (return 0 if not found) + NPFont* find(const char* name); + +private: + // hidden constructor; access available only through instance() + NPFontManager(); + + // list of recorded fonts + std::vector _fonts; + + // the sole instance of the FontManager + static NPFontManager* _instance; +}; + +#endif