- added freetype2 / FTGL support

This commit is contained in:
Mark Vejvoda
2011-06-06 21:38:25 +00:00
parent b6b13e2f0a
commit c808a5661a
28 changed files with 1412 additions and 376 deletions

View File

@@ -121,6 +121,58 @@ IF(UNIX)
SET(EXTERNAL_LIBS ${EXTERNAL_LIBS} ${PNG_LIBRARY})
ENDIF()
FIND_PACKAGE(FontConfig)
IF(FONTCONFIG_FOUND)
SET(HAVE_FONTCONFIG 1)
INCLUDE_DIRECTORIES( ${FONTCONFIG_INCLUDE_DIR} )
SET(EXTERNAL_LIBS ${EXTERNAL_LIBS} ${FONTCONFIG_LIBRARIES} )
ENDIF(FONTCONFIG_FOUND)
OPTION(USE_FTGL "Use FTGL for on-screen fonts (found on your system)" ON)
if(USE_FTGL)
ADD_DEFINITIONS(-DUSE_FTGL)
find_package( Freetype REQUIRED)
include_directories( ${FREETYPE_INCLUDE_DIRS} )
endif(USE_FTGL)
#INCLUDE(FindPkgConfig.cmake)
#pkg_search_module (FTGL ftgl)
FIND_PACKAGE(FTGL)
IF(USE_FTGL)
if (FTGL_FOUND)
MESSAGE(STATUS "**NOTE: FTGL font support was detected and enabled.")
else()
MESSAGE(STATUS
"**NOTE: Warning! FTGL has been enabled but not detected. Your compilation will probably break. Turn off FTGL support by setting USE_FTGL to false, or visit http://ftgl.wiki.sourceforge.net/ for help on installing FTGL.")
endif()
ADD_DEFINITIONS(-DUSE_FTGL)
#set(FTGL_INCUDE_DIR ${FTGL_INCLUDE_DIR} ${CMAKE_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR})
#set(FTGL_LINK_DIRS ${FTGL_LIBRARY_DIRS} )
#set(FTGL_LINK_TARGETS ftgl freetype)
INCLUDE_DIRECTORIES(${FTGL_INCLUDE_DIR})
SET(EXTERNAL_LIBS ${EXTERNAL_LIBS} ${FTGL_LIBRARY})
ELSE()
IF(FTGL_FOUND)
MESSAGE(STATUS "**NOTE: Warning: FTGL font support was detected but NOT enabled. You can enable it by setting USE_FTGL=true")
ELSE()
MESSAGE(STATUS "**NOTE: Warning: FTGL font support was not detected. Visit http://ftgl.wiki.sourceforge.net/ for help on installing FTGL.")
ENDIF()
# todo: change this because its obscure and probably not being used
#set (FTGL_INCLUDE_DIRS )
#set (FTGL_LINK_DIRS )
#set (FTGL_LINK_TARGETS )
ENDIF(USE_FTGL)
#########################################################################################
# megaglest lib

View File

@@ -17,25 +17,31 @@
using std::string;
namespace Shared{ namespace Graphics{
class Text;
namespace Shared { namespace Graphics {
// =====================================================
// class FontMetrics
// =====================================================
class FontMetrics{
class FontMetrics {
private:
float *widths;
float height;
Text *textHandler;
public:
FontMetrics();
FontMetrics(Text *textHandler=NULL);
~FontMetrics();
void setWidth(int i, float width) {widths[i]= width;}
void setTextHandler(Text *textHandler);
Text * getTextHandler();
void setWidth(int i, float width) {this->widths[i] = width;}
void setHeight(float height) {this->height= height;}
float getTextWidth(const string &str) const;
float getTextWidth(const string &str);
float getHeight() const;
};
@@ -43,14 +49,14 @@ public:
// class Font
// =====================================================
class Font{
class Font {
public:
static int charCount;
static std::string fontTypeName;
static bool fontIsMultibyte;
public:
enum Width{
enum Width {
wNormal= 400,
wBold= 700
};
@@ -61,48 +67,53 @@ protected:
bool inited;
FontMetrics metrics;
Text *textHandler;
public:
//constructor & destructor
Font();
virtual ~Font(){};
virtual ~Font();
virtual void init()=0;
virtual void end()=0;
//get
string getType() const {return type;}
int getWidth() const {return width;}
const FontMetrics *getMetrics() const {return &metrics;}
//string getType() const {return type;}
int getWidth() const;
FontMetrics *getMetrics() {return &metrics;}
Text * getTextHandler() {return textHandler;}
//set
void setType(string type) {this->type= type;}
void setWidth(int width) {this->width= width;}
void setType(string typeX11, string typeGeneric);
void setWidth(int width);
};
// =====================================================
// class Font2D
// =====================================================
class Font2D: public Font{
class Font2D: public Font {
protected:
int size;
public:
Font2D();
virtual ~Font2D() {};
int getSize() const {return size;}
void setSize(int size) {this->size= size;}
int getSize() const;
void setSize(int size);
};
// =====================================================
// class Font3D
// =====================================================
class Font3D: public Font{
class Font3D: public Font {
protected:
float depth;
public:
Font3D();
virtual ~Font3D() {};
float getDepth() const {return depth;}
void setDepth(float depth) {this->depth= depth;}

View File

@@ -18,7 +18,7 @@
using namespace std;
namespace Shared{ namespace Graphics{
namespace Shared { namespace Graphics {
// =====================================================
// class FontManager
@@ -26,7 +26,7 @@ namespace Shared{ namespace Graphics{
/// Creates, Intializes, Finalizes, and Deletes fonts
// =====================================================
class FontManager{
class FontManager {
protected:
typedef vector<Font*> FontContainer;

View File

@@ -0,0 +1,43 @@
// ==============================================================
// This file is part of the MegaGlest Shared Library (www.megaglest.org)
//
// Copyright (C) 2011 Mark Vejvoda and others
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef Text_h
#define Text_h
#include <string>
using std::string;
/**
* Base class upon which all text rendering calls are made.
*/
//====================================================================
class Text
{
public:
Text();
virtual ~Text();
virtual void init(string fontName, int fontSize);
virtual void SetFaceSize(int);
virtual int GetFaceSize();
virtual void Render(const char*, const int = -1);
virtual float Advance(const char*, const int = -1);
virtual float LineHeight(const char* = " ", const int = -1);
virtual void Render(const wchar_t*, const int = -1);
virtual float Advance(const wchar_t*, const int = -1);
virtual float LineHeight(const wchar_t* = L" ", const int = -1);
};
#endif // Text_h

View File

@@ -27,11 +27,18 @@ namespace Shared { namespace Graphics { namespace Gl {
class FontGl {
protected:
//#ifndef USE_FTGL
GLuint handle;
//#endif
static string default_fonttype;
public:
//#ifndef USE_FTGL
GLuint getHandle() const {return handle;}
//#endif
static string getDefault_fontType() { return default_fonttype; }
static void setDefault_fontType(string value) { default_fonttype = value; }
@@ -43,8 +50,9 @@ public:
/// OpenGL bitmap font
// =====================================================
class Font2DGl: public Font2D, public FontGl{
class Font2DGl: public Font2D, public FontGl {
public:
virtual void init();
virtual void end();
};
@@ -55,8 +63,9 @@ public:
/// OpenGL outline font
// =====================================================
class Font3DGl: public Font3D, public FontGl{
class Font3DGl: public Font3D, public FontGl {
public:
virtual void init();
virtual void end();
};

View File

@@ -0,0 +1,59 @@
// ==============================================================
// This file is part of the MegaGlest Shared Library (www.megaglest.org)
//
// Copyright (C) 2011 Mark Vejvoda and others
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef TextFTGL_h
#define TextFTGL_h
#ifdef USE_FTGL
#include <FTGL/ftgl.h>
#include "font_text.h"
namespace Shared{ namespace Graphics{ namespace Gl{
/**
* Use FTGL for rendering text in OpenGL
*/
//====================================================================
class TextFTGL : public Text
{
public:
TextFTGL();
virtual ~TextFTGL();
virtual void init(string fontName, int fontSize);
virtual void SetFaceSize(int);
virtual int GetFaceSize();
virtual void Render(const char*, const int = -1);
virtual float Advance(const char*, const int = -1);
virtual float LineHeight(const char*, const int = -1);
virtual void Render(const wchar_t*, const int = -1);
virtual float Advance(const wchar_t*, const int = -1);
virtual float LineHeight(const wchar_t* = L" ", const int = -1);
private:
FTFont *ftFont;
//FTGLPixmapFont *ftFont;
const char* fontFile;
const char* findFont(const char *firstFontToTry=NULL);
void cleanupFont();
};
}}}//end namespace
#endif // USE_FTGL
#endif // TextFTGL_h

View File

@@ -15,24 +15,33 @@
#include "text_renderer.h"
#include "leak_dumper.h"
namespace Shared{ namespace Graphics{ namespace Gl{
namespace Shared { namespace Graphics { namespace Gl {
class Font2DGl;
class Font3DGl;
//#ifdef USE_FTGL
// class TextFTGL;
//#endif
// =====================================================
// class TextRenderer2DGl
// =====================================================
class TextRenderer2DGl: public TextRenderer2D{
class TextRenderer2DGl: public TextRenderer2D {
private:
const Font2DGl *font;
Font2DGl *font;
bool rendering;
//#ifdef USE_FTGL
// TextFTGL *fontFTGL;
//#endif
public:
TextRenderer2DGl();
virtual ~TextRenderer2DGl();
virtual void begin(const Font2D *font);
virtual void begin(Font2D *font);
virtual void render(const string &text, int x, int y, bool centered, Vec3f *color=NULL);
virtual void end();
};
@@ -43,13 +52,18 @@ public:
class TextRenderer3DGl: public TextRenderer3D{
private:
const Font3DGl *font;
Font3DGl *font;
bool rendering;
//#ifdef USE_FTGL
// TextFTGL *fontFTGL;
//#endif
public:
TextRenderer3DGl();
virtual ~TextRenderer3DGl();
virtual void begin(const Font3D *font);
virtual void begin(Font3D *font);
virtual void render(const string &text, float x, float y, float size, bool centered);
virtual void end();
};

View File

@@ -19,17 +19,17 @@
using std::string;
namespace Shared{ namespace Graphics{
namespace Shared { namespace Graphics {
// =====================================================
// class TextRenderer2D
// =====================================================
class TextRenderer2D{
class TextRenderer2D {
public:
virtual ~TextRenderer2D(){};
virtual void begin(const Font2D *font)= 0;
virtual void begin(Font2D *font)= 0;
virtual void render(const string &text, int x, int y, bool centered= false,Vec3f *color=NULL)= 0;
virtual void end()= 0;
};
@@ -38,11 +38,11 @@ public:
// class TextRenderer3D
// =====================================================
class TextRenderer3D{
class TextRenderer3D {
public:
virtual ~TextRenderer3D(){};
virtual void begin(const Font3D *font)= 0;
virtual void begin(Font3D *font)= 0;
virtual void render(const string &text, float x, float y, float size, bool centered= false)= 0;
virtual void end()= 0;
};

View File

@@ -34,6 +34,8 @@ typedef Uint32 uint32;
typedef Sint64 int64;
typedef Uint64 uint64;
typedef uint8 byte;
}}//end namespace
#endif

View File

@@ -12,24 +12,38 @@
#include "font.h"
#include <stdexcept>
#include "conversion.h"
#include "font_text.h"
#ifdef USE_FTGL
#include "font_textFTGL.h"
#include <vector>
#include <algorithm>
//#include "string_utils.h"
using namespace Shared::Util;
#endif
#include "leak_dumper.h"
using namespace std;
using namespace Shared::Util;
using namespace Shared::Graphics::Gl;
namespace Shared{ namespace Graphics{
int Font::charCount= 256;
std::string Font::fontTypeName = "Times New Roman";
bool Font::fontIsMultibyte = false;
// Init statics
int Font::charCount = 256;
std::string Font::fontTypeName = "Times New Roman";
bool Font::fontIsMultibyte = false;
//
// =====================================================
// class FontMetrics
// =====================================================
FontMetrics::FontMetrics() {
widths= new float[Font::charCount];
height= 0;
FontMetrics::FontMetrics(Text *textHandler) {
this->textHandler = textHandler;
this->widths = new float[Font::charCount];
this->height = 0;
for(int i=0; i < Font::charCount; ++i) {
widths[i]= 0;
@@ -41,52 +55,117 @@ FontMetrics::~FontMetrics() {
widths = NULL;
}
float FontMetrics::getTextWidth(const string &str) const {
float width= 0.f;
for(unsigned int i=0; i< str.size() && (int)i < Font::charCount; ++i){
if(str[i] >= Font::charCount) {
string sError = "str[i] >= Font::charCount, [" + str + "] i = " + intToStr(i);
throw runtime_error(sError);
}
//Treat 2 byte characters as spaces
if(str[i] < 0) {
width+= (widths[97]); // This is the letter a which is a normal wide character and good to use for spacing
//i++;
}
else {
width+= widths[str[i]];
}
}
return width;
void FontMetrics::setTextHandler(Text *textHandler) {
this->textHandler = textHandler;
}
float FontMetrics::getHeight() const{
return height;
Text * FontMetrics::getTextHandler() {
return this->textHandler;
}
float FontMetrics::getTextWidth(const string &str) {
if(textHandler != NULL) {
return textHandler->Advance(str.c_str());
}
else {
float width= 0.f;
for(unsigned int i=0; i< str.size() && (int)i < Font::charCount; ++i){
if(str[i] >= Font::charCount) {
string sError = "str[i] >= Font::charCount, [" + str + "] i = " + intToStr(i);
throw runtime_error(sError);
}
//Treat 2 byte characters as spaces
if(str[i] < 0) {
width+= (widths[97]); // This is the letter a which is a normal wide character and good to use for spacing
//i++;
}
else {
width+= widths[str[i]];
}
}
return width;
}
}
float FontMetrics::getHeight() const {
if(textHandler != NULL) {
return textHandler->LineHeight(" ");
}
else {
return height;
}
}
// ===============================================
// class Font
// ===============================================
Font::Font(){
inited= false;
type= fontTypeName;
width= 400;
Font::Font() {
inited = false;
type = fontTypeName;
width = 400;
textHandler = NULL;
#ifdef USE_FTGL
textHandler = new TextFTGL();
metrics.setTextHandler(this->textHandler);
#endif
}
Font::~Font() {
if(textHandler) {
delete textHandler;
}
textHandler = NULL;
}
void Font::setType(string typeX11, string typeGeneric) {
if(textHandler) {
textHandler->init(typeGeneric,textHandler->GetFaceSize());
}
else {
this->type= type;
}
}
void Font::setWidth(int width) {
this->width= width;
}
int Font::getWidth() const {
return width;
}
// ===============================================
// class Font2D
// ===============================================
Font2D::Font2D(){
size= 10;
Font2D::Font2D() {
size = 10;
}
int Font2D::getSize() const {
if(textHandler) {
return textHandler->GetFaceSize();
}
else {
return size;
}
}
void Font2D::setSize(int size) {
if(textHandler) {
return textHandler->SetFaceSize(size);
}
else {
this->size= size;
}
}
// ===============================================
// class Font3D
// ===============================================
Font3D::Font3D(){
Font3D::Font3D() {
depth= 10.f;
}

View File

@@ -15,41 +15,41 @@
#include "graphics_factory.h"
#include "leak_dumper.h"
namespace Shared{ namespace Graphics{
namespace Shared { namespace Graphics {
// =====================================================
// class FontManager
// =====================================================
FontManager::FontManager(){
FontManager::FontManager() {
fonts.clear();
}
FontManager::~FontManager(){
FontManager::~FontManager() {
end();
}
Font2D *FontManager::newFont2D(){
Font2D *FontManager::newFont2D() {
Font2D *font= GraphicsInterface::getInstance().getFactory()->newFont2D();
fonts.push_back(font);
return font;
}
Font3D *FontManager::newFont3D(){
Font3D *FontManager::newFont3D() {
Font3D *font= GraphicsInterface::getInstance().getFactory()->newFont3D();
fonts.push_back(font);
return font;
}
void FontManager::init(){
for(size_t i=0; i<fonts.size(); ++i){
void FontManager::init() {
for(size_t i=0; i<fonts.size(); ++i) {
if(fonts[i] != NULL) {
fonts[i]->init();
}
}
}
void FontManager::end(){
for(size_t i=0; i<fonts.size(); ++i){
void FontManager::end() {
for(size_t i=0; i<fonts.size(); ++i) {
if(fonts[i] != NULL) {
fonts[i]->end();
delete fonts[i];
@@ -58,5 +58,4 @@ void FontManager::end(){
fonts.clear();
}
}}//end namespace

View File

@@ -0,0 +1,26 @@
// ==============================================================
// This file is part of the MegaGlest Shared Library (www.megaglest.org)
//
// Copyright (C) 2011 Mark Vejvoda and others
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the
// License, or (at your option) any later version
// ==============================================================
#include "font_text.h"
using namespace std;
//====================================================================
Text::Text() {}
Text::~Text() {}
void Text::init(string fontName, int fontSize) {}
void Text::Render(const char*, const int) {}
float Text::Advance(const char*, const int) {return 0;}
float Text::LineHeight(const char*, const int) {return 0;}
void Text::Render(const wchar_t*, const int) {}
float Text::Advance(const wchar_t*, const int) {return 0;}
float Text::LineHeight(const wchar_t*, const int) {return 0;}
void Text::SetFaceSize(int) {}
int Text::GetFaceSize() {return 0;}

View File

@@ -15,7 +15,7 @@
#include "gl_wrap.h"
#include "leak_dumper.h"
namespace Shared{ namespace Graphics{ namespace Gl{
namespace Shared { namespace Graphics { namespace Gl {
using namespace Platform;
@@ -25,57 +25,65 @@ using namespace Platform;
string FontGl::default_fonttype = "fixed";
void Font2DGl::init(){
assertGl();
void Font2DGl::init() {
if(inited == false) {
//#ifndef USE_FTGL
if(getTextHandler() == NULL) {
assertGl();
handle= glGenLists(charCount);
assertGl();
if(!inited){
handle= glGenLists(charCount);
assertGl();
createGlFontBitmaps(handle, type, size, width, charCount, metrics);
createGlFontBitmaps(handle, type, size, width, charCount, metrics);
assertGl();
}
//#endif
inited= true;
}
assertGl();
}
void Font2DGl::end(){
assertGl();
if(inited){
//assert(glIsList(handle));
glDeleteLists(handle, 1);
inited= false;
void Font2DGl::end() {
if(inited) {
//#ifndef USE_FTGL
if(getTextHandler() == NULL) {
assertGl();
//assert(glIsList(handle));
glDeleteLists(handle, 1);
assertGl();
}
//#endif
inited = false;
}
assertGl();
}
// =====================================================
// class Font3DGl
// =====================================================
void Font3DGl::init(){
assertGl();
if(!inited){
handle= glGenLists(charCount);
createGlFontOutlines(handle, type, width, depth, charCount, metrics);
void Font3DGl::init() {
if(inited == false) {
//#ifndef USE_FTGL
if(getTextHandler() == NULL) {
assertGl();
handle= glGenLists(charCount);
createGlFontOutlines(handle, type, width, depth, charCount, metrics);
assertGl();
}
//#endif
inited= true;
}
assertGl();
}
void Font3DGl::end(){
assertGl();
if(inited){
assert(glIsList(handle));
glDeleteLists(handle, 1);
void Font3DGl::end() {
if(inited) {
//#ifndef USE_FTGL
if(getTextHandler() == NULL) {
assertGl();
assert(glIsList(handle));
glDeleteLists(handle, 1);
assertGl();
}
//#endif
}
assertGl();
}
}}}//end namespace

View File

@@ -0,0 +1,261 @@
// ==============================================================
// This file is part of the MegaGlest Shared Library (www.megaglest.org)
//
// Copyright (C) 2011 Mark Vejvoda and others
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the
// License, or (at your option) any later version
// ==============================================================
#ifdef USE_FTGL
//#include "gettext.h"
#include "font_textFTGL.h"
#include <stdexcept>
#include <sys/stat.h>
#include <FTGL/ftgl.h>
#ifdef HAVE_FONTCONFIG
#include <fontconfig/fontconfig.h>
#endif
using namespace std;
namespace Shared{ namespace Graphics{ namespace Gl{
//====================================================================
TextFTGL::TextFTGL() {
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",0);
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/arphic/uming.ttc",0); // Chinese
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/arphic/ukai.ttc",0); // Chinese
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-doulos/DoulosSILR.ttf",0); // Russian / Cyrillic
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-charis/CharisSILR.ttf",0); // Russian / Cyrillic
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf",0); // Russian / Cyrillic
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-scheherazade/ScheherazadeRegOT.ttf",0); // Arabic
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/linux-libertine/LinLibertine_Re.ttf",0); // Hebrew
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/unifont/unifont.ttf",0); // Czech?
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Regular.ttf",0); // Czech?
fontFile = findFont();
//ftFont = new FTBufferFont(fontFile);
//ftFont = new FTGLPixmapFont(fontFile);
//ftFont = new FTGLExtrdFont(fontFile);
//ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc");
//ftFont = new FTGLPixmapFont("/usr/share/fonts/truetype/arphic/uming.ttc");
ftFont = new FTGLPixmapFont(fontFile);
if(ftFont->Error()) {
printf("FTGL: error loading font: %s\n", fontFile);
delete ftFont; ftFont = NULL;
free((void*)fontFile);
fontFile = NULL;
throw runtime_error("FTGL: error loading font");
}
free((void*)fontFile);
fontFile = NULL;
ftFont->FaceSize(24);
//ftFont->UseDisplayList(false);
//ftFont->CharMap(ft_encoding_gb2312);
//ftFont->CharMap(ft_encoding_big5);
ftFont->CharMap(ft_encoding_unicode);
}
TextFTGL::~TextFTGL() {
cleanupFont();
}
void TextFTGL::cleanupFont() {
delete ftFont;
ftFont = NULL;
free((void*)fontFile);
fontFile = NULL;
}
void TextFTGL::init(string fontName, int fontSize) {
cleanupFont();
fontFile = findFont(fontName.c_str());
//ftFont = new FTBufferFont(fontFile);
//ftFont = new FTGLPixmapFont(fontFile);
//ftFont = new FTGLExtrdFont(fontFile);
//ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc");
//ftFont = new FTGLPixmapFont("/usr/share/fonts/truetype/arphic/uming.ttc");
ftFont = new FTGLPixmapFont(fontFile);
if(ftFont->Error()) {
printf("FTGL: error loading font: %s\n", fontFile);
delete ftFont; ftFont = NULL;
free((void*)fontFile);
fontFile = NULL;
throw runtime_error("FTGL: error loading font");
}
free((void*)fontFile);
fontFile = NULL;
if(fontSize > 0) {
ftFont->FaceSize(fontSize);
}
else {
ftFont->FaceSize(24);
}
//ftFont->UseDisplayList(false);
//ftFont->CharMap(ft_encoding_gb2312);
//ftFont->CharMap(ft_encoding_big5);
ftFont->CharMap(ft_encoding_unicode);
}
void TextFTGL::SetFaceSize(int value) {
ftFont->FaceSize(value);
}
int TextFTGL::GetFaceSize() {
return ftFont->FaceSize();
}
void TextFTGL::Render(const char* str, const int len) {
/*
FTGL renders the whole string when len == 0
but we don't want any text rendered then.
*/
if(len != 0) {
ftFont->Render(str, len);
}
}
float TextFTGL::Advance(const char* str, const int len) {
return ftFont->Advance(str, len);
}
float TextFTGL::LineHeight(const char* str, const int len) {
return ftFont->LineHeight();
}
void TextFTGL::Render(const wchar_t* str, const int len) {
/*
FTGL renders the whole string when len == 0
but we don't want any text rendered then.
*/
if(len != 0) {
ftFont->Render(str, len);
}
}
float TextFTGL::Advance(const wchar_t* str, const int len) {
return ftFont->Advance(str, len);
}
float TextFTGL::LineHeight(const wchar_t* str, const int len) {
return ftFont->LineHeight();
}
const char* TextFTGL::findFont(const char *firstFontToTry) {
struct stat statbuf;
const char* font = NULL;
const char* path = NULL;
#define CHECK_FONT_PATH(filename) \
{ \
path = filename; \
if( !font && path && 0 == stat(path, &statbuf) ) \
font = strdup(path); \
}
if(firstFontToTry) {
CHECK_FONT_PATH(getenv(firstFontToTry))
}
// Get user-specified font path
CHECK_FONT_PATH(getenv("MEGAGLEST_FONT"))
#ifdef FONT_PATH
// Get distro-specified font path
CHECK_FONT_PATH(FONT_PATH)
#endif
#ifdef HAVE_FONTCONFIG
// Get default font via fontconfig
if( !font && FcInit() ) {
FcResult result;
FcFontSet *fs;
FcPattern* pat;
FcPattern *match;
/*
TRANSLATORS: If using the FTGL backend, this should be the font
name of a font that contains all the Unicode characters in use in
your translation.
*/
pat = FcNameParse((FcChar8 *)"Gothic Uralic");
FcConfigSubstitute(0, pat, FcMatchPattern);
FcPatternDel(pat, FC_WEIGHT);
FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BOLD);
FcDefaultSubstitute(pat);
fs = FcFontSetCreate();
match = FcFontMatch(0, pat, &result);
if (match) FcFontSetAdd(fs, match);
if (pat) FcPatternDestroy(pat);
if(fs) {
FcChar8* file;
if( FcPatternGetString (fs->fonts[0], FC_FILE, 0, &file) == FcResultMatch ) {
CHECK_FONT_PATH((const char*)file)
}
FcFontSetDestroy(fs);
}
FcFini();
}
#endif
// Check a couple of common paths for Gothic Uralic/bold as a last resort
// Debian
/*
TRANSLATORS: If using the FTGL backend, this should be the path of a bold
font that contains all the Unicode characters in use in your translation.
If the font is available in Debian it should be the Debian path.
*/
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf")
/*
TRANSLATORS: If using the FTGL backend, this should be the path of a
font that contains all the Unicode characters in use in your translation.
If the font is available in Debian it should be the Debian path.
*/
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf")
// Mandrake
/*
TRANSLATORS: If using the FTGL backend, this should be the path of a bold
font that contains all the Unicode characters in use in your translation.
If the font is available in Mandrake it should be the Mandrake path.
*/
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF")
/*
TRANSLATORS: If using the FTGL backend, this should be the path of a
font that contains all the Unicode characters in use in your translation.
If the font is available in Mandrake it should be the Mandrake path.
*/
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF")
// Check the non-translated versions of the above
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf")
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf")
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF")
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF")
return font;
}
}}}//end namespace
#endif // USE_FTGL

View File

@@ -13,27 +13,53 @@
#include "opengl.h"
#include "font_gl.h"
//#include <stdlib.h>
#include "font_text.h"
//#ifdef USE_FTGL
//#include "font_textFTGL.h"
#include <vector>
#include <algorithm>
//#include "string_utils.h"
//using namespace Shared::Util;
//#endif
#include "leak_dumper.h"
namespace Shared{ namespace Graphics{ namespace Gl{
namespace Shared { namespace Graphics { namespace Gl {
// =====================================================
// class TextRenderer2DGl
// =====================================================
TextRenderer2DGl::TextRenderer2DGl(){
TextRenderer2DGl::TextRenderer2DGl() {
rendering= false;
this->font = NULL;
//#ifdef USE_FTGL
// fontFTGL = new TextFTGL();
//#endif
}
void TextRenderer2DGl::begin(const Font2D *font){
TextRenderer2DGl::~TextRenderer2DGl() {
//#ifdef USE_FTGL
// delete fontFTGL;
// fontFTGL = NULL;
//#endif
}
void TextRenderer2DGl::begin(Font2D *font) {
assert(!rendering);
rendering= true;
this->font= static_cast<const Font2DGl*>(font);
this->font= static_cast<Font2DGl*>(font);
//#ifdef USE_FTGL
// this->font->getMetrics()->setHeight(fontFTGL->LineHeight(" "));
// this->font->getMetrics()->setWidth(i,fontFTGL->Advance(" "));
//#endif
}
//// Convert a narrow string to a wide string//
// Convert a narrow string to a wide string//
//std::wstring widen(const std::string& str) {
// // Make space for wide string
// wchar_t* buffer = new wchar_t[str.size() + 1];
@@ -45,9 +71,8 @@ void TextRenderer2DGl::begin(const Font2D *font){
// std::wstring wstr = buffer;
// delete [] buffer;
// return wstr;
//
//}
//// Widen an individual character
// Widen an individual character
void TextRenderer2DGl::render(const string &text, int x, int y, bool centered, Vec3f *color) {
assert(rendering);
@@ -59,60 +84,254 @@ void TextRenderer2DGl::render(const string &text, int x, int y, bool centered, V
glColor3fv(color->ptr());
}
int line=0;
int size= font->getSize();
const unsigned char *utext= reinterpret_cast<const unsigned char*>(text.c_str());
int line = 0;
int size = font->getSize();
const unsigned char *utext = NULL;
FontMetrics *metrics = NULL;
Vec2f rasterPos;
const FontMetrics *metrics= font->getMetrics();
if(centered){
rasterPos.x= x-metrics->getTextWidth(text)/2.f;
rasterPos.y= y+metrics->getHeight()/2.f;
//#ifdef USE_FTGL
if(font->getTextHandler() != NULL) {
//font->getTextHandler()->SetFaceSize(size);
if(centered) {
rasterPos.x= x - font->getTextHandler()->Advance(text.c_str()) / 2.f;
rasterPos.y= y + font->getTextHandler()->LineHeight(text.c_str()) / 2.f;
}
else {
rasterPos= Vec2f(static_cast<float>(x), static_cast<float>(y));
}
}
else{
rasterPos= Vec2f(static_cast<float>(x), static_cast<float>(y));
else {
//#else
utext= reinterpret_cast<const unsigned char*>(text.c_str());
metrics= font->getMetrics();
if(centered) {
rasterPos.x= x-metrics->getTextWidth(text)/2.f;
rasterPos.y= y+metrics->getHeight()/2.f;
}
else {
rasterPos= Vec2f(static_cast<float>(x), static_cast<float>(y));
}
}
//#endif
glRasterPos2f(rasterPos.x, rasterPos.y);
if(Font::fontIsMultibyte == true) {
//setlocale(LC_CTYPE, "en_ca.UTF-8");
//wstring wText = widen(text);
//glListBase(font->getHandle());
//glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]);
//#ifdef USE_FTGL
if(font->getTextHandler() != NULL) {
//String str("資料");
//WString wstr(str);
//fontFTGL->Render(wstr.cw_str());
//string utfText = text;
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
//String str(L"資料");
//WString wstr(str);
//fontFTGL->Render(wstr.cw_str());
string utfText = text;
glListBase(font->getHandle());
glCallLists(text.length(), GL_UNSIGNED_SHORT, &utext[0]);
//WString wstr(L"資料");
//fontFTGL->Render(wstr.cw_str());
//std::locale loc("");
//wstring wText = widen(text);
//std::string strBuffer(Text.size() * 4 + 1, 0);
//std::use_facet<std::ctype<wchar_t> >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]);
//string utfText = std::string(&strBuffer[0]);
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
}
else {
for (int i=0; utext[i]!='\0'; ++i) {
switch(utext[i]){
case '\t':
rasterPos= Vec2f((rasterPos.x/size+3.f)*size, y-(size+1.f)*line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
line++;
rasterPos= Vec2f(static_cast<float>(x), y-(metrics->getHeight()*2.f)*line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
glCallList(font->getHandle()+utext[i]);
//size_t length = text.length();
// string temp = String::ConvertToUTF8("資料");
// size_t length = temp.length();
// wchar_t *utf32 = (wchar_t*)malloc((length+1) * sizeof(wchar_t));
// mbstowcs(utf32, temp.c_str(), length);
// utf32[length] = 0;
// fontFTGL->Render(utf32);
// free(utf32);
//wstring wstr(L"資料");
//fontFTGL->Render(wstr.c_str());
//fontFTGL->Render(text.c_str());
//const wchar_t *str = L" 中文";
//fontFTGL->Render(str);
//fontFTGL->Render(" 中文"); // Chinese Works!
//fontFTGL->Render("ёшзхсдертбнйуимлопьжющэъ́"); // Russian Works!
//fontFTGL->Render("更新履歴はこちらをご覧下さい。"); // Japanese Works!
//fontFTGL->Render("مرحبا العالم"); //Arabic Works!
//wstring temp = L"مرحبا العالم";
//temp = wstring (temp.rbegin(), temp.rend());
//fontFTGL->Render(temp.c_str());
// Hebrew is Right To Left
//wstring temp = L"שלום העולם";
//temp = wstring (temp.rbegin(), temp.rend());
//fontFTGL->Render(temp.c_str());
//fontFTGL->Render("testování slovanský jazyk"); // Czech Works!
// This works
//fontFTGL->Render(text.c_str());
if(text.find("\n") == text.npos && text.find("\t") == text.npos) {
font->getTextHandler()->Render(text.c_str());
}
else {
bool lastCharacterWasSpecial = true;
vector<string> parts;
char szBuf[4096]="";
for (int i=0; text[i] != '\0'; ++i) {
szBuf[0] = '\0';
sprintf(szBuf,"%c",text[i]);
switch(text[i]) {
case '\t':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//line++;
//rasterPos= Vec2f(static_cast<float>(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
//glCallList(font->getHandle()+utext[i]);
if(lastCharacterWasSpecial == true) {
parts.push_back(szBuf);
}
else {
parts[parts.size()-1] += szBuf;
}
lastCharacterWasSpecial = false;
}
}
for (unsigned int i=0; i < parts.size(); ++i) {
switch(parts[i][0]) {
case '\t':
rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
line++;
rasterPos= Vec2f(static_cast<float>(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
font->getTextHandler()->Render(parts[i].c_str());
}
}
}
}
else {
//#else
//setlocale(LC_CTYPE, "en_ca.UTF-8");
//wstring wText = widen(text);
//glListBase(font->getHandle());
//glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]);
//string utfText = text;
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
string utfText = text;
glListBase(font->getHandle());
glCallLists(text.length(), GL_UNSIGNED_SHORT, &utext[0]);
//std::locale loc("");
//wstring wText = widen(text);
//std::string strBuffer(Text.size() * 4 + 1, 0);
//std::use_facet<std::ctype<wchar_t> >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]);
//string utfText = std::string(&strBuffer[0]);
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
}
//#endif
}
else {
//#ifdef USE_FTGL
if(font->getTextHandler() != NULL) {
if(text.find("\n") == text.npos && text.find("\t") == text.npos) {
font->getTextHandler()->Render(text.c_str());
}
else {
bool lastCharacterWasSpecial = true;
vector<string> parts;
char szBuf[4096]="";
for (int i=0; text[i] != '\0'; ++i) {
szBuf[0] = '\0';
sprintf(szBuf,"%c",text[i]);
switch(text[i]) {
case '\t':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//line++;
//rasterPos= Vec2f(static_cast<float>(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
//glCallList(font->getHandle()+utext[i]);
if(lastCharacterWasSpecial == true) {
parts.push_back(szBuf);
}
else {
parts[parts.size()-1] += szBuf;
}
lastCharacterWasSpecial = false;
}
}
for (unsigned int i=0; i < parts.size(); ++i) {
switch(parts[i][0]) {
case '\t':
rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
line++;
rasterPos= Vec2f(static_cast<float>(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
font->getTextHandler()->Render(parts[i].c_str());
}
}
}
}
else {
//#else
for (int i=0; utext[i]!='\0'; ++i) {
switch(utext[i]){
case '\t':
rasterPos= Vec2f((rasterPos.x/size+3.f)*size, y-(size+1.f)*line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
line++;
rasterPos= Vec2f(static_cast<float>(x), y-(metrics->getHeight()*2.f)*line);
glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
glCallList(font->getHandle()+utext[i]);
}
}
}
//#endif
}
if(color != NULL) {
@@ -121,7 +340,7 @@ void TextRenderer2DGl::render(const string &text, int x, int y, bool centered, V
assertGl();
}
void TextRenderer2DGl::end(){
void TextRenderer2DGl::end() {
assert(rendering);
rendering= false;
}
@@ -130,15 +349,26 @@ void TextRenderer2DGl::end(){
// class TextRenderer3DGl
// =====================================================
TextRenderer3DGl::TextRenderer3DGl(){
TextRenderer3DGl::TextRenderer3DGl() {
rendering= false;
this->font = NULL;
//#ifdef USE_FTGL
// fontFTGL = new TextFTGL();
//#endif
}
void TextRenderer3DGl::begin(const Font3D *font){
TextRenderer3DGl::~TextRenderer3DGl() {
//#ifdef USE_FTGL
// delete fontFTGL;
// fontFTGL = NULL;
//#endif
}
void TextRenderer3DGl::begin(Font3D *font) {
assert(!rendering);
rendering= true;
this->font= static_cast<const Font3DGl*>(font);
this->font= static_cast<Font3DGl*>(font);
assertGl();
@@ -148,53 +378,208 @@ void TextRenderer3DGl::begin(const Font3D *font){
assertGl();
}
void TextRenderer3DGl::render(const string &text, float x, float y, float size, bool centered){
void TextRenderer3DGl::render(const string &text, float x, float y, float size, bool centered) {
assert(rendering);
const unsigned char *utext= NULL;
assertGl();
const unsigned char *utext= reinterpret_cast<const unsigned char*>(text.c_str());
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glPushAttrib(GL_POLYGON_BIT);
float scale= size/10.f;
if(centered){
const FontMetrics *metrics= font->getMetrics();
glTranslatef(x-scale*metrics->getTextWidth(text)/2.f, y-scale*metrics->getHeight()/2.f, 0);
float scale= size / 10.f;
Vec3f translatePos;
//#ifdef USE_FTGL
if(font->getTextHandler() != NULL) {
//font->getTextHandler()->SetFaceSize(size);
if(centered) {
translatePos.x = x - scale * font->getTextHandler()->Advance(text.c_str()) / 2.f;
translatePos.y = y - scale * font->getTextHandler()->LineHeight(text.c_str()) / 2.f;
translatePos.z = 0;
}
else {
translatePos.x = x-scale;
translatePos.y = y-scale;
translatePos.z = 0;
}
}
else{
glTranslatef(x-scale, y-scale, 0);
else {
//#else
utext= reinterpret_cast<const unsigned char*>(text.c_str());
if(centered) {
FontMetrics *metrics= font->getMetrics();
//glTranslatef(x-scale*metrics->getTextWidth(text)/2.f, y-scale*metrics->getHeight()/2.f, 0);
translatePos.x = x-scale*metrics->getTextWidth(text)/2.f;
translatePos.y = y-scale*metrics->getHeight()/2.f;
translatePos.z = 0;
}
else {
//glTranslatef(x-scale, y-scale, 0);
translatePos.x = x-scale;
translatePos.y = y-scale;
translatePos.z = 0;
}
}
//#endif
glTranslatef(translatePos.x, translatePos.y, translatePos.z);
glScalef(scale, scale, scale);
if(Font::fontIsMultibyte == true) {
//setlocale(LC_CTYPE, "en_ca.UTF-8");
//wstring wText = widen(text);
//glListBase(font->getHandle());
//glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]);
//#ifdef USE_FTGL
if(font->getTextHandler() != NULL) {
if(text.find("\n") == text.npos && text.find("\t") == text.npos) {
font->getTextHandler()->Render(text.c_str());
}
else {
int line=0;
bool lastCharacterWasSpecial = true;
vector<string> parts;
char szBuf[4096]="";
//string utfText = text;
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
for (int i=0; text[i] != '\0'; ++i) {
szBuf[0] = '\0';
sprintf(szBuf,"%c",text[i]);
string utfText = text;
glListBase(font->getHandle());
glCallLists(text.length(), GL_UNSIGNED_SHORT, &utext[0]);
switch(text[i]) {
case '\t':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//line++;
//rasterPos= Vec2f(static_cast<float>(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
//glCallList(font->getHandle()+utext[i]);
if(lastCharacterWasSpecial == true) {
parts.push_back(szBuf);
}
else {
parts[parts.size()-1] += szBuf;
}
lastCharacterWasSpecial = false;
}
}
//std::locale loc("");
//wstring wText = widen(text);
//std::string strBuffer(Text.size() * 4 + 1, 0);
//std::use_facet<std::ctype<wchar_t> >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]);
//string utfText = std::string(&strBuffer[0]);
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
for (unsigned int i=0; i < parts.size(); ++i) {
switch(parts[i][0]) {
case '\t':
translatePos= Vec3f((translatePos.x / size + 3.f) * size, y-(size + 1.f) * line, translatePos.z);
glTranslatef(translatePos.x, translatePos.y, translatePos.z);
break;
case '\n':
line++;
translatePos= Vec3f(static_cast<float>(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line, translatePos.z);
glTranslatef(translatePos.x, translatePos.y, translatePos.z);
break;
default:
font->getTextHandler()->Render(parts[i].c_str());
}
}
}
}
else {
//#else
//setlocale(LC_CTYPE, "en_ca.UTF-8");
//wstring wText = widen(text);
//glListBase(font->getHandle());
//glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]);
//string utfText = text;
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
string utfText = text;
glListBase(font->getHandle());
glCallLists(text.length(), GL_UNSIGNED_SHORT, &utext[0]);
//std::locale loc("");
//wstring wText = widen(text);
//std::string strBuffer(Text.size() * 4 + 1, 0);
//std::use_facet<std::ctype<wchar_t> >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]);
//string utfText = std::string(&strBuffer[0]);
//glListBase(font->getHandle());
//glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]);
}
//#endif
}
else {
for (int i=0; utext[i]!='\0'; ++i) {
glCallList(font->getHandle()+utext[i]);
if(font->getTextHandler() != NULL) {
//#ifdef USE_FTGL
if(text.find("\n") == text.npos && text.find("\t") == text.npos) {
font->getTextHandler()->Render(text.c_str());
}
else {
int line=0;
bool lastCharacterWasSpecial = true;
vector<string> parts;
char szBuf[4096]="";
for (int i=0; text[i] != '\0'; ++i) {
szBuf[0] = '\0';
sprintf(szBuf,"%c",text[i]);
switch(text[i]) {
case '\t':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
case '\n':
parts.push_back(szBuf);
lastCharacterWasSpecial = true;
//line++;
//rasterPos= Vec2f(static_cast<float>(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line);
//glRasterPos2f(rasterPos.x, rasterPos.y);
break;
default:
//glCallList(font->getHandle()+utext[i]);
if(lastCharacterWasSpecial == true) {
parts.push_back(szBuf);
}
else {
parts[parts.size()-1] += szBuf;
}
lastCharacterWasSpecial = false;
}
}
for (unsigned int i=0; i < parts.size(); ++i) {
switch(parts[i][0]) {
case '\t':
translatePos= Vec3f((translatePos.x / size + 3.f) * size, y-(size + 1.f) * line, translatePos.z);
glTranslatef(translatePos.x, translatePos.y, translatePos.z);
break;
case '\n':
line++;
translatePos= Vec3f(static_cast<float>(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line, translatePos.z);
glTranslatef(translatePos.x, translatePos.y, translatePos.z);
break;
default:
font->getTextHandler()->Render(parts[i].c_str());
}
}
}
}
else {
//#else
for (int i=0; utext[i]!='\0'; ++i) {
glCallList(font->getHandle()+utext[i]);
}
}
//#endif
}
glPopMatrix();
glPopAttrib();
@@ -202,7 +587,7 @@ void TextRenderer3DGl::render(const string &text, float x, float y, float size,
assertGl();
}
void TextRenderer3DGl::end(){
void TextRenderer3DGl::end() {
assert(rendering);
rendering= false;

View File

@@ -34,6 +34,8 @@ namespace Shared { namespace Platform {
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
int charCount, FontMetrics &metrics) {
//#ifndef USE_FTGL
Display* display = glXGetCurrentDisplay();
if(display == 0) {
throw std::runtime_error("Couldn't create font: display is 0");
@@ -144,6 +146,7 @@ void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
glXUseXFont(fontInfo->fid, 0, charCount, base);
XFreeFont(display, fontInfo);
//#endif
}
void createGlFontOutlines(uint32 &base, const string &type, int width,

View File

@@ -27,157 +27,158 @@ using namespace Shared::Util;
namespace Shared{ namespace Platform{
//#ifndef USE_FTGL
// ======================================
// Global Fcs
// ======================================
// ======================================
// Global Fcs
// ======================================
int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX *lpelfe,
NEWTEXTMETRICEX *lpntme,
int FontType,
LPARAM lParam) {
std::vector<std::string> *systemFontList = (std::vector<std::string> *)lParam;
systemFontList->push_back((char *)lpelfe->elfFullName);
return 1; // I want to get all fonts
}
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX *lpelfe,
NEWTEXTMETRICEX *lpntme,
int FontType,
LPARAM lParam) {
std::vector<std::string> *systemFontList = (std::vector<std::string> *)lParam;
systemFontList->push_back((char *)lpelfe->elfFullName);
return 1; // I want to get all fonts
}
//#endif
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
int charCount, FontMetrics &metrics) {
//return;
//return;
// -adecw-screen-medium-r-normal--18-180-75-75-m-160-gb2312.1980-1 this is a Chinese font
//#ifndef USE_FTGL
// -adecw-screen-medium-r-normal--18-180-75-75-m-160-gb2312.1980-1 this is a Chinese font
std::string useRealFontName = type;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] trying to load useRealFontName [%s], size = %d, width = %d\n",__FILE__,__FUNCTION__,__LINE__,useRealFontName.c_str(),size,width);
DWORD dwErrorGL = 0;
HDC hDC = 0;
static std::vector<std::string> systemFontList;
if(systemFontList.size() == 0) {
LOGFONT lf;
//POSITION pos;
//lf.lfCharSet = ANSI_CHARSET;
lf.lfCharSet = (BYTE)charSet;
lf.lfFaceName[0]='\0';
std::string useRealFontName = type;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] trying to load useRealFontName [%s], size = %d, width = %d\n",__FILE__,__FUNCTION__,__LINE__,useRealFontName.c_str(),size,width);
//HGLRC hdRC =wglGetCurrentContext();
//DWORD dwErrorGL = GetLastError();
//assertGl();
hDC = wglGetCurrentDC();
dwErrorGL = GetLastError();
assertGl();
//hDC = CreateCompatibleDC(0);
//dwErrorGL = GetLastError();
::EnumFontFamiliesEx(hDC,
&lf,
(FONTENUMPROC) EnumFontFamExProc,
(LPARAM) &systemFontList, 0);
DWORD dwErrorGL = 0;
HDC hDC = 0;
static std::vector<std::string> systemFontList;
if(systemFontList.size() == 0) {
LOGFONT lf;
//POSITION pos;
//lf.lfCharSet = ANSI_CHARSET;
lf.lfCharSet = (BYTE)charSet;
lf.lfFaceName[0]='\0';
//HGLRC hdRC =wglGetCurrentContext();
//DWORD dwErrorGL = GetLastError();
//assertGl();
hDC = wglGetCurrentDC();
dwErrorGL = GetLastError();
assertGl();
//hDC = CreateCompatibleDC(0);
//dwErrorGL = GetLastError();
::EnumFontFamiliesEx(hDC,
&lf,
(FONTENUMPROC) EnumFontFamExProc,
(LPARAM) &systemFontList, 0);
for(unsigned int idx = 0; idx < systemFontList.size(); ++idx) {
string &fontName = systemFontList[idx];
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found system font [%s]\n",__FILE__,__FUNCTION__,__LINE__,fontName.c_str());
}
for(unsigned int idx = 0; idx < systemFontList.size(); ++idx) {
string &fontName = systemFontList[idx];
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found system font [%s]\n",__FILE__,__FUNCTION__,__LINE__,fontName.c_str());
}
else {
for(unsigned int idx = 0; idx < systemFontList.size(); ++idx) {
string &fontName = systemFontList[idx];
}
else {
for(unsigned int idx = 0; idx < systemFontList.size(); ++idx) {
string &fontName = systemFontList[idx];
if(_stricmp(useRealFontName.c_str(),fontName.c_str()) != 0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] switch font name from [%s] to [%s]\n",__FILE__,__FUNCTION__,__LINE__,useRealFontName.c_str(),fontName.c_str());
if(_stricmp(useRealFontName.c_str(),fontName.c_str()) != 0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] switch font name from [%s] to [%s]\n",__FILE__,__FUNCTION__,__LINE__,useRealFontName.c_str(),fontName.c_str());
useRealFontName = fontName;
break;
}
}
}
LPWSTR wstr = Ansi2WideString(useRealFontName.c_str());
HFONT font= CreateFont(
size, 0, 0, 0, width, FALSE, FALSE, FALSE, charSet,
OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH| (useRealFontName.c_str() ? FF_DONTCARE:FF_SWISS), wstr);
delete [] wstr;
assert(font!=NULL);
HDC dc= wglGetCurrentDC();
dwErrorGL = GetLastError();
assertGl();
SelectObject(dc, font);
dwErrorGL = GetLastError();
assertGl();
BOOL err= 0;
err= wglUseFontBitmaps(dc, 0, charCount, base);
dwErrorGL = GetLastError();
/*
for(int glBugRetry = 0; glBugRetry <= 10; glBugRetry++) {
err= wglUseFontBitmaps(dc, 0, charCount, base);
dwErrorGL = GetLastError();
//assertGl();
GLenum error = glGetError();
if(error == 0) {
useRealFontName = fontName;
break;
}
}
*/
assertGl();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] wglUseFontBitmaps returned = %d, charCount = %d, base = %d\n",__FILE__,__FUNCTION__,__LINE__,err,charCount,base);
FIXED one;
one.value= 1;
one.fract= 0;
FIXED zero;
zero.value= 0;
zero.fract= 0;
MAT2 mat2;
mat2.eM11= one;
mat2.eM12= zero;
mat2.eM21= zero;
mat2.eM22= one;
//MAT2 mat2 = {{0,1},{0,0},{0,0},{0,1}};
//metrics
GLYPHMETRICS glyphMetrics;
int errorCode= GetGlyphOutline(dc, 'a', GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] GetGlyphOutline returned = %d\n",__FILE__,__FUNCTION__,__LINE__,errorCode);
if(errorCode!=GDI_ERROR){
metrics.setHeight(static_cast<float>(glyphMetrics.gmBlackBoxY));
}
for(int i=0; i<charCount; ++i){
int errorCode= GetGlyphOutline(dc, i, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(errorCode!=GDI_ERROR){
metrics.setWidth(i, static_cast<float>(glyphMetrics.gmCellIncX));
}
else {
metrics.setWidth(i, static_cast<float>(6));
}
}
DeleteObject(font);
//if(hDC != 0) {
// DeleteDC(hDC);
//}
}
assert(err);
LPWSTR wstr = Ansi2WideString(useRealFontName.c_str());
HFONT font= CreateFont(
size, 0, 0, 0, width, FALSE, FALSE, FALSE, charSet,
OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH| (useRealFontName.c_str() ? FF_DONTCARE:FF_SWISS), wstr);
delete [] wstr;
assert(font!=NULL);
HDC dc= wglGetCurrentDC();
dwErrorGL = GetLastError();
assertGl();
SelectObject(dc, font);
dwErrorGL = GetLastError();
assertGl();
BOOL err= 0;
err= wglUseFontBitmaps(dc, 0, charCount, base);
dwErrorGL = GetLastError();
/*
for(int glBugRetry = 0; glBugRetry <= 10; glBugRetry++) {
err= wglUseFontBitmaps(dc, 0, charCount, base);
dwErrorGL = GetLastError();
//assertGl();
GLenum error = glGetError();
if(error == 0) {
break;
}
}
*/
assertGl();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] wglUseFontBitmaps returned = %d, charCount = %d, base = %d\n",__FILE__,__FUNCTION__,__LINE__,err,charCount,base);
FIXED one;
one.value= 1;
one.fract= 0;
FIXED zero;
zero.value= 0;
zero.fract= 0;
MAT2 mat2;
mat2.eM11= one;
mat2.eM12= zero;
mat2.eM21= zero;
mat2.eM22= one;
//MAT2 mat2 = {{0,1},{0,0},{0,0},{0,1}};
//metrics
GLYPHMETRICS glyphMetrics;
int errorCode= GetGlyphOutline(dc, 'a', GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] GetGlyphOutline returned = %d\n",__FILE__,__FUNCTION__,__LINE__,errorCode);
if(errorCode!=GDI_ERROR){
metrics.setHeight(static_cast<float>(glyphMetrics.gmBlackBoxY));
}
for(int i=0; i<charCount; ++i){
int errorCode= GetGlyphOutline(dc, i, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(errorCode!=GDI_ERROR){
metrics.setWidth(i, static_cast<float>(glyphMetrics.gmCellIncX));
}
else {
metrics.setWidth(i, static_cast<float>(6));
}
}
DeleteObject(font);
//if(hDC != 0) {
// DeleteDC(hDC);
//}
assert(err);
//#endif
}
void createGlFontOutlines(uint32 &base, const string &type, int width,
float depth, int charCount, FontMetrics &metrics) {
NOIMPL;
}
void createGlFontOutlines(uint32 &base, const string &type, int width,
float depth, int charCount, FontMetrics &metrics) {
NOIMPL;
}
}}//end namespace