diff --git a/es-core/src/resources/Font.cpp b/es-core/src/resources/Font.cpp index d19d57bde..c89f4dafc 100644 --- a/es-core/src/resources/Font.cpp +++ b/es-core/src/resources/Font.cpp @@ -17,10 +17,10 @@ Font::Font(int size, const std::string& path) : mRenderer {Renderer::getInstance()} + , mPath(path) + , mTextSize {0.0f, 0.0f} , mFontSize(size) , mMaxGlyphHeight {0} - , mTextSize {0.0f, 0.0f} - , mPath(path) { if (mFontSize < 9) { mFontSize = 9; @@ -56,45 +56,6 @@ Font::~Font() } } -void Font::initLibrary() -{ - assert(sLibrary == nullptr); - - if (FT_Init_FreeType(&sLibrary)) { - sLibrary = nullptr; - LOG(LogError) << "Couldn't initialize FreeType"; - } -} - -std::vector Font::getFallbackFontPaths() -{ - std::vector fontPaths; - - // Standard fonts, let's include them here for exception handling purposes even though that's - // not really the correct location. (The application will crash if they are missing.) - ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-Regular.ttf"); - ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-SemiBold.ttf"); - ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-Bold.ttf"); - - // Vera sans Unicode. - fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/DejaVuSans.ttf")); - // GNU FreeFont monospaced. - fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/FreeMono.ttf")); - // Various languages, such as Japanese and Chinese. - fontPaths.push_back( - ResourceManager::getInstance().getResourcePath(":/fonts/DroidSansFallbackFull.ttf")); - // Korean. - fontPaths.push_back( - ResourceManager::getInstance().getResourcePath(":/fonts/NanumMyeongjo.ttf")); - // Font Awesome icon glyphs, used for various special symbols like stars, folders etc. - fontPaths.push_back( - ResourceManager::getInstance().getResourcePath(":/fonts/fontawesome-webfont.ttf")); - // This is only needed for some really rare special characters. - fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/Ubuntu-C.ttf")); - - return fontPaths; -} - std::shared_ptr Font::get(int size, const std::string& path) { const std::string canonicalPath {Utils::FileSystem::getCanonicalPath(path)}; @@ -107,7 +68,7 @@ std::shared_ptr Font::get(int size, const std::string& path) return foundFont->second.lock(); } - std::shared_ptr font {std::shared_ptr(new Font(def.second, def.first))}; + std::shared_ptr font {new Font(def.second, def.first)}; sFontMap[def] = std::weak_ptr(font); ResourceManager::getInstance().addReloadable(font); return font; @@ -145,16 +106,6 @@ glm::vec2 Font::sizeText(std::string text, float lineSpacing) return glm::vec2 {highestWidth, y}; } -std::string Font::getTextMaxWidth(std::string text, float maxWidth) -{ - float width {sizeText(text).x}; - while (width > maxWidth) { - text.pop_back(); - width = sizeText(text).x; - } - return text; -} - TextCache* Font::buildTextCache(const std::string& text, float offsetX, float offsetY, @@ -442,12 +393,6 @@ glm::vec2 Font::getWrappedTextCursorOffset(const std::string& wrappedText, return glm::vec2 {lineWidth, yPos}; } -float Font::getHeight(float lineSpacing) const -{ - // Return overall height including line spacing. - return mMaxGlyphHeight * lineSpacing; -} - float Font::getLetterHeight() { Glyph* glyph {getGlyph('S')}; @@ -519,6 +464,34 @@ size_t Font::getTotalMemUsage() return total; } +std::vector Font::getFallbackFontPaths() +{ + std::vector fontPaths; + + // Default application fonts. + ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-Regular.ttf"); + ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-SemiBold.ttf"); + ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-Bold.ttf"); + + // Vera sans Unicode. + fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/DejaVuSans.ttf")); + // GNU FreeFont monospaced. + fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/FreeMono.ttf")); + // Various languages, such as Japanese and Chinese. + fontPaths.push_back( + ResourceManager::getInstance().getResourcePath(":/fonts/DroidSansFallbackFull.ttf")); + // Korean. + fontPaths.push_back( + ResourceManager::getInstance().getResourcePath(":/fonts/NanumMyeongjo.ttf")); + // Font Awesome icon glyphs, used for various special symbols like stars, folders etc. + fontPaths.push_back( + ResourceManager::getInstance().getResourcePath(":/fonts/fontawesome-webfont.ttf")); + // This is only needed for some really rare special characters. + fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/Ubuntu-C.ttf")); + + return fontPaths; +} + Font::FontTexture::FontTexture(const int mFontSize) { textureId = 0; @@ -621,6 +594,16 @@ Font::FontFace::~FontFace() FT_Done_Face(face); } +void Font::initLibrary() +{ + assert(sLibrary == nullptr); + + if (FT_Init_FreeType(&sLibrary)) { + sLibrary = nullptr; + LOG(LogError) << "Couldn't initialize FreeType"; + } +} + void Font::rebuildTextures() { // Recreate OpenGL textures. diff --git a/es-core/src/resources/Font.h b/es-core/src/resources/Font.h index 602c763a5..f2f4ea09d 100644 --- a/es-core/src/resources/Font.h +++ b/es-core/src/resources/Font.h @@ -42,16 +42,11 @@ class Font : public IReloadable { public: virtual ~Font(); - static void initLibrary(); - std::vector getFallbackFontPaths(); static std::shared_ptr get(int size, const std::string& path = getDefaultPath()); // Returns the expected size of a string when rendered. Extra spacing is applied to the Y axis. glm::vec2 sizeText(std::string text, float lineSpacing = 1.5f); - // Returns the portion of a string that fits within the passed argument maxWidth. - std::string getTextMaxWidth(std::string text, float maxWidth); - // Returns the size of the overall text area. const glm::vec2 getTextSize() { return mTextSize; } @@ -84,7 +79,8 @@ public: const size_t stop, const float lineSpacing = 1.5f); - float getHeight(float lineSpacing = 1.5f) const; + // Return overall height including line spacing. + float getHeight(float lineSpacing = 1.5f) const { return mMaxGlyphHeight * lineSpacing; } float getLetterHeight(); void reload(ResourceManager& rm) override { rebuildTextures(); } @@ -104,16 +100,12 @@ public: static size_t getTotalMemUsage(); private: - Renderer* mRenderer; - static inline FT_Library sLibrary {nullptr}; - static inline std::map, std::weak_ptr> sFontMap; - Font(int size, const std::string& path); + static void initLibrary(); struct FontTexture { unsigned int textureId; glm::ivec2 textureSize; - glm::ivec2 writePos; int rowHeight; @@ -126,8 +118,7 @@ private: // updating textureId. void initTexture(); - // Deinitializes the OpenGL texture if any exists, is automatically called - // in the destructor. + // Deinitializes any existing OpenGL textures, is automatically called in destructor. void deinitTexture(); }; @@ -139,6 +130,14 @@ private: virtual ~FontFace(); }; + struct Glyph { + FontTexture* texture; + glm::vec2 texPos; + glm::vec2 texSize; // In texels. + glm::vec2 advance; + glm::vec2 bearing; + }; + // Completely recreate the texture data for all textures based on mGlyphs information. void rebuildTextures(); void unloadTextures(); @@ -147,35 +146,30 @@ private: FontTexture*& tex_out, glm::ivec2& cursor_out); - std::map> mFaceCache; + std::vector getFallbackFontPaths(); FT_Face getFaceForChar(unsigned int id); - void clearFaceCache() { mFaceCache.clear(); } - - struct Glyph { - FontTexture* texture; - - glm::vec2 texPos; - glm::vec2 texSize; // In texels. - - glm::vec2 advance; - glm::vec2 bearing; - }; - - std::vector mTextures; - std::map mGlyphMap; Glyph* getGlyph(const unsigned int id); - int mFontSize; - int mMaxGlyphHeight; - glm::vec2 mTextSize; - const std::string mPath; - float getNewlineStartOffset(const std::string& text, const unsigned int& charStart, const float& xLen, const Alignment& alignment); - friend TextCache; + void clearFaceCache() { mFaceCache.clear(); } + + static inline FT_Library sLibrary {nullptr}; + static inline std::map, std::weak_ptr> sFontMap; + static inline std::vector mFallbackFonts; + + Renderer* mRenderer; + std::map> mFaceCache; + std::vector mTextures; + std::map mGlyphMap; + + const std::string mPath; + glm::vec2 mTextSize; + int mFontSize; + int mMaxGlyphHeight; }; // Used to store a sort of "pre-rendered" string. @@ -200,8 +194,6 @@ public: protected: struct VertexList { std::vector verts; - // This is a pointer because the texture ID can change during - // deinit/reinit (when launching a game). unsigned int* textureIdPtr; };