1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

TTF fonts can now be used as fallback for H3 fonts

This commit is contained in:
Ivan Savenko 2023-04-04 22:23:32 +03:00
parent c5225aab70
commit 0770a1a153
5 changed files with 55 additions and 5 deletions

View File

@ -13,7 +13,6 @@
#include "../../lib/Point.h"
#include "../../lib/TextOperations.h"
//
size_t IFont::getStringWidth(const std::string & data) const
{

View File

@ -70,7 +70,7 @@ CBitmapFont::CBitmapFont(const std::string & filename):
loadModFont("core", resource);
for (auto const & modName : VLC->modh->getActiveMods())
for(const auto & modName : VLC->modh->getActiveMods())
{
if (CResourceHandler::get(modName)->existsResource(resource))
loadModFont(modName, resource);
@ -94,6 +94,24 @@ size_t CBitmapFont::getGlyphWidth(const char * data) const
return iter->second.leftOffset + iter->second.width + iter->second.rightOffset;
}
bool CBitmapFont::canRepresentCharacter(const char *data) const
{
CodePoint localChar = TextOperations::getUnicodeCodepoint(data, 4);
auto iter = chars.find(localChar);
return iter != chars.end();
}
bool CBitmapFont::canRepresentString(const std::string & data) const
{
for(size_t i=0; i<data.size(); i += TextOperations::getUnicodeCharacterSize(data[i]))
if (!canRepresentCharacter(data.data() + i))
return false;
return true;
}
void CBitmapFont::renderCharacter(SDL_Surface * surface, const BitmapChar & character, const SDL_Color & color, int &posX, int &posY) const
{
Rect clipRect;

View File

@ -41,6 +41,11 @@ public:
size_t getLineHeight() const override;
size_t getGlyphWidth(const char * data) const override;
/// returns true if this font contains provided utf-8 character
bool canRepresentCharacter(const char * data) const;
bool canRepresentString(const std::string & data) const;
friend class CBitmapHanFont;
friend class CTrueTypeFont;
};

View File

@ -10,6 +10,8 @@
#include "StdInc.h"
#include "CTrueTypeFont.h"
#include "CBitmapFont.h"
#include "../render/Colors.h"
#include "../renderSDL/SDL_Extensions.h"
@ -52,30 +54,45 @@ int CTrueTypeFont::getFontStyle(const JsonNode &config)
CTrueTypeFont::CTrueTypeFont(const JsonNode & fontConfig):
data(loadData(fontConfig)),
font(loadFont(fontConfig), TTF_CloseFont),
dropShadow(fontConfig["blend"].Bool()),
blended(fontConfig["blend"].Bool())
{
assert(font);
TTF_SetFontStyle(font.get(), getFontStyle(fontConfig));
std::string fallbackName = fontConfig["fallback"].String();
if (!fallbackName.empty())
fallbackFont = std::make_unique<CBitmapFont>(fallbackName);
}
CTrueTypeFont::~CTrueTypeFont() = default;
size_t CTrueTypeFont::getLineHeight() const
{
if (fallbackFont)
fallbackFont->getLineHeight();
return TTF_FontHeight(font.get());
}
size_t CTrueTypeFont::getGlyphWidth(const char *data) const
{
if (fallbackFont && fallbackFont->canRepresentCharacter(data))
return fallbackFont->getGlyphWidth(data);
return getStringWidth(std::string(data, TextOperations::getUnicodeCharacterSize(*data)));
/*
int advance;
TTF_GlyphMetrics(font.get(), *data, nullptr, nullptr, nullptr, nullptr, &advance);
return advance;
*/
}
size_t CTrueTypeFont::getStringWidth(const std::string & data) const
{
if (fallbackFont && fallbackFont->canRepresentString(data))
return fallbackFont->getStringWidth(data);
int width;
TTF_SizeUTF8(font.get(), data.c_str(), &width, nullptr);
return width;
@ -83,7 +100,13 @@ size_t CTrueTypeFont::getStringWidth(const std::string & data) const
void CTrueTypeFont::renderText(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const
{
if (color.r != 0 && color.g != 0 && color.b != 0) // not black - add shadow
if (fallbackFont && fallbackFont->canRepresentString(data))
{
fallbackFont->renderText(surface, data, color, pos);
return;
}
if (dropShadow && color.r != 0 && color.g != 0 && color.b != 0) // not black - add shadow
renderText(surface, data, Colors::BLACK, pos + Point(1,1));
if (!data.empty())

View File

@ -15,14 +15,18 @@ VCMI_LIB_NAMESPACE_BEGIN
class JsonNode;
VCMI_LIB_NAMESPACE_END
class CBitmapFont;
typedef struct _TTF_Font TTF_Font;
class CTrueTypeFont : public IFont
{
std::unique_ptr<CBitmapFont> fallbackFont;
const std::pair<std::unique_ptr<ui8[]>, ui64> data;
const std::unique_ptr<TTF_Font, void (*)(TTF_Font*)> font;
const bool blended;
const bool dropShadow;
std::pair<std::unique_ptr<ui8[]>, ui64> loadData(const JsonNode & config);
TTF_Font * loadFont(const JsonNode & config);
@ -31,6 +35,7 @@ class CTrueTypeFont : public IFont
void renderText(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const override;
public:
CTrueTypeFont(const JsonNode & fontConfig);
~CTrueTypeFont();
size_t getLineHeight() const override;
size_t getGlyphWidth(const char * data) const override;