diff --git a/examples/10-font/font.cpp b/examples/10-font/font.cpp index c9f98d5ab..38f1c1388 100644 --- a/examples/10-font/font.cpp +++ b/examples/10-font/font.cpp @@ -20,6 +20,48 @@ #include #include +TrueTypeHandle loadTtf(FontManager* _fm, const char* _fontPath) +{ + FILE* pFile; + pFile = fopen(_fontPath, "rb"); + if (NULL != pFile) + { + if (0 == fseek(pFile, 0L, SEEK_END) ) + { + // Get the size of the file. + long bufsize = ftell(pFile); + if (bufsize == -1) + { + fclose(pFile); + TrueTypeHandle invalid = BGFX_INVALID_HANDLE; + return invalid; + } + + uint8_t* buffer = new uint8_t[bufsize]; + + // Go back to the start of the file. + fseek(pFile, 0L, SEEK_SET); + + // Read the entire file into memory. + uint32_t newLen = fread( (void*)buffer, sizeof(char), bufsize, pFile); + if (newLen == 0) + { + fclose(pFile); + delete[] buffer; + TrueTypeHandle invalid = BGFX_INVALID_HANDLE; + return invalid; + } + + fclose(pFile); + + return _fm->createTtf(buffer, bufsize); + } + } + + TrueTypeHandle invalid = BGFX_INVALID_HANDLE; + return invalid; +} + int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; @@ -65,7 +107,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) for (uint32_t ii = 0; ii < fontCount; ++ii) { // Instantiate a usable font. - fontFiles[ii] = fontManager->loadTrueTypeFromFile(fontNames[ii]); + fontFiles[ii] = loadTtf(fontManager, fontNames[ii]); fonts[ii] = fontManager->createFontByPixelSize(fontFiles[ii], 0, 32); // Preload glyphs and blit them to atlas. @@ -74,10 +116,10 @@ int _main_(int /*_argc*/, char** /*_argv*/) // You can unload the truetype files at this stage, but in that // case, the set of glyph's will be limited to the set of preloaded // glyph. - fontManager->unloadTrueType(fontFiles[ii]); + fontManager->destroyTtf(fontFiles[ii]); } - TrueTypeHandle console_tt = fontManager->loadTrueTypeFromFile("font/visitor1.ttf"); + TrueTypeHandle console_tt = loadTtf(fontManager, "font/visitor1.ttf"); // This font doesn't have any preloaded glyph's but the truetype file // is loaded so glyph will be generated as needed. @@ -180,7 +222,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::frame(); } - fontManager->unloadTrueType(console_tt); + fontManager->destroyTtf(console_tt); // Destroy the fonts. fontManager->destroyFont(consola_16); diff --git a/examples/11-fontsdf/fontsdf.cpp b/examples/11-fontsdf/fontsdf.cpp index 0fa1c99d1..d7a57d11d 100644 --- a/examples/11-fontsdf/fontsdf.cpp +++ b/examples/11-fontsdf/fontsdf.cpp @@ -69,6 +69,48 @@ char* loadText(const char* _textFile) return NULL; } +TrueTypeHandle loadTtf(FontManager* _fm, const char* _fontPath) +{ + FILE* pFile; + pFile = fopen(_fontPath, "rb"); + if (NULL != pFile) + { + if (0 == fseek(pFile, 0L, SEEK_END) ) + { + // Get the size of the file. + long bufsize = ftell(pFile); + if (bufsize == -1) + { + fclose(pFile); + TrueTypeHandle invalid = BGFX_INVALID_HANDLE; + return invalid; + } + + uint8_t* buffer = new uint8_t[bufsize]; + + // Go back to the start of the file. + fseek(pFile, 0L, SEEK_SET); + + // Read the entire file into memory. + uint32_t newLen = fread( (void*)buffer, sizeof(char), bufsize, pFile); + if (newLen == 0) + { + fclose(pFile); + delete[] buffer; + TrueTypeHandle invalid = BGFX_INVALID_HANDLE; + return invalid; + } + + fclose(pFile); + + return _fm->createTtf(buffer, bufsize); + } + } + + TrueTypeHandle invalid = BGFX_INVALID_HANDLE; + return invalid; +} + int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; @@ -108,7 +150,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) FontManager* fontManager = new FontManager(512); TextBufferManager* textBufferManager = new TextBufferManager(fontManager); - TrueTypeHandle font_tt = fontManager->loadTrueTypeFromFile("font/special_elite.ttf");//bleeding_cowboys.ttf"); + TrueTypeHandle font_tt = loadTtf(fontManager, "font/special_elite.ttf"); // Create a distance field font. FontHandle base_distance_font = fontManager->createFontByPixelSize(font_tt, 0, 48, FONT_TYPE_DISTANCE); @@ -247,7 +289,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::frame(); } - fontManager->unloadTrueType(font_tt); + fontManager->destroyTtf(font_tt); // Destroy the fonts. fontManager->destroyFont(base_distance_font); fontManager->destroyFont(scaled_font); diff --git a/examples/common/cube_atlas.h b/examples/common/cube_atlas.h index 159d2519d..9f5c26869 100644 --- a/examples/common/cube_atlas.h +++ b/examples/common/cube_atlas.h @@ -110,7 +110,7 @@ public: } /// retrieve the size of side of a texture in pixels - uint16_t getTextureSize() + uint16_t getTextureSize() const { return m_textureSize; } diff --git a/examples/common/font/font_manager.cpp b/examples/common/font/font_manager.cpp index caecb7b5e..8838f1151 100644 --- a/examples/common/font/font_manager.cpp +++ b/examples/common/font/font_manager.cpp @@ -539,58 +539,7 @@ FontManager::~FontManager() } } -TrueTypeHandle FontManager::loadTrueTypeFromFile(const char* _fontPath) -{ - FILE* pFile; - pFile = fopen(_fontPath, "rb"); - if (pFile == NULL) - { - TrueTypeHandle invalid = BGFX_INVALID_HANDLE; - return invalid; - } - - // Go to the end of the file. - if (fseek(pFile, 0L, SEEK_END) == 0) - { - // Get the size of the file. - long bufsize = ftell(pFile); - if (bufsize == -1) - { - fclose(pFile); - TrueTypeHandle invalid = BGFX_INVALID_HANDLE; - return invalid; - } - - uint8_t* buffer = new uint8_t[bufsize]; - - // Go back to the start of the file. - fseek(pFile, 0L, SEEK_SET); - - // Read the entire file into memory. - uint32_t newLen = fread( (void*)buffer, sizeof(char), bufsize, pFile); - if (newLen == 0) - { - fclose(pFile); - delete[] buffer; - TrueTypeHandle invalid = BGFX_INVALID_HANDLE; - return invalid; - } - - fclose(pFile); - - uint16_t id = m_filesHandles.alloc(); - BX_CHECK(id != bx::HandleAlloc::invalid, "No more room for files"); - m_cachedFiles[id].buffer = buffer; - m_cachedFiles[id].bufferSize = bufsize; - TrueTypeHandle ret = {id}; - return ret; - } - - TrueTypeHandle invalid = BGFX_INVALID_HANDLE; - return invalid; -} - -TrueTypeHandle FontManager::loadTrueTypeFromMemory(const uint8_t* _buffer, uint32_t _size) +TrueTypeHandle FontManager::createTtf(const uint8_t* _buffer, uint32_t _size) { uint16_t id = m_filesHandles.alloc(); BX_CHECK(id != bx::HandleAlloc::invalid, "Invalid handle used"); @@ -602,7 +551,7 @@ TrueTypeHandle FontManager::loadTrueTypeFromMemory(const uint8_t* _buffer, uint3 return ret; } -void FontManager::unloadTrueType(TrueTypeHandle _handle) +void FontManager::destroyTtf(TrueTypeHandle _handle) { BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used"); delete m_cachedFiles[_handle.idx].buffer; @@ -764,9 +713,9 @@ bool FontManager::preloadGlyph(FontHandle _handle, CodePoint _codePoint) { if (preloadGlyph(font.masterFontHandle, _codePoint) ) { - GlyphInfo glyphInfo; - getGlyphInfo(font.masterFontHandle, _codePoint, glyphInfo); + const GlyphInfo* glyph = getGlyphInfo(font.masterFontHandle, _codePoint); + GlyphInfo glyphInfo = *glyph; glyphInfo.advance_x = (glyphInfo.advance_x * fontInfo.scale); glyphInfo.advance_y = (glyphInfo.advance_y * fontInfo.scale); glyphInfo.offset_x = (glyphInfo.offset_x * fontInfo.scale); @@ -790,23 +739,23 @@ const FontInfo& FontManager::getFontInfo(FontHandle _handle) const return m_cachedFonts[_handle.idx].fontInfo; } -bool FontManager::getGlyphInfo(FontHandle _handle, CodePoint _codePoint, GlyphInfo& _outInfo) +const GlyphInfo* FontManager::getGlyphInfo(FontHandle _handle, CodePoint _codePoint) { - GlyphHashMap::iterator iter = m_cachedFonts[_handle.idx].cachedGlyphs.find(_codePoint); - if (iter == m_cachedFonts[_handle.idx].cachedGlyphs.end() ) + const GlyphHashMap& cachedGlyphs = m_cachedFonts[_handle.idx].cachedGlyphs; + GlyphHashMap::const_iterator it = cachedGlyphs.find(_codePoint); + if (it == cachedGlyphs.end() ) { if (preloadGlyph(_handle, _codePoint) ) { - iter = m_cachedFonts[_handle.idx].cachedGlyphs.find(_codePoint); + it = cachedGlyphs.find(_codePoint); } else { - return false; + return NULL; } } - _outInfo = iter->second; - return true; + return &it->second; } bool FontManager::addBitmap(GlyphInfo& _glyphInfo, const uint8_t* _data) diff --git a/examples/common/font/font_manager.h b/examples/common/font/font_manager.h index eec4d7377..d4d0fae91 100644 --- a/examples/common/font/font_manager.h +++ b/examples/common/font/font_manager.h @@ -132,19 +132,14 @@ public: return m_atlas; } - /// Load a TrueType font from a file path. - /// - /// @return INVALID_HANDLE if the loading fail. - TrueTypeHandle loadTrueTypeFromFile(const char* _fontPath); - /// Load a TrueType font from a given buffer. The buffer is copied and /// thus can be freed or reused after this call. /// /// @return invalid handle if the loading fail - TrueTypeHandle loadTrueTypeFromMemory(const uint8_t* _buffer, uint32_t _size); + TrueTypeHandle createTtf(const uint8_t* _buffer, uint32_t _size); /// Unload a TrueType font (free font memory) but keep loaded glyphs. - void unloadTrueType(TrueTypeHandle _handle); + void destroyTtf(TrueTypeHandle _handle); /// Return a font whose height is a fixed pixel size. FontHandle createFontByPixelSize(TrueTypeHandle _handle, uint32_t _typefaceIndex, uint32_t _pixelSize, uint32_t _fontType = FONT_TYPE_ALPHA); @@ -164,11 +159,6 @@ public: /// Preload a single glyph, return true on success. bool preloadGlyph(FontHandle _handle, CodePoint _character); - /// Bake a font to disk (the set of preloaded glyph). - /// - /// @return true if the baking succeed, false otherwise - bool saveBakedFont(FontHandle _handle, const char* _fontDirectory, const char* _fontName); - /// Return the font descriptor of a font. /// /// @remark the handle is required to be valid @@ -177,10 +167,9 @@ public: /// Return the rendering informations about the glyph region. Load the /// glyph from a TrueType font if possible /// - /// @return True if the Glyph is available. - bool getGlyphInfo(FontHandle _handle, CodePoint _codePoint, GlyphInfo& _outInfo); + const GlyphInfo* getGlyphInfo(FontHandle _handle, CodePoint _codePoint); - GlyphInfo& getBlackGlyph() + const GlyphInfo& getBlackGlyph() const { return m_blackGlyph; } diff --git a/examples/common/font/text_buffer_manager.cpp b/examples/common/font/text_buffer_manager.cpp index 772d2dd87..8cc468937 100644 --- a/examples/common/font/text_buffer_manager.cpp +++ b/examples/common/font/text_buffer_manager.cpp @@ -130,7 +130,7 @@ public: } private: - void appendGlyph(CodePoint _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo); + void appendGlyph(FontHandle _handle, CodePoint _codePoint); void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom); static uint32_t toABGR(uint32_t _rgba) @@ -224,9 +224,6 @@ TextBuffer::~TextBuffer() void TextBuffer::appendText(FontHandle _fontHandle, const char* _string, const char* _end) { - GlyphInfo glyph; - const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); - if (m_vertexCount == 0) { m_originX = m_penX; @@ -243,14 +240,7 @@ void TextBuffer::appendText(FontHandle _fontHandle, const char* _string, const c { if (utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT ) { - if (m_fontManager->getGlyphInfo(_fontHandle, codepoint, glyph) ) - { - appendGlyph(codepoint, font, glyph); - } - else - { - BX_CHECK(false, "Glyph not found"); - } + appendGlyph(_fontHandle, codepoint); } } @@ -259,9 +249,6 @@ void TextBuffer::appendText(FontHandle _fontHandle, const char* _string, const c void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string, const wchar_t* _end) { - GlyphInfo glyph; - const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); - if (m_vertexCount == 0) { m_originX = m_penX; @@ -280,14 +267,7 @@ void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string, cons for (const wchar_t* _current = _string; _current < _end; ++_current) { uint32_t _codePoint = *_current; - if (m_fontManager->getGlyphInfo(_fontHandle, _codePoint, glyph) ) - { - appendGlyph(_codePoint, font, glyph); - } - else - { - BX_CHECK(false, "Glyph not found"); - } + appendGlyph(_fontHandle, _codePoint); } } @@ -341,8 +321,17 @@ void TextBuffer::clearTextBuffer() m_rectangle.height = 0; } -void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo) -{ +void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint) +{ + const GlyphInfo* glyph = m_fontManager->getGlyphInfo(_handle, _codePoint); + BX_WARN(NULL != glyph, "Glyph not found (font handle %d, code point %d)", _handle.idx, _codePoint); + if (NULL == glyph) + { + return; + } + + const FontInfo& font = m_fontManager->getFontInfo(_handle); + if( m_vertexCount/4 >= MAX_BUFFERED_CHARACTERS) { return; @@ -352,40 +341,40 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const { m_penX = m_originX; m_penY += m_lineGap + m_lineAscender -m_lineDescender; - m_lineGap = _font.lineGap; - m_lineDescender = _font.descender; - m_lineAscender = _font.ascender; + m_lineGap = font.lineGap; + m_lineDescender = font.descender; + m_lineAscender = font.ascender; m_lineStartIndex = m_vertexCount; return; } //is there a change of font size that require the text on the left to be centered again ? - if (_font.ascender > m_lineAscender - || (_font.descender < m_lineDescender) ) + if (font.ascender > m_lineAscender + || (font.descender < m_lineDescender) ) { - if (_font.descender < m_lineDescender) + if (font.descender < m_lineDescender) { - m_lineDescender = _font.descender; - m_lineGap = _font.lineGap; + m_lineDescender = font.descender; + m_lineGap = font.lineGap; } - float txtDecals = (_font.ascender - m_lineAscender); - m_lineAscender = _font.ascender; - m_lineGap = _font.lineGap; + float txtDecals = (font.ascender - m_lineAscender); + m_lineAscender = font.ascender; + m_lineGap = font.lineGap; verticalCenterLastLine( (txtDecals), (m_penY - m_lineAscender), (m_penY + m_lineAscender - m_lineDescender + m_lineGap) ); } - float kerning = 0 * _font.scale; + float kerning = 0 * font.scale; m_penX += kerning; - GlyphInfo& blackGlyph = m_fontManager->getBlackGlyph(); + const GlyphInfo& blackGlyph = m_fontManager->getBlackGlyph(); if (m_styleFlags & STYLE_BACKGROUND && m_backgroundColor & 0xFF000000) { float x0 = (m_penX - kerning); float y0 = (m_penY); - float x1 = ( (float)x0 + (_glyphInfo.advance_x) ); + float x1 = ( (float)x0 + (glyph->advance_x) ); float y1 = (m_penY + m_lineAscender - m_lineDescender + m_lineGap); m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex @@ -414,8 +403,8 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const { float x0 = (m_penX - kerning); float y0 = (m_penY + m_lineAscender - m_lineDescender * 0.5f); - float x1 = ( (float)x0 + (_glyphInfo.advance_x) ); - float y1 = y0 + _font.underlineThickness; + float x1 = ( (float)x0 + (glyph->advance_x) ); + float y1 = y0 + font.underlineThickness; m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex , (uint8_t*)m_vertexBuffer @@ -443,8 +432,8 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const { float x0 = (m_penX - kerning); float y0 = (m_penY); - float x1 = ( (float)x0 + (_glyphInfo.advance_x) ); - float y1 = y0 + _font.underlineThickness; + float x1 = ( (float)x0 + (glyph->advance_x) ); + float y1 = y0 + font.underlineThickness; m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex , (uint8_t*)m_vertexBuffer @@ -471,9 +460,9 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const && m_strikeThroughColor & 0xFF000000) { float x0 = (m_penX - kerning); - float y0 = (m_penY + 0.666667f * _font.ascender); - float x1 = ( (float)x0 + (_glyphInfo.advance_x) ); - float y1 = y0 + _font.underlineThickness; + float y0 = (m_penY + 0.666667f * font.ascender); + float x1 = ( (float)x0 + (glyph->advance_x) ); + float y1 = y0 + font.underlineThickness; m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex , (uint8_t*)m_vertexBuffer @@ -496,12 +485,12 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const m_indexCount += 6; } - float x0 = m_penX + (_glyphInfo.offset_x); - float y0 = (m_penY + m_lineAscender + (_glyphInfo.offset_y) ); - float x1 = (x0 + _glyphInfo.width); - float y1 = (y0 + _glyphInfo.height); + float x0 = m_penX + (glyph->offset_x); + float y0 = (m_penY + m_lineAscender + (glyph->offset_y) ); + float x1 = (x0 + glyph->width); + float y1 = (y0 + glyph->height); - m_fontManager->getAtlas()->packUV(_glyphInfo.regionIndex + m_fontManager->getAtlas()->packUV(glyph->regionIndex , (uint8_t*)m_vertexBuffer , sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u) , sizeof(TextVertex) @@ -521,7 +510,7 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const m_vertexCount += 4; m_indexCount += 6; - m_penX += _glyphInfo.advance_x; + m_penX += glyph->advance_x; if (m_penX > m_rectangle.width) { m_rectangle.width = m_penX; diff --git a/examples/common/font/text_metrics.cpp b/examples/common/font/text_metrics.cpp index 93ace94c2..841fa08d3 100644 --- a/examples/common/font/text_metrics.cpp +++ b/examples/common/font/text_metrics.cpp @@ -20,7 +20,6 @@ TextMetrics::TextMetrics(FontManager* _fontManager) void TextMetrics::appendText(FontHandle _fontHandle, const char* _string) { - GlyphInfo glyph; const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); if (font.lineGap > m_lineGap) @@ -42,7 +41,8 @@ void TextMetrics::appendText(FontHandle _fontHandle, const char* _string) { if (!utf8_decode(&state, (uint32_t*)&codepoint, *_string) ) { - if (m_fontManager->getGlyphInfo(_fontHandle, codepoint, glyph) ) + const GlyphInfo* glyph = m_fontManager->getGlyphInfo(_fontHandle, codepoint); + if (NULL != glyph) { if (codepoint == L'\n') { @@ -53,8 +53,7 @@ void TextMetrics::appendText(FontHandle _fontHandle, const char* _string) break; } - - m_x += glyph.advance_x; + m_x += glyph->advance_x; if(m_x > m_width) { m_width = m_x; @@ -72,7 +71,6 @@ void TextMetrics::appendText(FontHandle _fontHandle, const char* _string) void TextMetrics::appendText(FontHandle _fontHandle, const wchar_t* _string) { - GlyphInfo glyph; const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); if (font.lineGap > m_lineGap) @@ -90,7 +88,8 @@ void TextMetrics::appendText(FontHandle _fontHandle, const wchar_t* _string) for (uint32_t ii = 0, end = (uint32_t)wcslen(_string); ii < end; ++ii) { uint32_t codepoint = _string[ii]; - if (m_fontManager->getGlyphInfo(_fontHandle, codepoint, glyph) ) + const GlyphInfo* glyph = m_fontManager->getGlyphInfo(_fontHandle, codepoint); + if (NULL != glyph) { if (codepoint == L'\n') { @@ -101,7 +100,7 @@ void TextMetrics::appendText(FontHandle _fontHandle, const wchar_t* _string) break; } - m_x += glyph.advance_x; + m_x += glyph->advance_x; if(m_x > m_width) { m_width = m_x;