Implement underline & strikethrough in ui::label
This commit is contained in:
parent
b9b3e7577b
commit
a9de6232de
2 changed files with 70 additions and 0 deletions
|
|
@ -106,6 +106,9 @@ namespace psemek::ui
|
|||
|
||||
void update_cached_state() const;
|
||||
cached_state cached_state_for(geom::box<float, 2> const & bbox) const;
|
||||
|
||||
mutable std::shared_ptr<gfx::texture_2d> single_white_pixel_texture_;
|
||||
std::shared_ptr<gfx::texture_2d> single_white_pixel_texture() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,9 @@ namespace psemek::ui
|
|||
|
||||
auto font = st->text_style->is_set(text_style_flag::bold) ? st->bold_font.get() : st->font.get();
|
||||
|
||||
bool const underline = st->text_style->is_set(text_style_flag::underline);
|
||||
bool const strikethrough = st->text_style->is_set(text_style_flag::strikethrough);
|
||||
|
||||
if (!font) return state;
|
||||
|
||||
shape_options opts;
|
||||
|
|
@ -242,6 +245,12 @@ namespace psemek::ui
|
|||
|
||||
float max_line_size = 0.f;
|
||||
|
||||
float const underline_width = *(st->text_scale);
|
||||
float const strikethrough_width = *(st->text_scale);
|
||||
|
||||
std::vector<geom::box<float, 2>> underline_box(lines.size());
|
||||
std::vector<geom::box<float, 2>> strikethrough_box(lines.size());
|
||||
|
||||
for (std::size_t l = 0; l < lines.size(); ++l)
|
||||
{
|
||||
geom::interval<float> x_range;
|
||||
|
|
@ -290,6 +299,14 @@ namespace psemek::ui
|
|||
break;
|
||||
}
|
||||
|
||||
underline_box[l][0] = x_range + offset[0];
|
||||
underline_box[l][1].min = offset[1] + font->size()[1] * (*st->text_scale);
|
||||
underline_box[l][1].max = underline_box[l][1].min + underline_width;
|
||||
|
||||
strikethrough_box[l][0] = x_range + offset[0];
|
||||
strikethrough_box[l][1].min = offset[1] + font->size()[1] * (*st->text_scale) / 2.f;
|
||||
strikethrough_box[l][1].max = strikethrough_box[l][1].min + strikethrough_width;
|
||||
|
||||
for (std::size_t i = lines[l].first; i < lines[l].second; ++i)
|
||||
{
|
||||
glyphs[i].position += offset;
|
||||
|
|
@ -315,10 +332,60 @@ namespace psemek::ui
|
|||
}
|
||||
}
|
||||
|
||||
if (underline)
|
||||
{
|
||||
auto & batch = state.batches.emplace_back();
|
||||
batch.texture = single_white_pixel_texture().get();
|
||||
|
||||
for (auto const & u : underline_box)
|
||||
{
|
||||
auto & image = batch.images.emplace_back();
|
||||
image.position = u;
|
||||
image.texcoords = {{{0.f, 1.f}, {0.f, 1.f}}};
|
||||
}
|
||||
}
|
||||
|
||||
if (strikethrough)
|
||||
{
|
||||
auto & batch = state.batches.emplace_back();
|
||||
batch.texture = single_white_pixel_texture().get();
|
||||
|
||||
for (auto const & u : strikethrough_box)
|
||||
{
|
||||
auto & image = batch.images.emplace_back();
|
||||
image.position = u;
|
||||
image.texcoords = {{{0.f, 1.f}, {0.f, 1.f}}};
|
||||
}
|
||||
}
|
||||
|
||||
state.size[0] = max_line_size;
|
||||
state.size[1] = lines.size() * (*st->text_scale) * font->size()[1];
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
std::shared_ptr<gfx::texture_2d> label::single_white_pixel_texture() const
|
||||
{
|
||||
static std::weak_ptr<gfx::texture_2d> texture;
|
||||
|
||||
if (!single_white_pixel_texture_)
|
||||
{
|
||||
std::shared_ptr<gfx::texture_2d> ptr;
|
||||
|
||||
if (!(ptr = texture.lock()))
|
||||
{
|
||||
ptr = std::make_shared<gfx::texture_2d>();
|
||||
|
||||
gfx::pixmap_rgba pm({1, 1}, {255, 255, 255, 255});
|
||||
ptr->load(pm);
|
||||
ptr->nearest_filter();
|
||||
texture = ptr;
|
||||
}
|
||||
|
||||
single_white_pixel_texture_ = ptr;
|
||||
}
|
||||
|
||||
return single_white_pixel_texture_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue