diff --git a/specter/include/specter/TextView.hpp b/specter/include/specter/TextView.hpp index 3d2b1288b..9e6893bb0 100644 --- a/specter/include/specter/TextView.hpp +++ b/specter/include/specter/TextView.hpp @@ -60,6 +60,7 @@ public: private: size_t m_capacity; + size_t m_curSize = 0; hecl::VertexBufferPool::Token m_glyphBuf; boo::ObjToken m_vtxFmt; /* OpenGL only */ boo::ObjToken m_shaderBinding; diff --git a/specter/lib/MultiLineTextView.cpp b/specter/lib/MultiLineTextView.cpp index c927ccf7b..c4d6df21a 100644 --- a/specter/lib/MultiLineTextView.cpp +++ b/specter/lib/MultiLineTextView.cpp @@ -170,7 +170,6 @@ void MultiLineTextView::typesetGlyphs(std::string_view str, } m_width = 0; - m_lines.clear(); size_t rem = str.size() + 1; const utf8proc_uint8_t* it = reinterpret_cast(str.data()); @@ -191,6 +190,7 @@ void MultiLineTextView::typesetGlyphs(std::string_view str, rem = str.size() + 1; it = reinterpret_cast(str.data()); const utf8proc_uint8_t* beginIt = it; + size_t lineIt = 0; while (rem) { @@ -198,10 +198,12 @@ void MultiLineTextView::typesetGlyphs(std::string_view str, utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch); if (ch == '\n' || ch == '\0') { - m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity)); - m_lines.back()->typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor); - m_width = std::max(m_width, m_lines.back()->nominalWidth()); + TextView& tv = (lineIt < m_lines.size()) ? *m_lines[lineIt] : + *m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity)); + tv.typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor); + m_width = std::max(m_width, tv.nominalWidth()); beginIt = it + 1; + ++lineIt; } rem -= sz; it += sz; @@ -221,7 +223,6 @@ void MultiLineTextView::typesetGlyphs(std::wstring_view str, } m_width = 0; - m_lines.clear(); size_t rem = str.size() + 1; auto it = str.cbegin(); @@ -238,15 +239,18 @@ void MultiLineTextView::typesetGlyphs(std::wstring_view str, rem = str.size() + 1; it = str.cbegin(); auto beginIt = it; + size_t lineIt = 0; while (rem) { if (*it == L'\n' || *it == L'\0') { - m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity)); - m_lines.back()->typesetGlyphs(std::wstring(beginIt, it), defaultColor); - m_width = std::max(m_width, m_lines.back()->nominalWidth()); + TextView& tv = (lineIt < m_lines.size()) ? *m_lines[lineIt] : + *m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity)); + tv.typesetGlyphs(std::wstring(beginIt, it), defaultColor); + m_width = std::max(m_width, tv.nominalWidth()); beginIt = it + 1; + ++lineIt; } --rem; ++it; diff --git a/specter/lib/TextView.cpp b/specter/lib/TextView.cpp index 15e2f08ab..adcc1f527 100644 --- a/specter/lib/TextView.cpp +++ b/specter/lib/TextView.cpp @@ -300,7 +300,7 @@ void TextView::_commitResources(size_t capacity) { auto& res = rootView().viewRes(); auto fontTex = m_fontAtlas.texture(res.m_factory); - View::commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool + View::commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) { buildResources(ctx, res); @@ -409,7 +409,11 @@ void TextView::typesetGlyphs(std::string_view str, const zeus::CColor& defaultCo { UTF8Iterator it(str.begin()); size_t charLen = str.size() ? std::min(it.countTo(str.end()), m_capacity) : 0; - _commitResources(charLen); + if (charLen > m_curSize) + { + m_curSize = charLen; + _commitResources(charLen); + } uint32_t lCh = -1; m_glyphs.clear(); @@ -478,7 +482,11 @@ void TextView::typesetGlyphs(std::string_view str, const zeus::CColor& defaultCo void TextView::typesetGlyphs(std::wstring_view str, const zeus::CColor& defaultColor) { size_t charLen = std::min(str.size(), m_capacity); - _commitResources(charLen); + if (charLen > m_curSize) + { + m_curSize = charLen; + _commitResources(charLen); + } uint32_t lCh = -1; m_glyphs.clear();