PDF-API2 编程指南.doc_第1页
PDF-API2 编程指南.doc_第2页
PDF-API2 编程指南.doc_第3页
PDF-API2 编程指南.doc_第4页
PDF-API2 编程指南.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PDF:API2 编程指南PDF:API2 编程指南版本0.10 - 2004-08-20 - Original version posted at .au/clients/pdfapi2/0.20 - 2007-02-14 - 完成代码修正、文档更新、页面样式调整。下载链接修正。 指南编程样例PDF 是一种强有力的文档发布媒体,掌握对它的处理将为你带来很大的优势。不过要提醒的是文档中有不少相关的术语,所以你可以直接使用样例代码,不必强求全面深入的理解。这篇文档是用来教你使用 PDF:API2 这个模块的,它可以说是 Perl 程序员可以使用的最深入的 PDF 工具模块了。但是本文不会深入介绍 PDF 本身,如果你感兴趣的话,Adobe 的网站上有足够了解细节的规范可供下载。 为了使用 PDF:API2,有几个必要的步骤。这篇文章会涉及那些最基础的创建 PDF 的步骤。实际应用中应该还有很多其他的功能和选项可以考虑的。这篇文章最初是为了 PDF:API2 的 0.03.77 版本而编写的。如果你使用的是更早的版本,我建议你进行升级。当然不升级也许没问题,但是我不能保证。自从 0.04 版发布以来,我还没有发现有什么改动会与这个文档产生冲突。我是谁?我是一个 Perl 爱好者,就像你一样。只不过我在出版业工作了十二年以上,在印刷之前所有工序的技术问题上面都有些经验。我解决过的问题包括数据和软件相关的,也有颜色管理方面的,还有照排或系统相关的。在编写本文档的时候,我正在为一个项目工作。那个项目中需要使用 PDF:API2 来实现在线文具订购系统的精确预览功能。之后我还用 PDF:API2 为一个垃圾邮件过滤公司实现了较为复杂的报表系统。如何使用 PDFPDF 的优势是可以在一个文件中嵌入各种信息,比如颜色、文字,以及字体和图片。所有这些内容都可以用单个文件发布出去,然后既可以在屏幕上显示,也可以进行高精度的打印输出。PDF 的内置颜色管理功能对于那些高端输出系统来说是非常受欢迎的。因为 PDF 集成了这么许多功能,对于它的编程也会比较复杂,不过你还是可以逐渐上手。这个指南主要介绍了那些比较复杂的边框处理功能。也许有一天我会有时间进一步介绍其他的细节。不过对于 PDF 来说,你其实不必了解所有的细节也能使用它或进行相关的编程。你可以在 LGPL 协议的约束下使用 text_block 这个子程序。一些重要的 PDF 概念媒体框、出血框、媒体框和作品框当你观察一篇打印的文档时,可能会注意到某个图片或某个色块恰好覆盖到了纸的边界。让我告诉你一个秘密吧:其实它会超出边界!每个打印机生厂商可能会有不同程度的越界宽度,但是肯定都支持越界。这种界限被称为出血线。另外一件要注意的事就是我们并非在真正的纸张大小范围中打印。如果是那样的话,出血线以外的东西也会被打印在纸上,这可不是什么好事。所以在 A4 纸(或者信纸)上打印的时候,其实我们会稍稍超出 A4 的范围一些,这样出血线就能和纸张边缘尽量靠近。我们把纸张称为媒体,因为你可能还会在塑料、幻灯片、T恤等物品上打印。在打印之后,我们可以把打印件切成你需要的大小。这个界限就被称为裁切范围。理论上说,任何需要最终展示的信息都不应该超过这个范围,除非打印机有什么限制。现在还剩下的就是作品框了。这个范围顾名思义就是用来容纳真正重要的“艺术品”的地方。一般来说这个范围离裁切框的距离和出血框离裁切框的距离相等。这么规定是因为尽管现在的打印机都很精确,但是还不能算完美。如果你的文档中有些重要的内容超越了这个界限,那么很有可能在实际的输出中会看不到它。核心字体、postscript 字体、truetype 字体和构造字体如同之前介绍的,PDF 能把各种信息集成在一个文件中,也包括其中使用的字体。字体的来源比较多,但是对于 PDF:API2 来说,真正支持的字体其实只有核心字体、postscript 字体和 truetype 字体。我们不会在这个文档中介绍所有的字体,而只会使用核心字体,因为它完全不依赖于外部文件。度量系统以及座标原点PDF 默认情况下会使用”点“作为长度单位,不过这里的例子程序会显示如何使用那些大家更加习惯的单位(下面会看到,我用的是毫米)。座标轴的原点被定在 左下角 ,这类似于笛卡尔座标。一般来说我们习惯于把左上角定义为 (0,0),座标轴指向右下角。但是在处理 PDF 的时候,你需要习惯这种左下角为原点的座标系统。当然,要是能知道纸张的大小,那么应该很容易写一个函数进行两种座标的转换,不过这里不会介绍它的实现。软件安装安装 PDF:API2 的步骤在这个文档中不会介绍,不过类似于其他所有的 CPAN 模块的安装那样,在 Linux 或其他 Unix 衍生系统上你可以用下面的命令:sudo perl -MCPAN -e install PDF:API2如果你遇到了安装问题,那么可以问问系统管理员或者某个信得过的高手。实在不行的话还可以去 PerlMonks 碰碰运气. 创建文档一个例子在这个指南中,我们会创建一个如上的文件(你可以用自己的照片,我用的是前澳大利亚首相的照片)。这里要注意的是我们定义了裁切框,所以在 Acrobat、kpdf、xpdf 或者其他各种 PDF 浏览器中查看的时候,它看起来应该类似这样:你可以在这里下载源程序: pdf-api2.txt (10k 字节),最终生成的 PDF 文件在此下载: pdf-api2.pdf (59k 字节)载入模块大多数情况下,你只要 use 这个模块就可以了。这样,在需要的时候,它会自动调用软件包中附带的其他模块。当然,在这里我们还会一并 use strict 和 warnings,因为我们都是好程序员,不是么? 1: #!/usr/bin/perl 2: 3: use strict; 4: use warnings; 5: 6: use PDF:API2;定义基本常量这些常量使得 PDF:API2 的长度更加容易衡量。PDF 习惯于使用点来作为大小和长度的单位,而这些常量使我们能使用其他的单位。比如 5/mm 就能返回 5 毫米对应的点数。而这里的点数(pt)是用来更加清晰的显示长度单位是点数的情况。注意这些定义都不是必须的,只是为了便于使用 Perl 来创建 PDF 文件而已。对于那些喜欢数字的人:每英寸有 72 个 postscript 的点,而一英寸相当于 25.4 毫米。 8: use constant mm = 25.4 / 72; 9: use constant in = 1 / 72; 10: use constant pt = 1; 12: my ( $paragraph1, $paragraph2, $picture ) = get_data();定义 PDF这是创建 PDF 文件的第一步,而这里需要的仅仅是定义而已。这个例子中我们还一并设置了文件的名字,但这不是必须的,其实我们可以在最后再指定它。 14: my $pdf = PDF:API2-new( -file = $0.pdf );创建页面每当你调用 $pdf-page($page) 的时候,就会获得一个新的页面。这里 -page 方法其实调用了 PDF:API2:Page 类的构造器,只不过它还会把这个页面附加到当前 PDF 的末尾。如果你在调用此方法的时候还设置了页号,那么这个页面会插入到那一页之后;如果没有那么多页,那它就会成为文档的最后一页。 16: my $page = $pdf-page;设置属性对于 PDF 来说,每一页都可以有自己的大小定义。我们之前介绍了描述页面大小的四种边框。在这里例子里我们只会设置媒体框(纸张大小)和裁切框(裁剪后剩余的范围)。大多数边框会自动继承父容器的定义,所以这里真正需要定义的其实只有媒体框。这里媒体框只需要设置宽度和高度。而出血框, 裁切框和作品框都需要分别设置左、下、右、上边界。 17: $page-mediabox (105/mm, 148/mm); 18: #$page-bleedbox( 5/mm, 5/mm, 100/mm, 143/mm); 19: $page-cropbox (7.5/mm, 7.5/mm, 97.5/mm, 140.5/mm); 20: #$page-artbox ( 10/mm, 10/mm, 95/mm, 138/mm);定义字体字体是在 PDF 级别定义的,然后所有的页面都可以使用。所以一般是在程序开始时候进行定义,这样可以避免在 PDF 中反复嵌入相同的字体。类似页面的定义,我们可以用另一个函数来定义字体对象。在这个例子中,我们只会使用核心字体。这类的字体 Adobe 已经授权开发人员在文件中免费的使用了。另外,PDF:API2 还提供了一些微软授权使用的核心字体。如何存储这些对象是你的自由。我喜欢使用嵌套的哈希来集中存放它们,这样以后用起来显得更加方便些。但是,只要你高兴,可以把 Helvetica Bold 存储在 $foo 或者 $helveticabold 这样的变量中.你可能需要注释掉这里的某些行,因为它们可能不必定义。要知道,每定义一个字体,就会在 PDF 中多嵌入一种字体,哪怕你从来都没有用过它。 22: my %font = ( 23: Helvetica = 24: Bold = $pdf-corefont( Helvetica-Bold, -encoding = latin1 ), 25: Roman = $pdf-corefont( Helvetica, -encoding = latin1 ), 26: Italic = $pdf-corefont( Helvetica-Oblique, -encoding = latin1 ), 27: , 28: Times = 29: Bold = $pdf-corefont( Times-Bold, -encoding = latin1 ), 30: Roman = $pdf-corefont( Times, -encoding = latin1 ), 31: Italic = $pdf-corefont( Times-Italic, -encoding = latin1 ), 32: , 33: );做点有意义的事情目前为止还没有发生任何事情。如果你保存这个 PDF 文件(执行 $pdf-save; $pdf-close;),那么打开它时会看到一个空的 PDF 文件。现在我们开始做点有意义的事情。PDF 是自底向上创建的,后绘制的内容会浮在之前绘制的内容的上面。对于我们的样例 PDF 来说,有两个主要的区域:标题区域和文本区域。这两个区域互相不覆盖,所以我们先绘制哪个都可以。我们先从文档的顶部开始,首先定义那块蓝色的区域,因为它出现在其他对象的下面。追加内容绘制蓝色方块为了完成这个任务,我们需要从页面获取一个图形句柄。我们可以把它命名为 $gfx ,用它来完成所有图形元素的绘制,但是这样会导致 PDF 的事后编辑非常困难。如果你并不打算以后再编辑创建的文件,那么这样做是可以的。在这里,我们会每次用一个新的句柄来绘制新的对象。注意:一般认为最佳实践是每用完一个句柄就对它调用 save() 和 restore() 方法。也许我会在下一版实践它。 35: my $blue_box = $page-gfx;下一步我们需要设置的是画笔的颜色。记住,这里定义的只是颜色,我们还没有用它来绘制图形。不过类似于字体,哪怕没有用过的颜色,也会嵌入在 PDF 中。在 PDF:API2 中支持几种配色方案,这里我们打算使用的是商业的颜色名。如果将来对这个指南进行扩充,我会介绍那些高端输出设备支持的配色方案的使用。 36: $blue_box-fillcolor(darkblue);现在我们可以画方形区域了。这里需要的参数是左、下、宽、高四个位置,这里左边界和下边界都是相对于媒体框(而不是剪切框)的位置。所以我们将要绘制的方框是离左边界 5 毫米、离下边界 125 毫米开始,95 毫米宽、18 毫米高的。 37: $blue_box-rect( 5/mm, 125/mm, 95/mm, 18/mm );之前说过,颜色虽然定义好了,但是还没有使用过。现在就是我们用填充色来填充方框的时候了。在此之后我们可以切换填充色而不必担心影响方框,因为我们已经使用过了那种颜色。 38: $blue_box-fill;绘制红线下一步就是绘制红线。你小时候曾经学习过 logo 编程么?下面要做的事情和那很类似。首先我们从页面中获取另一个图形句柄(之前介绍过,我们可以使用从头到尾使用一个句柄,这对输出没有什么影响,但是对于事后的编辑来说是个灾难)。 40: my $red_line = $page-gfx;这一次我们需要设置的是前景色而不是填充色。不过还是同样的规则:这并不会使用这个颜色,只是定义而已。 41: $red_line-strokecolor(red);类似于 logo 中那样,你可以控制笔的抬起或放下。这里用 -move( $x, $y ) 函数来把笔抬起,并移到制定的座标。请记住 PDF 的座标原点是在左下角,而不是左上角。 42: $red_line-move( 5/mm, 125/mm );现在我们可以放下笔开始画线,直到下一个座标。 43: $red_line-line( 100/mm, 125/mm );最后,我们把刚才定义的前景色应用在线上。 44: $red_line-stroke;有用的文档到此为止,我们已经可以关闭 PDF 并查看结果了。你看到的应该是一个两端填满页面的蓝色方形区域,它下面有一条红线。你可能会感到奇怪,为什么它会从左边覆盖到右边呢?我们不是明明告诉它从 5 毫米处开始绘制的么?你还记得剪切框么?这里显示的 PDF 内容正是剪切框中的。如果你用的软件支持查看更大的区域,你可以让它显示媒体框。如果浏览器不支持这个特性的话,你还可以注释掉第 37 行设置剪切框的代码,然后再运行一次。现在你应该看到方块确实是从媒体框的 5 毫米处开始的了!追加文字之前我们已经定义了字体,现在就可以用它们了。我们的标题区域是 USING PDF:API2 几个字,它们靠右对齐。这里的右边界其实就是作品框,我们就把文字右边界设在这里。首先,我们获取一个文本句柄: 46: my $headline_text = $page-text;然后为它设置字体。-font() 方法的第一个参数就是我们之前创建并存储在哈希中的字体对象。第二个参数是字体的大小,在此我们指定 18 点大小。 47: $headline_text-font( $fontHelveticaBold, 18/pt );你应该已经能读懂这一行了: 48: $headline_text-fillcolor(white);要把文本写上去,我们需要把光标移到需要的位置。在这里,我们的理想位置是作品框的右边(95 毫米处),在媒体框上面的 131 毫米处。我们需要使用的函数是 -translate() 49: $headline_text-translate( 95/mm, 131/mm );在 PDF 文件中书写文本的函数很多,大多是为了单行文本而设计的,不过也有些函数能完成一段文本的书写。目前,我们只需要书写单行右对齐的文本: 50: $headline_text-text_right(USING PDF:API2);加上圆圈为了让文档的背景显得更有味道,我们会先画几个相交的圆圈。在我写这个教程的时候,这种设计还是比较流行的,这样我们就显得比较专业了。同样的,我们再次从页面获取图形句柄: 52: my $background = $page-gfx;设置前景色 53: $background-strokecolor(lightgrey);然后绘制圆圈这里 -circle() 函数有三个参数:前两个参数是圆心的 X 和 Y 轴座标(相对于左下角),第三个参数是半径大小。 54: $background-circle( 20/mm, 45/mm, 45/mm ); 55: $background-circle( 18/mm, 48/mm, 43/mm ); 56: $background-circle( 19/mm, 40/mm, 46/mm );最后,我们套用前景色。 57: $background-stroke;加上正文还是例行的步骤,如果你看不懂,请回到教程前面的部分,了解如何追加对象: 59: my $left_column_text = $page-text; 60: $left_column_text-font( $fontTimesRoman, 6/pt ); 61: $left_column_text-fillcolor(black);PDF:API2 有几个函数用来添加跨行的文本,另外还有一个名为 paragraph 的函数可以用来添加一段文本。我们现在需要添加的是多段的文本,所以我专门写了一个函数,名为 text_block。如果你对那个模块的工作原理有兴趣的话,请参考它自带的教程。这个函数的最简单调用接口是:($width_of_last_line, $ypos_of_last_line, $left_over_text) = text_block( $text_handler_from_page, $text_to_place, -x = $left_edge_of_block, -y = $baseline_of_first_line, -w = $width_of_block, -h = $height_of_block, -lead = $font_size * 1.2 | $distance_between_lines, -parspace = 0 | $extra_distance_between_paragraphs, -align = left|right|center|justify|fulljustify, -hang = $optional_hanging_indent,); 62: my ( $endw, $ypos, $paragraph ) = text_block( 63: $left_column_text, 64: $paragraph1, 65: -x = 10/mm, 66: -y = 119/mm, 67: -w = 41.5/mm, 68: -h = 110/mm - 7/pt, 69: -lead = 7/pt, 70: -parspace = 0/pt, 71: -align = justify, 72: );END OF WRITTEN TUTORIAL:目前为止剩下的内容只有代码,我暂时没有时间逐行解释。不过,到此为止你应该已经能读懂下面的代码了。 74: $left_column_text-font( $fontHelveticaBold, 6/pt ); 75: $left_column_text-fillcolor(darkblue); 76: ( $endw, $ypos, $paragraph ) = text_block( 77: $left_column_text, 78: Enim eugiamc ommodolor sendre feum zzrit at. Ut prat. Ut lum quisi., 79: -x = 10/mm, 80: -y = $ypos - 7/pt, 81: -w = 41.5/mm, 82: -h = 110/mm - ( 119/mm - $ypos ), 83: -lead = 7/pt, 84: -parspace = 0/pt, 85: -align = center, 86: ); 87: 88: $left_column_text-font( $fontTimesRoman, 6/pt ); 89: $left_column_text-fillcolor(black); 90: ( $endw, $ypos, $paragraph ) = text_block( 91: $left_column_text, 92: $paragraph2, 93: -x = 10/mm, 94: -y = $ypos, 95: -w = 41.5/mm, 96: -h = 110/mm - ( 119/mm - $ypos ), 97: -lead = 7/pt, 98: -parspace = 0/pt, 99: -align = justify, 100: ); 101: 102: my $photo = $page-gfx; 103: die(Unable to find image file: $!) unless -e $picture; 104: my $photo_file = $pdf-image_jpeg($picture); 105: $photo-image( $photo_file, 54/mm, 66/mm, 41/mm, 55/mm ); 106: 107: my $right_column_text = $page-text; 108: $right_column_text-font( $fontTimesRoman, 6/pt ); 109: $right_column_text-fillcolor(black); 110: ( $endw, $ypos, $paragraph ) = text_block( 111: $right_column_text, 112: $paragraph, 113: -x = 54/mm, 114: -y = 62/mm, 115: -w = 41.5/mm, 116: -h = 54/mm, 117: -lead = 7/pt, 118: -parspace = 0/pt, 119: -align = justify, 120: -hang = xB7 , 121: ); 122: 123: $pdf-save; 124: $pdf-end(); 125: 126 sub text_block 127: 128: my $text_object = shift; 129: my $text = shift; 130: 131: my %arg = _; 132: 133: # Get the text in paragraphs 134: my paragraphs = split( /n/, $text ); 135: 136: # calculate width of all words 137: my $space_width = $text_object-advancewidth( ); 138: 139: my words = split( /s+/, $text ); 140: my %width = (); 141: foreach (words) 142: next if exists $width$_; 143: $width$_ = $text_object-advancewidth($_); 144: 145: 146: $ypos = $arg-y; 147: my paragraph = split( / /, shift(paragraphs) ); 148: 149: my $first_line = 1; 150: my $first_paragraph = 1; 151: 152: # while we can add another line 153: 154: while ( $ypos = $arg-y - $arg-h + $arg-lead ) 155: 156: unless (paragraph) 157: last unless scalar paragraphs; 158: 159: paragraph = split( / /, shift(paragraphs) ); 160: 161: $ypos -= $arg-parspace if $arg-parspace; 162: last unless $ypos = $arg-y - $arg-h; 163: 164: $first_line = 1; 165: $first_paragraph = 0; 166: 167: 168: my $xpos = $arg-x; 169: 170: # while theres room on the line, add another word 171: my line = (); 172: 173: my $line_width = 0; 174: if ( $first_line & exists $arg-hang ) 175: 176: my $hang_width = $text_object-advancewidth( $arg-hang ); 177: 178: $text_object-translate( $xpos, $ypos ); 179: $text_object-text( $arg-hang ); 180: 181: $xpos += $hang_width; 182: $line_width += $hang_width; 183: $arg-indent += $hang_width if $first_paragraph; 184: 185: 186: elsif ( $first_line & exists $arg-flindent ) 187: 188: $xpos += $arg-flindent; 189: $line_width += $arg-flindent; 190: 191: 192: elsif ( $first_paragraph & exists $arg-fpindent ) 193: 194: $xpos += $arg-fpindent; 195: $line_width += $arg-fpindent; 196: 197: 198: elsif ( exists $arg-indent ) 199: 200: $xpos += $arg-indent; 201: $line_width += $arg-indent; 202: 203: 204: 205: while ( paragraph 206: and $line_width + ( scalar(line) * $space_width ) 207 $width $paragraph0 translate( $xpos, $ypos ); 240: $text_object-text($word); 241: 242: $xpos += ( $width$word + $wordspace ) if (line); 243: 244: 245: $endw = $arg-w; 246: 247: else 248: 249: # calculate the left hand position of the line 250: if ( $align eq right ) 251: $xpos += $arg-w - $line_width; 252: 253: 254: elsif ( $align eq center ) 255: $xpos += ( $arg-w / 2 ) - ( $line_width / 2 ); 256: 257: 258: 259: # render the line 260: $text_object-translate( $xpos, $ypos ); 261: 262: $endw = $text_object-text( join( , line ) ); 263: 264: 265: $ypos -= $arg-lead; 266: $first_line = 0; 267: 268: 269: unshift( paragraphs, join( , paragraph ) ) if scalar(paragraph); 270: 271: return ( $endw, $ypos, join( n, paragraphs ) ) 272: 273: 274: 275: # SAVE ROOM AT THE TOP # 276 sub get_data 277: ( 278: qq|Perci ent ulluptat vel eum zzriure feuguero core consenis adignim irilluptat praessit la con henit velis dio ex enim ex ex euguercilit il enismol eseniam, suscing essequis nit iliquip erci blam dolutpatisi. 279: Orpero do odipit ercilis ad er augait ing ex elit autatio od minisis amconsequam, quis am il do consenim esequi eui blamcorer adiat. Ut prat la facip ercip eugiamconsed tio do exero ea consequis do odolor il dolut wisim adit, susciniscing et adit num num vel ip ercilit alismolorem zzril ute dolendre ming eu feui bla feugait il illa facin eu feugiam conseniam eliquisl et luptat la feu feugait, volore euguerc incillu msandigna feuipisl iriuscilit velit wisl utem veros ad min velit laor iuscilit veliquis ad tie endignim dignisl et, qui bla feugue mod enibh esendiam, si blaor si blaore te min vel utpat nonsequ issequis dolorperosto dolobore ex erit, vel in utating etum ad dolutatet la feugiatue mod euisci blandre tat iurem eum velit prat nosting essim ver aliscil dolortie cor alisit wisl delesti sciduisci ting eu feu facidunt autat. Duipis amcommy non er sit, commy numsand ionsequam, commy num alisim euis dio eu faciduisit ate moloreet, quam zzrillaore magnit eum dolor ipsum dunt dolor sequatie dolor iustrud te molum dolore velit la faccum zzriuscil utpat irit nummod magna alis eu faccum inibh erosto ea ad magniamet vel esto dipsusto elesting eugiam, commolobore deliquat praessenim et, vel ut et nibh et adit lortisi.|, 280: 281: qq|It augait ate magniametum irit, venim doloreet augiamet ilit alis nonse dolore delessit volor susto od ming eugiam voloborem ip ea faciduisis alit, vent nim nulput utat endre dolum quissit atem nim dolorperci tat dunt veliquat ipis acip elenit lum d

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论