# 排版

## 背景

对翻译后的文本，需要排版后才能放到 PDF 里。

翻译后的段落可以包含以下几种类型的任意组合：

1. PDF 公式
2. 单个 PDF 原始字符
3. 同样式的 PDF 原始字符串
4. 翻译出来的同样式 unicode 字符串

接下来分情况讨论：

对于以下 3 种类型，可以直接透明传输到新位置。

1. PDF 公式
2. 单个 PDF 原始字符
3. 同样式的 PDF 原始字符串

只有`翻译出来的同样式 unicode 字符串` 需要执行重排版操作，因为这一步丢失了原有的排版信息。但是由于段落可以包含其他需要透明传输的组成部分，所以其他部分的位置也可能发生变更，也需要参与进排版来。

## 目标

在段落原始包围框内想办法摆下所有的组成部分。如果实在摆不下，则尝试向书写方向扩展包围框。

## 具体实现

首先进行重排判断，判断该段落是否需要重排。如果该段落所有元素均可透明传输，则无需重排。之后，如需重排，则执行具体重排算法 1：

1. 将所有元素转换为排版单元类型，排版单元内记录了该元素的长度宽度信息。
2. 从原始段落包围框的左上角开始开始，依次摆放各元素。
3. 若当前行无法放下下一个元素，则换行。
4. 重复 2~3，直到所有元素摆放完毕，或超出原始包围框。

在译文长度小于原文长度时，上述算法 1 可以正常使用。但是当译文长度大于原文长度时，需要增加一步算法 2：

1. 初始化元素缩放系数为 1.0。
2. 初始化行距为 1.7。
3. 使用算法 1 尝试排版。
4. 若无法放下所有元素，则首先以步长 0.1 缩小行距。若行距达到 1.1 后仍无法放下所有元素，则将元素缩放系数缩小 0.01，然后跳至第二步执行。
5. 若元素缩放系数小于 0.1，则报错。

通过算法 2 即可在原始位置摆放下几乎所有语言的译文。

但是对于某些特殊情况，例如 `图 1` 翻译成 `Figure 1` 等，即使 0.1 的元素缩放也摆不下，需要尝试向书写方向扩展包围框。所以引出算法 3：

1. 以最小缩放限制 0.8 尝试排版。
2. 若无法放下所有元素，则通过页面信息计算该段落右侧空白空间。
3. 根据空白空间，扩展段落包围框。
4. 以最小缩放限制 0.1 尝试排版。

## 局限性

1. 暂时只能处理从左向右书写的文字。
2. 暂时无法处理目录条目根据点号对齐。
3. 性能较差，需要优化。
4. 没有考虑页面全局信息，文字忽大忽小。
5. 没有实现高级排版功能，阅读体验较差。
