From cfa965269d07ffa6e7ce59c08e759432698a38e2 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 19 Nov 2012 07:58:25 +0100 Subject: [PATCH] [DEV] compositing in progress : starting Draw and Text (nearly ended) component --- data/color3.frag | 10 + data/color3.prog | 2 + data/color3.vert | 18 + sources/ewol/compositing/Draw.cpp | 531 ++++++++++++++++++ sources/ewol/compositing/Draw.h | 148 ++++- .../{DrawVectorial.cpp => DrawBitmap.cpp} | 0 .../{DrawVectorial.h => DrawBitmap.h} | 6 +- sources/ewol/compositing/Text.cpp | 274 ++++++--- sources/ewol/compositing/Text.h | 93 +-- sources/ewol/font/Font.h | 3 +- sources/ewol/font/TexturedFont.cpp | 21 + sources/ewol/font/TexturedFont.h | 8 + sources/ewol/widget/Button.cpp | 2 +- sources/file.mk | 7 +- 14 files changed, 981 insertions(+), 142 deletions(-) create mode 100644 data/color3.frag create mode 100644 data/color3.prog create mode 100644 data/color3.vert rename sources/ewol/compositing/{DrawVectorial.cpp => DrawBitmap.cpp} (100%) rename sources/ewol/compositing/{DrawVectorial.h => DrawBitmap.h} (63%) diff --git a/data/color3.frag b/data/color3.frag new file mode 100644 index 00000000..cb8e54cd --- /dev/null +++ b/data/color3.frag @@ -0,0 +1,10 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +varying vec4 f_color; + +void main(void) { + gl_FragColor = f_color; +} diff --git a/data/color3.prog b/data/color3.prog new file mode 100644 index 00000000..3b4f3411 --- /dev/null +++ b/data/color3.prog @@ -0,0 +1,2 @@ +color3.vert +color3.frag \ No newline at end of file diff --git a/data/color3.vert b/data/color3.vert new file mode 100644 index 00000000..76c3f049 --- /dev/null +++ b/data/color3.vert @@ -0,0 +1,18 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +// Input : +attribute vec3 EW_coord3d; +attribute vec4 EW_color; +uniform mat4 EW_MatrixTransformation; + +// output : +varying vec4 f_color; + +void main(void) { + gl_Position = EW_MatrixTransformation * vec4(EW_coord3d, 1.0); + //gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(EW_coord2d, 0.0, 1.0); + f_color = EW_color; +} diff --git a/sources/ewol/compositing/Draw.cpp b/sources/ewol/compositing/Draw.cpp index e69de29b..7780dcb5 100644 --- a/sources/ewol/compositing/Draw.cpp +++ b/sources/ewol/compositing/Draw.cpp @@ -0,0 +1,531 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include + + +#if 0 + +static void generatePolyGone(etk::Vector > & input, etk::Vector > & output ) +{ + if (input.Size()<3) { + return; + } + // TODO : Regenerate a linear poligone generation + for (int32_t iii=1; iii " << output.Size() ); +} + +static void SutherlandHodgman(etk::Vector > & input, etk::Vector > & output, float sx, float sy, float ex, float ey) +{ + // with Sutherland-Hodgman-Algorithm + if (input.Size() <0) { + return; + } + //int32_t sizeInit=input.Size(); + // last element : + etk::Vector2D destPoint; + etk::Vector2D lastElement = input[input.Size()-1]; + bool inside = true; + if (lastElement.x < sx) { + inside = false; + } + //EWOL_DEBUG("generate an crop : "); + for(int32_t iii=0; iii OUT "); + //new point intersection ... + //y=aaax+bbb + float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x); + float bbb = lastElement.y - (aaa*lastElement.x); + destPoint.y = aaa*sx + bbb; + destPoint.x = sx; + output.PushBack(destPoint); + } else { + //EWOL_DEBUG("element OUT ==> OUT "); + } + inside = false; + } else { + if(true == inside) { + //EWOL_DEBUG("element IN ==> IN "); + output.PushBack(input[iii]); + } else { + //EWOL_DEBUG("element OUT ==> IN "); + //new point intersection ... + //y=aaax+bbb + float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x); + float bbb = lastElement.y - (aaa*lastElement.x); + destPoint.y = aaa*sx + bbb; + destPoint.x = sx; + output.PushBack(destPoint); + output.PushBack(input[iii]); + } + inside = true; + } + // update the last point position : + lastElement.x = input[iii].x; + lastElement.y = input[iii].y; + } + + //EWOL_DEBUG("generate an crop on element : " << sizeInit << " ==> " << output.Size() << "intermediate (1)"); + input = output; + output.Clear(); + lastElement = input[input.Size()-1]; + inside = true; + if (lastElement.y < sy) { + inside = false; + } + for(int32_t iii=0; iii OUT "); + //new point intersection ... + //x=aaay+bbb + float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y); + float bbb = lastElement.x - (aaa*lastElement.y); + destPoint.y = sy; + destPoint.x = sy*aaa + bbb; + output.PushBack(destPoint); + } else { + //EWOL_DEBUG("element OUT ==> OUT "); + } + inside = false; + } else { + if(true == inside) { + //EWOL_DEBUG("element IN ==> IN "); + output.PushBack(input[iii]); + } else { + //EWOL_DEBUG("element OUT ==> IN "); + //new point intersection ... + //y=aaax+bbb + float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y); + float bbb = lastElement.x - (aaa*lastElement.y); + destPoint.y = sy; + destPoint.x = sy*aaa + bbb; + output.PushBack(destPoint); + output.PushBack(input[iii]); + } + inside = true; + } + // update the last point position : + lastElement.x = input[iii].x; + lastElement.y = input[iii].y; + } + + input = output; + output.Clear(); + lastElement = input[input.Size()-1]; + inside = true; + if (lastElement.x > ex) { + inside = false; + } + //EWOL_DEBUG("generate an crop : "); + for(int32_t iii=0; iii ex) { + if(true == inside) { + //EWOL_DEBUG("element IN ==> OUT "); + //new point intersection ... + //y=aaax+bbb + float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x); + float bbb = lastElement.y - (aaa*lastElement.x); + destPoint.y = aaa*ex + bbb; + destPoint.x = ex; + output.PushBack(destPoint); + } else { + //EWOL_DEBUG("element OUT ==> OUT "); + } + inside = false; + } else { + if(true == inside) { + //EWOL_DEBUG("element IN ==> IN "); + output.PushBack(input[iii]); + } else { + //EWOL_DEBUG("element OUT ==> IN "); + //new point intersection ... + //y=aaax+bbb + float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x); + float bbb = lastElement.y - (aaa*lastElement.x); + destPoint.y = aaa*ex + bbb; + destPoint.x = ex; + output.PushBack(destPoint); + output.PushBack(input[iii]); + } + inside = true; + } + // update the last point position : + lastElement.x = input[iii].x; + lastElement.y = input[iii].y; + } + + input = output; + output.Clear(); + lastElement = input[input.Size()-1]; + inside = true; + if (lastElement.y > ey) { + inside = false; + } + for(int32_t iii=0; iii ey) { + if(true == inside) { + //EWOL_DEBUG("element IN ==> OUT "); + //new point intersection ... + //x=aaay+bbb + float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y); + float bbb = lastElement.x - (aaa*lastElement.y); + destPoint.y = ey; + destPoint.x = ey*aaa + bbb; + output.PushBack(destPoint); + } else { + //EWOL_DEBUG("element OUT ==> OUT "); + } + inside = false; + } else { + if(true == inside) { + //EWOL_DEBUG("element IN ==> IN "); + output.PushBack(input[iii]); + } else { + //EWOL_DEBUG("element OUT ==> IN "); + //new point intersection ... + //y=aaax+bbb + float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y); + float bbb = lastElement.x - (aaa*lastElement.y); + destPoint.y = ey; + destPoint.x = ey*aaa + bbb; + output.PushBack(destPoint); + output.PushBack(input[iii]); + } + inside = true; + } + // update the last point position : + lastElement.x = input[iii].x; + lastElement.y = input[iii].y; + } + + + //EWOL_DEBUG("generate an crop on element : " << sizeInit << " ==> " << output.Size() ); +} +#endif + +ewol::Drawing::Drawing(void) : + 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(draw::color::black), + m_colorBg(draw::color::none), + m_GLprogram(NULL), + m_GLPosition(-1), + m_GLMatrix(-1), + m_GLColor(-1), + m_thickness(0.0), + m_triElement(0) +{ + LoadProgram(); + for (int32_t iii=0; iii<3; iii++) { + m_triangle[iii] = m_position; + m_tricolor[iii] = m_color; + } +} + + +ewol::Drawing::~Drawing(void) +{ + ewol::resource::Release(m_GLprogram); +} + + +void ewol::Drawing::GenerateTriangle(void) +{ + m_triElement = 0; + + m_coord.PushBack(m_triangle[0]); + m_coordColor.PushBack(m_tricolor[0]); + m_coord.PushBack(m_triangle[1]); + m_coordColor.PushBack(m_tricolor[1]); + m_coord.PushBack(m_triangle[2]); + m_coordColor.PushBack(m_tricolor[2]); +} + +void ewol::Drawing::InternalSetColor(draw::Color& color) +{ + if (m_triElement < 1) { + m_tricolor[0] = color; + } + if (m_triElement < 2) { + m_tricolor[1] = color; + } + if (m_triElement < 3) { + m_tricolor[2] = color; + } +} + + +void ewol::Drawing::SetPoint(etk::Vector3D point) +{ + m_triangle[m_triElement] = point; + m_triElement++; + if (m_triElement>=3) { + GenerateTriangle(); + } +} + + +void ewol::Drawing::ResetCount(void) +{ + m_triElement = 0; +} + +void ewol::Drawing::LoadProgram(void) +{ + etk::UString tmpString("DATA:color3.prog"); + // get the shader resource : + if (true == ewol::resource::Keep(tmpString, m_GLprogram) ) { + m_GLPosition = m_GLprogram->GetAttribute("EW_coord3d"); + m_GLColor = m_GLprogram->GetAttribute("EW_color"); + m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation"); + } +} + +void ewol::Drawing::Draw(void) +{ + if (m_coord.Size()<=0) { + // TODO : a remÚtre ... + //EWOL_WARNING("Nothink to draw..."); + return; + } + if (m_GLprogram==NULL) { + EWOL_ERROR("No shader ..."); + return; + } + // set Matrix : translation/positionMatrix + etk::Matrix4 tmpMatrix = ewol::openGL::GetMatrix()*m_matrixApply; + m_GLprogram->Use(); + m_GLprogram->UniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat); + // position : + m_GLprogram->SendAttribute(m_GLPosition, 3/*x,y,z*/, &m_coord[0]); + // color : + m_GLprogram->SendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]); + // Request the draw od the elements : + glDrawArrays(GL_TRIANGLES, 0, m_coord.Size()); + m_GLprogram->UnUse(); +} + + +void ewol::Drawing::Clear(void) +{ + // call upper class + ewol::Compositing::Clear(); + // Reset Buffer : + m_coord.Clear(); + m_coordColor.Clear(); + // Reset temporal variables : + m_position = etk::Vector3D(0.0, 0.0, 0.0); + + m_clippingPosStart = etk::Vector3D(0.0, 0.0, 0.0); + m_clippingPosStop = etk::Vector3D(0.0, 0.0, 0.0); + m_clippingEnable = false; + + m_color = draw::color::black; + m_colorBg = draw::color::none; + + for (int32_t iii=0; iii<3; iii++) { + m_triangle[iii] = m_position; + m_tricolor[iii] = m_color; + } +} + + +void ewol::Drawing::SetPos(etk::Vector3D pos) +{ + m_position = pos; +} + + +void ewol::Drawing::SetRelPos(etk::Vector3D pos) +{ + m_position += pos; +} + + +void ewol::Drawing::SetColor(draw::Color color) +{ + m_color = color; +} + + +void ewol::Drawing::SetColorBG(draw::Color color) +{ + m_colorBg = color; +} + + +void ewol::Drawing::SetClippingWidth(etk::Vector3D pos, etk::Vector3D width) +{ + SetClipping(pos, pos+width); +} + +void ewol::Drawing::SetClipping(etk::Vector3D pos, etk::Vector3D 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.x = pos.x; + m_clippingPosStop.x = posEnd.x; + } else { + m_clippingPosStart.x = posEnd.x; + m_clippingPosStop.x = pos.x; + } + if (pos.y <= posEnd.y) { + m_clippingPosStart.y = pos.y; + m_clippingPosStop.y = posEnd.y; + } else { + m_clippingPosStart.y = posEnd.y; + m_clippingPosStop.y = pos.y; + } + if (pos.z <= posEnd.z) { + m_clippingPosStart.z = pos.z; + m_clippingPosStop.z = posEnd.z; + } else { + m_clippingPosStart.z = posEnd.z; + m_clippingPosStop.z = pos.z; + } + m_clippingEnable = true; +} + + +void ewol::Drawing::SetClippingMode(bool newMode) +{ + m_clippingEnable = newMode; +} + + +void ewol::Drawing::SetThickness(float thickness) +{ + m_thickness = thickness; + // thickness must be positive + if (m_thickness < 0) { + m_thickness *= -1; + } +} + + +void ewol::Drawing::AddVertex(void) +{ + +} + + +void ewol::Drawing::LineTo(etk::Vector3D dest) +{ + ResetCount(); + InternalSetColor(m_color); + if (m_position.x == dest.x && m_position.y == dest.y) { + EWOL_WARNING("Try to draw an line width 0"); + return; + } + //teta = tan-1(oposer/adjacent) + float teta = 0; + if (m_position.x <= dest.x) { + teta = atan((dest.y-m_position.y)/(dest.x-m_position.x)); + } else { + teta = M_PI + atan((dest.y-m_position.y)/(dest.x-m_position.x)); + } + if (teta < 0) { + teta += 2*M_PI; + } else if (teta > 2*M_PI) { + teta -= 2*M_PI; + } + //EWOL_DEBUG("teta = " << (teta*180/(M_PI)) << " deg." ); + float offsety = sin(teta-M_PI/2) * (m_thickness/2); + float offsetx = cos(teta-M_PI/2) * (m_thickness/2); + + SetPoint(etk::Vector3D(m_position.x - offsetx, m_position.y - offsety, (float)0.0) ); + SetPoint(etk::Vector3D(m_position.x + offsetx, m_position.y + offsety, (float)0.0) ); + SetPoint(etk::Vector3D(dest.x + offsetx, dest.y + offsety, (float)0.0) ); + + SetPoint(etk::Vector3D(dest.x + offsetx, dest.y + offsety, (float)0.0) ); + SetPoint(etk::Vector3D(dest.x - offsetx, dest.y - offsety, (float)0.0) ); + SetPoint(etk::Vector3D(m_position.x - offsetx, m_position.y - offsety, (float)0.0) ); + // update the system position : + m_position = dest; +} + + +void ewol::Drawing::Rectangle(etk::Vector3D dest) +{ + ResetCount(); + InternalSetColor(m_color); + /* + x += 3; + y += 3; + w -= 6; + h -= 6; + */ + /* Bitmap position + * xA xB + * yC *------* + * | | + * | | + * yD *------* + */ + float dxA = m_position.x; + float dxB = dest.x; + float dyC = m_position.y; + float dyD = dest.y; + + if (true == m_clippingEnable) { + if (dxA < m_clippingPosStart.x) { + dxA = m_clippingPosStart.x; + } + if (dxB > m_clippingPosStop.x) { + dxB = m_clippingPosStop.x; + } + if (dyC < m_clippingPosStart.y) { + dyC = m_clippingPosStart.y; + } + if (dyD > m_clippingPosStop.y) { + dyD = m_clippingPosStop.y; + } + } + if( dyC >= dyD + || dxA >= dxB) { + return; + } + SetPoint(etk::Vector3D(dxA, dyD, (float)0.0) ); + SetPoint(etk::Vector3D(dxA, dyC, (float)0.0) ); + SetPoint(etk::Vector3D(dxB, dyC, (float)0.0) ); + + SetPoint(etk::Vector3D(dxB, dyC, (float)0.0) ); + SetPoint(etk::Vector3D(dxB, dyD, (float)0.0) ); + SetPoint(etk::Vector3D(dxA, dyD, (float)0.0) ); +} + + +void ewol::Drawing::RectangleWidth(etk::Vector3D size) +{ + Rectangle(m_position+size); +} + + + +void ewol::Drawing::Cube(etk::Vector3D dest) +{ + +} + + +void ewol::Drawing::Circle(float radius, float angleStart, float angleStop) +{ + +} + diff --git a/sources/ewol/compositing/Draw.h b/sources/ewol/compositing/Draw.h index b114fb27..16f0fcb6 100644 --- a/sources/ewol/compositing/Draw.h +++ b/sources/ewol/compositing/Draw.h @@ -6,17 +6,155 @@ * @license BSD v3 (see license file) */ -#ifndef __EWOL_DRAW_H__ -#define __EWOL_DRAW_H__ +#ifndef __EWOL_DRAWING_H__ +#define __EWOL_DRAWING_H__ + +#include +#include +#include +#include + namespace ewol { - class Draw : public ewol::Compositing + class Drawing : public ewol::Compositing { - protected: + private: + etk::Vector3D m_position; //!< The current position to draw + etk::Vector3D m_clippingPosStart; //!< Clipping start position + etk::Vector3D m_clippingPosStop; //!< Clipping stop position + bool m_clippingEnable; //!< true if the clipping must be activated + private: + draw::Color m_color; //!< The text foreground color + draw::Color m_colorBg; //!< The text background color + private: + ewol::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) + private: // Background Color (display only when needed) + etk::Vector > m_coord; //!< internal position for the text display + etk::Vector m_coordColor; //!< internal color of the background + public: + /** + * @brief Basic constructor + */ + Drawing(void); + /** + * @brief Basic destructor + */ + ~Drawing(void); + private: + /** + * @brief Load the openGL program and get all the ID needed + */ + void LoadProgram(void); + float m_thickness; //!< when drawing line and other things + int32_t m_triElement; //!< special counter of the single dot generated + etk::Vector3D m_triangle[3]; //!< Register every system with a combinaison of tiangle + draw::Colorf m_tricolor[3]; //!< Register every the associated color foreground + // internal API for the generation abstraction of triangles + /** + * @brief Lunch the generation of triangle + */ + void GenerateTriangle(void); + /** + * @brief in case of some error the count can be reset + */ + void ResetCount(void); + /** + * @brief Set the Color of the current triangle drawing + * @param[in] color Color to current dots generated + */ + void InternalSetColor(draw::Color& color); + /** + * @brief internal add of the specific point + * @param[in] point The requeste dpoint to add + */ + void SetPoint(etk::Vector3D point); public: - + /** + * @brief Draw All the refistered text in the current element on openGL + */ + void Draw(void); + /** + * @brief Clear alll tre registered element in the current element + */ + void Clear(void); + /** + * @brief Set position for the next text writen + * @param[in] pos Position of the text (in 3D) + */ + void SetPos(etk::Vector3D pos); + /** + * @brief Set relative position for the next text writen + * @param[in] pos ofset apply of the text (in 3D) + */ + void SetRelPos(etk::Vector3D pos); + /** + * @brief Set the Color of the current foreground font + * @param[in] color Color to set on foreground (for next print) + */ + void SetColor(draw::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(draw::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(etk::Vector3D pos, etk::Vector3D 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(etk::Vector3D pos, etk::Vector3D posEnd); + /** + * @brief Enable/Disable the clipping (without lose the current clipping position) + * @brief newMode The new status of the clipping + */ + void SetClippingMode(bool newMode); + /** + * @brief Specify the line thickness for the next elements + * @param[in] thickness The thickness disired for the next print + */ + void SetThickness(float thickness); + /** + * @brief Add a point reference at the current position (this is a vertex reference at the current position + */ + void AddVertex(void); + /** + * @brief Draw a line to a specific position + * @param[in] dest Position of the end of the line. + */ + void LineTo(etk::Vector3D dest); + /** + * @brief Draw a 2D rectangle to the position requested. + * @param[in] dest Position the the end of the rectangle + */ + void Rectangle(etk::Vector3D dest); + /** + * @brief Draw a 2D rectangle to the requested size. + * @param[in] width size of the rectangle + */ + void RectangleWidth(etk::Vector3D size); + /** + * @brief Draw a 3D rectangle to the position requested. + * @param[in] dest Position the the end of the rectangle + */ + void Cube(etk::Vector3D dest); + /** + * @brief Draw a 2D circle with the specify rafdius parameter. + * @param[in] radius Distence to the dorder + * @param[in] angleStart start angle of this circle ([0..2PI] otherwithe ==> disable) + * @param[in] angleStop stop angle of this circle ([0..2PI] otherwithe ==> disable) + */ + void Circle(float radius, float angleStart = -1, float angleStop = -1); }; }; diff --git a/sources/ewol/compositing/DrawVectorial.cpp b/sources/ewol/compositing/DrawBitmap.cpp similarity index 100% rename from sources/ewol/compositing/DrawVectorial.cpp rename to sources/ewol/compositing/DrawBitmap.cpp diff --git a/sources/ewol/compositing/DrawVectorial.h b/sources/ewol/compositing/DrawBitmap.h similarity index 63% rename from sources/ewol/compositing/DrawVectorial.h rename to sources/ewol/compositing/DrawBitmap.h index 480f0b93..84194f91 100644 --- a/sources/ewol/compositing/DrawVectorial.h +++ b/sources/ewol/compositing/DrawBitmap.h @@ -6,12 +6,12 @@ * @license BSD v3 (see license file) */ -#ifndef __EWOL_DRAW_VECTORIAL_H__ -#define __EWOL_DRAW_VECTORIAL_H__ +#ifndef __EWOL_DRAW_BITMAP_H__ +#define __EWOL_DRAW_BITMAP_H__ namespace ewol { - class DrawVectorial : public ewol::Compositing + class DrawBitmap : public ewol::Compositing { protected: diff --git a/sources/ewol/compositing/Text.cpp b/sources/ewol/compositing/Text.cpp index f26bea6d..a157174f 100644 --- a/sources/ewol/compositing/Text.cpp +++ b/sources/ewol/compositing/Text.cpp @@ -25,8 +25,8 @@ ewol::Text::Text(void) : m_position(0.0, 0.0, 0.0), - m_clippingPosition(0.0, 0.0, 0.0), - m_clippingSize(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(draw::color::black), m_colorBg(draw::color::none), @@ -52,8 +52,8 @@ ewol::Text::Text(void) : ewol::Text::Text(etk::UString fontName, int32_t fontSize) : m_position(0.0, 0.0, 0.0), - m_clippingPosition(0.0, 0.0, 0.0), - m_clippingSize(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(draw::color::black), m_colorBg(draw::color::none), @@ -116,9 +116,10 @@ void ewol::Text::Draw(void) EWOL_ERROR("No shader ..."); return; } - m_GLprogram->Use(); + m_vectorialDraw.Draw(); // set Matrix : translation/positionMatrix etk::Matrix4 tmpMatrix = ewol::openGL::GetMatrix()*m_matrixApply; + m_GLprogram->Use(); m_GLprogram->UniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat); // TextureID m_GLprogram->SetTexture0(m_GLtexID, m_font->GetId()); @@ -138,14 +139,16 @@ void ewol::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 : m_position = etk::Vector3D(0.0, 0.0, 0.0); - m_clippingPosition = etk::Vector3D(0.0, 0.0, 0.0); - m_clippingSize = etk::Vector3D(0.0, 0.0, 0.0); + m_clippingPosStart = etk::Vector3D(0.0, 0.0, 0.0); + m_clippingPosStop = etk::Vector3D(0.0, 0.0, 0.0); m_clippingEnable = false; m_color = draw::color::black; m_colorBg = draw::color::none; @@ -162,6 +165,7 @@ void ewol::Text::SetPos(etk::Vector3D pos) { m_position = pos; m_previousCharcode = 0; + m_vectorialDraw.SetPos(m_position); } @@ -169,6 +173,7 @@ void ewol::Text::SetRelPos(etk::Vector3D pos) { m_position += pos; m_previousCharcode = 0; + m_vectorialDraw.SetPos(m_position); } @@ -181,20 +186,48 @@ void ewol::Text::SetColor(draw::Color color) void ewol::Text::SetColorBG(draw::Color color) { m_colorBg = color; + m_vectorialDraw.SetColor(color); } -void ewol::Text::SetClipping(etk::Vector3D pos, etk::Vector3D width) +void ewol::Text::SetClippingWidth(etk::Vector3D pos, etk::Vector3D width) { - m_clippingPosition = pos; - m_clippingSize = width; + SetClipping(pos, pos+width); +} + +void ewol::Text::SetClipping(etk::Vector3D pos, etk::Vector3D 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.x = pos.x; + m_clippingPosStop.x = posEnd.x; + } else { + m_clippingPosStart.x = posEnd.x; + m_clippingPosStop.x = pos.x; + } + if (pos.y <= posEnd.y) { + m_clippingPosStart.y = pos.y; + m_clippingPosStop.y = posEnd.y; + } else { + m_clippingPosStart.y = posEnd.y; + m_clippingPosStop.y = pos.y; + } + if (pos.z <= posEnd.z) { + m_clippingPosStart.z = pos.z; + m_clippingPosStop.z = posEnd.z; + } else { + m_clippingPosStart.z = posEnd.z; + m_clippingPosStop.z = pos.z; + } m_clippingEnable = true; + m_vectorialDraw.SetClipping(m_clippingPosStart, m_clippingPosStop); } void ewol::Text::SetClippingMode(bool newMode) { m_clippingEnable = newMode; + m_vectorialDraw.SetClippingMode(m_clippingEnable); } @@ -239,7 +272,9 @@ void ewol::Text::SetFont(etk::UString fontName, int32_t fontSize) void ewol::Text::SetFontMode(ewol::font::mode_te mode) { - m_mode = mode; + if (NULL!=m_font) { + m_mode = m_font->GetWrappingMode(mode); + } } @@ -258,58 +293,8 @@ void ewol::Text::SetDistanceFieldMode(bool newMode) void ewol::Text::Print(const etk::UString& text) { - if (m_font == NULL) { - EWOL_ERROR("Font Id is not corectly defined"); - return; - } - switch(m_alignement) - { - default: - case ewol::Text::alignDisable: - for(int32_t iii=0; iii(m_position.x + interpolation, - m_position.y, - m_position.z) ); - } else { - Print(text[iii]); - } - } - if (currentId == stop) { - currentId++; - } else if( text[stop] == (uniChar_t)' ' - || text[stop] == (uniChar_t)'\n') { - currentId = stop+1; - } else { - currentId = stop; - } - // Reset position : - SetPos(etk::Vector3D(m_startTextpos, - (float)(m_position.y - m_font->GetHeight(m_mode)), - m_position.z) ); - } - } - break; - } + etk::Vector decorationEmpty; + Print(text, decorationEmpty); } @@ -322,8 +307,88 @@ void ewol::Text::PrintDecorated(const etk::UString& text) void ewol::Text::Print(const etk::UString& text, const etk::Vector& decoration) { - EWOL_TODO("The Advenced print is not supported now ..."); - Print(text); + if (m_font == NULL) { + EWOL_ERROR("Font Id is not corectly defined"); + return; + } + if (m_alignement == ewol::Text::alignDisable) { + // note this is faster when nothing is requested ... + for(int32_t iii=0; iii(15,15,0) ); + } + Print(text[iii]); + } + } else { + float basicSpaceWidth = CalculateSize(' ').x; + int32_t currentId = 0; + int32_t stop; + int32_t space; + int32_t freeSpace; + while (currentId < text.Size()) { + bool needNoJustify = ExtrapolateLastId(text, currentId, stop, space, freeSpace); + + float interpolation = basicSpaceWidth; + switch (m_alignement) + { + case ewol::Text::alignJustify: + if (needNoJustify == false) { + interpolation += (float)freeSpace / (float)(space-1); + } + break; + case ewol::Text::alignDisable: // must not came from here ... + case ewol::Text::alignLeft: + // nothing to do ... + break; + case ewol::Text::alignRight: + // Move the first char at the right : + SetPos(etk::Vector3D(m_position.x + freeSpace, + m_position.y, + m_position.z) ); + break; + case ewol::Text::alignCenter: + // Move the first char at the right : + SetPos(etk::Vector3D(m_position.x + freeSpace/2, + m_position.y, + m_position.z) ); + break; + } + // display all the elements + for(int32_t iii=currentId; iii(m_position.x + interpolation, + m_position.y, + m_position.z) ); + } else { + if (iii(m_startTextpos, + (float)(m_position.y - m_font->GetHeight(m_mode)), + m_position.z) ); + } + } } @@ -367,54 +432,54 @@ void ewol::Text::Print(const uniChar_t charcode) // Clipping and drawing area - /* - if( true == hasClipping - && ( dxB < clipping.x - || dxA > clipping.x + clipping.w) ) { + if( true == m_clippingEnable + && ( dxB < m_clippingPosStart.x + || dxA > m_clippingPosStop.x + || dyC < m_clippingPosStart.y + || dyD > m_clippingPosStop.y ) ) { // Nothing to diplay ... } else { - if (true == hasClipping) { + if (true == m_clippingEnable) { // generata positions... float TexSizeX = tuB - tuA; - if (dxA < clipping.x) { + if (dxA < m_clippingPosStart.x) { // clip display - float drawSize = clipping.x - dxA; + float drawSize = m_clippingPosStart.x - dxA; // Update element start display - dxA = clipping.x; + dxA = m_clippingPosStart.x; float addElement = TexSizeX * drawSize / (float)myGlyph->m_sizeTexture.x; // update texture start X Pos tuA += addElement; } - if (dxB > clipping.x + clipping.w) { + if (dxB > m_clippingPosStop.x) { // clip display - float drawSize = dxB - (clipping.x + clipping.w); + float drawSize = dxB - m_clippingPosStop.x; // Update element start display - dxB = clipping.x + clipping.w; + dxB = m_clippingPosStop.x; float addElement = TexSizeX * drawSize / (float)myGlyph->m_sizeTexture.x; // update texture start X Pos tuB -= addElement; } - float TexSizeY = tvD - tvC; - if (dyC < clipping.y) { + float TexSizeY = tvC - tvD; + if (dyC > m_clippingPosStop.y) { // clip display - float drawSize = clipping.y - dyC; + float drawSize = dyC - m_clippingPosStop.y; // Update element start display - dyC = clipping.y; - float addElement = TexSizeY * drawSize / (float)myGlyph->m_sizeTexture.x; + dyC = m_clippingPosStop.y; + float addElement = TexSizeY * drawSize / (float)myGlyph->m_sizeTexture.y; // update texture start X Pos - tvC += addElement; + tvC -= addElement; } - if (dyD > clipping.y + clipping.h) { + if (dyD < m_clippingPosStart.y) { // clip display - float drawSize = dyD - (clipping.y + clipping.h); + float drawSize = m_clippingPosStart.y - dyD; // Update element start display - dyD = clipping.y + clipping.h; - float addElement = TexSizeX * drawSize / (float)myGlyph->m_sizeTexture.x; + dyD = m_clippingPosStart.y; + float addElement = TexSizeY * drawSize / (float)myGlyph->m_sizeTexture.y; // update texture start X Pos - tvD -= addElement; + tvD += addElement; } } - */ if( dxB <= dxA || dyD >= dyC) { // nothing to do ... @@ -472,7 +537,20 @@ void ewol::Text::Print(const uniChar_t charcode) m_coordColor.PushBack(m_color); m_coordColor.PushBack(m_color); m_coordColor.PushBack(m_color); - + /* + if (m_colorBg.a != 0) { + + m_vectorialDraw.SetPos(); + // set display positions : + m_coordBg.PushBack(bitmapDrawPos[0]); + m_coordBg.PushBack(bitmapDrawPos[1]); + m_coordBg.PushBack(bitmapDrawPos[2]); + // set the color + m_coordColorBg.PushBack(m_colorBg); + m_coordColorBg.PushBack(m_colorBg); + m_coordColorBg.PushBack(m_colorBg); + } + */ /* Step 2 : * * ** @@ -492,8 +570,20 @@ void ewol::Text::Print(const uniChar_t charcode) m_coordColor.PushBack(m_color); m_coordColor.PushBack(m_color); m_coordColor.PushBack(m_color); + /* + if (m_colorBg.a != 0) { + // set display positions : + m_coordBg.PushBack(bitmapDrawPos[0]); + m_coordBg.PushBack(bitmapDrawPos[2]); + m_coordBg.PushBack(bitmapDrawPos[3]); + // set the color + m_coordColorBg.PushBack(m_colorBg); + m_coordColorBg.PushBack(m_colorBg); + m_coordColorBg.PushBack(m_colorBg); + } + */ } - //} + } } // move the position : m_position.x += myGlyph->m_advance.x + kerningOffset; @@ -581,8 +671,6 @@ bool ewol::Text::ExtrapolateLastId(const etk::UString& text, const int32_t start stop = iii; break; } - // update local size : - endPos += tmpSize.x; // save number of space : if (text[iii] == (uniChar_t)' ') { space++; @@ -593,6 +681,8 @@ bool ewol::Text::ExtrapolateLastId(const etk::UString& text, const int32_t start endOfLine = true; break; } + // update local size : + endPos += tmpSize.x; } freeSpace = m_stopTextPos - endPos; // retore previous : diff --git a/sources/ewol/compositing/Text.h b/sources/ewol/compositing/Text.h index f70fec70..fde7d565 100644 --- a/sources/ewol/compositing/Text.h +++ b/sources/ewol/compositing/Text.h @@ -11,20 +11,30 @@ #include #include +#include #include #include namespace ewol { + /** + * @brief This class represent the specific display for every char in the string ... + */ class TextDecoration { public: - draw::Color m_colorBg; - draw::Color m_colorFg; - ewol::font::mode_te m_mode; + draw::Color m_colorBg; //!< Display background color + draw::Color m_colorFg; //!< Display foreground color + ewol::font::mode_te m_mode; //!< Display mode Regular/Bold/Italic/BoldItalic + TextDecoration(void) + { + m_colorBg = draw::color::blue; + m_colorBg = draw::color::green; + m_mode = ewol::font::Regular; + + } }; - class Text : public ewol::Compositing { public: @@ -35,38 +45,35 @@ namespace ewol alignCenter, alignJustify } aligneMode_te; - private: - // curent Drawing position - etk::Vector3D m_position; //!< the next position to draw the text - // clipping section - etk::Vector3D m_clippingPosition; - etk::Vector3D m_clippingSize; - bool m_clippingEnable; - // Basic color - draw::Color m_color; - draw::Color m_colorBg; - // font property : - ewol::font::mode_te m_mode; - bool m_kerning; - bool m_distanceField; - uniChar_t m_previousCharcode; - // alignement propoerty - float m_startTextpos; - float m_stopTextPos; - aligneMode_te m_alignement; - // OpenGL interface for shader - ewol::Program* m_GLprogram; - int32_t m_GLPosition; - int32_t m_GLMatrix; - int32_t m_GLColor; - int32_t m_GLtexture; - int32_t m_GLtexID; - // Font resource : - ewol::TexturedFont* m_font; //!< ewol font system - // data vector for all the display : - // Note : the X texture range change to select the Regular / Bold / italic / BoldItalic mode , and the next is for no font but background color - // ==> associate with a special shader + ewol::Drawing m_vectorialDraw; //!< This is used to draw background selection and other things ... + private: + etk::Vector3D m_position; //!< The current position to draw + etk::Vector3D m_clippingPosStart; //!< Clipping start position + etk::Vector3D m_clippingPosStop; //!< Clipping stop position + bool m_clippingEnable; //!< true if the clipping must be activated + private: + draw::Color m_color; //!< The text foreground color + draw::Color m_colorBg; //!< The text background color + private: + ewol::font::mode_te 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. + uniChar_t m_previousCharcode; //!< we remember the previous charcode to perform the kerning. @ref Kerning + private: + 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) + aligneMode_te m_alignement; //!< Current Alignement mode (justify/left/right ...) + private: + ewol::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) + private: + ewol::TexturedFont* m_font; //!< Font resources + private: // Text etk::Vector > m_coord; //!< internal coord of the object etk::Vector m_coordTex; //!< internal texture coordinate for every point etk::Vector m_coordColor; //!< internal color of the different point @@ -121,10 +128,16 @@ namespace ewol void SetColorBG(draw::Color color); /** * @brief Request a clipping area for the text (next draw only) - * @param[in] pos Start position of the clipping - * @param[in] width End position of th clipping + * @param[in] pos Start position of the clipping + * @param[in] width Width size of the clipping */ - void SetClipping(etk::Vector3D pos, etk::Vector3D width); + void SetClippingWidth(etk::Vector3D pos, etk::Vector3D 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(etk::Vector3D pos, etk::Vector3D posEnd); /** * @brief Enable/Disable the clipping (without lose the current clipping position) * @brief newMode The new status of the clipping @@ -177,6 +190,7 @@ namespace ewol * \ ... \ To align center. * \ ... \ To align justify. * @param[in] text The string to display. + * @TODO : implementation not done .... */ void PrintDecorated(const etk::UString& text); /** @@ -222,7 +236,8 @@ namespace ewol * @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. - * @return true if need not alligne justify (end of string) + * @parma[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 etk::UString& text, const int32_t start, int32_t& stop, int32_t& space, int32_t& freeSpace); }; diff --git a/sources/ewol/font/Font.h b/sources/ewol/font/Font.h index 4b97d2b7..0899e03e 100644 --- a/sources/ewol/font/Font.h +++ b/sources/ewol/font/Font.h @@ -21,10 +21,11 @@ namespace ewol { class Font : public ewol::Resource { + protected: public: Font(etk::UString fontName) : ewol::Resource(fontName) {}; - virtual ~Font(void) {}; + virtual ~Font(void) { }; const char* GetType(void) { return "ewol::Font"; }; diff --git a/sources/ewol/font/TexturedFont.cpp b/sources/ewol/font/TexturedFont.cpp index 5733aaad..5619945d 100644 --- a/sources/ewol/font/TexturedFont.cpp +++ b/sources/ewol/font/TexturedFont.cpp @@ -49,6 +49,11 @@ ewol::TexturedFont::TexturedFont(etk::UString fontName) : m_font[2] = NULL; m_font[3] = NULL; + m_modeWraping[0] = ewol::font::Regular; + m_modeWraping[1] = ewol::font::Regular; + m_modeWraping[2] = ewol::font::Regular; + m_modeWraping[3] = ewol::font::Regular; + m_lastGlyphPos[0].x = 0; m_lastGlyphPos[0].y = 0; m_lastGlyphPos[1].x = 0; @@ -133,6 +138,22 @@ ewol::TexturedFont::TexturedFont(etk::UString fontName) : m_fileName[ewol::font::Regular] = output[iii]; } } + // try to find the reference mode : + ewol::font::mode_te refMode = ewol::font::Regular; + for(int32_t iii=3; iii>=0; iii--) { + if (m_fileName[iii] != "") { + refMode = (ewol::font::mode_te)iii; + } + } + // generate the wrapping on the preventing error + for(int32_t iii=3; iii>=0; iii--) { + if (m_fileName[iii] != "") { + m_modeWraping[iii] = (ewol::font::mode_te)iii; + } else { + m_modeWraping[iii] = refMode; + } + } + for (int32_t iiiFontId=0; iiiFontId<4 ; iiiFontId++) { if (m_fileName[iiiFontId] == "") { EWOL_CRITICAL("can not load FONT [" << iiiFontId << "] name : \"" << m_fileName[iiiFontId] << "\" ==> size=" << m_size ); diff --git a/sources/ewol/font/TexturedFont.h b/sources/ewol/font/TexturedFont.h index 0f808bd2..98fb80cb 100644 --- a/sources/ewol/font/TexturedFont.h +++ b/sources/ewol/font/TexturedFont.h @@ -34,6 +34,7 @@ namespace ewol // ==> otherwise I can just generate italic ... // ==> Bold is a little more complicated (maybe with the bordersize) ewol::Font* m_font[4]; + ewol::font::mode_te m_modeWraping[4]; //!< This is a wrapping mode to prevent the fact that no font is define for a specific mode public: etk::Vector m_listElement[4]; private: @@ -114,6 +115,13 @@ namespace ewol * @return The pointer on the glyph ==> never NULL */ ewol::GlyphProperty* GetGlyphPointer(const uniChar_t charcode, const ewol::font::mode_te displayMode); + /** + * @brief The wrapping mode is used to prevent the non existance of a specific mode. + * For exemple when a blod mode does not exist, this resend a regular mode. + * @param[in] source The requested mode. + * @return the best mode we have in stock. + */ + ewol::font::mode_te GetWrappingMode(ewol::font::mode_te source) { return m_modeWraping[source]; }; }; diff --git a/sources/ewol/widget/Button.cpp b/sources/ewol/widget/Button.cpp index 19806b5b..11e20b97 100644 --- a/sources/ewol/widget/Button.cpp +++ b/sources/ewol/widget/Button.cpp @@ -268,7 +268,7 @@ void ewol::Button::OnRegenerateDisplay(void) textPos.x += m_padding.x + fontHeight; } */ - etk::Vector3D drawClippingPos((float)padding.x, (float)padding.y, (float)-0.5); + etk::Vector3D drawClippingPos(0.0, 0.0, -0.5); etk::Vector3D drawClippingSize((float)(m_size.x - 2*padding.x), (float)(m_size.y - 2*padding.y), (float)1.0); diff --git a/sources/file.mk b/sources/file.mk index 2fa14ba5..b4f147cd 100644 --- a/sources/file.mk +++ b/sources/file.mk @@ -28,7 +28,8 @@ FILE_LIST+= ewol/game/GameElement.cpp \ # Compositing FILE_LIST+= ewol/compositing/Compositing.cpp \ - ewol/compositing/Text.cpp + ewol/compositing/Text.cpp \ + ewol/compositing/Draw.cpp # Object abstraction for OpenGl FILE_LIST+= ewol/oObject/OObject.cpp \ @@ -103,6 +104,10 @@ LOCAL_COPY_FILES := ../data/textured3D.prog:textured3D.prog \ ../data/color.frag:color.frag \ ../data/color.vert:color.vert \ \ + ../data/color3.prog:color3.prog \ + ../data/color3.frag:color3.frag \ + ../data/color3.vert:color3.vert \ + \ ../data/textured.prog:textured.prog \ ../data/textured.frag:textured.frag \ ../data/textured.vert:textured.vert \