mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
overlays: find missing characters lost during wrapped rendering
This commit is contained in:
parent
fdc15e12c4
commit
d2be12bb07
1 changed files with 90 additions and 111 deletions
|
@ -294,128 +294,107 @@ namespace rsx
|
|||
return;
|
||||
}
|
||||
|
||||
usz i = 0u;
|
||||
bool skip_whitespace = false;
|
||||
|
||||
while (true)
|
||||
// Render as many characters as possible as glyphs.
|
||||
for (usz i = 0u, begin_of_word = 0u; i < char_limit; i++)
|
||||
{
|
||||
if (auto c = text[i++]; c && (i <= char_limit))
|
||||
switch (const auto& c = text[i])
|
||||
{
|
||||
switch (c)
|
||||
case '\0':
|
||||
{
|
||||
// We're done.
|
||||
return;
|
||||
}
|
||||
case '\n':
|
||||
{
|
||||
// Reset x to 0 and increase y to advance to the new line.
|
||||
x_advance = 0.f;
|
||||
y_advance += size_px + 2.f;
|
||||
begin_of_word = result.size();
|
||||
continue;
|
||||
}
|
||||
case '\r':
|
||||
{
|
||||
// Reset x to 0.
|
||||
x_advance = 0.f;
|
||||
begin_of_word = result.size();
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
{
|
||||
const bool is_whitespace = c == ' ';
|
||||
stbtt_aligned_quad quad{};
|
||||
|
||||
if (is_whitespace)
|
||||
{
|
||||
case '\n':
|
||||
{
|
||||
y_advance += size_px + 2.f;
|
||||
x_advance = 0.f;
|
||||
continue;
|
||||
}
|
||||
case '\r':
|
||||
{
|
||||
x_advance = 0.f;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
{
|
||||
stbtt_aligned_quad quad;
|
||||
if (skip_whitespace && text[i - 1] == ' ')
|
||||
// Skip whitespace if we are at the start of a line.
|
||||
if (x_advance > 0.f)
|
||||
{
|
||||
quad = {};
|
||||
// Get the glyph size.
|
||||
quad = get_char(c, x_advance, y_advance);
|
||||
|
||||
// Reset the result if the glyph would protrude out of the given space anyway.
|
||||
if (x_advance > max_width)
|
||||
{
|
||||
quad = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No whitespace. Get the glyph size.
|
||||
quad = get_char(c, x_advance, y_advance);
|
||||
}
|
||||
|
||||
// Add the glyph's vertices.
|
||||
result.emplace_back(quad.x0, quad.y0, quad.s0, quad.t0);
|
||||
result.emplace_back(quad.x1, quad.y0, quad.s1, quad.t0);
|
||||
result.emplace_back(quad.x0, quad.y1, quad.s0, quad.t1);
|
||||
result.emplace_back(quad.x1, quad.y1, quad.s1, quad.t1);
|
||||
|
||||
// The next word will begin after any whitespaces.
|
||||
if (is_whitespace)
|
||||
{
|
||||
begin_of_word = result.size();
|
||||
}
|
||||
|
||||
// Check if we reached the end of the available space.
|
||||
if (x_advance > max_width)
|
||||
{
|
||||
// Try to wrap the protruding text
|
||||
if (wrap)
|
||||
{
|
||||
// Increase y to advance to the next line.
|
||||
y_advance += size_px + 2.f;
|
||||
|
||||
// We can just reset x and move on to the next character if this is a whitespace.
|
||||
if (is_whitespace)
|
||||
{
|
||||
x_advance = 0.f;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the leftmost offset of the current word.
|
||||
const f32 base_x = result[begin_of_word].x();
|
||||
|
||||
// Move all characters of the current word one line down and to the left.
|
||||
for (usz n = begin_of_word; n < result.size(); ++n)
|
||||
{
|
||||
result[n].x() -= base_x;
|
||||
result[n].y() += size_px + 2.f;
|
||||
}
|
||||
|
||||
// Set x offset to the rightmost position of the current word
|
||||
x_advance = result.back().x();
|
||||
}
|
||||
else
|
||||
{
|
||||
quad = get_char(c, x_advance, y_advance);
|
||||
skip_whitespace = false;
|
||||
// TODO: Ellipsize
|
||||
}
|
||||
|
||||
if (x_advance > max_width)
|
||||
{
|
||||
bool wrapped = false;
|
||||
bool non_whitespace_break = false;
|
||||
|
||||
if (wrap)
|
||||
{
|
||||
// scan previous chars
|
||||
for (usz j = i - 1, nb_chars = 0; j > 0; j--, nb_chars++)
|
||||
{
|
||||
if (text[j] == '\n')
|
||||
break;
|
||||
|
||||
if (text[j] == ' ')
|
||||
{
|
||||
non_whitespace_break = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (non_whitespace_break)
|
||||
{
|
||||
if (nb_chars > 1)
|
||||
{
|
||||
nb_chars--;
|
||||
|
||||
auto first_affected = result.size() - (nb_chars * 4);
|
||||
f32 base_x = result[first_affected].values[0];
|
||||
|
||||
for (usz n = first_affected; n < result.size(); ++n)
|
||||
{
|
||||
auto char_index = n / 4;
|
||||
if (text[char_index] == ' ')
|
||||
{
|
||||
// Skip character
|
||||
result[n++].vec2(0.f, 0.f);
|
||||
result[n++].vec2(0.f, 0.f);
|
||||
result[n++].vec2(0.f, 0.f);
|
||||
result[n].vec2(0.f, 0.f);
|
||||
continue;
|
||||
}
|
||||
|
||||
result[n].values[0] -= base_x;
|
||||
result[n].values[1] += size_px + 2.f;
|
||||
}
|
||||
|
||||
x_advance = result.back().values[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
x_advance = 0.f;
|
||||
}
|
||||
|
||||
wrapped = true;
|
||||
y_advance += size_px + 2.f;
|
||||
|
||||
if (text[i - 1] == ' ')
|
||||
{
|
||||
quad = {};
|
||||
skip_whitespace = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
quad = get_char(c, x_advance, y_advance);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!wrapped)
|
||||
{
|
||||
// TODO: Ellipsize
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.emplace_back(quad.x0, quad.y0, quad.s0, quad.t0);
|
||||
result.emplace_back(quad.x1, quad.y0, quad.s1, quad.t0);
|
||||
result.emplace_back(quad.x0, quad.y1, quad.s0, quad.t1);
|
||||
result.emplace_back(quad.x1, quad.y1, quad.s1, quad.t1);
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue