Add (bad) support for multiline text in gfx::painter:

This commit is contained in:
Nikita Lisitsa 2025-02-03 00:43:39 +03:00
parent cd31187d3f
commit 3655fc9c6f

View file

@ -301,18 +301,37 @@ namespace psemek::gfx
math::vector<float, 2> painter::text_size(std::string_view str, font f) math::vector<float, 2> painter::text_size(std::string_view str, font f)
{ {
// TODO: multiline text // TODO: multiline text
math::vector<float, 2> s; math::vector<float, 2> font_size;
switch (f) switch (f)
{ {
case font::font_9x12: case font::font_9x12:
s = {9.f, 12.f}; font_size = {9.f, 12.f};
break; break;
default: default:
throw util::unknown_enum_value_exception(f); throw util::unknown_enum_value_exception(f);
} }
s[0] *= str.size(); int max_line_width = 0;
return s; int line_count = 0;
int last_line_start = 0;
for (int i = 0; i < str.size(); ++i)
{
if (str[i] == '\n')
{
math::make_max(max_line_width, i - last_line_start);
last_line_start = i;
++line_count;
}
}
if (last_line_start + 1 != str.size())
{
math::make_max(max_line_width, static_cast<int>(str.size()) - last_line_start);
++line_count;
}
return {font_size[0] * max_line_width, font_size[1] * line_count};
} }
void painter::text(math::point<float, 2> const & p, std::string_view str, text_options const & opts) void painter::text(math::point<float, 2> const & p, std::string_view str, text_options const & opts)
@ -489,17 +508,17 @@ namespace psemek::gfx
{ {
auto const size = math::pointwise_mult(text_size(str, opts.f), opts.scale); auto const size = math::pointwise_mult(text_size(str, opts.f), opts.scale);
math::vector<float, 3> pen { 0.f, 0.f, 0.f }; math::vector<float, 3> origin { 0.f, 0.f, 0.f };
switch (opts.x) switch (opts.x)
{ {
case x_align::left: case x_align::left:
break; break;
case x_align::center: case x_align::center:
pen[0] -= size[0] / 2.f; origin[0] -= size[0] / 2.f;
break; break;
case x_align::right: case x_align::right:
pen[0] -= size[0]; origin[0] -= size[0];
break; break;
default: default:
throw util::unknown_enum_value_exception(opts.x); throw util::unknown_enum_value_exception(opts.x);
@ -510,15 +529,17 @@ namespace psemek::gfx
case y_align::top: case y_align::top:
break; break;
case y_align::center: case y_align::center:
pen[1] -= size[1] / 2.f; origin[1] -= size[1] / 2.f;
break; break;
case y_align::bottom: case y_align::bottom:
pen[1] -= size[1]; origin[1] -= size[1];
break; break;
default: default:
throw util::unknown_enum_value_exception(opts.y); throw util::unknown_enum_value_exception(opts.y);
} }
auto pen = origin;
math::vector<float, 3> const sx = {9.f * opts.scale[0], 0.f, 0.f}; math::vector<float, 3> const sx = {9.f * opts.scale[0], 0.f, 0.f};
math::vector<float, 3> const sy = {0.f, 12.f * opts.scale[1], 0.f}; math::vector<float, 3> const sy = {0.f, 12.f * opts.scale[1], 0.f};
@ -529,6 +550,13 @@ namespace psemek::gfx
for (char c : str) for (char c : str)
{ {
if (c == '\n')
{
pen[0] = origin[0];
pen += sy;
continue;
}
// Guard against unsigned char // Guard against unsigned char
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push