- 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

@@ -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