Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions TeXmacs/tests/tmu/0109.tmu
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<TMU|<tuple|1.1.0|2026.2.4>>

<style|<tuple|generic|chinese|table-captions-above|number-europe|preview-ref>>

<\body>
<\big-table|<block|<tformat|<table|<row|<cell|>|<cell|>|<cell|>>|<row|<cell|>|<cell|<subtable|<tformat|<cwith|1|-1|1|-1|cell-tborder|1ln>|<cwith|1|-1|1|-1|cell-bborder|1ln>|<cwith|1|-1|1|-1|cell-lborder|1ln>|<cwith|1|-1|1|-1|cell-rborder|1ln>|<table|<row|<cell|>|<cell|>>|<row|<cell|>|<cell|>>>>>>|<cell|>>|<row|<cell|>|<cell|这是一个单元格>|<cell|>>>>>>
\;
</big-table>
</body>

<\initial>
<\collection>
<associate|page-medium|paper>
<associate|page-screen-margin|false>
</collection>
</initial>

<\references>
<\collection>
<associate|auto-1|<tuple|1|1>>
</collection>
</references>

<\auxiliary>
<\collection>
<\associate|table>
<tuple|normal|<\surround|<hidden-binding|<tuple>|1>|>
\;
</surround>|<pageref|auto-1>>
</associate>
</collection>
</auxiliary>
65 changes: 65 additions & 0 deletions devel/0109.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# [0109] 修复子表格编辑辅助线与外部表格的间隙问题

## 相关文档
- [dddd.md](dddd.md) - 任务文档模板
- [0403.md](0403.md) - 相关任务文档(合并单元格后编辑线条重叠问题)

## 任务相关的代码文件
- `src/Typeset/Table/table.cpp`
- `src/Typeset/Table/cell.cpp`
- `src/Edit/Interface/edit_interface.cpp`

## 如何测试

### 确定性测试(单元测试)
```bash
# 无单元测试
```

### 非确定性测试(文档验证)
测试文档:`TeXmacs/tests/tmu/0109.tmu`

```bash
# 编译并运行 Mogan,打开 TeXmacs/tests/tmu/0109.tmu
# 确保「编辑 -> 首选项 -> 其他 -> 显示表格单元格」已开启
# 将光标放入中间单元格的子表格中
# 观察子表格的编辑辅助细线(env_rects)与外部 3x3 表格的中间单元格边框是否完全重合
# 修复前:子表格边框与外部单元格边框之间存在微小间隙
# 修复后:两者应完全重合,无间隙
```

## 如何提交

提交前执行以下最少步骤:

```bash
# 运行代码格式化
bin/format

# 确认修改仅涉及指定文件
git diff --stat
```

## What

修复在编辑状态下,嵌套于单元格中的子表格辅助边框线与外部单元格边框线未完全重合、存在间隙的问题。

1. 在 `cell.cpp` 处理 `SUBTABLE` 时,当前代码虽然将子表格所在单元格的 `lsep/rsep/bsep/tsep` 显式设为 0,但传入 `typeset_subtable` 的 `var` 仍可能携带父单元格的 `CELL_LSEP`/`CELL_RSEP`/`CELL_BSEP`/`CELL_TSEP` 等格式变量。
2. 子表格通过 `inherited_format(var)` 继承这些变量,导致子表格内部单元格的默认 `lsep`/`rsep` 等使用 `env->fn->spc->def`(非零默认值),而非与父单元格一致的 0 值。
3. 这使得子表格内部单元格的排版边界与外部单元格的边界产生偏移,在 `compute_env_rects` 绘制的编辑辅助线(env_rects)上表现为子表格边框与外部单元格边框之间的可见间隙。
4. 修复方式:在 `cell.cpp` 的 `typeset` 函数中,构造子表格前,从传入的 `var` 中显式移除 `CELL_LSEP`、`CELL_RSEP`、`CELL_BSEP`、`CELL_TSEP` 键,确保子表格内部单元格不继承父单元格的 sep 值,从而使其边框与外部单元格边框完全重合。

## Why

在无框表格中,用户期望子表格能够完全贴合父单元格的边界。当前实现虽然将子表格所在单元格本身的 sep 设为 0,但通过 `inherited_format` 机制,子表格内部单元格仍继承了父单元格的 sep 格式变量(或环境默认值)。这些额外的 padding 导致子表格内容的排版范围与父单元格边界不一致,在编辑辅助线渲染时产生可见间隙,影响视觉体验。

## How

在 `src/Typeset/Table/cell.cpp` 的 `cell_rep::typeset` 函数中,处理 `SUBTABLE` 的分支内,于调用 `typeset_subtable` 之前,从 `var` 中移除以下键:

- `CELL_LSEP`
- `CELL_RSEP`
- `CELL_BSEP`
- `CELL_TSEP`

这样 `inherited_format(var)` 将不会把这些 sep 值传递给子表格,子表格内部单元格将使用与父单元格一致的 sep=0,确保两者边框重合。
28 changes: 21 additions & 7 deletions src/Typeset/Table/cell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ cell_rep::typeset (tree fm, tree t, path iq) {
cell_local_begin (fm);
if (is_func (t, SUBTABLE, 1)) {
lsep= rsep= bsep= tsep= 0;
T = table (env, 2);
var->reset (CELL_LSEP);
var->reset (CELL_RSEP);
var->reset (CELL_BSEP);
var->reset (CELL_TSEP);
T= table (env, 2);
T->typeset_subtable (t[0], descend (iq, 0), var);
}
else if (is_func (t, DOCUMENT, 1) && is_func (t[0], SUBTABLE, 1)) {
lsep= rsep= bsep= tsep= 0;
T = table (env, 2);
var->reset (CELL_LSEP);
var->reset (CELL_RSEP);
var->reset (CELL_BSEP);
var->reset (CELL_TSEP);
T= table (env, 2);
T->typeset_subtable (t[0][0], descend (descend (iq, 0), 0), var);
}
else {
Expand Down Expand Up @@ -386,7 +394,7 @@ cell_rep::position_horizontally (SI offset, SI mw, SI lw, SI rw) {
else xoff= lw;
if (N (halign) > 1) xoff-= b->get_leaf_offset (halign (1, N (halign)));
}
else xoff= -T->x1 + lborder;
else xoff= -T->x1;
}

void
Expand All @@ -404,7 +412,7 @@ cell_rep::position_vertically (SI offset, SI mh, SI bh, SI th) {
else if (align_c == 'T') yoff= mh - th;
else yoff= bh;
}
else yoff= -T->y1 + bborder;
else yoff= -T->y1;
}

/******************************************************************************
Expand Down Expand Up @@ -452,7 +460,13 @@ cell_rep::finish () {
b= T->b;
}

b= cell_box (ip, b, xoff, yoff, 0, 0, x2 - x1, y2 - y1, lborder, rborder,
bborder, tborder, dborder, aborder, env->pen->get_brush (),
brush (bg, env->alpha));
if (!is_nil (T)) {
b= cell_box (ip, b, xoff, yoff, 0, 0, x2 - x1, y2 - y1, 0, 0, 0, 0, 0, 0,
env->pen->get_brush (), brush (bg, env->alpha));
}
else {
b= cell_box (ip, b, xoff, yoff, 0, 0, x2 - x1, y2 - y1, lborder, rborder,
bborder, tborder, dborder, aborder, env->pen->get_brush (),
brush (bg, env->alpha));
}
}
16 changes: 12 additions & 4 deletions src/Typeset/Table/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,18 @@ table_rep::merge_borders () {
kk= ii * hh + jj;
bb= max (verb[kk], bb);
}
C->lborder= lb;
C->rborder= rb;
C->bborder= bb;
C->tborder= tb;
if (!is_nil (C->T)) {
C->lborder= 0;
C->rborder= 0;
C->bborder= 0;
C->tborder= 0;
}
else {
C->lborder= lb;
C->rborder= rb;
C->bborder= bb;
C->tborder= tb;
}
}
}
}
Expand Down
Loading