文件格式之PDF

目录:
1、PDF格式分析
  1.1 header
  1.2 Obj
  1.3 cross reference table
  1.4 trailer
  1.5 文件尾
  1.6 Obj对象
2、VC生成PDF
  2.1 前期准备
  2.2 源码及效果
3、参考资料
正文:
1、PDF文件分析
  PDF文件主要包含以下几种结构:
1.1 header
PDF文件的第一行,格式如下:
%PDF-1.1    //表示当前文件的版本为1.1(目前最高版本是1.7)
1.2 Obj (文件体)
  PDF中用到的对象,包括文本/图象/音乐/视频/字体/超连接/加密信息等,格式如下:
例:
代码:

1  0  obj  
//1标示这个obj的序号,便于在xref中查找,0是用来标示不同的obj现在都是0,obj是关键字
<<     // 从这里开始各行就是obj的属性了 以“/关键字 值”的形式来出现
/Type /Catalog           //obj的类型是目录catalog
/Outlines 2 0 R          //第二个obj是outlines
/Pages 3 0 R            //第三个obj是Pages
/OpenAction 7 0 R      // OpenAction 在第7个obj
>>
endobj                       //一个obj结束


1.3 cross reference table
代码:

xref  
  0   5  
  0000000000   65535   f  
  0000000009   00000   n  
  0000000074   00000   n  
  0000000120   00000   n  
  0000000179   00000   n


xref 是obj的索引表,用来索引各个obj在文档中的起始位置,它的形式如下图,其中0,211分别代表这个xref的obj的起始和终止序号。下面的各行就 代表各个obj在这个文档的起始位置,其中第一串字符(10个)代表起始位置,中间的五个字符也是为了区分用的,只有当这个对象被删除的时候才有用,表示 这个对象被删除后又被重新生成后的对象号,现在基本上全为0。 后面的字母有两种:f代表删除的,n代表要使用的。
1.4 trailer
代码:

trailer  
  <<  
  /Size   8  
  /Root   1   0   R  
  >>  


后面的trailer是对整个xref的摘要,说明里面有多少个OBJ,读的时候从哪个OBJ开始解析,信息节点等,其中:
/size   :这个pdf中总共使用了多少个对象  
/root   :这个pdf文件的catalog对象的对象号,这是pdf中最顶层的对象,即PDF是组织对象号,此例中位 1 0 R
1.5 文件尾
代码:

startxref  
  553  
  %%EOF  


因为一个文档中可以有多个xref,所以这里要指明要从哪个xref开始进行解析这个文件。
/startxref: 后面的数字表示cross  reference  table的开始位置,里面的数字是10进制。
/%%EOF :文件结束符.  
1.6 OBJ对象
  Pdf的OBJ中的对象有如下几种,现介绍如下:
(1)文件描述对象,用来描述这个文件的标题,作者,时间等
(2)组对象,也就是文档内容的起始结点。Type 为Catalog
(3)页集合,里面聚合了大量的页对象。  Type 为pages
(4)页对象,里面指明了当前页里面用到的字体,内容,活动对象,图片等。Type 为page
(5)活动对象,有链接,文字,声音,电影等,Type 为Annots
(6)图片对象, Type 为 XObject
(7)字体对象,Type 为 Font 。PDF可以内置字体,所以即使目标机器上没有,只要它内置了,也可以正常地显示,不受影响。
(8) 流对象。所有的二进制内容都是存在这个对象里面,文件流的常见的压缩方式是:图片的一些压缩算 法,FlateDecode,ASCIIHexDecode,ASCII85Decode等等,FlateDecode事实上就是ZIP的压缩算法。流对 象的长度是关连到一个长度对象上的/Length  188 0 R这种形式。188就是存这个长度的OBJ的顺序号。
(9)数字对象。例如:
188 0 obj
2538
endobj
里面只有一个数字,经常用来表示长度。
2、VC生成PDF
  PDFLib是用于创建PDF文档的开发库,提供了简单易用的API,隐藏了创建PDF的复杂细节且不需要第3方软件的支持。已VC编辑一个控制应用台程序为例来生成一个PDF。
2.1 前期准备
  先到PDFLib官网下载库文件,最新版为pdflib8,但是生成的pdf有一个官网的网址,5.0版本以下没有,链接地址:http://www.pdflib.com/download/pdflib-family/pdflib-8 建立工程后,将下载库中pdflib.h,pdflib.dll,pdflib.lib拷贝到工程目录。
2.2 源码
参照官网提供的一些sample,改编了一个,源代码如下:
代码:

#include "stdafx.h"
#include "pdflib.h"
#pragma comment(lib,"pdflib.lib")
int main()
{
  PDF *p;
   /* create a new PDFlib object */
    if ((p = PDF_new()) == (PDF *) 0)
    {
        printf("Couldn't create PDFlib object (out of memory)!/n");
        return(2);
    }
PDF_TRY(p)
  {
    /* This means we must check return values of load_font() etc. */
    PDF_set_parameter(p, "errorpolicy", "return");
    
    if (PDF_begin_document(p, "pediy.pdf", 0, "") == -1)
    {
      printf("Error: %s/n", PDF_get_errmsg(p));
      return(2);
    }  
//     /* This line is required to avoid problems on Japanese systems */
//     PDF_set_parameter(p, "hypertextencoding", "host");
    PDF_set_info(p, "Creator", "pediy.c");
    PDF_set_info(p, "Author", "youstar");
    PDF_set_info(p, "Title", "Hello, pediy (C)!");  
    PDF_begin_page_ext(p, a4_width, a4_height, "");  
    /* Change "host" encoding to "winansi" or whatever you need! */
    font = PDF_load_font(p, "Helvetica-Bold", 0, "host", "");
    if (font == -1)
    {
      printf("Error: %s/n", PDF_get_errmsg(p));
      PDF_delete(p);
      return(2);
    }  
    PDF_setfont(p, font, 24);
    PDF_set_text_pos(p, 50, 700);
    PDF_show(p, "pediy");
    PDF_continue_text(p, "2010 better!");
    PDF_end_page_ext(p, "");  
    PDF_end_document(p, "");
    }
    PDF_CATCH(p) {
        printf("PDFlib exception occurred in hello sample:/n");
        printf("[%d] %s: %s/n",
      PDF_get_errnum(p), PDF_get_apiname(p), PDF_get_errmsg(p));
        PDF_delete(p);
        return(2);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章