From 395464ebd5bd37a95ea874b02ab3c32a621b523f Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 19 May 2022 12:06:04 +0300 Subject: [PATCH] Remove draw_glyph using in ui::edit, cache raw images instead --- libs/ui/include/psemek/ui/edit.hpp | 10 +++++-- libs/ui/source/edit.cpp | 43 ++++++++++++++++++------------ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/libs/ui/include/psemek/ui/edit.hpp b/libs/ui/include/psemek/ui/edit.hpp index 89f5dff5..ad54c6f4 100644 --- a/libs/ui/include/psemek/ui/edit.hpp +++ b/libs/ui/include/psemek/ui/edit.hpp @@ -104,8 +104,14 @@ namespace psemek::ui struct cached_state { - struct font const * font = nullptr; - std::vector glyphs; + struct image + { + geom::box texcoords; + geom::box position; + }; + + gfx::texture_2d const * texture = nullptr; + std::vector images; geom::vector size{0.f, 0.f}; }; diff --git a/libs/ui/source/edit.cpp b/libs/ui/source/edit.cpp index 91ba2a79..ca85cf30 100644 --- a/libs/ui/source/edit.cpp +++ b/libs/ui/source/edit.cpp @@ -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 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(*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];