mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 04:49:39 -10:00
Multi-line and tabbed strings drawn with a scaleMultiplier != 1 overlapped or misaligned because the font code advanced newlines and tabs by the unscaled font height/tab width -- most visible in FRED's viewport labels now that they honor an adjustable font scale. Scale the newline and tab advance in both the rendering and measurement paths of each backend: the NVG path (gr_string and NVGFont::getStringSize) and the VFNT path (gr_string_old and VFNTFont::getStringSize), which also gains tab handling. The tab width is hoisted onto the shared FSFont base so both backends share it. While here, pass the FSFont wrapper to gr_string_old instead of a bag of scalars, make its font pointer const, and consolidate the get_char_width_old externs into a single declaration in font_internal.h. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
153 lines
3.4 KiB
C++
153 lines
3.4 KiB
C++
#include "graphics/software/FSFont.h"
|
|
#include "options/Option.h"
|
|
|
|
float Font_Scale_Factor = 1.0;
|
|
|
|
// coverity[GLOBAL_INIT_ORDER] -- safe; OptionBuilder::finish() uses Meyers singleton
|
|
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);
|
|
}
|
|
|
|
float get_font_scale_factor()
|
|
{
|
|
return FontScaleFactor->getValue();
|
|
}
|
|
|
|
// Calculate the font size based on the current screen resolution to provide a similar size on all resolutions
|
|
// The returned size will be roughly similar to the size of the font at 1080p
|
|
// Use 1080p because that's generally what font sizes have been targeting for years
|
|
// And should provide a fairly close out-of-the-box solution
|
|
float calculate_auto_font_size(float current_size)
|
|
{
|
|
int vmin = std::min(gr_screen.max_w, gr_screen.max_h);
|
|
float baseSize = vmin * (current_size / 1080.0f);
|
|
return std::round(baseSize);
|
|
}
|
|
|
|
namespace font
|
|
{
|
|
|
|
void FSFont::setAutoScaleBehavior(bool auto_scale)
|
|
{
|
|
this->autoScale = auto_scale;
|
|
}
|
|
|
|
void FSFont::setScaleBehavior(bool scale)
|
|
{
|
|
this->canScale = scale;
|
|
}
|
|
|
|
void FSFont::setBottomOffset(float offset)
|
|
{
|
|
this->offsetBottom = offset;
|
|
}
|
|
|
|
void FSFont::setTopOffset(float offset)
|
|
{
|
|
this->offsetTop = offset;
|
|
}
|
|
|
|
void FSFont::setName(const SCP_string &newName)
|
|
{
|
|
this->name = newName;
|
|
}
|
|
|
|
void FSFont::setFilename(const SCP_string& newName)
|
|
{
|
|
this->filename = newName;
|
|
}
|
|
|
|
void FSFont::setFamilyName(const SCP_string& newName)
|
|
{
|
|
this->familyName = newName;
|
|
}
|
|
|
|
[[nodiscard]] bool FSFont::getAutoScaleBehavior() const
|
|
{
|
|
return this->autoScale;
|
|
}
|
|
|
|
[[nodiscard]] bool FSFont::getScaleBehavior() const
|
|
{
|
|
return this->canScale;
|
|
}
|
|
|
|
float FSFont::getBottomOffset() const
|
|
{
|
|
return this->offsetBottom;
|
|
}
|
|
|
|
float FSFont::getTopOffset() const
|
|
{
|
|
return this->offsetTop;
|
|
}
|
|
|
|
float FSFont::getTabWidth() const
|
|
{
|
|
return this->tabWidth;
|
|
}
|
|
|
|
void FSFont::setTabWidth(float newTabWidth)
|
|
{
|
|
Assertion(newTabWidth >= 0.0f, "Invalid tab width passed!");
|
|
this->tabWidth = newTabWidth;
|
|
}
|
|
|
|
float FSFont::getHeight() const
|
|
{
|
|
return _height;
|
|
}
|
|
|
|
const SCP_string &FSFont::getName() const
|
|
{
|
|
return this->name;
|
|
}
|
|
|
|
const SCP_string &FSFont::getFilename() const
|
|
{
|
|
return this->filename;
|
|
}
|
|
|
|
const SCP_string& FSFont::getFamilyName() const
|
|
{
|
|
return this->familyName;
|
|
}
|
|
|
|
void FSFont::computeFontMetrics() {
|
|
_height = this->getTextHeight() + this->offsetTop + this->offsetBottom;
|
|
|
|
// By default the base line of the font is also the lowest point of the font
|
|
_ascender = _height;
|
|
_descender = 0.0f;
|
|
|
|
checkFontMetrics();
|
|
}
|
|
void FSFont::checkFontMetrics() {
|
|
if (_height <= 1.0f)
|
|
{
|
|
Warning(LOCATION, "The height of font %s has an invalid height of %f, must be greater than one!",
|
|
getName().c_str(), _height);
|
|
}
|
|
}
|
|
float FSFont::getAscender() {
|
|
return _ascender;
|
|
}
|
|
float FSFont::getDescender() {
|
|
return _descender;
|
|
}
|
|
}
|