diff --git a/libs/ui/source/label.cpp b/libs/ui/source/label.cpp index 1f48d077..6572bd32 100644 --- a/libs/ui/source/label.cpp +++ b/libs/ui/source/label.cpp @@ -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, gfx::color_rgba>> current_underline; - std::optional, 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 last_underline_end; + std::optional 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(); } }