Fix ui::label underline & strikethrough handling
This commit is contained in:
parent
2b228fbd32
commit
3f282356d7
1 changed files with 31 additions and 65 deletions
|
|
@ -449,6 +449,17 @@ namespace psemek::ui
|
|||
{
|
||||
float const line_width = 1.f * (*st->text_scale);
|
||||
|
||||
auto get_batch = [&](gfx::color_rgba const & color) -> cached_state::batch & {
|
||||
auto texture = single_white_pixel_texture().get();
|
||||
if (state.batches.empty() || state.batches.back().texture != texture || state.batches.back().color != color)
|
||||
{
|
||||
auto & b = state.batches.emplace_back();
|
||||
b.texture = texture;
|
||||
b.color = color;
|
||||
}
|
||||
return state.batches.back();
|
||||
};
|
||||
|
||||
std::size_t ch_begin = 0;
|
||||
std::size_t ch = 0;
|
||||
for (std::size_t l = 0; l < lines.size(); ++l)
|
||||
|
|
@ -456,33 +467,8 @@ namespace psemek::ui
|
|||
float underline_y = std::round(line_offset[l][1] + font_height - line_width);
|
||||
float strikethrough_y = std::round(line_offset[l][1] + font_height / 2.f - line_width / 2.f);
|
||||
|
||||
std::optional<std::pair<geom::interval<float>, gfx::color_rgba>> current_underline;
|
||||
std::optional<std::pair<geom::interval<float>, gfx::color_rgba>> current_strikethrough;
|
||||
|
||||
auto batch = [&](gfx::color_rgba const & color) -> cached_state::batch & {
|
||||
auto texture = single_white_pixel_texture().get();
|
||||
if (state.batches.empty() || state.batches.back().texture != texture || state.batches.back().color != color)
|
||||
{
|
||||
auto & b = state.batches.emplace_back();
|
||||
b.texture = texture;
|
||||
b.color = color;
|
||||
}
|
||||
return state.batches.back();
|
||||
};
|
||||
|
||||
auto flush_underline = [&]{
|
||||
auto & image = batch(current_underline->second).images.emplace_back();
|
||||
image.position[0] = current_underline->first;
|
||||
image.position[1] = {underline_y, underline_y + line_width};
|
||||
current_underline = std::nullopt;
|
||||
};
|
||||
|
||||
auto flush_strikethrough = [&]{
|
||||
auto & image = batch(current_strikethrough->second).images.emplace_back();
|
||||
image.position[0] = current_strikethrough->first;
|
||||
image.position[1] = {strikethrough_y, strikethrough_y + line_width};
|
||||
current_strikethrough = std::nullopt;
|
||||
};
|
||||
std::optional<float> last_underline_end;
|
||||
std::optional<float> last_strikethrough_end;
|
||||
|
||||
for (; ch < glyph_chunks.size(); ++ch)
|
||||
{
|
||||
|
|
@ -500,43 +486,29 @@ namespace psemek::ui
|
|||
for (std::size_t i = ibegin; i < iend; ++i)
|
||||
x_range |= glyphs[i].position[0];
|
||||
|
||||
if (underline && current_underline)
|
||||
if (underline)
|
||||
{
|
||||
if (current_underline->second != chunk.color)
|
||||
{
|
||||
flush_underline();
|
||||
current_underline = {x_range, chunk.color};
|
||||
}
|
||||
else
|
||||
current_underline->first |= x_range;
|
||||
}
|
||||
else if (underline && !current_underline)
|
||||
{
|
||||
current_underline = {x_range, chunk.color};
|
||||
}
|
||||
else if (!underline && current_underline)
|
||||
{
|
||||
flush_underline();
|
||||
auto & image = get_batch(chunk.color).images.emplace_back();
|
||||
image.position[0] = x_range;
|
||||
if (last_underline_end)
|
||||
image.position[0] |= *last_underline_end;
|
||||
image.position[1] = {underline_y, underline_y + line_width};
|
||||
last_underline_end = image.position[0].max;
|
||||
}
|
||||
else
|
||||
last_underline_end = std::nullopt;
|
||||
|
||||
if (strikethrough && current_strikethrough)
|
||||
if (strikethrough)
|
||||
{
|
||||
if (current_strikethrough->second != chunk.color)
|
||||
{
|
||||
flush_strikethrough();
|
||||
current_strikethrough = {x_range, chunk.color};
|
||||
}
|
||||
else
|
||||
current_strikethrough->first |= x_range;
|
||||
}
|
||||
else if (strikethrough && !current_strikethrough)
|
||||
{
|
||||
current_strikethrough = {x_range, chunk.color};
|
||||
}
|
||||
else if (!strikethrough && current_strikethrough)
|
||||
{
|
||||
flush_strikethrough();
|
||||
auto & image = get_batch(chunk.color).images.emplace_back();
|
||||
image.position[0] = x_range;
|
||||
if (last_strikethrough_end)
|
||||
image.position[0] |= *last_strikethrough_end;
|
||||
image.position[1] = {strikethrough_y, strikethrough_y + line_width};
|
||||
last_strikethrough_end = image.position[0].max;
|
||||
}
|
||||
else
|
||||
last_strikethrough_end = std::nullopt;
|
||||
}
|
||||
|
||||
if (chunk.end > lines[l].end)
|
||||
|
|
@ -544,12 +516,6 @@ namespace psemek::ui
|
|||
|
||||
ch_begin = chunk.end;
|
||||
}
|
||||
|
||||
if (current_underline)
|
||||
flush_underline();
|
||||
|
||||
if (current_strikethrough)
|
||||
flush_strikethrough();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue