日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

RTF文件结构分析及其应用

發(fā)布時(shí)間:2023/12/13 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 RTF文件结构分析及其应用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

 RTF是一種非常流行的文件結(jié)構(gòu),很多文字編輯器都支持它,VB等開發(fā)工具

甚至還提供了Richtxtbox的控件。編寫通用工具的程序員應(yīng)該考慮在自己的軟

件中加入讀寫RTF文件的功能,這樣就需要對RTF的結(jié)構(gòu)有充分的了解。而現(xiàn)在

最重要的信息發(fā)布手段莫過于WWW了,在編輯軟件中提供RTF到HTML的轉(zhuǎn)換也是程

序員應(yīng)該考慮的事情。盡管WORD中已經(jīng)有這個(gè)功能,但不能因此就對您的顧客

說:“先用我的程序存成RTF,然后再用WORD......”。

  下面將對RTF文件結(jié)構(gòu)分析及其應(yīng)用進(jìn)行討論。

  一、RTF文件結(jié)構(gòu)分析

  RTF的結(jié)構(gòu)并不復(fù)雜,但內(nèi)容繁多,本文不可能一一說明,只能從總體上討

論一下(如果想閱讀詳盡的RTF文檔,則可在Internet上尋找或與筆者聯(lián)系。)

每個(gè)RTF文件都是一個(gè)文本文件,顯示時(shí)由RTF閱讀器格式化。文件開始處是

{\rtf,它作為RTF文件的標(biāo)志是必不可少的,RTF閱讀器根據(jù)它來判斷一個(gè)文件

是否為RTF格式。然后是文件頭和正文,文件頭包括字體表、文件表、顏色表等

幾個(gè)數(shù)據(jù)結(jié)構(gòu),正文中的字體、表格的風(fēng)格就是根據(jù)文件頭的信息來格式化的。

每個(gè)表用一對大括號括起來,當(dāng)中包含了很多用字符“\”開始的命令。例如,

某個(gè)顏色表如下:

  {\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}

  開始時(shí)用\colortbl標(biāo)明大括號內(nèi)是顏色表,接著是\red0\green0\blue0,

登記了一種顏色,這種顏色的紅綠藍(lán)分量都為0。其它表依此類推。文件頭之后是

正文,正文由版面格式化命令、文字和各種特殊命令組成。其中只有特殊命令

用大括號括起來,而版面格式化命令和文字是“開放式”的,從而把文字和命

令分離。文件結(jié)束時(shí)有一個(gè)“}”,和第一個(gè)“{”對應(yīng)。在整個(gè)文件中,“}”

和“{”必須一一對應(yīng)。這種格式是RTF閱讀器和轉(zhuǎn)換器算法的基礎(chǔ)。

  RTF格式還有一個(gè)特別之處,就是有些字符在命令中有特殊的含義,所以當(dāng)

它們作為文本出現(xiàn)時(shí)需要在它們的前面加一個(gè)“\”,例如“\”本身就要表示

為“\\”。事實(shí)上,這種形式在大多數(shù)編程語言中是很常見的。

  二、算法分析

  本節(jié)介紹的算法雖然是針對RTF的讀寫,但也是一般文件過濾器通用的方

法,適用于各種格式文件之間的轉(zhuǎn)換。具體來說就是把各種文件都轉(zhuǎn)換成一種

中間格式,再根據(jù)要求進(jìn)行顯示或轉(zhuǎn)換。其中有個(gè)原則是一定要遵守的:程序必

須能過濾掉不認(rèn)識的格式。各種文件都有其特殊的格式,在轉(zhuǎn)換過程中不可避免

會(huì)出現(xiàn)格式損失的現(xiàn)象,在算法中要考慮這種情況。對于RTF這類格式化文本

文件來說,最重要的是要正確地顯示或轉(zhuǎn)換文件的大小、顏色、字體等風(fēng)格。

因此,在程序中應(yīng)該用一個(gè)數(shù)據(jù)結(jié)構(gòu)把這些信息存起來,這個(gè)結(jié)構(gòu)就是所謂的

中間格式,怎樣規(guī)定悉聽尊便。以下是其流程圖:

  三、難點(diǎn)分析

  在開發(fā)過程中我們遇到了不少問題,其中有兩個(gè)問題特別有意思。

  第一個(gè)問題是中文的表示方式。在RTF中中文用命令的形式表示:

“\'內(nèi)碼”。內(nèi)碼就是漢字機(jī)內(nèi)碼。不過,請注意:RTF是文本文件,內(nèi)碼

是用ASCII碼來儲(chǔ)存的,必須把它轉(zhuǎn)換成數(shù)字才能使用。例如,“電子與電腦”

在RTF中的形式是:

  \'b5\'e7\'d7\'d3\'d3\'eb\'b5\'e7\'c4\'d4

  第二個(gè)是圖片的問題,這也是本文的重點(diǎn)。RTF中圖片以兩種方式存在:第

一種方式是直接嵌入,以{\pict開始;第二種方式是作為OLE對象嵌入,這時(shí)以

{\object開始。當(dāng)RTF處理器能直接使用OLE時(shí),RTF文件中提供了OLE的數(shù)據(jù);否

則,文件中直接提供圖片的數(shù)據(jù),以{\result開始。在使用中最常見的圖片格式

是內(nèi)含DIB BITMAP的元文件(METAFILE),這種格式在SDK中沒有說明,而且

在RTF中是以壓縮形式儲(chǔ)存的,所以在轉(zhuǎn)換時(shí)有一定困難。我們采取了一種比較

新的方法:先把META FILE的數(shù)據(jù)讀出來存成一個(gè)文件,然后用GetMetafile和

PlayMetafile函數(shù)把文件中的圖形打印在一個(gè)內(nèi)存DC上,最后用抓圖的方法把

它存成BITMAP文件。以下是具體程序:

  voidWmfToBmp(intwidth,intheight,char *metafile)

  {

  //width為圖片寬度,height為圖片高度,*metafile為元文件名

  static HMETAFILE hmf;

  charnum[4];

  FILE *fh;

  HDC hMemDC;

  HBITMAP hbmp,hold;

  BITMAPFILEHEADER hdr;

  LPBITMAPINFOHEADER lpbmpih;

  HGLOBAL hg;

  

  BitmapCount++;

  if(BitmapCount==3)

  {

  width=128;

  height=132;

  }

  if(BitmapCount==1)

  {

  width=80;

  height=50;

  }

  ToString10(BitmapCount,num);

  //把字符串轉(zhuǎn)換成數(shù)字的函數(shù)

  lstrcpy(bmpFile,FilePath);

  lstrcat(bmpFile,num);

  lstrcpy(gifFile,bmpFile);

  lstrcat(bmpFile,".bmp");

  lstrcat(gifFile,".gif");

  hmf=GetMetaFile(metafile);

  hDisplayDC=CreateDC("DISPLAY",NULL,NULL,NULL);

  hMemDC=CreateCompatibleDC(hDisplayDC);

  hg=GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER));

  lpbmpih=(LPBITMAPINFOHEADER)GlobalLock(hg);

  lpbmpih->biSize=sizeof(BITMAPINFOHEADER);

  lpbmpih->biWidth=width;

  lpbmpih->biHeight=height;

  lpbmpih->biPlanes=1;

  lpbmpih->biBitCount=8;

  lpbmpih->biCompression=0;

  hbmp=CreateCompatibleBitmap(hDisplayDC,width,height);

  GlobalUnlock(hg);

  GlobalFree(hg);

  hold=SelectObject(hMemDC,hbmp);

  SetMapMode(hMemDC,MM_ANISOTROPIC);

  SetWindowOrgEx(hMemDC,0,0,NULL);

  SetViewportExtEx(hMemDC,width,height,NULL);

  PlayMetaFile(hMemDC,hmf);

  hbmp=SelectObject(hMemDC,hold);

  if((fh=fopen(bmpFile,"w+b"))==NULL)

  {

  return;

  }

  hdr.bfType=0x4d42;

  hdr.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+width*height;

  hdr.bfReserved1=0;

  hdr.bfReserved2=0;

  hdr.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);

  fwrite((LPSTR)&hdr,sizeof(BITMAPFILEHEADER),1,fh);

  hg=GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD));

  lpbmpih=(LPBITMAPINFOHEADER)GlobalLock(hg);

  lpbmpih->biSize=sizeof(BITMAPINFOHEADER);

  lpbmpih->biWidth=width;

  lpbmpih->biHeight=height;

  lpbmpih->biPlanes=1;

  lpbmpih->biBitCount=8;

  lpbmpih->biCompression=0;

  lpbmpih->biSizeImage=width*height;

  lpbmpih->biClrUsed=256;

  lpbmpih->biClrImportant=0;

  j=GetDIBits(hMemDC,hbmp,0,height,NULL,(BITMAPINFO*)lpbmpih,DIB_RGB_COLORS);

  lpbmpih->biSize=sizeof(BITMAPINFOHEADER);

  fwrite(lpbmpih,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD),1,fh);

  GetDIBits(hMemDC,hbmp,0,height,(LPSTR)FileBuffer,(BITMAPINFO*)lpbmpih,DIB_RGB_COLS);

  fwrite(FileBuffer,width*height,1,fh);

  GlobalUnlock(hg);

  GlobalFree(hg);

  fclose(fh);

  DeleteDC(hMemDC);

  DeleteDC(hDisplayDC);

  DeleteObject(hbmp);

  DeleteObject(hold);

  DeleteMetaFile(hmf);

  }//end function WmfToBmp()

  用這種方法還有一個(gè)好處,那就是當(dāng)你從最底層開始開發(fā)RTF閱讀器時(shí),只

需把PlayMetaFile的參數(shù)從內(nèi)存DC換成屏幕DC就可以顯示圖片了。

  四.RTF格式的擴(kuò)展

  最后討論一下RTF格式的擴(kuò)展。RTF格式作為一個(gè)標(biāo)準(zhǔn)應(yīng)該是統(tǒng)一的,但在

某種情況下進(jìn)行擴(kuò)展是必要的。最明顯的例子是微軟的WORD,它有自己獨(dú)有

的RTF命令。如果想使自己的軟件在技術(shù)上占有優(yōu)勢,也可以通過創(chuàng)造新的RTF

命令來實(shí)現(xiàn)。例如,如果你希望在軟件中支持DHTML,則可在RTF中嵌入

{\dhtml或{\java之類的命令。由于RTF閱讀器有過濾不認(rèn)識命令的功能,所以

這樣做不會(huì)影響RTF文件的通用性。

總結(jié)

以上是生活随笔為你收集整理的RTF文件结构分析及其应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。