首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

OFD文档解析流程

背景介绍

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

流程框架

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

框架解读

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

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

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

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

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

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

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

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

对于图片资源:

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

对于文字

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

1)有字体信息

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

2)无字体信息

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

对于图形信息

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

元素绘制

从图中可以看出,绘制的过程只对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的色彩空间比较简单,仅仅支持RGB,CMYK,GRAY三种

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

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

绘制顺序

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

AWT避坑

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

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/1787802df805f47a27181892c
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券