improve text input
This commit is contained in:
36
src/font.cpp
36
src/font.cpp
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user