Skip to content

Commit

Permalink
Ttf font scaling option (#6330)
Browse files Browse the repository at this point in the history
* Add option to set a font size multiplier for ttf fonts

* remove the option if we have no scaling fonts

* Clang the conquerer strikes again

* Update XSTRs

* clang

* Clarify comments
  • Loading branch information
MjnMixael authored Nov 27, 2024
1 parent 5e57e5e commit 06b0966
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 4 deletions.
19 changes: 17 additions & 2 deletions code/graphics/render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,12 +814,27 @@ void gr_string(float sx, float sy, const char* s, int resize_mode, size_t in_len
GR_DEBUG_SCOPE("Render TTF string");

auto path = beginDrawing(resize_mode);
path->translate(sx, sy);

auto nvgFont = static_cast<NVGFont*>(currentFont);

float scale_factor = Font_Scale_Factor;
if (!nvgFont->getScaleBehavior()) {
scale_factor = 1.0f;
}

float originalSize = nvgFont->getSize();
float scaledSize = originalSize * scale_factor;

// Calculate the offset to center the text
float offsetX = 0.0f;
// This is a compromise to try and size the text around center to minimize text offsets during scaling behavior.
// TODO Update this if multiline text is found to be negatively affected or a proper method of setting text anchors is added
float offsetY = (scaledSize - originalSize) * 0.5f;

path->translate(sx - offsetX, sy - offsetY);

path->fontFaceId(nvgFont->getHandle());
path->fontSize(nvgFont->getSize());
path->fontSize(scaledSize);
path->textLetterSpacing(nvgFont->getLetterSpacing());
path->textAlign(static_cast<TextAlign>(ALIGN_TOP | ALIGN_LEFT));

Expand Down
11 changes: 11 additions & 0 deletions code/graphics/software/FSFont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

namespace font
{

void FSFont::setScaleBehavior(bool scale)
{
this->canScale = scale;
}

void FSFont::setBottomOffset(float offset)
{
this->offsetBottom = offset;
Expand All @@ -22,6 +28,11 @@ namespace font
this->filename = newName;
}

[[nodiscard]] bool FSFont::getScaleBehavior() const
{
return this->canScale;
}

float FSFont::getBottomOffset() const
{
return this->offsetBottom;
Expand Down
19 changes: 19 additions & 0 deletions code/graphics/software/FSFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace font
SCP_string filename; //!< The file name used to retrieve this font

protected:
bool canScale = false; //!< If the font is allowed to scale with the user font multiplier
float offsetTop = 0.0f; //!< The offset at the top of a line of text
float offsetBottom = 0.0f; //!< The offset at the bottom of a line of text

Expand Down Expand Up @@ -142,6 +143,15 @@ namespace font
virtual void getStringSize(const char *text, size_t textLen = std::numeric_limits<size_t>::max(),
int resize_mode = -1, float *width = NULL, float *height = NULL) const = 0;

/**
* @brief Gets the scaling behavior of this font
*
* @date 28.8.2024
*
* @return The scaling behavior
*/
[[nodiscard]] bool getScaleBehavior() const;

/**
* @brief Gets the offset of this font from the top of the drawing line
*
Expand All @@ -160,6 +170,15 @@ namespace font
*/
float getBottomOffset() const;

/**
* @brief Sets the scaling behavior
*
* @date 28.8.2024
*
* @param scale whether or not this font can scale with the font multiplier
*/
void setScaleBehavior(bool scale);


/**
* @brief Sets the top offset for this font
Expand Down
9 changes: 9 additions & 0 deletions code/graphics/software/FontManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "localization/localize.h"
#include "options/Option.h"

namespace font
{
Expand Down Expand Up @@ -91,6 +92,14 @@ namespace font
return -1;
}

bool FontManager::hasScalingFonts()
{
return std::any_of(fonts.begin(), fonts.end(), [](const std::unique_ptr<FSFont>& font) {
const auto& thisFont = font.get();
return thisFont->getType() == NVG_FONT && thisFont->getScaleBehavior();
});
}

int FontManager::numberOfFonts()
{
return static_cast<int>(fonts.size());
Expand Down
5 changes: 5 additions & 0 deletions code/graphics/software/FontManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ namespace font {
*/
static int getFontIndexByFilename(const SCP_string &filename);

/**
* @brief Checks if we have any Scaling TTF fonts loaded. If not it disables the font scaling option
*/
static bool hasScalingFonts();

/**
* @brief Returns the number of fonts currently saved in the manager
* @return The number of fonts
Expand Down
25 changes: 24 additions & 1 deletion code/graphics/software/NVGFont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,29 @@
#include "graphics/paths/PathRenderer.h"

#include "mod_table/mod_table.h"
#include "options/Option.h"

#include "localization/localize.h"

#include <limits>

float Font_Scale_Factor = 1.0;

static auto FontScaleFactor __UNUSED = options::OptionBuilder<float>("Game.FontScaleFactor",
std::pair<const char*, int>{"Font Scale Factor", 1862},
std::pair<const char*, int>{"Sets a multipler to scale fonts by. Only works on fonts the mod has explicitely allowed", 1863})
.category(std::make_pair("Game", 1824))
.range(0.2f, 4.0f) // Upper limit is somewhat arbitrary
.level(options::ExpertLevel::Advanced)
.default_val(1.0)
.bind_to(&Font_Scale_Factor)
.importance(55)
.finish();

void removeFontMultiplierOption() {
options::OptionsManager::instance()->removeOption(FontScaleFactor);
}

namespace
{
const char* const TOKEN_SEPARATORS = "\n\t\r";
Expand Down Expand Up @@ -120,8 +138,13 @@ namespace font
path->saveState();
path->resetState();

float scale_factor = Font_Scale_Factor;
if (!canScale) {
scale_factor = 1.0f;
}

path->fontFaceId(m_handle);
path->fontSize(m_size);
path->fontSize(m_size * scale_factor);
path->textLetterSpacing(m_letterSpacing);
path->textAlign(static_cast<TextAlign>(ALIGN_TOP | ALIGN_LEFT));

Expand Down
2 changes: 2 additions & 0 deletions code/graphics/software/NVGFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "globalincs/pstypes.h"
#include "graphics/software/FSFont.h"

extern float Font_Scale_Factor;

namespace font
{
struct font;
Expand Down
2 changes: 2 additions & 0 deletions code/graphics/software/VFNTFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "globalincs/pstypes.h"
#include "graphics/software/FSFont.h"

void removeFontMultiplierOption();

namespace font
{
struct font;
Expand Down
14 changes: 14 additions & 0 deletions code/graphics/software/font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ namespace
return;
}

if (optional_string("+Can Scale:")) {
bool temp;

stuff_boolean(&temp);

nvgFont->setScaleBehavior(temp);
}

if (optional_string("+Top offset:"))
{
float temp;
Expand Down Expand Up @@ -506,6 +514,12 @@ namespace font
font_initialized = true;
}

void checkFontOptions() {
if (!FontManager::hasScalingFonts()) {
removeFontMultiplierOption();
}
}

void close()
{
if (!font_initialized) {
Expand Down
7 changes: 7 additions & 0 deletions code/graphics/software/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ namespace font
*/
void init();

/**
* @brief Verifies which font options should be available
*
* Removes options if they are not valid for the current font definitions,
*/
void checkFontOptions();

/**
* @brief Closes the Font system
*
Expand Down
2 changes: 1 addition & 1 deletion code/localization/localize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool *Lcl_unexpected_tstring_check = nullptr;
// NOTE: with map storage of XSTR strings, the indexes no longer need to be contiguous,
// but internal strings should still increment XSTR_SIZE to avoid collisions.
// retail XSTR_SIZE = 1570
// #define XSTR_SIZE 1862 // This is the next available ID
// #define XSTR_SIZE 1864 // This is the next available ID

// struct to allow for strings.tbl-determined x offset
// offset is 0 for english, by default
Expand Down
1 change: 1 addition & 0 deletions freespace2/freespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,7 @@ void game_init()
#endif

font::init(); // loads up all fonts
font::checkFontOptions();

// add title screen
game_title_screen_display();
Expand Down

0 comments on commit 06b0966

Please sign in to comment.