-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: load system fonts automatically #686
Comments
I currently achieved this on Windows with this code. std::vector<std::filesystem::path> getSystemFonts() {
std::vector<std::filesystem::path> fonts;
std::string windowsPath(MAX_PATH, '\0');
GetWindowsDirectoryA(windowsPath.data(), windowsPath.size());
windowsPath.resize(strlen(windowsPath.c_str()));
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts", 0,
KEY_READ, &hKey) == ERROR_SUCCESS) {
DWORD index = 0;
char valueName[16383];
DWORD valueNameSize = 16383;
DWORD valueType;
BYTE valueData[16383];
DWORD valueDataSize = 16383;
while (RegEnumValue(hKey, index, valueName, &valueNameSize, NULL,
&valueType, valueData,
&valueDataSize) == ERROR_SUCCESS) {
fonts.push_back(std::filesystem::path(windowsPath) / "Fonts" /
std::string(valueData, valueData + valueDataSize));
index++;
valueNameSize = 16383;
valueDataSize = 16383;
}
RegCloseKey(hKey);
}
if (RegOpenKeyEx(HKEY_CURRENT_USER,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts", 0,
KEY_READ, &hKey) == ERROR_SUCCESS) {
DWORD index = 0;
char valueName[16383];
DWORD valueNameSize = 16383;
DWORD valueType;
BYTE valueData[16383];
DWORD valueDataSize = 16383;
while (RegEnumValue(hKey, index, valueName, &valueNameSize, NULL,
&valueType, valueData,
&valueDataSize) == ERROR_SUCCESS) {
fonts.push_back(std::filesystem::path(
std::string(valueData, valueData + valueDataSize)));
index++;
valueNameSize = 16383;
valueDataSize = 16383;
}
RegCloseKey(hKey);
}
return fonts;
}
struct FontFace {
std::string name;
std::string style;
int weight;
std::string file;
};
std::vector<FontFace> getFontFaces() {
auto fonts = getSystemFonts();
std::vector<FontFace> fontFaces;
FT_Library library;
FT_Init_FreeType(&library);
for (auto &font : fonts) {
FT_Face face;
if (!FT_New_Face(library, font.string().c_str(), 0, &face)) {
TT_OS2 *font_table = (TT_OS2 *)FT_Get_Sfnt_Table(face, FT_SFNT_OS2);
int weight;
if (font_table && font_table->usWeightClass != 0)
weight = font_table->usWeightClass;
else
weight = (face->style_flags & FT_STYLE_FLAG_BOLD) == FT_STYLE_FLAG_BOLD
? 700
: 400;
fontFaces.push_back({.name = face->family_name,
.style = face->style_name,
.weight = weight,
.file = font.string()});
FT_Done_Face(face);
}
}
return fontFaces;
}
// In main()
auto fonts = getFontFaces();
auto loadFonts = [&](std::initializer_list<std::string> preferedFonts,
bool fallback, bool onlyOne = true) {
for (auto &preferedFont : preferedFonts) {
auto font = std::find_if(fonts.begin(), fonts.end(), [&](auto &font) {
return font.name == preferedFont && font.weight == 400;
});
if (font != fonts.end()) {
Rml::LoadFontFace(font->file, fallback);
if (onlyOne)
return;
}
}
};
loadFonts(
{
"Arial",
},
false);
loadFonts(
{
"Noto Sans SC",
"Microsoft YaHei",
"Segoe UI",
},
true); |
This can also involve a load-when-used system for fonts and glyphs. Currently the memory consumption is significant for loading a font. |
We do have one example for loading system fonts: https://github.com/mikke89/RmlUi/blob/master/Samples/basic/ime/src/SystemFontWin32.cpp I don't really think it's the right thing for our library to include this functionality in our core library. We want to give users full control over things like font resources. So any such platform-specific behavior should be located on the user side. We might later consider adding it to the platform layer, Some kind of system for loading fonts as needed based on provided families and glyphs would indeed be nice. See in particular #500, I believe that issue should cover this feature already. |
The things is that it's extremely awful for users to implement this. Consider the following three points:
|
The thing can be optional, but we really should have something like that in the platform abstraction. if the user is not satisfied with the default implementation, they can use theit own's |
Bringing fonts into the binary creates more distribution burdens and legal risks. I suppose exposing an interface on the system interface to make the process of searching and loading system fonts automatic. The CSS font-family fallback order can be used.
The text was updated successfully, but these errors were encountered: