From 292b021e0ebccdb23a0eb1b6f82b47adff948573 Mon Sep 17 00:00:00 2001 From: Jeremie Roy Date: Tue, 21 May 2013 14:45:14 +0200 Subject: [PATCH] add functionality to measure text without rendering it --- examples/common/font/text_buffer_manager.cpp | 86 +++++++++++++++++++- examples/common/font/text_buffer_manager.h | 9 +- 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/examples/common/font/text_buffer_manager.cpp b/examples/common/font/text_buffer_manager.cpp index 985ec4f23..5bbdba953 100644 --- a/examples/common/font/text_buffer_manager.cpp +++ b/examples/common/font/text_buffer_manager.cpp @@ -248,8 +248,7 @@ void TextBuffer::appendText(FontHandle _fontHandle, const char* _string) if (state != UTF8_ACCEPT) { - // assert(false && "The string is not well-formed"); - return; //"The string is not well-formed\n" + BX_CHECK(false, "The string is not well-formed"); } } @@ -280,6 +279,7 @@ void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string) } } } + void TextBuffer::appendAtlasFace(uint16_t _faceIndex) { float x0 = m_penX; @@ -841,6 +841,88 @@ void TextBufferManager::clearTextBuffer(TextBufferHandle _handle) bc.textBuffer->clearTextBuffer(); } +TextRectangle TextBufferManager::measureText(FontHandle _fontHandle, const char* _string) const +{ + GlyphInfo glyph; + const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); + TextRectangle rect; + rect.width = 0; + rect.height = font.ascender - font.descender; //should I put lineGap here ? + + CodePoint codepoint = 0; + uint32_t state = 0; + float w = 0; + + for (; *_string; ++_string) + { + if (!utf8_decode(&state, (uint32_t*)&codepoint, *_string) ) + { + if (m_fontManager->getGlyphInfo(_fontHandle, codepoint, glyph) ) + { + if (codepoint == L'\n') + { + rect.height += font.lineGap + font.ascender - font.descender; + w=0; + break; + } + //TODO kerning + + if((w + glyph.advance_x) > rect.width) + { + rect.width = w + glyph.advance_x; + } + } + else + { + BX_CHECK(false, "Glyph not found"); + } + } + } + + if (state != UTF8_ACCEPT) + { + BX_CHECK(false, "The string is not well-formed"); + } + + return rect; +} + +TextRectangle TextBufferManager::measureText(FontHandle _fontHandle, const wchar_t* _string) const +{ + GlyphInfo glyph; + const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); + TextRectangle rect; + rect.width = 0; + rect.height = font.ascender - font.descender; //should I put lineGap here ? + float w = 0; + + for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii) + { + uint32_t codepoint = _string[ii]; + if (m_fontManager->getGlyphInfo(_fontHandle, codepoint, glyph) ) + { + if (codepoint == L'\n') + { + rect.height += font.lineGap + font.ascender - font.descender; + w=0; + break; + } + //TODO kerning + + if((w + glyph.advance_x) > rect.width) + { + rect.width = w + glyph.advance_x; + } + } + else + { + BX_CHECK(false, "Glyph not found"); + } + } + + return rect; +} + TextRectangle TextBufferManager::getRectangle(TextBufferHandle _handle) const { BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used"); diff --git a/examples/common/font/text_buffer_manager.h b/examples/common/font/text_buffer_manager.h index c57830926..9a00302af 100644 --- a/examples/common/font/text_buffer_manager.h +++ b/examples/common/font/text_buffer_manager.h @@ -65,7 +65,14 @@ public: /// Clear the text buffer and reset its state (pen/color) void clearTextBuffer(TextBufferHandle _handle); - + + /// Return the rectangular size of the text without adding it to the buffer + TextRectangle measureText(FontHandle _fontHandle, const wchar_t* _string) const; + + /// Return the rectangular size of the text without adding it to the buffer + TextRectangle measureText(FontHandle _fontHandle, const char* _string) const; + + /// Return the rectangular size of the current text buffer (including all its content) TextRectangle getRectangle(TextBufferHandle _handle) const; private: