improve text input

This commit is contained in:
2019-09-17 13:57:37 +02:00
parent 882a516455
commit 72fa400651
14 changed files with 598 additions and 83 deletions

View File

@@ -83,7 +83,7 @@ std::vector<TextMesh::Token> TextMesh::tokenize(const std::string& s, const Font
bool is_delim = std::find(delims.begin(), delims.end(), c) != delims.end();
wrap |= is_delim; // set wrap to notify a delimiter has been reached
// when a new non-delim char is detected, start a new token
if (wrap && !is_delim)
if (wrap && !is_delim && !tmp.empty())
{
parts.push_back(tmp);
tmp.clear();
@@ -130,40 +130,61 @@ bool TextMesh::create()
return true;
}
void TextMesh::update(kFont id, const char* text)
void TextMesh::update(kFont id, const std::string& text)
{
font_id = id;
auto& f = FontManager::get(id);
float spacing = f.bounds.w - f.bounds.y;
float avg_width = f.bounds.z - f.bounds.x;
cur_box = glm::vec4(0, 0, 5, spacing);
glm::vec2 bbmin(FLT_MAX);
glm::vec2 bbmax(-FLT_MAX);
if (text.empty())
{
bbmin = { 0, -spacing * 0.5f };
bbmax = { 1, +spacing * 0.5f };
}
if (f.chars.size())
{
float x = 0;
float y = 0;
std::vector<glm::vec4> v;
std::vector<GLushort> idx;
glm::vec2 bbmin(FLT_MAX);
glm::vec2 bbmax(-FLT_MAX);
std::vector<Token> parts = max_width > 0 ?
tokenize(text, f) :
std::vector<Token>{ Token(text, 0.f) };
if (parts.empty())
{
bbmin = { 0, -spacing * 0.5f };
bbmax = { 1, +spacing * 0.5f };
}
for (auto p : parts)
{
if (max_width > 0 && x + p.w > max_width * f.scale)
if (max_width > 0 && (x + p.w) * f.scale > max_width)
{
x = 0;
y += f.size * f.scale;
y += spacing;
}
for (char c : p.s)
{
if (c == '\n')
{
x = 0;
y += f.size * f.scale;
y += spacing;
continue;
}
stbtt_aligned_quad q;
stbtt_GetBakedQuad((stbtt_bakedchar*)f.chars.data(), f.w, f.h, c - f.start_char, &x, &y, &q, true);
if (max_width > 0 && x * f.scale > max_width /*font scale factor*/)
{
x = 0;
y += spacing;
}
auto n = (int)v.size();
v.emplace_back(q.x0 / f.scale, q.y1 / f.scale, q.s0, q.t1);
v.emplace_back(q.x0 / f.scale, q.y0 / f.scale, q.s0, q.t0);
@@ -177,6 +198,7 @@ void TextMesh::update(kFont id, const char* text)
idx.push_back(n + 3);
bbmin = glm::min(bbmin, { q.x0 / f.scale, q.y0 / f.scale });
bbmax = glm::max(bbmax, { q.x1 / f.scale, q.y1 / f.scale });
cur_box = glm::vec4(x, y, 5, spacing);
}
}
for (auto& vi : v)