From 00945a44d795a62032283733fd1a40cc9b29d22a Mon Sep 17 00:00:00 2001
From: Jack Andersen <jackoalan@gmail.com>
Date: Thu, 17 May 2018 18:15:11 -1000
Subject: [PATCH] Better use of TextView resources

---
 specter/include/specter/TextView.hpp |  1 +
 specter/lib/MultiLineTextView.cpp    | 20 ++++++++++++--------
 specter/lib/TextView.cpp             | 14 +++++++++++---
 3 files changed, 24 insertions(+), 11 deletions(-)

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<RenderGlyph>::Token m_glyphBuf;
     boo::ObjToken<boo::IVertexFormat> m_vtxFmt; /* OpenGL only */
     boo::ObjToken<boo::IShaderDataBinding> 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<const utf8proc_uint8_t*>(str.data());
 
@@ -191,6 +190,7 @@ void MultiLineTextView::typesetGlyphs(std::string_view str,
     rem = str.size() + 1;
     it = reinterpret_cast<const utf8proc_uint8_t*>(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();