Refactoring/cleanup.

This commit is contained in:
Leon Styhre 2022-10-09 19:13:54 +02:00
parent 0757156caf
commit 0232635504
2 changed files with 69 additions and 94 deletions

View file

@ -17,10 +17,10 @@
Font::Font(int size, const std::string& path) Font::Font(int size, const std::string& path)
: mRenderer {Renderer::getInstance()} : mRenderer {Renderer::getInstance()}
, mPath(path)
, mTextSize {0.0f, 0.0f}
, mFontSize(size) , mFontSize(size)
, mMaxGlyphHeight {0} , mMaxGlyphHeight {0}
, mTextSize {0.0f, 0.0f}
, mPath(path)
{ {
if (mFontSize < 9) { if (mFontSize < 9) {
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<std::string> Font::getFallbackFontPaths()
{
std::vector<std::string> 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> Font::get(int size, const std::string& path) std::shared_ptr<Font> Font::get(int size, const std::string& path)
{ {
const std::string canonicalPath {Utils::FileSystem::getCanonicalPath(path)}; const std::string canonicalPath {Utils::FileSystem::getCanonicalPath(path)};
@ -107,7 +68,7 @@ std::shared_ptr<Font> Font::get(int size, const std::string& path)
return foundFont->second.lock(); return foundFont->second.lock();
} }
std::shared_ptr<Font> font {std::shared_ptr<Font>(new Font(def.second, def.first))}; std::shared_ptr<Font> font {new Font(def.second, def.first)};
sFontMap[def] = std::weak_ptr<Font>(font); sFontMap[def] = std::weak_ptr<Font>(font);
ResourceManager::getInstance().addReloadable(font); ResourceManager::getInstance().addReloadable(font);
return font; return font;
@ -145,16 +106,6 @@ glm::vec2 Font::sizeText(std::string text, float lineSpacing)
return glm::vec2 {highestWidth, y}; 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, TextCache* Font::buildTextCache(const std::string& text,
float offsetX, float offsetX,
float offsetY, float offsetY,
@ -442,12 +393,6 @@ glm::vec2 Font::getWrappedTextCursorOffset(const std::string& wrappedText,
return glm::vec2 {lineWidth, yPos}; return glm::vec2 {lineWidth, yPos};
} }
float Font::getHeight(float lineSpacing) const
{
// Return overall height including line spacing.
return mMaxGlyphHeight * lineSpacing;
}
float Font::getLetterHeight() float Font::getLetterHeight()
{ {
Glyph* glyph {getGlyph('S')}; Glyph* glyph {getGlyph('S')};
@ -519,6 +464,34 @@ size_t Font::getTotalMemUsage()
return total; return total;
} }
std::vector<std::string> Font::getFallbackFontPaths()
{
std::vector<std::string> 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) Font::FontTexture::FontTexture(const int mFontSize)
{ {
textureId = 0; textureId = 0;
@ -621,6 +594,16 @@ Font::FontFace::~FontFace()
FT_Done_Face(face); 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() void Font::rebuildTextures()
{ {
// Recreate OpenGL textures. // Recreate OpenGL textures.

View file

@ -42,16 +42,11 @@ class Font : public IReloadable
{ {
public: public:
virtual ~Font(); virtual ~Font();
static void initLibrary();
std::vector<std::string> getFallbackFontPaths();
static std::shared_ptr<Font> get(int size, const std::string& path = getDefaultPath()); static std::shared_ptr<Font> 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. // 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); 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. // Returns the size of the overall text area.
const glm::vec2 getTextSize() { return mTextSize; } const glm::vec2 getTextSize() { return mTextSize; }
@ -84,7 +79,8 @@ public:
const size_t stop, const size_t stop,
const float lineSpacing = 1.5f); 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(); float getLetterHeight();
void reload(ResourceManager& rm) override { rebuildTextures(); } void reload(ResourceManager& rm) override { rebuildTextures(); }
@ -104,16 +100,12 @@ public:
static size_t getTotalMemUsage(); static size_t getTotalMemUsage();
private: private:
Renderer* mRenderer;
static inline FT_Library sLibrary {nullptr};
static inline std::map<std::pair<std::string, int>, std::weak_ptr<Font>> sFontMap;
Font(int size, const std::string& path); Font(int size, const std::string& path);
static void initLibrary();
struct FontTexture { struct FontTexture {
unsigned int textureId; unsigned int textureId;
glm::ivec2 textureSize; glm::ivec2 textureSize;
glm::ivec2 writePos; glm::ivec2 writePos;
int rowHeight; int rowHeight;
@ -126,8 +118,7 @@ private:
// updating textureId. // updating textureId.
void initTexture(); void initTexture();
// Deinitializes the OpenGL texture if any exists, is automatically called // Deinitializes any existing OpenGL textures, is automatically called in destructor.
// in the destructor.
void deinitTexture(); void deinitTexture();
}; };
@ -139,6 +130,14 @@ private:
virtual ~FontFace(); 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. // Completely recreate the texture data for all textures based on mGlyphs information.
void rebuildTextures(); void rebuildTextures();
void unloadTextures(); void unloadTextures();
@ -147,35 +146,30 @@ private:
FontTexture*& tex_out, FontTexture*& tex_out,
glm::ivec2& cursor_out); glm::ivec2& cursor_out);
std::map<unsigned int, std::unique_ptr<FontFace>> mFaceCache; std::vector<std::string> getFallbackFontPaths();
FT_Face getFaceForChar(unsigned int id); 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<FontTexture> mTextures;
std::map<unsigned int, Glyph> mGlyphMap;
Glyph* getGlyph(const unsigned int id); Glyph* getGlyph(const unsigned int id);
int mFontSize;
int mMaxGlyphHeight;
glm::vec2 mTextSize;
const std::string mPath;
float getNewlineStartOffset(const std::string& text, float getNewlineStartOffset(const std::string& text,
const unsigned int& charStart, const unsigned int& charStart,
const float& xLen, const float& xLen,
const Alignment& alignment); const Alignment& alignment);
friend TextCache; void clearFaceCache() { mFaceCache.clear(); }
static inline FT_Library sLibrary {nullptr};
static inline std::map<std::pair<std::string, int>, std::weak_ptr<Font>> sFontMap;
static inline std::vector<std::string> mFallbackFonts;
Renderer* mRenderer;
std::map<unsigned int, std::unique_ptr<FontFace>> mFaceCache;
std::vector<FontTexture> mTextures;
std::map<unsigned int, Glyph> mGlyphMap;
const std::string mPath;
glm::vec2 mTextSize;
int mFontSize;
int mMaxGlyphHeight;
}; };
// Used to store a sort of "pre-rendered" string. // Used to store a sort of "pre-rendered" string.
@ -200,8 +194,6 @@ public:
protected: protected:
struct VertexList { struct VertexList {
std::vector<Renderer::Vertex> verts; std::vector<Renderer::Vertex> verts;
// This is a pointer because the texture ID can change during
// deinit/reinit (when launching a game).
unsigned int* textureIdPtr; unsigned int* textureIdPtr;
}; };