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;
|
void update_cached_state() const;
|
||||||
cached_state cached_state_for(geom::box<float, 2> const & bbox) 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();
|
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;
|
if (!font) return state;
|
||||||
|
|
||||||
shape_options opts;
|
shape_options opts;
|
||||||
|
|
@ -242,6 +245,12 @@ namespace psemek::ui
|
||||||
|
|
||||||
float max_line_size = 0.f;
|
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)
|
for (std::size_t l = 0; l < lines.size(); ++l)
|
||||||
{
|
{
|
||||||
geom::interval<float> x_range;
|
geom::interval<float> x_range;
|
||||||
|
|
@ -290,6 +299,14 @@ namespace psemek::ui
|
||||||
break;
|
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)
|
for (std::size_t i = lines[l].first; i < lines[l].second; ++i)
|
||||||
{
|
{
|
||||||
glyphs[i].position += offset;
|
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[0] = max_line_size;
|
||||||
state.size[1] = lines.size() * (*st->text_scale) * font->size()[1];
|
state.size[1] = lines.size() * (*st->text_scale) * font->size()[1];
|
||||||
|
|
||||||
return state;
|
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