Skip to content

Commit 1906f15

Browse files
committed
wip
1 parent 168d26b commit 1906f15

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

devel/0101.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# [0101] Latin Modern Math 数学模式下希腊字母斜体问题修复
2+
3+
## 相关文档
4+
- [dddd.md](dddd.md) - 任务文档模板
5+
- [11_41.md](11_41.md) - Latin Modern Math 数学模式下希腊字母斜体问题修复
6+
- [11_42.md](11_42.md) - 相关任务文档
7+
- [11_44.md](11_44.md) - Unicode 根号下沉问题修复
8+
- [11_45.md](11_45.md) - Noto CJK SC 光标倾斜问题修复
9+
10+
## 任务相关的代码文件
11+
- `src/Graphics/Fonts/smart_font.cpp`
12+
- `tests/Graphics/Fonts/smart_font_test.cpp`
13+
14+
## 如何测试
15+
16+
### 确定性测试(单元测试)
17+
```bash
18+
xmake b smart_font_test
19+
xmake r smart_font_test
20+
```
21+
22+
新增 `test_latin_modern_math_italic_greek` 测试用例,验证在 `Latin Modern Math` 字体、`mathitalic` 模式下:
23+
- `<alpha>` 映射到 `<#1D6FC>`(数学斜体小写 alpha)
24+
- `<beta>` 映射到 `<#1D6FD>`(数学斜体小写 beta)
25+
- `<gamma>` 映射到 `<#1D6FE>`(数学斜体小写 gamma)
26+
27+
### 非确定性测试(文档验证)
28+
打开 Mogan,在数学模式下输入希腊字母(如 `\alpha``\beta``\gamma`),使用 Latin Modern Math 字体,确认希腊字母显示为斜体而非正体。
29+
30+
## 如何提交
31+
32+
提交前执行以下最少步骤:
33+
34+
```bash
35+
xmake b smart_font_test
36+
xmake r smart_font_test
37+
```
38+
39+
## What
40+
41+
修复 Latin Modern Math 字体在数学模式下希腊字母显示为正体而非斜体的问题。
42+
43+
1.`smart_font_rep::resolve` 中,当主字体支持原始希腊字符时,增加判断逻辑:若处于数学模式、字符为希腊字母、且当前 shape 不是 `mathupright`,则优先尝试使用斜体希腊字母码点(U+1D6E2+ 区域)。
44+
2. 只有当主字体不支持对应的斜体希腊字母码点时,才回退到原始码点。
45+
3. 新增 C++ 单元测试 `test_latin_modern_math_italic_greek`,通过 `advance` 函数验证 alpha、beta、gamma 的映射结果。
46+
47+
## Why
48+
49+
在数学模式下使用 Latin Modern Math 字体时:
50+
- 拉丁字母(a-z, A-Z)在 `advance` 中被硬编码映射到 Unicode 数学字母数字符号区(U+1D434+),显示为斜体。
51+
- 希腊字母(如 `<alpha>`)不在该硬编码映射中,进入 `resolve` 处理后直接使用基本希腊字母码点(U+03B1+)。Unicode 标准中基本希腊字母区块的默认字形为正体,导致数学模式下希腊字母显示为正体,与拉丁字母的斜体风格不一致。
52+
53+
对于 `roman``is_math_family` 字体,`REWRITE_MATH` 机制会将数学字符转换到正确的 Unicode 区域,因此正常。但 Latin Modern Math 未被纳入该机制。
54+
55+
## How
56+
57+
修改 `resolve` 函数中 `fn[SUBFONT_MAIN]->supports (c)` 分支的逻辑:
58+
59+
```cpp
60+
bool prefer_italic_greek= false;
61+
if (math_kind != 0 && is_greek (c) && use_italic_greek (a) &&
62+
shape != "mathupright") {
63+
string gc= substitute_italic_greek (c);
64+
if (gc != "" && fn[SUBFONT_MAIN]->supports (gc)) {
65+
prefer_italic_greek= true;
66+
}
67+
}
68+
if (!prefer_italic_greek) {
69+
return sm->add_char (tuple ("main"), c);
70+
}
71+
```
72+
73+
`prefer_italic_greek` 为 true 时,不直接返回 "main" 子字体,而是继续执行后续逻辑。后续代码(约 1189 行)会检测到希腊字母并通过 `substitute_italic_greek` 将其映射到数学斜体希腊字母区域(U+1D6E2+),从而确保 Latin Modern Math 渲染出斜体字形。
74+
75+
测试用例通过 `advance` 函数间接验证:
76+
- `advance` 在处理 `<alpha>` 等希腊字母时会调用 `resolve`
77+
- `resolve` 中的斜体优先逻辑使最终返回的字符被重写为 `<#1D6FC>` 等斜体码点

src/Graphics/Fonts/smart_font.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,17 @@ smart_font_rep::resolve (string c) {
11411141
string range= get_unicode_range (c);
11421142
// 如果设置了字体,就优先使用当前设置的字体
11431143
if (fn[SUBFONT_MAIN]->supports (c)) {
1144-
return sm->add_char (tuple ("main"), c);
1144+
bool prefer_italic_greek= false;
1145+
if (math_kind != 0 && is_greek (c) && use_italic_greek (a) &&
1146+
shape != "mathupright") {
1147+
string gc= substitute_italic_greek (c);
1148+
if (gc != "" && fn[SUBFONT_MAIN]->supports (gc)) {
1149+
prefer_italic_greek= true;
1150+
}
1151+
}
1152+
if (!prefer_italic_greek) {
1153+
return sm->add_char (tuple ("main"), c);
1154+
}
11451155
}
11461156

11471157
if (range == "emoji") {

tests/Graphics/Fonts/smart_font_test.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private slots:
3535
void test_resolve_first_attempt ();
3636
void test_resolve_chinese_puncts ();
3737
void test_get_right_slope ();
38+
void test_latin_modern_math_italic_greek ();
3839
};
3940

4041
void
@@ -103,5 +104,34 @@ TestSmartFont::test_get_right_slope () {
103104
QCOMPARE (fn_rep->get_right_slope (utf8_to_cork ("")), 0.0);
104105
}
105106

107+
void
108+
TestSmartFont::test_latin_modern_math_italic_greek () {
109+
font fn= smart_font ("Latin Modern Math", "rm", "medium", "mathitalic", 10,
110+
600);
111+
smart_font_rep* fn_rep= (smart_font_rep*) fn.rep;
112+
113+
int pos;
114+
string r;
115+
int nr;
116+
117+
// Test alpha in mathitalic mode should map to math italic alpha (U+1D6FC)
118+
pos= 0;
119+
fn_rep->advance ("<alpha>", pos, r, nr);
120+
QCOMPARE (pos, N (string ("<alpha>")));
121+
qcompare (r, "<#1D6FC>");
122+
123+
// Test beta in mathitalic mode should map to math italic beta (U+1D6FD)
124+
pos= 0;
125+
fn_rep->advance ("<beta>", pos, r, nr);
126+
QCOMPARE (pos, N (string ("<beta>")));
127+
qcompare (r, "<#1D6FD>");
128+
129+
// Test gamma in mathitalic mode should map to math italic gamma (U+1D6FE)
130+
pos= 0;
131+
fn_rep->advance ("<gamma>", pos, r, nr);
132+
QCOMPARE (pos, N (string ("<gamma>")));
133+
qcompare (r, "<#1D6FE>");
134+
}
135+
106136
QTEST_MAIN (TestSmartFont)
107137
#include "smart_font_test.moc"

0 commit comments

Comments
 (0)