Categories
程式開發

OFD文档解析流程


背景介绍

之前的文章介绍了什么是OFD,OFD中的各个元素的标识方法以及各个元素的定位方法。这次从显示的流程上介绍一下如何把一个OFD文件显示出来。

流程框架

要把一个OFD文件显示到屏幕上是有一定的流程的,首先要把这个文件读入到内存中,然后按照OFD 的标准解析文件,最后在显示设备上把解析是元素按照要求进行绘制。具体的流程可以用下图进行表示:

OFD文档解析流程 1

框架解读

从图中可以看出,首先是读入OFD文件,然后按照标准解析文件,解析的内容大概有:

文档的元数据信息资源文件大纲电子签章注释页面元素

元数据信息,我们可以比对一下PDF的文档信息。一个pdf文件,可以获取到他的作者信息,创建时间,修改时间等信息,同理,OFD也包含这些信息。

资源文件,对OFD的内嵌资源进行解析与提取,内嵌资源对比PDF的话最直接的就是查看文档属性,然后选择字体,这样就可以看到如下信息。

OFD文档解析流程 2

这些就是嵌入的资源。因为一个文档并不可能把所有的文字都显示一次,所以就把该文档所包含的字符组合成一个新的字体文件。所以,你会看到显示的是嵌入子集。OFD解析的过程就是把这些字体,还有内嵌的图片的路径和这些元素的ID构建一张索引表,供后期显示的时候查询元素。

大纲就是这个文档的一个索引以及点击这个大纲元素的动作信息,比如说点击这个标题会跳转到指定的页码。

签章信息,如何这个签章信息包含印章图片,那么就需要按照上一篇文章所说的剥洋葱的方法把图片解析出来。然后显示到指定的位置。

注释信息和元素信息都是由基本的元素构成的(图片、图形、文字)对于这三类元素,解析的元素信息就不太相同。

对于图片资源:

图片的编号,根据编号索引具体的图片图片的外接边框,图片显示的位置与大小变换矩阵,对图片进行旋转或者变形裁剪信息,限制图片的显示区域

对于文字

可以分为文件中有字体信息和没有字体信息两类:

1)有字体信息

字体的编号,根据编号索引具体的字体字体的大小,获取矢量图的时候传入的参数外接边框, 控制显示的位置填充颜色、勾边颜色,控制颜色的显示裁剪信息,变换矩阵,控制字型的显示区域以及显示的形状文字的索引号,根据这个编号从字体中获取到字型,可见字体解析这篇分享

2)无字体信息

字体的编号,根据编号索引具体的字体字体的大小,获取矢量图的时候传入的参数外接边框, 控制显示的位置填充颜色、勾边颜色,控制颜色的显示裁剪信息,变换矩阵,控制字型的显示区域以及显示的形状文字内容,根据文字从系统字体中获取字型

OFD文档解析流程 3

对于图形信息

图形信息,可参考svg 的路径表示方法外接边框,图形的显示位置填充颜色和勾边颜色,图形的外观裁剪区域

OFD文档解析流程 4

元素绘制

从图中可以看出,绘制的过程只对OFD的资源信息(虚线)、签章、注释以及元素信息(实线)有关联。因为这些信息是需要显示到设备上与用户直接进行交互的元素。

为什么要把资源信息用虚线表示?

资源文件是绘制的基石,但绘制的时候并没有直接体现出来,所以这里用了虚线,而对于文字、图片、图形、印章图片则是直接显示到页面上的。所以用了实线表示。

绘制方案

对于如何把这些元素信息显示到页面上,可以有很多方案:

1.利用OPENCV绘制一张图片,显示一张图片

2.把元素表示转化成SVG的表示形式,嵌入页面中显示

3.转化成其他的格式,比如说PDF 用pdf.js 显示

4.利用其他的绘制工具进行绘制

通过综合考虑,选择了第4种方案,这里的其他工具我们选择了java元素的AWT工具。原因如下:

操作简单,学习成本低功能强大,可以满足显示的所有的需求坐标系统和OFD的坐标系统一致,都是以左上角为原点

注意点

绘制单位

在OFD种使用毫米(mm)来表示元素的大小,而AWT种则是使用像素(Px)。在绘制的时候需要把单位转化一下。

转化过程种我们要使用一个参数(DPI),表示每英寸显示几个点。转化的公式如下:

px / DPI = 英寸

英寸 * 25.4 = mm

裁剪区

裁剪区是用于限制元素的显示范围的,特别是在表格元素中,经常遇到文字长度超出了表格的长度,这时候就需要把文字的显示范围限制一下。具体效果如图所示:

OFD文档解析流程 5

颜色转化

OFD的色彩空间比较简单,仅仅支持RGB,CMYK,GRAY三种

在绘制的时候,需要获取他的色彩空间,一个简单的办法就是根据颜色的长度进行判断

色彩空间颜色长度示例(黑色)gray10rgb30 0 0cmyk40 0 0 100

绘制顺序

也许有人会问,这么多元素是不是可以使用多线程进行绘制,答案呢是不可以。只能按照元素的顺序进行绘制。因为绘制过程就像是一个写作业的过程,如果你手持几根笔写作业,可能会导致有些元素的覆盖。

AWT避坑

JDK1.8的AWT在X86平台的drawShape() 或者draw()函数是正常的,但是迁移到arm平台下,会出现绘制问题,这里可以使用OPENJDk解决。

拓展阅读:

OFD 版式技术解析系列(一):开篇

OFD 版式技术解析系列(二):OFD的颜色显示

OFD 版式技术解析系列(三):仿射变换在 OFD 中的应用

OFD文档解析流程 6