简单文字换行算法

很多情况下,平台只支持单行文本的渲染(如HTML5 Canvas),这时就需要手动按照一定的规则对文本进行换行处理。

具体规则如下:

1、分组

该过程稍类似于词法分析过程和LL(1)语法分析过程,每次读取一个字符(每个汉字算一个字符),根据当前字符和上一个字符的类型,决定将该字符插入到上一个字符所在组的末尾,还是新建一个组并将该字符插入到新建的分组中。

以下情况当前字符将被添加到上一个字符所在的组中:

一般情况下,以下标点是不能出现在行首的(Word中称为“后置标点”):

!),.:;?]}¨·ˇˉ―‖’”…∶、。〃々〉》」』】〕〗!"'),.:;?]`|}~¢

以下标点是不能出现在行尾的(Word中称为“前置标点”):

([{·‘“〈《「『【〔〖(.[{£¥

举个例子:对以下文本进行分组

HTML5的canvas元素使用JavaScript在网页上绘制图像,画布是一个矩形区域。

分组后的结果如下:

HTML5 canvas 使 JavaScript 像, 域。

英文单词被单独归为一组,逗号和句号被放到前一个字符所在的分组中。

后续操作需要对各个分组的宽度进行测量,一般使用平台提供的相关接口(对于HTML5 Canvas,则是context.measureText())。

2、拆分超长组

如果某些组去掉尾部空格后的宽度仍然超过了容器宽度,则需要对该组进行强制拆分,否则会导致内容出界、内容显示不全,甚至系统崩溃。

拆分过程如下:

  1. 去掉待拆分的组尾部的空格。
  2. 从待拆分的组的开头取出字符,并添加到新分组中,直到新分组的宽度超过容器宽度。
  3. 把新分组中最后一个字符取出,放回待拆分组的开头。然后把新分组放到待拆分组之前。
  4. 重复步骤2、3,直到待拆分组的宽度小于容器宽度。

3、确定最终换行结果

  1. 取出一个分组,确定当前分组的宽度是否超过当前行的剩余宽度。
  2. 如果当前分组的内容是换行符,则另起一行作为当前行并转步骤1。
  3. 如果当前分组的宽度大于当前行剩余宽度,则去掉尾部空格后再测量宽度。如果仍然大于当前行剩余宽度,则另起一行作为当前行。
  4. 将该分组放到当前行中,当前行剩余宽度减去当前分组的宽度。
  5. 重复步骤1-4,直到所有分组都处理完。

4、渲染

将分好行的文本按行进行渲染,此时可自行控制行高,以及对齐方式。

运用条件

该文字换行算法仅适用于英语、法语、德语等使用拉丁字母的文字,俄语等使用西里尔字母的文字,以及中日韩文字。