Remove draw_glyph using in ui::edit, cache raw images instead

This commit is contained in:
Nikita Lisitsa 2022-05-19 12:06:04 +03:00
parent 35eaf17a3b
commit 395464ebd5
2 changed files with 34 additions and 19 deletions

View file

@ -104,8 +104,14 @@ namespace psemek::ui
struct cached_state
{
struct font const * font = nullptr;
std::vector<glyph> glyphs;
struct image
{
geom::box<float, 2> texcoords;
geom::box<float, 2> position;
};
gfx::texture_2d const * texture = nullptr;
std::vector<image> images;
geom::vector<float, 2> size{0.f, 0.f};
};

View file

@ -146,11 +146,11 @@ namespace psemek::ui
break;
}
auto it = std::lower_bound(cached_state_->glyphs.begin(), cached_state_->glyphs.end(), *mouse_x_, [&](glyph const & g, float x){
return g.position[0].center() + x_offset < x;
auto it = std::lower_bound(cached_state_->images.begin(), cached_state_->images.end(), *mouse_x_, [&](auto const & i, float x){
return i.position[0].center() + x_offset < x;
});
caret_ = it - cached_state_->glyphs.begin();
caret_ = it - cached_state_->images.begin();
caret_blink_timer_ = 0.f;
caret_visible_ = true;
}
@ -388,19 +388,28 @@ namespace psemek::ui
if (!cached_state_)
{
auto font = (font_ == font_type::bold) ? st->bold_font.get() : st->font.get();
cached_state state;
state.font = (font_ == font_type::bold) ? st->bold_font.get() : st->font.get();
state.texture = &font->atlas();
shape_options options;
options.scale = *st->text_scale;
state.glyphs = state.font->shape(text_, options);
auto glyphs = font->shape(text_, options);
geom::box<float, 2> bbox;
for (auto const & g : state.glyphs)
for (auto const & g : glyphs)
bbox |= g.position;
state.size[0] = state.glyphs.empty() ? 0.f : bbox[0].length();
state.size[1] = state.font->size()[1] * (*st->text_scale);
state.size[0] = glyphs.empty() ? 0.f : bbox[0].length();
state.size[1] = font->size()[1] * (*st->text_scale);
for (auto const & g : glyphs)
{
auto tc = font->texcoords(g.character);
if (!tc) continue;
state.images.push_back({*tc, g.position});
}
cached_state_ = std::move(state);
}
@ -440,26 +449,26 @@ namespace psemek::ui
if (*st->text_shadow_offset != geom::vector{0, 0} && (*st->shadow_color)[3] != 0)
{
auto shoffset = offset + geom::cast<float>(*st->text_shadow_offset);
for (auto const & g : cached_state_->glyphs)
p.draw_glyph(*cached_state_->font, g.character, g.position + shoffset, *st->shadow_color);
for (auto const & i : cached_state_->images)
p.draw_image(i.position + shoffset, {cached_state_->texture, i.texcoords}, {*st->shadow_color});
}
for (auto const & g : cached_state_->glyphs)
p.draw_glyph(*cached_state_->font, g.character, g.position + offset, *st->text_color);
for (auto const & i : cached_state_->images)
p.draw_image(i.position + offset, {cached_state_->texture, i.texcoords}, {*st->text_color});
p.end_stencil();
if (caret_visible_)
{
float x;
if (cached_state_->glyphs.empty())
if (cached_state_->images.empty())
x = 0.f;
else if (caret_ == 0)
x = cached_state_->glyphs.front().position[0].min;
else if (caret_ >= cached_state_->glyphs.size())
x = cached_state_->glyphs.back().position[0].max;
x = cached_state_->images.front().position[0].min;
else if (caret_ >= cached_state_->images.size())
x = cached_state_->images.back().position[0].max;
else
x = (cached_state_->glyphs[caret_ - 1].position[0].max + cached_state_->glyphs[caret_].position[0].min) / 2.f;
x = (cached_state_->images[caret_ - 1].position[0].max + cached_state_->images[caret_].position[0].min) / 2.f;
x += offset[0];