Skip to content

Commit 4edef63

Browse files
authored
fix(shell): 修复 #367 - 使用 msyh.ttc 时部分菜单项显示 "□"
原 apply_fonts_to_nvg 委托给 ui::register_default_windows_font_suite, 其回退链设计假设 main=Segoe UI(Latin) + fallback=msyh(CJK)。 当用户把 main 改成 msyh.ttc 时,main 和 fallback 两条线都指向 msyh.ttc, 没有任何拉丁/符号字体兜底。Shell 扩展菜单项中混入了少量特殊 Unicode 字符(不在 msyh.ttc 中),原本指望 Segoe UI 兜底,现在 兜底没了,直接渲染成 .notdef → "□"。 另外 msyh.ttc 集合里 index=1 是「Microsoft YaHei UI」, 字面度量和字形都更贴 UI 场景;之前的实现始终用 index=0 「Microsoft YaHei」普通版,菜单里看着略偏大、有些字间距也对不齐。 变更: - src/shell/config.cc: 重写 apply_fonts_to_nvg - 新增独立的 "segoeui" 字体族,从系统字体目录直接加载 segoeui.ttf 及其字重变体(semilight / light / semibold / bold) - "fallback" 的 fallback_families 设为 {"segoeui"},确保兜底 - "main" 的 fallback_families 设为 {"segoeui", "fallback"}, 改 CJK 字体也不会再丢掉拉丁/符号覆盖 - "monospace" 的 fallback_families 设为 {"main", "segoeui", "fallback"} - 检测到 fallback 路径是 msyh.ttc 时 collection_index=1 (选 YaHei UI 而非普通 YaHei) - src/shell/config.cc: 新增 <cctype> 头(用 std::tolower 做大小写不敏感匹配) close #367
1 parent ac46f97 commit 4edef63

1 file changed

Lines changed: 106 additions & 4 deletions

File tree

src/shell/config.cc

Lines changed: 106 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "config.h"
2+
#include <cctype>
23
#include <chrono>
34
#include <filesystem>
45
#include <fstream>
@@ -156,10 +157,111 @@ std::filesystem::path config::default_mono_font() {
156157
"consola.ttf";
157158
}
158159
void config::apply_fonts_to_nvg(NVGcontext *nvg) {
159-
ui::register_default_windows_font_suite(
160-
nvg, {.main_regular = {.path = font_path_main},
161-
.fallback_regular = {.path = font_path_fallback},
162-
.monospace_regular = {.path = font_path_monospace}});
160+
auto font_dir = ui::windows_font_directory();
161+
162+
auto to_lower = [](std::string s) {
163+
for (auto &c : s)
164+
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
165+
return s;
166+
};
167+
168+
auto add_with_system_variants =
169+
[&](std::vector<ui::weighted_font_face> &faces,
170+
const std::filesystem::path &user_path, const char *expected_name,
171+
int collection_index = 0) {
172+
if (user_path.empty())
173+
return;
174+
faces.push_back(
175+
{.weight = 400,
176+
.source = {.path = user_path,
177+
.collection_index = collection_index}});
178+
179+
if (to_lower(user_path.filename().string()) !=
180+
to_lower(expected_name))
181+
return;
182+
183+
struct variant_entry {
184+
int weight;
185+
const char *file;
186+
};
187+
const variant_entry *variants = nullptr;
188+
int variant_count = 0;
189+
190+
// clang-format off
191+
if (to_lower(expected_name) == "segoeui.ttf") {
192+
static constexpr variant_entry v[] = {
193+
{200, "segoeuisl.ttf"}, {300, "segoeuil.ttf"},
194+
{600, "seguisb.ttf"}, {700, "segoeuib.ttf"},
195+
};
196+
variants = v; variant_count = 4;
197+
} else if (to_lower(expected_name) == "msyh.ttc") {
198+
static constexpr variant_entry v[] = {
199+
{300, "msyhl.ttc"}, {700, "msyhbd.ttc"},
200+
};
201+
variants = v; variant_count = 2;
202+
} else if (to_lower(expected_name) == "consola.ttf") {
203+
static constexpr variant_entry v[] = {
204+
{700, "consolab.ttf"},
205+
};
206+
variants = v; variant_count = 1;
207+
}
208+
// clang-format on
209+
210+
for (int i = 0; i < variant_count; ++i) {
211+
auto p = font_dir / variants[i].file;
212+
if (std::filesystem::exists(p))
213+
faces.push_back(
214+
{.weight = variants[i].weight,
215+
.source = {.path = std::move(p),
216+
.collection_index = collection_index}});
217+
}
218+
};
219+
220+
// 1. System Segoe UI – always available as ultimate fallback
221+
{
222+
std::vector<ui::weighted_font_face> faces;
223+
add_with_system_variants(faces, font_dir / "segoeui.ttf",
224+
"segoeui.ttf");
225+
ui::register_font_family(nvg, {.family_name = "segoeui",
226+
.faces = faces});
227+
}
228+
229+
// 2. Fallback font (user-configured) – falls back to segoeui
230+
// For msyh.ttc use collection_index=1 → "Microsoft YaHei UI"
231+
{
232+
int fb_idx = 0;
233+
if (to_lower(font_path_fallback.filename().string()) == "msyh.ttc")
234+
fb_idx = 1;
235+
236+
std::vector<ui::weighted_font_face> faces;
237+
add_with_system_variants(faces, font_path_fallback, "msyh.ttc",
238+
fb_idx);
239+
ui::register_font_family(
240+
nvg, {.family_name = "fallback",
241+
.faces = faces,
242+
.fallback_families = {"segoeui"}});
243+
}
244+
245+
// 3. Main font (user-configured) – falls back to segoeui + fallback
246+
{
247+
std::vector<ui::weighted_font_face> faces;
248+
add_with_system_variants(faces, font_path_main, "segoeui.ttf");
249+
ui::register_font_family(
250+
nvg, {.family_name = "main",
251+
.faces = faces,
252+
.fallback_families = {"segoeui", "fallback"}});
253+
}
254+
255+
// 4. Monospace font (user-configured) – falls back to main + segoeui +
256+
// fallback
257+
{
258+
std::vector<ui::weighted_font_face> faces;
259+
add_with_system_variants(faces, font_path_monospace, "consola.ttf");
260+
ui::register_font_family(
261+
nvg, {.family_name = "monospace",
262+
.faces = faces,
263+
.fallback_families = {"main", "segoeui", "fallback"}});
264+
}
163265
}
164266
void config::animated_float_conf::apply_to(ui::animated_color &anim,
165267
float delay) {

0 commit comments

Comments
 (0)