| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /*
- * Copyright 2013 Jeremie Roy. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
- */
- #include "text_metrics.h"
- #include "utf8.h"
- TextMetrics::TextMetrics(FontManager* _fontManager)
- : m_fontManager(_fontManager)
- {
- clearText();
- }
- void TextMetrics::clearText()
- {
- m_width = m_height = m_x = m_lineHeight = m_lineGap = 0;
- }
- void TextMetrics::appendText(FontHandle _fontHandle, const char* _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;
- }
- CodePoint codepoint = 0;
- uint32_t state = 0;
- for (; *_string; ++_string)
- {
- if (!utf8_decode(&state, (uint32_t*)&codepoint, *_string) )
- {
- 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_ASSERT(false, "Glyph not found");
- }
- }
- }
- BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
- }
- TextLineMetrics::TextLineMetrics(const FontInfo& _fontInfo)
- {
- m_lineHeight = _fontInfo.ascender - _fontInfo.descender + _fontInfo.lineGap;
- }
- uint32_t TextLineMetrics::getLineCount(const bx::StringView& _str) const
- {
- CodePoint codepoint = 0;
- uint32_t state = 0;
- uint32_t lineCount = 1;
- for (const char* ptr = _str.getPtr(); ptr != _str.getTerm(); ++ptr)
- {
- if (utf8_decode(&state, (uint32_t*)&codepoint, *ptr) == UTF8_ACCEPT)
- {
- if (codepoint == L'\n')
- {
- ++lineCount;
- }
- }
- }
- BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
- return lineCount;
- }
- 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;
- const char* ptr = _str.getPtr();
- while (ptr != _str.getTerm()
- && (currentLine < _firstLine) )
- {
- for (; ptr != _str.getTerm(); ++ptr)
- {
- if (utf8_decode(&state, (uint32_t*)&codepoint, *ptr) == UTF8_ACCEPT)
- {
- if (codepoint == L'\n')
- {
- ++currentLine;
- ++ptr;
- break;
- }
- }
- }
- }
- BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
- _begin = ptr;
- while (ptr != _str.getTerm()
- && (currentLine < _lastLine) )
- {
- for (; ptr != _str.getTerm(); ++ptr)
- {
- if(utf8_decode(&state, (uint32_t*)&codepoint, *ptr) == UTF8_ACCEPT)
- {
- if(codepoint == L'\n')
- {
- ++currentLine;
- ++ptr;
- break;
- }
- }
- }
- }
- BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
- _end = ptr;
- }
|