diff --git a/src/framework/graphics/ogl/painterogl1.cpp b/src/framework/graphics/ogl/painterogl1.cpp index 7223e4c9..f47e5353 100644 --- a/src/framework/graphics/ogl/painterogl1.cpp +++ b/src/framework/graphics/ogl/painterogl1.cpp @@ -135,6 +135,12 @@ void PainterOGL1::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode) #endif } +void PainterOGL1::drawFillCoords(CoordsBuffer& coordsBuffer) +{ + setTexture(nullptr); + drawCoords(coordsBuffer); +} + void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) { if(texture->isEmpty()) diff --git a/src/framework/graphics/ogl/painterogl1.h b/src/framework/graphics/ogl/painterogl1.h index 8799fb51..66c5dfae 100644 --- a/src/framework/graphics/ogl/painterogl1.h +++ b/src/framework/graphics/ogl/painterogl1.h @@ -50,6 +50,7 @@ public: void refreshState(); void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles); + void drawFillCoords(CoordsBuffer& coordsBuffer); void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture); void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); diff --git a/src/framework/graphics/ogl/painterogl2.cpp b/src/framework/graphics/ogl/painterogl2.cpp index fa4caa51..9e6ab4c5 100644 --- a/src/framework/graphics/ogl/painterogl2.cpp +++ b/src/framework/graphics/ogl/painterogl2.cpp @@ -120,6 +120,13 @@ void PainterOGL2::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode) PainterShaderProgram::enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR); } +void PainterOGL2::drawFillCoords(CoordsBuffer& coordsBuffer) +{ + setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawSolidColorProgram.get()); + setTexture(nullptr); + drawCoords(coordsBuffer); +} + void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) { if(texture && texture->isEmpty()) diff --git a/src/framework/graphics/ogl/painterogl2.h b/src/framework/graphics/ogl/painterogl2.h index 2b02474e..f6d40582 100644 --- a/src/framework/graphics/ogl/painterogl2.h +++ b/src/framework/graphics/ogl/painterogl2.h @@ -41,6 +41,7 @@ public: void unbind(); void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles); + void drawFillCoords(CoordsBuffer& coordsBuffer); void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture); void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index 1c710cdf..c8145aa4 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -62,6 +62,7 @@ public: virtual void clear(const Color& color) = 0; virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0; + virtual void drawFillCoords(CoordsBuffer& coordsBuffer) = 0; virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0; virtual void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0; void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); } diff --git a/src/framework/ui/uitextedit.cpp b/src/framework/ui/uitextedit.cpp index d3006346..cffec788 100644 --- a/src/framework/ui/uitextedit.cpp +++ b/src/framework/ui/uitextedit.cpp @@ -49,6 +49,9 @@ UITextEdit::UITextEdit() m_updatesEnabled = true; m_selectionColor = Color::white; m_selectionBackgroundColor = Color::black; + m_glyphsTextCoordsBuffer.enableHardwareCaching(); + m_glyphsSelectCoordsBuffer.enableHardwareCaching(); + m_glyphsMustRecache = true; blinkCursor(); } @@ -62,38 +65,36 @@ void UITextEdit::drawSelf(Fw::DrawPane drawPane) drawImage(m_rect); drawIcon(m_rect); - //TODO: text rendering could be much optimized by using vertex buffer or caching the render into a texture - int textLength = m_text.length(); const TexturePtr& texture = m_font->getTexture(); if(!texture) return; - if(hasSelection()) { - if(m_color != Color::alpha) { - g_painter->setColor(m_color); - for(int i=0;idrawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]); - } - - for(int i=m_selectionStart;isetColor(m_selectionBackgroundColor); - g_painter->drawFilledRect(m_glyphsCoords[i]); - g_painter->setColor(m_selectionColor); - g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]); - } + bool glyphsMustRecache = m_glyphsMustRecache; + if(glyphsMustRecache) + m_glyphsMustRecache = false; - if(m_color != Color::alpha) { - g_painter->setColor(m_color); - for(int i=m_selectionEnd;idrawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]); + if(m_color != Color::alpha) { + if(glyphsMustRecache) { + m_glyphsTextCoordsBuffer.clear(); + for(int i=0;isetColor(m_color); - for(int i=0;idrawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]); + g_painter->drawTextureCoords(m_glyphsTextCoordsBuffer, texture); } + if(hasSelection()) { + if(glyphsMustRecache) { + m_glyphsSelectCoordsBuffer.clear(); + for(int i=m_selectionStart;isetColor(m_selectionBackgroundColor); + g_painter->drawFillCoords(m_glyphsSelectCoordsBuffer); + g_painter->setColor(m_selectionColor); + g_painter->drawTextureCoords(m_glyphsSelectCoordsBuffer, texture); + } // render cursor if(isExplicitlyEnabled() && m_cursorVisible && m_cursorInRange && isActive() && m_cursorPos >= 0) { @@ -136,6 +137,9 @@ void UITextEdit::update(bool focusCursor) if(m_rect.isEmpty()) return; + // recache coords buffers + recacheGlyphs(); + // map glyphs positions Size textBoxSize; const std::vector& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize); @@ -360,6 +364,7 @@ void UITextEdit::setSelection(int start, int end) m_selectionStart = stdext::clamp(start, 0, (int)m_text.length()); m_selectionEnd = stdext::clamp(end, 0, (int)m_text.length()); + recacheGlyphs(); } void UITextEdit::setTextHidden(bool hidden) diff --git a/src/framework/ui/uitextedit.h b/src/framework/ui/uitextedit.h index 2b9bb93b..79508bb4 100644 --- a/src/framework/ui/uitextedit.h +++ b/src/framework/ui/uitextedit.h @@ -108,6 +108,7 @@ protected: private: void disableUpdates() { m_updatesEnabled = false; } void enableUpdates() { m_updatesEnabled = true; } + void recacheGlyphs() { m_glyphsMustRecache = true; } Rect m_drawArea; int m_cursorPos; @@ -137,6 +138,10 @@ private: std::vector m_glyphsCoords; std::vector m_glyphsTexCoords; + + CoordsBuffer m_glyphsTextCoordsBuffer; + CoordsBuffer m_glyphsSelectCoordsBuffer; + bool m_glyphsMustRecache; }; #endif