diff --git a/Sources/libagg b/Sources/libagg index 80585116..bfba3999 160000 --- a/Sources/libagg +++ b/Sources/libagg @@ -1 +1 @@ -Subproject commit 80585116ed17a8ead625d229e40ecef37783c7bb +Subproject commit bfba3999b5cee49bd9a556f51170193849228a46 diff --git a/Sources/libetk/etk/TypesCoordonate.h b/Sources/libetk/etk/TypesCoordonate.h index 58194322..0582c500 100644 --- a/Sources/libetk/etk/TypesCoordonate.h +++ b/Sources/libetk/etk/TypesCoordonate.h @@ -168,9 +168,18 @@ template class Vector2D --(*this); return result; } + + T QuadDist(void) + { + return x*x + y*y; + } + + T Dist(void) + { + return sqrt(x*x + y*y); + } }; - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////: template class Vector3D diff --git a/Sources/libewol/Linux.mk b/Sources/libewol/Linux.mk index 0493ba7b..510b1e81 100644 --- a/Sources/libewol/Linux.mk +++ b/Sources/libewol/Linux.mk @@ -28,10 +28,11 @@ LOCAL_CFLAGS := -Wno-write-strings \ -DEWOL_VERSION_TAG_NAME="\"$(LOCAL_VERSION_TAG_SHORT)-$(BUILD_DIRECTORY_MODE)\"" \ -Wall -ifdef CONFIG_EWOL_OPENGL_ES_V1 - LOCAL_CFLAGS += -D__VIDEO__OPENGL_ES_2 - LOCAL_EXPORT_CFLAGS := -D__VIDEO__OPENGL_ES_2 -endif +#ifdef CONFIG_EWOL_OPENGL_ES_V2 +LOCAL_CFLAGS += -D__VIDEO__OPENGL_ES_2 +LOCAL_EXPORT_CFLAGS := -D__VIDEO__OPENGL_ES_2 +$(info Compilation For openGL-ES-v2 compatibility) +#endif # load the common sources file of the platform include $(LOCAL_PATH)/file.mk diff --git a/Sources/libewol/ewol/ResourceManager.cpp b/Sources/libewol/ewol/ResourceManager.cpp index e4cee604..952505b4 100644 --- a/Sources/libewol/ewol/ResourceManager.cpp +++ b/Sources/libewol/ewol/ResourceManager.cpp @@ -234,6 +234,25 @@ bool ewol::resource::Keep(etk::UString& filename, ewol::Font*& object) } #endif +#ifdef __VIDEO__OPENGL_ES_2 + bool ewol::resource::Keep(etk::UString& filename, ewol::DistantFieldFont*& object) + { + EWOL_VERBOSE("KEEP : DistanceFieldFont : file : \"" << filename << "\""); + object = static_cast(LocalKeep(filename)); + if (NULL != object) { + return true; + } + // need to crate a new one ... + object = new ewol::DistantFieldFont(filename); + if (NULL == object) { + EWOL_ERROR("allocation error of a resource : " << filename); + return false; + } + LocalAdd(object); + return true; + } +#endif + bool ewol::resource::Keep(ewol::Texture*& object) { // this element create a new one every time .... @@ -333,6 +352,14 @@ void ewol::resource::Release(ewol::Font*& object) object = NULL; } #endif +#ifdef __VIDEO__OPENGL_ES_2 + void ewol::resource::Release(ewol::DistantFieldFont*& object) + { + ewol::Resource* object2 = static_cast(object); + Release(object2); + object = NULL; + } +#endif void ewol::resource::Release(ewol::Texture*& object) { ewol::Resource* object2 = static_cast(object); diff --git a/Sources/libewol/ewol/ResourceManager.h b/Sources/libewol/ewol/ResourceManager.h index 11297474..1ab4befb 100644 --- a/Sources/libewol/ewol/ResourceManager.h +++ b/Sources/libewol/ewol/ResourceManager.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,7 @@ namespace ewol #ifdef __VIDEO__OPENGL_ES_2 bool Keep(etk::UString& filename, ewol::Program*& object); bool Keep(etk::UString& filename, ewol::Shader*& object); + bool Keep(etk::UString& filename, ewol::DistantFieldFont*& object); #endif bool Keep(ewol::Texture*& object); // no name needed here ... bool Keep(etk::UString& filename, ewol::TextureFile*& object, Vector2D size); @@ -63,6 +65,7 @@ namespace ewol #ifdef __VIDEO__OPENGL_ES_2 void Release(ewol::Program*& object); void Release(ewol::Shader*& object); + void Release(ewol::DistantFieldFont*& object); #endif void Release(ewol::Texture*& object); void Release(ewol::TextureFile*& object); diff --git a/Sources/libewol/ewol/font/DistantFieldFont.cpp b/Sources/libewol/ewol/font/DistantFieldFont.cpp new file mode 100644 index 00000000..40dd071d --- /dev/null +++ b/Sources/libewol/ewol/font/DistantFieldFont.cpp @@ -0,0 +1,465 @@ +/** + ******************************************************************************* + * @file ewol/font/DistanceFieldFont.cpp + * @brief ewol Textured distant field Font system (Sources) + * @author Edouard DUPIN + * @date 22/08/2012 + * @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 + + +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; +} + + +ewol::DistantFieldFont::DistantFieldFont(etk::UString fontName) : + ewol::Texture(fontName), + m_font(NULL), + m_lastGlyphPos(0,0), + m_lastRawHeigh(0) +{ + int32_t tmpSize = 0; + // extarct name and size : + char * tmpData = fontName.c_str(); + char * tmpPos = strchr(tmpData, ':'); + + if (tmpPos==NULL) { + m_size = 1; + EWOL_CRITICAL("Can not parse the font name : \"" << fontName << "\" ??? ':' " ); + return; + } else { + if (sscanf(tmpPos+1, "%d", &tmpSize)!=1) { + m_size = 1; + EWOL_CRITICAL("Can not parse the font name : \"" << fontName << "\" ==> size ???"); + return; + } + } + m_name = fontName.Extract(0, (tmpPos - tmpData)); + m_size = tmpSize; + + //EWOL_CRITICAL("Load FONT name : \"" << m_name << "\" ==> size=" << m_size); + ewol::resource::Keep(m_name, m_font); + if (NULL == m_font) { + return; + } + + // set the bassic charset: + m_listElement.Clear(); + freeTypeFontElement_ts tmpchar1; + tmpchar1.property.m_UVal = 0; + m_listElement.PushBack(tmpchar1); + for (int32_t iii=0x20; iii<0xFF; iii++) { + freeTypeFontElement_ts tmpchar; + tmpchar.property.m_UVal = iii; + m_listElement.PushBack(tmpchar); + if (0x7F == iii) { + iii = 0x9F; + } + } + + /* this is a bad code for now ... */ + // ==> determine the texture Size + GlyphProperty tmpproperty; + tmpproperty.m_UVal = 'A'; + m_font->GetGlyphProperty(m_size, tmpproperty); + + int32_t nbElement = 0xFF - 0x20 + 1; + int32_t coter = simpleSQRT(nbElement); + // note : +1 is for the overlapping of the glyph (Part 1) + int32_t glyphMaxWidth = tmpproperty.m_advance.x +1; + int32_t glyphMaxHeight = tmpproperty.m_advance.y +1; + int32_t textureWidth = nextP2(coter*glyphMaxWidth); + int32_t nbRaws = textureWidth / glyphMaxWidth; + if (nbRaws <= 0) { + EWOL_ERROR("devide by 0"); + nbRaws = 1; + } + int32_t nbLine = (nbElement / nbRaws) + 1; + int32_t textureHeight = nextP2(nbLine*glyphMaxHeight); + // for android : + textureHeight = etk_max(textureHeight, textureWidth); + textureWidth = textureHeight; + + + EWOL_DEBUG("Generate a text texture for char(" << nbRaws << "," << nbLine << ") with size=(" << textureWidth << "," << textureHeight << ")"); + // resize must be done on the texture ... + SetImageSize(Vector2D(textureWidth,textureHeight)); + // now we can acces directly on the image + m_data.SetFillColor(draw::Color(0xFFFFFF00)); + m_data.Clear(); + + m_height = m_font->GetHeight(m_size); + + int32_t CurrentLineHigh = 0; + Vector2D glyphPosition(1,1); + for (int32_t iii=0; iiiGetGlyphProperty(m_size, m_listElement[iii].property)) { + /* + // check internal property: + // enought in the texture : + //if (m_data.GetWidth() < m_lastGlyphPos.x + m_listElement[iii].property.m_sizeTexture.x + // resize if needed ... + + // line size : + + // draw + + // move the curent pointer of drawing: + */ + // change line if needed ... + if (glyphPosition.x+m_listElement[iii].property.m_sizeTexture.x > textureWidth) { + glyphPosition.x = 0; + glyphPosition.y += CurrentLineHigh; + CurrentLineHigh = 0; + } + // draw the glyph + m_font->DrawGlyph(m_data, m_size, glyphPosition, m_listElement[iii].property); + // set video position + m_listElement[iii].posStart.u = (float)(glyphPosition.x) / (float)textureWidth; + m_listElement[iii].posStart.v = (float)(glyphPosition.y) / (float)textureHeight; + m_listElement[iii].posStop.u = (float)(glyphPosition.x + m_listElement[iii].property.m_sizeTexture.x) / (float)textureWidth; + m_listElement[iii].posStop.v = (float)(glyphPosition.y + m_listElement[iii].property.m_sizeTexture.y) / (float)textureHeight; + /* + EWOL_DEBUG("generate '" << (char)m_listElement[iii].property.m_UVal << "'"); + EWOL_DEBUG(" in tex : " << glyphPosition << " ==> " << m_listElement[iii].posStart.u<< "," << m_listElement[iii].posStart.v ); + EWOL_DEBUG(" m_sizeTexture =" << m_listElement[iii].property.m_sizeTexture ); + EWOL_DEBUG(" m_bearing =" << m_listElement[iii].property.m_bearing ); + EWOL_DEBUG(" m_advance =" << m_listElement[iii].property.m_advance ); + */ + + // update the maximum of the line hight : + if (CurrentLineHigh(iii, jjj) ); + // set only alpha : + tlpppp.a = etk_min( tlpppp.a+0x60, 0xFF); + // real set of color + m_data.Set(Vector2D(iii, jjj), tlpppp ); + } + } + #endif + EWOL_DEBUG("End generation of the Fond bitmap, start adding texture"); + // generate the distance field from this element ... + m_data.DistanceField(); + Flush(); + +} + +ewol::DistantFieldFont::~DistantFieldFont(void) +{ + if (NULL!= m_font) { + ewol::resource::Release(m_font); + } +} + + +bool ewol::DistantFieldFont::HasName(etk::UString& fileName) +{ + etk::UString tmpName = m_name; + tmpName += ":"; + tmpName += m_size; + EWOL_VERBOSE("S : check : " << fileName << " ?= " << tmpName << " = " << (fileName==tmpName) ); + return (fileName==tmpName); +} + + + +int32_t ewol::DistantFieldFont::Draw(Vector2D textPos, + const etk::UString& unicodeString, + etk::Vector > & coord, + etk::Vector & coordTex) +{ + float totalSize = 0; + Vector2D tmpPos = textPos; + for(int32_t iii=0; iii bitmapDrawPos[4]; + bitmapDrawPos[0].x = 10; + bitmapDrawPos[1].x = 400; + bitmapDrawPos[2].x = 400; + bitmapDrawPos[3].x = 10; + + bitmapDrawPos[0].y = 400; + bitmapDrawPos[1].y = 400; + bitmapDrawPos[2].y = 10; + bitmapDrawPos[3].y = 10; + /* texture Position : + * 0------1 + * | | + * | | + * 3------2 + */ + texCoord_ts texturePos[4]; + texturePos[0].u = 0; + texturePos[1].u = 1; + texturePos[2].u = 1; + texturePos[3].u = 0; + + texturePos[0].v = 0; + texturePos[1].v = 0; + texturePos[2].v = 1; + texturePos[3].v = 1; + + // NOTE : Android does not support the Quads elements ... + /* Step 1 : + * ******** + * ****** + * **** + * ** + * + */ + // set texture coordonates : + coordTex.PushBack(texturePos[0]); + coordTex.PushBack(texturePos[1]); + coordTex.PushBack(texturePos[2]); + // set display positions : + coord.PushBack(bitmapDrawPos[0]); + coord.PushBack(bitmapDrawPos[1]); + coord.PushBack(bitmapDrawPos[2]); + + /* Step 2 : + * + * ** + * **** + * ****** + * ******** + */ + // set texture coordonates : + coordTex.PushBack(texturePos[0]); + coordTex.PushBack(texturePos[2]); + coordTex.PushBack(texturePos[3]); + // set display positions : + coord.PushBack(bitmapDrawPos[0]); + coord.PushBack(bitmapDrawPos[2]); + coord.PushBack(bitmapDrawPos[3]); + } + #endif + return totalSize; +} + +int32_t ewol::DistantFieldFont::Draw(Vector2D textPos, + const uniChar_t unicodeChar, + etk::Vector > & coord, + etk::Vector & coordTex) +{ + float posDrawX = textPos.x; + + int32_t charIndex; + if (unicodeChar < 0x20) { + charIndex = 0; + } else if (unicodeChar < 0x80) { + charIndex = unicodeChar - 0x1F; + } else { + charIndex = 0; + for (int32_t iii=0x80-0x20; iii < m_listElement.Size(); iii++) { + if (m_listElement[iii].property.m_UVal == unicodeChar) { + charIndex = iii; + break; + } + } + } + // 0x01 == 0x20 == ' '; + if (unicodeChar != 0x01) { + /* Bitmap position + * xA xB + * yC *------* + * | | + * | | + * yD *------* + */ + float dxA = posDrawX + m_listElement[charIndex].property.m_bearing.x; + float dxB = posDrawX + m_listElement[charIndex].property.m_bearing.x + m_listElement[charIndex].property.m_sizeTexture.x; + float dyC = textPos.y + m_listElement[charIndex].property.m_bearing.y + m_height - m_size; + float dyD = dyC - m_listElement[charIndex].property.m_sizeTexture.y; + + float tuA = m_listElement[charIndex].posStart.u; + float tuB = m_listElement[charIndex].posStop.u; + float tvC = m_listElement[charIndex].posStart.v; + float tvD = m_listElement[charIndex].posStop.v; + + + // Clipping and drawing area + if( dxB <= dxA + || dyD >= dyC) { + // nothing to do ... + } else { + /* Bitmap position + * 0------1 + * | | + * | | + * 3------2 + */ + Vector2D bitmapDrawPos[4]; + bitmapDrawPos[0].x = (int32_t)dxA; + bitmapDrawPos[1].x = (int32_t)dxB; + bitmapDrawPos[2].x = (int32_t)dxB; + bitmapDrawPos[3].x = (int32_t)dxA; + + bitmapDrawPos[0].y = (int32_t)dyC; + bitmapDrawPos[1].y = (int32_t)dyC; + bitmapDrawPos[2].y = (int32_t)dyD; + bitmapDrawPos[3].y = (int32_t)dyD; + /* texture Position : + * 0------1 + * | | + * | | + * 3------2 + */ + texCoord_ts texturePos[4]; + texturePos[0].u = tuA; + texturePos[1].u = tuB; + texturePos[2].u = tuB; + texturePos[3].u = tuA; + + texturePos[0].v = tvC; + texturePos[1].v = tvC; + texturePos[2].v = tvD; + texturePos[3].v = tvD; + + // NOTE : Android does not support the Quads elements ... + /* Step 1 : + * ******** + * ****** + * **** + * ** + * + */ + // set texture coordonates : + coordTex.PushBack(texturePos[0]); + coordTex.PushBack(texturePos[1]); + coordTex.PushBack(texturePos[2]); + // set display positions : + coord.PushBack(bitmapDrawPos[0]); + coord.PushBack(bitmapDrawPos[1]); + coord.PushBack(bitmapDrawPos[2]); + + /* Step 2 : + * + * ** + * **** + * ****** + * ******** + */ + // set texture coordonates : + coordTex.PushBack(texturePos[0]); + coordTex.PushBack(texturePos[2]); + coordTex.PushBack(texturePos[3]); + // set display positions : + coord.PushBack(bitmapDrawPos[0]); + coord.PushBack(bitmapDrawPos[2]); + coord.PushBack(bitmapDrawPos[3]); + + } + } + posDrawX += m_listElement[charIndex].property.m_advance.x; + int32_t sizeOut = posDrawX - textPos.x; + textPos.x = posDrawX; + return sizeOut; +} + +Vector2D ewol::DistantFieldFont::GetSize(const etk::UString & unicodeString) +{ + Vector2D outputSize(0,m_height); + for(int32_t iii=0; iii tmpp = GetSize(unicodeString[iii]); + outputSize.x += tmpp.x; + } + return outputSize; +} + + +Vector2D ewol::DistantFieldFont::GetSize(const uniChar_t unicodeChar) +{ + Vector2D outputSize(0,m_height); + int32_t charIndex; + if (unicodeChar >= 0x80) { + charIndex = 0; + } else if (unicodeChar < 0x20) { + charIndex = 0; + } else if (unicodeChar < 0x80) { + charIndex = unicodeChar - 0x1F; + } else { + for (int32_t iii=0x80-0x20; iii < m_listElement.Size(); iii++) { + if (m_listElement[iii].property.m_UVal == unicodeChar) { + charIndex = iii; + break; + } + } + // TODO : Update if possible the mapping + charIndex = 0; + } + outputSize.x = m_listElement[charIndex].property.m_advance.x; + return outputSize; +} + + diff --git a/Sources/libewol/ewol/font/DistantFieldFont.h b/Sources/libewol/ewol/font/DistantFieldFont.h new file mode 100644 index 00000000..3439bb34 --- /dev/null +++ b/Sources/libewol/ewol/font/DistantFieldFont.h @@ -0,0 +1,76 @@ +/** + ******************************************************************************* + * @file ewol/font/TexturedFont.h + * @brief ewol Textured Font system (header) + * @author Edouard DUPIN + * @date 22/08/2012 + * @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. + * + ******************************************************************************* + */ + + + +#ifndef __EWOL_DISTANT_FIELD_FONT_H__ +#define __EWOL_DISTANT_FIELD_FONT_H__ + +#include +#include +#include + +namespace ewol +{ + class DistantFieldFont : public ewol::Texture { + + typedef struct { + GlyphProperty property; + texCoord_ts posStart; + texCoord_ts posStop; + }freeTypeFontElement_ts; + private: + int32_t m_size; + int32_t m_height; + ewol::Font* m_font; + etk::Vector m_listElement; + // for the texture generation : + Vector2D m_lastGlyphPos; + int32_t m_lastRawHeigh; + public: + DistantFieldFont(etk::UString fontName); + ~DistantFieldFont(void); + virtual bool HasName(etk::UString& fileName); + const char* GetType(void) { return "ewol::TexturedFont"; }; + int32_t getFontSize(void) { return m_size; }; + int32_t Draw(Vector2D textPos, + const etk::UString& unicodeString, + etk::Vector > & coord, + etk::Vector & coordTex); + int32_t Draw(Vector2D textPos, + const uniChar_t unicodeChar, + etk::Vector > & coord, + etk::Vector & coordTex); + Vector2D GetSize(const etk::UString & unicodeString); + Vector2D GetSize(const uniChar_t unicodeChar); + // TODO : Remove this element, it is stupid ... + int32_t GetHeight(void) { return m_height; }; + int32_t GetFontSize(void) { return m_size; }; + }; + + +}; + +#endif + diff --git a/Sources/libewol/ewol/font/TexturedFont.cpp b/Sources/libewol/ewol/font/TexturedFont.cpp index ac93b3aa..a43d494c 100644 --- a/Sources/libewol/ewol/font/TexturedFont.cpp +++ b/Sources/libewol/ewol/font/TexturedFont.cpp @@ -196,11 +196,8 @@ ewol::TexturedFont::TexturedFont(etk::UString fontName) : } #endif EWOL_DEBUG("End generation of the Fond bitmap, start adding texture"); + //m_data.DistanceField(); Flush(); - - // initilize the texture ... - // TODO : Do a better methode that not initialize with a stupid language ... like now ... - //m_font->GenerateBitmapFont(m_size, m_height, m_texture, m_listElement); } ewol::TexturedFont::~TexturedFont(void) diff --git a/Sources/libewol/ewol/oObject/2DTextShader.cpp b/Sources/libewol/ewol/oObject/2DTextShader.cpp new file mode 100644 index 00000000..e4d093d0 --- /dev/null +++ b/Sources/libewol/ewol/oObject/2DTextShader.cpp @@ -0,0 +1,223 @@ +/** + ******************************************************************************* + * @file ewol/oObject/2DTextColored.cpp + * @brief ewol OpenGl Object system (Sources) + * @author Edouard DUPIN + * @date 16/01/2012 + * @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 + +#undef __class__ +#define __class__ "ewol::OObject2DTextShader" + +void ewol::OObject2DTextShader::SetFontProperty(etk::UString fontName, int32_t fontSize) +{ + // remove old one + if (NULL != m_font) { + ewol::resource::Release(m_font); + m_font = NULL; + } + etk::UString tmpName = fontName; + tmpName += ":"; + tmpName += fontSize; + // link to new One + if (false == ewol::resource::Keep(tmpName, m_font)) { + EWOL_ERROR("Can not get font resource"); + } +} + +void ewol::OObject2DTextShader::SetFont(etk::UString fontName) +{ + // get old size + int32_t fontSize = ewol::font::GetDefaultSize(); + if (NULL != m_font) { + fontSize = m_font->GetFontSize(); + } + SetFontProperty(fontName, fontSize); +} + +void ewol::OObject2DTextShader::SetSize(int32_t fontSize) +{ + // get old size + etk::UString fontName = ewol::font::GetDefaultFont(); + if (NULL != m_font) { + fontName = m_font->GetName(); + } + SetFontProperty(fontName, fontSize); +} + +ewol::OObject2DTextShader::OObject2DTextShader(etk::UString fontName, int32_t size) : + m_font(NULL) +{ + m_color = draw::color::black; + SetFontProperty(fontName, size); + etk::UString tmpString("fontDistanceField/font1.prog"); + // get the shader resource : + m_GLPosition = 0; + if (true == ewol::resource::Keep(tmpString, m_GLprogram) ) { + m_GLPosition = m_GLprogram->GetAttribute("EW_coord2d"); + m_GLColor = m_GLprogram->GetAttribute("EW_color"); + m_GLtexture = m_GLprogram->GetAttribute("EW_texture2d"); + m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation"); + m_GLtexID = m_GLprogram->GetUniform("EW_texID"); + } +} + + +// open with default font ... +ewol::OObject2DTextShader::OObject2DTextShader(void) : + m_font(NULL) +{ + m_color = draw::color::black; + SetFontProperty(ewol::font::GetDefaultFont(), ewol::font::GetDefaultSize()); + etk::UString tmpString("fontDistanceField/font1.prog"); + // get the shader resource : + m_GLPosition = 0; + if (true == ewol::resource::Keep(tmpString, m_GLprogram) ) { + m_GLPosition = m_GLprogram->GetAttribute("EW_coord2d"); + m_GLColor = m_GLprogram->GetAttribute("EW_color"); + m_GLtexture = m_GLprogram->GetAttribute("EW_texture2d"); + m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation"); + m_GLtexID = m_GLprogram->GetUniform("EW_texID"); + } +} + + +ewol::OObject2DTextShader::~OObject2DTextShader(void) +{ + if (NULL != m_font) { + ewol::resource::Release(m_font); + m_font = NULL; + } + ewol::resource::Release(m_GLprogram); +} + +void ewol::OObject2DTextShader::Draw(void) +{ + if (m_coord.Size()<=0 || NULL == m_font) { + // TODO : a remètre ... + //EWOL_WARNING("Nothink to draw..."); + return; + } + if (m_font == NULL) { + EWOL_WARNING("no font..."); + return; + } + if (m_GLprogram==NULL) { + EWOL_ERROR("No shader ..."); + return; + } + m_GLprogram->Use(); + // set Matrix : translation/positionMatrix + etk::Matrix tmpMatrix = ewol::openGL::GetMatrix(); + m_GLprogram->SendUniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat); + // TextureID + m_GLprogram->SetTexture0(m_GLtexID, m_font->GetId()); + // position : + m_GLprogram->SendAttribute(m_GLPosition, 2/*x,y*/, &m_coord[0]); + // Texture : + m_GLprogram->SendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]); + // color : + m_GLprogram->SendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + // Request the draw od the elements : + glDrawArrays(GL_TRIANGLES, 0, m_coord.Size()); + m_GLprogram->UnUse(); +} + +void ewol::OObject2DTextShader::Clear(void) +{ + m_coord.Clear(); + m_coordTex.Clear(); + m_coordColor.Clear(); +} + +int32_t ewol::OObject2DTextShader::Text(Vector2D textPos, const etk::UString& unicodeString) +{ + if (m_font == NULL) { + EWOL_ERROR("Font Id is not corectly defined"); + return 0; + } + int32_t nbElementInTheArray = m_coord.Size(); + int32_t size = 0; + if (true==m_hasClipping) { + size = m_font->Draw(textPos, unicodeString, m_coord, m_coordTex); + } else { + size = m_font->Draw(textPos, unicodeString, m_coord, m_coordTex); + } + // set the color ... + for (int32_t iii=nbElementInTheArray; iii textPos, const uniChar_t unicodeChar) +{ + if (m_font == NULL) { + EWOL_ERROR("Font Id is not corectly defined"); + return 0; + } + int32_t nbElementInTheArray = m_coord.Size(); + int32_t size = 0; + if (true==m_hasClipping) { + size = m_font->Draw(textPos, unicodeChar, m_coord, m_coordTex); + } else { + size = m_font->Draw(textPos, unicodeChar, m_coord, m_coordTex); + } + for (int32_t iii=nbElementInTheArray; iii ewol::OObject2DTextShader::GetSize(const uniChar_t unicodeChar) +{ + if (m_font == NULL) { + EWOL_ERROR("Font Id is not corectly defined"); + return Vector2D(0,0); + } + return m_font->GetSize(unicodeChar); +} + +Vector2D ewol::OObject2DTextShader::GetSize(const etk::UString& unicodeString) +{ + if (m_font == NULL) { + EWOL_ERROR("Font Id is not corectly defined"); + return Vector2D(0,0); + } + return m_font->GetSize(unicodeString); +} + diff --git a/Sources/libewol/ewol/oObject/2DTextShader.h b/Sources/libewol/ewol/oObject/2DTextShader.h new file mode 100644 index 00000000..68f20aba --- /dev/null +++ b/Sources/libewol/ewol/oObject/2DTextShader.h @@ -0,0 +1,70 @@ +/** + ******************************************************************************* + * @file ewol/oObject/2DTextColored.h + * @brief ewol OpenGl Object system (header) + * @author Edouard DUPIN + * @date 16/01/2012 + * @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. + * + ******************************************************************************* + */ + +#ifndef __EWOL_O_OBJECT_2D_TEXT_SHADER_H__ +#define __EWOL_O_OBJECT_2D_TEXT_SHADER_H__ + +#include +#include +#include + +namespace ewol { + class OObject2DTextShader :public ewol::OObject + { + public: + OObject2DTextShader(etk::UString FontName, int32_t size); + OObject2DTextShader(void); + virtual ~OObject2DTextShader(void); + public: + virtual void Draw(void); + void SetColor(float red, float green, float blue, float alpha = 1.0); + void SetColor(draw::Color color); + // set a specific text + void Clear(void); + int32_t Text(Vector2D textPos, const etk::UString& unicodeString); + int32_t Text(Vector2D textPos, const uniChar_t unicodeChar); + protected: + ewol::Program* m_GLprogram; + int32_t m_GLPosition; + int32_t m_GLMatrix; + int32_t m_GLColor; + int32_t m_GLtexture; + int32_t m_GLtexID; + ewol::DistantFieldFont* m_font; //!< ewol font system + draw::Color m_color; //!< tmp text color ... + etk::Vector > m_coord; //!< internal coord of the object + etk::Vector m_coordTex; //!< internal texture coordinate for every point + etk::Vector m_coordColor; //!< internal color of the different point + public: + void SetFont(etk::UString fontName); + void SetSize(int32_t fontSize); + void SetFontProperty(etk::UString fontName, int32_t fontSize); + int32_t GetHeight(void) { return (NULL!=m_font)?m_font->GetHeight():10; }; + Vector2D GetSize(const uniChar_t unicodeChar); + Vector2D GetSize(const etk::UString& unicodeString); + }; +}; + +#endif + diff --git a/Sources/libewol/ewol/oObject/OObject.h b/Sources/libewol/ewol/oObject/OObject.h index 9003eb45..196539ab 100644 --- a/Sources/libewol/ewol/oObject/OObject.h +++ b/Sources/libewol/ewol/oObject/OObject.h @@ -75,3 +75,6 @@ namespace ewol { #include #include +#ifdef __VIDEO__OPENGL_ES_2 +#include +#endif diff --git a/Sources/libewol/file.mk b/Sources/libewol/file.mk index 6f3914f9..4d85456a 100644 --- a/Sources/libewol/file.mk +++ b/Sources/libewol/file.mk @@ -27,6 +27,7 @@ FILE_LIST+= ewol/game/GameElement.cpp \ # Object abstraction for OpenGl FILE_LIST+= ewol/oObject/OObject.cpp \ ewol/oObject/2DTextColored.cpp \ + ewol/oObject/2DTextShader.cpp \ ewol/oObject/2DColored.cpp \ ewol/oObject/2DTextured.cpp \ ewol/oObject/3DTextured.cpp \ @@ -42,7 +43,8 @@ FILE_LIST+= ewol/texture/Texture.cpp \ # fonst system FILE_LIST+= ewol/font/FontManager.cpp \ ewol/font/FontFreeType.cpp \ - ewol/font/TexturedFont.cpp + ewol/font/TexturedFont.cpp \ + ewol/font/DistantFieldFont.cpp # all widgets FILE_LIST+= ewol/widget/Widget.cpp \ diff --git a/share/fontDistanceField/font1.frag b/share/fontDistanceField/font1.frag new file mode 100644 index 00000000..d6b403dd --- /dev/null +++ b/share/fontDistanceField/font1.frag @@ -0,0 +1,26 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +// Input : +uniform sampler2D EW_texID; + +varying vec2 f_texcoord; +varying vec4 f_color; + +void main(void) { + vec4 tmpcolor = texture2D(EW_texID, f_texcoord); + vec4 outColor = vec4(0,0,0,0); + // compare distance with 0.5 that represent the middle ... + if (tmpcolor[3]>0.5) { + outColor = f_color; + outColor[3] = 1.0; + } else if (tmpcolor[3]>0.49) { + // antialiasing : + outColor = f_color; + outColor[3] = (tmpcolor[3]-0.49)*1.0/0.02; + } + gl_FragColor = outColor; +} + diff --git a/share/fontDistanceField/font1.prog b/share/fontDistanceField/font1.prog new file mode 100644 index 00000000..a34383fc --- /dev/null +++ b/share/fontDistanceField/font1.prog @@ -0,0 +1,2 @@ +fontDistanceField/font1.vert +fontDistanceField/font1.frag \ No newline at end of file diff --git a/share/fontDistanceField/font1.vert b/share/fontDistanceField/font1.vert new file mode 100644 index 00000000..d975573d --- /dev/null +++ b/share/fontDistanceField/font1.vert @@ -0,0 +1,42 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +// Input : +attribute vec2 EW_coord2d; +attribute vec2 EW_texture2d; +attribute vec4 EW_color; +uniform mat4 EW_MatrixTransformation; + +// output : +varying vec4 f_color; +varying vec2 f_texcoord; + +void main(void) { + gl_Position = EW_MatrixTransformation * vec4(EW_coord2d, 0.0, 1.0); + // set texture output coord + f_texcoord = EW_texture2d; + // set output color : + f_color = EW_color; +} + +/* +// Distance map contour texturing according to Green (2007), +// implementation by Stefan Gustavson 2009. +// This code is in the public domain. + +uniform sampler2D gradtexture, reftexture; +uniform float texw, texh; +varying float onestepu, onestepv; +varying vec2 st; + +void main( void ) +{ + // Get the texture coordinates + st = gl_MultiTexCoord0.xy; + onestepu = 1.0 / texw; // Saves a division in the fragment shader + onestepv = 1.0 / texh; + gl_Position = ftransform(); +} +*/ diff --git a/share/fontDistanceField/font2.frag b/share/fontDistanceField/font2.frag new file mode 100644 index 00000000..ba7f9448 --- /dev/null +++ b/share/fontDistanceField/font2.frag @@ -0,0 +1,57 @@ +// Distance map contour texturing, Stefan Gustavson 2009 +// A re-implementation of Green's method, with an +// 8-bit distance map but explicit texel interpolation. +// This code is in the public domain. + +uniform sampler2D disttexture, reftexture; +uniform float texw, texh; +varying float onestepu, onestepv; +varying vec2 st; + +void main( void ) +{ + // Scale texcoords to range ([0,texw], [0,texh]) + vec2 uv = st * vec2(texw, texh); + + // Compute texel-local (u,v) coordinates for the four closest texels + vec2 uv00 = floor(uv - vec2(0.5)); // Lower left corner of lower left texel + vec2 uvthis = floor(uv); // Lower left corner of texel containing (u,v) + vec2 uvlerp = uv - uv00 - vec2(0.5); // Texel-local lerp blends [0,1] + + // Perform explicit texture interpolation of D coefficient. + // This works around the currently very bad texture interpolation + // precision in ATI hardware. + + // Center st00 on lower left texel and rescale to [0,1] for texture lookup + vec2 st00 = (uv00 + vec2(0.5)) * vec2(onestepu, onestepv); + + // Compute g_u, g_v, D coefficients from four closest 8-bit RGBA texels + vec4 rawtex00 = texture2D(disttexture, st00); + vec4 rawtex10 = texture2D(disttexture, st00 + vec2(0.5*onestepu, 0.0)); + vec4 rawtex01 = texture2D(disttexture, st00 + vec2(0.0, 0.5*onestepv)); + vec4 rawtex11 = texture2D(disttexture, st00 + vec2(0.5*onestepu, 0.5*onestepv)); + + // Restore the value for D from its 8-bit encoding + vec2 D00_10 = 16.0*(vec2(rawtex00.r, rawtex10.r)-0.50196); + vec2 D01_11 = 16.0*(vec2(rawtex01.r, rawtex11.r)-0.50196); + + // Interpolate D between four closest texels + vec2 uvlocal = fract(uv)-0.5; // Texel-local uv coordinates [-0.5,0.5] + // Interpolate along v + vec2 D0_1 = mix(D00_10, D01_11, uvlerp.y); + // Interpolate along u + float D = mix(D0_1.x, D0_1.y, uvlerp.x); + + // Perform anisotropic analytic antialiasing (fwidth() is slightly wrong) + float aastep = length(vec2(dFdx(D), dFdy(D))); + + // 'pattern' is 1 where D>0, 0 where D<0, with proper AA around D=0. + float pattern = smoothstep(-aastep, aastep, D); + + // 'bitmap' is a regular grayscale texture with AA for comparison. + vec2 uvoffset = uvthis - uv00; // 0 or 1 depending on (u,v) quadrant + float bitmap = texture2D(reftexture, st00+uvoffset*vec2(onestepu, onestepv)).r; + + // Final fragment color + gl_FragColor = vec4(bitmap, pattern, bitmap, 1.0); +}