Better true-type display of the none-mono-space font

This commit is contained in:
Edouard Dupin 2012-01-18 14:32:08 +01:00
parent 83c7165c53
commit b21e1a74f8
4 changed files with 109 additions and 57 deletions

View File

@ -87,7 +87,7 @@ namespace ewol
int32_t GetHeight(int32_t fontID); int32_t GetHeight(int32_t fontID);
void DrawText(int32_t fontID, int32_t DrawText(int32_t fontID,
coord2D_ts & drawPosition, coord2D_ts & drawPosition,
coord2D_ts & clipSize, coord2D_ts & clipSize,
const char * utf8String, const char * utf8String,

View File

@ -52,12 +52,15 @@
extern "C" extern "C"
{ {
// show : http://www.freetype.org/freetype2/docs/tutorial/step2.html
typedef struct { typedef struct {
uniChar_t unicodeCharVal; uniChar_t unicodeCharVal;
int32_t width;
texCoord_ts posStart; texCoord_ts posStart;
texCoord_ts posStop; texCoord_ts posStop;
etkFloat_t ratio; coord2D_ts bearing;
coord2D_ts size;
int32_t advance;
etkFloat_t ratio;
}freeTypeFontElement_ts; }freeTypeFontElement_ts;
}; };
@ -278,24 +281,33 @@ class FTFontInternal
int32_t glyphMaxHeight = /*(m_fftFace->max_advance_height>>6); */slot->metrics.vertAdvance>>6; int32_t glyphMaxHeight = /*(m_fftFace->max_advance_height>>6); */slot->metrics.vertAdvance>>6;
int32_t textureWidth = nextP2(coter*glyphMaxWidth); int32_t textureWidth = nextP2(coter*glyphMaxWidth);
int32_t nbRaws = textureWidth / glyphMaxWidth; int32_t nbRaws = textureWidth / glyphMaxWidth;
if (nbRaws <= 0) {
EWOL_ERROR("devide by 0");
nbRaws = 1;
}
int32_t nbLine = (nbElement / nbRaws) + 1; int32_t nbLine = (nbElement / nbRaws) + 1;
int32_t textureHeight = nextP2(nbLine*glyphMaxHeight); int32_t textureHeight = nextP2(nbLine*glyphMaxHeight);
EWOL_DEBUG("Generate a text texture for char(" << nbRaws << "," << nbLine << ") with size=(" << textureWidth << "," << textureHeight << ")"); EWOL_DEBUG("Generate a text texture for char(" << nbRaws << "," << nbLine << ") with size=(" << textureWidth << "," << textureHeight << ")");
// Allocate Memory For The Texture Data. // Allocate Memory For The Texture Data.
GLubyte* expanded_data = new GLubyte[textureWidth * textureHeight]; GLubyte* expanded_data = new GLubyte[textureWidth * textureHeight];
if (NULL == expanded_data) {
EWOL_ERROR("Allocation tmp data ERROR");
return false;
}
// clean the data : // clean the data :
for(int j=0; j <textureHeight;j++) { for(int j=0; j <textureHeight;j++) {
for(int i=0; i < textureWidth; i++){ for(int i=0; i < textureWidth; i++){
expanded_data[(i+j*textureWidth)] = 0; expanded_data[(i+j*textureWidth)] = 0;
} }
} }
int32_t tmpRowStartPos = 0;
int32_t tmpRowId = 0; int32_t tmpLineStartPos = 0;
int32_t tmpLineId = 0; int32_t CurrentLineHigh = 0;
// Generate for All Elements : // Generate for All Elements :
for (int32_t iii=0; iii<listElement.Size(); iii++) { for (int32_t iii=0; iii<listElement.Size(); iii++) {
// increment the position of the texture // increment the position of the texture
/*
if (iii!=0) { if (iii!=0) {
tmpRowId++; tmpRowId++;
if (tmpRowId>=nbRaws) { if (tmpRowId>=nbRaws) {
@ -303,6 +315,7 @@ class FTFontInternal
tmpLineId++; tmpLineId++;
} }
} }
*/
// retrieve glyph index from character code // retrieve glyph index from character code
glyph_index = FT_Get_Char_Index(m_fftFace, listElement[iii].unicodeCharVal ); glyph_index = FT_Get_Char_Index(m_fftFace, listElement[iii].unicodeCharVal );
// load glyph image into the slot (erase previous one) // load glyph image into the slot (erase previous one)
@ -320,6 +333,14 @@ class FTFontInternal
} }
int32_t tmpWidth=slot->bitmap.width; int32_t tmpWidth=slot->bitmap.width;
int32_t tmpHeight=slot->bitmap.rows; int32_t tmpHeight=slot->bitmap.rows;
// check if we have enought place on the bitmap to add the current element :
if (tmpRowStartPos+tmpWidth >= textureWidth) {
tmpRowStartPos = 0;
tmpLineStartPos += CurrentLineHigh;
CurrentLineHigh = 0;
EWOL_ASSERT(tmpLineStartPos+tmpHeight < textureHeight, "Texture dimention estimatiuon error for the current Font");
}
EWOL_DEBUG("elem=" << listElement[iii].unicodeCharVal EWOL_DEBUG("elem=" << listElement[iii].unicodeCharVal
<<" size=(" << tmpWidth << "," << tmpHeight << ")" <<" size=(" << tmpWidth << "," << tmpHeight << ")"
@ -328,17 +349,30 @@ class FTFontInternal
for(int32_t j=0; j < tmpHeight;j++) { for(int32_t j=0; j < tmpHeight;j++) {
for(int32_t i=0; i < tmpWidth; i++){ for(int32_t i=0; i < tmpWidth; i++){
int32_t position = ( (tmpRowId *glyphMaxWidth + i /*+ (slot->metrics.horiBearingX>>6)*/ ) int32_t position = (tmpRowStartPos + i )
+ (tmpLineId*glyphMaxHeight + j + (size-(slot->metrics.horiBearingY>>6)) ) * textureWidth); + (tmpLineStartPos + j ) * textureWidth;
//EWOL_DEBUG(" BEARING=(" << i << "," << j << ") pos=" << position);
expanded_data[position] = slot->bitmap.buffer[i + tmpWidth*j]; expanded_data[position] = slot->bitmap.buffer[i + tmpWidth*j];
} }
} }
listElement[iii].width = glyphMaxWidth; listElement[iii].bearing.x = slot->metrics.horiBearingX>>6;
listElement[iii].posStart.u = (etkFloat_t)(tmpRowId *glyphMaxWidth) / (etkFloat_t)textureWidth; listElement[iii].bearing.y = slot->metrics.horiBearingY>>6;
listElement[iii].posStart.v = (etkFloat_t)(tmpLineId*glyphMaxHeight) / (etkFloat_t)textureHeight; listElement[iii].size.x = tmpWidth;
listElement[iii].posStop.u = (etkFloat_t)(tmpRowId *glyphMaxWidth + glyphMaxWidth) / (etkFloat_t)textureWidth; listElement[iii].size.y = tmpHeight;
listElement[iii].posStop.v = (etkFloat_t)(tmpLineId*glyphMaxHeight + glyphMaxHeight+1) / (etkFloat_t)textureHeight; listElement[iii].advance = slot->metrics.horiAdvance>>6;
listElement[iii].posStart.u = (etkFloat_t)(tmpRowStartPos) / (etkFloat_t)textureWidth;
listElement[iii].posStart.v = (etkFloat_t)(tmpLineStartPos) / (etkFloat_t)textureHeight;
listElement[iii].posStop.u = (etkFloat_t)(tmpRowStartPos + tmpWidth) / (etkFloat_t)textureWidth;
listElement[iii].posStop.v = (etkFloat_t)(tmpLineStartPos + tmpHeight+1) / (etkFloat_t)textureHeight;
// update the maximum of the line hight :
if (CurrentLineHigh<tmpHeight) {
CurrentLineHigh = tmpHeight;
}
// update the Bitmap position drawing :
tmpRowStartPos += tmpWidth;
} }
// Now We Just Setup Some Texture Parameters. // Now We Just Setup Some Texture Parameters.
glBindTexture( GL_TEXTURE_2D, textureId); glBindTexture( GL_TEXTURE_2D, textureId);
@ -493,7 +527,7 @@ int32_t ewol::GetDefaultFontId(void)
int32_t ewol::LoadFont(etk::String fontName, int32_t size) int32_t ewol::LoadFont(etk::String fontName, int32_t size)
{ {
// check if folder file // check if folder file
etk::String tmpFileName = s_currentFolderName + "/" + fontName + ".ttf"; etk::String tmpFileName = s_currentFolderName + "/" + fontName;
etk::File fileName(tmpFileName, etk::FILE_TYPE_DATA); etk::File fileName(tmpFileName, etk::FILE_TYPE_DATA);
if (false == fileName.Exist()) { if (false == fileName.Exist()) {
EWOL_ERROR("Font does not exist: \"" << fileName.GetCompleateName() << "\""); EWOL_ERROR("Font does not exist: \"" << fileName.GetCompleateName() << "\"");
@ -515,7 +549,7 @@ void ewol::UnloadFont(int32_t id)
} }
void ewol::DrawText(int32_t fontID, int32_t ewol::DrawText(int32_t fontID,
coord2D_ts & drawPosition, coord2D_ts & drawPosition,
coord2D_ts & clipSize, coord2D_ts & clipSize,
const char * utf8String, const char * utf8String,
@ -539,13 +573,14 @@ void ewol::DrawText(int32_t fontID,
*/ */
if(fontID>=m_listLoadedFont.Size() || fontID < 0) { if(fontID>=m_listLoadedFont.Size() || fontID < 0) {
EWOL_WARNING("try to display text with an fontID that does not existed " << fontID); EWOL_WARNING("try to display text with an fontID that does not existed " << fontID);
return; return 0;
} }
etk::VectorType<freeTypeFontElement_ts> & listOfElement = m_listLoadedFont[fontID]->GetRefOnElement(); etk::VectorType<freeTypeFontElement_ts> & listOfElement = m_listLoadedFont[fontID]->GetRefOnElement();
char * tmpVal = (char*)utf8String; char * tmpVal = (char*)utf8String;
fontTextureId = m_listLoadedFont[fontID]->GetOglId(); fontTextureId = m_listLoadedFont[fontID]->GetOglId();
int32_t size = m_listLoadedFont[fontID]->GetHeight(); int32_t size = m_listLoadedFont[fontID]->GetHeight();
int32_t fontSize = m_listLoadedFont[fontID]->GetSize();
etkFloat_t posDrawX = drawPosition.x; etkFloat_t posDrawX = drawPosition.x;
while(*tmpVal != 0) { while(*tmpVal != 0) {
@ -567,7 +602,7 @@ void ewol::DrawText(int32_t fontID,
// TODO : Update if possible the mapping // TODO : Update if possible the mapping
charIndex = 0; charIndex = 0;
} }
etkFloat_t sizeWidth = listOfElement[charIndex].width; etkFloat_t sizeWidth = listOfElement[charIndex].advance;
// check the clipping // check the clipping
if (clipSize.x>0 && posDrawX+sizeWidth > clipSize.x) { if (clipSize.x>0 && posDrawX+sizeWidth > clipSize.x) {
// TODO : Create a better clipping methode ... // TODO : Create a better clipping methode ...
@ -575,6 +610,38 @@ void ewol::DrawText(int32_t fontID,
} }
// 0x01 == 0x20 == ' '; // 0x01 == 0x20 == ' ';
if (tmpChar != 0x01) { if (tmpChar != 0x01) {
/* Bitmap position
* 0------1
* | |
* | |
* 3------2
*/
coord2D_ts bitmapDrawPos[4];
bitmapDrawPos[0].x = posDrawX + listOfElement[charIndex].bearing.x;
bitmapDrawPos[1].x = posDrawX + listOfElement[charIndex].bearing.x + listOfElement[charIndex].size.x;
bitmapDrawPos[2].x = posDrawX + listOfElement[charIndex].bearing.x + listOfElement[charIndex].size.x;
bitmapDrawPos[3].x = posDrawX + listOfElement[charIndex].bearing.x;
bitmapDrawPos[0].y = drawPosition.y + fontSize - listOfElement[charIndex].bearing.y;
bitmapDrawPos[1].y = drawPosition.y + fontSize - listOfElement[charIndex].bearing.y;
bitmapDrawPos[2].y = drawPosition.y + fontSize - listOfElement[charIndex].bearing.y + listOfElement[charIndex].size.y;
bitmapDrawPos[3].y = drawPosition.y + fontSize - listOfElement[charIndex].bearing.y + listOfElement[charIndex].size.y;
/* texture Position :
* 0------1
* | |
* | |
* 3------2
*/
texCoord_ts texturePos[4];
texturePos[0].u = listOfElement[charIndex].posStart.u;
texturePos[1].u = listOfElement[charIndex].posStop.u;
texturePos[2].u = listOfElement[charIndex].posStop.u;
texturePos[3].u = listOfElement[charIndex].posStart.u;
texturePos[0].v = listOfElement[charIndex].posStart.v;
texturePos[1].v = listOfElement[charIndex].posStart.v;
texturePos[2].v = listOfElement[charIndex].posStop.v;
texturePos[3].v = listOfElement[charIndex].posStop.v;
// NOTE : Android does not support the Quads elements ... // NOTE : Android does not support the Quads elements ...
/* Step 1 : /* Step 1 :
@ -585,21 +652,13 @@ void ewol::DrawText(int32_t fontID,
* *
*/ */
// set texture coordonates : // set texture coordonates :
coordTex.PushBack(listOfElement[charIndex].posStart); coordTex.PushBack(texturePos[0]);
texCoord_ts tmpTex; coordTex.PushBack(texturePos[1]);
tmpTex.u = listOfElement[charIndex].posStop.u; coordTex.PushBack(texturePos[2]);
tmpTex.v = listOfElement[charIndex].posStart.v;
coordTex.PushBack(tmpTex);
coordTex.PushBack(listOfElement[charIndex].posStop);
// set display positions : // set display positions :
coord2D_ts tmpCoord; coord.PushBack(bitmapDrawPos[0]);
tmpCoord.x = posDrawX; coord.PushBack(bitmapDrawPos[1]);
tmpCoord.y = drawPosition.y; coord.PushBack(bitmapDrawPos[2]);
coord.PushBack(tmpCoord);
tmpCoord.x = posDrawX + sizeWidth;
coord.PushBack(tmpCoord);
tmpCoord.y = drawPosition.y + size;
coord.PushBack(tmpCoord);
/* Step 2 : /* Step 2 :
* *
@ -608,28 +667,20 @@ void ewol::DrawText(int32_t fontID,
* ****** * ******
* ******** * ********
*/ */
// set texture coordonates : // set texture coordonates :
coordTex.PushBack(listOfElement[charIndex].posStart); coordTex.PushBack(texturePos[0]);
coordTex.PushBack(listOfElement[charIndex].posStop); coordTex.PushBack(texturePos[2]);
tmpTex.u = listOfElement[charIndex].posStart.u; coordTex.PushBack(texturePos[3]);
tmpTex.v = listOfElement[charIndex].posStop.v;
coordTex.PushBack(tmpTex);
// set display positions : // set display positions :
tmpCoord.x = posDrawX; coord.PushBack(bitmapDrawPos[0]);
tmpCoord.y = drawPosition.y; coord.PushBack(bitmapDrawPos[2]);
coord.PushBack(tmpCoord); coord.PushBack(bitmapDrawPos[3]);
tmpCoord.x = posDrawX + sizeWidth;
tmpCoord.y = drawPosition.y + size;
coord.PushBack(tmpCoord);
tmpCoord.x = posDrawX;
coord.PushBack(tmpCoord);
} }
posDrawX += sizeWidth; posDrawX += sizeWidth;
} }
int32_t sizeOut = posDrawX - drawPosition.x;
drawPosition.x = posDrawX; drawPosition.x = posDrawX;
return sizeOut;
} }
int32_t ewol::GetWidth(int32_t fontID, const char * utf8String) int32_t ewol::GetWidth(int32_t fontID, const char * utf8String)
@ -661,7 +712,7 @@ int32_t ewol::GetWidth(int32_t fontID, const char * utf8String)
// TODO : Update if possible the mapping // TODO : Update if possible the mapping
charIndex = 0; charIndex = 0;
} }
posDrawX += listOfElement[charIndex].width; posDrawX += listOfElement[charIndex].advance;
} }
return posDrawX; return posDrawX;
} }

View File

@ -81,21 +81,21 @@ void ewol::OObject2DTextColored::Draw(void)
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
void ewol::OObject2DTextColored::Text(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX) int32_t ewol::OObject2DTextColored::Text(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX)
{ {
m_coord.Clear(); m_coord.Clear();
m_coordTex.Clear(); m_coordTex.Clear();
m_coordColor.Clear(); m_coordColor.Clear();
// normal adding text : // normal adding text :
TextAdd(x, y, utf8String, clippingPositionX); return TextAdd(x, y, utf8String, clippingPositionX);
} }
void ewol::OObject2DTextColored::TextAdd(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX) int32_t ewol::OObject2DTextColored::TextAdd(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX)
{ {
m_FontTextureId = 0; m_FontTextureId = 0;
if (m_FontId == -1) { if (m_FontId == -1) {
EWOL_ERROR("Font Id is not corectly defined"); EWOL_ERROR("Font Id is not corectly defined");
return; return 0;
} }
coord2D_ts drawPosition; coord2D_ts drawPosition;
drawPosition.x = x; drawPosition.x = x;
@ -104,10 +104,11 @@ void ewol::OObject2DTextColored::TextAdd(etkFloat_t x, etkFloat_t y, const char*
clipSize.x = clippingPositionX; clipSize.x = clippingPositionX;
clipSize.y = -1; clipSize.y = -1;
int32_t nbElementInTheArray = m_coord.Size(); int32_t nbElementInTheArray = m_coord.Size();
ewol::DrawText(m_FontId, drawPosition, clipSize, utf8String, m_FontTextureId, m_coord, m_coordTex); int32_t size = ewol::DrawText(m_FontId, drawPosition, clipSize, utf8String, m_FontTextureId, m_coord, m_coordTex);
for (int32_t iii=nbElementInTheArray; iii<m_coord.Size(); iii++) { for (int32_t iii=nbElementInTheArray; iii<m_coord.Size(); iii++) {
m_coordColor.PushBack(m_color); m_coordColor.PushBack(m_color);
} }
return size;
} }
void ewol::OObject2DTextColored::UpdateOrigin(etkFloat_t x, etkFloat_t y) void ewol::OObject2DTextColored::UpdateOrigin(etkFloat_t x, etkFloat_t y)

View File

@ -39,8 +39,8 @@ namespace ewol {
void SetColor(etkFloat_t red, etkFloat_t green, etkFloat_t blue, etkFloat_t alpha = 1.0); void SetColor(etkFloat_t red, etkFloat_t green, etkFloat_t blue, etkFloat_t alpha = 1.0);
void SetColor(color_ts color); void SetColor(color_ts color);
// set a specific text // set a specific text
void Text(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX); int32_t Text(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX);
void TextAdd(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX); int32_t TextAdd(etkFloat_t x, etkFloat_t y, const char* utf8String, int32_t clippingPositionX);
protected: protected:
int32_t m_FontId; //!< font internal ID int32_t m_FontId; //!< font internal ID
color_ts m_color; //!< tmp text color ... color_ts m_color; //!< tmp text color ...