mirror of https://github.com/bkaradzic/bgfx
Fixed issue #1681.
This commit is contained in:
parent
a6bdbd4a03
commit
ac8a686f6e
|
@ -73,7 +73,9 @@ public:
|
|||
// Imgui.
|
||||
imguiCreate();
|
||||
|
||||
m_bigText = (char*)load("text/sherlock_holmes_a_scandal_in_bohemia_arthur_conan_doyle.txt");
|
||||
uint32_t size;
|
||||
m_txtFile = load("text/sherlock_holmes_a_scandal_in_bohemia_arthur_conan_doyle.txt", &size);
|
||||
m_bigText = bx::StringView( (const char*)m_txtFile, size);
|
||||
|
||||
// Init the text rendering system.
|
||||
m_fontManager = new FontManager(512);
|
||||
|
@ -111,7 +113,7 @@ public:
|
|||
{
|
||||
imguiDestroy();
|
||||
|
||||
BX_FREE(entry::getAllocator(), m_bigText);
|
||||
unload(m_txtFile);
|
||||
|
||||
m_fontManager->destroyTtf(m_font);
|
||||
// Destroy the fonts.
|
||||
|
@ -253,7 +255,8 @@ public:
|
|||
uint32_t m_debug;
|
||||
uint32_t m_reset;
|
||||
|
||||
char* m_bigText;
|
||||
void* m_txtFile;
|
||||
bx::StringView m_bigText;
|
||||
|
||||
// Init the text rendering system.
|
||||
FontManager* m_fontManager;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define FONT_MANAGER_H_HEADER_GUARD
|
||||
|
||||
#include <bx/handlealloc.h>
|
||||
#include <bx/string.h>
|
||||
#include <bgfx/bgfx.h>
|
||||
|
||||
class Atlas;
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
||||
*/
|
||||
|
||||
#include <wchar.h> // wcslen
|
||||
|
||||
#include "text_metrics.h"
|
||||
#include "utf8.h"
|
||||
|
||||
|
@ -69,62 +67,19 @@ void TextMetrics::appendText(FontHandle _fontHandle, const char* _string)
|
|||
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
|
||||
}
|
||||
|
||||
void TextMetrics::appendText(FontHandle _fontHandle, const wchar_t* _string)
|
||||
{
|
||||
const FontInfo& font = m_fontManager->getFontInfo(_fontHandle);
|
||||
|
||||
if (font.lineGap > m_lineGap)
|
||||
{
|
||||
m_lineGap = font.lineGap;
|
||||
}
|
||||
|
||||
if ( (font.ascender - font.descender) > m_lineHeight)
|
||||
{
|
||||
m_height -= m_lineHeight;
|
||||
m_lineHeight = font.ascender - font.descender;
|
||||
m_height += m_lineHeight;
|
||||
}
|
||||
|
||||
for (uint32_t ii = 0, end = (uint32_t)wcslen(_string); ii < end; ++ii)
|
||||
{
|
||||
uint32_t codepoint = _string[ii];
|
||||
const GlyphInfo* glyph = m_fontManager->getGlyphInfo(_fontHandle, codepoint);
|
||||
if (NULL != glyph)
|
||||
{
|
||||
if (codepoint == L'\n')
|
||||
{
|
||||
m_height += m_lineGap + font.ascender - font.descender;
|
||||
m_lineGap = font.lineGap;
|
||||
m_lineHeight = font.ascender - font.descender;
|
||||
m_x = 0;
|
||||
}
|
||||
|
||||
m_x += glyph->advance_x;
|
||||
if(m_x > m_width)
|
||||
{
|
||||
m_width = m_x;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BX_CHECK(false, "Glyph not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextLineMetrics::TextLineMetrics(const FontInfo& _fontInfo)
|
||||
{
|
||||
m_lineHeight = _fontInfo.ascender - _fontInfo.descender + _fontInfo.lineGap;
|
||||
}
|
||||
|
||||
uint32_t TextLineMetrics::getLineCount(const char* _string) const
|
||||
uint32_t TextLineMetrics::getLineCount(const bx::StringView& _str) const
|
||||
{
|
||||
CodePoint codepoint = 0;
|
||||
uint32_t state = 0;
|
||||
uint32_t lineCount = 1;
|
||||
for (; *_string; ++_string)
|
||||
for (const char* ptr = _str.getPtr(); ptr != _str.getTerm(); ++ptr)
|
||||
{
|
||||
if (utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT)
|
||||
if (utf8_decode(&state, (uint32_t*)&codepoint, *ptr) == UTF8_ACCEPT)
|
||||
{
|
||||
if (codepoint == L'\n')
|
||||
{
|
||||
|
@ -137,36 +92,26 @@ uint32_t TextLineMetrics::getLineCount(const char* _string) const
|
|||
return lineCount;
|
||||
}
|
||||
|
||||
uint32_t TextLineMetrics::getLineCount(const wchar_t* _string) const
|
||||
{
|
||||
uint32_t lineCount = 1;
|
||||
for ( ;*_string != L'\0'; ++_string)
|
||||
{
|
||||
if(*_string == L'\n')
|
||||
{
|
||||
++lineCount;
|
||||
}
|
||||
}
|
||||
return lineCount;
|
||||
}
|
||||
|
||||
|
||||
void TextLineMetrics::getSubText(const char* _string, uint32_t _firstLine, uint32_t _lastLine, const char*& _begin, const char*& _end)
|
||||
void TextLineMetrics::getSubText(const bx::StringView& _str, uint32_t _firstLine, uint32_t _lastLine, const char*& _begin, const char*& _end)
|
||||
{
|
||||
CodePoint codepoint = 0;
|
||||
uint32_t state = 0;
|
||||
// y is bottom of a text line
|
||||
uint32_t currentLine = 0;
|
||||
while(*_string && (currentLine < _firstLine) )
|
||||
|
||||
const char* ptr = _str.getPtr();
|
||||
|
||||
while (ptr != _str.getTerm()
|
||||
&& (currentLine < _firstLine) )
|
||||
{
|
||||
for (; *_string; ++_string)
|
||||
for (; ptr != _str.getTerm(); ++ptr)
|
||||
{
|
||||
if (utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT)
|
||||
if (utf8_decode(&state, (uint32_t*)&codepoint, *ptr) == UTF8_ACCEPT)
|
||||
{
|
||||
if (codepoint == L'\n')
|
||||
{
|
||||
++currentLine;
|
||||
++_string;
|
||||
++ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -174,18 +119,19 @@ void TextLineMetrics::getSubText(const char* _string, uint32_t _firstLine, uint3
|
|||
}
|
||||
|
||||
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
|
||||
_begin = _string;
|
||||
_begin = ptr;
|
||||
|
||||
while ( (*_string) && (currentLine < _lastLine) )
|
||||
while (ptr != _str.getTerm()
|
||||
&& (currentLine < _lastLine) )
|
||||
{
|
||||
for (; *_string; ++_string)
|
||||
for (; ptr != _str.getTerm(); ++ptr)
|
||||
{
|
||||
if(utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT)
|
||||
if(utf8_decode(&state, (uint32_t*)&codepoint, *ptr) == UTF8_ACCEPT)
|
||||
{
|
||||
if(codepoint == L'\n')
|
||||
{
|
||||
++currentLine;
|
||||
++_string;
|
||||
++ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -193,122 +139,5 @@ void TextLineMetrics::getSubText(const char* _string, uint32_t _firstLine, uint3
|
|||
}
|
||||
|
||||
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
|
||||
_end = _string;
|
||||
}
|
||||
|
||||
void TextLineMetrics::getSubText(const wchar_t* _string, uint32_t _firstLine, uint32_t _lastLine, const wchar_t*& _begin, const wchar_t*& _end)
|
||||
{
|
||||
uint32_t currentLine = 0;
|
||||
while ( (*_string != L'\0') && (currentLine < _firstLine) )
|
||||
{
|
||||
for ( ;*_string != L'\0'; ++_string)
|
||||
{
|
||||
if(*_string == L'\n')
|
||||
{
|
||||
++currentLine;
|
||||
++_string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_begin = _string;
|
||||
|
||||
while ( (*_string != L'\0') && (currentLine < _lastLine) )
|
||||
{
|
||||
for ( ;*_string != L'\0'; ++_string)
|
||||
{
|
||||
if(*_string == L'\n')
|
||||
{
|
||||
++currentLine;
|
||||
++_string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_end = _string;
|
||||
}
|
||||
|
||||
void TextLineMetrics::getVisibleText(const char* _string, float _top, float _bottom, const char*& _begin, const char*& _end)
|
||||
{
|
||||
CodePoint codepoint = 0;
|
||||
uint32_t state = 0;
|
||||
// y is bottom of a text line
|
||||
float y = m_lineHeight;
|
||||
while (*_string && (y < _top) )
|
||||
{
|
||||
for (; *_string; ++_string)
|
||||
{
|
||||
if(utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT)
|
||||
{
|
||||
if(codepoint == L'\n')
|
||||
{
|
||||
y += m_lineHeight;
|
||||
++_string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
|
||||
_begin = _string;
|
||||
|
||||
// y is now top of a text line
|
||||
y -= m_lineHeight;
|
||||
while ( (*_string) && (y < _bottom) )
|
||||
{
|
||||
for (; *_string; ++_string)
|
||||
{
|
||||
if(utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT)
|
||||
{
|
||||
if(codepoint == L'\n')
|
||||
{
|
||||
y += m_lineHeight;
|
||||
++_string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
|
||||
_end = _string;
|
||||
}
|
||||
|
||||
void TextLineMetrics::getVisibleText(const wchar_t* _string, float _top, float _bottom, const wchar_t*& _begin, const wchar_t*& _end)
|
||||
{
|
||||
// y is bottom of a text line
|
||||
float y = m_lineHeight;
|
||||
|
||||
const wchar_t* _textEnd = _string + wcslen(_string);
|
||||
|
||||
while (y < _top)
|
||||
{
|
||||
for (const wchar_t* _current = _string; _current < _textEnd; ++_current)
|
||||
{
|
||||
if(*_current == L'\n')
|
||||
{
|
||||
y += m_lineHeight;
|
||||
++_string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_begin = _string;
|
||||
|
||||
// y is now top of a text line
|
||||
y -= m_lineHeight;
|
||||
while (y < _bottom )
|
||||
{
|
||||
for (const wchar_t* _current = _string; _current < _textEnd; ++_current)
|
||||
{
|
||||
if(*_current == L'\n')
|
||||
{
|
||||
y += m_lineHeight;
|
||||
++_string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_end = _string;
|
||||
_end = ptr;
|
||||
}
|
||||
|
|
|
@ -47,22 +47,10 @@ public:
|
|||
float getLineHeight() const { return m_lineHeight; }
|
||||
|
||||
/// Return the number of text line in the given text.
|
||||
uint32_t getLineCount(const char* _string) const;
|
||||
|
||||
/// Return the number of text line in the given text.
|
||||
uint32_t getLineCount(const wchar_t* _string) const;
|
||||
uint32_t getLineCount(const bx::StringView& _string) const;
|
||||
|
||||
/// Return the first and last character visible in the [_firstLine, _lastLine] range.
|
||||
void getSubText(const char* _string, uint32_t _firstLine, uint32_t _lastLine, const char*& _begin, const char*& _end);
|
||||
|
||||
/// Return the first and last character visible in the [_firstLine, _lastLine] range.
|
||||
void getSubText(const wchar_t* _string, uint32_t _firstLine, uint32_t _lastLine, const wchar_t*& _begin, const wchar_t*& _end);
|
||||
|
||||
/// Return the first and last character visible in the [_top, _bottom] range,
|
||||
void getVisibleText(const char* _string, float _top, float _bottom, const char*& _begin, const char*& _end);
|
||||
|
||||
/// Return the first and last character visible in the [_top, _bottom] range,
|
||||
void getVisibleText(const wchar_t* _string, float _top, float _bottom, const wchar_t*& _begin, const wchar_t*& _end);
|
||||
void getSubText(const bx::StringView& _str, uint32_t _firstLine, uint32_t _lastLine, const char*& _begin, const char*& _end);
|
||||
|
||||
private:
|
||||
float m_lineHeight;
|
||||
|
|
Loading…
Reference in New Issue