[DEV] better distance-field and normal font display

This commit is contained in:
Edouard DUPIN 2014-01-14 23:56:17 +01:00
parent 6fcff69f11
commit c2a6833037
21 changed files with 250 additions and 73 deletions

2
build

@ -1 +1 @@
Subproject commit 862ab0f7b799039cadc310607040d2ea16ce782c
Subproject commit 0e6c61e2ed2dafa6bc6eaa67df095808f56c5bb4

View File

@ -14,11 +14,11 @@ varying vec4 f_color;
const float glyph_center = 0.50;
const float outline_center = 0.55;
const float glow_center = 1.25;
const float glow_center = 1.55;
vec3 glyph_color = vec3(1.0,1.0,1.0);
vec3 glyph_color = vec3(0.0,0.0,0.0);
vec3 outline_color = vec3(0.0,0.0,0.0);
vec3 glow_color = vec3(0.0,1.0,0.0);
vec3 glow_color = vec3(0.0,0.0,0.0);
void main(void) {
vec4 color = texture2D(EW_texID, f_texcoord );
@ -27,7 +27,6 @@ void main(void) {
float alpha = smoothstep(glyph_center-width, glyph_center+width, dist);
// Smooth
gl_FragColor = vec4(f_color[0], f_color[1], f_color[2], f_color[3]*alpha);
// Outline

View File

@ -23,21 +23,28 @@ void main(void) {
/*
// Distance map contour texturing according to Green (2007),
// implementation by Stefan Gustavson 2009.
// This code is in the public domain.
// Input :
attribute vec3 EW_coord3d;
attribute vec2 EW_texture2d;
attribute vec4 EW_color;
uniform mat4 EW_MatrixTransformation;
uniform int EW_texHeight;
uniform int EW_texWidth;
uniform sampler2D gradtexture, reftexture;
uniform float texw, texh;
varying float onestepu, onestepv;
varying vec2 st;
// output :
varying vec4 f_color;
varying vec2 f_texcoord;
varying float f_onestepu;
varying float f_onestepv;
void main( void )
{
// Get the texture coordinates
st = gl_MultiTexCoord0.xy;
onestepu = 1.0 / texw; // Saves a division in the fragment shader
onestepv = 1.0 / texh;
gl_Position = ftransform();
void main(void) {
gl_Position = EW_MatrixTransformation * vec4(EW_coord3d, 1.0);
// set texture output coord
f_texcoord = EW_texture2d;
f_onestepu = 1.0 / float(EW_texWidth);
f_onestepv = 1.0 / float(EW_texHeight);
// set output color :
f_color = EW_color;
}
*/

View File

@ -1,3 +1,74 @@
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
// Input :
uniform sampler2D EW_texID;
uniform float EW_SoftEdgeMin;
uniform float EW_SoftEdgeMax;
uniform int EW_SoftEdge;
uniform int EW_texHeight;
uniform int EW_texWidth;
varying vec2 f_texcoord;
varying vec4 f_color;
varying float f_onestepu;
varying float f_onestepv;
const float glyph_center = 0.50;
const float outline_center = 0.55;
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) {
// Scale texcoords to range ([0,texw], [0,texh])
vec2 uv = f_texcoord * vec2(EW_texWidth, EW_texHeight);
// Compute texel-local (u,v) coordinates for the four closest texels
vec2 uv00 = floor(uv - vec2(0.5)); // Lower left corner of lower left texel
vec2 uvthis = floor(uv); // Lower left corner of texel containing (u,v)
vec2 uvlerp = uv - uv00 - vec2(0.5); // Texel-local lerp blends [0,1]
// Perform explicit texture interpolation of D coefficient.
// This works around the currently very bad texture interpolation
// precision in ATI hardware.
// Center st00 on lower left texel and rescale to [0,1] for texture lookup
vec2 st00 = (uv00 + vec2(0.5)) * vec2(f_onestepu, f_onestepv);
// Compute g_u, g_v, D coefficients from four closest 8-bit RGBA texels
vec4 rawtex00 = texture2D(EW_texID, st00);
vec4 rawtex10 = texture2D(EW_texID, st00 + vec2(0.5*f_onestepu, 0.0));
vec4 rawtex01 = texture2D(EW_texID, st00 + vec2(0.0, 0.5*f_onestepv));
vec4 rawtex11 = texture2D(EW_texID, st00 + vec2(0.5*f_onestepu, 0.5*f_onestepv));
// Restore the value for D from its 8-bit encoding
vec2 D00_10 = 16.0*(vec2(rawtex00.r, rawtex10.r)-0.50196);
vec2 D01_11 = 16.0*(vec2(rawtex01.r, rawtex11.r)-0.50196);
// Interpolate D between four closest texels
vec2 uvlocal = fract(uv)-0.5; // Texel-local uv coordinates [-0.5,0.5]
// Interpolate along v
vec2 D0_1 = mix(D00_10, D01_11, uvlerp.y);
// Interpolate along u
float D = mix(D0_1.x, D0_1.y, uvlerp.x);
// Perform anisotropic analytic antialiasing (fwidth() is slightly wrong)
float aastep = length(vec2(dFdx(D), dFdy(D)));
// 'pattern' is 1 where D>0, 0 where D<0, with proper AA around D=0.
float pattern = smoothstep(-aastep, aastep, D);
// Final fragment color
gl_FragColor = vec4(f_color[0], f_color[1], f_color[2], f_color[3]*pattern);
}
#if 0
// Distance map contour texturing, Stefan Gustavson 2009
// A re-implementation of Green's method, with an
// 8-bit distance map but explicit texel interpolation.
@ -55,3 +126,4 @@ void main( void )
// Final fragment color
gl_FragColor = vec4(bitmap, pattern, bitmap, 1.0);
}
#endif

View File

@ -120,6 +120,13 @@ namespace ewol {
void setColor(const etk::Color<>& _color) {
m_color = _color;
};
/**
* @brief Get the foreground color of the font.
* @return Foreground color.
*/
const etk::Color<>& getColor(void) {
return m_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)
@ -127,6 +134,13 @@ namespace ewol {
void setColorBg(const etk::Color<>& _color) {
m_colorBg = _color;
};
/**
* @brief Get the background color of the font.
* @return Background color.
*/
const etk::Color<>& getColorBg(void) {
return m_colorBg;
};
/**
* @brief Request a clipping area for the text (next draw only)
* @param[in]_ pos Start position of the clipping

View File

@ -52,8 +52,10 @@ void ewol::compositing::Text::drawMT(const mat4& _transformationMatrix, bool _en
mat4 tmpMatrix = projMatrix * camMatrix * _transformationMatrix;
m_GLprogram->use();
m_GLprogram->uniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
// TextureID
// Texture :
m_GLprogram->setTexture0(m_GLtexID, m_font->getId());
m_GLprogram->uniform1i(m_GLtextWidth, m_font->getOpenGlSize().x());
m_GLprogram->uniform1i(m_GLtextHeight, m_font->getOpenGlSize().x());
// position :
m_GLprogram->sendAttribute(m_GLPosition, 3/*x,y,z*/, &m_coord[0]);
// Texture :
@ -89,8 +91,10 @@ void ewol::compositing::Text::drawD(bool _disableDepthTest) {
mat4 tmpMatrix = ewol::openGL::getMatrix()*m_matrixApply;
m_GLprogram->use();
m_GLprogram->uniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
// TextureID
// Texture :
m_GLprogram->setTexture0(m_GLtexID, m_font->getId());
m_GLprogram->uniform1i(m_GLtextWidth, m_font->getOpenGlSize().x());
m_GLprogram->uniform1i(m_GLtextHeight, m_font->getOpenGlSize().x());
// position :
m_GLprogram->sendAttribute(m_GLPosition, m_coord);
// Texture :
@ -340,3 +344,24 @@ void ewol::compositing::Text::printChar(const char32_t& _charcode) {
m_previousCharcode = _charcode;
return;
}
vec3 ewol::compositing::Text::calculateSizeChar(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;
}

View File

@ -53,6 +53,7 @@ namespace ewol {
virtual void setFont(std::string _fontName, int32_t _fontSize);
virtual void setFontMode(enum ewol::font::mode _mode);
virtual void printChar(const char32_t& _charcode);
virtual vec3 calculateSizeChar(const char32_t& _charcode);
};
};
};

View File

@ -56,6 +56,8 @@ void ewol::compositing::TextBase::loadProgram(const std::string& _shaderName) {
m_GLtexture = m_GLprogram->getAttribute("EW_texture2d");
m_GLMatrix = m_GLprogram->getUniform("EW_MatrixTransformation");
m_GLtexID = m_GLprogram->getUniform("EW_texID");
m_GLtextWidth = m_GLprogram->getUniform("EW_texWidth");
m_GLtextHeight = m_GLprogram->getUniform("EW_texHeight");
}
}
@ -904,25 +906,6 @@ vec3 ewol::compositing::TextBase::calculateSize(const std::u32string& _text) {
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) {

View File

@ -80,6 +80,8 @@ namespace ewol {
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)
int32_t m_GLtextWidth; //!< openGL Id on the texture width
int32_t m_GLtextHeight; //!< openGL Id on the texture height
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)
@ -398,7 +400,13 @@ namespace ewol {
* @param[in] _charcode The µUnicode value to calculate dimention.
* @return The theoric size used.
*/
vec3 calculateSize(const char32_t& _charcode);
inline vec3 calculateSize(const char32_t& _charcode) {
return calculateSizeChar(_charcode);
};
protected:
//! @previous
virtual vec3 calculateSizeChar(const char32_t& _charcode) = 0;
public:
/**
* @brief draw a cursor at the specify position
* @param[in] _isInsertMode True if the insert mode is activated

View File

@ -55,8 +55,10 @@ void ewol::compositing::TextDF::drawMT(const mat4& _transformationMatrix, bool _
mat4 tmpMatrix = projMatrix * camMatrix * _transformationMatrix;
m_GLprogram->use();
m_GLprogram->uniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
// TextureID
// Texture :
m_GLprogram->setTexture0(m_GLtexID, m_fontDF->getId());
m_GLprogram->uniform1i(m_GLtextWidth, m_fontDF->getOpenGlSize().x());
m_GLprogram->uniform1i(m_GLtextHeight, m_fontDF->getOpenGlSize().x());
// position :
m_GLprogram->sendAttribute(m_GLPosition, m_coord);
// Texture :
@ -94,8 +96,10 @@ void ewol::compositing::TextDF::drawD(bool _disableDepthTest) {
mat4 tmpMatrix = ewol::openGL::getMatrix()*m_matrixApply;
m_GLprogram->use();
m_GLprogram->uniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
// TextureID
// Texture :
m_GLprogram->setTexture0(m_GLtexID, m_fontDF->getId());
m_GLprogram->uniform1i(m_GLtextWidth, m_fontDF->getOpenGlSize().x());
m_GLprogram->uniform1i(m_GLtextHeight, m_fontDF->getOpenGlSize().x());
// position :
m_GLprogram->sendAttribute(m_GLPosition, m_coord);
// Texture :
@ -199,18 +203,29 @@ void ewol::compositing::TextDF::printChar(const char32_t& _charcode) {
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;
//EWOL_DEBUG(" plop : fontHeigh" << fontHeigh << " fontSize=" << fontSize);
float dxA = m_position.x() + ((float)myGlyph->m_bearing.x() + kerningOffset - (float)m_fontDF->getPixelBorderSize()*0.5f) * factorDisplay;
float dxB = dxA + ((float)myGlyph->m_sizeTexture.x() + (float)m_fontDF->getPixelBorderSize()) * factorDisplay;
float dyC = m_position.y() + (fontHeigh - fontSize + ((float)myGlyph->m_bearing.y() + (float)m_fontDF->getPixelBorderSize()*0.5f) * factorDisplay);
float dyD = dyC - ((float)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();
/*
vec3 drawingPos = m_vectorialDraw.getPos();
etk::Color<> backColor = m_vectorialDraw.getColor();
m_vectorialDraw.setPos(vec2(dxA, dyC));
m_vectorialDraw.setColor(etk::Color<>(0.0,1.0,0.0,1.0));
m_vectorialDraw.rectangle(vec2(dxB, dyD));
m_vectorialDraw.setPos(drawingPos);
m_vectorialDraw.setColor(backColor);
*/
// Clipping and drawing area
if( m_clippingEnable == true
&& ( dxB < m_clippingPosStart.x()
@ -339,3 +354,25 @@ void ewol::compositing::TextDF::printChar(const char32_t& _charcode) {
m_previousCharcode = _charcode;
return;
}
vec3 ewol::compositing::TextDF::calculateSizeChar(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)*m_fontDF->getDisplayRatio(getSize()),
(float)(fontHeigh),
(float)(0.0));
// Register the previous character
m_previousCharcode = _charcode;
return outputSize;
}

View File

@ -53,6 +53,7 @@ namespace ewol {
virtual void setFont(std::string _fontName, int32_t _fontSize);
virtual void setFontMode(enum ewol::font::mode _mode);
virtual void printChar(const char32_t& _charcode);
virtual vec3 calculateSizeChar(const char32_t& _charcode);
};
};
};

View File

@ -174,6 +174,8 @@ void ewol::Context::processEvents(void) {
case eSystemMessage::msgKeyboardKey:
case eSystemMessage::msgKeyboardMove:
//EWOL_DEBUG("Receive MSG : THREAD_KEYBORAD_KEY");
// store the keyboard special key status for mouse event...
m_input.setLastKeyboardSpecial(data->keyboardSpecial);
if (NULL != m_windowsCurrent) {
if (false == m_windowsCurrent->onEventShortCut(data->keyboardSpecial,
data->keyboardChar,

View File

@ -49,7 +49,7 @@ bool ewol::context::InputManager::localEventInput(enum ewol::key::type _type,
if (NULL != _destWidget) {
if (_type == ewol::key::typeMouse || _type == ewol::key::typeFinger) {
// create the system Event :
ewol::event::InputSystem tmpEventSystem(_type, _status, _IdInput, _pos, _destWidget, 0); // TODO : set the real ID ...
ewol::event::InputSystem tmpEventSystem(_type, _status, _IdInput, _pos, _destWidget, 0, m_specialKey); // TODO : set the real ID ...
// generate the event :
return _destWidget->systemEventInput(tmpEventSystem);
} else {

View File

@ -119,6 +119,12 @@ namespace ewol {
* @brief This fonction un-lock the pointer properties to move in relative instead of absolute
*/
void unGrabPointer(void);
private:
ewol::key::Special m_specialKey;
public:
void setLastKeyboardSpecial(const ewol::key::Special& _specialKey) {
m_specialKey = _specialKey;
}
};
};
};

View File

@ -19,15 +19,18 @@ namespace ewol {
enum ewol::key::status m_status;
uint8_t m_inputId;
vec2 m_pos;
ewol::key::Special m_specialKey; //!< input key status (prevent change in time..)
public:
Input(enum ewol::key::type _type,
enum ewol::key::status _status,
uint8_t _id,
const vec2& _pos):
const vec2& _pos,
ewol::key::Special _specialKey):
m_type(_type),
m_status(_status),
m_inputId(_id),
m_pos(_pos){
m_pos(_pos),
m_specialKey(_specialKey) {
};
void setType(enum ewol::key::type _type) {
@ -54,6 +57,12 @@ namespace ewol {
inline const vec2& getPos(void) const {
return m_pos;
};
void setSpecialKey(const ewol::key::Special& _specialKey) {
m_specialKey = _specialKey;
};
inline const ewol::key::Special& getSpecialKey(void) const {
return m_specialKey;
};
/**
* @brief Reset the input property of the curent event.
*/
@ -70,8 +79,9 @@ namespace ewol {
uint8_t _id,
const vec2& _pos,
ewol::Widget* _dest,
int32_t _realIdEvent) :
m_event(_type, _status, _id, _pos),
int32_t _realIdEvent,
ewol::key::Special _specialKey) :
m_event(_type, _status, _id, _pos, _specialKey),
m_dest(_dest),
m_realIdEvent(_realIdEvent) { };
ewol::event::Input m_event;

View File

@ -22,7 +22,7 @@
#undef __class__
#define __class__ "resource::DistanceFieldFont"
#define SIZE_GENERATION (70)
#define SIZE_GENERATION (30)
ewol::resource::DistanceFieldFont::DistanceFieldFont(const std::string& _fontName) :
ewol::resource::Texture(_fontName),
@ -218,12 +218,12 @@ bool ewol::resource::DistanceFieldFont::addGlyph(const char32_t& _val) {
//EWOL_DEBUG("load char : '" << _val << "'=" << _val.get());
hasChange = true;
// change line if needed ...
if (m_lastGlyphPos.x() + tmpchar.m_sizeTexture.x() > m_data.getSize().x()) {
if (m_lastGlyphPos.x() + tmpchar.m_sizeTexture.x()+m_borderSize*2.0 > m_data.getSize().x()) {
m_lastGlyphPos.setX(1);
m_lastGlyphPos += ivec2(0, m_lastRawHeigh);
m_lastRawHeigh = 0;
}
while(m_lastGlyphPos.y()+tmpchar.m_sizeTexture.y() > m_data.getSize().y()) {
while(m_lastGlyphPos.y()+tmpchar.m_sizeTexture.y()+m_borderSize*2.0 > m_data.getSize().y()) {
ivec2 size = m_data.getSize();
size.setY(size.y()*2);
m_data.resize(size, etk::Color<>(0));

View File

@ -41,7 +41,7 @@ namespace ewol {
* @return Dimention of the font need between 2 lines
*/
float getHeight(float _size) {
return _size * m_sizeRatio;;
return ((float)m_font->getHeight(_size));
};
/**
* @brief get the ID of a unicode charcode

View File

@ -34,12 +34,15 @@ namespace ewol {
void removeContextToLate(void);
// middleware interface:
public:
GLuint getId(void) {
GLuint getId(void) const {
return m_texId;
};
vec2 getUsableSize(void) {
const vec2& getUsableSize(void) const {
return m_endPointSize;
};
const ivec2& getOpenGlSize(void) const {
return m_data.getSize();
};
// Public API:
protected:
Texture(const std::string& _filename);

View File

@ -238,12 +238,12 @@ bool ewol::resource::TexturedFont::addGlyph(const char32_t& _val) {
//EWOL_DEBUG("load char : '" << _val << "'=" << _val.get());
hasChange = true;
// change line if needed ...
if (m_lastGlyphPos[iii].x()+tmpchar.m_sizeTexture.x() > m_data.getSize().x()) {
if (m_lastGlyphPos[iii].x()+tmpchar.m_sizeTexture.x()+3 > m_data.getSize().x()) {
m_lastGlyphPos[iii].setX(1);
m_lastGlyphPos[iii] += ivec2(0, m_lastRawHeigh[iii]);
m_lastRawHeigh[iii] = 0;
}
while(m_lastGlyphPos[iii].y()+tmpchar.m_sizeTexture.y() > m_data.getSize().y()) {
while(m_lastGlyphPos[iii].y()+tmpchar.m_sizeTexture.y()+3 > m_data.getSize().y()) {
ivec2 size = m_data.getSize();
size.setY(size.y()*2);
m_data.resize(size, etk::Color<>(0));

View File

@ -231,6 +231,11 @@ namespace ewol {
* @return the current zoom value
*/
virtual float getZoom(void);
/**
* @brief Change Zoom property.
* @param[in] _range Range of the zoom change.
*/
virtual void changeZoom(float _range) {};
protected:
vec2 m_origin; //!< internal ... I do not really known how i can use it ...
public:

View File

@ -116,12 +116,14 @@ bool ewol::widget::WidgetScrooled::onEventInput(const ewol::event::Input& _event
return false;
} else if ( _event.getId() == 4
&& _event.getStatus() == ewol::key::statusUp) {
if (true == _event.getSpecialKey().getCtrl()) {
changeZoom(1);
/*
if (true == ewol::isSetCtrl()) {
float zoom = getZoom()*1.1;
zoom = etk_avg(0.1, zoom, 5000);
setZoom(zoom);
} else */{
*/
} else {
if(m_size.y() < m_maxSize.y()
|| m_originScrooled.y() != 0
|| m_size.y()*m_limitScrolling < m_maxSize.y() ) {
@ -133,12 +135,14 @@ bool ewol::widget::WidgetScrooled::onEventInput(const ewol::event::Input& _event
}
} else if ( _event.getId() == 5
&& _event.getStatus() == ewol::key::statusUp) {
if (true == _event.getSpecialKey().getCtrl()) {
changeZoom(-1);
/*
if (true == ewol::isSetCtrl()) {
float zoom = getZoom()*0.9;
zoom = etk_avg(0.1, zoom, 5000);
setZoom(zoom);
} else */{
*/
} else {
if(m_size.y() < m_maxSize.y()
|| m_originScrooled.y()!=0
|| m_size.y()*m_limitScrolling < m_maxSize.y() ) {