Fix invalid URL in line breaking
This commit is contained in:
parent
0c20dda1da
commit
e85b82001f
@ -34,7 +34,8 @@ GLF_BREAKABLE = 4, /* This glyph is breakable when line breaking. */
|
|||||||
GLF_QUICK_DRAW = 8, /* This glyph is not created by libraqm, which get x_advance_x directly from font. */
|
GLF_QUICK_DRAW = 8, /* This glyph is not created by libraqm, which get x_advance_x directly from font. */
|
||||||
GLF_NEWLINE = 16, /* This glyph will start a newline. */
|
GLF_NEWLINE = 16, /* This glyph will start a newline. */
|
||||||
GLF_COLORED = 32, /* This glyph is a colored one (for example emoji). */
|
GLF_COLORED = 32, /* This glyph is a colored one (for example emoji). */
|
||||||
GLF_URL = 64 /* This glyph contains clickable url (https or http atm). */
|
GLF_URL = 64, /* This glyph contains clickable url (https or http atm). */
|
||||||
|
GLF_BREAKTEXT_NEWLINE = 128 /* Newline added via breakGlyphLayouts. */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GlyphLayoutDraw
|
enum GlyphLayoutDraw
|
||||||
@ -238,6 +239,17 @@ inline void breakGlyphLayouts(std::vector<GlyphLayout>& gls, f32 max_line_width,
|
|||||||
{
|
{
|
||||||
if (gls.size() < 2)
|
if (gls.size() < 2)
|
||||||
return;
|
return;
|
||||||
|
auto it = gls.begin();
|
||||||
|
while (it != gls.end())
|
||||||
|
{
|
||||||
|
if ((it->flags & GLF_BREAKTEXT_NEWLINE) != 0)
|
||||||
|
{
|
||||||
|
it = gls.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::vector<GlyphLayout> > broken_line;
|
std::vector<std::vector<GlyphLayout> > broken_line;
|
||||||
u32 start = 0;
|
u32 start = 0;
|
||||||
for (u32 i = 0; i < gls.size(); i++)
|
for (u32 i = 0; i < gls.size(); i++)
|
||||||
@ -245,12 +257,13 @@ inline void breakGlyphLayouts(std::vector<GlyphLayout>& gls, f32 max_line_width,
|
|||||||
GlyphLayout& glyph = gls[i];
|
GlyphLayout& glyph = gls[i];
|
||||||
if ((glyph.flags & GLF_NEWLINE) != 0)
|
if ((glyph.flags & GLF_NEWLINE) != 0)
|
||||||
{
|
{
|
||||||
Private::breakLine({ gls.begin() + start, gls.begin() + i},
|
Private::breakLine({ gls.begin() + start, gls.begin() + i },
|
||||||
max_line_width, inverse_shaping, scale, broken_line);
|
max_line_width, inverse_shaping, scale, broken_line);
|
||||||
start = i + 1;
|
start = i + 1;
|
||||||
|
broken_line.push_back(std::vector<GlyphLayout>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (start - gls.size() - 1 > 0)
|
if (gls.size() > start)
|
||||||
{
|
{
|
||||||
Private::breakLine({ gls.begin() + start, gls.begin() + gls.size() },
|
Private::breakLine({ gls.begin() + start, gls.begin() + gls.size() },
|
||||||
max_line_width, inverse_shaping, scale, broken_line);
|
max_line_width, inverse_shaping, scale, broken_line);
|
||||||
@ -260,12 +273,6 @@ inline void breakGlyphLayouts(std::vector<GlyphLayout>& gls, f32 max_line_width,
|
|||||||
// Sort glyphs in original order
|
// Sort glyphs in original order
|
||||||
for (u32 i = 0; i < broken_line.size(); i++)
|
for (u32 i = 0; i < broken_line.size(); i++)
|
||||||
{
|
{
|
||||||
if (i != 0)
|
|
||||||
{
|
|
||||||
gui::GlyphLayout gl = { 0 };
|
|
||||||
gl.flags = gui::GLF_NEWLINE;
|
|
||||||
gls.push_back(gl);
|
|
||||||
}
|
|
||||||
auto& line = broken_line[i];
|
auto& line = broken_line[i];
|
||||||
std::sort(line.begin(), line.end(), []
|
std::sort(line.begin(), line.end(), []
|
||||||
(const irr::gui::GlyphLayout& a_gi,
|
(const irr::gui::GlyphLayout& a_gi,
|
||||||
@ -275,6 +282,17 @@ inline void breakGlyphLayouts(std::vector<GlyphLayout>& gls, f32 max_line_width,
|
|||||||
});
|
});
|
||||||
for (auto& glyph : line)
|
for (auto& glyph : line)
|
||||||
gls.push_back(glyph);
|
gls.push_back(glyph);
|
||||||
|
if (i != broken_line.size() - 1)
|
||||||
|
{
|
||||||
|
gui::GlyphLayout gl = { 0 };
|
||||||
|
gl.flags = gui::GLF_NEWLINE | gui::GLF_BREAKTEXT_NEWLINE;
|
||||||
|
if (broken_line.at(i + 1).empty())
|
||||||
|
{
|
||||||
|
gl.flags &= ~gui::GLF_BREAKTEXT_NEWLINE;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
gls.push_back(gl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,6 +557,7 @@ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
|
|||||||
* \param font_settings \ref FontSettings to use.
|
* \param font_settings \ref FontSettings to use.
|
||||||
* \param char_collector \ref FontCharCollector to render billboard text.
|
* \param char_collector \ref FontCharCollector to render billboard text.
|
||||||
*/
|
*/
|
||||||
|
#undef DEBUG_NEWLINE
|
||||||
void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
||||||
const core::rect<s32>& position,
|
const core::rect<s32>& position,
|
||||||
const video::SColor& color, bool hcenter,
|
const video::SColor& color, bool hcenter,
|
||||||
@ -619,6 +620,21 @@ void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
|||||||
const gui::GlyphLayout& glyph_layout = gl[i];
|
const gui::GlyphLayout& glyph_layout = gl[i];
|
||||||
if ((glyph_layout.flags & gui::GLF_NEWLINE) != 0)
|
if ((glyph_layout.flags & gui::GLF_NEWLINE) != 0)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_NEWLINE
|
||||||
|
if ((glyph_layout.flags & gui::GLF_BREAKTEXT_NEWLINE) != 0)
|
||||||
|
{
|
||||||
|
GL32_draw2DRectangle(video::SColor(255, 255, 50, 50),
|
||||||
|
core::recti(offset.X, offset.Y, offset.X + 3,
|
||||||
|
offset.Y + next_line_height));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL32_draw2DRectangle(video::SColor(255, 50, 50, 255),
|
||||||
|
core::recti(offset.X, offset.Y, offset.X + 3,
|
||||||
|
offset.Y + next_line_height));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
offset.X = float(position.UpperLeftCorner.X);
|
||||||
offset.Y += (s32)next_line_height;
|
offset.Y += (s32)next_line_height;
|
||||||
cur_line++;
|
cur_line++;
|
||||||
line_changed = true;
|
line_changed = true;
|
||||||
@ -628,7 +644,6 @@ void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
|||||||
{
|
{
|
||||||
line_changed = false;
|
line_changed = false;
|
||||||
rtl = (glyph_layout.flags & gui::GLF_RTL_LINE) != 0;
|
rtl = (glyph_layout.flags & gui::GLF_RTL_LINE) != 0;
|
||||||
offset.X = float(position.UpperLeftCorner.X);
|
|
||||||
if (hcenter)
|
if (hcenter)
|
||||||
{
|
{
|
||||||
offset.X += (s32)(
|
offset.X += (s32)(
|
||||||
|
@ -62,7 +62,13 @@ namespace Online
|
|||||||
int start = glyph_idx;
|
int start = glyph_idx;
|
||||||
while (start != 0)
|
while (start != 0)
|
||||||
{
|
{
|
||||||
if ((gls[start - 1].flags & gui::GLF_URL) == 0)
|
const gui::GlyphLayout& cur_gl = gls[start - 1];
|
||||||
|
if ((cur_gl.flags & gui::GLF_BREAKTEXT_NEWLINE) != 0)
|
||||||
|
{
|
||||||
|
start--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((cur_gl.flags & gui::GLF_URL) == 0)
|
||||||
break;
|
break;
|
||||||
start--;
|
start--;
|
||||||
}
|
}
|
||||||
@ -70,7 +76,13 @@ namespace Online
|
|||||||
while (gls.size() - end > 1)
|
while (gls.size() - end > 1)
|
||||||
{
|
{
|
||||||
size_t next_end = end + 1;
|
size_t next_end = end + 1;
|
||||||
if ((gls[next_end].flags & gui::GLF_URL) == 0)
|
const gui::GlyphLayout& cur_gl = gls[next_end];
|
||||||
|
if ((cur_gl.flags & gui::GLF_BREAKTEXT_NEWLINE) != 0)
|
||||||
|
{
|
||||||
|
end = next_end;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((cur_gl.flags & gui::GLF_URL) == 0)
|
||||||
break;
|
break;
|
||||||
end = next_end;
|
end = next_end;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user