Added support for linear interpolation for font texture magnifications.

This commit is contained in:
Leon Styhre 2022-12-07 18:24:00 +01:00
parent 2799974938
commit 304d304727
7 changed files with 32 additions and 22 deletions

View file

@ -63,7 +63,7 @@ void HelpStyle::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::s
iconColorDimmed = iconColor;
if (elem->has("fontPath") || elem->has("fontSize"))
font = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, theme->isLegacyTheme());
font = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, false, theme->isLegacyTheme());
if (elem->has("entrySpacing"))
entrySpacing = glm::clamp(elem->get<float>("entrySpacing"), 0.0f, 0.04f);

View file

@ -224,5 +224,5 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (properties & LINE_SPACING && elem->has("lineSpacing"))
setLineSpacing(glm::clamp(elem->get<float>("lineSpacing"), 0.5f, 3.0f));
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, theme->isLegacyTheme()));
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, false, theme->isLegacyTheme()));
}

View file

@ -486,5 +486,5 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (properties & LINE_SPACING && elem->has("lineSpacing"))
setLineSpacing(glm::clamp(elem->get<float>("lineSpacing"), 0.5f, 3.0f));
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, theme->isLegacyTheme()));
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, false, theme->isLegacyTheme()));
}

View file

@ -1204,7 +1204,7 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
}
// For non-legacy themes, scale the font size with the itemScale property value.
mFont = Font::getFromTheme(elem, properties, mFont, 0.0f, mLegacyMode,
mFont = Font::getFromTheme(elem, properties, mFont, 0.0f, false, mLegacyMode,
(mLegacyMode ? 1.0f : (mItemScale >= 1.0f ? mItemScale : 1.0f)));
if (elem->has("textColor"))

View file

@ -529,7 +529,7 @@ void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
mSelectedSecondaryColor = mSelectedColor;
}
setFont(Font::getFromTheme(elem, properties, mFont, 0.0f, mLegacyMode));
setFont(Font::getFromTheme(elem, properties, mFont, 0.0f, false, mLegacyMode));
if (mLegacyMode)
mFont->useLegacyMaxGlyphHeight();
const float selectorHeight {mFont->getHeight(mLineSpacing)};

View file

@ -15,10 +15,11 @@
#include "utils/PlatformUtil.h"
#include "utils/StringUtil.h"
Font::Font(float size, const std::string& path)
Font::Font(float size, const std::string& path, const bool linearMagnify)
: mRenderer {Renderer::getInstance()}
, mPath(path)
, mFontSize {size}
, mLinearMagnify {linearMagnify}
, mLetterHeight {0.0f}
, mMaxGlyphHeight {static_cast<int>(std::round(size))}
, mLegacyMaxGlyphHeight {0}
@ -46,7 +47,8 @@ Font::~Font()
{
unload(ResourceManager::getInstance());
auto fontEntry = sFontMap.find(std::pair<std::string, float>(mPath, mFontSize));
auto fontEntry =
sFontMap.find(std::tuple<float, std::string, bool>(mFontSize, mPath, mLinearMagnify));
if (fontEntry != sFontMap.cend())
sFontMap.erase(fontEntry);
@ -57,11 +59,11 @@ Font::~Font()
}
}
std::shared_ptr<Font> Font::get(float size, const std::string& path)
std::shared_ptr<Font> Font::get(float size, const std::string& path, const bool linearMagnify)
{
const std::string canonicalPath {Utils::FileSystem::getCanonicalPath(path)};
const std::pair<std::string, float> def {
canonicalPath.empty() ? getDefaultPath() : canonicalPath, size};
const std::tuple<float, std::string, bool> def {
size, canonicalPath.empty() ? getDefaultPath() : canonicalPath, linearMagnify};
auto foundFont = sFontMap.find(def);
if (foundFont != sFontMap.cend()) {
@ -69,7 +71,7 @@ std::shared_ptr<Font> Font::get(float size, const std::string& path)
return foundFont->second.lock();
}
std::shared_ptr<Font> font {new Font(def.second, def.first)};
std::shared_ptr<Font> font {new Font(std::get<0>(def), std::get<1>(def), std::get<2>(def))};
sFontMap[def] = std::weak_ptr<Font>(font);
ResourceManager::getInstance().addReloadable(font);
return font;
@ -423,6 +425,7 @@ std::shared_ptr<Font> Font::getFromTheme(const ThemeData::ThemeElement* elem,
unsigned int properties,
const std::shared_ptr<Font>& orig,
const float maxHeight,
const bool linearMagnify,
const bool legacyTheme,
const float sizeMultiplier)
{
@ -459,9 +462,9 @@ std::shared_ptr<Font> Font::getFromTheme(const ThemeData::ThemeElement* elem,
}
if (mLegacyTheme)
return get(std::floor(size), path);
return get(std::floor(size), path, false);
else
return get(size, path);
return get(size, path, linearMagnify);
}
size_t Font::getMemUsage() const
@ -522,11 +525,12 @@ std::vector<std::string> Font::getFallbackFontPaths()
return fontPaths;
}
Font::FontTexture::FontTexture(const int mFontSize)
Font::FontTexture::FontTexture(const int mFontSize, const bool linearMagnifyArg)
{
textureId = 0;
rowHeight = 0;
writePos = glm::ivec2 {0, 0};
linearMagnify = linearMagnifyArg;
// Set the texture to a reasonable size, if we run out of space for adding glyphs then
// more textures will be created dynamically.
@ -573,9 +577,9 @@ void Font::FontTexture::initTexture()
// glyphs will not be visible. That would otherwise lead to edge artifacts as these pixels
// would get sampled during scaling.
std::vector<uint8_t> texture(textureSize.x * textureSize.y * 4, 0);
textureId =
Renderer::getInstance()->createTexture(Renderer::TextureType::RED, true, false, false,
false, textureSize.x, textureSize.y, &texture[0]);
textureId = Renderer::getInstance()->createTexture(Renderer::TextureType::RED, true,
linearMagnify, false, false, textureSize.x,
textureSize.y, &texture[0]);
}
void Font::FontTexture::deinitTexture()
@ -664,7 +668,8 @@ void Font::getTextureForNewGlyph(const glm::ivec2& glyphSize,
return; // Yes.
}
mTextures.emplace_back(std::make_unique<FontTexture>(static_cast<int>(std::round(mFontSize))));
mTextures.emplace_back(
std::make_unique<FontTexture>(static_cast<int>(std::round(mFontSize)), mLinearMagnify));
tex_out = mTextures.back().get();
tex_out->initTexture();

View file

@ -36,7 +36,9 @@ class Font : public IReloadable
{
public:
virtual ~Font();
static std::shared_ptr<Font> get(float size, const std::string& path = getDefaultPath());
static std::shared_ptr<Font> get(float size,
const std::string& path = getDefaultPath(),
const bool linearMagnify = false);
// 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);
@ -93,6 +95,7 @@ public:
unsigned int properties,
const std::shared_ptr<Font>& orig,
const float maxHeight = 0.0f,
const bool linearMagnify = false,
const bool legacyTheme = false,
const float sizeMultiplier = 1.0f);
@ -102,7 +105,7 @@ public:
static size_t getTotalMemUsage();
private:
Font(float size, const std::string& path);
Font(float size, const std::string& path, const bool linearMagnify);
static void initLibrary();
struct FontTexture {
@ -110,8 +113,9 @@ private:
glm::ivec2 textureSize;
glm::ivec2 writePos;
int rowHeight;
bool linearMagnify;
FontTexture(const int mFontSize);
FontTexture(const int mFontSize, const bool linearMagnifyArg);
~FontTexture();
bool findEmpty(const glm::ivec2& size, glm::ivec2& cursor_out);
@ -161,7 +165,7 @@ private:
void clearFaceCache() { mFaceCache.clear(); }
static inline FT_Library sLibrary {nullptr};
static inline std::map<std::pair<std::string, float>, std::weak_ptr<Font>> sFontMap;
static inline std::map<std::tuple<float, std::string, bool>, std::weak_ptr<Font>> sFontMap;
static inline bool mLegacyTheme {false};
Renderer* mRenderer;
@ -171,6 +175,7 @@ private:
const std::string mPath;
float mFontSize;
const bool mLinearMagnify;
float mLetterHeight;
int mMaxGlyphHeight;
int mLegacyMaxGlyphHeight;