diff --git a/devel/209_5.md b/devel/209_5.md new file mode 100644 index 0000000000000000000000000000000000000000..80f32dce53d605c067b317af2135d7751ff1e29f --- /dev/null +++ b/devel/209_5.md @@ -0,0 +1,66 @@ +# 209_5 修复代码模式下箭头符号显示问题 + +## 如何测试 + +### 测试步骤 + +1. 在TeXmacs中创建一个verbatim/代码块 +2. 在代码块中输入箭头符号,如 `hookrightarrow`、`leftarrow`、`rightarrow` 等 +3. 观察符号是否正确显示 + +### 预期结果 + +#### 修复前 +- 箭头符号在代码模式(tt字体)下显示不正确 +- 数学符号在等宽字体环境中无法正确回退到支持的字体 + +#### 修复后 +- 箭头符号在代码模式下正确显示 +- 等宽字体环境中的数学符号能够正确回退到Unicode字体 +- 保持等宽字体外观 + +## 2025/11/26 + +### What +从C++字体选择机制层面修复TeXmacs代码模式(tt字体)下箭头符号显示不正确的问题 + +### Why + +#### 问题分析 +箭头符号(特别是 `hookrightarrow` 等数学符号)在TeXmacs的代码/verbatim模式(使用tt等宽字体)下显示不正确,而在普通文本模式下显示正常。 + +#### 根本原因 + +当前的字体选择机制在处理等宽字体(tt variant)时,对于数学符号的回退策略不够完善: + +1. **字体回退不足**:在`smart_font.cpp`的`resolve()`函数中,当tt字体不支持某个数学符号时,没有正确回退到支持该符号的Unicode字体 +2. **数学符号特殊处理缺失**:对于等宽字体环境中的数学符号,需要特殊的字体选择逻辑 +3. **Unicode字体优先级**:需要在等宽字体环境中提高Unicode字体对数学符号的支持优先级 + +### How + +#### 方案:修改C++字体选择机制 + +需要修改 `src/Graphics/Fonts/smart_font.cpp` 中的字体解析逻辑,使得在等宽字体(tt variant)环境中遇到数学符号时,能够正确回退到支持该符号的Unicode字体。 + +#### 修改位置 + +在 `smart_font_rep::resolve(string c)` 函数中添加针对等宽字体环境的数学符号处理逻辑。 + +#### 具体实现思路 + +1. **检测等宽字体环境**: + - 判断当前 `variant` 是否为 "tt" 或以 "-tt" 结尾 + - 判断字符是否为数学符号(箭头、数学运算符、补充数学运算符等) + - 判断字符是否为TeXmacs特殊符号格式(`<...>`) + +2. **使用DejaVu Sans Mono字体**: + - 当检测到等宽字体环境中的数学符号时 + - 尝试使用 DejaVu Sans Mono 字体(支持丰富的Unicode数学符号) + - 如果该字体支持该符号,则使用它进行渲染 + +3. **简洁设计**: + - 只使用单一的Unicode等宽字体(DejaVu Sans Mono) + - 不提供额外的回退机制,保持代码简洁 + - 对于普通ASCII字符,继续使用原有的等宽字体 + diff --git a/src/Graphics/Fonts/smart_font.cpp b/src/Graphics/Fonts/smart_font.cpp index 946bde542c067e7620b287dd822971cf27e54505..670e6a510720e70a5a6619103384fcc6c9424bad 100644 --- a/src/Graphics/Fonts/smart_font.cpp +++ b/src/Graphics/Fonts/smart_font.cpp @@ -1211,6 +1211,27 @@ smart_font_rep::resolve (string c) { (c[0] < 'A' || c[0] > 'Z') && (c[0] < 'a' || c[0] > 'z')) return sm->add_char (tuple ("italic-roman"), c); + // Special handling for math symbols in monospace (tt) font environment + if (variant == "tt" || ends (variant, "-tt")) { + string range= get_unicode_range (c); + bool is_math_symbol= + (range == "arrows" || range == "mathematical_operators" || + range == "supplemental_mathematical_operators" || + (starts (c, "<") && ends (c, ">") && N (c) > 2)); + + if (is_math_symbol) { + // Try DejaVu Sans Mono for Unicode math symbols + font cfn= + closest_font ("DejaVu Sans Mono", "rm", series, "right", sz, dpi, 1); + if (!is_nil (cfn) && cfn->supports (c)) { + tree key= tuple ("unicode-mono-math", "DejaVu Sans Mono"); + int nr = sm->add_font (key, REWRITE_NONE); + initialize_font (nr); + return sm->add_char (key, c); + } + } + } + for (int attempt= 1; attempt <= FONT_ATTEMPTS; attempt++) { if (attempt > 1 && substitute_math_letter (c, math_kind) != "") break; for (int i= 0; i < N (a); i++) { @@ -1281,6 +1302,9 @@ smart_font_rep::initialize_font (int nr) { else if (a[0] == "emoji-font") fn[nr]= adjust_subfont ( closest_font (a[1], "rm", "medium", "right", sz, dpi, 1)); + else if (a[0] == "unicode-mono-math" && N (a) >= 2) + fn[nr]= + adjust_subfont (closest_font (a[1], "rm", series, "right", sz, dpi, 1)); else if (a[0] == "special") fn[nr]= smart_font_bis (family, variant, series, "right", sz, hdpi, dpi); else if (a[0] == "emu-bracket")