Fixed text alignment to be visible based rather than surface based
This commit is contained in:
parent
8e88adf1df
commit
9f8a037f69
@ -15,6 +15,72 @@ static SDL_Surface* render_text(bool should_wrap, TTF_Font* font, const string&
|
||||
return txt_surface;
|
||||
}
|
||||
|
||||
static SDL_Rect find_visible_area(const SDL_Surface* txt_surface)
|
||||
{
|
||||
int x_start = -1;
|
||||
int x_end = -1;
|
||||
int y_start = -1;
|
||||
int y_end = -1;
|
||||
|
||||
for (int y = 0; y < txt_surface->h; ++y)
|
||||
{
|
||||
bool found = false;
|
||||
for (int x = 0; x < txt_surface->w; ++x)
|
||||
{
|
||||
if (1 == (static_cast<Uint8*>(txt_surface->pixels)[y * txt_surface->pitch + x]))
|
||||
{
|
||||
if (-1 == x_start)
|
||||
{
|
||||
x_start = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < x_start)
|
||||
{
|
||||
x_start = x;
|
||||
}
|
||||
}
|
||||
|
||||
if (-1 == x_end)
|
||||
{
|
||||
x_end = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > x_end)
|
||||
{
|
||||
x_end = x;
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (-1 == y_start)
|
||||
{
|
||||
y_start = y;
|
||||
}
|
||||
y_end = y;
|
||||
}
|
||||
}
|
||||
SDL_Rect result = {.x = 0, .y = 0, .w = 0, .h = 0};
|
||||
if ((-1 != x_start) && (-1 != x_end))
|
||||
{
|
||||
result.x = x_start;
|
||||
result.w = x_end - x_start + 1;
|
||||
}
|
||||
|
||||
if ((-1 != y_start) && (-1 != y_end))
|
||||
{
|
||||
result.y = y_start;
|
||||
result.h = y_end - y_start + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WidgetText::WidgetText(int x, int y, int width, int height, string text,
|
||||
TextFit fit, bool should_wrap,
|
||||
HorizontalAlign halign, VerticalAlign valign,
|
||||
@ -171,7 +237,8 @@ void WidgetText::draw()
|
||||
}
|
||||
|
||||
// Now we have the final rendered text surface
|
||||
SDL_Rect align = surface_align(m_surface, txt_surface, m_halign, m_valign);
|
||||
SDL_Rect hint = find_visible_area(txt_surface);
|
||||
SDL_Rect align = surface_align(m_surface, txt_surface, m_halign, m_valign, &hint);
|
||||
SDL_BlitSurface(txt_surface, NULL, m_surface, &align);
|
||||
SDL_FreeSurface(txt_surface);
|
||||
}
|
||||
|
||||
@ -77,42 +77,52 @@ TTF_Font* get_font(int size, const string& filename)
|
||||
}
|
||||
|
||||
SDL_Rect surface_align(const SDL_Surface* base, const SDL_Surface* applied,
|
||||
HorizontalAlign halign, VerticalAlign valign)
|
||||
HorizontalAlign halign, VerticalAlign valign, const SDL_Rect* hint_external)
|
||||
{
|
||||
SDL_Rect align = {.x = 0, .y = 0, .w = 0, .h = 0};
|
||||
SDL_Rect hint;
|
||||
|
||||
if ((nullptr == base) || (nullptr == applied))
|
||||
{
|
||||
return align;
|
||||
}
|
||||
|
||||
if (nullptr == hint_external)
|
||||
{
|
||||
hint = SDL_Rect{.x = 0, .y = 0, .w = applied->w, .h = applied->h};
|
||||
}
|
||||
else
|
||||
{
|
||||
hint = *hint_external;
|
||||
}
|
||||
|
||||
switch (halign)
|
||||
{
|
||||
case HALIGN_LEFT:
|
||||
align.x = 0;
|
||||
align.x = -hint.x;
|
||||
break;
|
||||
|
||||
case HALIGN_CENTER:
|
||||
align.x = base->w / 2 - applied->w / 2;
|
||||
align.x = base->w / 2 - hint.x - hint.w / 2;
|
||||
break;
|
||||
|
||||
case HALIGN_RIGHT:
|
||||
align.x = base->w - applied->w;
|
||||
align.x = base->w - (hint.x + hint.w);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (valign)
|
||||
{
|
||||
case VALIGN_TOP:
|
||||
align.y = 0;
|
||||
align.y = -hint.y;
|
||||
break;
|
||||
|
||||
case VALIGN_CENTER:
|
||||
align.y = base->h / 2 - applied->h / 2;
|
||||
align.y = base->h / 2 - hint.y - hint.h / 2;
|
||||
break;
|
||||
|
||||
case VALIGN_BOTTOM:
|
||||
align.y = base->h - applied->h;
|
||||
align.y = base->h - (hint.y + hint.h);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -66,8 +66,9 @@ TTF_Font* get_font(int size, const std::string& filename = default_font_name);
|
||||
// Returns a rect to use during bliting of 2 surfaces
|
||||
// base - surface on which the other is applied to
|
||||
// applied - the surface which will be applied to the other
|
||||
// hint - rect to hint visible area from applied - can be NULL
|
||||
SDL_Rect surface_align(const SDL_Surface* base, const SDL_Surface* applied,
|
||||
HorizontalAlign halign, VerticalAlign valign);
|
||||
HorizontalAlign halign, VerticalAlign valign, const SDL_Rect* hint = nullptr);
|
||||
|
||||
// Reads the file and tries to parse a JSON file with comments
|
||||
// cfg - output json struct
|
||||
|
||||
Loading…
Reference in New Issue
Block a user