Skip to content

Commit

Permalink
fix: colorize text in UITextEdit (mehah#917)
Browse files Browse the repository at this point in the history
  • Loading branch information
nekiro authored Oct 11, 2024
1 parent e9d4b1d commit 54421bb
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 12 deletions.
58 changes: 50 additions & 8 deletions src/framework/ui/uitextedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,15 @@ void UITextEdit::drawSelf(DrawPoolType drawPane)
m_placeholderFont->drawText(m_placeholder, m_drawArea, m_placeholderColor, m_placeholderAlign);
}
}

if (m_color != Color::alpha) {
if (glyphsMustRecache) {
m_glyphsTextRectCache.clear();
for (int i = -1; ++i < textLength;)
m_glyphsTextRectCache.emplace_back(m_glyphsCoords[i].first, m_glyphsCoords[i].second);
if (m_drawTextColors.empty() || m_colorCoordsBuffer.empty()) {
g_drawPool.addTexturedCoordsBuffer(texture, m_coordsBuffer, m_color, m_textDrawConductor);
} else {
for (const auto& [color, coordsBuffer] : m_colorCoordsBuffer) {
g_drawPool.addTexturedCoordsBuffer(texture, coordsBuffer, color, m_textDrawConductor);
}
}
for (const auto& [dest, src] : m_glyphsTextRectCache)
g_drawPool.addTexturedRect(dest, texture, src, m_color);
}

if (hasSelection()) {
Expand Down Expand Up @@ -258,12 +259,40 @@ void UITextEdit::update(bool focusCursor)
} else { // AlignLeft
}

std::map<uint32_t, CoordsBufferPtr> colorCoordsMap;
uint32_t curColorRgba;
int32_t nextColorIndex = 0;
int32_t colorIndex = -1;
CoordsBufferPtr coords;

const int textColorsSize = m_drawTextColors.size();
m_colorCoordsBuffer.clear();
m_coordsBuffer->clear();

for (int i = 0; i < textLength; ++i) {
if (i >= nextColorIndex) {
colorIndex = colorIndex + 1;
if (colorIndex < textColorsSize) {
curColorRgba = m_drawTextColors[colorIndex].second.rgba();
}
if (colorIndex + 1 < textColorsSize) {
nextColorIndex = m_drawTextColors[colorIndex + 1].first;
} else {
nextColorIndex = textLength;
}

if (colorCoordsMap.find(curColorRgba) == colorCoordsMap.end()) {
colorCoordsMap.insert(std::make_pair(curColorRgba, std::make_shared<CoordsBuffer>()));
}

coords = colorCoordsMap[curColorRgba];
}

glyph = static_cast<uint8_t>(text[i]);
m_glyphsCoords[i].first.clear();

// skip invalid glyphs
if (glyph < 32 && glyph != static_cast<uint8_t>('\n'))
if (glyph < 32)
continue;

// calculate initial glyph rect and texture coords
Expand Down Expand Up @@ -324,6 +353,16 @@ void UITextEdit::update(bool focusCursor)
// render glyph
m_glyphsCoords[i].first = glyphScreenCoords;
m_glyphsCoords[i].second = glyphTextureCoords;

if (textColorsSize > 0) {
coords->addRect(glyphScreenCoords, glyphTextureCoords);
} else {
m_coordsBuffer->addRect(glyphScreenCoords, glyphTextureCoords);
}
}

for (auto& [rgba, crds] : colorCoordsMap) {
m_colorCoordsBuffer.emplace_back(Color(rgba), crds);
}

if (fireAreaUpdate)
Expand Down Expand Up @@ -575,8 +614,11 @@ void UITextEdit::updateDisplayedText()
else
text = m_text;

if (isTextWrap() && m_rect.isValid())
m_drawTextColors = m_textColors;

if (isTextWrap() && m_rect.isValid()) {
text = m_font->wrapText(text, getPaddingRect().width() - m_textOffset.x);
}

m_displayedText = text;
}
Expand Down
1 change: 0 additions & 1 deletion src/framework/ui/uitextedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ class UITextEdit : public UIWidget

std::vector<std::pair<Rect, Rect>> m_glyphsCoords;

std::vector<std::pair<Rect, Rect>> m_glyphsTextRectCache;
std::vector<std::pair<Rect, Rect>> m_glyphsSelectRectCache;

std::string m_displayedText;
Expand Down
8 changes: 5 additions & 3 deletions src/framework/ui/uiwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ class UIWidget : public LuaObject
DrawConductor m_backgroundDrawConductor;
DrawConductor m_imageDrawConductor;
DrawConductor m_iconDrawConductor;
DrawConductor m_textDrawConductor;
DrawConductor m_borderDrawConductor;

// state managment
Expand Down Expand Up @@ -383,6 +382,8 @@ class UIWidget : public LuaObject
uint16_t m_autoRepeatDelay{ 500 };
Point m_lastClickPosition;

DrawConductor m_textDrawConductor;

public:
void setX(int x) { move(x, getY()); }
void setY(int y) { move(getX(), y); }
Expand Down Expand Up @@ -573,8 +574,6 @@ class UIWidget : public LuaObject
Rect m_textCachedScreenCoords;
std::vector<Point> m_glyphsPositionsCache;
Size m_textSize;
CoordsBufferPtr m_coordsBuffer;
std::vector<std::pair<Color, CoordsBufferPtr>> m_colorCoordsBuffer;

protected:
virtual void updateText();
Expand All @@ -592,6 +591,9 @@ class UIWidget : public LuaObject
std::vector<std::pair<int, Color>> m_textColors;
std::vector<std::pair<int, Color>> m_drawTextColors;

CoordsBufferPtr m_coordsBuffer;
std::vector<std::pair<Color, CoordsBufferPtr>> m_colorCoordsBuffer;

float m_fontScale{ 1.f };

public:
Expand Down

0 comments on commit 54421bb

Please sign in to comment.