From c808a5661ae799c2e326f2b3320f527159595934 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Mon, 6 Jun 2011 21:38:25 +0000 Subject: [PATCH] - added freetype2 / FTGL support --- mk/cmake/Modules/FindFTGL.cmake | 32 + mk/cmake/Modules/FindFontConfig.cmake | 39 ++ source/glest_game/facilities/components.h | 14 +- source/glest_game/global/core_data.cpp | 12 +- source/glest_game/graphics/renderer.cpp | 28 +- source/glest_game/graphics/renderer.h | 22 +- source/glest_game/main/intro.cpp | 6 +- source/glest_game/main/intro.h | 6 +- source/glest_game/main/main.cpp | 13 + .../menu/menu_state_connected_game.cpp | 2 +- .../menu/menu_state_custom_game.cpp | 2 +- source/shared_lib/CMakeLists.txt | 52 ++ source/shared_lib/include/graphics/font.h | 45 +- .../include/graphics/font_manager.h | 4 +- .../shared_lib/include/graphics/font_text.h | 43 ++ .../shared_lib/include/graphics/gl/font_gl.h | 13 +- .../include/graphics/gl/font_textFTGL.h | 59 ++ .../include/graphics/gl/text_renderer_gl.h | 26 +- .../include/graphics/text_renderer.h | 10 +- .../shared_lib/include/platform/sdl/types.h | 2 + source/shared_lib/sources/graphics/font.cpp | 143 ++++- .../sources/graphics/font_manager.cpp | 19 +- .../shared_lib/sources/graphics/font_text.cpp | 26 + .../sources/graphics/gl/font_gl.cpp | 78 +-- .../sources/graphics/gl/font_textFTGL.cpp | 261 +++++++++ .../sources/graphics/gl/text_renderer_gl.cpp | 549 +++++++++++++++--- .../sources/platform/unix/gl_wrap.cpp | 3 + .../sources/platform/win32/gl_wrap_billy.cpp | 279 ++++----- 28 files changed, 1412 insertions(+), 376 deletions(-) create mode 100644 mk/cmake/Modules/FindFTGL.cmake create mode 100644 mk/cmake/Modules/FindFontConfig.cmake create mode 100644 source/shared_lib/include/graphics/font_text.h create mode 100644 source/shared_lib/include/graphics/gl/font_textFTGL.h create mode 100644 source/shared_lib/sources/graphics/font_text.cpp create mode 100644 source/shared_lib/sources/graphics/gl/font_textFTGL.cpp diff --git a/mk/cmake/Modules/FindFTGL.cmake b/mk/cmake/Modules/FindFTGL.cmake new file mode 100644 index 000000000..e3ac9f127 --- /dev/null +++ b/mk/cmake/Modules/FindFTGL.cmake @@ -0,0 +1,32 @@ +# +# +# Try to find the FTGL libraries +# Once done this will define +# +# FTGL_FOUND - system has ftgl +# FTGL_INCLUDE_DIR - path to FTGL/FTGL.h +# FTGL_LIBRARY - the library that must be included +# +# + +IF (FTGL_LIBRARY AND FTGL_INCLUDE_DIR) + SET(FTGL_FOUND "YES") +ELSE (FTGL_LIBRARY AND FTGL_INCLUDE_DIR) + FIND_PATH(FTGL_INCLUDE_DIR FTGL/ftgl.h PATHS /usr/local/include /usr/include) + FIND_LIBRARY(FTGL_LIBRARY ftgl PATHS /usr/local/lib /usr/lib) + + IF (FTGL_INCLUDE_DIR AND FTGL_LIBRARY) + SET(FTGL_FOUND "YES") + ELSE (FTGL_INCLUDE_DIR AND FTGL_LIBRARY) + SET(FTGL_FOUND "NO") + ENDIF (FTGL_INCLUDE_DIR AND FTGL_LIBRARY) +ENDIF (FTGL_LIBRARY AND FTGL_INCLUDE_DIR) + +IF (FTGL_FOUND) + MESSAGE(STATUS "Found FTGL libraries at ${FTGL_LIBRARY} and includes at ${FTGL_INCLUDE_DIR}") +ELSE (FTGL_FOUND) + IF (FTGL_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find FTGL libraries") + ENDIF (FTGL_FIND_REQUIRED) +ENDIF (FTGL_FOUND) + diff --git a/mk/cmake/Modules/FindFontConfig.cmake b/mk/cmake/Modules/FindFontConfig.cmake new file mode 100644 index 000000000..e58ca0208 --- /dev/null +++ b/mk/cmake/Modules/FindFontConfig.cmake @@ -0,0 +1,39 @@ +# - Find FONTCONFIG +# Find the native FONTCONFIG headers and libraries. +# +# FONTCONFIG_INCLUDE_DIR - where to find fontconfig.h, etc. +# FONTCONFIG_LIBRARIES - List of libraries when using FONTCONFIG. +# FONTCONFIG_FOUND - True if FONTCONFIG found. + + +# Look for the header file. +FIND_PATH( FONTCONFIG_INCLUDE_DIR NAMES fontconfig/fontconfig.h + DOC "Path in which the file fontconfig/fontconfig.h is located." ) +MARK_AS_ADVANCED(FONTCONFIG_INCLUDE_DIR) + +# Look for the library. +FIND_LIBRARY( FONTCONFIG_LIBRARY NAMES fontconfig + DOC "Path to fontconfig library." ) +MARK_AS_ADVANCED(FONTCONFIG_LIBRARY) + +# Copy the results to the output variables. +IF(FONTCONFIG_INCLUDE_DIR AND FONTCONFIG_LIBRARY) + SET(FONTCONFIG_FOUND 1) + SET(FONTCONFIG_LIBRARIES ${FONTCONFIG_LIBRARY}) + SET(FONTCONFIG_INCLUDE_DIR ${FONTCONFIG_INCLUDE_DIR}) +ELSE(FONTCONFIG_INCLUDE_DIR AND FONTCONFIG_LIBRARY) + SET(FONTCONFIG_FOUND 0) + SET(FONTCONFIG_LIBRARIES) + SET(FONTCONFIG_INCLUDE_DIR) +ENDIF(FONTCONFIG_INCLUDE_DIR AND FONTCONFIG_LIBRARY) + +# Report the results. +IF(NOT FONTCONFIG_FOUND) + SET(FONTCONFIG_DIR_MESSAGE + "FONTCONFIG was not found. Make sure FONTCONFIG_LIBRARY and FONTCONFIG_INCLUDE_DIR are set.") + IF(FontConfig_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "${FONTCONFIG_DIR_MESSAGE}") + ELSEIF(NOT FontConfig_FIND_QUIETLY) + MESSAGE(STATUS "${FONTCONFIG_DIR_MESSAGE}") + ENDIF(FontConfig_FIND_REQUIRED) +ENDIF(NOT FONTCONFIG_FOUND) diff --git a/source/glest_game/facilities/components.h b/source/glest_game/facilities/components.h index 18ed324d2..9c3e6ac2f 100644 --- a/source/glest_game/facilities/components.h +++ b/source/glest_game/facilities/components.h @@ -48,7 +48,7 @@ public: protected: int x, y, w, h; string text; - const Font2D *font; + Font2D *font; bool enabled; bool editable; bool visible; @@ -83,7 +83,7 @@ public: virtual int getW() const {return w;} virtual int getH() const {return h;} virtual const string &getText() const {return text;} - virtual const Font2D *getFont() const {return font;} + virtual Font2D *getFont() {return font;} virtual bool getEnabled() const {return enabled;} virtual bool getEditable() const {return editable;} virtual bool getVisible() const {return visible;} @@ -93,7 +93,7 @@ public: virtual void setW(int w) {this->w= w;} virtual void setH(int h) {this->h= h;} virtual void setText(const string &text) {this->text= text;} - virtual void setFont(const Font2D *font) {this->font= font;} + virtual void setFont(Font2D *font) {this->font= font;} virtual void setEnabled(bool enabled) {this->enabled= enabled;} virtual void setEditable(bool editable) {this->editable= editable;} virtual void setVisible(bool value) {this->visible = value;} @@ -188,8 +188,8 @@ public: string getItem(int index) const {return items[index];} int getSelectedItemIndex() const {return selectedItemIndex;} string getSelectedItem() const {return items[selectedItemIndex];} - const GraphicButton *getButton1() const {return &graphButton1;} - const GraphicButton *getButton2() const {return &graphButton2;} + GraphicButton *getButton1() {return &graphButton1;} + GraphicButton *getButton2() {return &graphButton2;} bool getLighted() const {return lighted;} void setLighted(bool lighted) {this->lighted= lighted;} Vec3f getTextColor() const {return textColor;} @@ -227,8 +227,8 @@ public: void init(const string &button1Str); int getButtonCount() const {return buttonCount;} - const GraphicButton *getButton1() const {return &button1;} - const GraphicButton *getButton2() const {return &button2;} + GraphicButton *getButton1() {return &button1;} + GraphicButton *getButton2() {return &button2;} string getHeader() const {return header;} virtual void setX(int x); diff --git a/source/glest_game/global/core_data.cpp b/source/glest_game/global/core_data.cpp index 6f2d079d6..ad06b3565 100644 --- a/source/glest_game/global/core_data.cpp +++ b/source/glest_game/global/core_data.cpp @@ -146,7 +146,7 @@ void CoreData::load() { string displayFontName=displayFontNamePrefix+intToStr(displayFontSize)+displayFontNamePostfix; displayFont= renderer.newFont(rsGlobal); - displayFont->setType(displayFontName); + displayFont->setType(displayFontName,config.getString("FontDisplay","")); displayFont->setSize(displayFontSize); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] displayFontName = [%s] displayFontSize = %d\n",__FILE__,__FUNCTION__,__LINE__,displayFontName.c_str(),displayFontSize); @@ -168,7 +168,7 @@ void CoreData::load() { string displayFontNameSmall=displayFontNameSmallPrefix+intToStr(displayFontNameSmallSize)+displayFontNameSmallPostfix; displayFontSmall= renderer.newFont(rsGlobal); - displayFontSmall->setType(displayFontNameSmall); + displayFontSmall->setType(displayFontNameSmall,config.getString("FontDisplay","")); displayFontSmall->setSize(displayFontNameSmallSize); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] displayFontSmallName = [%s] displayFontSmallNameSize = %d\n",__FILE__,__FUNCTION__,__LINE__,displayFontNameSmall.c_str(),displayFontNameSmallSize); @@ -189,7 +189,7 @@ void CoreData::load() { string menuFontNameNormal= menuFontNameNormalPrefix+intToStr(menuFontNameNormalSize)+menuFontNameNormalPostfix; menuFontNormal= renderer.newFont(rsGlobal); - menuFontNormal->setType(menuFontNameNormal); + menuFontNormal->setType(menuFontNameNormal,config.getString("FontMenuNormal","")); menuFontNormal->setSize(menuFontNameNormalSize); menuFontNormal->setWidth(Font::wBold); @@ -212,7 +212,7 @@ void CoreData::load() { string menuFontNameBig= menuFontNameBigPrefix+intToStr(menuFontNameBigSize)+menuFontNameBigPostfix; menuFontBig= renderer.newFont(rsGlobal); - menuFontBig->setType(menuFontNameBig); + menuFontBig->setType(menuFontNameBig,config.getString("FontMenuBig","")); menuFontBig->setSize(menuFontNameBigSize); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] menuFontNameBig = [%s] menuFontNameBigSize = %d\n",__FILE__,__FUNCTION__,__LINE__,menuFontNameBig.c_str(),menuFontNameBigSize); @@ -234,7 +234,7 @@ void CoreData::load() { string menuFontNameVeryBig= menuFontNameVeryBigPrefix+intToStr(menuFontNameVeryBigSize)+menuFontNameVeryBigPostfix; menuFontVeryBig= renderer.newFont(rsGlobal); - menuFontVeryBig->setType(menuFontNameVeryBig); + menuFontVeryBig->setType(menuFontNameVeryBig,config.getString("FontMenuBig","")); menuFontVeryBig->setSize(menuFontNameVeryBigSize); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] menuFontNameVeryBig = [%s] menuFontNameVeryBigSize = %d\n",__FILE__,__FUNCTION__,__LINE__,menuFontNameVeryBig.c_str(),menuFontNameVeryBigSize); @@ -257,7 +257,7 @@ void CoreData::load() { string consoleFontName= consoleFontNamePrefix+intToStr(consoleFontNameSize)+consoleFontNamePostfix; consoleFont= renderer.newFont(rsGlobal); - consoleFont->setType(consoleFontName); + consoleFont->setType(consoleFontName,config.getString("FontConsole","")); consoleFont->setSize(consoleFontNameSize); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] consoleFontName = [%s] consoleFontNameSize = %d\n",__FILE__,__FUNCTION__,__LINE__,consoleFontName.c_str(),consoleFontNameSize); diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index d91ee0702..c2cbb9d77 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -946,10 +946,10 @@ void Renderer::renderTextureQuad(int x, int y, int w, int h, const Texture2D *te } void Renderer::renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, - const Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) { + Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) { Vec4f fontColor; const Metrics &metrics= Metrics::getInstance(); - const FontMetrics *fontMetrics= font->getMetrics(); + FontMetrics *fontMetrics= font->getMetrics(); if(game != NULL) { fontColor = game->getGui()->getDisplay()->getColor(); @@ -1208,12 +1208,12 @@ void Renderer::renderSelectionQuad() { } } -Vec2i computeCenteredPos(const string &text, const Font2D *font, int x, int y) { +Vec2i computeCenteredPos(const string &text, Font2D *font, int x, int y) { if(font == NULL) { throw runtime_error("font == NULL"); } const Metrics &metrics= Metrics::getInstance(); - const FontMetrics *fontMetrics= font->getMetrics(); + FontMetrics *fontMetrics= font->getMetrics(); if(fontMetrics == NULL) { throw runtime_error("fontMetrics == NULL"); @@ -1229,7 +1229,7 @@ Vec2i computeCenteredPos(const string &text, const Font2D *font, int x, int y) { return textPos; } -void Renderer::renderText(const string &text, const Font2D *font, float alpha, int x, int y, bool centered){ +void Renderer::renderText(const string &text, Font2D *font, float alpha, int x, int y, bool centered){ glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); glEnable(GL_BLEND); glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); @@ -1243,7 +1243,7 @@ void Renderer::renderText(const string &text, const Font2D *font, float alpha, i glPopAttrib(); } -void Renderer::renderText(const string &text, const Font2D *font, const Vec3f &color, int x, int y, bool centered){ +void Renderer::renderText(const string &text, Font2D *font, const Vec3f &color, int x, int y, bool centered){ glPushAttrib(GL_CURRENT_BIT); glColor3fv(color.ptr()); @@ -1256,7 +1256,7 @@ void Renderer::renderText(const string &text, const Font2D *font, const Vec3f &c glPopAttrib(); } -void Renderer::renderText(const string &text, const Font2D *font, const Vec4f &color, int x, int y, bool centered){ +void Renderer::renderText(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered){ glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); glEnable(GL_BLEND); glColor4fv(color.ptr()); @@ -1270,7 +1270,7 @@ void Renderer::renderText(const string &text, const Font2D *font, const Vec4f &c glPopAttrib(); } -void Renderer::renderTextShadow(const string &text, const Font2D *font,const Vec4f &color, int x, int y, bool centered){ +void Renderer::renderTextShadow(const string &text, Font2D *font,const Vec4f &color, int x, int y, bool centered){ if(font == NULL) { throw runtime_error("font == NULL"); } @@ -1293,13 +1293,13 @@ void Renderer::renderTextShadow(const string &text, const Font2D *font,const Vec // ============= COMPONENTS ============================= -void Renderer::renderLabel(const GraphicLabel *label) { +void Renderer::renderLabel(GraphicLabel *label) { Vec3f labelColor=label->getTextColor(); Vec4f colorWithAlpha = Vec4f(labelColor.x,labelColor.y,labelColor.z,GraphicComponent::getFade()); renderLabel(label,&colorWithAlpha); } -void Renderer::renderLabel(const GraphicLabel *label,const Vec3f *color) { +void Renderer::renderLabel(GraphicLabel *label,const Vec3f *color) { if(color != NULL) { Vec4f colorWithAlpha = Vec4f(*color); colorWithAlpha.w = GraphicComponent::getFade(); @@ -1311,7 +1311,7 @@ void Renderer::renderLabel(const GraphicLabel *label,const Vec3f *color) { } } -void Renderer::renderLabel(const GraphicLabel *label,const Vec4f *color) { +void Renderer::renderLabel(GraphicLabel *label,const Vec4f *color) { if(label->getVisible() == false) { return; } @@ -1351,7 +1351,7 @@ void Renderer::renderLabel(const GraphicLabel *label,const Vec4f *color) { glPopAttrib(); } -void Renderer::renderButton(const GraphicButton *button, const Vec4f *fontColorOverride, bool *lightedOverride) { +void Renderer::renderButton(GraphicButton *button, const Vec4f *fontColorOverride, bool *lightedOverride) { if(button->getVisible() == false) { return; } @@ -1740,7 +1740,7 @@ void Renderer::renderScrollBar(const GraphicScrollBar *sb) { glPopAttrib(); } -void Renderer::renderListBox(const GraphicListBox *listBox) { +void Renderer::renderListBox(GraphicListBox *listBox) { if(listBox->getVisible() == false) { return; } @@ -1806,7 +1806,7 @@ void Renderer::renderListBox(const GraphicListBox *listBox) { glPopAttrib(); } -void Renderer::renderMessageBox(const GraphicMessageBox *messageBox) { +void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { if(messageBox->getVisible() == false) { return; } diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 1d3f1bffd..101cc6937 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -343,25 +343,25 @@ public: void renderBackground(const Texture2D *texture); void renderTextureQuad(int x, int y, int w, int h, const Texture2D *texture, float alpha=1.f,const Vec3f *color=NULL); void renderConsole(const Console *console, const bool showAll=false, const bool showMenuConsole=false, int overrideMaxConsoleLines=-1); - void renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, const Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); + void renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); void renderChatManager(const ChatManager *chatManager); void renderResourceStatus(); void renderSelectionQuad(); - void renderText(const string &text, const Font2D *font, float alpha, int x, int y, bool centered= false); - void renderText(const string &text, const Font2D *font, const Vec3f &color, int x, int y, bool centered= false); - void renderText(const string &text, const Font2D *font, const Vec4f &color, int x, int y, bool centered=false); - void renderTextShadow(const string &text, const Font2D *font,const Vec4f &color, int x, int y, bool centered= false); + void renderText(const string &text, Font2D *font, float alpha, int x, int y, bool centered= false); + void renderText(const string &text, Font2D *font, const Vec3f &color, int x, int y, bool centered= false); + void renderText(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered=false); + void renderTextShadow(const string &text, Font2D *font,const Vec4f &color, int x, int y, bool centered= false); //components - void renderLabel(const GraphicLabel *label); - void renderLabel(const GraphicLabel *label,const Vec3f *color); - void renderLabel(const GraphicLabel *label,const Vec4f *color); - void renderButton(const GraphicButton *button,const Vec4f *fontColorOverride=NULL,bool *lightedOverride=NULL); + void renderLabel(GraphicLabel *label); + void renderLabel(GraphicLabel *label,const Vec3f *color); + void renderLabel(GraphicLabel *label,const Vec4f *color); + void renderButton(GraphicButton *button,const Vec4f *fontColorOverride=NULL,bool *lightedOverride=NULL); void renderCheckBox(const GraphicCheckBox *box); void renderLine(const GraphicLine *line); void renderScrollBar(const GraphicScrollBar *sb); - void renderListBox(const GraphicListBox *listBox); - void renderMessageBox(const GraphicMessageBox *listBox); + void renderListBox(GraphicListBox *listBox); + void renderMessageBox(GraphicMessageBox *listBox); //complex rendering void renderSurface(const int renderFps); diff --git a/source/glest_game/main/intro.cpp b/source/glest_game/main/intro.cpp index c5bc11754..fa6df9caa 100644 --- a/source/glest_game/main/intro.cpp +++ b/source/glest_game/main/intro.cpp @@ -32,7 +32,7 @@ namespace Glest{ namespace Game{ // class Text // ===================================================== -Text::Text(const string &text, const Vec2i &pos, int time, const Font2D *font){ +Text::Text(const string &text, const Vec2i &pos, int time, Font2D *font) { this->text= text; this->pos= pos; this->time= time; @@ -40,7 +40,7 @@ Text::Text(const string &text, const Vec2i &pos, int time, const Font2D *font){ this->font= font; } -Text::Text(const Texture2D *texture, const Vec2i &pos, const Vec2i &size, int time){ +Text::Text(const Texture2D *texture, const Vec2i &pos, const Vec2i &size, int time) { this->pos= pos; this->size= size; this->time= time; @@ -103,7 +103,7 @@ void Intro::update(){ mouse2d= (mouse2d+1) % Renderer::maxMouse2dAnim; } -void Intro::render(){ +void Intro::render() { Renderer &renderer= Renderer::getInstance(); int difTime; diff --git a/source/glest_game/main/intro.h b/source/glest_game/main/intro.h index 5eb00a0af..5c5b299dd 100644 --- a/source/glest_game/main/intro.h +++ b/source/glest_game/main/intro.h @@ -40,15 +40,15 @@ private: Vec2i pos; Vec2i size; int time; - const Font2D *font; + Font2D *font; const Texture2D *texture; public: - Text(const string &text, const Vec2i &pos, int time, const Font2D *font); + Text(const string &text, const Vec2i &pos, int time, Font2D *font); Text(const Texture2D *texture, const Vec2i &pos, const Vec2i &size, int time); const string &getText() const {return text;} - const Font2D *getFont() const {return font;} + Font2D *getFont() {return font;} const Vec2i &getPos() const {return pos;} const Vec2i &getSize() const {return size;} int getTime() const {return time;} diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 3f2c1aef6..91032de81 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -2558,6 +2558,11 @@ int glestMain(int argc, char** argv) { Font::fontIsMultibyte = strToBool(lang.get("FONT_MULTIBYTE")); } + if( lang.hasString("MEGAGLEST_FONT")) { + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese + setenv("MEGAGLEST_FONT",lang.get("MEGAGLEST_FONT").c_str(),0); + } + #if defined(WIN32) // Win32 overrides for fonts (just in case they must be different) if( lang.hasString("FONT_CHARCOUNT_WINDOWS")) { @@ -2577,6 +2582,11 @@ int glestMain(int argc, char** argv) { if( lang.hasString("FONT_MULTIBYTE_WINDOWS")) { Font::fontIsMultibyte = strToBool(lang.get("FONT_MULTIBYTE_WINDOWS")); } + if( lang.hasString("MEGAGLEST_FONT_WINDOWS")) { + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese + setenv("MEGAGLEST_FONT",lang.get("MEGAGLEST_FONT_WINDOWS").c_str(),0); + } + // end win32 #endif SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::charSet = %d, Font::fontIsMultibyte = %d\n",__FILE__,__FUNCTION__,__LINE__,Font::charCount,Font::fontTypeName.c_str(),Shared::Platform::charSet,Font::fontIsMultibyte); @@ -3063,6 +3073,9 @@ int glestMain(int argc, char** argv) { int glestMainWrapper(int argc, char** argv) { + //setlocale(LC_ALL, "zh_TW.UTF-8"); + //setlocale(LC_ALL, ""); + #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) //#ifdef DEBUG //printf("MTRACE will be called...\n"); diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index b577c9c06..b52d450d5 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -898,7 +898,7 @@ void MenuStateConnectedGame::render() { int offsetPosition=0; for(int i=0; i < GameConstants::maxPlayers; ++i) { const Metrics &metrics= Metrics::getInstance(); - const FontMetrics *fontMetrics= CoreData::getInstance().getMenuFontNormal()->getMetrics(); + FontMetrics *fontMetrics= CoreData::getInstance().getMenuFontNormal()->getMetrics(); if(fontMetrics == NULL) { throw runtime_error("fontMetrics == NULL"); } diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 23e7e7403..fbb807a32 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -1323,7 +1323,7 @@ void MenuStateCustomGame::render() { int offsetPosition=0; for(int i=0; i < GameConstants::maxPlayers; ++i) { const Metrics &metrics= Metrics::getInstance(); - const FontMetrics *fontMetrics= CoreData::getInstance().getMenuFontNormal()->getMetrics(); + FontMetrics *fontMetrics= CoreData::getInstance().getMenuFontNormal()->getMetrics(); if(fontMetrics == NULL) { throw runtime_error("fontMetrics == NULL"); } diff --git a/source/shared_lib/CMakeLists.txt b/source/shared_lib/CMakeLists.txt index 755c57b72..79b1451a0 100644 --- a/source/shared_lib/CMakeLists.txt +++ b/source/shared_lib/CMakeLists.txt @@ -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 diff --git a/source/shared_lib/include/graphics/font.h b/source/shared_lib/include/graphics/font.h index e0f8aefe4..2faefa53a 100644 --- a/source/shared_lib/include/graphics/font.h +++ b/source/shared_lib/include/graphics/font.h @@ -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;} diff --git a/source/shared_lib/include/graphics/font_manager.h b/source/shared_lib/include/graphics/font_manager.h index 030ed5895..01f16a442 100644 --- a/source/shared_lib/include/graphics/font_manager.h +++ b/source/shared_lib/include/graphics/font_manager.h @@ -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 FontContainer; diff --git a/source/shared_lib/include/graphics/font_text.h b/source/shared_lib/include/graphics/font_text.h new file mode 100644 index 000000000..c55581d5e --- /dev/null +++ b/source/shared_lib/include/graphics/font_text.h @@ -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 + +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 diff --git a/source/shared_lib/include/graphics/gl/font_gl.h b/source/shared_lib/include/graphics/gl/font_gl.h index 72eaf8ac4..8554ff75b 100644 --- a/source/shared_lib/include/graphics/gl/font_gl.h +++ b/source/shared_lib/include/graphics/gl/font_gl.h @@ -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(); }; diff --git a/source/shared_lib/include/graphics/gl/font_textFTGL.h b/source/shared_lib/include/graphics/gl/font_textFTGL.h new file mode 100644 index 000000000..1fb541096 --- /dev/null +++ b/source/shared_lib/include/graphics/gl/font_textFTGL.h @@ -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 + +#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 diff --git a/source/shared_lib/include/graphics/gl/text_renderer_gl.h b/source/shared_lib/include/graphics/gl/text_renderer_gl.h index 7a83201bc..51484eac5 100644 --- a/source/shared_lib/include/graphics/gl/text_renderer_gl.h +++ b/source/shared_lib/include/graphics/gl/text_renderer_gl.h @@ -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(); }; diff --git a/source/shared_lib/include/graphics/text_renderer.h b/source/shared_lib/include/graphics/text_renderer.h index d135c24d4..d7a6ee25e 100644 --- a/source/shared_lib/include/graphics/text_renderer.h +++ b/source/shared_lib/include/graphics/text_renderer.h @@ -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; }; diff --git a/source/shared_lib/include/platform/sdl/types.h b/source/shared_lib/include/platform/sdl/types.h index 8e316d623..3a8df1eeb 100644 --- a/source/shared_lib/include/platform/sdl/types.h +++ b/source/shared_lib/include/platform/sdl/types.h @@ -34,6 +34,8 @@ typedef Uint32 uint32; typedef Sint64 int64; typedef Uint64 uint64; +typedef uint8 byte; + }}//end namespace #endif diff --git a/source/shared_lib/sources/graphics/font.cpp b/source/shared_lib/sources/graphics/font.cpp index 0fca99430..10da4ed64 100644 --- a/source/shared_lib/sources/graphics/font.cpp +++ b/source/shared_lib/sources/graphics/font.cpp @@ -12,24 +12,38 @@ #include "font.h" #include #include "conversion.h" + +#include "font_text.h" +#ifdef USE_FTGL +#include "font_textFTGL.h" +#include +#include +//#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; } diff --git a/source/shared_lib/sources/graphics/font_manager.cpp b/source/shared_lib/sources/graphics/font_manager.cpp index 79c28e15b..4ba85e9cb 100644 --- a/source/shared_lib/sources/graphics/font_manager.cpp +++ b/source/shared_lib/sources/graphics/font_manager.cpp @@ -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; iinit(); } } } -void FontManager::end(){ - for(size_t i=0; iend(); delete fonts[i]; @@ -58,5 +58,4 @@ void FontManager::end(){ fonts.clear(); } - }}//end namespace diff --git a/source/shared_lib/sources/graphics/font_text.cpp b/source/shared_lib/sources/graphics/font_text.cpp new file mode 100644 index 000000000..9e264962f --- /dev/null +++ b/source/shared_lib/sources/graphics/font_text.cpp @@ -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;} diff --git a/source/shared_lib/sources/graphics/gl/font_gl.cpp b/source/shared_lib/sources/graphics/gl/font_gl.cpp index 77cd08e1f..7bf223d97 100644 --- a/source/shared_lib/sources/graphics/gl/font_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/font_gl.cpp @@ -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 diff --git a/source/shared_lib/sources/graphics/gl/font_textFTGL.cpp b/source/shared_lib/sources/graphics/gl/font_textFTGL.cpp new file mode 100644 index 000000000..b92a0f97d --- /dev/null +++ b/source/shared_lib/sources/graphics/gl/font_textFTGL.cpp @@ -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 +#include +#include + +#ifdef HAVE_FONTCONFIG +#include +#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 diff --git a/source/shared_lib/sources/graphics/gl/text_renderer_gl.cpp b/source/shared_lib/sources/graphics/gl/text_renderer_gl.cpp index 2be668e01..6b1deb45f 100644 --- a/source/shared_lib/sources/graphics/gl/text_renderer_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/text_renderer_gl.cpp @@ -13,27 +13,53 @@ #include "opengl.h" #include "font_gl.h" -//#include + +#include "font_text.h" +//#ifdef USE_FTGL +//#include "font_textFTGL.h" +#include +#include +//#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(font); + this->font= static_cast(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(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(x), static_cast(y)); + } } - else{ - rasterPos= Vec2f(static_cast(x), static_cast(y)); + else { +//#else + utext= reinterpret_cast(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(x), static_cast(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 >(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(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 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(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(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 >(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 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(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(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(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(font); + this->font= static_cast(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(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(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 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(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 >(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(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 >(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 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(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(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; diff --git a/source/shared_lib/sources/platform/unix/gl_wrap.cpp b/source/shared_lib/sources/platform/unix/gl_wrap.cpp index ad8338c42..00bb1fd1f 100644 --- a/source/shared_lib/sources/platform/unix/gl_wrap.cpp +++ b/source/shared_lib/sources/platform/unix/gl_wrap.cpp @@ -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, diff --git a/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp b/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp index 1cc6b6f51..aac1aad62 100644 --- a/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp +++ b/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp @@ -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 *systemFontList = (std::vector *)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 *systemFontList = (std::vector *)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 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 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(glyphMetrics.gmBlackBoxY)); - } - for(int i=0; i(glyphMetrics.gmCellIncX)); - } - else { - metrics.setWidth(i, static_cast(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(glyphMetrics.gmBlackBoxY)); + } + for(int i=0; i(glyphMetrics.gmCellIncX)); + } + else { + metrics.setWidth(i, static_cast(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