Utility/RichTextDrawer: Fixes block removal not adjusting glyph indexes

+ Add HasBlocks method
This commit is contained in:
Lynix 2019-09-24 18:44:12 +02:00 committed by Jérôme Leclercq
parent 1ea653ab5b
commit 3c7addc262
3 changed files with 38 additions and 20 deletions

View File

@ -54,6 +54,8 @@ namespace Nz
std::size_t GetLineCount() const override; std::size_t GetLineCount() const override;
float GetMaxLineWidth() const override; float GetMaxLineWidth() const override;
inline bool HasBlocks() const;
void MergeBlocks(); void MergeBlocks();
void RemoveBlock(std::size_t index); void RemoveBlock(std::size_t index);
@ -62,7 +64,7 @@ namespace Nz
inline void SetBlockColor(std::size_t index, const Color& color); inline void SetBlockColor(std::size_t index, const Color& color);
inline void SetBlockFont(std::size_t index, FontRef font); inline void SetBlockFont(std::size_t index, FontRef font);
inline void SetBlockStyle(std::size_t index, TextStyleFlags style); inline void SetBlockStyle(std::size_t index, TextStyleFlags style);
inline void SetBlockText(std::size_t index, const String& str); inline void SetBlockText(std::size_t index, String str);
inline void SetDefaultCharacterSize(unsigned int characterSize); inline void SetDefaultCharacterSize(unsigned int characterSize);
inline void SetDefaultColor(const Color& color); inline void SetDefaultColor(const Color& color);

View File

@ -9,6 +9,16 @@ namespace Nz
{ {
inline std::size_t RichTextDrawer::FindBlock(std::size_t glyphIndex) const inline std::size_t RichTextDrawer::FindBlock(std::size_t glyphIndex) const
{ {
auto it = m_blocks.begin();
for (; it != m_blocks.end(); ++it)
{
if (it->glyphIndex > glyphIndex)
break;
}
assert(it != m_blocks.begin());
return std::distance(m_blocks.begin(), it) - 1;
/*
// Binary search // Binary search
std::size_t count = m_blocks.size(); std::size_t count = m_blocks.size();
std::size_t step; std::size_t step;
@ -25,14 +35,14 @@ namespace Nz
if (m_blocks[i].glyphIndex < glyphIndex) if (m_blocks[i].glyphIndex < glyphIndex)
{ {
first = i + 1; first = ++i;
count -= step + 1; count -= step + 1;
} }
else else
count = step; count = step;
} }
return i; return i;*/
} }
inline auto RichTextDrawer::GetBlock(std::size_t index) -> BlockRef inline auto RichTextDrawer::GetBlock(std::size_t index) -> BlockRef
@ -193,6 +203,11 @@ namespace Nz
} }
} }
inline bool RichTextDrawer::HasBlocks() const
{
return !m_blocks.empty();
}
inline void RichTextDrawer::SetBlockCharacterSize(std::size_t index, unsigned int characterSize) inline void RichTextDrawer::SetBlockCharacterSize(std::size_t index, unsigned int characterSize)
{ {
NazaraAssert(index < m_blocks.size(), "Invalid block index"); NazaraAssert(index < m_blocks.size(), "Invalid block index");
@ -232,13 +247,13 @@ namespace Nz
InvalidateGlyphs(); InvalidateGlyphs();
} }
inline void RichTextDrawer::SetBlockText(std::size_t index, const String& str) inline void RichTextDrawer::SetBlockText(std::size_t index, String str)
{ {
NazaraAssert(index < m_blocks.size(), "Invalid block index"); NazaraAssert(index < m_blocks.size(), "Invalid block index");
std::size_t previousLength = m_blocks[index].text.GetLength(); std::size_t previousLength = m_blocks[index].text.GetLength();
m_blocks[index].text = str; m_blocks[index].text = std::move(str);
std::size_t newLength = m_blocks[index].text.GetLength(); std::size_t newLength = m_blocks[index].text.GetLength();
if (newLength != previousLength) if (newLength != previousLength)

View File

@ -166,9 +166,6 @@ namespace Nz
void RichTextDrawer::MergeBlocks() void RichTextDrawer::MergeBlocks()
{ {
if (m_blocks.size() < 2)
return;
auto TestBlockProperties = [](const Block& lhs, const Block& rhs) auto TestBlockProperties = [](const Block& lhs, const Block& rhs)
{ {
return lhs.characterSize == rhs.characterSize && return lhs.characterSize == rhs.characterSize &&
@ -177,22 +174,16 @@ namespace Nz
lhs.style == rhs.style; lhs.style == rhs.style;
}; };
auto lastBlockIt = m_blocks.begin(); std::size_t previousBlockIndex = 0;
for (auto it = lastBlockIt + 1; it != m_blocks.end();) for (std::size_t i = 1; i < m_blocks.size(); ++i)
{ {
if (TestBlockProperties(*lastBlockIt, *it)) if (TestBlockProperties(m_blocks[previousBlockIndex], m_blocks[i]))
{ {
// Append text to previous block and erase RemoveBlock(i);
lastBlockIt->text += it->text; --i;
ReleaseFont(it->fontIndex);
it = m_blocks.erase(it);
} }
else else
{ previousBlockIndex = i;
lastBlockIt = it;
++it;
}
} }
} }
@ -200,8 +191,18 @@ namespace Nz
{ {
NazaraAssert(index < m_blocks.size(), "Invalid block index"); NazaraAssert(index < m_blocks.size(), "Invalid block index");
std::size_t textLength = m_blocks[index].text.GetLength();
ReleaseFont(m_blocks[index].fontIndex); ReleaseFont(m_blocks[index].fontIndex);
m_blocks.erase(m_blocks.begin() + index); m_blocks.erase(m_blocks.begin() + index);
for (std::size_t i = index; i < m_blocks.size(); ++i)
{
assert(m_blocks[i].glyphIndex > textLength);
m_blocks[i].glyphIndex -= textLength;
}
InvalidateGlyphs();
} }
void RichTextDrawer::SetMaxLineWidth(float lineWidth) void RichTextDrawer::SetMaxLineWidth(float lineWidth)