Skip to content

fix(xeCJK): 修复 fntef 周期装饰的相位与接点#1024

Open
Liam0205 wants to merge 5 commits into
masterfrom
fix/1012-fntef-decoration-overlap
Open

fix(xeCJK): 修复 fntef 周期装饰的相位与接点#1024
Liam0205 wants to merge 5 commits into
masterfrom
fix/1012-fntef-decoration-overlap

Conversation

@Liam0205

@Liam0205 Liam0205 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

问题

xeCJKfntef 基于 ulem 把正文拆成多个装饰片段。原来的
\CJKunderwave 使用固定字号的 lasy6 波浪符号,\CJKxout 使用数学字体中的
斜线;装饰单元的宽度与正文字号、字宽和实际伸缩后的 CJKglue 没有稳定比例。
正文片段、中文字间距和命令端点又会分别排出 leaders,因此在字符、标点、相邻命令和
换行处可能出现相位跳变、局部过密、连接断开或左右不均。

这个问题同时有三项约束:同一行的波浪线或斜线必须共享相位;相邻带 - 命令之间
必须有明确断口;整段装饰必须始终相对正文居中。只清零 \UL@pixel、只缩短图案周期,
或只更换 leader 类型,都不能同时满足这三项约束。

下面三张图由同一份单页 MWE编译得到。三次编译使用相同的字体、字号、正文、150 mm × 105 mm 页面和 600 dpi 渲染;三张 PNG 都是 3544 × 2481 像素,差别只有所加载的 xeCJK 提交。

修复前(01d5624a 不完整的普通 \leaders 方案(bd3edb54 本 PR 的处理(44a7be68
固定宽度图案在片段接点处重叠或变密 相位统一了,但端点不精确,带 - 命令之间没有断口 共享相位,并分别控制端点和可断行接点

修改

  • 默认波浪线和斜删除线改用 l3draw 绘制宽 1em/4 的图案;振幅、高度和线宽随
    当前 em 缩放,常规全角字符每字约容纳四个周期,斜删除线不再依赖数学字体。
  • 两个默认图案都使用普通 \leaders。正文片段、固定或伸缩后的 CJKglue 以及
    换行后的片段落在同一个相位网格上;外层水平位移不会让各片段重新选择相位。
  • 首段和真正的末段在 leaders 区间两侧各多画一个周期,再用局部 PDF 裁切限制
    可见范围。普通形式相对正文左右各外伸半周期;带 - 形式左右各内缩半周期。
    两种形式都不改变正文宽度和断行,相邻带 - 命令之间恰好留下一个周期的断口。
  • - 形式首段后的第一个可断 CJKglue,在断点两侧各放一个净宽为零的半周期
    连接。不换行时两半相接;换行时分别止于上一行末尾和下一行开头。裁切内部的
    leaders 前加入 penalty 10000,避免 PDF 的 gsavegrestore 被拆到两行。
  • ulem 会追加随后删除的结尾语法空格;实现结合 \UL@spfactor 哨兵与装饰片段
    宽度区分它、正文中的真实源码空格和普通后续片段。空参数、空分组以及不产生节点的
    正文继续保持零宽、零高、零深,不会凭空留下一个装饰周期;真实源码空格仍按原宽度
    排版并绘制装饰。
  • l3draw 会把负纵坐标归一化成盒子高度,绘图盒本身的 depth 为零。默认斜线约高
    .93em,使用时整体下移 .09em,实际覆盖约为基线下 .09em 至基线上 .84em
    使斜线同时覆盖常见全角汉字的高度和深度。
  • 普通 \quad、显式 \hskipCJKglue 都继续使用普通 leaders 路径。
    underwave/symbol 只有保持默认值时才进入上述处理;用户自定义波浪符号继续使用
    历史 \xleaders 行为。

字体、字号和伸缩胶水

补充矩阵 MWE覆盖:

  • Noto Serif CJK SC Regular 的 8pt、10.53937pt 和 15pt;
  • Noto Sans CJK SC Regular/Black;
  • 普通形式和相邻的带 - 形式;
  • 8.5em 窄行中实际伸缩的 CJKglue 和换行。

在这组常见全角 CJK 字体中,字体和字重主要影响异常是否醒目;字号、非一 em 字宽、
标点、特殊盒子和实际胶水宽度会直接参与几何计算。本 PR 不要求伸缩后的 CJKglue
恰好是图案周期的整数倍。

验证

  • fntef-phase01 把 XDV 转为不压缩 PDF,再由 Lua 读取页面横坐标,检查相位、普通/
    - 形式的对称端点、固定/伸缩胶水、相邻命令断口和普通显式跳距。
  • fntef-underline-offset 固定真正的 l3draw 图案在 8pt、10.53937pt、15pt 下的
    宽、高、深;同时检查空参数、空分组、不产生节点的正文和真实源码空格。节点与换行
    回归使用同尺寸轻量盒子检查 leaders、裁切结构和断行行为。
  • xeCJK:l3build check,113/113 通过。
  • l3build doc 通过,生成 243 页 xeCJK.pdf 和 51 页
    xunicode-symbols.pdf;日志确认加载工作树生成的 xeCJKfntef.sty
  • 普通 PDF 与启用 tagging 的同一 MWE,在 pdftotext -raw-layout 下都只包含
    正文,没有波浪线、斜线或自定义装饰字符。
  • git diff --check 通过。

Closes #1012

@Liam0205
Liam0205 requested a review from a team as a code owner July 25, 2026 18:01
@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 审查

项目 结果
结论 APPROVE
审查范围 01d5624a24a336c0f5bbfbbb2aa5bbd983892231...d75a1fd135fd244feccfbfce9825658ee7f4a69d

未发现需要修改的问题。无重叠路径仅作用于波浪线和斜删除线,普通形式、减号形式的端点处理及窄片段保护逻辑一致;新增回归覆盖了标点、字号、换行、弹性间距和宽图案配窄正文等关键场景。

验证说明

已完成完整 diff、相关 ulem 调用路径、测试输入与预期基线的静态审计,并通过 git diff --check。当前 runner 未安装 kpsewhich/TeX 工具链,因此无法在本地执行 l3build 回归测试。


本次审查由 Codex 主链路 (gpt-5.6-sol) 完成。

@Liam0205

Copy link
Copy Markdown
Contributor Author

已核实,Bot 未提出需要修改的问题。补充运行证据:固定提交 d75a1fd1 已在本地 TeX 环境通过 xeCJK 112/112、ctex 185/185、CHANGELOG 确定性检查、测试文件 lint、git diff --check、同一单页 MWE 的修复前后 600 dpi 视觉比对,以及最终 l3build docxeCJK.pdf 240 页、xunicode-symbols.pdf 51 页)。因此不需要追加代码改动。

@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 审查

项目 结果
结论 APPROVE
审查范围 01d5624a24a336c0f5bbfbbb2aa5bbd983892231...187fdcf1c7bf6457f675d945464e1b49a295ba24

未发现需要修改的问题。周期装饰的内部重叠已被清零,减号形式的首尾留白也得到保留;新增回归覆盖了跨行、标点、不同字号、相邻装饰及窄片段场景。

验证限制

尝试运行 xeCJK 的相关 l3build check,但当前 runner 未安装 l3build,因此未能执行测试;本次结论基于源码、完整 diff、测试输入及预期基线的静态核查。


本次审查由 Codex 主链路 (gpt-5.6-sol) 完成。

@Liam0205 Liam0205 changed the title fix(xeCJK): 避免 fntef 周期装饰在字间重叠 fix(xeCJK): 按字号重绘 fntef 波浪线和斜删除线 Jul 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 审查

项目 结果
结论 APPROVE
审查范围 01d5624a24a336c0f5bbfbbb2aa5bbd983892231...ee8e27594b4888a8cf8609385ecbe4567b1ea322

未发现需要修改的问题。新的波浪线与斜删除线单元按字号缩放,并保留既有的 leaders 与端点几何;l3draw 加载及依赖声明、用户文档和分层回归测试也已同步。

验证说明

已检查完整 diff 与工作树、相关调用路径、测试基线及 git diff --check;本地提供的 diff 与指定提交范围完全一致。当前 runner 未安装 TeX、XeTeX 和 l3build,因此未能实际执行 xeCJK 回归测试。


本次审查由 Codex 主链路 (gpt-5.6-sol) 完成。

@Liam0205

Copy link
Copy Markdown
Contributor Author

已核实,本轮 Bot 审查没有提出 blocking、important 或 minor 问题。补充其 runner 缺少 TeX 工具链的验证缺口:固定提交 ee8e2759 已在断网的独立快照中通过 xeCJK 112/112、安装当前快照 xeCJK 与 zhnumber 后的 ctex 185/185、l3build docxeCJK.pdf 240 页、xunicode-symbols.pdf 51 页)、CHANGELOG 字节新鲜度、依赖映射和 git diff --check。上下文隔离的最终全范围审查为 0/0/0,终局证据审计也已 PASS。因此不需要追加代码改动。

@Liam0205 Liam0205 changed the title fix(xeCJK): 按字号重绘 fntef 波浪线和斜删除线 fix(xeCJK): 分离 fntef 周期装饰接点 Jul 27, 2026
@Liam0205
Liam0205 force-pushed the fix/1012-fntef-decoration-overlap branch from ee8e275 to b836d8e Compare July 27, 2026 01:52
@Liam0205
Liam0205 marked this pull request as ready for review July 27, 2026 02:10
@Liam0205 Liam0205 changed the title fix(xeCJK): 分离 fntef 周期装饰接点 fix(xeCJK): 修复 fntef 周期装饰的相位与接点 Jul 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 审查

项目 结果
结论 REQUEST_CHANGES
审查范围 01d5624a24a336c0f5bbfbbb2aa5bbd983892231...13e8b82f1af58ad019c415f34f85aee8a88febc2

周期装饰的常规路径覆盖较完整,但新增末段状态不能安全支持项目已声明允许的 fntef 嵌套。

重要建议 (1)

  • xeCJK/xeCJK.dtx: \g_@@_ulem_periodic_later_bool 在每个周期装饰开始时被全局清零,并在结束时决定是否重画末段;因此内层 \CJKunderwave\CJKxout 会覆盖外层状态。例如外层已经产生后续片段后,若末尾嵌入一个只有单片段的周期装饰,内层会将该值留为 false,外层结束时便跳过末段重画,右端重新依赖普通 \leaders 的完整盒取整,无法保证承诺的半周期端点。请将该状态改为按嵌套层保存/恢复或局部持有,并增加周期装饰互相嵌套且内层位于外层末尾的端点回归。(代码链接)
验证限制

已完成完整 diff、当前工作树及相关 llmdoc 的静态审查,并执行 git diff --check(通过)。runner 未安装 l3build/TeX,因此无法在本地执行新增的 xeCJK 定向回归;这不影响上述共享全局状态问题的代码路径判断。


本次审查由 Codex 主链路 (gpt-5.6-sol) 完成。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

xeCJKfntef: 删除线/下划线存在重叠

1 participant