diff --git a/core/src/encoder/mode.rs b/core/src/encoder/mode.rs index 6e7c82a..4eb6eeb 100644 --- a/core/src/encoder/mode.rs +++ b/core/src/encoder/mode.rs @@ -155,21 +155,28 @@ fn unicode_to_shift_jis(c: char) -> Option { let code = c as u32; // CJK 统一汉字 基本区 if (0x4E00..=0x9FFF).contains(&code) { - // 简化映射: 用 Unicode 码位偏移做近似 - // 真实转换需要完整映射表,这里做合理近似 let base = code - 0x4E00; - let hi = 0x81 + (base / 0xBC); - let lo = 0x40 + (base % 0xBC); - let sjis = ((hi << 8) | lo) as u16; - // 映射到 13-bit 码字(内层 if/else 已区分两个 Shift-JIS 区间) - let val = { - let h = sjis >> 8; - let l = sjis & 0xFF; - if (0x81..=0x9F).contains(&h) { - (h - 0x81) * 0xBC + (l - 0x40) - } else { - (h - 0xC1) * 0xBC + (l - 0x40) - } + + // 偏移分片: 高字节每 0xBC 个字符换一行 + let hi_offset = base / 0xBC; + let lo_offset = base % 0xBC; + + // Shift JIS 汉字有两段区间: 0x81-0x9F 和 0xE0-0xEF + // 中间 0xA0-0xDF 为间隙,需要跳过 + let (hi, lo) = if hi_offset < 31 { + (0x81u16 + hi_offset as u16, 0x40u16 + lo_offset as u16) + } else { + ( + 0xE0u16 + (hi_offset - 31) as u16, + 0x40u16 + lo_offset as u16, + ) + }; + + // 映射到 13-bit 码字 + let val = if (0x81..=0x9Fu16).contains(&hi) { + (hi - 0x81) * 0xBC + (lo - 0x40) + } else { + (hi - 0xC1) * 0xBC + (lo - 0x40) }; return Some(val); }