5#include <unordered_set>
8#include "absl/status/status.h"
9#include "absl/strings/str_cat.h"
10#include "absl/strings/str_format.h"
13#include "imgui/imgui.h"
19static const char* KARLA_REGULAR =
"Karla-Regular.ttf";
20static const char* ROBOTO_MEDIUM =
"Roboto-Medium.ttf";
21static const char* COUSINE_REGULAR =
"Cousine-Regular.ttf";
22static const char* DROID_SANS =
"DroidSans.ttf";
23static const char* NOTO_SANS_JP =
"NotoSansJP.ttf";
24static const char* IBM_PLEX_JP =
"IBMPlexSansJP-Bold.ttf";
26static const float FONT_SIZE_DEFAULT = 16.0f;
27static const float FONT_SIZE_DROID_SANS = 18.0f;
28static const float ICON_FONT_SIZE = 18.0f;
36 return kBundlePath + font_path;
42 return absl::StrCat(
"assets/font/", font_path);
47 ImGuiIO& io = ImGui::GetIO();
51 if (!std::filesystem::exists(actual_font_path)) {
52 return absl::InternalError(
53 absl::StrFormat(
"Font file %s does not exist", actual_font_path));
56 if (!io.Fonts->AddFontFromFileTTF(actual_font_path.data(),
58 return absl::InternalError(
59 absl::StrFormat(
"Failed to load font from %s", actual_font_path));
61 return absl::OkStatus();
65 static const ImWchar icons_ranges[] = {
ICON_MIN_MD, 0xf900, 0};
66 ImFontConfig icons_config;
67 icons_config.MergeMode =
true;
68 icons_config.GlyphOffset.y = 5.0f;
69 icons_config.GlyphMinAdvanceX = 13.0f;
70 icons_config.PixelSnapH =
true;
72 ImGuiIO& io = ImGui::GetIO();
73 if (!io.Fonts->AddFontFromFileTTF(icon_font_path.c_str(), ICON_FONT_SIZE,
74 &icons_config, icons_ranges)) {
75 return absl::InternalError(
"Failed to add icon fonts");
77 return absl::OkStatus();
81 ImFontConfig japanese_font_config;
82 japanese_font_config.MergeMode =
true;
83 japanese_font_config.GlyphOffset.y = 5.0f;
84 japanese_font_config.GlyphMinAdvanceX = 13.0f;
85 japanese_font_config.PixelSnapH =
true;
86 std::string japanese_font_path =
SetFontPath(NOTO_SANS_JP);
87 ImGuiIO& io = ImGui::GetIO();
88 if (!io.Fonts->AddFontFromFileTTF(japanese_font_path.data(), ICON_FONT_SIZE,
89 &japanese_font_config,
90 io.Fonts->GetGlyphRangesJapanese())) {
91 return absl::InternalError(
"Failed to add Japanese fonts");
93 return absl::OkStatus();
99 if (font_registry.fonts.empty()) {
101 font_registry.fonts = {
102 {KARLA_REGULAR, FONT_SIZE_DEFAULT},
103 {ROBOTO_MEDIUM, FONT_SIZE_DEFAULT},
104 {COUSINE_REGULAR, FONT_SIZE_DEFAULT},
105 {IBM_PLEX_JP, FONT_SIZE_DEFAULT},
106 {DROID_SANS, FONT_SIZE_DROID_SANS},
111 for (
const auto& font_config : font_registry.fonts) {
116 return absl::OkStatus();
120 ImGuiIO& io = ImGui::GetIO();
121 std::string actual_font_path = SetFontPath(config.
font_path);
122 if (!io.Fonts->AddFontFromFileTTF(actual_font_path.data(),
124 return absl::InternalError(
125 absl::StrFormat(
"Failed to load font from %s", actual_font_path));
129 return absl::OkStatus();
135int CALLBACK EnumFontFamExProc(
const LOGFONT* lpelfe,
const TEXTMETRIC* lpntme,
136 DWORD FontType, LPARAM lParam) {
138 ImGuiIO& io = ImGui::GetIO();
139 io.Fonts->AddFontFromFileTTF(lpelfe->lfFaceName, 16.0f);
146 std::vector<std::string> fontPaths;
151 TEXT(
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), 0,
152 KEY_READ, &hKey) == ERROR_SUCCESS) {
154 DWORD maxValueNameSize;
155 DWORD maxValueDataSize;
158 RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &valueCount,
159 &maxValueNameSize, &maxValueDataSize, NULL, NULL);
161 char* valueName =
new char[maxValueNameSize + 1];
162 BYTE* valueData =
new BYTE[maxValueDataSize + 1];
165 for (DWORD i = 0; i < valueCount; i++) {
166 DWORD valueNameSize = maxValueNameSize + 1;
167 DWORD valueDataSize = maxValueDataSize + 1;
171 memset(valueName, 0, valueNameSize);
172 memset(valueData, 0, valueDataSize);
175 if (RegEnumValue(hKey, i, valueName, &valueNameSize, NULL, &valueType,
176 valueData, &valueDataSize) == ERROR_SUCCESS) {
177 if (valueType == REG_SZ) {
179 std::string fontPath(
reinterpret_cast<char*
>(valueData),
182 fontPaths.push_back(fontPath);
193 ImGuiIO& io = ImGui::GetIO();
196 static const std::unordered_set<std::string> commonFontFaceNames = {
208 "Lucida Sans Unicode",
212 for (
auto& fontPath : fontPaths) {
214 if (fontPath.substr(0, 2) !=
"C:") {
216 fontPath = absl::StrFormat(
"C:\\Windows\\Fonts\\%s", fontPath.c_str());
220 std::string extension = fontPath.substr(fontPath.find_last_of(
".") + 1);
221 if (extension ==
"ttf" || extension ==
"TTF") {
223 std::string fontFaceName =
224 fontPath.substr(fontPath.find_last_of(
"\\/") + 1);
225 fontFaceName = fontFaceName.substr(0, fontFaceName.find_last_of(
"."));
228 if (commonFontFaceNames.find(fontFaceName) != commonFontFaceNames.end()) {
229 io.Fonts->AddFontFromFileTTF(fontPath.c_str(), 16.0f);
233 static const ImWchar icons_ranges[] = {
ICON_MIN_MD, 0xf900, 0};
234 ImFontConfig icons_config;
235 static const float ICON_FONT_SIZE = 18.0f;
236 icons_config.MergeMode =
true;
237 icons_config.GlyphOffset.y = 5.0f;
238 icons_config.GlyphMinAdvanceX = 13.0f;
239 icons_config.PixelSnapH =
true;
241 &icons_config, icons_ranges);
247#elif defined(__linux__)
#define FONT_ICON_FILE_NAME_MD
#define RETURN_IF_ERROR(expression)
absl::Status AddIconFont(const FontConfig &config)
std::string SetFontPath(const std::string &font_path)
absl::Status AddJapaneseFont(const FontConfig &config)
absl::Status LoadFont(const FontConfig &font_config)
std::string GetBundleResourcePath()
GetBundleResourcePath returns the path to the bundle resource directory. Specific to MacOS.
absl::Status ReloadPackageFont(const FontConfig &config)
absl::Status LoadPackageFonts()
Main namespace for the application.