mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
TextLayout: Fixed some bugs setting stringRanges
This commit is contained in:
parent
76f3aec386
commit
edf99d171f
4 changed files with 170 additions and 31 deletions
|
|
@ -27,6 +27,11 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
static String substring (const String& text, Range<int> range)
|
||||
{
|
||||
return text.substring (range.getStart(), range.getEnd());
|
||||
}
|
||||
|
||||
TextLayout::Glyph::Glyph (int glyph, Point<float> anch, float w) noexcept
|
||||
: glyphCode (glyph), anchor (anch), width (w)
|
||||
{
|
||||
|
|
@ -207,9 +212,9 @@ void TextLayout::ensureStorageAllocated (int numLinesNeeded)
|
|||
lines.ensureStorageAllocated (numLinesNeeded);
|
||||
}
|
||||
|
||||
void TextLayout::addLine (Line* line)
|
||||
void TextLayout::addLine (std::unique_ptr<Line> line)
|
||||
{
|
||||
lines.add (line);
|
||||
lines.add (line.release());
|
||||
}
|
||||
|
||||
void TextLayout::draw (Graphics& g, Rectangle<float> area) const
|
||||
|
|
@ -221,9 +226,9 @@ void TextLayout::draw (Graphics& g, Rectangle<float> area) const
|
|||
auto clipTop = clip.getY() - origin.y;
|
||||
auto clipBottom = clip.getBottom() - origin.y;
|
||||
|
||||
for (auto* line : lines)
|
||||
for (auto& line : *this)
|
||||
{
|
||||
auto lineRangeY = line->getLineBoundsY();
|
||||
auto lineRangeY = line.getLineBoundsY();
|
||||
|
||||
if (lineRangeY.getEnd() < clipTop)
|
||||
continue;
|
||||
|
|
@ -231,9 +236,9 @@ void TextLayout::draw (Graphics& g, Rectangle<float> area) const
|
|||
if (lineRangeY.getStart() > clipBottom)
|
||||
break;
|
||||
|
||||
auto lineOrigin = origin + line->lineOrigin;
|
||||
auto lineOrigin = origin + line.lineOrigin;
|
||||
|
||||
for (auto* run : line->runs)
|
||||
for (auto* run : line.runs)
|
||||
{
|
||||
context.setFont (run->font);
|
||||
context.setFill (run->colour);
|
||||
|
|
@ -363,8 +368,8 @@ namespace TextLayoutHelpers
|
|||
Array<float> xOffsets;
|
||||
t.font.getGlyphPositions (getTrimmedEndIfNotAllWhitespace (t.text), newGlyphs, xOffsets);
|
||||
|
||||
if (currentRun == nullptr) currentRun .reset (new TextLayout::Run());
|
||||
if (currentLine == nullptr) currentLine.reset (new TextLayout::Line());
|
||||
if (currentRun == nullptr) currentRun = std::make_unique<TextLayout::Run>();
|
||||
if (currentLine == nullptr) currentLine = std::make_unique<TextLayout::Line>();
|
||||
|
||||
if (newGlyphs.size() > 0)
|
||||
{
|
||||
|
|
@ -389,9 +394,10 @@ namespace TextLayoutHelpers
|
|||
|
||||
charPosition += newGlyphs.size();
|
||||
}
|
||||
|
||||
if (t.isWhitespace || t.isNewLine)
|
||||
else if (t.isWhitespace || t.isNewLine)
|
||||
{
|
||||
++charPosition;
|
||||
}
|
||||
|
||||
if (auto* nextToken = tokens[i + 1])
|
||||
{
|
||||
|
|
@ -404,13 +410,13 @@ namespace TextLayoutHelpers
|
|||
if (t.line != nextToken->line)
|
||||
{
|
||||
if (currentRun == nullptr)
|
||||
currentRun.reset (new TextLayout::Run());
|
||||
currentRun = std::make_unique<TextLayout::Run>();
|
||||
|
||||
addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition);
|
||||
currentLine->stringRange = { lineStartPosition, charPosition };
|
||||
|
||||
if (! needToSetLineOrigin)
|
||||
layout.addLine (currentLine.release());
|
||||
layout.addLine (std::move (currentLine));
|
||||
|
||||
runStartPosition = charPosition;
|
||||
lineStartPosition = charPosition;
|
||||
|
|
@ -423,7 +429,7 @@ namespace TextLayoutHelpers
|
|||
currentLine->stringRange = { lineStartPosition, charPosition };
|
||||
|
||||
if (! needToSetLineOrigin)
|
||||
layout.addLine (currentLine.release());
|
||||
layout.addLine (std::move (currentLine));
|
||||
|
||||
needToSetLineOrigin = true;
|
||||
}
|
||||
|
|
@ -434,14 +440,14 @@ namespace TextLayoutHelpers
|
|||
auto totalW = layout.getWidth();
|
||||
bool isCentred = (text.getJustification().getFlags() & Justification::horizontallyCentred) != 0;
|
||||
|
||||
for (int i = 0; i < layout.getNumLines(); ++i)
|
||||
for (auto& line : layout)
|
||||
{
|
||||
auto dx = totalW - layout.getLine(i).getLineBoundsX().getLength();
|
||||
auto dx = totalW - line.getLineBoundsX().getLength();
|
||||
|
||||
if (isCentred)
|
||||
dx /= 2.0f;
|
||||
|
||||
layout.getLine(i).lineOrigin.x += dx;
|
||||
line.lineOrigin.x += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -560,7 +566,7 @@ namespace TextLayoutHelpers
|
|||
{
|
||||
auto& attr = text.getAttribute (i);
|
||||
|
||||
appendText (text.getText().substring (attr.range.getStart(), attr.range.getEnd()),
|
||||
appendText (substring (text.getText(), attr.range),
|
||||
attr.font, attr.colour);
|
||||
}
|
||||
}
|
||||
|
|
@ -611,4 +617,66 @@ void TextLayout::recalculateSize()
|
|||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
struct TextLayoutTests : public UnitTest
|
||||
{
|
||||
TextLayoutTests()
|
||||
: UnitTest ("Text Layout", UnitTestCategories::text)
|
||||
{}
|
||||
|
||||
static TextLayout createLayout (StringRef text, float width)
|
||||
{
|
||||
Font fontToUse (12.0f);
|
||||
|
||||
AttributedString string (text);
|
||||
string.setFont (std::move (fontToUse));
|
||||
|
||||
TextLayout layout;
|
||||
layout.createLayout (std::move (string), width);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void testLineBreaks (const String& line, float width, const StringArray& expected)
|
||||
{
|
||||
const auto layout = createLayout (line, width);
|
||||
|
||||
beginTest ("A line is split into expected pieces");
|
||||
{
|
||||
expectEquals (layout.getNumLines(), expected.size());
|
||||
|
||||
const auto limit = jmin (layout.getNumLines(), expected.size());
|
||||
|
||||
for (int i = 0; i != limit; ++i)
|
||||
expectEquals (substring (line, layout.getLine (i).stringRange), expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
const String shortLine ("hello world");
|
||||
testLineBreaks (shortLine, 1.0e7f, { shortLine });
|
||||
|
||||
testLineBreaks ("this line should be split",
|
||||
60.0f,
|
||||
{ "this line ",
|
||||
"should be ",
|
||||
"split" });
|
||||
|
||||
testLineBreaks ("these\nlines \nhave\n weird \n spacing ",
|
||||
80.0f,
|
||||
{ "these\n",
|
||||
"lines \n",
|
||||
"have\n",
|
||||
" weird \n",
|
||||
" spacing " });
|
||||
}
|
||||
};
|
||||
|
||||
static TextLayoutTests textLayoutTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue