计算机工程
Computer Engineering
1999年 第25卷 第4期 Vol.25 No.4 1999
--------------------------------------------------------------------------------
RTF文件格式分析及在多媒体中的应用
余阳 游燕
摘 要 RTF是一种在不同操作系统下不同应用软件之间进行文本和图象信息交换的文件格式。以RTF格式作为多媒体系统中文本媒体的一种输入形式,可为用户提供极大的方便。简要分析了RTF文件格式并介绍了RTF阅读器(RTF Reader)的编程方法。
关键词 RTF多媒体 文件格式 RTF阅读器
Analyses of Rich Text format and application in Multimedia
YuYang YouYan
(Research Center for Electronical Mechanism,Zhongshan University Guangzhou 510275)
Abstract:Rich Text Format(RTF)provides a format for text and graphics interchange that can be used with different output devices,operating environments,and operating system.This paper analyses the format structure of RTF and introduces the programming of RTF reader.
Key words:RTF;multimedia;File format;RTF reader
RTF(Rich Text Format)格式是Microsoft公司为进行文本和图象信息格式的交换而制定的一种文件格式,它适用于不同的设备、操作环境和操作系统。自从1987年3月《Microsoft System Journal》发表RTF格式说明书以来,它在MS-DOS、Windows、OS/2和Apple Macintosh等环境下的字处理系统中得到了广泛的支持。目前的版本是1.4。
1 RTF文件格式分析
1.1 RTF格式描述中的基本概念
RTF文件的基本元素是正文(Text)、控制字(Control word)、控制符号(Control Symbol)和群组(Group)。
控制字是一种特定格式的命令,RTF用它作为正文格式的控制代码,也作为应用程序管理文档的控制信息。一般形式如下:
\字符序列<定界符>
控制字均以反斜杠开头,字符序列是小写字母(RTF对大小写敏感),定界符标志一个RTF控制字的结束,它是下列形式之一:
.空格。
.数字或连字符(-),它表示后跟数字参数。后续的数字序列以空格或任何非字母数字的字符作为结束。
.非字母数字的任何其它字符。
控制符号由反斜杠后跟一个单独的、非字母的字符,表示一个特定的符号。
群组由包括在大括号({})中的正文和控制字或控制符号组成。每个群组描述了由它修饰的正文和正文的各种属性。
1.2 RTF格式的语法描述
RTF格式的语法可用backus-Naur范式描述。完整的描述需要大量的篇幅,这里简要分析其中重要的部分。一个完整的RTF文件可看作是一个群组:
<File> '{'<header><document>'}'
它包括文件头<header>和文档区<document>两大部分。其中文件头具有下面语法:
<header>\rtf<charset>\deff?<fonttbl>
<filetbl>?<colortbl>?<stylesheet>?<revtbl>?
控制字\rtf 必须紧跟在左括号后,后跟数字参数表示版本号;<charset>说明文档中使用的字符集;\deff 指出省确字体;<fonttbl>群组定义了文档中所有可用的字体,并用来作为整个文档字体的索引;<filetbl>定义了文档参考引用的文件;<colortbl>群组定义了屏幕颜色、字符颜色、以及其它颜色信息;<stylesheet>描述了文档中可以使用的各种字型;<revtbl>这个表格跟踪记录该文档每一次修订的作者和时间。一旦RTF定义了文件头,就有了足够的的信息去正确阅读文档区。
文档区遵守下面的语法:
<document><info>?<docfmt>*<section>+
信息群组<info>包含了有关该文档的信息。这些信息包括标题、作者、关键字、批注以及其它有关该文件的特有信息。<docfmt>是一组定义该文档格式属性的控制字,如:页边空白、脚注位置、页高页宽等,这些属性必须在文档中第一个纯正文字符之前出现。接下来的部分由一个或多个节构成,每个节具有下面的语法:
<section> <secfmt>*<hdrftr>?<para>+(\sect<section>)?
关键字\sect标志着一个新节的开始。<secfmt>是一系列的节格式属性控制字,它们也可出现在节的任何位置(不仅仅是开头),每一节都可定义它本身的页信息(宽、高、空白等)、页号格式等;<hdrftr>单元设定页眉和页脚;<para>是段落群组,每一节的内容由一个或多个段落组成。
段落有简单型和表格型两种,关键字\par标志着一个新段落的开始。在一个段落里,可以定义段落的格式属性,如:对齐方式、缩排、间隔、段落边界、底纹等。文档的实际内容也出现在段落中,这包括字符正文、图片、OLE嵌入对象等等。每一种实质内容都可定义其格式属性,如:对于字符正文,我们可以定义粗体、斜体、下划线、底纹、背景色、字符色等。
总之,我们可以看到,RTF格式描述除了文件头外,其它内容的描述呈层次结构:
文档→节→段落→对象(正文、图片、OLE对象等)
前者包含后者,前3层主要是定义各种格式属性,对象层除了描述具体对象的属性外,出现了对象的实质内容。
2 RTF阅读器的编程方法
要在自己的多媒体系统中支持RTF格式的文档,就必须自己编写相应的RTF阅读器程序。一个RTF阅读器的开发必定要包含以下3个基本步骤。
(1)分离RTF控制字与正文
RTF控制字与正文的分离比较简单。因所有的RTF控制字都以反斜杠开始,并以定界符结束(上一节已说明),所以,很容易将其与正文内容分开。下面是该算法的形式描述:
while(没有到达文件尾){
ch<- 从文件读取一个字符;
switch(ch){
case'{':
保存RTF状态(文档属性、节属性、段落属性、字符属性、程序分析中间状态等);
break;
case'}':
恢复RTF状态;
break ;
case'\':
RTF 控制字语法分析
break;
case回车、换行:
break;
default:
if(ch是西文)
输出ch;
else
等下一个ch共同组成汉字,输出;
};//switch结束
};//while结束
return;
(2)RTF控制字语法分析
这一步也相当简单。一个RTF控制字要么是小写字母的字符串(后可跟数字参数),要么是一个非字母数字的字符。下面是该算法的形式描述:
ch<-从文件读取一个字符;
if(到达文件尾)return;
if(ch是非字母数字){
控制字语义翻译;
return;
};
keyword<- 读取关键字;
if(后续字符是'-')
表示负数;
if(后续字符是数字)
Parameter<-读取数字参数;
控制字语义翻译;
return
(3)控制字语义翻译
语义翻译是相当复杂的一步。这不仅仅是由于控制字数量繁多、含义类型各异,还由于 RTF 在描述不同但相关的属性时在顺序上是模糊的,这就要求语法分析和语义翻译必须灵活准确。无论采用什么方法,语义翻译应与前两个步骤相互配合,做到以下3点:
1)忽略你不准备翻译的控制字
如果不处理好该问题,则RTF阅读器遇到不"懂"的控制字就很易崩溃。事实上,要面面俱到地翻译全部控制字是很困难的,对于具体应用也是不必要的。Microsoft也在不断增加新的控制字,正确的忽略可以使阅读器兼容于不同程序产生的RTF文档,也可兼容于RTF以后发展的版本。
2)永远要理解控制字\*
该控制字引入了一个目标单元,它不属于文档的一部分,它告诉RTF阅读器:如果它不识别下一个控制字,它应该跳过整个封闭的群组({…})。
3)跳过忽略的RTF字符时要注意二进制数据的出现
在RTF中跳过一个群组的简单方法是保持一个动态计数器,以记录RTF流中遇到的大括号:遇到"{"时,计数器加1;遇到"}"时,计数器减1,计数器为负时,表明到了群组的结尾。不幸的是,当RTF文件包含\bin控制字时,这种方法就无效了。阅读器必须检查每一个遇到的控制字是否是\bin ,若是,先要跳过它说明的所有字节(我们目前不准备支持二进制图片数据),然后才能恢复扫描大括号。
这里我们简单介绍一种"表格驱动"的翻译方法:首先,建立一个控制字描述表和一个属性描述表。前者将控制字翻译为属性索引,并得到该属性的省缺值、控制字类型(属性、特殊字符、目标单元、等)等信息。然后通过属性索引在属性描述表中查到属性所在的结构以及在结构中的偏移量、属性值的类型(字节、字、需特殊处理)等。有了这些信息,程序就能正确翻译控制字并将它的值存到指定结构的指定位置。
以上3个基本步骤完成后,我们已经将正文与控制分离开,并能用一定的结构跟踪记录不断变化的各种属性。在网址:http://www.Sunpack.com/RTF/Webdocs/RTF-Spec/RTF1-4.htm处,你可以从附录A得到实现这3步的示意性C程序。我们已经对这部分程序进行了更正(有部分小错误) 、扩充和改进:①使其支持更多的控制字和语法,支持中文;②扩充了各种排版算法,完成了另一个重要步骤:根据属性将正文排版输出;③用C++中类的概念封装了该解释器,更便于使用和进一步扩充;④将该解释器并入我们开发的"图文特技软件包",进而用于我们的多媒体产品。
作者简介:余阳 男,31岁,工程师,主研多媒体,网络技术
作者单位:中山大学电子机械研究中心 广州510275
参考文献
1 Microsoft Product Support Services,Rich Text Format(RTF)Specification and Sample RTF Reader Program,http://www.Sunpack.com/RTF/Webdocs/RTF-Spec/RTF1-4.htm
2 HellerM著.朱鸿隽译.Windows高级程序设计,北京:电子工业出版社,1994-11
3 姚玉明,胡晓峰 . 超媒体系统中文本媒体的处理方法及表现.全国第四届多媒体技术学术会议论文集:198-202
收稿日期:1998-02-23