mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Improve text wrapping when multiple characters are combined into one glyph.
#1923
This commit is contained in:
@@ -151,8 +151,7 @@ int GenericShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ran
|
||||
float w = 0.0f;
|
||||
float outwidth = 0.0f;
|
||||
float widthbeforelastspace = 0.0f;
|
||||
int wrapindex = -1;
|
||||
int lastspaceindex = -1;
|
||||
int firstindexafterspace = -1;
|
||||
|
||||
for (int i = (int)range.getMin(); i <= (int)range.getMax(); i++)
|
||||
{
|
||||
@@ -166,37 +165,48 @@ int GenericShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ran
|
||||
|
||||
float newwidth = w + getKerning(prevglyph, g) + getGlyphAdvance(g);
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit && !isWhitespace(g))
|
||||
{
|
||||
// Rewind to the last seen space when wrapping.
|
||||
if (lastspaceindex != -1)
|
||||
{
|
||||
wrapindex = lastspaceindex;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't count trailing spaces in the output width.
|
||||
if (isWhitespace(g))
|
||||
{
|
||||
lastspaceindex = i;
|
||||
if (!isWhitespace(prevglyph))
|
||||
widthbeforelastspace = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isWhitespace(prevglyph))
|
||||
firstindexafterspace = i;
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit)
|
||||
{
|
||||
// If this is the first character, wrap from the next one instead of this one.
|
||||
int wrapindex = i > (int)range.first ? i : (int)range.first + 1;
|
||||
|
||||
// Rewind to after the last seen space when wrapping.
|
||||
if (firstindexafterspace != -1)
|
||||
{
|
||||
wrapindex = firstindexafterspace;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
}
|
||||
|
||||
outwidth = newwidth;
|
||||
}
|
||||
|
||||
w = newwidth;
|
||||
prevglyph = g;
|
||||
wrapindex = i;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
// There wasn't any wrap in the middle of the range.
|
||||
return range.last + 1;
|
||||
}
|
||||
|
||||
} // font
|
||||
|
||||
@@ -303,10 +303,10 @@ void TextShaper::getWrap(const ColoredCodepoints &codepoints, float wraplimit, s
|
||||
float width = 0.0f;
|
||||
int wrapindex = computeWordWrapIndex(codepoints, r, wraplimit, &width);
|
||||
|
||||
if (wrapindex >= (int) i)
|
||||
if (wrapindex > (int) i)
|
||||
{
|
||||
r = Range(i, (size_t) wrapindex + 1 - i);
|
||||
i = (size_t)wrapindex + 1;
|
||||
r = Range(i, (size_t) wrapindex - i);
|
||||
i = (size_t)wrapindex;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -335,8 +335,7 @@ int HarfbuzzShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ra
|
||||
float w = 0.0f;
|
||||
float outwidth = 0.0f;
|
||||
float widthbeforelastspace = 0.0f;
|
||||
int wrapindex = -1;
|
||||
int lastspaceindex = -1;
|
||||
int firstindexafterspace = -1;
|
||||
|
||||
uint32 prevcodepoint = 0;
|
||||
|
||||
@@ -376,38 +375,49 @@ int HarfbuzzShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ra
|
||||
|
||||
float newwidth = w + floorf((glyphpos.x_advance >> 6) / dpiScales[0] + 0.5f);
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit && !isWhitespace(clustercodepoint))
|
||||
{
|
||||
// Rewind to the last seen space when wrapping.
|
||||
if (lastspaceindex != -1)
|
||||
{
|
||||
wrapindex = lastspaceindex;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't count trailing spaces in the output width.
|
||||
if (isWhitespace(clustercodepoint))
|
||||
{
|
||||
lastspaceindex = info.cluster;
|
||||
if (!isWhitespace(prevcodepoint))
|
||||
widthbeforelastspace = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isWhitespace(prevcodepoint))
|
||||
firstindexafterspace = info.cluster;
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit)
|
||||
{
|
||||
// If this is the first character, wrap from the next one instead of this one.
|
||||
int wrapindex = info.cluster > (int) range.first ? info.cluster : (int) range.first + 1;
|
||||
|
||||
// Rewind to after the last seen space when wrapping.
|
||||
if (firstindexafterspace != -1)
|
||||
{
|
||||
wrapindex = firstindexafterspace;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
}
|
||||
|
||||
outwidth = newwidth;
|
||||
}
|
||||
|
||||
w = newwidth;
|
||||
prevcodepoint = clustercodepoint;
|
||||
wrapindex = info.cluster;
|
||||
}
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
// There wasn't any wrap in the middle of the range.
|
||||
return (int) range.last + 1;
|
||||
}
|
||||
|
||||
} // freetype
|
||||
|
||||
Reference in New Issue
Block a user