# 拼版算法与坐标约定

设一册选取 k 个逻辑页面，每册容量 C 是 4 的倍数。取 P = 4 × ceil(k / 4)，在册末补 P-k 个空白。每张纸含正反各两个页面，因此需要 P/4 张。

对于从外到内编号 d = 0..P/4-1 的纸张，左装订的逻辑位置（从 1 开始）为：

- 正面：[P - 2d, 1 + 2d]
- 背面：[2 + 2d, P - 1 - 2d]

位置超过 k 时写入 0，否则映射到保留原顺序的原稿页码。每一对位置之和都是 P+1，每个位置出现且只出现一次。右装订分别交换正反面的左右槽。

前满册相互独立；末册重新计算 P。例如 18 页、C=16：第一册 16 页/4 张；第二册 2 页补 2 空白/1 张。不是把每册都填满到 16 页。

## 双面旋转

画布是横向纸张，页面坐标基于各自印刷面正视图。短边翻转使用 backs=0°。长边翻转需在合成背面后绕画布中心整体旋转 180°；槽位数组仍表示旋转前逻辑左右位置。SVG 体现该整体旋转，JSON 消费者必须应用 back_rotation。

这只是数字版面约定；消费 JSON 计划的处理器只应应用一次 `back_rotation`。适配器生成的 PDF 已写入页面旋转，SVG 也已包含旋转，下游无须再次应用该角度。

## 接口契约和复杂度

页码数量上限 10,000；每册 4..64 页；所有整数先界限检查，避免溢出。选择语法保留顺序但禁止同一原稿页出现两次；如确需重复页，应先在上游文档生成阶段创建新页。验证和布局构造 O(N)，空间 O(N)，仅使用 MoonBit 标准库。核心不访问文件或网络。

JSON schema_version=1；blank_page=0；selected 是原稿页序；sheets 依册序及外到内顺序排列。每张 sheet 包含 signature、depth（均从 1 开始）、front/back 两个槽位、back_rotation。SVG 为示意而非印刷尺寸文件，最多显示前 24 张并明确标记总张数。

测试用已知 8 页排版及 20 页分册作为参考，并遍历页数 1..129、5 种容量、2 种装订、2 种翻转，共 2,580 组。检验原页计数、空白计数、总槽位、册数以及独立的折页配对和，不仅比较自身生成的快照。
