[DEV] compositing in progress : starting Draw and Text (nearly ended) component

This commit is contained in:
Edouard DUPIN 2012-11-19 07:58:25 +01:00
parent 640810ee8d
commit cfa965269d
14 changed files with 981 additions and 142 deletions

10
data/color3.frag Normal file
View File

@ -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;
}

2
data/color3.prog Normal file
View File

@ -0,0 +1,2 @@
color3.vert
color3.frag

18
data/color3.vert Normal file
View File

@ -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;
}

View File

@ -0,0 +1,531 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <ewol/Debug.h>
#include <ewol/compositing/Draw.h>
#if 0
static void generatePolyGone(etk::Vector<etk::Vector2D<float> > & input, etk::Vector<etk::Vector2D<float> > & output )
{
if (input.Size()<3) {
return;
}
// TODO : Regenerate a linear poligone generation
for (int32_t iii=1; iii<input.Size()-1; iii++) {
output.PushBack(input[0]);
output.PushBack(input[iii]);
output.PushBack(input[iii+1]);
}
//EWOL_DEBUG("generate Plygone : " << input.Size() << " ==> " << output.Size() );
}
static void SutherlandHodgman(etk::Vector<etk::Vector2D<float> > & input, etk::Vector<etk::Vector2D<float> > & 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<float> destPoint;
etk::Vector2D<float> 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<input.Size(); iii++) {
if(input[iii].x < sx) {
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*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<input.Size(); iii++) {
if(input[iii].y < sy) {
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 = 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<input.Size(); iii++) {
if(input[iii].x > 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<input.Size(); iii++) {
if(input[iii].y > 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<float> 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<float>(0.0, 0.0, 0.0);
m_clippingPosStart = etk::Vector3D<float>(0.0, 0.0, 0.0);
m_clippingPosStop = etk::Vector3D<float>(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<float> pos)
{
m_position = pos;
}
void ewol::Drawing::SetRelPos(etk::Vector3D<float> 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<float> pos, etk::Vector3D<float> width)
{
SetClipping(pos, pos+width);
}
void ewol::Drawing::SetClipping(etk::Vector3D<float> pos, etk::Vector3D<float> 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<float> 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<float>(m_position.x - offsetx, m_position.y - offsety, (float)0.0) );
SetPoint(etk::Vector3D<float>(m_position.x + offsetx, m_position.y + offsety, (float)0.0) );
SetPoint(etk::Vector3D<float>(dest.x + offsetx, dest.y + offsety, (float)0.0) );
SetPoint(etk::Vector3D<float>(dest.x + offsetx, dest.y + offsety, (float)0.0) );
SetPoint(etk::Vector3D<float>(dest.x - offsetx, dest.y - offsety, (float)0.0) );
SetPoint(etk::Vector3D<float>(m_position.x - offsetx, m_position.y - offsety, (float)0.0) );
// update the system position :
m_position = dest;
}
void ewol::Drawing::Rectangle(etk::Vector3D<float> 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<float>(dxA, dyD, (float)0.0) );
SetPoint(etk::Vector3D<float>(dxA, dyC, (float)0.0) );
SetPoint(etk::Vector3D<float>(dxB, dyC, (float)0.0) );
SetPoint(etk::Vector3D<float>(dxB, dyC, (float)0.0) );
SetPoint(etk::Vector3D<float>(dxB, dyD, (float)0.0) );
SetPoint(etk::Vector3D<float>(dxA, dyD, (float)0.0) );
}
void ewol::Drawing::RectangleWidth(etk::Vector3D<float> size)
{
Rectangle(m_position+size);
}
void ewol::Drawing::Cube(etk::Vector3D<float> dest)
{
}
void ewol::Drawing::Circle(float radius, float angleStart, float angleStop)
{
}

View File

@ -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 <ewol/Debug.h>
#include <ewol/compositing/Compositing.h>
#include <draw/Color.h>
#include <ewol/ResourceManager.h>
namespace ewol
{
class Draw : public ewol::Compositing
class Drawing : public ewol::Compositing
{
protected:
private:
etk::Vector3D<float> m_position; //!< The current position to draw
etk::Vector3D<float> m_clippingPosStart; //!< Clipping start position
etk::Vector3D<float> 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<etk::Vector3D<float> > m_coord; //!< internal position for the text display
etk::Vector<draw::Colorf> 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<float> 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<float> 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<float> pos);
/**
* @brief Set relative position for the next text writen
* @param[in] pos ofset apply of the text (in 3D)
*/
void SetRelPos(etk::Vector3D<float> 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<float> pos, etk::Vector3D<float> 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<float> pos, etk::Vector3D<float> 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<float> dest);
/**
* @brief Draw a 2D rectangle to the position requested.
* @param[in] dest Position the the end of the rectangle
*/
void Rectangle(etk::Vector3D<float> dest);
/**
* @brief Draw a 2D rectangle to the requested size.
* @param[in] width size of the rectangle
*/
void RectangleWidth(etk::Vector3D<float> size);
/**
* @brief Draw a 3D rectangle to the position requested.
* @param[in] dest Position the the end of the rectangle
*/
void Cube(etk::Vector3D<float> 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);
};
};

View File

@ -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:

View File

@ -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<float>(0.0, 0.0, 0.0);
m_clippingPosition = etk::Vector3D<float>(0.0, 0.0, 0.0);
m_clippingSize = etk::Vector3D<float>(0.0, 0.0, 0.0);
m_clippingPosStart = etk::Vector3D<float>(0.0, 0.0, 0.0);
m_clippingPosStop = etk::Vector3D<float>(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<float> pos)
{
m_position = pos;
m_previousCharcode = 0;
m_vectorialDraw.SetPos(m_position);
}
@ -169,6 +173,7 @@ void ewol::Text::SetRelPos(etk::Vector3D<float> 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<float> pos, etk::Vector3D<float> width)
void ewol::Text::SetClippingWidth(etk::Vector3D<float> pos, etk::Vector3D<float> width)
{
m_clippingPosition = pos;
m_clippingSize = width;
SetClipping(pos, pos+width);
}
void ewol::Text::SetClipping(etk::Vector3D<float> pos, etk::Vector3D<float> 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<text.Size(); iii++) {
Print(text[iii]);
}
break;
case ewol::Text::alignJustify:
{
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;
if (needNoJustify == false) {
interpolation += (float)freeSpace / (float)(space-1);
}
for(int32_t iii=currentId; iii<stop && iii<text.Size(); iii++) {
if (text[iii] == (uniChar_t)' ') {
// Must generate a dynamic space :
SetPos(etk::Vector3D<float>(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<float>(m_startTextpos,
(float)(m_position.y - m_font->GetHeight(m_mode)),
m_position.z) );
}
}
break;
}
etk::Vector<TextDecoration> 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<TextDecoration>& 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<text.Size(); iii++) {
if (iii<decoration.Size()) {
SetColor(decoration[iii].m_colorFg);
SetColorBG(decoration[iii].m_colorBg);
SetFontMode(decoration[iii].m_mode);
}
if (m_colorBg.a != 0) {
m_vectorialDraw.SetPos(m_position);
m_vectorialDraw.RectangleWidth(etk::Vector3D<float>(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<float>(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<float>(m_position.x + freeSpace/2,
m_position.y,
m_position.z) );
break;
}
// display all the elements
for(int32_t iii=currentId; iii<stop && iii<text.Size(); iii++) {
if (text[iii] == (uniChar_t)' ') {
// Must generate a dynamic space :
SetPos(etk::Vector3D<float>(m_position.x + interpolation,
m_position.y,
m_position.z) );
} else {
if (iii<decoration.Size()) {
SetColor(decoration[iii].m_colorFg);
SetColorBG(decoration[iii].m_colorBg);
SetFontMode(decoration[iii].m_mode);
}
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<float>(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 :

View File

@ -11,20 +11,30 @@
#include <ewol/Debug.h>
#include <ewol/compositing/Compositing.h>
#include <ewol/compositing/Draw.h>
#include <draw/Color.h>
#include <ewol/ResourceManager.h>
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<float> m_position; //!< the next position to draw the text
// clipping section
etk::Vector3D<float> m_clippingPosition;
etk::Vector3D<float> 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<float> m_position; //!< The current position to draw
etk::Vector3D<float> m_clippingPosStart; //!< Clipping start position
etk::Vector3D<float> 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<etk::Vector2D<float> > m_coord; //!< internal coord of the object
etk::Vector<texCoord_ts> m_coordTex; //!< internal texture coordinate for every point
etk::Vector<draw::Colorf> 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<float> pos, etk::Vector3D<float> width);
void SetClippingWidth(etk::Vector3D<float> pos, etk::Vector3D<float> 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<float> pos, etk::Vector3D<float> 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
* \<center\> ... \</center\> To align center.
* \<justify\> ... \</justify\> 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);
};

View File

@ -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"; };

View File

@ -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 );

View File

@ -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<GlyphProperty> 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]; };
};

View File

@ -268,7 +268,7 @@ void ewol::Button::OnRegenerateDisplay(void)
textPos.x += m_padding.x + fontHeight;
}
*/
etk::Vector3D<float> drawClippingPos((float)padding.x, (float)padding.y, (float)-0.5);
etk::Vector3D<float> drawClippingPos(0.0, 0.0, -0.5);
etk::Vector3D<float> drawClippingSize((float)(m_size.x - 2*padding.x),
(float)(m_size.y - 2*padding.y),
(float)1.0);

View File

@ -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 \