Skip to content

Commit

Permalink
Common: properly restore font metrics when setting an old font renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-mogilko committed Jul 30, 2022
1 parent 6854505 commit 1333f72
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 30 deletions.
5 changes: 4 additions & 1 deletion Common/font/agsfontrenderer.h
Expand Up @@ -80,16 +80,19 @@ struct FontMetrics

// The strictly internal font renderer interface, not to use in plugin API.
// Contains methods necessary for built-in font renderers.
class IAGSFontRendererInternal
class IAGSFontRendererInternal : public IAGSFontRenderer2
{
public:
// Tells if this is a bitmap font (otherwise it's a vector font)
virtual bool IsBitmapFont() = 0;
// Load font, applying extended font rendering parameters
virtual bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params,
FontMetrics *metrics) = 0;
// Fill FontMetrics struct; note that it may be left cleared if this is not supported
virtual void GetFontMetrics(int fontNumber, FontMetrics *metrics) = 0;
// Perform any necessary adjustments when the AA mode is toggled
virtual void AdjustFontForAntiAlias(int fontNumber, bool aa_mode) = 0;

protected:
IAGSFontRendererInternal() = default;
~IAGSFontRendererInternal() = default;
Expand Down
43 changes: 28 additions & 15 deletions Common/font/fonts.cpp
Expand Up @@ -110,7 +110,7 @@ static void font_post_init(size_t fontNumber)
Font &font = fonts[fontNumber];
// If no font height property was provided, then try several methods,
// depending on which interface is available
if (font.Metrics.Height == 0)
if ((font.Metrics.Height == 0) && font.Renderer)
{
int height = 0;
if (font.Renderer2)
Expand Down Expand Up @@ -159,30 +159,43 @@ static void font_post_init(size_t fontNumber)
}
}

static void font_replace_renderer(size_t fontNumber,
IAGSFontRenderer* renderer, IAGSFontRenderer2* renderer2)
{
fonts[fontNumber].Renderer = renderer;
fonts[fontNumber].Renderer2 = renderer2;
// If this is one of our built-in font renderers, then correctly
// reinitialize interfaces and font metrics
if ((renderer == &ttfRenderer) || (renderer == &wfnRenderer))
{
fonts[fontNumber].RendererInt = static_cast<IAGSFontRendererInternal*>(renderer);
fonts[fontNumber].RendererInt->GetFontMetrics(fontNumber, &fonts[fontNumber].Metrics);
}
// Otherwise, this is probably coming from plugin
else
{
fonts[fontNumber].RendererInt = nullptr;
fonts[fontNumber].Metrics = FontMetrics(); // reset to defaults
}
font_post_init(fontNumber);
}

IAGSFontRenderer* font_replace_renderer(size_t fontNumber, IAGSFontRenderer* renderer)
{
if (fontNumber >= fonts.size())
return nullptr;
IAGSFontRenderer* oldRender = fonts[fontNumber].Renderer;
fonts[fontNumber].Renderer = renderer;
fonts[fontNumber].Renderer2 = nullptr;
fonts[fontNumber].RendererInt = nullptr;
fonts[fontNumber].Metrics = FontMetrics();
font_post_init(fontNumber);
return oldRender;
IAGSFontRenderer* old_render = fonts[fontNumber].Renderer;
font_replace_renderer(fontNumber, renderer, nullptr);
return old_render;
}

IAGSFontRenderer2* font_replace_renderer(size_t fontNumber, IAGSFontRenderer2* renderer)
{
if (fontNumber >= fonts.size())
return nullptr;
IAGSFontRenderer2* oldRender = fonts[fontNumber].Renderer2;
fonts[fontNumber].Renderer = renderer;
fonts[fontNumber].Renderer2 = renderer;
fonts[fontNumber].RendererInt = nullptr;
fonts[fontNumber].Metrics = FontMetrics();
font_post_init(fontNumber);
return oldRender;
IAGSFontRenderer2* old_render = fonts[fontNumber].Renderer2;
font_replace_renderer(fontNumber, renderer, renderer);
return old_render;
}

void font_recalc_metrics(size_t fontNumber)
Expand Down
33 changes: 22 additions & 11 deletions Common/font/ttffontrenderer.cpp
Expand Up @@ -81,9 +81,8 @@ static int GetAlfontFlags(int load_mode)
return flags;
}

// Loads a TTF font of a certain size, optionally fill the FontMetrics struct
static ALFONT_FONT *LoadTTF(const String &filename, int fontSize,
int alfont_flags, FontMetrics *metrics)
// Loads a TTF font of a certain size
static ALFONT_FONT *LoadTTF(const String &filename, int fontSize, int alfont_flags)
{
std::unique_ptr<Stream> reader(AssetMgr->OpenAsset(filename));
if (!reader)
Expand All @@ -98,14 +97,17 @@ static ALFONT_FONT *LoadTTF(const String &filename, int fontSize,
if (!alfptr)
return nullptr;
alfont_set_font_size_ex(alfptr, fontSize, alfont_flags);
if (metrics)
{
metrics->Height = alfont_get_font_height(alfptr);
metrics->RealHeight = alfont_get_font_real_height(alfptr);
}
return alfptr;
}

// Fill the FontMetrics struct from the given ALFONT
static void FillMetrics(ALFONT_FONT *alfptr, FontMetrics *metrics)
{
metrics->Height = alfont_get_font_height(alfptr);
metrics->RealHeight = alfont_get_font_real_height(alfptr);
metrics->CompatHeight = metrics->Height; // just set to default here
}

bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize,
const FontRenderParams *params, FontMetrics *metrics)
{
Expand All @@ -116,12 +118,14 @@ bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize,
fontSize *= params->SizeMultiplier;

ALFONT_FONT *alfptr = LoadTTF(filename, fontSize,
GetAlfontFlags(params->LoadMode), metrics);
GetAlfontFlags(params->LoadMode));
if (!alfptr)
return false;

_fontData[fontNumber].AlFont = alfptr;
_fontData[fontNumber].Params = params ? *params : FontRenderParams();
if (metrics)
FillMetrics(alfptr, metrics);
return true;
}

Expand All @@ -135,6 +139,11 @@ int TTFFontRenderer::GetFontHeight(int fontNumber)
return alfont_get_font_real_height(_fontData[fontNumber].AlFont);
}

void TTFFontRenderer::GetFontMetrics(int fontNumber, FontMetrics *metrics)
{
FillMetrics(_fontData[fontNumber].AlFont, metrics);
}

void TTFFontRenderer::AdjustFontForAntiAlias(int fontNumber, bool /*aa_mode*/)
{
if (loaded_game_file_version < kGameVersion_341)
Expand All @@ -154,18 +163,20 @@ void TTFFontRenderer::FreeMemory(int fontNumber)

bool TTFFontRenderer::MeasureFontOfPointSize(const String &filename, int size_pt, FontMetrics *metrics)
{
ALFONT_FONT *alfptr = LoadTTF(filename, size_pt, ALFONT_FLG_FORCE_RESIZE | ALFONT_FLG_SELECT_NOMINAL_SZ, metrics);
ALFONT_FONT *alfptr = LoadTTF(filename, size_pt, ALFONT_FLG_FORCE_RESIZE | ALFONT_FLG_SELECT_NOMINAL_SZ);
if (!alfptr)
return false;
FillMetrics(alfptr, metrics);
alfont_destroy_font(alfptr);
return true;
}

bool TTFFontRenderer::MeasureFontOfPixelHeight(const String &filename, int pixel_height, FontMetrics *metrics)
{
ALFONT_FONT *alfptr = LoadTTF(filename, pixel_height, ALFONT_FLG_FORCE_RESIZE, metrics);
ALFONT_FONT *alfptr = LoadTTF(filename, pixel_height, ALFONT_FLG_FORCE_RESIZE);
if (!alfptr)
return false;
FillMetrics(alfptr, metrics);
alfont_destroy_font(alfptr);
return true;
}
3 changes: 2 additions & 1 deletion Common/font/ttffontrenderer.h
Expand Up @@ -20,7 +20,7 @@

struct ALFONT_FONT;

class TTFFontRenderer : public IAGSFontRenderer2, public IAGSFontRendererInternal {
class TTFFontRenderer : public IAGSFontRendererInternal {
public:
// IAGSFontRenderer implementation
bool LoadFromDisk(int fontNumber, int fontSize) override;
Expand All @@ -43,6 +43,7 @@ class TTFFontRenderer : public IAGSFontRenderer2, public IAGSFontRendererInterna
bool IsBitmapFont() override;
bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params,
FontMetrics *metrics) override;
void GetFontMetrics(int fontNumber, FontMetrics *metrics) override;
void AdjustFontForAntiAlias(int fontNumber, bool aa_mode) override;

//
Expand Down
4 changes: 3 additions & 1 deletion Common/font/wfnfontrenderer.cpp
Expand Up @@ -139,7 +139,7 @@ bool WFNFontRenderer::IsBitmapFont()
}

bool WFNFontRenderer::LoadFromDiskEx(int fontNumber, int /*fontSize*/,
const FontRenderParams *params, FontMetrics * /*metrics*/)
const FontRenderParams *params, FontMetrics *metrics)
{
String file_name;
Stream *ffi = nullptr;
Expand Down Expand Up @@ -167,6 +167,8 @@ bool WFNFontRenderer::LoadFromDiskEx(int fontNumber, int /*fontSize*/,
}
_fontData[fontNumber].Font = font;
_fontData[fontNumber].Params = params ? *params : FontRenderParams();
if (metrics)
*metrics = FontMetrics();
return true;
}

Expand Down
3 changes: 2 additions & 1 deletion Common/font/wfnfontrenderer.h
Expand Up @@ -20,7 +20,7 @@

class WFNFont;

class WFNFontRenderer : public IAGSFontRenderer2, public IAGSFontRendererInternal {
class WFNFontRenderer : public IAGSFontRendererInternal {
public:
// IAGSFontRenderer implementation
bool LoadFromDisk(int fontNumber, int fontSize) override;
Expand All @@ -43,6 +43,7 @@ class WFNFontRenderer : public IAGSFontRenderer2, public IAGSFontRendererInterna
bool IsBitmapFont() override;
bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params,
FontMetrics *metrics) override;
void GetFontMetrics(int fontNumber, FontMetrics *metrics) override { *metrics = FontMetrics(); }
void AdjustFontForAntiAlias(int /*fontNumber*/, bool /*aa_mode*/) override { /* do nothing */}

private:
Expand Down

0 comments on commit 1333f72

Please sign in to comment.