From 6fcff69f11b27f1f94627ab8a3a511b7343dcad0 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 14 Jan 2014 21:50:21 +0100 Subject: [PATCH] [DEV] distance field developement --- data/fontDistanceField/font1.frag | 10 +- data/text.vert | 4 +- sources/ewol/compositing/Area.cpp | 6 +- sources/ewol/compositing/Drawing.cpp | 4 +- sources/ewol/compositing/Image.cpp | 6 +- sources/ewol/compositing/Text.cpp | 1123 +------------------ sources/ewol/compositing/Text.h | 450 +------- sources/ewol/compositing/TextBase.cpp | 1109 ++++++++++++++++++ sources/ewol/compositing/TextBase.h | 470 ++++++++ sources/ewol/compositing/TextBasic.cpp | 0 sources/ewol/compositing/TextBasic.h | 0 sources/ewol/compositing/TextDF.cpp | 196 +++- sources/ewol/compositing/TextDF.h | 8 +- sources/ewol/resource/DistanceFieldFont.cpp | 30 +- sources/ewol/resource/DistanceFieldFont.h | 13 +- sources/ewol/resource/Program.cpp | 2 +- sources/ewol/resource/Program.h | 12 +- sources/ewol/resource/font/GlyphProperty.h | 18 +- sources/ewol/widget/ButtonColor.cpp | 2 +- sources/ewol/widget/Label.cpp | 6 +- sources/lutin_ewol.py | 1 + 21 files changed, 1873 insertions(+), 1597 deletions(-) create mode 100644 sources/ewol/compositing/TextBase.cpp create mode 100644 sources/ewol/compositing/TextBase.h create mode 100644 sources/ewol/compositing/TextBasic.cpp create mode 100644 sources/ewol/compositing/TextBasic.h diff --git a/data/fontDistanceField/font1.frag b/data/fontDistanceField/font1.frag index fda03013..193bc1ed 100644 --- a/data/fontDistanceField/font1.frag +++ b/data/fontDistanceField/font1.frag @@ -12,15 +12,15 @@ uniform int EW_SoftEdge; varying vec2 f_texcoord; varying vec4 f_color; - vec3 glyph_color = vec3(1.0,1.0,1.0); const float glyph_center = 0.50; - vec3 outline_color = vec3(0.0,0.0,0.0); const float outline_center = 0.55; - vec3 glow_color = vec3(1.0,1.0,1.0); const float glow_center = 1.25; +vec3 glyph_color = vec3(1.0,1.0,1.0); +vec3 outline_color = vec3(0.0,0.0,0.0); +vec3 glow_color = vec3(0.0,1.0,0.0); + void main(void) { - //vec4 color = texture2D(EW_texID, vec2(int(f_texcoord[0]*256.0)/256.0,int(f_texcoord[1]*256.0)/256.0) ); vec4 color = texture2D(EW_texID, f_texcoord ); float dist = color.r; float width = fwidth(dist); @@ -28,7 +28,7 @@ void main(void) { // Smooth - gl_FragColor = vec4(glyph_color, alpha); + gl_FragColor = vec4(f_color[0], f_color[1], f_color[2], f_color[3]*alpha); // Outline /* diff --git a/data/text.vert b/data/text.vert index 83dc9b3f..c06eb71b 100644 --- a/data/text.vert +++ b/data/text.vert @@ -4,7 +4,7 @@ precision mediump int; #endif // Input : -attribute vec2 EW_coord2d; +attribute vec3 EW_coord3d; attribute vec2 EW_texture2d; attribute vec4 EW_color; uniform mat4 EW_MatrixTransformation; @@ -24,7 +24,7 @@ void main(void) { */ varying vec4 f_patern; void main(void) { - gl_Position = EW_MatrixTransformation * vec4(EW_coord2d, 0.0, 1.0); + gl_Position = EW_MatrixTransformation * vec4(EW_coord3d, 1.0); //gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(EW_coord2d, 0.0, 1.0); // set output color : f_color = EW_color; diff --git a/sources/ewol/compositing/Area.cpp b/sources/ewol/compositing/Area.cpp index f5a2eb51..c15f1851 100644 --- a/sources/ewol/compositing/Area.cpp +++ b/sources/ewol/compositing/Area.cpp @@ -66,11 +66,11 @@ void ewol::compositing::Area::draw(bool _disableDepthTest) { // TextureID m_GLprogram->setTexture0(m_GLtexID, m_resource->getId()); // position : - m_GLprogram->sendAttribute(m_GLPosition, 3/*x,y,z,unused*/, &m_coord[0], 4*sizeof(btScalar)); + m_GLprogram->sendAttribute(m_GLPosition, m_coord); // Texture : - m_GLprogram->sendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]); + m_GLprogram->sendAttribute(m_GLtexture, m_coordTex); // color : - m_GLprogram->sendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + m_GLprogram->sendAttribute(m_GLColor, m_coordColor); // Request the draw od the elements : ewol::openGL::drawArrays(GL_TRIANGLES, 0, m_coord.size()); m_GLprogram->unUse(); diff --git a/sources/ewol/compositing/Drawing.cpp b/sources/ewol/compositing/Drawing.cpp index a7c8785a..df6756f4 100644 --- a/sources/ewol/compositing/Drawing.cpp +++ b/sources/ewol/compositing/Drawing.cpp @@ -308,9 +308,9 @@ void ewol::compositing::Drawing::draw(bool _disableDepthTest) { m_GLprogram->use(); m_GLprogram->uniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat); // position : - m_GLprogram->sendAttribute(m_GLPosition, 3/*x,y,z,unused*/, &m_coord[0], 4*sizeof(btScalar)); + m_GLprogram->sendAttribute(m_GLPosition, m_coord); // color : - m_GLprogram->sendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + m_GLprogram->sendAttribute(m_GLColor, m_coordColor); // Request the draw od the elements : ewol::openGL::drawArrays(GL_TRIANGLES, 0, m_coord.size()); m_GLprogram->unUse(); diff --git a/sources/ewol/compositing/Image.cpp b/sources/ewol/compositing/Image.cpp index 995ff4a0..51df0d95 100644 --- a/sources/ewol/compositing/Image.cpp +++ b/sources/ewol/compositing/Image.cpp @@ -73,11 +73,11 @@ void ewol::compositing::Image::draw(bool _disableDepthTest) { // TextureID m_GLprogram->setTexture0(m_GLtexID, m_resource->getId()); // position : - m_GLprogram->sendAttribute(m_GLPosition, 3/*x,y,z,unused*/, &m_coord[0], 4*sizeof(btScalar)); + m_GLprogram->sendAttribute(m_GLPosition, m_coord); // Texture : - m_GLprogram->sendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]); + m_GLprogram->sendAttribute(m_GLtexture, m_coordTex); // color : - m_GLprogram->sendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + m_GLprogram->sendAttribute(m_GLColor, m_coordColor); // Request the draw od the elements : ewol::openGL::drawArrays(GL_TRIANGLES, 0, m_coord.size()); m_GLprogram->unUse(); diff --git a/sources/ewol/compositing/Text.cpp b/sources/ewol/compositing/Text.cpp index 5397b61c..78fb5039 100644 --- a/sources/ewol/compositing/Text.cpp +++ b/sources/ewol/compositing/Text.cpp @@ -15,54 +15,14 @@ #define __class__ "ewol::compositing::Text" -ewol::compositing::Text::Text(const std::string& _fontName, int32_t _fontSize, bool _tmpInit) : - m_position(0.0, 0.0, 0.0), - m_clippingPosStart(0.0, 0.0, 0.0), - m_clippingPosStop(0.0, 0.0, 0.0), - m_clippingEnable(false), - m_color(etk::color::black), - m_colorBg(etk::color::none), - m_colorCursor(etk::color::black), - m_colorSelection(etk::color::olive), - m_mode(ewol::font::Regular), - m_kerning(true), - m_distanceField(false), - m_previousCharcode(0), - m_startTextpos(0), - m_stopTextPos(0), - m_alignement(alignDisable), - m_GLprogram(NULL), - m_GLPosition(-1), - m_GLMatrix(-1), - m_GLColor(-1), - m_GLtexture(-1), - m_GLtexID(-1), - m_selectionStartPos(-100), - m_cursorPos(-100), +ewol::compositing::Text::Text(const std::string& _fontName, int32_t _fontSize) : m_font(NULL) { - if (_tmpInit == true) { - setFont(_fontName, _fontSize); - loadProgram(); - } + setFont(_fontName, _fontSize); } ewol::compositing::Text::~Text(void) { ewol::resource::TexturedFont::release(m_font); - ewol::resource::Program::release(m_GLprogram); -} - -void ewol::compositing::Text::loadProgram(const std::string& _shaderName) { - // get the shader resource : - m_GLPosition = 0; - m_GLprogram = ewol::resource::Program::keep(_shaderName); - if (m_GLprogram != NULL) { - 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"); - } } void ewol::compositing::Text::drawMT(const mat4& _transformationMatrix, bool _enableDepthTest) { @@ -71,7 +31,7 @@ void ewol::compositing::Text::drawMT(const mat4& _transformationMatrix, bool _en m_vectorialDraw.draw(); if (m_coord.size() <= 0 || m_font == NULL) { - // TODO : a remÚtre ... + // TODO : a remÃtre ... //EWOL_WARNING("Nothink to draw..."); return; } @@ -95,7 +55,7 @@ void ewol::compositing::Text::drawMT(const mat4& _transformationMatrix, bool _en // TextureID m_GLprogram->setTexture0(m_GLtexID, m_font->getId()); // position : - m_GLprogram->sendAttribute(m_GLPosition, 2/*x,y*/, &m_coord[0]); + m_GLprogram->sendAttribute(m_GLPosition, 3/*x,y,z*/, &m_coord[0]); // Texture : m_GLprogram->sendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]); // color : @@ -113,7 +73,7 @@ void ewol::compositing::Text::drawD(bool _disableDepthTest) { m_vectorialDraw.draw(); if (m_coord.size() <= 0 || m_font == NULL) { - // TODO : a remètre ... + // TODO : a remèe ... //EWOL_WARNING("Nothink to draw..."); return; } @@ -132,11 +92,11 @@ void ewol::compositing::Text::drawD(bool _disableDepthTest) { // TextureID m_GLprogram->setTexture0(m_GLtexID, m_font->getId()); // position : - m_GLprogram->sendAttribute(m_GLPosition, 2/*x,y*/, &m_coord[0]); + m_GLprogram->sendAttribute(m_GLPosition, m_coord); // Texture : - m_GLprogram->sendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]); + m_GLprogram->sendAttribute(m_GLtexture, m_coordTex); // color : - m_GLprogram->sendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + m_GLprogram->sendAttribute(m_GLColor, m_coordColor); // Request the draw od the elements : ewol::openGL::drawArrays(GL_TRIANGLES, 0, m_coord.size()); m_GLprogram->unUse(); @@ -164,131 +124,6 @@ ewol::GlyphProperty * ewol::compositing::Text::getGlyphPointer(char32_t _charcod return m_font->getGlyphPointer(_charcode, m_mode); } - -void ewol::compositing::Text::translate(const vec3& _vect) { - ewol::Compositing::translate(_vect); - m_vectorialDraw.translate(_vect); -} - -void ewol::compositing::Text::rotate(const vec3& _vect, float _angle) { - ewol::Compositing::rotate(_vect, _angle); - m_vectorialDraw.rotate(_vect, _angle); -} - -void ewol::compositing::Text::scale(const vec3& _vect) { - ewol::Compositing::scale(_vect); - m_vectorialDraw.scale(_vect); -} - -void ewol::compositing::Text::clear(void) { - // call upper class - ewol::Compositing::clear(); - // remove sub draw system - m_vectorialDraw.clear(); - // reset Buffer : - m_coord.clear(); - m_coordTex.clear(); - m_coordColor.clear(); - // reset temporal variables : - reset(); -} - -void ewol::compositing::Text::reset(void) { - m_position = vec3(0,0,0); - m_clippingPosStart = vec3(0,0,0); - m_clippingPosStop = vec3(0,0,0); - m_sizeDisplayStart = m_position; - m_sizeDisplayStop = m_position; - m_nbCharDisplayed = 0; - m_clippingEnable = false; - m_color = etk::color::black; - m_colorBg = etk::color::none; - m_mode = ewol::font::Regular; - m_previousCharcode = 0; - m_startTextpos = 0; - m_stopTextPos = 0; - m_alignement = alignDisable; - m_htmlCurrrentLine = U""; - m_selectionStartPos = -100; - m_cursorPos = -100; - m_htmlDecoration.clear(); - m_needDisplay = true; - m_nbCharDisplayed = 0; -} - -void ewol::compositing::Text::setPos(const vec3& _pos) { - // check min max for display area - if (m_nbCharDisplayed != 0) { - EWOL_VERBOSE("update size 1 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); - m_sizeDisplayStop.setX(etk_max(m_position.x(), m_sizeDisplayStop.x())); - m_sizeDisplayStop.setY(etk_max(m_position.y(), m_sizeDisplayStop.y())); - m_sizeDisplayStart.setX(etk_min(m_position.x(), m_sizeDisplayStart.x())); - m_sizeDisplayStart.setY(etk_min(m_position.y(), m_sizeDisplayStart.y())); - EWOL_VERBOSE("update size 2 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); - } - // update position - m_position = _pos; - m_previousCharcode = 0; - m_vectorialDraw.setPos(m_position); - // update min max of the display area: - if (m_nbCharDisplayed == 0) { - m_sizeDisplayStart = m_position; - m_sizeDisplayStop = m_position; - m_sizeDisplayStop.setY( m_sizeDisplayStop.y()+ getHeight()); - EWOL_VERBOSE("update size 0 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); - } else { - EWOL_VERBOSE("update size 3 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); - m_sizeDisplayStop.setX(etk_max(m_position.x(), m_sizeDisplayStop.x())); - m_sizeDisplayStop.setY(etk_max(m_position.y(), m_sizeDisplayStop.y())); - m_sizeDisplayStart.setX(etk_min(m_position.x(), m_sizeDisplayStart.x())); - m_sizeDisplayStart.setY(etk_min(m_position.y(), m_sizeDisplayStart.y())); - EWOL_VERBOSE("update size 4 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); - } -} - -void ewol::compositing::Text::setRelPos(const vec3& _pos) { - m_position += _pos; - m_previousCharcode = 0; - m_vectorialDraw.setPos(m_position); -} - -void ewol::compositing::Text::setColorBg(const etk::Color<>& _color) { - m_colorBg = _color; - m_vectorialDraw.setColor(_color); -} - -void ewol::compositing::Text::setClipping(const vec3& _pos, const vec3& _posEnd) { - // note the internal system all time request to have a bounding all time in the same order - if (_pos.x() <= _posEnd.x()) { - m_clippingPosStart.setX(_pos.x()); - m_clippingPosStop.setX(_posEnd.x()); - } else { - m_clippingPosStart.setX(_posEnd.x()); - m_clippingPosStop.setX(_pos.x()); - } - if (_pos.y() <= _posEnd.y()) { - m_clippingPosStart.setY(_pos.y()); - m_clippingPosStop.setY(_posEnd.y()); - } else { - m_clippingPosStart.setY(_posEnd.y()); - m_clippingPosStop.setY(_pos.y()); - } - if (_pos.z() <= _posEnd.z()) { - m_clippingPosStart.setZ(_pos.z()); - m_clippingPosStop.setZ(_posEnd.z()); - } else { - m_clippingPosStart.setZ(_posEnd.z()); - m_clippingPosStop.setZ(_pos.z()); - } - m_clippingEnable = true; - //m_vectorialDraw.setClipping(m_clippingPosStart, m_clippingPosStop); -} - -void ewol::compositing::Text::setClippingMode(bool _newMode) { - m_clippingEnable = _newMode; - //m_vectorialDraw.setClippingMode(m_clippingEnable); -} - void ewol::compositing::Text::setFontSize(int32_t _fontSize) { // get old size std::string fontName = ""; @@ -339,601 +174,7 @@ void ewol::compositing::Text::setFontMode(enum ewol::font::mode _mode) { } } -void ewol::compositing::Text::setFontBold(bool _status) { - if (_status == true) { - // enable - if (m_mode == ewol::font::Regular) { - setFontMode(ewol::font::Bold); - } else if (m_mode == ewol::font::Italic) { - setFontMode(ewol::font::BoldItalic); - } - } else { - // disable - if (m_mode == ewol::font::Bold) { - setFontMode(ewol::font::Regular); - } else if (m_mode == ewol::font::BoldItalic) { - setFontMode(ewol::font::Italic); - } - } -} - -void ewol::compositing::Text::setFontItalic(bool _status) { - if (_status == true) { - // enable - if (m_mode == ewol::font::Regular) { - setFontMode(ewol::font::Italic); - } else if (m_mode == ewol::font::Bold) { - setFontMode(ewol::font::BoldItalic); - } - } else { - // disable - if (m_mode == ewol::font::Italic) { - setFontMode(ewol::font::Regular); - } else if (m_mode == ewol::font::BoldItalic) { - setFontMode(ewol::font::Bold); - } - } -} - -void ewol::compositing::Text::setKerningMode(bool _newMode) { - m_kerning = _newMode; -} - -void ewol::compositing::Text::setDistanceFieldMode(bool _newMode) { - m_distanceField = _newMode; - EWOL_TODO("The Distance field mode is not availlable for now ..."); -} - -void ewol::compositing::Text::print(const std::u32string& _text) { - std::vector decorationEmpty; - print(_text, decorationEmpty); -} - -void ewol::compositing::Text::print(const std::string& _text) { - std::vector decorationEmpty; - print(_text, decorationEmpty); -} - - -void ewol::compositing::Text::parseHtmlNode(exml::Element* _element) { - // get the static real pointer - if (_element == NULL) { - EWOL_ERROR( "Error Input node does not existed ..."); - } - for(size_t iii=0; iii< _element->size(); iii++) { - if (_element->getType(iii) == exml::typeComment) { - // nothing to do ... - } else if (_element->getType(iii) == exml::typeText) { - exml::Node* child = _element->getNode(iii); - htmlAddData(std::to_u32string(child->getValue())); - EWOL_VERBOSE("XML add : " << child->getValue()); - continue; - } else if (_element->getType(iii)!=exml::typeElement) { - EWOL_ERROR("(l "<< _element->getNode(iii)->getPos() << ") node not suported type : " << _element->getType(iii) << " val=\""<< _element->getNode(iii)->getValue() << "\"" ); - continue; - } - exml::Element* elem = _element->getElement(iii); - if (elem == NULL) { - EWOL_ERROR("Cast error ..."); - continue; - } - if(compare_no_case(elem->getValue(), "br") == true) { - htmlFlush(); - EWOL_VERBOSE("XML flush & newLine"); - forceLineReturn(); - } else if (compare_no_case(elem->getValue(), "font") == true) { - EWOL_VERBOSE("XML Font ..."); - TextDecoration tmpDeco = m_htmlDecoTmp; - std::string colorValue = elem->getAttribute("color"); - m_htmlDecoTmp.m_colorFg = colorValue; - colorValue = elem->getAttribute("colorBg"); - m_htmlDecoTmp.m_colorBg = colorValue; - parseHtmlNode(elem); - m_htmlDecoTmp = tmpDeco; - } else if( compare_no_case(elem->getValue(), "b") == true - || compare_no_case(elem->getValue(), "bold") == true) { - EWOL_VERBOSE("XML bold ..."); - TextDecoration tmpDeco = m_htmlDecoTmp; - if (m_htmlDecoTmp.m_mode == ewol::font::Regular) { - m_htmlDecoTmp.m_mode = ewol::font::Bold; - } else if (m_htmlDecoTmp.m_mode == ewol::font::Italic) { - m_htmlDecoTmp.m_mode = ewol::font::BoldItalic; - } - parseHtmlNode(elem); - m_htmlDecoTmp = tmpDeco; - } else if( compare_no_case(elem->getValue(), "i") == true - || compare_no_case(elem->getValue(), "italic") == true) { - EWOL_VERBOSE("XML italic ..."); - TextDecoration tmpDeco = m_htmlDecoTmp; - if (m_htmlDecoTmp.m_mode == ewol::font::Regular) { - m_htmlDecoTmp.m_mode = ewol::font::Italic; - } else if (m_htmlDecoTmp.m_mode == ewol::font::Bold) { - m_htmlDecoTmp.m_mode = ewol::font::BoldItalic; - } - parseHtmlNode(elem); - m_htmlDecoTmp = tmpDeco; - } else if( compare_no_case(elem->getValue(), "u") == true - || compare_no_case(elem->getValue(), "underline") == true) { - EWOL_VERBOSE("XML underline ..."); - parseHtmlNode(elem); - } else if( compare_no_case(elem->getValue(), "p") == true - || compare_no_case(elem->getValue(), "paragraph") == true) { - EWOL_VERBOSE("XML paragraph ..."); - htmlFlush(); - m_alignement = alignLeft; - forceLineReturn(); - parseHtmlNode(elem); - forceLineReturn(); - } else if (compare_no_case(elem->getValue(), "center") == true) { - EWOL_VERBOSE("XML center ..."); - htmlFlush(); - m_alignement = alignCenter; - parseHtmlNode(elem); - } else if (compare_no_case(elem->getValue(), "left") == true) { - EWOL_VERBOSE("XML left ..."); - htmlFlush(); - m_alignement = alignLeft; - parseHtmlNode(elem); - } else if (compare_no_case(elem->getValue(), "right") == true) { - EWOL_VERBOSE("XML right ..."); - htmlFlush(); - m_alignement = alignRight; - parseHtmlNode(elem); - } else if (compare_no_case(elem->getValue(), "justify") == true) { - EWOL_VERBOSE("XML justify ..."); - htmlFlush(); - m_alignement = alignJustify; - parseHtmlNode(elem); - } else { - EWOL_ERROR("(l "<< elem->getPos() << ") node not suported type : " << elem->getType() << " val=\""<< elem->getValue() << "\"" ); - } - } -} - -void ewol::compositing::Text::printDecorated(const std::string& _text) { - std::string tmpData("\n\n"); - tmpData += _text; - tmpData += "\n\n\n"; - //EWOL_DEBUG("plop : " << tmpData); - printHTML(tmpData); -} - -void ewol::compositing::Text::printDecorated(const std::u32string& _text) { - std::u32string tmpData(U"\n\n"); - tmpData += _text; - tmpData += U"\n\n\n"; - //EWOL_DEBUG("plop : " << tmpData); - printHTML(tmpData); -} - -void ewol::compositing::Text::printHTML(const std::string& _text) { - exml::Document doc; - - // reset parameter : - m_htmlDecoTmp.m_colorBg = etk::color::none; - m_htmlDecoTmp.m_colorFg = etk::color::black; - m_htmlDecoTmp.m_mode = ewol::font::Regular; - - if (doc.parse(_text) == false) { - EWOL_ERROR( "can not load XML: PARSING error: Decorated text "); - return; - } - - exml::Element* root = (exml::Element*)doc.getNamed( "html" ); - if (root == NULL) { - EWOL_ERROR( "can not load XML: main node not find: \"html\""); - doc.display(); - return; - } - exml::Element* bodyNode = (exml::Element*)root->getNamed( "body" ); - if (root == NULL) { - EWOL_ERROR( "can not load XML: main node not find: \"body\""); - return; - } - (void)parseHtmlNode(bodyNode); - htmlFlush(); -} - -void ewol::compositing::Text::printHTML(const std::u32string& _text) { - exml::Document doc; - - // reset parameter : - m_htmlDecoTmp.m_colorBg = etk::color::none; - m_htmlDecoTmp.m_colorFg = etk::color::black; - m_htmlDecoTmp.m_mode = ewol::font::Regular; - // TODO : Create an instance of xml parser to manage std::u32string... - if (doc.parse(std::to_string(_text)) == false) { - EWOL_ERROR( "can not load XML: PARSING error: Decorated text "); - return; - } - - exml::Element* root = (exml::Element*)doc.getNamed( "html" ); - if (root == NULL) { - EWOL_ERROR( "can not load XML: main node not find: \"html\""); - doc.display(); - return; - } - exml::Element* bodyNode = (exml::Element*)root->getNamed( "body" ); - if (root == NULL) { - EWOL_ERROR( "can not load XML: main node not find: \"body\""); - return; - } - (void)parseHtmlNode(bodyNode); - htmlFlush(); -} - -void ewol::compositing::Text::print(const std::string& _text, const std::vector& _decoration) { - etk::Color<> tmpFg(m_color); - etk::Color<> tmpBg(m_colorBg); - if (m_alignement == alignDisable) { - //EWOL_DEBUG(" 1 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - // display the cursor if needed (if it is at the start position...) - if (m_needDisplay == true) { - if (0 == m_cursorPos) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - } - // note this is faster when nothing is requested ... - for(size_t iii=0; iii<_text.size(); iii++) { - // check if ve have decoration - if (iii<_decoration.size()) { - tmpFg = _decoration[iii].m_colorFg; - tmpBg = _decoration[iii].m_colorBg; - setFontMode(_decoration[iii].m_mode); - } - // if real display : ( not display is for size calculation) - if (m_needDisplay == true) { - if( ( m_selectionStartPos-1 < (int64_t)iii - && (int64_t)iii <= m_cursorPos-1) - || ( m_selectionStartPos-1 >= (int64_t)iii - && (int64_t)iii > m_cursorPos-1) ) { - setColor( 0x000000FF); - setColorBg(m_colorSelection); - } else { - setColor( tmpFg); - setColorBg(tmpBg); - } - } - if( m_needDisplay == true - && m_colorBg.a() != 0) { - vec3 pos = m_position; - m_vectorialDraw.setPos(pos); - print(_text[iii]); - float fontHeigh = getHeight(); - m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); - m_nbCharDisplayed++; - } else { - print(_text[iii]); - m_nbCharDisplayed++; - } - // display the cursor if needed (if it is at the other position...) - if (m_needDisplay == true) { - if ((int64_t)iii == m_cursorPos-1) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - } - } - //EWOL_DEBUG(" 2 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - } else { - //EWOL_DEBUG(" 3 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - // special start case at the right of the endpoint : - if (m_stopTextPos < m_position.x()) { - forceLineReturn(); - } - float basicSpaceWidth = calculateSize(char32_t(' ')).x(); - int32_t currentId = 0; - int32_t stop; - int32_t space; - int32_t freeSpace; - while (currentId < (int64_t)_text.size()) { - bool needNoJustify = extrapolateLastId(_text, currentId, stop, space, freeSpace); - float interpolation = basicSpaceWidth; - switch (m_alignement) { - case alignJustify: - if (needNoJustify == false) { - interpolation += (float)freeSpace / (float)(space-1); - } - break; - case alignDisable: // must not came from here ... - case alignLeft: - // nothing to do ... - break; - case alignRight: - if (m_needDisplay == true) { - // Move the first char at the right : - setPos(vec3(m_position.x() + freeSpace, - m_position.y(), - m_position.z()) ); - } - break; - case alignCenter: - if (m_needDisplay == true) { - // Move the first char at the right : - setPos(vec3(m_position.x() + freeSpace/2, - m_position.y(), - m_position.z()) ); - } - break; - } - // display all the elements - if( m_needDisplay == true - && m_cursorPos == 0) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - for(size_t iii=currentId; (int64_t)iii= (int64_t)iii - && (int64_t)iii > m_cursorPos-1) ) { - setColor( 0x000000FF); - setColorBg(m_colorSelection); - } else { - setColor( tmpFg); - setColorBg(tmpBg); - } - } - // special for the justify mode - if ((char32_t)_text[iii] == u32char::Space) { - //EWOL_DEBUG(" generateString : \" \""); - if( m_needDisplay == true - && m_colorBg.a() != 0) { - m_vectorialDraw.setPos(m_position); - } - // Must generate a dynamic space : - setPos(vec3(m_position.x() + interpolation, - m_position.y(), - m_position.z()) ); - if( m_needDisplay == true - && m_colorBg.a() != 0) { - m_vectorialDraw.rectangleWidth(vec3(interpolation,fontHeigh,0.0f) ); - } - } else { - //EWOL_DEBUG(" generateString : \"" << (char)text[iii] << "\""); - if( m_needDisplay == true - && m_colorBg.a() != 0) { - vec3 pos = m_position; - m_vectorialDraw.setPos(pos); - print(_text[iii]); - m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); - m_nbCharDisplayed++; - } else { - print(_text[iii]); - m_nbCharDisplayed++; - } - } - if (m_needDisplay == true) { - if ((int64_t)iii == m_cursorPos-1) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - } - } - if (currentId == stop) { - currentId++; - } else if((char32_t)_text[stop] == u32char::Space) { - currentId = stop+1; - // reset position : - setPos(vec3(m_startTextpos, - (float)(m_position.y() - getHeight()), - m_position.z()) ); - m_nbCharDisplayed++; - } else if((char32_t)_text[stop] == u32char::Return) { - currentId = stop+1; - // reset position : - setPos(vec3(m_startTextpos, - (float)(m_position.y() - getHeight()), - m_position.z()) ); - m_nbCharDisplayed++; - } else { - currentId = stop; - } - } - //EWOL_DEBUG(" 4 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - } -} - -void ewol::compositing::Text::print(const std::u32string& _text, const std::vector& _decoration) { - etk::Color<> tmpFg(m_color); - etk::Color<> tmpBg(m_colorBg); - if (m_alignement == alignDisable) { - //EWOL_DEBUG(" 1 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - // display the cursor if needed (if it is at the start position...) - if (m_needDisplay == true) { - if (0 == m_cursorPos) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - } - // note this is faster when nothing is requested ... - for(size_t iii=0; iii<_text.size(); iii++) { - // check if ve have decoration - if (iii<_decoration.size()) { - tmpFg = _decoration[iii].m_colorFg; - tmpBg = _decoration[iii].m_colorBg; - setFontMode(_decoration[iii].m_mode); - } - // if real display : ( not display is for size calculation) - if (m_needDisplay == true) { - if( ( m_selectionStartPos-1<(int64_t)iii - && (int64_t)iii <= m_cursorPos-1) - || ( m_selectionStartPos-1 >= (int64_t)iii - && (int64_t)iii > m_cursorPos-1) ) { - setColor( 0x000000FF); - setColorBg(m_colorSelection); - } else { - setColor( tmpFg); - setColorBg(tmpBg); - } - } - if( m_needDisplay == true - && m_colorBg.a() != 0) { - vec3 pos = m_position; - m_vectorialDraw.setPos(pos); - print(_text[iii]); - float fontHeigh = getHeight(); - m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); - m_nbCharDisplayed++; - } else { - print(_text[iii]); - m_nbCharDisplayed++; - } - // display the cursor if needed (if it is at the other position...) - if (m_needDisplay == true) { - if ((int64_t)iii == m_cursorPos-1) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - } - } - //EWOL_DEBUG(" 2 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - } else { - //EWOL_DEBUG(" 3 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - // special start case at the right of the endpoint : - if (m_stopTextPos < m_position.x()) { - forceLineReturn(); - } - float basicSpaceWidth = calculateSize(char32_t(' ')).x(); - int32_t currentId = 0; - int32_t stop; - int32_t space; - int32_t freeSpace; - while (currentId < (int64_t)_text.size()) { - bool needNoJustify = extrapolateLastId(_text, currentId, stop, space, freeSpace); - float interpolation = basicSpaceWidth; - switch (m_alignement) { - case alignJustify: - if (needNoJustify == false) { - interpolation += (float)freeSpace / (float)(space-1); - } - break; - case alignDisable: // must not came from here ... - case alignLeft: - // nothing to do ... - break; - case alignRight: - if (m_needDisplay == true) { - // Move the first char at the right : - setPos(vec3(m_position.x() + freeSpace, - m_position.y(), - m_position.z()) ); - } - break; - case alignCenter: - if (m_needDisplay == true) { - // Move the first char at the right : - setPos(vec3(m_position.x() + freeSpace/2, - m_position.y(), - m_position.z()) ); - } - break; - } - // display all the elements - if( m_needDisplay == true - && m_cursorPos == 0) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - for(size_t iii=currentId; (int64_t)iii= (int64_t)iii - && (int64_t)iii > m_cursorPos-1) ) { - setColor( 0x000000FF); - setColorBg(m_colorSelection); - } else { - setColor( tmpFg); - setColorBg(tmpBg); - } - } - // special for the justify mode - if ((char32_t)_text[iii] == u32char::Space) { - //EWOL_DEBUG(" generateString : \" \""); - if( m_needDisplay == true - && m_colorBg.a() != 0) { - m_vectorialDraw.setPos(m_position); - } - // Must generate a dynamic space : - setPos(vec3(m_position.x() + interpolation, - m_position.y(), - m_position.z()) ); - if( m_needDisplay == true - && m_colorBg.a() != 0) { - m_vectorialDraw.rectangleWidth(vec3(interpolation,fontHeigh,0.0f) ); - } - } else { - //EWOL_DEBUG(" generateString : \"" << (char)text[iii] << "\""); - if( m_needDisplay == true - && m_colorBg.a() != 0) { - vec3 pos = m_position; - m_vectorialDraw.setPos(pos); - print(_text[iii]); - m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); - m_nbCharDisplayed++; - } else { - print(_text[iii]); - m_nbCharDisplayed++; - } - } - if (m_needDisplay == true) { - if ((int64_t)iii == m_cursorPos-1) { - m_vectorialDraw.setPos(m_position); - setColorBg(m_colorCursor); - printCursor(false); - } - } - } - if (currentId == stop) { - currentId++; - } else if(_text[stop] == u32char::Space) { - currentId = stop+1; - // reset position : - setPos(vec3(m_startTextpos, - (float)(m_position.y() - getHeight()), - m_position.z()) ); - m_nbCharDisplayed++; - } else if(_text[stop] == u32char::Return) { - currentId = stop+1; - // reset position : - setPos(vec3(m_startTextpos, - (float)(m_position.y() - getHeight()), - m_position.z()) ); - m_nbCharDisplayed++; - } else { - currentId = stop; - } - } - //EWOL_DEBUG(" 4 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); - } -} - - -void ewol::compositing::Text::print(const char32_t& _charcode) { +void ewol::compositing::Text::printChar(const char32_t& _charcode) { // get a pointer on the glyph property : ewol::GlyphProperty* myGlyph = getGlyphPointer(_charcode); if (NULL == myGlyph) { @@ -1031,11 +272,11 @@ void ewol::compositing::Text::print(const char32_t& _charcode) { * 3------2 */ if (m_needDisplay == true) { - ivec2 bitmapDrawPos[4]; - bitmapDrawPos[0].setValue((int32_t)dxA, (int32_t)dyC); - bitmapDrawPos[1].setValue((int32_t)dxB, (int32_t)dyC); - bitmapDrawPos[2].setValue((int32_t)dxB, (int32_t)dyD); - bitmapDrawPos[3].setValue((int32_t)dxA, (int32_t)dyD); + vec3 bitmapDrawPos[4]; + bitmapDrawPos[0].setValue((int32_t)dxA, (int32_t)dyC, 0); + bitmapDrawPos[1].setValue((int32_t)dxB, (int32_t)dyC, 0); + bitmapDrawPos[2].setValue((int32_t)dxB, (int32_t)dyD, 0); + bitmapDrawPos[3].setValue((int32_t)dxA, (int32_t)dyD, 0); /* texture Position : * 0------1 * | | @@ -1098,338 +339,4 @@ void ewol::compositing::Text::print(const char32_t& _charcode) { // Register the previous character m_previousCharcode = _charcode; return; -} - -void ewol::compositing::Text::forceLineReturn(void) { - // reset position : - setPos(vec3(m_startTextpos, m_position.y() - getHeight(), 0) ); -} - -void ewol::compositing::Text::setTextAlignement(float _startTextpos, float _stopTextPos, enum ewol::compositing::Text::aligneMode _alignement) { - m_startTextpos = _startTextpos; - m_stopTextPos = _stopTextPos+1; - m_alignement = _alignement; - if (m_startTextpos >= m_stopTextPos) { - EWOL_ERROR("Request allignement with Borne position error : " << _startTextpos << " => " << _stopTextPos); - } -} - -enum ewol::compositing::Text::aligneMode ewol::compositing::Text::getAlignement(void) { - return m_alignement; -} - -void ewol::compositing::Text::disableAlignement(void) { - m_alignement = alignDisable; -} - -vec3 ewol::compositing::Text::calculateSizeHTML(const std::string& _text) { - // remove intermediate result - reset(); - //EWOL_DEBUG(" 0 size for=\n" << text); - // disable display system - m_needDisplay = false; - - setPos(vec3(0,0,0) ); - // same as print without the end display ... - printHTML(_text); - //EWOL_DEBUG(" 1 Start pos=" << m_sizeDisplayStart); - //EWOL_DEBUG(" 1 Stop pos=" << m_sizeDisplayStop); - - // get the last elements - m_sizeDisplayStop.setValue(etk_max(m_position.x(), m_sizeDisplayStop.x()) , - etk_max(m_position.y(), m_sizeDisplayStop.y()) , - 0); - m_sizeDisplayStart.setValue(etk_min(m_position.x(), m_sizeDisplayStart.x()) , - etk_min(m_position.y(), m_sizeDisplayStart.y()) , - 0); - - //EWOL_DEBUG(" 2 Start pos=" << m_sizeDisplayStart); - //EWOL_DEBUG(" 2 Stop pos=" << m_sizeDisplayStop); - // set back the display system - m_needDisplay = true; - - return vec3( m_sizeDisplayStop.x()-m_sizeDisplayStart.x(), - m_sizeDisplayStop.y()-m_sizeDisplayStart.y(), - m_sizeDisplayStop.z()-m_sizeDisplayStart.z()); -} - -vec3 ewol::compositing::Text::calculateSizeHTML(const std::u32string& _text) { - // remove intermediate result - reset(); - //EWOL_DEBUG(" 0 size for=\n" << text); - // disable display system - m_needDisplay = false; - - setPos(vec3(0,0,0) ); - // same as print without the end display ... - printHTML(_text); - //EWOL_DEBUG(" 1 Start pos=" << m_sizeDisplayStart); - //EWOL_DEBUG(" 1 Stop pos=" << m_sizeDisplayStop); - - // get the last elements - m_sizeDisplayStop.setValue(etk_max(m_position.x(), m_sizeDisplayStop.x()) , - etk_max(m_position.y(), m_sizeDisplayStop.y()) , - 0); - m_sizeDisplayStart.setValue(etk_min(m_position.x(), m_sizeDisplayStart.x()) , - etk_min(m_position.y(), m_sizeDisplayStart.y()) , - 0); - - //EWOL_DEBUG(" 2 Start pos=" << m_sizeDisplayStart); - //EWOL_DEBUG(" 2 Stop pos=" << m_sizeDisplayStop); - // set back the display system - m_needDisplay = true; - - return vec3( m_sizeDisplayStop.x()-m_sizeDisplayStart.x(), - m_sizeDisplayStop.y()-m_sizeDisplayStart.y(), - m_sizeDisplayStop.z()-m_sizeDisplayStart.z()); -} - -vec3 ewol::compositing::Text::calculateSizeDecorated(const std::string& _text) { - if (_text.size() == 0) { - return vec3(0,0,0); - } - std::string tmpData("\n"); - tmpData+=_text; - tmpData+="\n\n"; - vec3 tmpVal = calculateSizeHTML(tmpData); - return tmpVal; -} - -vec3 ewol::compositing::Text::calculateSizeDecorated(const std::u32string& _text) { - if (_text.size() == 0) { - return vec3(0,0,0); - } - std::u32string tmpData(U"\n"); - tmpData += _text; - tmpData += U"\n\n"; - vec3 tmpVal = calculateSizeHTML(tmpData); - return tmpVal; -} - -vec3 ewol::compositing::Text::calculateSize(const std::string& _text) { - vec3 outputSize(0, 0, 0); - for(auto element : _text) { - vec3 tmpp = calculateSize(element); - if (outputSize.y() == 0) { - outputSize.setY(tmpp.y()); - } - outputSize.setX( outputSize.x() + tmpp.x()); - } - return outputSize; -} - -vec3 ewol::compositing::Text::calculateSize(const std::u32string& _text) { - vec3 outputSize(0, 0, 0); - for(auto element : _text) { - vec3 tmpp = calculateSize(element); - if (outputSize.y() == 0) { - outputSize.setY(tmpp.y()); - } - outputSize.setX( outputSize.x() + tmpp.x()); - } - return outputSize; -} - -vec3 ewol::compositing::Text::calculateSize(const char32_t& _charcode) { - // get a pointer on the glyph property : - ewol::GlyphProperty * myGlyph = getGlyphPointer(_charcode); - int32_t fontHeigh = getHeight(); - - // get the kerning ofset : - float kerningOffset = 0.0; - if (true == m_kerning) { - kerningOffset = myGlyph->kerningGet(m_previousCharcode); - } - - vec3 outputSize((float)(myGlyph->m_advance.x() + kerningOffset), - (float)(fontHeigh), - (float)(0.0)); - // Register the previous character - m_previousCharcode = _charcode; - return outputSize; -} - -void ewol::compositing::Text::printCursor(bool _isInsertMode, float _cursorSize) { - int32_t fontHeigh = getHeight(); - if (true == _isInsertMode) { - m_vectorialDraw.rectangleWidth(vec3(_cursorSize, fontHeigh, 0) ); - } else { - m_vectorialDraw.setThickness(2); - m_vectorialDraw.lineRel( vec3(0, fontHeigh, 0) ); - m_vectorialDraw.setThickness(0); - } -} - -bool ewol::compositing::Text::extrapolateLastId(const std::string& _text, - const int32_t _start, - int32_t& _stop, - int32_t& _space, - int32_t& _freeSpace) { - // store previous : - char32_t storePrevious = m_previousCharcode; - - _stop = _text.size(); - _space = 0; - - int32_t lastSpacePosition = _start; - int32_t lastSpacefreeSize; - - float endPos = m_position.x(); - bool endOfLine = false; - - float stopPosition = m_stopTextPos; - if( m_needDisplay == false - || m_stopTextPos == m_startTextpos) { - stopPosition = m_startTextpos + 3999999999.0; - } - - for (size_t iii=_start; iii<_text.size(); iii++) { - vec3 tmpSize = calculateSize(_text[iii]); - // check oveflow : - if (endPos + tmpSize.x() > stopPosition) { - _stop = iii; - break; - } - // save number of space : - if ((char32_t)_text[iii] == u32char::Space) { - _space++; - lastSpacePosition = iii; - lastSpacefreeSize = stopPosition - endPos; - } else if ((char32_t)_text[iii] == u32char::Return) { - _stop = iii; - endOfLine = true; - break; - } - // update local size : - endPos += tmpSize.x(); - } - _freeSpace = stopPosition - endPos; - // retore previous : - m_previousCharcode = storePrevious; - // need to align left or right ... - if(_stop == (int64_t)_text.size()) { - return true; - } else { - if (endOfLine) { - return true; - } else { - if (_space == 0) { - return true; - } - _stop = lastSpacePosition; - _freeSpace = lastSpacefreeSize; - return false; - } - } -} - -bool ewol::compositing::Text::extrapolateLastId(const std::u32string& _text, - const int32_t _start, - int32_t& _stop, - int32_t& _space, - int32_t& _freeSpace) { - // store previous : - char32_t storePrevious = m_previousCharcode; - - _stop = _text.size(); - _space = 0; - - int32_t lastSpacePosition = _start; - int32_t lastSpacefreeSize; - - float endPos = m_position.x(); - bool endOfLine = false; - - float stopPosition = m_stopTextPos; - if( m_needDisplay == false - || m_stopTextPos == m_startTextpos) { - stopPosition = m_startTextpos + 3999999999.0; - } - - for (size_t iii=_start; iii<_text.size(); iii++) { - vec3 tmpSize = calculateSize(_text[iii]); - // check oveflow : - if (endPos + tmpSize.x() > stopPosition) { - _stop = iii; - break; - } - // save number of space : - if (_text[iii] == u32char::Space) { - _space++; - lastSpacePosition = iii; - lastSpacefreeSize = stopPosition - endPos; - } else if (_text[iii] == u32char::Return) { - _stop = iii; - endOfLine = true; - break; - } - // update local size : - endPos += tmpSize.x(); - } - _freeSpace = stopPosition - endPos; - // retore previous : - m_previousCharcode = storePrevious; - // need to align left or right ... - if(_stop == (int64_t)_text.size()) { - return true; - } else { - if (endOfLine) { - return true; - } else { - if (_space == 0) { - return true; - } - _stop = lastSpacePosition; - _freeSpace = lastSpacefreeSize; - return false; - } - } -} - -void ewol::compositing::Text::htmlAddData(const std::u32string& _data) { - if( m_htmlCurrrentLine.size()>0 - && m_htmlCurrrentLine[m_htmlCurrrentLine.size()-1] != ' ') { - m_htmlCurrrentLine += U" "; - if(m_htmlDecoration.size()>0) { - TextDecoration tmp = m_htmlDecoration[m_htmlDecoration.size()-1]; - m_htmlDecoration.push_back(tmp); - } else { - m_htmlDecoration.push_back(m_htmlDecoTmp); - } - } - m_htmlCurrrentLine += _data; - for(size_t iii=0; iii<_data.size() ; iii++) { - m_htmlDecoration.push_back(m_htmlDecoTmp); - } -} - -void ewol::compositing::Text::htmlFlush(void) { - if (m_htmlCurrrentLine.size()>0) { - print(m_htmlCurrrentLine, m_htmlDecoration); - } - m_htmlCurrrentLine = U""; - m_htmlDecoration.clear(); -} - -void ewol::compositing::Text::disableCursor(void) { - m_selectionStartPos = -100; - m_cursorPos = -100; -} - -void ewol::compositing::Text::setCursorPos(int32_t _cursorPos) { - m_selectionStartPos = _cursorPos; - m_cursorPos = _cursorPos; -} - -void ewol::compositing::Text::setCursorSelection(int32_t _cursorPos, int32_t _selectionStartPos) { - m_selectionStartPos = _selectionStartPos; - m_cursorPos = _cursorPos; -} - -void ewol::compositing::Text::setSelectionColor(const etk::Color<>& _color) { - m_colorSelection = _color; -} - -void ewol::compositing::Text::setCursorColor(const etk::Color<>& _color) { - m_colorCursor = _color; -} +} \ No newline at end of file diff --git a/sources/ewol/compositing/Text.h b/sources/ewol/compositing/Text.h index c6a5f56a..dfc7c2f3 100644 --- a/sources/ewol/compositing/Text.h +++ b/sources/ewol/compositing/Text.h @@ -15,467 +15,47 @@ #include #include #include +#include #include #include +#include + namespace ewol { namespace compositing { - /** - * @brief This class represent the specific display for every char in the string ... - * @not-in-doc - */ - class TextDecoration { - public: - etk::Color<> m_colorBg; //!< display background color - etk::Color<> m_colorFg; //!< display foreground color - enum ewol::font::mode m_mode; //!< display mode Regular/Bold/Italic/BoldItalic - TextDecoration(void) { - m_colorBg = etk::color::blue; - m_colorBg = etk::color::green; - m_mode = ewol::font::Regular; - } - }; - - class Text : public ewol::Compositing { - public: - enum aligneMode { - alignDisable, - alignRight, - alignLeft, - alignCenter, - alignJustify - }; - protected: - ewol::compositing::Drawing m_vectorialDraw; //!< This is used to draw background selection and other things ... - public: - virtual ewol::compositing::Drawing& getDrawing(void) { - return m_vectorialDraw; - }; - protected: - int32_t m_nbCharDisplayed; //!< prevent some error in calculation size. - vec3 m_sizeDisplayStart; //!< The start windows of the display. - vec3 m_sizeDisplayStop; //!< The end windows of the display. - bool m_needDisplay; //!< This just need the display and not the size rendering. - vec3 m_position; //!< The current position to draw - vec3 m_clippingPosStart; //!< Clipping start position - vec3 m_clippingPosStop; //!< Clipping stop position - bool m_clippingEnable; //!< true if the clipping must be activated - protected: - etk::Color<> m_color; //!< The text foreground color - etk::Color<> m_colorBg; //!< The text background color - etk::Color<> m_colorCursor; //!< The text cursor color - etk::Color<> m_colorSelection; //!< The text Selection color - protected: - enum ewol::font::mode m_mode; //!< font display property : Regular/Bold/Italic/BoldItalic - bool m_kerning; //!< Kerning enable or disable on the next elements displayed - bool m_distanceField; //!< Texture in distance Field mode == > maybe move this in the font property. - char32_t m_previousCharcode; //!< we remember the previous charcode to perform the kerning. @ref Kerning - protected: - float m_startTextpos; //!< start position of the Alignement (when \n the text return at this position) - float m_stopTextPos; //!< end of the alignement (when a string is too hight it cut at the word previously this virtual line and the center is perform with this one) - enum aligneMode m_alignement; //!< Current Alignement mode (justify/left/right ...) - protected: - ewol::resource::Program* m_GLprogram; //!< pointer on the opengl display program - int32_t m_GLPosition; //!< openGL id on the element (vertex buffer) - int32_t m_GLMatrix; //!< openGL id on the element (transformation matrix) - int32_t m_GLColor; //!< openGL id on the element (color buffer) - int32_t m_GLtexture; //!< openGL id on the element (Texture position) - int32_t m_GLtexID; //!< openGL id on the element (texture ID) - protected: - int32_t m_selectionStartPos; //!< start position of the Selection (if == m_cursorPos ==> no selection) - int32_t m_cursorPos; //!< Cursor position (default no cursor == > -100) + class Text : public ewol::compositing::TextBase { protected: ewol::resource::TexturedFont* m_font; //!< Font resources - protected: // Text - std::vector m_coord; //!< internal coord of the object - std::vector m_coordTex; //!< internal texture coordinate for every point - std::vector > m_coordColor; //!< internal color of the different point - protected: - /** - * @brief load the openGL program and get all the ID needed - */ - virtual void loadProgram(const std::string& _shaderName="DATA:text.prog"); public: /** * @brief generic constructor * @param[in] _fontName Name of the font that might be loaded * @param[in] _fontSize size of the font that might be loaded */ - Text(const std::string& _fontName="", int32_t _fontSize=-1, bool _tmpInit = true); + Text(const std::string& _fontName="", int32_t _fontSize=-1); /** * @brief generic destructor */ virtual ~Text(void); - public: // Derived function - virtual void translate(const vec3& _vect); - virtual void rotate(const vec3& _vect, float _angle); - virtual void scale(const vec3& _vect); public: - /** - * @brief draw All the refistered text in the current element on openGL - */ - void draw(bool _disableDepthTest=true) { - drawD(_disableDepthTest); - } - /** - * @previous - */ - void draw(const mat4& _transformationMatrix, bool _enableDepthTest=false) { - drawMT(_transformationMatrix, _enableDepthTest); - } - /** - * @brief draw All the refistered text in the current element on openGL - */ virtual void drawD(bool _disableDepthTest); - /** - * @previous - */ virtual void drawMT(const mat4& _transformationMatrix, bool _enableDepthTest); - /** - * @brief clear all the registered element in the current element - */ - virtual void clear(void); - /** - * @brief clear all the intermediate result detween 2 prints - */ - virtual void reset(void); - /** - * @brief get the current display position (sometime needed in the gui control) - * @return the current position. - */ - virtual const vec3& getPos(void) { - return m_position; - }; - /** - * @brief set position for the next text writen - * @param[in] _pos Position of the text (in 3D) - */ - virtual void setPos(const vec3& _pos); - /** - * @previous - */ - inline void setPos(const vec2& _pos) { - setPos(vec3(_pos.x(),_pos.y(),0)); - }; - /** - * @brief set relative position for the next text writen - * @param[in] _pos ofset apply of the text (in 3D) - */ - virtual void setRelPos(const vec3& _pos); - /** - * @previous - */ - inline void setRelPos(const vec2& _pos) { - setRelPos(vec3(_pos.x(),_pos.y(),0)); - }; - /** - * @brief set the Color of the current foreground font - * @param[in] _color Color to set on foreground (for next print) - */ - virtual void setColor(const etk::Color<>& _color) { m_color = _color; }; - /** - * @brief set the background color of the font (for selected Text (not the global BG)) - * @param[in] _color Color to set on background (for next print) - */ - virtual void setColorBg(const etk::Color<>& _color); - /** - * @brief Request a clipping area for the text (next draw only) - * @param[in] _pos Start position of the clipping - * @param[in] _width Width size of the clipping - */ - virtual void setClippingWidth(const vec3& _pos, const vec3& _width) { - setClipping(_pos, _pos+_width); - } - /** - * @previous - */ - virtual void setClippingWidth(const vec2& _pos, const vec2& _width) { - setClipping(_pos, _pos+_width); - }; - /** - * @brief Request a clipping area for the text (next draw only) - * @param[in] _pos Start position of the clipping - * @param[in] _posEnd End position of the clipping - */ - virtual void setClipping(const vec3& _pos, const vec3& _posEnd); - /** - * @previous - */ - virtual void setClipping(const vec2& _pos, const vec2& _posEnd) { - setClipping(vec3(_pos.x(),_pos.y(),-1), vec3(_posEnd.x(),_posEnd.y(),1) ); - }; - /** - * @brief enable/Disable the clipping (without lose the current clipping position) - * @brief _newMode The new status of the clipping - */ - // TODO : Rename setClippingActivity - virtual void setClippingMode(bool _newMode); - /** - * @brief Specify the font size (this reset the internal element of the current text (system requirement) - * @param[in] _fontSize New font size - */ - virtual void setFontSize(int32_t _fontSize); - /** - * @brief Specify the font name (this reset the internal element of the current text (system requirement) - * @param[in] _fontName Current name of the selected font - */ - virtual void setFontName(const std::string& _fontName); - /** - * @brief Specify the font property (this reset the internal element of the current text (system requirement) - * @param[in] fontName Current name of the selected font - * @param[in] fontSize New font size - */ - virtual void setFont(std::string _fontName, int32_t _fontSize); - /** - * @brief Specify the font mode for the next @ref print - * @param[in] mode The font mode requested - */ - virtual void setFontMode(enum ewol::font::mode _mode); - /** - * @brief get the current font mode - * @return The font mode applied - */ - virtual enum ewol::font::mode getFontMode(void) { - return m_mode; - }; + protected: + float m_size; + public: virtual float getHeight(void); virtual float getSize(void); virtual ewol::GlyphProperty * getGlyphPointer(char32_t _charcode); - /** - * @brief enable or disable the bold mode - * @param[in] _status The new status for this display property - */ - virtual void setFontBold(bool _status); - /** - * @brief enable or disable the italic mode - * @param[in] _status The new status for this display property - */ - virtual void setFontItalic(bool _status); - /** - * @brief set the activation of the Kerning for the display (if it existed) - * @param[in] _newMode enable/Diasable the kerning on this font. - */ - virtual void setKerningMode(bool _newMode); - /** - * @brief Request the distance field mode for this text display - * @param[in] _newMode enable/Diasable the Distance Field on this font. - * @todo : not implemented for now - */ - virtual void setDistanceFieldMode(bool _newMode); - /** - * @brief display a compleat string in the current element. - * @param[in] _text The string to display. - */ - virtual void print(const std::string& _text); - /** - * @previous - */ - virtual void print(const std::u32string& _text); - /** - * @brief display a compleat string in the current element with the generic decoration specification. (basic html data) - * - * [code style=xml] - *
- *


- *
- * text exemple in bold other text bold part boldItalic part an other thext - * colored text bold color text bold italic text normal color text the end of the string
- * an an other thext - *
- *


- * - * plop 1 - * - *


- * - * plop 2 - * - *


- * - * Un exemple de text - * - * [/code] - * - * @note This is parsed with tiny xml, then be carfull that the XML is correct, and all balises are closed ... otherwite the display can not be done - * @param[in] _text The string to display. - * @TODO : implementation not done .... - */ - virtual void printDecorated(const std::string& _text); - //! @previous - virtual void printDecorated(const std::u32string& _text); - /** - * @brief display a compleat string in the current element with the generic decoration specification. (basic html data) - * - * [code style=xml] - * - * - *
- *


- *
- * text exemple in bold other text bold part boldItalic part an other thext - * colored text bold color text bold italic text normal color text the end of the string
- * an an other thext - *
- *


- * - * plop 1 - * - *


- * - * plop 2 - * - *


- * - * Un exemple de text - * - * - * - * [/code] - * - * @note This is parsed with tiny xml, then be carfull that the XML is correct, and all balises are closed ... otherwite the display can not be done - * @param[in] _text The string to display. - * @TODO : implementation not done .... - */ - virtual void printHTML(const std::string& _text); - //! @previous - virtual void printHTML(const std::u32string& _text); - /** - * @brief display a compleat string in the current element whith specific decorations (advence mode). - * @param[in] _text The string to display. - * @param[in] _decoration The text decoration for the text that might be display (if the vector is smaller, the last parameter is get) - */ - virtual void print(const std::string& _text, const std::vector& _decoration); - //! @previous - virtual void print(const std::u32string& _text, const std::vector& _decoration); - /** - * @brief display the current char in the current element (note that the kerning is availlable if the position is not changed) - * @param[in] _charcode Char that might be dispalyed - */ - virtual void print(const char32_t& _charcode); - /** - * @brief This generate the line return == > it return to the alignement position start and at the correct line position ==> it might be use to not know the line height - */ - virtual void forceLineReturn(void); - protected: - /** - * @brief This parse a tinyXML node (void pointer to permit to hide tiny XML in include). - * @param[in] _element the exml element. - */ - virtual void parseHtmlNode(exml::Element* _element); + public: - /** - * @brief This generate the possibility to generate the big text property - * @param[in] _startTextpos The x text start position of the display. - * @param[in] _stopTextPos The x text stop position of the display. - * @param[in] _alignement mode of alignement for the Text. - * @note The text align in center change of line every display done (even if it was just a char) - */ - virtual void setTextAlignement(float _startTextpos, float _stopTextPos, enum ewol::compositing::Text::aligneMode _alignement=ewol::compositing::Text::alignDisable); - /** - * @brief disable the alignement system - */ - virtual void disableAlignement(void); - /** - * @brief get the current alignement property - * @return the curent alignement type - */ - virtual enum ewol::compositing::Text::aligneMode getAlignement(void); - /** - * @brief calculate a theoric text size - * @param[in] _text The string to calculate dimention. - * @return The theoric size used. - */ - virtual vec3 calculateSizeHTML(const std::string& _text); - //!@previous - virtual vec3 calculateSizeHTML(const std::u32string& _text); - /** - * @brief calculate a theoric text size - * @param[in] _text The string to calculate dimention. - * @return The theoric size used. - */ - virtual vec3 calculateSizeDecorated(const std::string& _text); - //!@previous - virtual vec3 calculateSizeDecorated(const std::u32string& _text); - /** - * @brief calculate a theoric text size - * @param[in] _text The string to calculate dimention. - * @return The theoric size used. - */ - virtual vec3 calculateSize(const std::string& _text); - //!@previous - virtual vec3 calculateSize(const std::u32string& _text); - /** - * @brief calculate a theoric charcode size - * @param[in] _charcode The µUnicode value to calculate dimention. - * @return The theoric size used. - */ - virtual vec3 calculateSize(const char32_t& _charcode); - /** - * @brief draw a cursor at the specify position - * @param[in] _isInsertMode True if the insert mode is activated - * @param[in] _cursorSize The sizae of the cursor that might be set when insert mode is set [default 20] - */ - virtual void printCursor(bool _isInsertMode, float _cursorSize = 20.0f); - protected: - /** - * @brief calculate the element number that is the first out the alignement range - * (start at the specify ID, and use start pos with current one) - * @param[in] _text The string that might be parsed. - * @param[in] _start The first elemnt that might be used to calculate. - * @param[out] _stop The last Id availlable in the current string. - * @param[out] _space Number of space in the string. - * @param[out] _freespace This represent the number of pixel present in the right white space. - * @return true if the rifht has free space that can be use for jystify. - * @return false if we find '\n' - */ - virtual bool extrapolateLastId(const std::string& _text, const int32_t _start, int32_t& _stop, int32_t& _space, int32_t& _freeSpace); - /** - * @previous - */ - virtual bool extrapolateLastId(const std::u32string& _text, const int32_t _start, int32_t& _stop, int32_t& _space, int32_t& _freeSpace); - protected: - // this section is reserved for HTML parsing and display: - std::u32string m_htmlCurrrentLine; //!< current line for HTML display - std::vector m_htmlDecoration; //!< current decoration for the HTML display - TextDecoration m_htmlDecoTmp; //!< current decoration - /** - * @brief add a line with the current m_htmlDecoTmp decoration - * @param[in] _data The cuurent data to add. - */ - virtual void htmlAddData(const std::u32string& _data); - /** - * @brief draw the current line - */ - virtual void htmlFlush(void); - public: - /** - * @brief remove the cursor display - */ - virtual void disableCursor(void); - /** - * @brief set a cursor at a specific position: - * @param[in] _cursorPos id of the cursor position - */ - virtual void setCursorPos(int32_t _cursorPos); - /** - * @brief set a cursor at a specific position with his associated selection: - * @param[in] _cursorPos id of the cursor position - * @param[in] _selectionStartPos id of the starting of the selection - */ - virtual void setCursorSelection(int32_t _cursorPos, int32_t _selectionStartPos); - /** - * @brief change the selection color - * @param[in] _color New color for the Selection - */ - virtual void setSelectionColor(const etk::Color<>& _color); - /** - * @brief change the cursor color - * @param[in] _color New color for the Selection - */ - virtual void setCursorColor(const etk::Color<>& _color); + virtual void setFontSize(int32_t _fontSize); + virtual void setFontName(const std::string& _fontName); + virtual void setFont(std::string _fontName, int32_t _fontSize); + virtual void setFontMode(enum ewol::font::mode _mode); + virtual void printChar(const char32_t& _charcode); }; }; }; -#endif +#endif \ No newline at end of file diff --git a/sources/ewol/compositing/TextBase.cpp b/sources/ewol/compositing/TextBase.cpp new file mode 100644 index 00000000..532fb9bb --- /dev/null +++ b/sources/ewol/compositing/TextBase.cpp @@ -0,0 +1,1109 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include +#include +#include + +#undef __class__ +#define __class__ "ewol::compositing::TextBase" + + +ewol::compositing::TextBase::TextBase(const std::string& _shaderName) : + m_position(0.0, 0.0, 0.0), + m_clippingPosStart(0.0, 0.0, 0.0), + m_clippingPosStop(0.0, 0.0, 0.0), + m_clippingEnable(false), + m_color(etk::color::black), + m_colorBg(etk::color::none), + m_colorCursor(etk::color::black), + m_colorSelection(etk::color::olive), + m_mode(ewol::font::Regular), + m_kerning(true), + m_previousCharcode(0), + m_startTextpos(0), + m_stopTextPos(0), + m_alignement(alignDisable), + m_GLprogram(NULL), + m_GLPosition(-1), + m_GLMatrix(-1), + m_GLColor(-1), + m_GLtexture(-1), + m_GLtexID(-1), + m_selectionStartPos(-100), + m_cursorPos(-100) { + loadProgram(_shaderName); +} + + +ewol::compositing::TextBase::~TextBase(void) { + ewol::resource::Program::release(m_GLprogram); +} + +void ewol::compositing::TextBase::loadProgram(const std::string& _shaderName) { + // get the shader resource : + m_GLPosition = 0; + m_GLprogram = ewol::resource::Program::keep(_shaderName); + if (m_GLprogram != NULL) { + m_GLPosition = m_GLprogram->getAttribute("EW_coord3d"); + 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"); + } +} + +void ewol::compositing::TextBase::translate(const vec3& _vect) { + ewol::Compositing::translate(_vect); + m_vectorialDraw.translate(_vect); +} + +void ewol::compositing::TextBase::rotate(const vec3& _vect, float _angle) { + ewol::Compositing::rotate(_vect, _angle); + m_vectorialDraw.rotate(_vect, _angle); +} + +void ewol::compositing::TextBase::scale(const vec3& _vect) { + ewol::Compositing::scale(_vect); + m_vectorialDraw.scale(_vect); +} + +void ewol::compositing::TextBase::clear(void) { + // call upper class + ewol::Compositing::clear(); + // remove sub draw system + m_vectorialDraw.clear(); + // reset Buffer : + m_coord.clear(); + m_coordTex.clear(); + m_coordColor.clear(); + // reset temporal variables : + reset(); +} + +void ewol::compositing::TextBase::reset(void) { + m_position = vec3(0,0,0); + m_clippingPosStart = vec3(0,0,0); + m_clippingPosStop = vec3(0,0,0); + m_sizeDisplayStart = m_position; + m_sizeDisplayStop = m_position; + m_nbCharDisplayed = 0; + m_clippingEnable = false; + m_color = etk::color::black; + m_colorBg = etk::color::none; + m_mode = ewol::font::Regular; + m_previousCharcode = 0; + m_startTextpos = 0; + m_stopTextPos = 0; + m_alignement = alignDisable; + m_htmlCurrrentLine = U""; + m_selectionStartPos = -100; + m_cursorPos = -100; + m_htmlDecoration.clear(); + m_needDisplay = true; + m_nbCharDisplayed = 0; +} + +void ewol::compositing::TextBase::setPos(const vec3& _pos) { + // check min max for display area + if (m_nbCharDisplayed != 0) { + EWOL_VERBOSE("update size 1 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); + m_sizeDisplayStop.setX(etk_max(m_position.x(), m_sizeDisplayStop.x())); + m_sizeDisplayStop.setY(etk_max(m_position.y(), m_sizeDisplayStop.y())); + m_sizeDisplayStart.setX(etk_min(m_position.x(), m_sizeDisplayStart.x())); + m_sizeDisplayStart.setY(etk_min(m_position.y(), m_sizeDisplayStart.y())); + EWOL_VERBOSE("update size 2 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); + } + // update position + m_position = _pos; + m_previousCharcode = 0; + m_vectorialDraw.setPos(m_position); + // update min max of the display area: + if (m_nbCharDisplayed == 0) { + m_sizeDisplayStart = m_position; + m_sizeDisplayStop = m_position; + m_sizeDisplayStop.setY( m_sizeDisplayStop.y()+ getHeight()); + EWOL_VERBOSE("update size 0 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); + } else { + EWOL_VERBOSE("update size 3 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); + m_sizeDisplayStop.setX(etk_max(m_position.x(), m_sizeDisplayStop.x())); + m_sizeDisplayStop.setY(etk_max(m_position.y(), m_sizeDisplayStop.y())); + m_sizeDisplayStart.setX(etk_min(m_position.x(), m_sizeDisplayStart.x())); + m_sizeDisplayStart.setY(etk_min(m_position.y(), m_sizeDisplayStart.y())); + EWOL_VERBOSE("update size 4 " << m_sizeDisplayStart << " " << m_sizeDisplayStop); + } +} + +void ewol::compositing::TextBase::setRelPos(const vec3& _pos) { + m_position += _pos; + m_previousCharcode = 0; + m_vectorialDraw.setPos(m_position); +} + +void ewol::compositing::TextBase::setColorBg(const etk::Color<>& _color) { + m_colorBg = _color; + m_vectorialDraw.setColor(_color); +} + +void ewol::compositing::TextBase::setClipping(const vec3& _pos, const vec3& _posEnd) { + // note the internal system all time request to have a bounding all time in the same order + if (_pos.x() <= _posEnd.x()) { + m_clippingPosStart.setX(_pos.x()); + m_clippingPosStop.setX(_posEnd.x()); + } else { + m_clippingPosStart.setX(_posEnd.x()); + m_clippingPosStop.setX(_pos.x()); + } + if (_pos.y() <= _posEnd.y()) { + m_clippingPosStart.setY(_pos.y()); + m_clippingPosStop.setY(_posEnd.y()); + } else { + m_clippingPosStart.setY(_posEnd.y()); + m_clippingPosStop.setY(_pos.y()); + } + if (_pos.z() <= _posEnd.z()) { + m_clippingPosStart.setZ(_pos.z()); + m_clippingPosStop.setZ(_posEnd.z()); + } else { + m_clippingPosStart.setZ(_posEnd.z()); + m_clippingPosStop.setZ(_pos.z()); + } + m_clippingEnable = true; + //m_vectorialDraw.setClipping(m_clippingPosStart, m_clippingPosStop); +} + +void ewol::compositing::TextBase::setClippingMode(bool _newMode) { + m_clippingEnable = _newMode; + //m_vectorialDraw.setClippingMode(m_clippingEnable); +} + +void ewol::compositing::TextBase::setFontBold(bool _status) { + if (_status == true) { + // enable + if (m_mode == ewol::font::Regular) { + setFontMode(ewol::font::Bold); + } else if (m_mode == ewol::font::Italic) { + setFontMode(ewol::font::BoldItalic); + } + } else { + // disable + if (m_mode == ewol::font::Bold) { + setFontMode(ewol::font::Regular); + } else if (m_mode == ewol::font::BoldItalic) { + setFontMode(ewol::font::Italic); + } + } +} + +void ewol::compositing::TextBase::setFontItalic(bool _status) { + if (_status == true) { + // enable + if (m_mode == ewol::font::Regular) { + setFontMode(ewol::font::Italic); + } else if (m_mode == ewol::font::Bold) { + setFontMode(ewol::font::BoldItalic); + } + } else { + // disable + if (m_mode == ewol::font::Italic) { + setFontMode(ewol::font::Regular); + } else if (m_mode == ewol::font::BoldItalic) { + setFontMode(ewol::font::Bold); + } + } +} + +void ewol::compositing::TextBase::setKerningMode(bool _newMode) { + m_kerning = _newMode; +} + +void ewol::compositing::TextBase::print(const std::u32string& _text) { + std::vector decorationEmpty; + print(_text, decorationEmpty); +} + +void ewol::compositing::TextBase::print(const std::string& _text) { + std::vector decorationEmpty; + print(_text, decorationEmpty); +} + + +void ewol::compositing::TextBase::parseHtmlNode(exml::Element* _element) { + // get the static real pointer + if (_element == NULL) { + EWOL_ERROR( "Error Input node does not existed ..."); + } + for(size_t iii=0; iii< _element->size(); iii++) { + if (_element->getType(iii) == exml::typeComment) { + // nothing to do ... + } else if (_element->getType(iii) == exml::typeText) { + exml::Node* child = _element->getNode(iii); + htmlAddData(std::to_u32string(child->getValue())); + EWOL_VERBOSE("XML add : " << child->getValue()); + continue; + } else if (_element->getType(iii)!=exml::typeElement) { + EWOL_ERROR("(l "<< _element->getNode(iii)->getPos() << ") node not suported type : " << _element->getType(iii) << " val=\""<< _element->getNode(iii)->getValue() << "\"" ); + continue; + } + exml::Element* elem = _element->getElement(iii); + if (elem == NULL) { + EWOL_ERROR("Cast error ..."); + continue; + } + if(compare_no_case(elem->getValue(), "br") == true) { + htmlFlush(); + EWOL_VERBOSE("XML flush & newLine"); + forceLineReturn(); + } else if (compare_no_case(elem->getValue(), "font") == true) { + EWOL_VERBOSE("XML Font ..."); + TextDecoration tmpDeco = m_htmlDecoTmp; + std::string colorValue = elem->getAttribute("color"); + m_htmlDecoTmp.m_colorFg = colorValue; + colorValue = elem->getAttribute("colorBg"); + m_htmlDecoTmp.m_colorBg = colorValue; + parseHtmlNode(elem); + m_htmlDecoTmp = tmpDeco; + } else if( compare_no_case(elem->getValue(), "b") == true + || compare_no_case(elem->getValue(), "bold") == true) { + EWOL_VERBOSE("XML bold ..."); + TextDecoration tmpDeco = m_htmlDecoTmp; + if (m_htmlDecoTmp.m_mode == ewol::font::Regular) { + m_htmlDecoTmp.m_mode = ewol::font::Bold; + } else if (m_htmlDecoTmp.m_mode == ewol::font::Italic) { + m_htmlDecoTmp.m_mode = ewol::font::BoldItalic; + } + parseHtmlNode(elem); + m_htmlDecoTmp = tmpDeco; + } else if( compare_no_case(elem->getValue(), "i") == true + || compare_no_case(elem->getValue(), "italic") == true) { + EWOL_VERBOSE("XML italic ..."); + TextDecoration tmpDeco = m_htmlDecoTmp; + if (m_htmlDecoTmp.m_mode == ewol::font::Regular) { + m_htmlDecoTmp.m_mode = ewol::font::Italic; + } else if (m_htmlDecoTmp.m_mode == ewol::font::Bold) { + m_htmlDecoTmp.m_mode = ewol::font::BoldItalic; + } + parseHtmlNode(elem); + m_htmlDecoTmp = tmpDeco; + } else if( compare_no_case(elem->getValue(), "u") == true + || compare_no_case(elem->getValue(), "underline") == true) { + EWOL_VERBOSE("XML underline ..."); + parseHtmlNode(elem); + } else if( compare_no_case(elem->getValue(), "p") == true + || compare_no_case(elem->getValue(), "paragraph") == true) { + EWOL_VERBOSE("XML paragraph ..."); + htmlFlush(); + m_alignement = alignLeft; + forceLineReturn(); + parseHtmlNode(elem); + forceLineReturn(); + } else if (compare_no_case(elem->getValue(), "center") == true) { + EWOL_VERBOSE("XML center ..."); + htmlFlush(); + m_alignement = alignCenter; + parseHtmlNode(elem); + } else if (compare_no_case(elem->getValue(), "left") == true) { + EWOL_VERBOSE("XML left ..."); + htmlFlush(); + m_alignement = alignLeft; + parseHtmlNode(elem); + } else if (compare_no_case(elem->getValue(), "right") == true) { + EWOL_VERBOSE("XML right ..."); + htmlFlush(); + m_alignement = alignRight; + parseHtmlNode(elem); + } else if (compare_no_case(elem->getValue(), "justify") == true) { + EWOL_VERBOSE("XML justify ..."); + htmlFlush(); + m_alignement = alignJustify; + parseHtmlNode(elem); + } else { + EWOL_ERROR("(l "<< elem->getPos() << ") node not suported type : " << elem->getType() << " val=\""<< elem->getValue() << "\"" ); + } + } +} + +void ewol::compositing::TextBase::printDecorated(const std::string& _text) { + std::string tmpData("\n\n"); + tmpData += _text; + tmpData += "\n\n\n"; + //EWOL_DEBUG("plop : " << tmpData); + printHTML(tmpData); +} + +void ewol::compositing::TextBase::printDecorated(const std::u32string& _text) { + std::u32string tmpData(U"\n\n"); + tmpData += _text; + tmpData += U"\n\n\n"; + //EWOL_DEBUG("plop : " << tmpData); + printHTML(tmpData); +} + +void ewol::compositing::TextBase::printHTML(const std::string& _text) { + exml::Document doc; + + // reset parameter : + m_htmlDecoTmp.m_colorBg = etk::color::none; + m_htmlDecoTmp.m_colorFg = etk::color::black; + m_htmlDecoTmp.m_mode = ewol::font::Regular; + + if (doc.parse(_text) == false) { + EWOL_ERROR( "can not load XML: PARSING error: Decorated text "); + return; + } + + exml::Element* root = (exml::Element*)doc.getNamed( "html" ); + if (root == NULL) { + EWOL_ERROR( "can not load XML: main node not find: \"html\""); + doc.display(); + return; + } + exml::Element* bodyNode = (exml::Element*)root->getNamed( "body" ); + if (root == NULL) { + EWOL_ERROR( "can not load XML: main node not find: \"body\""); + return; + } + (void)parseHtmlNode(bodyNode); + htmlFlush(); +} + +void ewol::compositing::TextBase::printHTML(const std::u32string& _text) { + exml::Document doc; + + // reset parameter : + m_htmlDecoTmp.m_colorBg = etk::color::none; + m_htmlDecoTmp.m_colorFg = etk::color::black; + m_htmlDecoTmp.m_mode = ewol::font::Regular; + // TODO : Create an instance of xml parser to manage std::u32string... + if (doc.parse(std::to_string(_text)) == false) { + EWOL_ERROR( "can not load XML: PARSING error: Decorated text "); + return; + } + + exml::Element* root = (exml::Element*)doc.getNamed( "html" ); + if (root == NULL) { + EWOL_ERROR( "can not load XML: main node not find: \"html\""); + doc.display(); + return; + } + exml::Element* bodyNode = (exml::Element*)root->getNamed( "body" ); + if (root == NULL) { + EWOL_ERROR( "can not load XML: main node not find: \"body\""); + return; + } + (void)parseHtmlNode(bodyNode); + htmlFlush(); +} + +void ewol::compositing::TextBase::print(const std::string& _text, const std::vector& _decoration) { + etk::Color<> tmpFg(m_color); + etk::Color<> tmpBg(m_colorBg); + if (m_alignement == alignDisable) { + //EWOL_DEBUG(" 1 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + // display the cursor if needed (if it is at the start position...) + if (m_needDisplay == true) { + if (0 == m_cursorPos) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + } + // note this is faster when nothing is requested ... + for(size_t iii=0; iii<_text.size(); iii++) { + // check if ve have decoration + if (iii<_decoration.size()) { + tmpFg = _decoration[iii].m_colorFg; + tmpBg = _decoration[iii].m_colorBg; + setFontMode(_decoration[iii].m_mode); + } + // if real display : ( not display is for size calculation) + if (m_needDisplay == true) { + if( ( m_selectionStartPos-1 < (int64_t)iii + && (int64_t)iii <= m_cursorPos-1) + || ( m_selectionStartPos-1 >= (int64_t)iii + && (int64_t)iii > m_cursorPos-1) ) { + setColor( 0x000000FF); + setColorBg(m_colorSelection); + } else { + setColor( tmpFg); + setColorBg(tmpBg); + } + } + if( m_needDisplay == true + && m_colorBg.a() != 0) { + vec3 pos = m_position; + m_vectorialDraw.setPos(pos); + printChar(_text[iii]); + float fontHeigh = getHeight(); + m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); + m_nbCharDisplayed++; + } else { + printChar(_text[iii]); + m_nbCharDisplayed++; + } + // display the cursor if needed (if it is at the other position...) + if (m_needDisplay == true) { + if ((int64_t)iii == m_cursorPos-1) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + } + } + //EWOL_DEBUG(" 2 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + } else { + //EWOL_DEBUG(" 3 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + // special start case at the right of the endpoint : + if (m_stopTextPos < m_position.x()) { + forceLineReturn(); + } + float basicSpaceWidth = calculateSize(char32_t(' ')).x(); + int32_t currentId = 0; + int32_t stop; + int32_t space; + int32_t freeSpace; + while (currentId < (int64_t)_text.size()) { + bool needNoJustify = extrapolateLastId(_text, currentId, stop, space, freeSpace); + float interpolation = basicSpaceWidth; + switch (m_alignement) { + case alignJustify: + if (needNoJustify == false) { + interpolation += (float)freeSpace / (float)(space-1); + } + break; + case alignDisable: // must not came from here ... + case alignLeft: + // nothing to do ... + break; + case alignRight: + if (m_needDisplay == true) { + // Move the first char at the right : + setPos(vec3(m_position.x() + freeSpace, + m_position.y(), + m_position.z()) ); + } + break; + case alignCenter: + if (m_needDisplay == true) { + // Move the first char at the right : + setPos(vec3(m_position.x() + freeSpace/2, + m_position.y(), + m_position.z()) ); + } + break; + } + // display all the elements + if( m_needDisplay == true + && m_cursorPos == 0) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + for(size_t iii=currentId; (int64_t)iii= (int64_t)iii + && (int64_t)iii > m_cursorPos-1) ) { + setColor( 0x000000FF); + setColorBg(m_colorSelection); + } else { + setColor( tmpFg); + setColorBg(tmpBg); + } + } + // special for the justify mode + if ((char32_t)_text[iii] == u32char::Space) { + //EWOL_DEBUG(" generateString : \" \""); + if( m_needDisplay == true + && m_colorBg.a() != 0) { + m_vectorialDraw.setPos(m_position); + } + // Must generate a dynamic space : + setPos(vec3(m_position.x() + interpolation, + m_position.y(), + m_position.z()) ); + if( m_needDisplay == true + && m_colorBg.a() != 0) { + m_vectorialDraw.rectangleWidth(vec3(interpolation,fontHeigh,0.0f) ); + } + } else { + //EWOL_DEBUG(" generateString : \"" << (char)text[iii] << "\""); + if( m_needDisplay == true + && m_colorBg.a() != 0) { + vec3 pos = m_position; + m_vectorialDraw.setPos(pos); + printChar(_text[iii]); + m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); + m_nbCharDisplayed++; + } else { + printChar(_text[iii]); + m_nbCharDisplayed++; + } + } + if (m_needDisplay == true) { + if ((int64_t)iii == m_cursorPos-1) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + } + } + if (currentId == stop) { + currentId++; + } else if((char32_t)_text[stop] == u32char::Space) { + currentId = stop+1; + // reset position : + setPos(vec3(m_startTextpos, + (float)(m_position.y() - getHeight()), + m_position.z()) ); + m_nbCharDisplayed++; + } else if((char32_t)_text[stop] == u32char::Return) { + currentId = stop+1; + // reset position : + setPos(vec3(m_startTextpos, + (float)(m_position.y() - getHeight()), + m_position.z()) ); + m_nbCharDisplayed++; + } else { + currentId = stop; + } + } + //EWOL_DEBUG(" 4 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + } +} + +void ewol::compositing::TextBase::print(const std::u32string& _text, const std::vector& _decoration) { + etk::Color<> tmpFg(m_color); + etk::Color<> tmpBg(m_colorBg); + if (m_alignement == alignDisable) { + //EWOL_DEBUG(" 1 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + // display the cursor if needed (if it is at the start position...) + if (m_needDisplay == true) { + if (0 == m_cursorPos) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + } + // note this is faster when nothing is requested ... + for(size_t iii=0; iii<_text.size(); iii++) { + // check if ve have decoration + if (iii<_decoration.size()) { + tmpFg = _decoration[iii].m_colorFg; + tmpBg = _decoration[iii].m_colorBg; + setFontMode(_decoration[iii].m_mode); + } + // if real display : ( not display is for size calculation) + if (m_needDisplay == true) { + if( ( m_selectionStartPos-1<(int64_t)iii + && (int64_t)iii <= m_cursorPos-1) + || ( m_selectionStartPos-1 >= (int64_t)iii + && (int64_t)iii > m_cursorPos-1) ) { + setColor( 0x000000FF); + setColorBg(m_colorSelection); + } else { + setColor( tmpFg); + setColorBg(tmpBg); + } + } + if( m_needDisplay == true + && m_colorBg.a() != 0) { + vec3 pos = m_position; + m_vectorialDraw.setPos(pos); + printChar(_text[iii]); + float fontHeigh = getHeight(); + m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); + m_nbCharDisplayed++; + } else { + printChar(_text[iii]); + m_nbCharDisplayed++; + } + // display the cursor if needed (if it is at the other position...) + if (m_needDisplay == true) { + if ((int64_t)iii == m_cursorPos-1) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + } + } + //EWOL_DEBUG(" 2 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + } else { + //EWOL_DEBUG(" 3 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + // special start case at the right of the endpoint : + if (m_stopTextPos < m_position.x()) { + forceLineReturn(); + } + float basicSpaceWidth = calculateSize(char32_t(' ')).x(); + int32_t currentId = 0; + int32_t stop; + int32_t space; + int32_t freeSpace; + while (currentId < (int64_t)_text.size()) { + bool needNoJustify = extrapolateLastId(_text, currentId, stop, space, freeSpace); + float interpolation = basicSpaceWidth; + switch (m_alignement) { + case alignJustify: + if (needNoJustify == false) { + interpolation += (float)freeSpace / (float)(space-1); + } + break; + case alignDisable: // must not came from here ... + case alignLeft: + // nothing to do ... + break; + case alignRight: + if (m_needDisplay == true) { + // Move the first char at the right : + setPos(vec3(m_position.x() + freeSpace, + m_position.y(), + m_position.z()) ); + } + break; + case alignCenter: + if (m_needDisplay == true) { + // Move the first char at the right : + setPos(vec3(m_position.x() + freeSpace/2, + m_position.y(), + m_position.z()) ); + } + break; + } + // display all the elements + if( m_needDisplay == true + && m_cursorPos == 0) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + for(size_t iii=currentId; (int64_t)iii= (int64_t)iii + && (int64_t)iii > m_cursorPos-1) ) { + setColor( 0x000000FF); + setColorBg(m_colorSelection); + } else { + setColor( tmpFg); + setColorBg(tmpBg); + } + } + // special for the justify mode + if ((char32_t)_text[iii] == u32char::Space) { + //EWOL_DEBUG(" generateString : \" \""); + if( m_needDisplay == true + && m_colorBg.a() != 0) { + m_vectorialDraw.setPos(m_position); + } + // Must generate a dynamic space : + setPos(vec3(m_position.x() + interpolation, + m_position.y(), + m_position.z()) ); + if( m_needDisplay == true + && m_colorBg.a() != 0) { + m_vectorialDraw.rectangleWidth(vec3(interpolation,fontHeigh,0.0f) ); + } + } else { + //EWOL_DEBUG(" generateString : \"" << (char)text[iii] << "\""); + if( m_needDisplay == true + && m_colorBg.a() != 0) { + vec3 pos = m_position; + m_vectorialDraw.setPos(pos); + printChar(_text[iii]); + m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) ); + m_nbCharDisplayed++; + } else { + printChar(_text[iii]); + m_nbCharDisplayed++; + } + } + if (m_needDisplay == true) { + if ((int64_t)iii == m_cursorPos-1) { + m_vectorialDraw.setPos(m_position); + setColorBg(m_colorCursor); + printCursor(false); + } + } + } + if (currentId == stop) { + currentId++; + } else if(_text[stop] == u32char::Space) { + currentId = stop+1; + // reset position : + setPos(vec3(m_startTextpos, + (float)(m_position.y() - getHeight()), + m_position.z()) ); + m_nbCharDisplayed++; + } else if(_text[stop] == u32char::Return) { + currentId = stop+1; + // reset position : + setPos(vec3(m_startTextpos, + (float)(m_position.y() - getHeight()), + m_position.z()) ); + m_nbCharDisplayed++; + } else { + currentId = stop; + } + } + //EWOL_DEBUG(" 4 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + } +} + + + + +void ewol::compositing::TextBase::forceLineReturn(void) { + // reset position : + setPos(vec3(m_startTextpos, m_position.y() - getHeight(), 0) ); +} + +void ewol::compositing::TextBase::setTextAlignement(float _startTextpos, float _stopTextPos, enum ewol::compositing::aligneMode _alignement) { + m_startTextpos = _startTextpos; + m_stopTextPos = _stopTextPos+1; + m_alignement = _alignement; + if (m_startTextpos >= m_stopTextPos) { + EWOL_ERROR("Request allignement with Borne position error : " << _startTextpos << " => " << _stopTextPos); + } +} + +enum ewol::compositing::aligneMode ewol::compositing::TextBase::getAlignement(void) { + return m_alignement; +} + +void ewol::compositing::TextBase::disableAlignement(void) { + m_alignement = alignDisable; +} + +vec3 ewol::compositing::TextBase::calculateSizeHTML(const std::string& _text) { + // remove intermediate result + reset(); + //EWOL_DEBUG(" 0 size for=\n" << text); + // disable display system + m_needDisplay = false; + + setPos(vec3(0,0,0) ); + // same as print without the end display ... + printHTML(_text); + //EWOL_DEBUG(" 1 Start pos=" << m_sizeDisplayStart); + //EWOL_DEBUG(" 1 Stop pos=" << m_sizeDisplayStop); + + // get the last elements + m_sizeDisplayStop.setValue(etk_max(m_position.x(), m_sizeDisplayStop.x()) , + etk_max(m_position.y(), m_sizeDisplayStop.y()) , + 0); + m_sizeDisplayStart.setValue(etk_min(m_position.x(), m_sizeDisplayStart.x()) , + etk_min(m_position.y(), m_sizeDisplayStart.y()) , + 0); + + //EWOL_DEBUG(" 2 Start pos=" << m_sizeDisplayStart); + //EWOL_DEBUG(" 2 Stop pos=" << m_sizeDisplayStop); + // set back the display system + m_needDisplay = true; + + return vec3( m_sizeDisplayStop.x()-m_sizeDisplayStart.x(), + m_sizeDisplayStop.y()-m_sizeDisplayStart.y(), + m_sizeDisplayStop.z()-m_sizeDisplayStart.z()); +} + +vec3 ewol::compositing::TextBase::calculateSizeHTML(const std::u32string& _text) { + // remove intermediate result + reset(); + //EWOL_DEBUG(" 0 size for=\n" << text); + // disable display system + m_needDisplay = false; + + setPos(vec3(0,0,0) ); + // same as print without the end display ... + printHTML(_text); + //EWOL_DEBUG(" 1 Start pos=" << m_sizeDisplayStart); + //EWOL_DEBUG(" 1 Stop pos=" << m_sizeDisplayStop); + + // get the last elements + m_sizeDisplayStop.setValue(etk_max(m_position.x(), m_sizeDisplayStop.x()) , + etk_max(m_position.y(), m_sizeDisplayStop.y()) , + 0); + m_sizeDisplayStart.setValue(etk_min(m_position.x(), m_sizeDisplayStart.x()) , + etk_min(m_position.y(), m_sizeDisplayStart.y()) , + 0); + + //EWOL_DEBUG(" 2 Start pos=" << m_sizeDisplayStart); + //EWOL_DEBUG(" 2 Stop pos=" << m_sizeDisplayStop); + // set back the display system + m_needDisplay = true; + + return vec3( m_sizeDisplayStop.x()-m_sizeDisplayStart.x(), + m_sizeDisplayStop.y()-m_sizeDisplayStart.y(), + m_sizeDisplayStop.z()-m_sizeDisplayStart.z()); +} + +vec3 ewol::compositing::TextBase::calculateSizeDecorated(const std::string& _text) { + if (_text.size() == 0) { + return vec3(0,0,0); + } + std::string tmpData("\n"); + tmpData+=_text; + tmpData+="\n\n"; + vec3 tmpVal = calculateSizeHTML(tmpData); + return tmpVal; +} + +vec3 ewol::compositing::TextBase::calculateSizeDecorated(const std::u32string& _text) { + if (_text.size() == 0) { + return vec3(0,0,0); + } + std::u32string tmpData(U"\n"); + tmpData += _text; + tmpData += U"\n\n"; + vec3 tmpVal = calculateSizeHTML(tmpData); + return tmpVal; +} + +vec3 ewol::compositing::TextBase::calculateSize(const std::string& _text) { + vec3 outputSize(0, 0, 0); + for(auto element : _text) { + vec3 tmpp = calculateSize(element); + if (outputSize.y() == 0) { + outputSize.setY(tmpp.y()); + } + outputSize.setX( outputSize.x() + tmpp.x()); + } + return outputSize; +} + +vec3 ewol::compositing::TextBase::calculateSize(const std::u32string& _text) { + vec3 outputSize(0, 0, 0); + for(auto element : _text) { + vec3 tmpp = calculateSize(element); + if (outputSize.y() == 0) { + outputSize.setY(tmpp.y()); + } + outputSize.setX( outputSize.x() + tmpp.x()); + } + return outputSize; +} + +vec3 ewol::compositing::TextBase::calculateSize(const char32_t& _charcode) { + // get a pointer on the glyph property : + ewol::GlyphProperty * myGlyph = getGlyphPointer(_charcode); + int32_t fontHeigh = getHeight(); + + // get the kerning ofset : + float kerningOffset = 0.0; + if (true == m_kerning) { + kerningOffset = myGlyph->kerningGet(m_previousCharcode); + } + + vec3 outputSize((float)(myGlyph->m_advance.x() + kerningOffset), + (float)(fontHeigh), + (float)(0.0)); + // Register the previous character + m_previousCharcode = _charcode; + return outputSize; +} + +void ewol::compositing::TextBase::printCursor(bool _isInsertMode, float _cursorSize) { + int32_t fontHeigh = getHeight(); + if (true == _isInsertMode) { + m_vectorialDraw.rectangleWidth(vec3(_cursorSize, fontHeigh, 0) ); + } else { + m_vectorialDraw.setThickness(2); + m_vectorialDraw.lineRel( vec3(0, fontHeigh, 0) ); + m_vectorialDraw.setThickness(0); + } +} + +bool ewol::compositing::TextBase::extrapolateLastId(const std::string& _text, + const int32_t _start, + int32_t& _stop, + int32_t& _space, + int32_t& _freeSpace) { + // store previous : + char32_t storePrevious = m_previousCharcode; + + _stop = _text.size(); + _space = 0; + + int32_t lastSpacePosition = _start; + int32_t lastSpacefreeSize; + + float endPos = m_position.x(); + bool endOfLine = false; + + float stopPosition = m_stopTextPos; + if( m_needDisplay == false + || m_stopTextPos == m_startTextpos) { + stopPosition = m_startTextpos + 3999999999.0; + } + + for (size_t iii=_start; iii<_text.size(); iii++) { + vec3 tmpSize = calculateSize(_text[iii]); + // check oveflow : + if (endPos + tmpSize.x() > stopPosition) { + _stop = iii; + break; + } + // save number of space : + if ((char32_t)_text[iii] == u32char::Space) { + _space++; + lastSpacePosition = iii; + lastSpacefreeSize = stopPosition - endPos; + } else if ((char32_t)_text[iii] == u32char::Return) { + _stop = iii; + endOfLine = true; + break; + } + // update local size : + endPos += tmpSize.x(); + } + _freeSpace = stopPosition - endPos; + // retore previous : + m_previousCharcode = storePrevious; + // need to align left or right ... + if(_stop == (int64_t)_text.size()) { + return true; + } else { + if (endOfLine) { + return true; + } else { + if (_space == 0) { + return true; + } + _stop = lastSpacePosition; + _freeSpace = lastSpacefreeSize; + return false; + } + } +} + +bool ewol::compositing::TextBase::extrapolateLastId(const std::u32string& _text, + const int32_t _start, + int32_t& _stop, + int32_t& _space, + int32_t& _freeSpace) { + // store previous : + char32_t storePrevious = m_previousCharcode; + + _stop = _text.size(); + _space = 0; + + int32_t lastSpacePosition = _start; + int32_t lastSpacefreeSize; + + float endPos = m_position.x(); + bool endOfLine = false; + + float stopPosition = m_stopTextPos; + if( m_needDisplay == false + || m_stopTextPos == m_startTextpos) { + stopPosition = m_startTextpos + 3999999999.0; + } + + for (size_t iii=_start; iii<_text.size(); iii++) { + vec3 tmpSize = calculateSize(_text[iii]); + // check oveflow : + if (endPos + tmpSize.x() > stopPosition) { + _stop = iii; + break; + } + // save number of space : + if (_text[iii] == u32char::Space) { + _space++; + lastSpacePosition = iii; + lastSpacefreeSize = stopPosition - endPos; + } else if (_text[iii] == u32char::Return) { + _stop = iii; + endOfLine = true; + break; + } + // update local size : + endPos += tmpSize.x(); + } + _freeSpace = stopPosition - endPos; + // retore previous : + m_previousCharcode = storePrevious; + // need to align left or right ... + if(_stop == (int64_t)_text.size()) { + return true; + } else { + if (endOfLine) { + return true; + } else { + if (_space == 0) { + return true; + } + _stop = lastSpacePosition; + _freeSpace = lastSpacefreeSize; + return false; + } + } +} + +void ewol::compositing::TextBase::htmlAddData(const std::u32string& _data) { + if( m_htmlCurrrentLine.size()>0 + && m_htmlCurrrentLine[m_htmlCurrrentLine.size()-1] != ' ') { + m_htmlCurrrentLine += U" "; + if(m_htmlDecoration.size()>0) { + TextDecoration tmp = m_htmlDecoration[m_htmlDecoration.size()-1]; + m_htmlDecoration.push_back(tmp); + } else { + m_htmlDecoration.push_back(m_htmlDecoTmp); + } + } + m_htmlCurrrentLine += _data; + for(size_t iii=0; iii<_data.size() ; iii++) { + m_htmlDecoration.push_back(m_htmlDecoTmp); + } +} + +void ewol::compositing::TextBase::htmlFlush(void) { + if (m_htmlCurrrentLine.size()>0) { + print(m_htmlCurrrentLine, m_htmlDecoration); + } + m_htmlCurrrentLine = U""; + m_htmlDecoration.clear(); +} + +void ewol::compositing::TextBase::disableCursor(void) { + m_selectionStartPos = -100; + m_cursorPos = -100; +} + +void ewol::compositing::TextBase::setCursorPos(int32_t _cursorPos) { + m_selectionStartPos = _cursorPos; + m_cursorPos = _cursorPos; +} + +void ewol::compositing::TextBase::setCursorSelection(int32_t _cursorPos, int32_t _selectionStartPos) { + m_selectionStartPos = _selectionStartPos; + m_cursorPos = _cursorPos; +} + +void ewol::compositing::TextBase::setSelectionColor(const etk::Color<>& _color) { + m_colorSelection = _color; +} + +void ewol::compositing::TextBase::setCursorColor(const etk::Color<>& _color) { + m_colorCursor = _color; +} diff --git a/sources/ewol/compositing/TextBase.h b/sources/ewol/compositing/TextBase.h new file mode 100644 index 00000000..ab0a22e6 --- /dev/null +++ b/sources/ewol/compositing/TextBase.h @@ -0,0 +1,470 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_COMPOSITING_TEXT_BASE_H__ +#define __EWOL_COMPOSITING_TEXT_BASE_H__ + +#include + +#include +#include +#include +#include +#include +#include + +namespace ewol { + namespace compositing { + /** + * @brief This class represent the specific display for every char in the string ... + * @not-in-doc + */ + class TextDecoration { + public: + etk::Color<> m_colorBg; //!< display background color + etk::Color<> m_colorFg; //!< display foreground color + enum ewol::font::mode m_mode; //!< display mode Regular/Bold/Italic/BoldItalic + TextDecoration(void) { + m_colorBg = etk::color::blue; + m_colorBg = etk::color::green; + m_mode = ewol::font::Regular; + } + }; + + enum aligneMode { + alignDisable, + alignRight, + alignLeft, + alignCenter, + alignJustify + }; + + class TextBase : public ewol::Compositing { + protected: + ewol::compositing::Drawing m_vectorialDraw; //!< This is used to draw background selection and other things ... + public: + virtual ewol::compositing::Drawing& getDrawing(void) { + return m_vectorialDraw; + }; + protected: + int32_t m_nbCharDisplayed; //!< prevent some error in calculation size. + vec3 m_sizeDisplayStart; //!< The start windows of the display. + vec3 m_sizeDisplayStop; //!< The end windows of the display. + bool m_needDisplay; //!< This just need the display and not the size rendering. + vec3 m_position; //!< The current position to draw + vec3 m_clippingPosStart; //!< Clipping start position + vec3 m_clippingPosStop; //!< Clipping stop position + bool m_clippingEnable; //!< true if the clipping must be activated + protected: + etk::Color<> m_color; //!< The text foreground color + etk::Color<> m_colorBg; //!< The text background color + etk::Color<> m_colorCursor; //!< The text cursor color + etk::Color<> m_colorSelection; //!< The text Selection color + protected: + enum ewol::font::mode m_mode; //!< font display property : Regular/Bold/Italic/BoldItalic + bool m_kerning; //!< Kerning enable or disable on the next elements displayed + char32_t m_previousCharcode; //!< we remember the previous charcode to perform the kerning. @ref Kerning + protected: + float m_startTextpos; //!< start position of the Alignement (when \n the text return at this position) + float m_stopTextPos; //!< end of the alignement (when a string is too hight it cut at the word previously this virtual line and the center is perform with this one) + enum aligneMode m_alignement; //!< Current Alignement mode (justify/left/right ...) + protected: + ewol::resource::Program* m_GLprogram; //!< pointer on the opengl display program + int32_t m_GLPosition; //!< openGL id on the element (vertex buffer) + int32_t m_GLMatrix; //!< openGL id on the element (transformation matrix) + int32_t m_GLColor; //!< openGL id on the element (color buffer) + int32_t m_GLtexture; //!< openGL id on the element (Texture position) + int32_t m_GLtexID; //!< openGL id on the element (texture ID) + protected: + int32_t m_selectionStartPos; //!< start position of the Selection (if == m_cursorPos ==> no selection) + int32_t m_cursorPos; //!< Cursor position (default no cursor == > -100) + protected: // Text + std::vector m_coord; //!< internal coord of the object + std::vector m_coordTex; //!< internal texture coordinate for every point + std::vector > m_coordColor; //!< internal color of the different point + protected: + /** + * @brief load the openGL program and get all the ID needed + */ + void loadProgram(const std::string& _shaderName); + public: + /** + * @brief generic constructor + */ + TextBase(const std::string& _shaderName="DATA:text.prog"); + /** + * @brief generic destructor + */ + virtual ~TextBase(void); + public: // Derived function + void translate(const vec3& _vect); + void rotate(const vec3& _vect, float _angle); + void scale(const vec3& _vect); + public: + /** + * @brief draw All the refistered text in the current element on openGL + */ + void draw(bool _disableDepthTest=true) { + drawD(_disableDepthTest); + } + /** + * @previous + */ + void draw(const mat4& _transformationMatrix, bool _enableDepthTest=false) { + drawMT(_transformationMatrix, _enableDepthTest); + } + /** + * @brief draw All the refistered text in the current element on openGL + */ + virtual void drawD(bool _disableDepthTest) = 0; + /** + * @previous + */ + virtual void drawMT(const mat4& _transformationMatrix, bool _enableDepthTest) = 0; + /** + * @brief clear all the registered element in the current element + */ + virtual void clear(void); + /** + * @brief clear all the intermediate result detween 2 prints + */ + virtual void reset(void); + /** + * @brief get the current display position (sometime needed in the gui control) + * @return the current position. + */ + const vec3& getPos(void) { + return m_position; + }; + /** + * @brief set position for the next text writen + * @param[in] _pos Position of the text (in 3D) + */ + void setPos(const vec3& _pos); + /** + * @previous + */ + inline void setPos(const vec2& _pos) { + setPos(vec3(_pos.x(),_pos.y(),0)); + }; + /** + * @brief set relative position for the next text writen + * @param[in] _pos ofset apply of the text (in 3D) + */ + void setRelPos(const vec3& _pos); + /** + * @previous + */ + inline void setRelPos(const vec2& _pos) { + setRelPos(vec3(_pos.x(),_pos.y(),0)); + }; + /** + * @brief set the Color of the current foreground font + * @param[in] _color Color to set on foreground (for next print) + */ + void setColor(const etk::Color<>& _color) { m_color = _color; }; + /** + * @brief set the background color of the font (for selected Text (not the global BG)) + * @param[in] _color Color to set on background (for next print) + */ + void setColorBg(const etk::Color<>& _color); + /** + * @brief Request a clipping area for the text (next draw only) + * @param[in] _pos Start position of the clipping + * @param[in] _width Width size of the clipping + */ + void setClippingWidth(const vec3& _pos, const vec3& _width) { + setClipping(_pos, _pos+_width); + } + /** + * @previous + */ + void setClippingWidth(const vec2& _pos, const vec2& _width) { + setClipping(_pos, _pos+_width); + }; + /** + * @brief Request a clipping area for the text (next draw only) + * @param[in] _pos Start position of the clipping + * @param[in] _posEnd End position of the clipping + */ + void setClipping(const vec3& _pos, const vec3& _posEnd); + /** + * @previous + */ + void setClipping(const vec2& _pos, const vec2& _posEnd) { + setClipping(vec3(_pos.x(),_pos.y(),-1), vec3(_posEnd.x(),_posEnd.y(),1) ); + }; + /** + * @brief enable/Disable the clipping (without lose the current clipping position) + * @brief _newMode The new status of the clipping + */ + // TODO : Rename setClippingActivity + void setClippingMode(bool _newMode); + /** + * @brief Specify the font size (this reset the internal element of the current text (system requirement) + * @param[in] _fontSize New font size + */ + virtual void setFontSize(int32_t _fontSize) = 0; + /** + * @brief Specify the font name (this reset the internal element of the current text (system requirement) + * @param[in] _fontName Current name of the selected font + */ + virtual void setFontName(const std::string& _fontName) = 0; + /** + * @brief Specify the font property (this reset the internal element of the current text (system requirement) + * @param[in] fontName Current name of the selected font + * @param[in] fontSize New font size + */ + virtual void setFont(std::string _fontName, int32_t _fontSize) = 0; + /** + * @brief Specify the font mode for the next @ref print + * @param[in] mode The font mode requested + */ + virtual void setFontMode(enum ewol::font::mode _mode) = 0; + /** + * @brief get the current font mode + * @return The font mode applied + */ + enum ewol::font::mode getFontMode(void) { + return m_mode; + }; + virtual float getHeight(void) = 0; + virtual float getSize(void) = 0; + virtual ewol::GlyphProperty * getGlyphPointer(char32_t _charcode) = 0; + /** + * @brief enable or disable the bold mode + * @param[in] _status The new status for this display property + */ + void setFontBold(bool _status); + /** + * @brief enable or disable the italic mode + * @param[in] _status The new status for this display property + */ + void setFontItalic(bool _status); + /** + * @brief set the activation of the Kerning for the display (if it existed) + * @param[in] _newMode enable/Diasable the kerning on this font. + */ + void setKerningMode(bool _newMode); + /** + * @brief display a compleat string in the current element. + * @param[in] _text The string to display. + */ + void print(const std::string& _text); + /** + * @previous + */ + void print(const std::u32string& _text); + /** + * @brief display a compleat string in the current element with the generic decoration specification. (basic html data) + * + * [code style=xml] + *
+ *


+ *
+ * text exemple in bold other text bold part boldItalic part an other thext + * colored text bold color text bold italic text normal color text the end of the string
+ * an an other thext + *
+ *


+ * + * plop 1 + * + *


+ * + * plop 2 + * + *


+ * + * Un exemple de text + * + * [/code] + * + * @note This is parsed with tiny xml, then be carfull that the XML is correct, and all balises are closed ... otherwite the display can not be done + * @param[in] _text The string to display. + * @TODO : implementation not done .... + */ + void printDecorated(const std::string& _text); + //! @previous + void printDecorated(const std::u32string& _text); + /** + * @brief display a compleat string in the current element with the generic decoration specification. (basic html data) + * + * [code style=xml] + * + * + *
+ *


+ *
+ * text exemple in bold other text bold part boldItalic part an other thext + * colored text bold color text bold italic text normal color text the end of the string
+ * an an other thext + *
+ *


+ * + * plop 1 + * + *


+ * + * plop 2 + * + *


+ * + * Un exemple de text + * + * + * + * [/code] + * + * @note This is parsed with tiny xml, then be carfull that the XML is correct, and all balises are closed ... otherwite the display can not be done + * @param[in] _text The string to display. + * @TODO : implementation not done .... + */ + void printHTML(const std::string& _text); + //! @previous + void printHTML(const std::u32string& _text); + /** + * @brief display a compleat string in the current element whith specific decorations (advence mode). + * @param[in] _text The string to display. + * @param[in] _decoration The text decoration for the text that might be display (if the vector is smaller, the last parameter is get) + */ + void print(const std::string& _text, const std::vector& _decoration); + //! @previous + void print(const std::u32string& _text, const std::vector& _decoration); + /** + * @brief display the current char in the current element (note that the kerning is availlable if the position is not changed) + * @param[in] _charcode Char that might be dispalyed + */ + virtual void printChar(const char32_t& _charcode) = 0; + /** + * @brief This generate the line return == > it return to the alignement position start and at the correct line position ==> it might be use to not know the line height + */ + void forceLineReturn(void); + protected: + /** + * @brief This parse a tinyXML node (void pointer to permit to hide tiny XML in include). + * @param[in] _element the exml element. + */ + void parseHtmlNode(exml::Element* _element); + public: + /** + * @brief This generate the possibility to generate the big text property + * @param[in] _startTextpos The x text start position of the display. + * @param[in] _stopTextPos The x text stop position of the display. + * @param[in] _alignement mode of alignement for the Text. + * @note The text align in center change of line every display done (even if it was just a char) + */ + void setTextAlignement(float _startTextpos, float _stopTextPos, enum ewol::compositing::aligneMode _alignement=ewol::compositing::alignDisable); + /** + * @brief disable the alignement system + */ + void disableAlignement(void); + /** + * @brief get the current alignement property + * @return the curent alignement type + */ + enum ewol::compositing::aligneMode getAlignement(void); + /** + * @brief calculate a theoric text size + * @param[in] _text The string to calculate dimention. + * @return The theoric size used. + */ + vec3 calculateSizeHTML(const std::string& _text); + //!@previous + vec3 calculateSizeHTML(const std::u32string& _text); + /** + * @brief calculate a theoric text size + * @param[in] _text The string to calculate dimention. + * @return The theoric size used. + */ + vec3 calculateSizeDecorated(const std::string& _text); + //!@previous + vec3 calculateSizeDecorated(const std::u32string& _text); + /** + * @brief calculate a theoric text size + * @param[in] _text The string to calculate dimention. + * @return The theoric size used. + */ + vec3 calculateSize(const std::string& _text); + //!@previous + vec3 calculateSize(const std::u32string& _text); + /** + * @brief calculate a theoric charcode size + * @param[in] _charcode The µUnicode value to calculate dimention. + * @return The theoric size used. + */ + vec3 calculateSize(const char32_t& _charcode); + /** + * @brief draw a cursor at the specify position + * @param[in] _isInsertMode True if the insert mode is activated + * @param[in] _cursorSize The sizae of the cursor that might be set when insert mode is set [default 20] + */ + void printCursor(bool _isInsertMode, float _cursorSize = 20.0f); + protected: + /** + * @brief calculate the element number that is the first out the alignement range + * (start at the specify ID, and use start pos with current one) + * @param[in] _text The string that might be parsed. + * @param[in] _start The first elemnt that might be used to calculate. + * @param[out] _stop The last Id availlable in the current string. + * @param[out] _space Number of space in the string. + * @param[out] _freespace This represent the number of pixel present in the right white space. + * @return true if the rifht has free space that can be use for jystify. + * @return false if we find '\n' + */ + bool extrapolateLastId(const std::string& _text, const int32_t _start, int32_t& _stop, int32_t& _space, int32_t& _freeSpace); + /** + * @previous + */ + bool extrapolateLastId(const std::u32string& _text, const int32_t _start, int32_t& _stop, int32_t& _space, int32_t& _freeSpace); + protected: + // this section is reserved for HTML parsing and display: + std::u32string m_htmlCurrrentLine; //!< current line for HTML display + std::vector m_htmlDecoration; //!< current decoration for the HTML display + TextDecoration m_htmlDecoTmp; //!< current decoration + /** + * @brief add a line with the current m_htmlDecoTmp decoration + * @param[in] _data The cuurent data to add. + */ + void htmlAddData(const std::u32string& _data); + /** + * @brief draw the current line + */ + void htmlFlush(void); + public: + /** + * @brief remove the cursor display + */ + void disableCursor(void); + /** + * @brief set a cursor at a specific position: + * @param[in] _cursorPos id of the cursor position + */ + void setCursorPos(int32_t _cursorPos); + /** + * @brief set a cursor at a specific position with his associated selection: + * @param[in] _cursorPos id of the cursor position + * @param[in] _selectionStartPos id of the starting of the selection + */ + void setCursorSelection(int32_t _cursorPos, int32_t _selectionStartPos); + /** + * @brief change the selection color + * @param[in] _color New color for the Selection + */ + void setSelectionColor(const etk::Color<>& _color); + /** + * @brief change the cursor color + * @param[in] _color New color for the Selection + */ + void setCursorColor(const etk::Color<>& _color); + }; + }; +}; + +#endif + diff --git a/sources/ewol/compositing/TextBasic.cpp b/sources/ewol/compositing/TextBasic.cpp new file mode 100644 index 00000000..e69de29b diff --git a/sources/ewol/compositing/TextBasic.h b/sources/ewol/compositing/TextBasic.h new file mode 100644 index 00000000..e69de29b diff --git a/sources/ewol/compositing/TextDF.cpp b/sources/ewol/compositing/TextDF.cpp index 65036bae..218cb89f 100644 --- a/sources/ewol/compositing/TextDF.cpp +++ b/sources/ewol/compositing/TextDF.cpp @@ -16,11 +16,11 @@ ewol::compositing::TextDF::TextDF(const std::string& _fontName, int32_t _fontSize) : - ewol::compositing::Text::Text(_fontName, _fontSize, false), + ewol::compositing::TextBase("DATA:fontDistanceField/font1.prog"), m_fontDF(NULL), - m_size(9.0) { + m_size(12.0) { setFont(_fontName, _fontSize); - loadProgram("DATA:fontDistanceField/font1.prog"); + // TODO : Reset size .... when reset ... } @@ -35,7 +35,6 @@ void ewol::compositing::TextDF::drawMT(const mat4& _transformationMatrix, bool _ EWOL_WARNING("draw DF..."); if (m_coord.size() <= 0 || m_fontDF == NULL) { - // TODO : a remÚtre ... //EWOL_WARNING("Nothink to draw..."); return; } @@ -59,11 +58,11 @@ void ewol::compositing::TextDF::drawMT(const mat4& _transformationMatrix, bool _ // TextureID m_GLprogram->setTexture0(m_GLtexID, m_fontDF->getId()); // position : - m_GLprogram->sendAttribute(m_GLPosition, 2/*x,y*/, &m_coord[0]); + m_GLprogram->sendAttribute(m_GLPosition, m_coord); // Texture : - m_GLprogram->sendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]); + m_GLprogram->sendAttribute(m_GLtexture, m_coordTex); // color : - m_GLprogram->sendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + m_GLprogram->sendAttribute(m_GLColor, m_coordColor); // Request the draw od the elements : ewol::openGL::drawArrays(GL_TRIANGLES, 0, m_coord.size()); m_GLprogram->unUse(); @@ -98,11 +97,11 @@ void ewol::compositing::TextDF::drawD(bool _disableDepthTest) { // TextureID m_GLprogram->setTexture0(m_GLtexID, m_fontDF->getId()); // position : - m_GLprogram->sendAttribute(m_GLPosition, 2/*x,y*/, &m_coord[0]); + m_GLprogram->sendAttribute(m_GLPosition, m_coord); // Texture : - m_GLprogram->sendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]); + m_GLprogram->sendAttribute(m_GLtexture, m_coordTex); // color : - m_GLprogram->sendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + m_GLprogram->sendAttribute(m_GLColor, m_coordColor); // Request the draw od the elements : ewol::openGL::drawArrays(GL_TRIANGLES, 0, m_coord.size()); m_GLprogram->unUse(); @@ -163,3 +162,180 @@ void ewol::compositing::TextDF::setFont(std::string _fontName, int32_t _fontSize void ewol::compositing::TextDF::setFontMode(enum ewol::font::mode _mode) { m_mode = _mode; } + + +void ewol::compositing::TextDF::printChar(const char32_t& _charcode) { + // get a pointer on the glyph property : + ewol::GlyphProperty* myGlyph = getGlyphPointer(_charcode); + if (NULL == myGlyph) { + EWOL_ERROR(" font does not really existed ..."); + return; + } + float fontSize = getSize(); + float fontHeigh = getHeight(); + + float factorDisplay = m_fontDF->getDisplayRatio(fontSize); + + // get the kerning ofset : + float kerningOffset = 0; + if (true == m_kerning) { + kerningOffset = myGlyph->kerningGet(m_previousCharcode); + if (kerningOffset != 0) { + //EWOL_DEBUG("Kerning between : '" << m_previousCharcode << "'&'" << myGlyph->m_UVal << "' value : " << kerningOffset); + } + } + // 0x01 == 0x20 == ' '; + if (_charcode != 0x01) { + /* Bitmap position + * xA xB + * yC *------* + * | | + * | | + * yD *------* + */ + #if 0 + float dxA = m_position.x() + (myGlyph->m_bearing.x() + kerningOffset) * factorDisplay; + float dxB = dxA + myGlyph->m_sizeTexture.x() * factorDisplay; + float dyC = m_position.y() + (myGlyph->m_bearing.y() + fontHeigh - fontSize) * factorDisplay; + float dyD = dyC - myGlyph->m_sizeTexture.y() * factorDisplay; + #else + float dxA = m_position.x() + (myGlyph->m_bearing.x() + kerningOffset - (float)m_fontDF->getPixelBorderSize()*0.5f) * factorDisplay; + float dxB = dxA + (myGlyph->m_sizeTexture.x() + (float)m_fontDF->getPixelBorderSize()) * factorDisplay; + float dyC = m_position.y() + (myGlyph->m_bearing.y() + fontHeigh - fontSize + (float)m_fontDF->getPixelBorderSize()*0.5f) * factorDisplay; + float dyD = dyC - (myGlyph->m_sizeTexture.y() + (float)m_fontDF->getPixelBorderSize()) * factorDisplay; + #endif + + float tuA = myGlyph->m_texturePosStart.x(); + float tuB = tuA + myGlyph->m_texturePosSize.x(); + float tvC = myGlyph->m_texturePosStart.y(); + float tvD = tvC + myGlyph->m_texturePosSize.y(); + + + // Clipping and drawing area + if( m_clippingEnable == true + && ( dxB < m_clippingPosStart.x() + || dxA > m_clippingPosStop.x() + || dyC < m_clippingPosStart.y() + || dyD > m_clippingPosStop.y() ) ) { + // Nothing to diplay ... + } else { + if (m_clippingEnable == true) { + // generata positions... + float TexSizeX = tuB - tuA; + if (dxA < m_clippingPosStart.x()) { + // clip display + float drawSize = m_clippingPosStart.x() - dxA; + // update element start display + dxA = m_clippingPosStart.x(); + float addElement = TexSizeX * drawSize / ((float)myGlyph->m_sizeTexture.x() * factorDisplay); + // update texture start X Pos + tuA += addElement; + } + if (dxB > m_clippingPosStop.x()) { + // clip display + float drawSize = dxB - m_clippingPosStop.x(); + // update element start display + dxB = m_clippingPosStop.x(); + float addElement = TexSizeX * drawSize / ((float)myGlyph->m_sizeTexture.x() * factorDisplay); + // update texture start X Pos + tuB -= addElement; + } + float TexSizeY = tvC - tvD; + if (dyC > m_clippingPosStop.y()) { + // clip display + float drawSize = dyC - m_clippingPosStop.y(); + // update element start display + dyC = m_clippingPosStop.y(); + float addElement = TexSizeY * drawSize / ((float)myGlyph->m_sizeTexture.y() * factorDisplay); + // update texture start X Pos + tvC -= addElement; + } + if (dyD < m_clippingPosStart.y()) { + // clip display + float drawSize = m_clippingPosStart.y() - dyD; + // update element start display + dyD = m_clippingPosStart.y(); + float addElement = TexSizeY * drawSize / ((float)myGlyph->m_sizeTexture.y() * factorDisplay); + // update texture start X Pos + tvD += addElement; + } + } + if( dxB <= dxA + || dyD >= dyC) { + // nothing to do ... + } else { + /* Bitmap position + * 0------1 + * | | + * | | + * 3------2 + */ + if (m_needDisplay == true) { + vec3 bitmapDrawPos[4]; + bitmapDrawPos[0].setValue(dxA, dyC, 0); + bitmapDrawPos[1].setValue(dxB, dyC, 0); + bitmapDrawPos[2].setValue(dxB, dyD, 0); + bitmapDrawPos[3].setValue(dxA, dyD, 0); + /* texture Position : + * 0------1 + * | | + * | | + * 3------2 + */ + vec2 texturePos[4]; + texturePos[0].setValue(tuA+m_mode, tvC); + texturePos[1].setValue(tuB+m_mode, tvC); + texturePos[2].setValue(tuB+m_mode, tvD); + texturePos[3].setValue(tuA+m_mode, tvD); + + // NOTE : Android does not support the Quads elements ... + /* Step 1 : + * ******** + * ****** + * **** + * ** + * + */ + // set texture coordonates : + m_coordTex.push_back(texturePos[0]); + m_coordTex.push_back(texturePos[1]); + m_coordTex.push_back(texturePos[2]); + // set display positions : + m_coord.push_back(bitmapDrawPos[0]); + m_coord.push_back(bitmapDrawPos[1]); + m_coord.push_back(bitmapDrawPos[2]); + // set the color + m_coordColor.push_back(m_color); + m_coordColor.push_back(m_color); + m_coordColor.push_back(m_color); + /* Step 2 : + * + * ** + * **** + * ****** + * ******** + */ + // set texture coordonates : + m_coordTex.push_back(texturePos[0]); + m_coordTex.push_back(texturePos[2]); + m_coordTex.push_back(texturePos[3]); + // set display positions : + m_coord.push_back(bitmapDrawPos[0]); + m_coord.push_back(bitmapDrawPos[2]); + m_coord.push_back(bitmapDrawPos[3]); + // set the color + m_coordColor.push_back(m_color); + m_coordColor.push_back(m_color); + m_coordColor.push_back(m_color); + } + } + } + } + // move the position : + //EWOL_DEBUG(" 5 pos=" << m_position << " advance=" << myGlyph->m_advance.x() << " kerningOffset=" << kerningOffset); + m_position.setX(m_position.x() + (myGlyph->m_advance.x() + kerningOffset) * factorDisplay); + //EWOL_DEBUG(" 6 print '" << charcode << "' : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position); + // Register the previous character + m_previousCharcode = _charcode; + return; +} \ No newline at end of file diff --git a/sources/ewol/compositing/TextDF.h b/sources/ewol/compositing/TextDF.h index 9df52df4..14e82417 100644 --- a/sources/ewol/compositing/TextDF.h +++ b/sources/ewol/compositing/TextDF.h @@ -15,13 +15,13 @@ #include #include #include -#include +#include #include #include namespace ewol { namespace compositing { - class TextDF : public ewol::compositing::Text { + class TextDF : public ewol::compositing::TextBase { protected: ewol::resource::DistanceFieldFont* m_fontDF; //!< Font resources public: @@ -37,9 +37,6 @@ namespace ewol { virtual ~TextDF(void); public: virtual void drawD(bool _disableDepthTest); - /** - * @previous - */ virtual void drawMT(const mat4& _transformationMatrix, bool _enableDepthTest); protected: float m_size; @@ -55,6 +52,7 @@ namespace ewol { virtual void setFontName(const std::string& _fontName); virtual void setFont(std::string _fontName, int32_t _fontSize); virtual void setFontMode(enum ewol::font::mode _mode); + virtual void printChar(const char32_t& _charcode); }; }; }; diff --git a/sources/ewol/resource/DistanceFieldFont.cpp b/sources/ewol/resource/DistanceFieldFont.cpp index 1e5a7344..518aa76f 100644 --- a/sources/ewol/resource/DistanceFieldFont.cpp +++ b/sources/ewol/resource/DistanceFieldFont.cpp @@ -25,7 +25,9 @@ #define SIZE_GENERATION (70) ewol::resource::DistanceFieldFont::DistanceFieldFont(const std::string& _fontName) : - ewol::resource::Texture(_fontName) { + ewol::resource::Texture(_fontName), + m_borderSize(10), + m_textureBorderSize(0,0) { addObjectType("ewol::resource::DistanceFieldFont"); m_font = NULL; m_lastGlyphPos.setValue(1,1); @@ -115,7 +117,13 @@ ewol::resource::DistanceFieldFont::~DistanceFieldFont(void) { ewol::resource::FontFreeType::release(m_font); } -void ewol::resource::DistanceFieldFont::GenerateDistanceField(const egami::ImageMono& _input, egami::Image& _output) { + +float ewol::resource::DistanceFieldFont::getDisplayRatio(float _size) { + return _size / (float)SIZE_GENERATION; +} + + +void ewol::resource::DistanceFieldFont::generateDistanceField(const egami::ImageMono& _input, egami::Image& _output) { int32_t size = _input.getSize().x() * _input.getSize().y(); std::vector xdist(size); std::vector ydist(size); @@ -225,10 +233,13 @@ bool ewol::resource::DistanceFieldFont::addGlyph(const char32_t& _val) { m_listElement[jjj].m_texturePosSize *= vec2(1.0f, 0.5f); } } + m_textureBorderSize = vec2(m_borderSize/(float)m_data.getSize().x(), + m_borderSize/(float)m_data.getSize().y() ); // draw the glyph - m_font->drawGlyph(imageGlyphRaw, SIZE_GENERATION, tmpchar, 5); + m_font->drawGlyph(imageGlyphRaw, SIZE_GENERATION, tmpchar, m_borderSize); - GenerateDistanceField(imageGlyphRaw, imageGlyphDistanceField); + generateDistanceField(imageGlyphRaw, imageGlyphDistanceField); + /* if (_val == 'Z') { for (int32_t yyy = 0; yyy < imageGlyphDistanceField.getSize().y(); ++yyy) { for (int32_t xxx = 0; xxx < imageGlyphDistanceField.getSize().x(); ++xxx) { @@ -237,13 +248,14 @@ bool ewol::resource::DistanceFieldFont::addGlyph(const char32_t& _val) { //std::cout << std::endl; } } + */ m_data.insert(m_lastGlyphPos, imageGlyphDistanceField); // set image position - tmpchar.m_texturePosStart.setValue( (float)m_lastGlyphPos.x() / (float)m_data.getSize().x(), - (float)m_lastGlyphPos.y() / (float)m_data.getSize().y() ); - tmpchar.m_texturePosSize.setValue( (float)imageGlyphRaw.getSize().x() / (float)m_data.getSize().x(), - (float)imageGlyphRaw.getSize().y() / (float)m_data.getSize().y() ); + tmpchar.m_texturePosStart.setValue( ((float)m_lastGlyphPos.x()+(m_borderSize*0.5f)) / (float)m_data.getSize().x(), + ((float)m_lastGlyphPos.y()+(m_borderSize*0.5f)) / (float)m_data.getSize().y() ); + tmpchar.m_texturePosSize.setValue( ((float)imageGlyphRaw.getSize().x()-m_borderSize) / (float)m_data.getSize().x(), + ((float)imageGlyphRaw.getSize().y()-m_borderSize) / (float)m_data.getSize().y() ); // update the maximum of the line hight : if (m_lastRawHeigh < imageGlyphRaw.getSize().y()) { @@ -266,7 +278,7 @@ bool ewol::resource::DistanceFieldFont::addGlyph(const char32_t& _val) { } if (hasChange == true) { flush(); - //egami::store(m_data, "fileFont.bmp"); // ==> for debug test only ... + egami::store(m_data, "fileFont.bmp"); // ==> for debug test only ... } return hasChange; } diff --git a/sources/ewol/resource/DistanceFieldFont.h b/sources/ewol/resource/DistanceFieldFont.h index 9ee710b1..94db8b28 100644 --- a/sources/ewol/resource/DistanceFieldFont.h +++ b/sources/ewol/resource/DistanceFieldFont.h @@ -34,6 +34,7 @@ namespace ewol { DistanceFieldFont(const std::string& _fontName); ~DistanceFieldFont(void); public: + float getDisplayRatio(float _size); /** * @brief get the display height of this font * @param[in] _size Request font size @@ -75,7 +76,17 @@ namespace ewol { */ bool addGlyph(const char32_t& _val); - void GenerateDistanceField(const egami::ImageMono& _input, egami::Image& _output); + void generateDistanceField(const egami::ImageMono& _input, egami::Image& _output); + private: + float m_borderSize; //!< number of pixel added on the border of a glyph + vec2 m_textureBorderSize; //!< Transformed the border size in the texture dimention + public: + float getPixelBorderSize(void) { + return m_borderSize; + } + const vec2& getTextureBorderSize(void) { + return m_textureBorderSize; + } }; }; }; diff --git a/sources/ewol/resource/Program.cpp b/sources/ewol/resource/Program.cpp index 5a8ae07b..e6a6adfd 100644 --- a/sources/ewol/resource/Program.cpp +++ b/sources/ewol/resource/Program.cpp @@ -305,7 +305,7 @@ void ewol::resource::Program::reload(void) { void ewol::resource::Program::sendAttribute(int32_t _idElem, int32_t _nbElement, - void* _pointer, + const void* _pointer, int32_t _jumpBetweenSample) { if (0 == m_program) { return; diff --git a/sources/ewol/resource/Program.h b/sources/ewol/resource/Program.h index 603f1130..fc6f049c 100644 --- a/sources/ewol/resource/Program.h +++ b/sources/ewol/resource/Program.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace ewol { namespace resource { @@ -80,7 +81,7 @@ namespace ewol { */ void sendAttribute(int32_t _idElem, int32_t _nbElement, - void* _pointer, + const void* _pointer, int32_t _jumpBetweenSample=0); void sendAttributePointer(int32_t _idElem, int32_t _nbElement, @@ -88,6 +89,15 @@ namespace ewol { int32_t _index, int32_t _jumpBetweenSample=0, int32_t _offset=0); + inline void sendAttribute(int32_t _idElem, const std::vector& _data) { + sendAttribute(_idElem, 2/*u,v / x,y*/, &_data[0]); + } + inline void sendAttribute(int32_t _idElem, const std::vector& _data) { + sendAttribute(_idElem, 3/*x,y,z,unused*/, &_data[0], 4*sizeof(btScalar)); + } + inline void sendAttribute(int32_t _idElem, const std::vector >& _data) { + sendAttribute(_idElem, 4/*r,g,b,a*/, &_data[0]); + } /** * @brief User request an Uniform on this program. * @note uniform value is availlable for all the fragment shader in the program (only one value for all) diff --git a/sources/ewol/resource/font/GlyphProperty.h b/sources/ewol/resource/font/GlyphProperty.h index 2be32124..7ec8051a 100644 --- a/sources/ewol/resource/font/GlyphProperty.h +++ b/sources/ewol/resource/font/GlyphProperty.h @@ -60,8 +60,8 @@ namespace ewol { ivec2 m_sizeTexture; //!< size of the element to display ivec2 m_bearing; //!< offset to display the data (can be negatif id the texture sise is bigger than the theoric places in the string) ivec2 m_advance; //!< space use in the display for this specific char - vec2 m_texturePosStart; //!< Texture normalised position (START) - vec2 m_texturePosSize; //!< Texture normalised position (SIZE) + vec2 m_texturePosStart; //!< Texture normalized position (START) + vec2 m_texturePosSize; //!< Texture normalized position (SIZE) private: std::vector m_kerning; //!< kerning values of link of all elements public: @@ -84,23 +84,25 @@ namespace ewol { } return 0; }; - void kerningAdd(const char32_t _charcode, float _value) - { + void kerningAdd(const char32_t _charcode, float _value) { m_kerning.push_back(ewol::Kerning(_charcode, _value)); }; - void kerningClear(void) - { + void kerningClear(void) { m_kerning.clear(); }; /** * @brief get the status of the char, if it exist or not in the FONT * @return true if the char is availlable, false otherwise */ - bool exist(void) const { return m_exist; }; + bool exist(void) const { + return m_exist; + }; /** * @brief set the element doen not exist !!! */ - void setNotExist(void) { m_exist = false; }; + void setNotExist(void) { + m_exist = false; + }; }; }; diff --git a/sources/ewol/widget/ButtonColor.cpp b/sources/ewol/widget/ButtonColor.cpp index b3fa0013..879759aa 100644 --- a/sources/ewol/widget/ButtonColor.cpp +++ b/sources/ewol/widget/ButtonColor.cpp @@ -123,7 +123,7 @@ void ewol::widget::ButtonColor::onRegenerateDisplay(void) { } m_text.setPos(tmpTextOrigin); m_text.setColorBg(m_textColorFg); - m_text.setTextAlignement(tmpTextOrigin.x(), tmpTextOrigin.x()+localSize.x(), ewol::compositing::Text::alignCenter); + m_text.setTextAlignement(tmpTextOrigin.x(), tmpTextOrigin.x()+localSize.x(), ewol::compositing::alignCenter); m_text.print(label); diff --git a/sources/ewol/widget/Label.cpp b/sources/ewol/widget/Label.cpp index 9ca623d1..771703a3 100644 --- a/sources/ewol/widget/Label.cpp +++ b/sources/ewol/widget/Label.cpp @@ -39,7 +39,7 @@ void ewol::widget::Label::calculateMinMaxSize(void) { vec2 tmpMin = m_userMinSize.getPixel(); //EWOL_DEBUG("[" << getId() << "] {" << getObjectType() << "} tmpMax : " << tmpMax); if (tmpMax.x() <= 999999) { - m_text.setTextAlignement(0, tmpMax.x()-4, ewol::compositing::Text::alignLeft); + m_text.setTextAlignement(0, tmpMax.x()-4, ewol::compositing::alignLeft); //EWOL_DEBUG("[" << getId() << "] {" << getObjectType() << "} forcez Alignement "); } vec3 minSize = m_text.calculateSizeDecorated(m_label); @@ -78,7 +78,7 @@ void ewol::widget::Label::onRegenerateDisplay(void) { minSize.setX(etk_max(minSize.x(), m_minSize.x())); minSize.setY(etk_max(minSize.y(), m_minSize.y())); if (tmpMax.x() <= 999999) { - m_text.setTextAlignement(0, tmpMax.x()-2*paddingSize, ewol::compositing::Text::alignLeft); + m_text.setTextAlignement(0, tmpMax.x()-2*paddingSize, ewol::compositing::alignLeft); } vec3 curentTextSize = m_text.calculateSizeDecorated(m_label); @@ -113,7 +113,7 @@ void ewol::widget::Label::onRegenerateDisplay(void) { m_text.reset(); m_text.setPos(tmpTextOrigin); EWOL_VERBOSE("[" << getId() << "] {" << m_label << "} display at pos : " << tmpTextOrigin); - m_text.setTextAlignement(tmpTextOrigin.x(), tmpTextOrigin.x()+localSize.x(), ewol::compositing::Text::alignLeft); + m_text.setTextAlignement(tmpTextOrigin.x(), tmpTextOrigin.x()+localSize.x(), ewol::compositing::alignLeft); m_text.setClipping(drawClippingPos, drawClippingSize); m_text.printDecorated(m_label); } diff --git a/sources/lutin_ewol.py b/sources/lutin_ewol.py index e7cbbc7a..040d4e0a 100755 --- a/sources/lutin_ewol.py +++ b/sources/lutin_ewol.py @@ -28,6 +28,7 @@ def create(target): # compositing : myModule.add_src_file([ 'ewol/compositing/Compositing.cpp', + 'ewol/compositing/TextBase.cpp', 'ewol/compositing/Text.cpp', 'ewol/compositing/TextDF.cpp', 'ewol/compositing/Drawing.cpp',