Optimize UITextEdit rendering
This commit is contained in:
parent
559e545e36
commit
6893a5e98a
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())); }
|
||||
|
|
|
@ -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;i<m_selectionStart;++i)
|
||||
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||
}
|
||||
|
||||
for(int i=m_selectionStart;i<m_selectionEnd;++i) {
|
||||
g_painter->setColor(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;i<textLength;++i)
|
||||
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||
}
|
||||
} else if(m_color != Color::alpha) {
|
||||
g_painter->setColor(m_color);
|
||||
if(glyphsMustRecache) {
|
||||
m_glyphsTextCoordsBuffer.clear();
|
||||
for(int i=0;i<textLength;++i)
|
||||
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||
m_glyphsTextCoordsBuffer.addRect(m_glyphsCoords[i], m_glyphsTexCoords[i]);
|
||||
}
|
||||
g_painter->setColor(m_color);
|
||||
g_painter->drawTextureCoords(m_glyphsTextCoordsBuffer, texture);
|
||||
}
|
||||
|
||||
if(hasSelection()) {
|
||||
if(glyphsMustRecache) {
|
||||
m_glyphsSelectCoordsBuffer.clear();
|
||||
for(int i=m_selectionStart;i<m_selectionEnd;++i)
|
||||
m_glyphsSelectCoordsBuffer.addRect(m_glyphsCoords[i], m_glyphsTexCoords[i]);
|
||||
}
|
||||
g_painter->setColor(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<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
|
||||
|
@ -360,6 +364,7 @@ void UITextEdit::setSelection(int start, int end)
|
|||
|
||||
m_selectionStart = stdext::clamp<int>(start, 0, (int)m_text.length());
|
||||
m_selectionEnd = stdext::clamp<int>(end, 0, (int)m_text.length());
|
||||
recacheGlyphs();
|
||||
}
|
||||
|
||||
void UITextEdit::setTextHidden(bool hidden)
|
||||
|
|
|
@ -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<Rect> m_glyphsCoords;
|
||||
std::vector<Rect> m_glyphsTexCoords;
|
||||
|
||||
CoordsBuffer m_glyphsTextCoordsBuffer;
|
||||
CoordsBuffer m_glyphsSelectCoordsBuffer;
|
||||
bool m_glyphsMustRecache;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue