Files
broccoliandClaude Sonnet 5 1d17b5e20d Rework layout engine around exact-glyph collision, add tests and docs sync
Replace the old bbox/heuristic placement (scale search rounds, large-font
capping, stratified sampling, fill-retry ladders) with an area-model font
sizing pass feeding a C++ exact-glyph collision engine (centroid-biased
spiral + random probing, HD clearance refinement, density/hole
optimization). Simplify the frontend advanced-params panel and JobParams
type to match the surviving config surface, add a layout-constraints test
suite and a repeatable benchmark tool, and bring docs/*.md back in sync
with current code (plus new TESTING.md and DEPLOYMENT.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 18:32:25 +08:00

110 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 测试与基准
本文档覆盖当前代码中的测试工具和基准脚本。
## 单元测试
位置:`backend/tests/test_layout_constraints.py`
运行方式:
```bash
cd backend
python -m pytest tests/test_layout_constraints.py -v
```
测试矩阵(基于 `unittest`,不依赖外部服务):
| 测试 | 目的 |
|------|------|
| `test_size_ratio_one_keeps_every_equal_weight_size_identical` | `SIZE_RATIO=1` 时所有同权重词字号完全相同 |
| `test_explicit_equal_min_max_is_exact` | `USER_MIN=USER_MAX=12` 时所有词精确为 `12px` |
| `test_same_weight_groups_receive_the_same_size` | 相同权重组内字号一致;权重组间字号递增 |
| `test_stroke_weight_is_applied_when_excel_weights_are_flat` | Excel 权重全为 `1` 时,笔画权重仍能产生区分度 |
| `test_largest_empty_square_ignores_space_outside_mask` | 最大空洞算法只计算掩膜内区域 |
| `test_conflicting_explicit_font_bounds_fail` | `MIN > MAX` 时报错而非静默回退 |
| `test_explicit_max_overrides_automatic_readability_floor` | 用户覆盖最大字号时,自动可读性下限让位于用户输入 |
| `test_base_class_never_uses_a_private_fallback_size` | 基类布局不使用隐藏回退字号 |
| `test_rendered_ink_stays_inside_mask_and_does_not_overlap` | 工作网格上:墨迹不超出掩膜、不重叠 |
| `test_hd_rendered_ink_does_not_overlap_after_scaling` | 高清放大后:零重叠像素、零碰撞边距 |
固定种子(`SEED=LAYOUT_SEED=20260718`)确保可复现。
## 基准测试
位置:`backend/tools/benchmark_layout.py`
运行方式:
```bash
cd backend
python tools/benchmark_layout.py --counts 80 800 --canvas 2000 --assert-targets
```
参数:
| 参数 | 说明 |
|------|------|
| `--counts COUNT [COUNT ...]` | 测试名单数量,默认 `80 800` |
| `--canvas CANVAS` | 画布尺寸,默认 `2000` |
| `--max-growth-rounds N` | 最大画布扩展轮数,默认 `1` |
| `--assert-targets` | 启用门禁检查 |
| `--output-dir PATH` | 输出目录,默认 `backend/benchmark_outputs/` |
### 门禁检查项(`--assert-targets`
| 指标 | 阈值 | 含义 |
|------|------|------|
| `completeness` | `= 1.0` | 名单必须全部放入 |
| `equal_weight_font_consistent` | `True` | 等权重时字号一致 |
| `hd_overlap_pixels` | `= 0` | 高清渲染后零重叠 |
| `contour_grid_coverage` | `≥ 0.80` | 轮廓网格覆盖率(避免大块空洞) |
| `hd_true_density` | `≥ 0.10` | 真实笔画密度 |
| `total_seconds` | `< 1.0s` (count<100) / `< 5.0s` (count<1000) | 性能门槛 |
### 输出指标
| 指标 | 说明 |
|------|------|
| `count` | 名单数量 |
| `canvas` | 最终画布尺寸 |
| `canvas_growth_rounds` | 画布扩展轮数 |
| `placed` | 实际放置词数 |
| `completeness` | 完整率 |
| `layout_seconds` / `render_seconds` / `total_seconds` | 各阶段耗时 |
| `work_fill_ratio` | 工作网格填充率 |
| `font_size_min` / `font_size_max` | 字号范围 |
| `equal_weight_font_consistent` | 等权重字号一致性 |
| `collision_margin` | 碰撞边距 |
| `hd_clearance_shifted_words` | 高清精修时位移词数 |
| `hd_clearance_max_shift` | 最大位移像素 |
| `hd_clearance_px` | 隔离带宽度 |
| `hd_clearance_priority_restarts` | 优先级回溯次数 |
| `hd_overlap_pixels` | 高清重叠像素(双重检查) |
| `largest_empty_square_work_px` | 工作网格最大空洞(像素) |
| `largest_empty_square_font_ratio` | 空洞相对字号比例 |
| `hd_true_density` | 高清真实笔画密度 |
| `ink_bbox_coverage` | 墨迹包围盒覆盖率 |
| `contour_grid_coverage` | 轮廓网格覆盖率 |
基准结果保存为 JSON`backend/benchmark_outputs/benchmark.json`
## 扩展基准
基准脚本使用 `run_generation_pass()` 直接调用核心管线,绕过 HTTP 服务和文件 IO。
- 生成数据:`make_names()` 使用中文姓氏库和双字名库组合出不重复姓名
- 掩膜:`make_round_mask()` 生成圆形掩膜
- 固定种子:`SEED=LAYOUT_SEED=20260718`
- 固定配置:`SIZE_RATIO=1.0, N_REPETITIONS=1, WORK_SCALE=0.18, TARGET_FILL_RATIO=0.45`
## CI 建议
```bash
cd backend
python -m pytest tests/test_layout_constraints.py -v
python tools/benchmark_layout.py --counts 80 800 --canvas 2000 --assert-targets
```
两次运行均应在数秒内完成。