Utility/RichTextDrawer: Add character & line spacing offsets

This commit is contained in:
Lynix 2020-01-26 16:57:56 +01:00
parent 977044f59e
commit 8c7301f649
4 changed files with 162 additions and 33 deletions

View File

@ -219,7 +219,7 @@ Nazara Engine:
- On Windows, Thread::Set(Current)Name now uses `SetThreadDescription` Win32 function if possible instead of triggering a debugger exception. MinGW builds will use this if available too. - On Windows, Thread::Set(Current)Name now uses `SetThreadDescription` Win32 function if possible instead of triggering a debugger exception. MinGW builds will use this if available too.
- ⚠ Removed Texture(const Image\*) constructor, use Texture::LoadFromImage instead - ⚠ Removed Texture(const Image\*) constructor, use Texture::LoadFromImage instead
- ⚠ TextDrawers now use floating-point internally and to exposes their Bounds (AbstractTextDrawer::GetBounds() now returns a Rectf) - ⚠ TextDrawers now use floating-point internally and to exposes their Bounds (AbstractTextDrawer::GetBounds() now returns a Rectf)
- Added SimpleTextDrawer character and line spacing offset properties - Added [SimpleTextDrawer|RichTextDrawer] character and line spacing offset properties
Nazara Development Kit: Nazara Development Kit:
- Added ImageWidget (#139) - Added ImageWidget (#139)

View File

@ -33,10 +33,13 @@ namespace Nz
inline std::size_t FindBlock(std::size_t glyphIndex) const; inline std::size_t FindBlock(std::size_t glyphIndex) const;
inline unsigned int GetBlockCharacterSize(std::size_t index) const; inline unsigned int GetBlockCharacterSize(std::size_t index) const;
inline float GetBlockCharacterSpacingOffset(std::size_t index) const;
inline const Color& GetBlockColor(std::size_t index) const; inline const Color& GetBlockColor(std::size_t index) const;
inline std::size_t GetBlockCount() const; inline std::size_t GetBlockCount() const;
inline std::size_t GetBlockFirstGlyphIndex(std::size_t index) const; inline std::size_t GetBlockFirstGlyphIndex(std::size_t index) const;
inline const FontRef& GetBlockFont(std::size_t index) const; inline const FontRef& GetBlockFont(std::size_t index) const;
inline float GetBlockLineHeight(std::size_t index) const;
inline float GetBlockLineSpacingOffset(std::size_t index) const;
inline const Color& GetBlockOutlineColor(std::size_t index) const; inline const Color& GetBlockOutlineColor(std::size_t index) const;
inline float GetBlockOutlineThickness(std::size_t index) const; inline float GetBlockOutlineThickness(std::size_t index) const;
inline TextStyleFlags GetBlockStyle(std::size_t index) const; inline TextStyleFlags GetBlockStyle(std::size_t index) const;
@ -45,8 +48,10 @@ namespace Nz
inline BlockRef GetBlock(std::size_t index); inline BlockRef GetBlock(std::size_t index);
const Rectf& GetBounds() const override; const Rectf& GetBounds() const override;
inline unsigned int GetDefaultCharacterSize() const; inline unsigned int GetDefaultCharacterSize() const;
inline float GetDefaultCharacterSpacingOffset() const;
inline const Color& GetDefaultColor() const; inline const Color& GetDefaultColor() const;
inline const FontRef& GetDefaultFont() const; inline const FontRef& GetDefaultFont() const;
inline float GetDefaultLineSpacingOffset() const;
inline const Color& GetDefaultOutlineColor() const; inline const Color& GetDefaultOutlineColor() const;
inline float GetDefaultOutlineThickness() const; inline float GetDefaultOutlineThickness() const;
inline TextStyleFlags GetDefaultStyle() const; inline TextStyleFlags GetDefaultStyle() const;
@ -65,16 +70,20 @@ namespace Nz
void RemoveBlock(std::size_t index); void RemoveBlock(std::size_t index);
inline void SetBlockCharacterSize(std::size_t index, unsigned int characterSize); inline void SetBlockCharacterSize(std::size_t index, unsigned int characterSize);
inline void SetBlockCharacterSpacingOffset(std::size_t index, float offset);
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 SetBlockLineSpacingOffset(std::size_t index, float offset);
inline void SetBlockOutlineColor(std::size_t index, const Color& color); inline void SetBlockOutlineColor(std::size_t index, const Color& color);
inline void SetBlockOutlineThickness(std::size_t index, float thickness); inline void SetBlockOutlineThickness(std::size_t index, float thickness);
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, 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 SetDefaultCharacterSpacingOffset(float offset);
inline void SetDefaultColor(const Color& color); inline void SetDefaultColor(const Color& color);
inline void SetDefaultFont(const FontRef& font); inline void SetDefaultFont(const FontRef& font);
inline void SetDefaultLineSpacingOffset(float offset);
inline void SetDefaultOutlineColor(const Color& color); inline void SetDefaultOutlineColor(const Color& color);
inline void SetDefaultOutlineThickness(float thickness); inline void SetDefaultOutlineThickness(float thickness);
inline void SetDefaultStyle(TextStyleFlags style); inline void SetDefaultStyle(TextStyleFlags style);
@ -89,13 +98,15 @@ namespace Nz
private: private:
struct Block; struct Block;
inline void AppendNewLine(const Font* font, unsigned int characterSize) const; inline void AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset) const;
void AppendNewLine(const Font* font, unsigned int characterSize, std::size_t glyphIndex, float glyphPosition) const; void AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset, std::size_t glyphIndex, float glyphPosition) const;
inline void ClearGlyphs() const; inline void ClearGlyphs() const;
inline void ConnectFontSlots(); inline void ConnectFontSlots();
inline void DisconnectFontSlots(); inline void DisconnectFontSlots();
bool GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, int renderOrder, int* advance) const; bool GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, const Font* font, const Color& color, TextStyleFlags style, float lineSpacingOffset, unsigned int characterSize, int renderOrder, int* advance) const;
void GenerateGlyphs(const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, const Color& outlineColor, float outlineThickness, const String& text) const; void GenerateGlyphs(const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, const Color& outlineColor, float characterSpacingOffset, float lineSpacingOffset, float outlineThickness, const String& text) const;
inline float GetLineHeight(const Block& block) const;
inline float GetLineHeight(float lineSpacingOffset, const Font::SizeInfo& sizeInfo) const;
inline std::size_t HandleFontAddition(const FontRef& font); inline std::size_t HandleFontAddition(const FontRef& font);
inline void InvalidateGlyphs(); inline void InvalidateGlyphs();
inline void ReleaseFont(std::size_t fontIndex); inline void ReleaseFont(std::size_t fontIndex);
@ -117,6 +128,8 @@ namespace Nz
Color outlineColor; Color outlineColor;
String text; String text;
TextStyleFlags style; TextStyleFlags style;
float characterSpacingOffset;
float lineSpacingOffset;
float outlineThickness; float outlineThickness;
unsigned int characterSize; unsigned int characterSize;
}; };
@ -145,6 +158,8 @@ namespace Nz
mutable Rectf m_bounds; mutable Rectf m_bounds;
mutable Vector2f m_drawPos; mutable Vector2f m_drawPos;
mutable bool m_glyphUpdated; mutable bool m_glyphUpdated;
float m_defaultCharacterSpacingOffset;
float m_defaultLineSpacingOffset;
float m_defaultOutlineThickness; float m_defaultOutlineThickness;
float m_maxLineWidth; float m_maxLineWidth;
unsigned int m_defaultCharacterSize; unsigned int m_defaultCharacterSize;
@ -160,18 +175,22 @@ namespace Nz
BlockRef(BlockRef&&) = default; BlockRef(BlockRef&&) = default;
~BlockRef() = default; ~BlockRef() = default;
inline float GetCharacterSpacingOffset() const;
inline unsigned int GetCharacterSize() const; inline unsigned int GetCharacterSize() const;
inline Color GetColor() const; inline Color GetColor() const;
inline std::size_t GetFirstGlyphIndex() const; inline std::size_t GetFirstGlyphIndex() const;
inline const FontRef& GetFont() const; inline const FontRef& GetFont() const;
inline float GetLineSpacingOffset() const;
inline Color GetOutlineColor() const; inline Color GetOutlineColor() const;
inline float GetOutlineThickness() const; inline float GetOutlineThickness() const;
inline TextStyleFlags GetStyle() const; inline TextStyleFlags GetStyle() const;
inline const String& GetText() const; inline const String& GetText() const;
inline void SetCharacterSpacingOffset(float offset);
inline void SetCharacterSize(unsigned int size); inline void SetCharacterSize(unsigned int size);
inline void SetColor(Color color); inline void SetColor(Color color);
inline void SetFont(FontRef font); inline void SetFont(FontRef font);
inline void SetLineSpacingOffset(float offset);
inline void SetOutlineColor(Color color); inline void SetOutlineColor(Color color);
inline void SetOutlineThickness(float thickness); inline void SetOutlineThickness(float thickness);
inline void SetStyle(TextStyleFlags style); inline void SetStyle(TextStyleFlags style);

View File

@ -57,6 +57,12 @@ namespace Nz
return m_blocks[index].characterSize; return m_blocks[index].characterSize;
} }
inline float RichTextDrawer::GetBlockCharacterSpacingOffset(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].characterSpacingOffset;
}
inline const Color& RichTextDrawer::GetBlockColor(std::size_t index) const inline const Color& RichTextDrawer::GetBlockColor(std::size_t index) const
{ {
NazaraAssert(index < m_blocks.size(), "Invalid block index"); NazaraAssert(index < m_blocks.size(), "Invalid block index");
@ -82,6 +88,18 @@ namespace Nz
return m_fonts[fontIndex].font; return m_fonts[fontIndex].font;
} }
inline float RichTextDrawer::GetBlockLineHeight(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].lineSpacingOffset;
}
inline float RichTextDrawer::GetBlockLineSpacingOffset(std::size_t index) const
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
return m_blocks[index].lineSpacingOffset;
}
inline const Color& RichTextDrawer::GetBlockOutlineColor(std::size_t index) const inline const Color& RichTextDrawer::GetBlockOutlineColor(std::size_t index) const
{ {
NazaraAssert(index < m_blocks.size(), "Invalid block index"); NazaraAssert(index < m_blocks.size(), "Invalid block index");
@ -111,6 +129,11 @@ namespace Nz
return m_defaultCharacterSize; return m_defaultCharacterSize;
} }
inline float RichTextDrawer::GetDefaultCharacterSpacingOffset() const
{
return m_defaultCharacterSpacingOffset;
}
inline const Color& RichTextDrawer::GetDefaultColor() const inline const Color& RichTextDrawer::GetDefaultColor() const
{ {
return m_defaultColor; return m_defaultColor;
@ -121,6 +144,11 @@ namespace Nz
return m_defaultFont; return m_defaultFont;
} }
inline float RichTextDrawer::GetDefaultLineSpacingOffset() const
{
return m_defaultLineSpacingOffset;
}
inline const Color& RichTextDrawer::GetDefaultOutlineColor() const inline const Color& RichTextDrawer::GetDefaultOutlineColor() const
{ {
return m_defaultOutlineColor; return m_defaultOutlineColor;
@ -136,9 +164,9 @@ namespace Nz
return m_defaultStyle; return m_defaultStyle;
} }
inline void RichTextDrawer::AppendNewLine(const Font* font, unsigned int characterSize) const inline void RichTextDrawer::AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset) const
{ {
AppendNewLine(font, characterSize, InvalidGlyph, 0); AppendNewLine(font, characterSize, lineSpacingOffset, InvalidGlyph, 0);
} }
inline void RichTextDrawer::ClearGlyphs() const inline void RichTextDrawer::ClearGlyphs() const
@ -173,6 +201,19 @@ namespace Nz
} }
} }
inline float RichTextDrawer::GetLineHeight(const Block& block) const
{
assert(block.fontIndex < m_fonts.size());
const FontData& fontData = m_fonts[block.fontIndex];
return GetLineHeight(block.lineSpacingOffset, fontData.font->GetSizeInfo(block.characterSize));
}
inline float RichTextDrawer::GetLineHeight(float lineSpacingOffset, const Font::SizeInfo& sizeInfo) const
{
return float(sizeInfo.lineHeight) + lineSpacingOffset;
}
inline std::size_t RichTextDrawer::HandleFontAddition(const FontRef& font) inline std::size_t RichTextDrawer::HandleFontAddition(const FontRef& font)
{ {
auto it = m_fontIndexes.find(font); auto it = m_fontIndexes.find(font);
@ -204,10 +245,10 @@ namespace Nz
{ {
// Shift font indexes // Shift font indexes
m_fontIndexes.erase(fontData.font); m_fontIndexes.erase(fontData.font);
for (auto it = m_fontIndexes.begin(); it != m_fontIndexes.end(); ++it) for (auto& fontIndexe : m_fontIndexes)
{ {
if (it->second > fontIndex) if (fontIndexe.second > fontIndex)
it->second--; fontIndexe.second--;
} }
m_fonts.erase(m_fonts.begin() + fontIndex); m_fonts.erase(m_fonts.begin() + fontIndex);
@ -235,6 +276,14 @@ namespace Nz
InvalidateGlyphs(); InvalidateGlyphs();
} }
inline void RichTextDrawer::SetBlockCharacterSpacingOffset(std::size_t index, float offset)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].characterSpacingOffset = offset;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockColor(std::size_t index, const Color& color) inline void RichTextDrawer::SetBlockColor(std::size_t index, const Color& color)
{ {
NazaraAssert(index < m_blocks.size(), "Invalid block index"); NazaraAssert(index < m_blocks.size(), "Invalid block index");
@ -260,6 +309,14 @@ namespace Nz
InvalidateGlyphs(); InvalidateGlyphs();
} }
inline void RichTextDrawer::SetBlockLineSpacingOffset(std::size_t index, float offset)
{
NazaraAssert(index < m_blocks.size(), "Invalid block index");
m_blocks[index].lineSpacingOffset = offset;
InvalidateGlyphs();
}
inline void RichTextDrawer::SetBlockOutlineColor(std::size_t index, const Color& color) inline void RichTextDrawer::SetBlockOutlineColor(std::size_t index, const Color& color)
{ {
NazaraAssert(index < m_blocks.size(), "Invalid block index"); NazaraAssert(index < m_blocks.size(), "Invalid block index");
@ -308,6 +365,11 @@ namespace Nz
m_defaultCharacterSize = characterSize; m_defaultCharacterSize = characterSize;
} }
inline void RichTextDrawer::SetDefaultCharacterSpacingOffset(float offset)
{
m_defaultCharacterSpacingOffset = offset;
}
inline void RichTextDrawer::SetDefaultColor(const Color& color) inline void RichTextDrawer::SetDefaultColor(const Color& color)
{ {
m_defaultColor = color; m_defaultColor = color;
@ -318,6 +380,11 @@ namespace Nz
m_defaultFont = font; m_defaultFont = font;
} }
inline void RichTextDrawer::SetDefaultLineSpacingOffset(float offset)
{
m_defaultLineSpacingOffset = offset;
}
inline void RichTextDrawer::SetDefaultOutlineColor(const Color& color) inline void RichTextDrawer::SetDefaultOutlineColor(const Color& color)
{ {
m_defaultOutlineColor = color; m_defaultOutlineColor = color;
@ -351,6 +418,17 @@ namespace Nz
{ {
} }
/*!
* Returns the character spacing offset used for the characters of the referenced block
* \return The referenced block character size
*
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
*/
inline float RichTextDrawer::BlockRef::GetCharacterSpacingOffset() const
{
return m_drawer.GetBlockCharacterSpacingOffset(m_blockIndex);
}
/*! /*!
* Returns the character size used for the characters of the referenced block * Returns the character size used for the characters of the referenced block
* \return The referenced block character size * \return The referenced block character size
@ -384,6 +462,17 @@ namespace Nz
return m_drawer.GetBlockFont(m_blockIndex); return m_drawer.GetBlockFont(m_blockIndex);
} }
/*!
* Returns the line spacing offset used for the characters of the referenced block
* \return The referenced block character size
*
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
*/
inline float RichTextDrawer::BlockRef::GetLineSpacingOffset() const
{
return m_drawer.GetBlockLineSpacingOffset(m_blockIndex);
}
/*! /*!
* Returns the outline color used for the characters of the referenced block * Returns the outline color used for the characters of the referenced block
* \return The referenced block outline color * \return The referenced block outline color
@ -439,6 +528,17 @@ namespace Nz
return m_drawer.GetBlockText(m_blockIndex); return m_drawer.GetBlockText(m_blockIndex);
} }
/*!
* Changes the character spacing offset of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetCharacterSpacingOffset, SetColor, SetFont, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetCharacterSpacingOffset(float offset)
{
m_drawer.SetBlockCharacterSpacingOffset(m_blockIndex, offset);
}
/*! /*!
* Changes the character size of the referenced block characters * Changes the character size of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur. * \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
@ -472,6 +572,17 @@ namespace Nz
m_drawer.SetBlockFont(m_blockIndex, std::move(font)); m_drawer.SetBlockFont(m_blockIndex, std::move(font));
} }
/*!
* Changes the line spacing offset of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
*
* \see GetLineSpacingOffset, SetColor, SetFont, SetStyle, SetText
*/
inline void RichTextDrawer::BlockRef::SetLineSpacingOffset(float offset)
{
m_drawer.SetBlockLineSpacingOffset(m_blockIndex, offset);
}
/*! /*!
* Changes the outline color of the referenced block characters * Changes the outline color of the referenced block characters
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur. * \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.

View File

@ -267,7 +267,7 @@ namespace Nz
return *this; return *this;
} }
void RichTextDrawer::AppendNewLine(const Font* font, unsigned int characterSize, std::size_t glyphIndex, float glyphPosition) const void RichTextDrawer::AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset, std::size_t glyphIndex, float glyphPosition) const
{ {
// Ensure we're appending from last line // Ensure we're appending from last line
Line& lastLine = m_lines.back(); Line& lastLine = m_lines.back();
@ -276,13 +276,15 @@ namespace Nz
float previousDrawPos = m_drawPos.x; float previousDrawPos = m_drawPos.x;
float lineHeight = GetLineHeight(lineSpacingOffset, sizeInfo);
// Reset cursor // Reset cursor
m_drawPos.x = 0; m_drawPos.x = 0;
m_drawPos.y += sizeInfo.lineHeight; m_drawPos.y += lineHeight;
m_lastSeparatorGlyph = InvalidGlyph; m_lastSeparatorGlyph = InvalidGlyph;
m_bounds.ExtendTo(lastLine.bounds); m_bounds.ExtendTo(lastLine.bounds);
m_lines.emplace_back(Line{ Rectf(0.f, float(sizeInfo.lineHeight * m_lines.size()), 0.f, float(sizeInfo.lineHeight)), m_glyphs.size() + 1 }); m_lines.emplace_back(Line{ Rectf(0.f, lineHeight * m_lines.size(), 0.f, lineHeight), m_glyphs.size() + 1 });
if (glyphIndex != InvalidGlyph && glyphIndex > lastLine.glyphIndex) if (glyphIndex != InvalidGlyph && glyphIndex > lastLine.glyphIndex)
{ {
@ -293,12 +295,12 @@ namespace Nz
{ {
Glyph& glyph = m_glyphs[i]; Glyph& glyph = m_glyphs[i];
glyph.bounds.x -= glyphPosition; glyph.bounds.x -= glyphPosition;
glyph.bounds.y += sizeInfo.lineHeight; glyph.bounds.y += lineHeight;
for (auto& corner : glyph.corners) for (auto& corner : glyph.corners)
{ {
corner.x -= glyphPosition; corner.x -= glyphPosition;
corner.y += sizeInfo.lineHeight; corner.y += lineHeight;
} }
newLine.bounds.ExtendTo(glyph.bounds); newLine.bounds.ExtendTo(glyph.bounds);
@ -316,7 +318,7 @@ namespace Nz
} }
} }
bool RichTextDrawer::GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, int renderOrder, int* advance) const bool RichTextDrawer::GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, const Font* font, const Color& color, TextStyleFlags style, float lineSpacingOffset, unsigned int characterSize, int renderOrder, int* advance) const
{ {
const Font::Glyph& fontGlyph = font->GetGlyph(characterSize, style, outlineThickness, character); const Font::Glyph& fontGlyph = font->GetGlyph(characterSize, style, outlineThickness, character);
if (fontGlyph.valid && fontGlyph.fauxOutlineThickness <= 0.f) if (fontGlyph.valid && fontGlyph.fauxOutlineThickness <= 0.f)
@ -330,7 +332,7 @@ namespace Nz
glyph.bounds.Set(fontGlyph.aabb); glyph.bounds.Set(fontGlyph.aabb);
if (lineWrap && ShouldLineWrap(glyph.bounds.width)) if (lineWrap && ShouldLineWrap(glyph.bounds.width))
AppendNewLine(font, characterSize, m_lastSeparatorGlyph, m_lastSeparatorPosition); AppendNewLine(font, characterSize, lineSpacingOffset, m_lastSeparatorGlyph, m_lastSeparatorPosition);
glyph.bounds.x += m_drawPos.x; glyph.bounds.x += m_drawPos.x;
glyph.bounds.y += m_drawPos.y; glyph.bounds.y += m_drawPos.y;
@ -356,7 +358,7 @@ namespace Nz
return false; return false;
}; };
void RichTextDrawer::GenerateGlyphs(const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, const Color& outlineColor, float outlineThickness, const String& text) const void RichTextDrawer::GenerateGlyphs(const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, const Color& outlineColor, float characterSpacingOffset, float lineSpacingOffset, float outlineThickness, const String& text) const
{ {
if (text.IsEmpty()) if (text.IsEmpty())
return; return;
@ -372,8 +374,9 @@ namespace Nz
char32_t previousCharacter = 0; char32_t previousCharacter = 0;
const Font::SizeInfo& sizeInfo = font->GetSizeInfo(characterSize); const Font::SizeInfo& sizeInfo = font->GetSizeInfo(characterSize);
float lineHeight = GetLineHeight(lineSpacingOffset, sizeInfo);
float heightDifference = sizeInfo.lineHeight - m_lines.back().bounds.height; float heightDifference = lineHeight - m_lines.back().bounds.height;
if (heightDifference > 0.f) if (heightDifference > 0.f)
{ {
for (std::size_t glyphIndex = m_lines.back().glyphIndex; glyphIndex < m_glyphs.size(); ++glyphIndex) for (std::size_t glyphIndex = m_lines.back().glyphIndex; glyphIndex < m_glyphs.size(); ++glyphIndex)
@ -388,10 +391,6 @@ namespace Nz
m_drawPos.y += static_cast<unsigned int>(heightDifference); m_drawPos.y += static_cast<unsigned int>(heightDifference);
m_lines.back().bounds.height += heightDifference; m_lines.back().bounds.height += heightDifference;
} }
/*if (firstFont.font)
m_lines.emplace_back(Line{ Rectf(0.f, 0.f, 0.f, float(font->GetSizeInfo(firstBlock.characterSize).lineHeight)), 0 });
else
m_lines.emplace_back(Line{ Rectf::Zero(), 0 });*/
m_glyphs.reserve(m_glyphs.size() + characters.size() * ((outlineThickness > 0.f) ? 2 : 1)); m_glyphs.reserve(m_glyphs.size() + characters.size() * ((outlineThickness > 0.f) ? 2 : 1));
for (char32_t character : characters) for (char32_t character : characters)
@ -402,16 +401,16 @@ namespace Nz
previousCharacter = character; previousCharacter = character;
bool whitespace = true; bool whitespace = true;
float advance = 0.f; float advance = characterSpacingOffset;
switch (character) switch (character)
{ {
case ' ': case ' ':
case '\n': case '\n':
advance = float(sizeInfo.spaceAdvance); advance += float(sizeInfo.spaceAdvance);
break; break;
case '\t': case '\t':
advance = float(sizeInfo.spaceAdvance) * 4.f; advance += float(sizeInfo.spaceAdvance) * 4.f;
break; break;
default: default:
@ -423,22 +422,22 @@ namespace Nz
if (!whitespace) if (!whitespace)
{ {
int iAdvance; int iAdvance;
if (!GenerateGlyph(glyph, character, 0.f, true, font, color, style, characterSize, 0, &iAdvance)) if (!GenerateGlyph(glyph, character, 0.f, true, font, color, style, lineSpacingOffset, characterSize, 0, &iAdvance))
continue; // Glyph failed to load, just skip it (can't do much) continue; // Glyph failed to load, just skip it (can't do much)
advance = float(iAdvance); advance += float(iAdvance);
if (outlineThickness > 0.f) if (outlineThickness > 0.f)
{ {
Glyph outlineGlyph; Glyph outlineGlyph;
if (GenerateGlyph(outlineGlyph, character, outlineThickness, false, font, outlineColor, style, characterSize, -1, nullptr)) if (GenerateGlyph(outlineGlyph, character, outlineThickness, false, font, outlineColor, style, lineSpacingOffset, characterSize, -1, nullptr))
m_glyphs.push_back(outlineGlyph); m_glyphs.push_back(outlineGlyph);
} }
} }
else else
{ {
if (ShouldLineWrap(advance)) if (ShouldLineWrap(advance))
AppendNewLine(font, characterSize, m_lastSeparatorGlyph, m_lastSeparatorPosition); AppendNewLine(font, characterSize, lineSpacingOffset, m_lastSeparatorGlyph, m_lastSeparatorPosition);
glyph.atlas = nullptr; glyph.atlas = nullptr;
glyph.bounds.Set(m_drawPos.x, m_lines.back().bounds.y, advance, float(sizeInfo.lineHeight)); glyph.bounds.Set(m_drawPos.x, m_lines.back().bounds.y, advance, float(sizeInfo.lineHeight));
@ -455,7 +454,7 @@ namespace Nz
{ {
case '\n': case '\n':
{ {
AppendNewLine(font, characterSize); AppendNewLine(font, characterSize, lineSpacingOffset);
break; break;
} }
@ -545,7 +544,7 @@ namespace Nz
const auto& firstFont = m_fonts[firstBlock.fontIndex]; const auto& firstFont = m_fonts[firstBlock.fontIndex];
if (firstFont.font) if (firstFont.font)
m_lines.emplace_back(Line{ Rectf(0.f, 0.f, 0.f, float(firstFont.font->GetSizeInfo(firstBlock.characterSize).lineHeight)), 0 }); m_lines.emplace_back(Line{ Rectf(0.f, 0.f, 0.f, GetLineHeight(firstBlock)), 0 });
else else
m_lines.emplace_back(Line{ Rectf::Zero(), 0 }); m_lines.emplace_back(Line{ Rectf::Zero(), 0 });
@ -556,7 +555,7 @@ namespace Nz
assert(block.fontIndex < m_fonts.size()); assert(block.fontIndex < m_fonts.size());
const auto& fontData = m_fonts[block.fontIndex]; const auto& fontData = m_fonts[block.fontIndex];
GenerateGlyphs(fontData.font, block.color, block.style, block.characterSize, block.outlineColor, block.outlineThickness, block.text); GenerateGlyphs(fontData.font, block.color, block.style, block.characterSize, block.outlineColor, block.outlineThickness, block.characterSpacingOffset, block.lineSpacingOffset, block.text);
} }
} }
else else