2011-10-29 17:32:11 +02:00
/**
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2011-11-06 20:24:44 +01:00
* @ file ewolFontBitmap . cpp
2011-10-29 17:32:11 +02:00
* @ brief ewol Font system ( sources )
* @ author Edouard DUPIN
* @ date 29 / 10 / 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 <ewolFont.h>
# include <ewolTexture.h>
# include <etkVectorType.h>
2011-10-30 14:52:55 +01:00
# include <GL/gl.h>
# include <GL/glu.h>
# include <GL/glx.h>
# include <GL/glut.h>
# if defined(EWOL_X11_MODE__XF86V)
# include <X11 / extensions / xf86vmode.h>
# elif defined(EWOL_X11_MODE__XRENDER)
# include <X11 / extensions / Xrender.h>
# endif
# undef __class__
2011-11-06 20:24:44 +01:00
# define __class__ "ewol::FontBitmap"
2011-10-30 14:52:55 +01:00
2011-10-29 17:32:11 +02:00
extern " C "
{
typedef struct {
2011-10-31 11:01:47 +01:00
texCoord_ts posStart ;
texCoord_ts posStop ;
2011-10-30 15:09:44 +01:00
float ratio ;
2011-10-29 17:32:11 +02:00
} UTF8Element_ts ;
}
2011-10-30 14:52:55 +01:00
namespace ewol
2011-10-29 17:32:11 +02:00
{
2011-10-30 14:52:55 +01:00
class Font
2011-10-29 17:32:11 +02:00
{
2011-10-30 14:52:55 +01:00
public :
Font ( etk : : File newFile )
{
m_loadedOK = false ;
m_filename = newFile ;
2011-10-31 11:01:47 +01:00
for ( int32_t iii = 0 ; iii < FONT_MODE_NUMBER ; iii + + ) {
2011-10-30 14:52:55 +01:00
m_textureId [ iii ] = 0 ;
m_textureLoaded [ iii ] = false ;
}
if ( m_filename . GetExtention ( ) ! = " ebt " ) {
EWOL_ERROR ( " Not the coorect extention of the file " < < m_filename ) ;
return ;
}
if ( false = = m_filename . Exist ( ) ) {
EWOL_ERROR ( " File does not Exist ... " < < m_filename ) ;
return ;
}
FILE * File = fopen ( m_filename . GetCompleateName ( ) . c_str ( ) , " r " ) ;
if ( NULL = = File ) {
EWOL_ERROR ( " Can not find the file name= \" " < < m_filename < < " \" " ) ;
return ;
}
// load all element of the file ...
char elementLine [ 2048 ] ;
int32_t lineID = 1 ;
while ( NULL ! = fgets ( elementLine , 2048 , File ) )
{
if ( ' \n ' ! = elementLine [ 0 ] // EOL
& & ' \0 ' ! = elementLine [ 0 ] // EOF
& & ' # ' ! = elementLine [ 0 ] // Comment line
)
{
if ( 0 = = strncmp ( " name: " , elementLine , 5 ) ) {
char extractString [ 256 ] = " " ;
sscanf ( elementLine , " name:%s " , extractString ) ;
m_fontName = extractString ;
EWOL_INFO ( " Find font named : \" " < < m_fontName < < " \" " ) ;
} else if ( 0 = = strncmp ( " normal: " , elementLine , 7 ) ) {
char extractString [ 256 ] = " " ;
sscanf ( elementLine , " normal:%s " , extractString ) ;
SetModeFile ( FONT_MODE_NORMAL , extractString ) ;
LoadMode ( FONT_MODE_NORMAL ) ;
} else if ( 0 = = strncmp ( " bold-italic: " , elementLine , 12 ) ) {
char extractString [ 256 ] = " " ;
sscanf ( elementLine , " bold-italic:%s " , extractString ) ;
SetModeFile ( FONT_MODE_BOLD_ITALIC , extractString ) ;
} else if ( 0 = = strncmp ( " bold: " , elementLine , 5 ) ) {
char extractString [ 256 ] = " " ;
sscanf ( elementLine , " bold:%s " , extractString ) ;
SetModeFile ( FONT_MODE_BOLD , extractString ) ;
} else if ( 0 = = strncmp ( " italic: " , elementLine , 7 ) ) {
char extractString [ 256 ] = " " ;
sscanf ( elementLine , " italic:%s " , extractString ) ;
SetModeFile ( FONT_MODE_ITALIC , extractString ) ;
} else if ( 0 = = strncmp ( " 0x00 " , elementLine , 4 ) ) {
int32_t GlyphPositionX ;
int32_t GlyphPositionY ;
int32_t GlyphSizeX ;
int32_t GlyphSizeY ;
sscanf ( elementLine , " 0x00 (%d,%d) (%d,%d) " , & GlyphPositionX , & GlyphPositionY , & GlyphSizeX , & GlyphSizeY ) ;
ClearAll ( GlyphPositionX , GlyphPositionY , GlyphSizeX , GlyphSizeY ) ;
} else if ( 0 = = strncmp ( " 0x " , elementLine , 2 ) ) {
uint32_t utf8Value ;
int32_t GlyphPositionX ;
int32_t GlyphPositionY ;
int32_t GlyphSizeX ;
int32_t GlyphSizeY ;
sscanf ( elementLine , " 0x%x (%d,%d) (%d,%d) " , & utf8Value , & GlyphPositionX , & GlyphPositionY , & GlyphSizeX , & GlyphSizeY ) ;
SetGlyphID ( utf8Value , lineID , GlyphPositionX , GlyphPositionY , GlyphSizeX , GlyphSizeY ) ;
} else {
EWOL_ERROR ( " error when parsing the line : " < < lineID < < " \" " < < elementLine < < " \" " ) ;
}
}
lineID + + ;
}
// close the file at end of reading...
fclose ( File ) ;
m_loadedOK = true ;
} ;
~ Font ( void )
{
2011-10-31 11:01:47 +01:00
for ( int32_t iii = 0 ; iii < FONT_MODE_NUMBER ; iii + + ) {
if ( true = = m_textureLoaded [ iii ] ) {
ewol : : UnLoadTexture ( m_textureId [ iii ] ) ;
}
}
2011-10-30 14:52:55 +01:00
} ;
bool loadedOK ( void ) { return m_loadedOK ; } ;
private :
void ClearAll ( int32_t x , int32_t y , int32_t w , int32_t h )
{
2011-10-31 13:01:33 +01:00
//EWOL_DEBUG("Find default font glyph : (" << x << "," << y << ") (" << w << "," << h << ") ");
2011-10-29 17:32:11 +02:00
for ( int32_t iii = 0 ; iii < 0x80 ; iii + + ) {
2011-10-31 11:01:47 +01:00
m_listOfElement [ iii ] . posStart . u = ( double ) x / 512.0 ;
m_listOfElement [ iii ] . posStart . v = ( double ) y / 512.0 ;
m_listOfElement [ iii ] . posStop . u = ( double ) ( x + w ) / 512.0 ;
m_listOfElement [ iii ] . posStop . v = ( double ) ( y + h ) / 512.0 ;
2011-10-30 15:09:44 +01:00
m_listOfElement [ iii ] . ratio = ( float ) w / ( float ) h ;
2011-10-29 17:32:11 +02:00
}
2011-10-30 14:52:55 +01:00
} ;
void SetGlyphID ( int32_t utf8Value , int32_t lineID , int32_t x , int32_t y , int32_t w , int32_t h )
{
2011-10-31 13:01:33 +01:00
//EWOL_DEBUG("Add font glyph : "<< utf8Value << " (" << x << "," << y << ") (" << w << "," << h << ") ");
2011-10-29 17:32:11 +02:00
if ( utf8Value < 0x80 ) {
2011-10-31 11:01:47 +01:00
m_listOfElement [ utf8Value ] . posStart . u = ( double ) x / 512.0 ;
m_listOfElement [ utf8Value ] . posStart . v = ( double ) y / 512.0 ;
m_listOfElement [ utf8Value ] . posStop . u = ( double ) ( x + w ) / 512.0 ;
m_listOfElement [ utf8Value ] . posStop . v = ( double ) ( y + h ) / 512.0 ;
2011-10-30 15:09:44 +01:00
m_listOfElement [ utf8Value ] . ratio = ( float ) w / ( float ) h ;
2011-10-29 17:32:11 +02:00
} else {
2011-10-30 14:52:55 +01:00
EWOL_ERROR ( " not manage glyph with ID > 0x7F line : " < < lineID ) ;
2011-10-29 17:32:11 +02:00
}
2011-10-30 14:52:55 +01:00
} ;
public :
void SetModeFile ( ewol : : fontMode_te displayMode , etk : : String newFile )
{
if ( displayMode < FONT_MODE_NUMBER ) {
m_bitmapName [ displayMode ] = newFile ;
}
} ;
void LoadMode ( ewol : : fontMode_te displayMode )
{
if ( displayMode < FONT_MODE_NUMBER ) {
if ( m_bitmapName [ displayMode ] = = " " ) {
EWOL_ERROR ( " Can not load en empty file for the Font : " < < m_filename ) ;
return ;
}
if ( m_textureLoaded [ displayMode ] = = true ) {
EWOL_WARNING ( " Mode of font is alredy loaded : " < < m_filename ) ;
return ;
}
etk : : String elementName = m_filename . GetFolder ( ) ;
elementName + = ' / ' ;
elementName + = m_bitmapName [ displayMode ] ;
EWOL_INFO ( " load text font image : \" " < < elementName < < " \" " ) ;
m_textureId [ displayMode ] = ewol : : LoadTexture ( elementName ) ;
m_textureLoaded [ displayMode ] = true ;
}
} ;
etk : : File GetFileName ( void )
{
return m_filename ;
} ;
etk : : String GetName ( void )
{
return m_fontName ;
} ;
bool IsLoaded ( ewol : : fontMode_te displayMode )
{
return m_textureLoaded [ displayMode ] ;
} ;
private :
etk : : File m_filename ;
bool m_loadedOK ;
etk : : String m_fontName ;
uint32_t m_textureId [ FONT_MODE_NUMBER ] ;
bool m_textureLoaded [ FONT_MODE_NUMBER ] ;
etk : : String m_bitmapName [ FONT_MODE_NUMBER ] ;
UTF8Element_ts m_listOfElement [ 0x80 ] ;
public :
UTF8Element_ts * GetPointerOnElement ( void )
{
return m_listOfElement ;
} ;
uint32_t GetOglId ( ewol : : fontMode_te displayMode )
{
return m_textureId [ displayMode ] ;
} ;
} ;
} ;
static etk : : VectorType < ewol : : Font * > listLoadedFonts ;
2011-10-31 11:01:47 +01:00
void ewol : : UnInitFont ( void )
{
for ( int32_t iii = 0 ; iii < listLoadedFonts . Size ( ) ; iii + + ) {
delete ( listLoadedFonts [ iii ] ) ;
listLoadedFonts [ iii ] = NULL ;
}
listLoadedFonts . Clear ( ) ;
}
2011-10-30 14:52:55 +01:00
// 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 ewol : : AddFont ( etk : : File fontFileName , bool bold , bool italic , bool boldItalic )
{
for ( int32_t iii = 0 ; iii < listLoadedFonts . Size ( ) ; iii + + ) {
if ( listLoadedFonts [ iii ] - > GetFileName ( ) = = fontFileName ) {
if ( true = = bold ) {
listLoadedFonts [ iii ] - > LoadMode ( FONT_MODE_BOLD ) ;
}
if ( true = = italic ) {
listLoadedFonts [ iii ] - > LoadMode ( FONT_MODE_ITALIC ) ;
2011-10-29 17:32:11 +02:00
}
2011-10-30 14:52:55 +01:00
if ( true = = boldItalic ) {
listLoadedFonts [ iii ] - > LoadMode ( FONT_MODE_BOLD_ITALIC ) ;
}
return true ;
2011-10-29 17:32:11 +02:00
}
}
2011-10-30 14:52:55 +01:00
if ( fontFileName . GetExtention ( ) ! = " ebt " ) {
EWOL_ERROR ( " Not the correct extention of the file " < < fontFileName < < " supported only *.ebt " ) ;
return false ;
}
ewol : : Font * tmpFont = new ewol : : Font ( fontFileName ) ;
if ( false = = tmpFont - > loadedOK ( ) ) {
EWOL_ERROR ( " An error apear when loading Font file : " < < fontFileName ) ;
return false ;
}
if ( true = = bold ) {
tmpFont - > LoadMode ( FONT_MODE_BOLD ) ;
}
if ( true = = italic ) {
tmpFont - > LoadMode ( FONT_MODE_ITALIC ) ;
}
if ( true = = boldItalic ) {
tmpFont - > LoadMode ( FONT_MODE_BOLD_ITALIC ) ;
}
listLoadedFonts . PushBack ( tmpFont ) ;
return true ;
2011-10-29 17:32:11 +02:00
}
2011-10-30 14:52:55 +01:00
// get the name of the font
etk : : String ewol : : GetFontName ( int32_t Id )
{
if ( Id < listLoadedFonts . Size ( ) & & Id > = 0 ) {
return listLoadedFonts [ Id ] - > GetName ( ) ;
}
return " No-Name " ;
}
int32_t ewol : : GetFontIdWithFileName ( etk : : File fontFileName )
{
for ( int32_t iii = 0 ; iii < listLoadedFonts . Size ( ) ; iii + + ) {
if ( listLoadedFonts [ iii ] - > GetFileName ( ) = = fontFileName ) {
return iii ;
}
}
return - 1 ;
}
int32_t ewol : : GetFontIdWithName ( etk : : String fontName )
{
for ( int32_t iii = 0 ; iii < listLoadedFonts . Size ( ) ; iii + + ) {
if ( listLoadedFonts [ iii ] - > GetName ( ) = = fontName ) {
return iii ;
}
}
return - 1 ;
}
// get the size of a long string in UTF8 (note that \n and \r represent unknown char...)
int32_t ewol : : GetStringWidth ( int32_t fontID , ewol : : fontMode_te displayMode , int32_t size , const char * utf8String )
{
return 0 ;
}
2011-10-29 17:32:11 +02:00
2011-10-30 14:52:55 +01:00
// get the size of a specific char in UTF8
int32_t ewol : : GetCharWidth ( int32_t fontID , ewol : : fontMode_te displayMode , int32_t size , const char * utf8String )
2011-10-29 17:32:11 +02:00
{
2011-10-30 14:52:55 +01:00
return 0 ;
}
// draw the text without background
void ewol : : DrawText ( int32_t fontID ,
ewol : : fontMode_te displayMode ,
int32_t size ,
coord3D_ts & drawPosition ,
color_ts textColorFg ,
const char * utf8String )
{
if ( fontID > = listLoadedFonts . Size ( ) | | fontID < 0 ) {
EWOL_WARNING ( " try to display text with an fontID that does not existed " < < fontID ) ;
return ;
}
if ( false = = listLoadedFonts [ fontID ] - > IsLoaded ( displayMode ) ) {
listLoadedFonts [ fontID ] - > LoadMode ( displayMode ) ;
if ( false = = listLoadedFonts [ fontID ] - > IsLoaded ( displayMode ) ) {
EWOL_ERROR ( " Can not load Font mode : " < < displayMode < < " of font " < < listLoadedFonts [ fontID ] - > GetName ( ) ) ;
return ;
}
}
UTF8Element_ts * listOfElement = listLoadedFonts [ fontID ] - > GetPointerOnElement ( ) ;
char * tmpVal = ( char * ) utf8String ;
glColor4f ( textColorFg . red , textColorFg . green , textColorFg . blue , textColorFg . alpha ) ;
2011-10-29 17:32:11 +02:00
glEnable ( GL_TEXTURE_2D ) ;
2011-10-30 14:52:55 +01:00
glBindTexture ( GL_TEXTURE_2D , listLoadedFonts [ fontID ] - > GetOglId ( displayMode ) ) ;
2011-10-30 15:09:44 +01:00
float posDrawX = drawPosition . x ;
2011-10-29 17:32:11 +02:00
while ( * tmpVal ! = ' \0 ' ) {
2011-10-30 09:50:03 +01:00
int32_t tmpChar = ( int32_t ) * tmpVal ;
2011-10-29 17:32:11 +02:00
if ( tmpChar > = 0x80 ) {
tmpChar = 0 ;
}
2011-10-30 15:09:44 +01:00
float sizeWidth = size * listOfElement [ tmpChar ] . ratio ;
2011-10-30 14:52:55 +01:00
if ( tmpChar ! = 0x20 ) {
2011-10-31 11:01:47 +01:00
// TODO : this is really not availlable in the OpenGL ES ==> make with vertex system ...
2011-10-30 14:52:55 +01:00
glBegin ( GL_QUADS ) ;
2011-10-30 15:09:44 +01:00
//m_listOfElement[utf8Value].ratio = (float)w/(float)h;
2011-10-31 11:01:47 +01:00
glTexCoord2f ( listOfElement [ tmpChar ] . posStart . u , listOfElement [ tmpChar ] . posStart . v ) ; glVertex3f ( posDrawX , drawPosition . y , 0.0 ) ;
glTexCoord2f ( listOfElement [ tmpChar ] . posStop . u , listOfElement [ tmpChar ] . posStart . v ) ; glVertex3f ( posDrawX + sizeWidth , drawPosition . y , 0.0 ) ;
glTexCoord2f ( listOfElement [ tmpChar ] . posStop . u , listOfElement [ tmpChar ] . posStop . v ) ; glVertex3f ( posDrawX + sizeWidth , drawPosition . y + size , 0.0 ) ;
glTexCoord2f ( listOfElement [ tmpChar ] . posStart . u , listOfElement [ tmpChar ] . posStop . v ) ; glVertex3f ( posDrawX , drawPosition . y + size , 0.0 ) ;
2011-10-30 14:52:55 +01:00
glEnd ( ) ;
}
2011-10-29 17:32:11 +02:00
tmpVal + + ;
2011-10-30 15:09:44 +01:00
posDrawX + = sizeWidth ;
2011-10-29 17:32:11 +02:00
}
2011-10-30 15:09:44 +01:00
drawPosition . x = posDrawX ;
2011-10-29 17:32:11 +02:00
glDisable ( GL_TEXTURE_2D ) ;
}
2011-11-06 20:24:44 +01:00
2011-10-30 14:52:55 +01:00
2011-10-31 11:01:47 +01:00
void ewol : : DrawText ( int32_t fontID ,
ewol : : fontMode_te displayMode ,
int32_t size ,
coord2D_ts & drawPosition ,
const char * utf8String ,
uint32_t & fontTextureId ,
etk : : VectorType < coord2D_ts > & coord ,
etk : : VectorType < texCoord_ts > & coordTex )
{
if ( fontID > = listLoadedFonts . Size ( ) | | fontID < 0 ) {
EWOL_WARNING ( " try to display text with an fontID that does not existed " < < fontID ) ;
return ;
}
if ( false = = listLoadedFonts [ fontID ] - > IsLoaded ( displayMode ) ) {
listLoadedFonts [ fontID ] - > LoadMode ( displayMode ) ;
if ( false = = listLoadedFonts [ fontID ] - > IsLoaded ( displayMode ) ) {
EWOL_ERROR ( " Can not load Font mode : " < < displayMode < < " of font " < < listLoadedFonts [ fontID ] - > GetName ( ) ) ;
return ;
}
}
UTF8Element_ts * listOfElement = listLoadedFonts [ fontID ] - > GetPointerOnElement ( ) ;
char * tmpVal = ( char * ) utf8String ;
// set id of texture ... (i kwnow it was a little dangerous, but this ID is never remove while the program is running...
fontTextureId = listLoadedFonts [ fontID ] - > GetOglId ( displayMode ) ;
float posDrawX = drawPosition . x ;
while ( * tmpVal ! = ' \0 ' ) {
int32_t tmpChar = ( int32_t ) * tmpVal ;
if ( tmpChar > = 0x80 ) {
tmpChar = 0 ;
}
float sizeWidth = size * listOfElement [ tmpChar ] . ratio ;
if ( tmpChar ! = 0x20 ) {
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 ) ;
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 ) ;
}
tmpVal + + ;
posDrawX + = sizeWidth ;
}
drawPosition . x = posDrawX ;
}
2011-10-30 14:52:55 +01:00
2011-10-29 17:32:11 +02:00