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>
This commit is contained in:
+55
-22
@@ -7,13 +7,14 @@
|
||||
- 默认后端地址:`http://localhost:8000`
|
||||
- 请求体中上传文件使用 `multipart/form-data`
|
||||
- `params` 字段是 JSON 字符串,顶层必须是对象
|
||||
- 任务状态存在内存中,服务重启后状态会丢失
|
||||
- 任务状态存在内存中(`JobManager`),服务重启后状态会丢失;文件仍保留在 `service_workspace`
|
||||
- CORS 已开启,允许所有来源
|
||||
|
||||
## Jobs
|
||||
|
||||
### GET `/api/health`
|
||||
|
||||
返回:
|
||||
健康检查。
|
||||
|
||||
```json
|
||||
{"ok": true}
|
||||
@@ -30,15 +31,13 @@
|
||||
Form 字段:
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
|------|------|------|
|
||||
| `name_list` | 是 | `.xlsx` 名单文件 |
|
||||
| `mask_image` | IMAGE 模式必填 | `.png` / `.jpg` / `.jpeg` 掩膜 |
|
||||
| `font_file` | 否 | 临时上传字体,支持后端 `_FONT_EXTENSIONS` 中的格式 |
|
||||
| `font_file` | 否 | 临时上传字体(`.ttf` / `.ttc` / `.otf`) |
|
||||
| `font_id` | 否 | 使用已上传字体 |
|
||||
| `params` | 否 | JSON 字符串,合并到任务配置 |
|
||||
|
||||
字体格式当前支持 `.ttf`、`.ttc`、`.otf`。
|
||||
|
||||
`params` 示例:
|
||||
|
||||
```json
|
||||
@@ -129,10 +128,12 @@ SSE 事件流。事件数据模型:
|
||||
|
||||
### GET `/api/jobs/{job_id}/locations`
|
||||
|
||||
查询词语位置。查询参数:
|
||||
查询词语位置。
|
||||
|
||||
查询参数:
|
||||
|
||||
| 参数 | 说明 |
|
||||
| --- | --- |
|
||||
|------|------|
|
||||
| `name` | 可选;为空返回全部,非空精确匹配 |
|
||||
|
||||
返回:
|
||||
@@ -173,7 +174,7 @@ SSE 事件流。事件数据模型:
|
||||
查询参数:
|
||||
|
||||
| 参数 | 默认 | 说明 |
|
||||
| --- | --- | --- |
|
||||
|------|------|------|
|
||||
| `fill` | `fill` | `fill` / `dot` / `line` / `ring` |
|
||||
| `stroke` | `0` | 是否描边 |
|
||||
| `spacing` | `10` | 点阵间距 |
|
||||
@@ -192,11 +193,11 @@ SSE 事件流。事件数据模型:
|
||||
|
||||
返回后端硬编码模板列表:
|
||||
|
||||
- `poster_1x2`
|
||||
- `poster_4x5`
|
||||
- `poster_1x1`
|
||||
- `poster_3x4`
|
||||
- `poster_16x9`
|
||||
- `poster_1x2`(竖版手机海报,1080×2160)
|
||||
- `poster_4x5`(社交媒体图,1080×1350)
|
||||
- `poster_1x1`(方形封面,1080×1080)
|
||||
- `poster_3x4`(竖版广告,1080×1440)
|
||||
- `poster_16x9`(横版电商,1920×1080)
|
||||
|
||||
## Assets
|
||||
|
||||
@@ -205,7 +206,7 @@ SSE 事件流。事件数据模型:
|
||||
上传素材。Form 字段:
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
|------|------|------|
|
||||
| `file` | 是 | 素材文件 |
|
||||
| `name` | 否 | 名称 |
|
||||
| `type` | 否 | 默认 `upload` |
|
||||
@@ -215,7 +216,7 @@ SSE 事件流。事件数据模型:
|
||||
从任务产物导入素材。Form 字段:
|
||||
|
||||
| 字段 | 默认 | 说明 |
|
||||
| --- | --- | --- |
|
||||
|------|------|------|
|
||||
| `kind` | `png` | 产物类型 |
|
||||
| `name` | 空 | 素材名称 |
|
||||
| `type` | `wordcloud` | 素材类型 |
|
||||
@@ -243,10 +244,10 @@ SSE 事件流。事件数据模型:
|
||||
|
||||
### POST `/api/projects`
|
||||
|
||||
Form 字段:
|
||||
创建工程。Form 字段:
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
|------|------|------|
|
||||
| `name` | 是 | 工程名 |
|
||||
| `template_id` | 是 | 模板 ID |
|
||||
| `background_color` | 是 | `#RRGGBB` |
|
||||
@@ -272,29 +273,61 @@ Form 字段:
|
||||
|
||||
### GET `/api/fonts`
|
||||
|
||||
返回字体列表,包含默认字体项。
|
||||
返回字体列表,包含默认字体项(`__default__`)。
|
||||
|
||||
### POST `/api/fonts`
|
||||
|
||||
上传字体。Form 字段:
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `file` | 是 | 字体文件 |
|
||||
|------|------|------|
|
||||
| `file` | 是 | 字体文件(`.ttf` / `.ttc` / `.otf`) |
|
||||
| `name` | 否 | 字体名 |
|
||||
|
||||
### DELETE `/api/fonts/{font_id}`
|
||||
|
||||
删除已上传字体。默认字体不能删除。
|
||||
|
||||
## Line Spacing Analysis
|
||||
|
||||
### POST `/api/jobs/{job_id}/analyze-line-spacing`
|
||||
|
||||
分析 SVG 词云路径的线距,返回 `LineSpacingAnalysisSummary`。
|
||||
|
||||
请求体(JSON):
|
||||
|
||||
```json
|
||||
{
|
||||
"percentile": 3,
|
||||
"elementWidth": 100.0,
|
||||
"elementHeight": 100.0,
|
||||
"sampleStep": 2.0
|
||||
}
|
||||
```
|
||||
|
||||
响应字段:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `percentile` | 线距百分位 |
|
||||
| `spacingPx` | 采样线距(像素) |
|
||||
| `spacingMm` | 采样线距(毫米) |
|
||||
| `minSpacingPx` | 最小线距(像素) |
|
||||
| `minSpacingMm` | 最小线距(毫米) |
|
||||
| `curveCount` | 曲线数量 |
|
||||
| `segmentCount` | 线段数量 |
|
||||
| `sourceWidth` / `sourceHeight` | SVG 原始尺寸 |
|
||||
| `elementWidth` / `elementHeight` | 目标元素尺寸 |
|
||||
|
||||
## 常见错误
|
||||
|
||||
| 场景 | 状态码 | detail |
|
||||
| --- | --- | --- |
|
||||
|------|--------|--------|
|
||||
| `params` 不是合法 JSON | 400 | `params must be valid JSON` |
|
||||
| `params` 不是对象 | 400 | `params must be JSON object` |
|
||||
| `name_list` 非 `.xlsx` | 400 | `name_list must be xlsx` |
|
||||
| IMAGE 模式缺少掩膜 | 400 | `mask_image is required when MODE=IMAGE` |
|
||||
| 掩膜文件不存在 | 400 | `mask_image must be png/jpg/jpeg` |
|
||||
| job 不存在 | 404 | `job not found` |
|
||||
| 产物未就绪 | 404 | `artifact not ready` |
|
||||
| 文件类型未知 | 404 | `unknown artifact kind` |
|
||||
|
||||
Reference in New Issue
Block a user