Skip to content

Conversation

@TellowKrinkle
Copy link
Member

@TellowKrinkle TellowKrinkle commented Nov 23, 2025

Description of Changes

  • Allow use of system fonts
  • Load all language fonts instead of just the one supported by the current locale
  • mmap fonts instead of copying them into memory
  • Enable non-English game titles in FSUI
  • Allow slightly wider title strings on horizontal FSUI buttons
  • Center icons in their buttons on the FSUI nav bar

Fixes #12804

Rationale behind Changes

  • No more prompts to download fonts when using non-latin languages unless your system is missing that font
  • Don't need to ship 25MB Noto Color Emoji on Windows (still needed on macOS and Linux)
  • Can use non-English game titles in FSUI
  • Non-English characters in paths render properly in FSUI
  • Save ~75MB of ram when using the 25MB Noto Color Emoji font

Suggested Testing Steps

  • Delete any downloaded fonts from your PCSX2 directory
  • Make sure you don't get prompted to download any fonts (unless on Linux and don't have Noto fonts)
  • Make sure non-English game titles render properly in FSUI
  • Make sure fonts look nice in your language in FSUI (Arabic is still broken, sorry)
  • Make sure line height looks reasonable everywhere in FSUI (lines shouldn't look like they're squished against each other)

Notes

  • Font sizes have changed for non-latin fonts. Translators will need to re-check FSUI to make sure their translations still fit.
  • Linux packagers should add Noto Sans {CJK, Arabic, Hebrew, Devanagari} to the recommended dependencies of their packages.

Did you use AI to help find, test, or implement this issue or feature?

No

@TellowKrinkle TellowKrinkle force-pushed the AllTheFonts branch 2 times, most recently from 2f63b04 to 03f7350 Compare November 26, 2025 04:36
Copy link
Contributor

@TheLastRar TheLastRar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

translation.cpp needs to be formatted, any sections where you disagree with clang-format probably should have // clang-format off/on comments added.

I've not reviewed the added freetype code or the patches to imgui.

{"ko-KR", "NotoSansKR-Regular.ttf"},
{"zh-CN", "NotoSansSC-Regular.ttf"},
{"zh-TW", "NotoSansTC-Regular.ttf"},
static constexpr const struct { const char* name; FontScript script; } s_language_scripts[] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know you could do this

static InputLayout s_gamepad_layout = InputLayout::Unknown;
} // namespace ImGuiFullscreen

static float GetLineHeight(std::pair<ImFont*, float> font)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming this function should be used anywhere where font.second is used outside of the ImGui calc and draw text functions?

In that case, it is needed in various locations in Achievements.cpp, FullscreenUI.cpp and ImGuiOverlays.cpp
Additionally, extra consideration needs to be taken for any code that calls ImGuiManager::Get*Font() and ImGuiManager::GetFontSize*(), as they would need to reassemble the std::pair to get the LineHeight

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things sometimes look fine if you don't include the line height, especially when e.g. adding underlines under text like in the section headers, where including the line height looks worse IMO.

I don't have an RA account so I just blindly applied it to a bunch of stuff in Achievements.cpp, someone should actually look at those interfaces and see if things look ok.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to document exactly when GetLineHeight should or shouldn't be used

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't an exact place it should be used. GetLineHeight produces a number similar to what the font size was before fixing imgui, which was a pretty arbitrary number before. For new code, the way to use it is "Look at rendered UI. Does it look nice? If so, great. If not, add spacing."

The important thing for line height is that it makes imgui properly space multiline text so the lines don't look like they're touching. If you want to do the rest of the adjustment by adjusting all the arbitrary spacing values instead, that's fine. But it was easier for me to use GetLineHeight to match the old font size so I didn't have to mess with all the spacing numbers and verify that messing with them didn't break something else.

The only place it really matters is if you're trying to guess the result of CalcTextSizeA without actually calling it, which we do in a few places, but ideally we should actually call it and use the result instead of guessing.

Comment on lines -20 to 30
void SetFontPath(std::string path);
struct FontInfo
{
std::span<const u8> data;
std::span<const u32> exclude_ranges;
const char* face_name;
bool is_emoji_font;
};

/// Sets a list of fonts to use.
void SetFonts(std::vector<FontInfo> info);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given how we have to tread emoji fonts separately, would it make sense to pass those fonts as a second parameter instead of having to check is_emoji_font eveytime we iterate info?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully in the future we can treat emoji fonts less special, and it'll just be an is_emoji_font ? color : grayscale.

I'd like to keep them together.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from the Glyph*AdvanceX setting, the main special treatment needed would be filtering the Variation Selector codepoints.
I'm suspecting that will probably be needed for as long as we use ImGui for text rendering.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh true

I'd still like them together since it allows the font selection code to have minimal extra stuff to work around imgui's brokenness.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note, I'd like to get rid of the forced advance at some point, since it affects the spacing when used in normal text. If we want them to use a fixed amount of space when being used as icons, we should do that by separately rendering the icon and giving it a fixed amount of space, not by editing the font (which is shared by normal text rendering) to make it monospace.

Protects against all the other stuff we load eating up all the address space that we want
@TellowKrinkle TellowKrinkle force-pushed the AllTheFonts branch 2 times, most recently from e35ef57 to b1ba002 Compare November 27, 2025 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Japanese Game Title for Big Picture Mode

3 participants