diff --git a/es-core/src/resources/Font.cpp b/es-core/src/resources/Font.cpp index 2650c1f81..efe4de7fd 100644 --- a/es-core/src/resources/Font.cpp +++ b/es-core/src/resources/Font.cpp @@ -101,26 +101,39 @@ glm::vec2 Font::sizeText(std::string text, float lineSpacing) float highestWidth {0.0f}; float y {lineHeight}; - size_t i {0}; - while (i < text.length()) { - unsigned int character {Utils::String::chars2Unicode(text, i)}; // Advances i. + shapeText(text); - if (character == '\n') { - if (lineWidth > highestWidth) - highestWidth = lineWidth; + for (auto& segment : mSegmentsHB) { + for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) { + const unsigned int character {segment.glyphIndexes[i]}; + Glyph* glyph {nullptr}; - lineWidth = 0.0f; - y += lineHeight; + // Invalid character. + if (!segment.doShape && character == 0) + continue; + + if (!segment.doShape && character == '\n') { + if (lineWidth > highestWidth) + highestWidth = lineWidth; + + lineWidth = 0.0f; + y += lineHeight; + continue; + } + + if (segment.doShape) + glyph = getGlyphByIndex(character, segment.fontHB); + else + glyph = getGlyph(character); + + if (glyph) + lineWidth += glyph->advance.x; } - Glyph* glyph {getGlyph(character)}; - if (glyph) - lineWidth += glyph->advance.x; + if (lineWidth > highestWidth) + highestWidth = lineWidth; } - if (lineWidth > highestWidth) - highestWidth = lineWidth; - return glm::vec2 {highestWidth, y}; } @@ -128,13 +141,27 @@ int Font::loadGlyphs(const std::string& text) { mMaxGlyphHeight = static_cast<int>(std::round(mFontSize)); - for (size_t i {0}; i < text.length();) { - unsigned int character {Utils::String::chars2Unicode(text, i)}; // Advances i. - Glyph* glyph {getGlyph(character)}; + shapeText(text); - if (glyph->rows > mMaxGlyphHeight) - mMaxGlyphHeight = glyph->rows; + for (auto& segment : mSegmentsHB) { + for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) { + const unsigned int character {segment.glyphIndexes[i]}; + Glyph* glyph {nullptr}; + + // Invalid character. + if (!segment.doShape && character == 0) + continue; + + if (segment.doShape) + glyph = getGlyphByIndex(character, segment.fontHB); + else + glyph = getGlyph(character); + + if (glyph && glyph->rows > mMaxGlyphHeight) + mMaxGlyphHeight = glyph->rows; + } } + return mMaxGlyphHeight; } @@ -175,14 +202,11 @@ TextCache* Font::buildTextCache(const std::string& text, // Vertices by texture. std::map<FontTexture*, std::vector<Renderer::Vertex>> vertMap; - // Build segments for HarfBuzz. - if (buildShapeSegments(text)) - shapeSegments(text); + shapeText(text); for (auto& segment : mSegmentsHB) { for (size_t cursor {0}; cursor < segment.glyphIndexes.size(); ++cursor) { - unsigned int character {segment.glyphIndexes[cursor]}; - + const unsigned int character {segment.glyphIndexes[cursor]}; Glyph* glyph {nullptr}; // Invalid character. @@ -665,13 +689,13 @@ void Font::initLibrary() } } -bool Font::buildShapeSegments(const std::string& text) +void Font::shapeText(const std::string& text) { // Calculate the hash value for the string to make sure we're not building segments // repeatedly for the same text. const size_t hashValue {std::hash<std::string> {}(text)}; if (hashValue == mTextHash) - return false; + return; mTextHash = hashValue; mSegmentsHB.clear(); @@ -685,6 +709,8 @@ bool Font::buildShapeSegments(const std::string& text) size_t textCursor {0}; size_t lastFlushPos {0}; + // Step 1, build segments. + while (textCursor < text.length()) { addSegment = false; shapeSegment = true; @@ -739,11 +765,6 @@ bool Font::buildShapeSegments(const std::string& text) lastFont = currGlyph->fontHB; } - return true; -} - -void Font::shapeSegments(const std::string& text) -{ if (mSegmentsHB.empty()) return; @@ -753,6 +774,8 @@ void Font::shapeSegments(const std::string& text) hb_glyph_position_t* glyphPos {nullptr}; unsigned int glyphCount {0}; + // Step 2, shape text. + for (auto& segment : mSegmentsHB) { cursor = 0; length = 0; diff --git a/es-core/src/resources/Font.h b/es-core/src/resources/Font.h index 1cad4b880..e626f4591 100644 --- a/es-core/src/resources/Font.h +++ b/es-core/src/resources/Font.h @@ -205,8 +205,8 @@ private: } }; - // Builds segments for HarfBuzz. - bool buildShapeSegments(const std::string& text); + // Shape text using HarfBuzz. + void shapeText(const std::string& text); void shapeSegments(const std::string& text); // Completely recreate the texture data for all textures based on mGlyphs information.