From 7f64c170343f76c7e4fa1e57a49ef51ecacb133d Mon Sep 17 00:00:00 2001 From: Edouard Dupin Date: Sun, 6 Nov 2011 20:24:44 +0100 Subject: [PATCH] Freetype test is now OK Must update the old bitmap text that does not work anymore Display is generate with bitmap temporary font TODO : Regenerate the font Bitmap when new char apare... --- Makefile | 10 +- Sources/Main.cpp | 6 +- Sources/etk/etkTypes.h | 2 +- Sources/ewol.cpp | 1 + Sources/ewolDebug.h | 28 +- Sources/ewolFont.h | 67 ++- Sources/{ewolFont.cpp => ewolFontBitmap.cpp} | 17 +- Sources/ewolFontFreeType.cpp | 590 +++++++++++++++++++ Sources/ewolOObject.cpp | 5 +- Sources/ewolWindows.cpp | 180 +----- 10 files changed, 664 insertions(+), 242 deletions(-) rename Sources/{ewolFont.cpp => ewolFontBitmap.cpp} (96%) create mode 100644 Sources/ewolFontFreeType.cpp diff --git a/Makefile b/Makefile index 34c17cee..c0c75a53 100644 --- a/Makefile +++ b/Makefile @@ -178,9 +178,13 @@ CXXFILES += etk/etkDebug.cpp \ CXXFILES += ewol.cpp \ ewolDebug.cpp \ ewolOObject.cpp \ - ewolTexture.cpp \ - ewolFont.cpp \ - ewolWidget.cpp \ + ewolTexture.cpp +ifeq ("$(FREETYPE_CFLAGS)", "") + CXXFILES += ewolFontBitmap.cpp +else + CXXFILES += ewolFontFreeType.cpp +endif +CXXFILES += ewolWidget.cpp \ ewolWindows.cpp diff --git a/Sources/Main.cpp b/Sources/Main.cpp index 9c0debed..407495b4 100644 --- a/Sources/Main.cpp +++ b/Sources/Main.cpp @@ -54,11 +54,13 @@ int main(int argc, char *argv[]) { ewol::Init(argc, argv); - - + /* if (true == ewol::AddFont("dataTest/TextMonospace.ebt", true, true, true) ) { //fontID = GetFontIdWithFileName("dataTest/TextMonospace.ebt"); } + */ + ewol::SetFontFolder("Font"); + ewol::SetDefaultFont("freefont/FreeMono", 16); Plop * myWindowsExample = new Plop(); diff --git a/Sources/etk/etkTypes.h b/Sources/etk/etkTypes.h index d7b1eaf1..1750d70b 100644 --- a/Sources/etk/etkTypes.h +++ b/Sources/etk/etkTypes.h @@ -53,7 +53,7 @@ typedef unsigned long long int uint64_t; # endif #endif - +typedef int32_t uniChar_t; diff --git a/Sources/ewol.cpp b/Sources/ewol.cpp index ccf2b289..b33e0c19 100644 --- a/Sources/ewol.cpp +++ b/Sources/ewol.cpp @@ -50,6 +50,7 @@ void ewol::Init(int argc, char *argv[]) EWOL_INFO("v" EWOL_VERSION_TAG_NAME); EWOL_INFO("Build Date: " VERSION_BUILD_TIME); guiAbstraction::Init(argc, argv); + ewol::InitFont(); } void ewol::Run(void) diff --git a/Sources/ewolDebug.h b/Sources/ewolDebug.h index ffd053d7..451fc75f 100644 --- a/Sources/ewolDebug.h +++ b/Sources/ewolDebug.h @@ -30,36 +30,38 @@ extern const char * ewolLibName; -#define EWOL_CRITICAL(data) ETK_CRITICAL(ewolLibName, data) +#define EWOL_CRITICAL(data) ETK_CRITICAL(ewolLibName, data) // General #if EWOL_DEBUG_LEVEL > 0 -# define EWOL_WARNING(data) ETK_WARNING(ewolLibName, data) -# define EWOL_ERROR(data) ETK_ERROR(ewolLibName, data) +# define EWOL_WARNING(data) ETK_WARNING(ewolLibName, data) +# define EWOL_ERROR(data) ETK_ERROR(ewolLibName, data) #else -# define EWOL_WARNING(data) do {}while(0) -# define EWOL_ERROR(data) do {}while(0) +# define EWOL_WARNING(data) do {}while(0) +# define EWOL_ERROR(data) do {}while(0) #endif #if EWOL_DEBUG_LEVEL > 1 -# define EWOL_INFO(data) ETK_INFO(ewolLibName, data) +# define EWOL_INFO(data) ETK_INFO(ewolLibName, data) #else -# define EWOL_INFO(data) do {}while(0) +# define EWOL_INFO(data) do {}while(0) #endif #if EWOL_DEBUG_LEVEL > 2 -# define EWOL_DEBUG(data) ETK_DEBUG(ewolLibName, data) +# define EWOL_DEBUG(data) ETK_DEBUG(ewolLibName, data) #else -# define EWOL_DEBUG(data) do {}while(0) +# define EWOL_DEBUG(data) do {}while(0) #endif -#define EWOL_ASSERT(cond, data) ETK_ASSERT(ewolLibName, cond, data) +#define EWOL_TODO(data) EWOL_WARNING("TODO : " << data) + +#define EWOL_ASSERT(cond, data) ETK_ASSERT(ewolLibName, cond, data) #if EWOL_DEBUG_LEVEL > 1 -# define EWOL_CHECK_INOUT(cond) ETK_CHECK_INOUT_ASSERT(ewolLibName, cond) +# define EWOL_CHECK_INOUT(cond) ETK_CHECK_INOUT_ASSERT(ewolLibName, cond) #elif EWOL_DEBUG_LEVEL > 0 -# define EWOL_CHECK_INOUT(cond) ETK_CHECK_INOUT_WARNING(ewolLibName, cond) +# define EWOL_CHECK_INOUT(cond) ETK_CHECK_INOUT_WARNING(ewolLibName, cond) #else -# define EWOL_CHECK_INOUT(cond) do { } while (0) +# define EWOL_CHECK_INOUT(cond) do { } while (0) #endif #endif diff --git a/Sources/ewolFont.h b/Sources/ewolFont.h index 6c399d50..4d194f49 100644 --- a/Sources/ewolFont.h +++ b/Sources/ewolFont.h @@ -32,6 +32,7 @@ namespace ewol { + // deprecated... typedef enum { FONT_MODE_NORMAL=0, FONT_MODE_BOLD, @@ -40,43 +41,41 @@ namespace ewol FONT_MODE_NUMBER, }fontMode_te; - void UnInitFont(void); - // load a font in momory, can be done many time for a specific fontname, if you specify true the font will be loaded in memory, otherwise, font is loaded only when needed the first time - bool AddFont(etk::File fontFileName, bool bold=false, bool italic=false, bool boldItalic=false); - // get the name of the font - etk::String GetFontName(int32_t Id); - int32_t GetFontIdWithFileName(etk::File fontFileName); - int32_t GetFontIdWithName(etk::String fontName); + + //typedef char* Utf8Char_t; + + // set default folder name of the font : + void SetFontFolder(etk::String folderName); + void SetDefaultFont(etk::String fontName, int32_t size); + // unload all font loaded + void InitFont(void); + void UnInitFont(void); + // load the fonts... + int32_t LoadFont(etk::String fontName, int32_t size); // return ID of font + int32_t GetDefaultFontId(void); + void UnloadFont(int32_t id); // get the size of a long string in UTF8 (note that \n and \r represent unknown char...) - int32_t GetStringWidth(int32_t fontID, ewol::fontMode_te displayMode, int32_t size, const char * utf8String); - // get the size of a specific char in UTF8 - int32_t GetCharWidth( int32_t fontID, ewol::fontMode_te displayMode, int32_t size, const char * utf8String);// only one element in the UTF8 string ... - // draw the text without background - void DrawText( int32_t fontID, - ewol::fontMode_te displayMode, - int32_t size, - coord3D_ts & drawPosition, - color_ts textColorFg, - const char * utf8String); - // draw the text with a spécify background - void DrawTextWithBg(int32_t fontID, - ewol::fontMode_te displayMode, - int32_t size, - coord3D_ts & drawPosition, - color_ts textColorFg, - color_ts textColorBg, - const char * utf8String); + int32_t GetWidth(int32_t fontID, const uniChar_t * unicodeString); + int32_t GetWidth(int32_t fontID, const char * utf8String); + int32_t GetWidth(int32_t fontID, const uniChar_t unicodeChar); + int32_t GetWidth(int32_t fontID, const char utf8Char); + int32_t GetHeight(int32_t fontID); - // draw the text without background - void DrawText( int32_t fontID, - ewol::fontMode_te displayMode, - int32_t size, - coord2D_ts & drawPosition, - const char * utf8String, - uint32_t & fontTextureId, - etk::VectorType & coord, - etk::VectorType & coordTex); + + void DrawText(int32_t fontID, + coord2D_ts & drawPosition, + const char * utf8String, + uint32_t & fontTextureId, + etk::VectorType & coord, + etk::VectorType & coordTex); + + void DrawText(int32_t fontID, + coord2D_ts & drawPosition, + const uniChar_t * unicodeString, + uint32_t & fontTextureId, + etk::VectorType & coord, + etk::VectorType & coordTex); int32_t LoadFont(etk::File fontFileName); void DrawText(double x, double y, const char * myString); diff --git a/Sources/ewolFont.cpp b/Sources/ewolFontBitmap.cpp similarity index 96% rename from Sources/ewolFont.cpp rename to Sources/ewolFontBitmap.cpp index 43b4b135..02d2ba99 100644 --- a/Sources/ewolFont.cpp +++ b/Sources/ewolFontBitmap.cpp @@ -1,6 +1,6 @@ /** ******************************************************************************* - * @file ewolFont.cpp + * @file ewolFontBitmap.cpp * @brief ewol Font system (sources) * @author Edouard DUPIN * @date 29/10/2011 @@ -40,7 +40,7 @@ #undef __class__ -#define __class__ "ewol::Font" +#define __class__ "ewol::FontBitmap" extern "C" @@ -374,17 +374,8 @@ void ewol::DrawText(int32_t fontID, drawPosition.x = posDrawX; glDisable(GL_TEXTURE_2D); } -// draw the text with a specify background -void ewol::DrawTextWithBg( int32_t fontID, - ewol::fontMode_te displayMode, - int32_t size, - coord3D_ts & drawPosition, - color_ts textColorFg, - color_ts textColorBg, - const char * utf8String) -{ - -} + + void ewol::DrawText(int32_t fontID, ewol::fontMode_te displayMode, diff --git a/Sources/ewolFontFreeType.cpp b/Sources/ewolFontFreeType.cpp new file mode 100644 index 00000000..14a3092d --- /dev/null +++ b/Sources/ewolFontFreeType.cpp @@ -0,0 +1,590 @@ +/** + ******************************************************************************* + * @file ewolFontFreeType.cpp + * @brief ewol Font system wrapper on freetype(sources) + * @author Edouard DUPIN + * @date 05/11/2011 + * @par Project + * ewol + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + + +#include +#include +#include + + +#include +#include +#include +#include +#if defined(EWOL_X11_MODE__XF86V) +# include +#elif defined(EWOL_X11_MODE__XRENDER) +# include +#endif + + +#include +#include FT_FREETYPE_H + +#undef __class__ +#define __class__ "ewol::FontFreeType" + + + +extern "C" +{ + typedef struct { + uniChar_t unicodeCharVal; + int32_t width; + texCoord_ts posStart; + texCoord_ts posStop; + float ratio; + }freeTypeFontElement_ts; +}; + +// free Font hnadle of librairies ... entry for acces ... +static FT_Library library; + +static int32_t nextP2(int32_t value) +{ + int32_t val=1; + for (int32_t iii=1; iii<31; iii++) { + if (value <= val) { + return val; + } + val *=2; + } + EWOL_CRITICAL("impossible CASE...."); + return val; +} + +static int32_t simpleSQRT(int32_t value) +{ + int32_t val=1; + for (int32_t iii=1; iii<1000; iii++) { + val =iii*iii; + if (value <= val) { + return iii; + } + } + EWOL_CRITICAL("impossible CASE...."); + return val; +} + +void ewol::InitFont(void) +{ + int32_t error = FT_Init_FreeType( &library ); + if(0 != error) { + EWOL_CRITICAL(" when loading FreeType Librairy ..."); + } +} + +// keep only one instance of every font in freetype +class FTFontInternal +{ + private: + void Display(void) + { + EWOL_INFO(" nuber of glyph = " << m_fftFace->num_glyphs); + if ((FT_FACE_FLAG_SCALABLE & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_SCALABLE (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_SCALABLE (disable)"); + } + if ((FT_FACE_FLAG_FIXED_SIZES & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_FIXED_SIZES (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_FIXED_SIZES (disable)"); + } + if ((FT_FACE_FLAG_FIXED_WIDTH & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_FIXED_WIDTH (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_FIXED_WIDTH (disable)"); + } + if ((FT_FACE_FLAG_SFNT & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_SFNT (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_SFNT (disable)"); + } + if ((FT_FACE_FLAG_HORIZONTAL & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_HORIZONTAL (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_HORIZONTAL (disable)"); + } + if ((FT_FACE_FLAG_VERTICAL & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_VERTICAL (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_VERTICAL (disable)"); + } + if ((FT_FACE_FLAG_KERNING & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_KERNING (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_KERNING (disable)"); + } + /* Deprecated flag + if ((FT_FACE_FLAG_FAST_GLYPHS & face->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_FAST_GLYPHS (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_FAST_GLYPHS (disable)"); + } + */ + if ((FT_FACE_FLAG_MULTIPLE_MASTERS & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_MULTIPLE_MASTERS (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_MULTIPLE_MASTERS (disable)"); + } + if ((FT_FACE_FLAG_GLYPH_NAMES & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_GLYPH_NAMES (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_GLYPH_NAMES (disable)"); + } + if ((FT_FACE_FLAG_EXTERNAL_STREAM & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_EXTERNAL_STREAM (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_EXTERNAL_STREAM (disable)"); + } + if ((FT_FACE_FLAG_HINTER & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_HINTER (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_HINTER (disable)"); + } + if ((FT_FACE_FLAG_CID_KEYED & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_CID_KEYED (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_CID_KEYED (disable)"); + } + if ((FT_FACE_FLAG_TRICKY & m_fftFace->face_flags) != 0) { + EWOL_INFO(" flags = FT_FACE_FLAG_TRICKY (enable)"); + } else { + EWOL_DEBUG(" flags = FT_FACE_FLAG_TRICKY (disable)"); + } + EWOL_INFO(" unit per EM = " << m_fftFace->units_per_EM); + EWOL_INFO(" num of fixed sizes = " << m_fftFace->num_fixed_sizes); + EWOL_INFO(" Availlable sizes = " << m_fftFace->available_sizes); + + EWOL_INFO(" Current size = " << m_fftFace->size); + } + public: + FTFontInternal(etk::File fontFileName, etk::String fontName) + { + m_fontName = fontName; + m_fileName = fontFileName; + int32_t error = FT_New_Face( library, m_fileName.GetCompleateName().c_str(), 0, &m_fftFace ); + if( FT_Err_Unknown_File_Format == error) { + EWOL_ERROR("... the font file could be opened and read, but it appears ... that its font format is unsupported"); + } else if (0 != error) { + EWOL_ERROR("... another error code means that the font file could not ... be opened or read, or simply that it is broken..."); + } else { + // all OK + EWOL_INFO("load font : \"" << m_fileName << "\" "); + Display(); + } + } + ~FTFontInternal(void) + { + + } + public: + etk::String GetFontName(void) {return m_fontName;}; + bool GenerateBitmapFont(int32_t size, int32_t textureId, etk::VectorType & listElement) + { + // 300dpi (hight quality) 96 dpi (normal quality) + int32_t fontQuality = 96; + // Select Size ... + // note tha <<6==*64 corespond with the 1/64th of points calculation of freetype + int32_t error = FT_Set_Char_Size(m_fftFace, size<<6, size<<6, fontQuality, fontQuality); + // the line height to have a correct display + //float lineHeight = size*1.43f; + + // a small shortcut + FT_GlyphSlot slot = m_fftFace->glyph; + + EWOL_DEBUG("Max size for ths glyph size=" << size << " is (" << m_fftFace->max_advance_width << "," << m_fftFace->max_advance_height << ")"); + + // retrieve glyph index from character code + int32_t glyph_index = FT_Get_Char_Index(m_fftFace, 'A' ); + // load glyph image into the slot (erase previous one) + error = FT_Load_Glyph(m_fftFace, // handle to face object + glyph_index, // glyph index + FT_LOAD_DEFAULT ); + if ( error ) { + EWOL_ERROR("FT_Load_Glyph"); + } + EWOL_DEBUG("linearHoriAdvance=" << (slot->linearHoriAdvance >> 6)); + EWOL_DEBUG("linearVertAdvance=" << (slot->linearVertAdvance >> 6)); + EWOL_DEBUG("metrics.horiAdvance=" << (slot->metrics.horiAdvance >> 6)); + EWOL_DEBUG("metrics.vertAdvance=" << (slot->metrics.vertAdvance >> 6)); + + int32_t nbElement = listElement.Size(); + int32_t coter = simpleSQRT(nbElement); + int32_t glyphMaxWidth = slot->metrics.horiAdvance>>6; + int32_t glyphMaxHeight = slot->metrics.vertAdvance>>6; + int32_t textureWidth = nextP2(coter*glyphMaxWidth); + int32_t nbRaws = textureWidth / glyphMaxWidth; + int32_t nbLine = (nbElement / nbRaws) + 1; + int32_t textureHeight = nextP2(nbLine*glyphMaxHeight); + EWOL_DEBUG("Generate a text texture for char(" << nbRaws << "," << nbLine << ") with size=(" << textureWidth << "," << textureHeight << ")"); + + // Allocate Memory For The Texture Data. + GLubyte* expanded_data = new GLubyte[ 2 * textureWidth * textureHeight]; + // clean the data : + for(int j=0; j =nbRaws) { + tmpRowId = 0; + tmpLineId++; + } + } + // retrieve glyph index from character code + glyph_index = FT_Get_Char_Index(m_fftFace, listElement[iii].unicodeCharVal ); + // load glyph image into the slot (erase previous one) + error = FT_Load_Glyph(m_fftFace, // handle to face object + glyph_index, // glyph index + FT_LOAD_DEFAULT ); + if ( error ) { + EWOL_ERROR("FT_Load_Glyph"); + } + + // convert to an anti-aliased bitmap + error = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL ); + if ( error ) { + EWOL_ERROR("FT_Render_Glyph"); + } + int32_t tmpWidth=slot->bitmap.width; + int32_t tmpHeight=slot->bitmap.rows; + /* + EWOL_DEBUG("elem=" << listElement[iii].unicodeCharVal + <<" size=(" << tmpWidth << "," << tmpHeight << ")" + << " for bitmap (left=" << slot->bitmap_left << ",top=" << slot->bitmap_top << ")"); + EWOL_DEBUG(" BEARING=(" << (slot->metrics.horiBearingX>>6) << "," << (slot->metrics.vertBearingY>>6) << ")" ); + */ + for(int32_t j=0; j < tmpHeight;j++) { + for(int32_t i=0; i < tmpWidth; i++){ + int32_t position = 2*( (tmpRowId *glyphMaxWidth + i /*+ (slot->metrics.horiBearingX>>6)*/ ) + + (tmpLineId*glyphMaxHeight + j + (size-(slot->metrics.horiBearingY>>6)) ) * textureWidth); + expanded_data[position+0] = slot->bitmap.buffer[i + tmpWidth*j]; + expanded_data[position+1] = slot->bitmap.buffer[i + tmpWidth*j]; + } + } + listElement[iii].width = glyphMaxWidth; + listElement[iii].posStart.u = (double)(tmpRowId *glyphMaxWidth) / (double)textureWidth; + listElement[iii].posStart.v = (double)(tmpLineId*glyphMaxHeight) / (double)textureHeight; + listElement[iii].posStop.u = (double)(tmpRowId *glyphMaxWidth + glyphMaxWidth) / (double)textureWidth;; + listElement[iii].posStop.v = (double)(tmpLineId*glyphMaxHeight + glyphMaxHeight) / (double)textureHeight; + } + // Now We Just Setup Some Texture Parameters. + glBindTexture( GL_TEXTURE_2D, textureId); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + + // Here We Actually Create The Texture Itself, Notice That We Are Using GL_LUMINANCE_ALPHA To Indicate That we Are Using 2 Channel Data. + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data ); + + // With The Texture Created, We Don't Need The Expanded Data Anymore. + delete [] expanded_data; + + return false; + } + private: + etk::String m_fontName; + etk::File m_fileName; + FT_Face m_fftFace; +}; + +static etk::VectorType m_listLoadedTTFont; + + +static etk::String s_currentFolderName = ""; +static etk::String s_currentDefaultFontName = ""; +static int32_t s_currentDefaultFontId = -1; + +class FTFont{ + public: + FTFont(etk::File fontfileName, etk::String fontName, int32_t size) + { + m_trueTypeFontId = -1; + for (int32_t iii=0; iii < m_listLoadedTTFont.Size(); iii++) { + if (m_listLoadedTTFont[iii]->GetFontName() == fontName) { + m_trueTypeFontId = iii; + } + } + if (-1==m_trueTypeFontId) { + // load a new one ... + FTFontInternal * tmpElement = new FTFontInternal(fontfileName, fontName); + m_listLoadedTTFont.PushBack(tmpElement); + m_trueTypeFontId = m_listLoadedTTFont.Size() -1; + } + // set the bassic charset: + m_elements.Clear(); + for (int32_t iii=0; iii<127; iii++) { + freeTypeFontElement_ts tmpchar; + tmpchar.unicodeCharVal = iii; + m_elements.PushBack(tmpchar); + } + m_size = size; + //generate font + glGenTextures(1, &m_textureId); + m_listLoadedTTFont[m_trueTypeFontId]->GenerateBitmapFont(m_size, m_textureId, m_elements); + } + ~FTFont(void) + { + + } + bool Check(etk::String fontName, int32_t size) + { + if (m_trueTypeFontId == -1) { + return false; + } + if( m_listLoadedTTFont[m_trueTypeFontId]->GetFontName() == fontName + && m_size == size) + { + return true; + } + return false; + }; + + etk::VectorType & GetRefOnElement(void) + { + return m_elements; + }; + + uint32_t GetOglId(void) + { + return m_textureId; + }; + + int32_t GetSize(void) + { + return m_size; + }; + + private: + int32_t m_trueTypeFontId; + uint32_t m_textureId; // internal texture ID + int32_t m_size; // nb pixel height + int32_t m_interline; // nb pixel between 2 lines + etk::VectorType m_elements; // + +}; + +static etk::VectorType m_listLoadedFont; + +#undef __class__ +#define __class__ "ewol::FontFreeType" + +void ewol::SetFontFolder(etk::String folderName) +{ + if (s_currentFolderName != "") { + EWOL_WARNING("Change the FontFolder, old=\"" << s_currentFolderName << "\""); + } + EWOL_TODO("Check if folder exist"); + s_currentFolderName = folderName; + EWOL_INFO("New default font folder name=\"" << s_currentFolderName << "\""); +} + + +void ewol::UnInitFont(void) +{ + EWOL_TODO("later"); +} + +void ewol::SetDefaultFont(etk::String fontName, int32_t size) +{ + if (s_currentDefaultFontName != "") { + EWOL_WARNING("Change the default Ewol Font, old=\"" << s_currentDefaultFontName << "\""); + } + EWOL_INFO("New default Font Name=\"" << fontName << "\""); + int32_t tmpId = ewol::LoadFont(fontName, size); + if (-1 == tmpId) { + if (s_currentDefaultFontName == "") { + EWOL_ASSERT(-1 != tmpId, "Error to load the default Font\"" << fontName << "\""); + } else { + EWOL_CRITICAL("Unable to load the new default font:\"" << fontName << "\""); + } + return; + } + // save the default font parameters ... + s_currentDefaultFontName = fontName; + s_currentDefaultFontId = tmpId; +} + +int32_t ewol::GetDefaultFontId(void) +{ + return s_currentDefaultFontId; +} + +int32_t ewol::LoadFont(etk::String fontName, int32_t size) +{ + // check if folder file + etk::String tmpFileName = s_currentFolderName + "/" + fontName + ".ttf"; + etk::File fileName(tmpFileName); + if (false == fileName.Exist()) { + EWOL_ERROR("Font does not exist: \"" << fileName.GetCompleateName() << "\""); + return -1; + } + for (int32_t iii=0; iii < m_listLoadedFont.Size(); iii++) { + if (true == m_listLoadedFont[iii]->Check(fontName, size)) { + return iii; + } + } + FTFont * tmpFont = new FTFont(fileName, fontName, size); + m_listLoadedFont.PushBack(tmpFont); + return m_listLoadedFont.Size()-1; +} + +void ewol::UnloadFont(int32_t id) +{ + EWOL_TODO("I do not think it was a good idea... will be done later"); +} + + + + + +void ewol::DrawText(int32_t fontID, + coord2D_ts & drawPosition, + const uniChar_t * unicodeString, + uint32_t & fontTextureId, + etk::VectorType & coord, + etk::VectorType & coordTex) +{ + if(fontID>=m_listLoadedFont.Size() || fontID < 0) { + EWOL_WARNING("try to display text with an fontID that does not existed " << fontID); + return; + } + etk::VectorType & listOfElement = m_listLoadedFont[fontID]->GetRefOnElement(); + + fontTextureId = m_listLoadedFont[fontID]->GetOglId(); + int32_t size = m_listLoadedFont[fontID]->GetSize(); + + float posDrawX = drawPosition.x; + while(*unicodeString != 0) { + int32_t tmpChar = *unicodeString++; + if (tmpChar >= 0x80) { + tmpChar = 0; + } + float sizeWidth = listOfElement[tmpChar].width; + if (tmpChar != 0x20) { + // set texture coordonates : + coordTex.PushBack(listOfElement[tmpChar].posStart); + texCoord_ts tmpTex; + tmpTex.u = listOfElement[tmpChar].posStop.u; + tmpTex.v = listOfElement[tmpChar].posStart.v; + coordTex.PushBack(tmpTex); + coordTex.PushBack(listOfElement[tmpChar].posStop); + tmpTex.u = listOfElement[tmpChar].posStart.u; + tmpTex.v = listOfElement[tmpChar].posStop.v; + coordTex.PushBack(tmpTex); + // set display positions : + coord2D_ts tmpCoord; + tmpCoord.x = posDrawX; + tmpCoord.y = drawPosition.y; + coord.PushBack(tmpCoord); + tmpCoord.x = posDrawX + sizeWidth; + coord.PushBack(tmpCoord); + tmpCoord.y = drawPosition.y + size; + coord.PushBack(tmpCoord); + tmpCoord.x = posDrawX; + coord.PushBack(tmpCoord); + } + posDrawX += sizeWidth; + } + drawPosition.x = posDrawX; +} + + + +void ewol::DrawText(int32_t fontID, + coord2D_ts & drawPosition, + const char * utf8String, + uint32_t & fontTextureId, + etk::VectorType & coord, + etk::VectorType & coordTex) +{ + // TODO : This code des not work, why ???? + /* + int32_t tmpstringLen = strlen(utf8String); + int32_t * tmpUnicodeString = new int32_t(tmpstringLen+1); + // TODO : generate a better convertor... + for (int32_t iii=0; iii=m_listLoadedFont.Size() || fontID < 0) { + EWOL_WARNING("try to display text with an fontID that does not existed " << fontID); + return; + } + etk::VectorType & listOfElement = m_listLoadedFont[fontID]->GetRefOnElement(); + char * tmpVal = (char*)utf8String; + + fontTextureId = m_listLoadedFont[fontID]->GetOglId(); + int32_t size = m_listLoadedFont[fontID]->GetSize(); + + float posDrawX = drawPosition.x; + while(*tmpVal != 0) { + int32_t tmpChar = *tmpVal++; + if (tmpChar >= 0x80) { + tmpChar = 0; + } + float sizeWidth = listOfElement[tmpChar].width; + if (tmpChar != 0x20) { + // set texture coordonates : + coordTex.PushBack(listOfElement[tmpChar].posStart); + texCoord_ts tmpTex; + tmpTex.u = listOfElement[tmpChar].posStop.u; + tmpTex.v = listOfElement[tmpChar].posStart.v; + coordTex.PushBack(tmpTex); + coordTex.PushBack(listOfElement[tmpChar].posStop); + tmpTex.u = listOfElement[tmpChar].posStart.u; + tmpTex.v = listOfElement[tmpChar].posStop.v; + coordTex.PushBack(tmpTex); + // set display positions : + coord2D_ts tmpCoord; + tmpCoord.x = posDrawX; + tmpCoord.y = drawPosition.y; + coord.PushBack(tmpCoord); + tmpCoord.x = posDrawX + sizeWidth; + coord.PushBack(tmpCoord); + tmpCoord.y = drawPosition.y + size; + coord.PushBack(tmpCoord); + tmpCoord.x = posDrawX; + coord.PushBack(tmpCoord); + } + posDrawX += sizeWidth; + } + drawPosition.x = posDrawX; + +} diff --git a/Sources/ewolOObject.cpp b/Sources/ewolOObject.cpp index d46c6e6d..d1821a36 100644 --- a/Sources/ewolOObject.cpp +++ b/Sources/ewolOObject.cpp @@ -228,7 +228,8 @@ void ewol::OObject2DText::Text(float x, float y, etk::String FontName, int32_t s m_coord.Clear(); m_coordTex.Clear(); // get font Name : - m_FontId = GetFontIdWithName(FontName); + //m_FontId = GetFontIdWithName(FontName); + m_FontId = GetDefaultFontId(); if (m_FontId == -1) { EWOL_ERROR("Can not find the font with the name : " << FontName); } @@ -237,7 +238,7 @@ void ewol::OObject2DText::Text(float x, float y, etk::String FontName, int32_t s coord2D_ts drawPosition; drawPosition.x = x; drawPosition.y = y; - ewol::DrawText(m_FontId, mode, size, drawPosition, utf8String, m_FontTextureId, m_coord, m_coordTex); + ewol::DrawText(m_FontId, drawPosition, utf8String, m_FontTextureId, m_coord, m_coordTex); } diff --git a/Sources/ewolWindows.cpp b/Sources/ewolWindows.cpp index 4cb6071e..649191c5 100644 --- a/Sources/ewolWindows.cpp +++ b/Sources/ewolWindows.cpp @@ -140,191 +140,23 @@ void ewol::Windows::SysDraw(void) //glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR); GenDraw(); - - static bool initTest = false; - static uint32_t TMPtextureid; - if (false == initTest) { - initTest = true; - int32_t error = FT_Init_FreeType( &library ); - if(0 != error) { - EWOL_CRITICAL("... an error occurred during library initialization ..."); - } else { - etk::File myFile = "Font/freefont/FreeMono.ttf"; - - error = FT_New_Face( library, myFile.GetCompleateName().c_str(), 0, &face ); - if( FT_Err_Unknown_File_Format == error) { - EWOL_ERROR("... the font file could be opened and read, but it appears ... that its font format is unsupported"); - } else if (0 != error) { - EWOL_ERROR("... another error code means that the font file could not ... be opened or read, or simply that it is broken..."); - } else { - // all OK - EWOL_INFO("load font : \"" << myFile << "\" "); - EWOL_INFO(" nuber of glyph = " << face->num_glyphs); - if ((FT_FACE_FLAG_SCALABLE & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_SCALABLE (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_SCALABLE (disable)"); - } - if ((FT_FACE_FLAG_FIXED_SIZES & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_FIXED_SIZES (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_FIXED_SIZES (disable)"); - } - if ((FT_FACE_FLAG_FIXED_WIDTH & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_FIXED_WIDTH (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_FIXED_WIDTH (disable)"); - } - if ((FT_FACE_FLAG_SFNT & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_SFNT (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_SFNT (disable)"); - } - if ((FT_FACE_FLAG_HORIZONTAL & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_HORIZONTAL (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_HORIZONTAL (disable)"); - } - if ((FT_FACE_FLAG_VERTICAL & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_VERTICAL (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_VERTICAL (disable)"); - } - if ((FT_FACE_FLAG_KERNING & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_KERNING (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_KERNING (disable)"); - } - /* Deprecated flag - if ((FT_FACE_FLAG_FAST_GLYPHS & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_FAST_GLYPHS (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_FAST_GLYPHS (disable)"); - } - */ - if ((FT_FACE_FLAG_MULTIPLE_MASTERS & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_MULTIPLE_MASTERS (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_MULTIPLE_MASTERS (disable)"); - } - if ((FT_FACE_FLAG_GLYPH_NAMES & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_GLYPH_NAMES (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_GLYPH_NAMES (disable)"); - } - if ((FT_FACE_FLAG_EXTERNAL_STREAM & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_EXTERNAL_STREAM (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_EXTERNAL_STREAM (disable)"); - } - if ((FT_FACE_FLAG_HINTER & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_HINTER (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_HINTER (disable)"); - } - if ((FT_FACE_FLAG_CID_KEYED & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_CID_KEYED (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_CID_KEYED (disable)"); - } - if ((FT_FACE_FLAG_TRICKY & face->face_flags) != 0) { - EWOL_INFO(" flags = FT_FACE_FLAG_TRICKY (enable)"); - } else { - EWOL_DEBUG(" flags = FT_FACE_FLAG_TRICKY (disable)"); - } - EWOL_INFO(" unit per EM = " << face->units_per_EM); - EWOL_INFO(" num of fixed sizes = " << face->num_fixed_sizes); - EWOL_INFO(" Availlable sizes = " << face->available_sizes); - - EWOL_INFO(" Current size = " << face->size); - - // set size : - int32_t fontSize = 12; - int32_t fontQuality = 96; // 300dpi (hight quality) 96 dpi (normal quality) - error = FT_Set_Char_Size(face, fontSize<<6, fontSize<<6, fontQuality, fontQuality); // note tha <<6==*64 corespond with the 1/64th of points calculation of freetype - float lineHeight = fontSize*1.43f; // the line height to have a correct display - /* retrieve glyph index from character code */ - int32_t glyph_index = FT_Get_Char_Index(face, 'A' ); - /* load glyph image into the slot (erase previous one) */ - error = FT_Load_Glyph(face, /* handle to face object */ - glyph_index, /* glyph index */ - FT_LOAD_DEFAULT ); - if ( error ) { - EWOL_ERROR("FT_Load_Glyph"); - } - /* a small shortcut */ - FT_GlyphSlot slot = face->glyph; - - /* convert to an anti-aliased bitmap */ - error = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL ); - if ( error ) { - EWOL_ERROR("FT_Render_Glyph"); - } - int32_t tmpWidth=slot->bitmap.width; - int32_t tmpHeight=slot->bitmap.rows; - - EWOL_DEBUG("Width=" << tmpWidth); - EWOL_DEBUG("Height=" << tmpHeight); - /* - my_draw_bitmap(&slot->bitmap, - pen_x + slot->bitmap_left, - pen_y - slot->bitmap_top); - glEnable(GL_TEXTURE_2D); - */ - // Allocate Memory For The Texture Data. - GLubyte* expanded_data = new GLubyte[ 2 * tmpWidth * tmpHeight]; - - /* - Here We Fill In The Data For The Expanded Bitmap. - Notice That We Are Using A Two Channel Bitmap (One For - Channel Luminosity And One For Alpha), But We Assign - Both Luminosity And Alpha To The Value That We - Find In The FreeType Bitmap. - We Use The ?: Operator To Say That Value Which We Use - Will Be 0 If We Are In The Padding Zone, And Whatever - Is The FreeType Bitmap Otherwise. - */ - for(int j=0; j =tmpWidth || j>=tmpHeight) ? 0 : slot->bitmap.buffer[i + tmpWidth*j]; - } - } - - // Now We Just Setup Some Texture Parameters. - glGenTextures(1, &TMPtextureid); - glBindTexture( GL_TEXTURE_2D, TMPtextureid); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - - // Here We Actually Create The Texture Itself, Notice That We Are Using GL_LUMINANCE_ALPHA To Indicate That we Are Using 2 Channel Data. - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tmpWidth, tmpHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data ); - - // With The Texture Created, We Don't Need The Expanded Data Anymore. - delete [] expanded_data; - } - } - } - - /* ewol::OObject2DColored tmpOObjects; - tmpOObjects.Rectangle( 290, 90, 60, 60, 1.0, 0.0, 0.0, 1.0); + tmpOObjects.Rectangle( 50, 50, 200, 300, 1.0, 0.0, 0.0, 1.0); tmpOObjects.Draw(); - */ - glColor4f(0.0, 0.0, 0.0, 1.0); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, TMPtextureid); + glBindTexture(GL_TEXTURE_2D, 1); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); - glVertex3f(300.0, 100.0, 0.0); + glVertex3f(50.0, 50.0, 0.0); glTexCoord2f(1.0, 0.0); - glVertex3f(310.0, 100.0, 0.0); + glVertex3f(250.0, 50.0, 0.0); glTexCoord2f(1.0, 1.0); - glVertex3f(310.0, 112.0, 0.0); + glVertex3f(250.0, 350.0, 0.0); glTexCoord2f(0.0, 1.0); - glVertex3f(300.0, 112.0, 0.0); + glVertex3f(50.0, 350.0, 0.0); glEnd(); glDisable(GL_TEXTURE_2D);