Quartz 2D编程指南- PDF文档的创建、显示及转换

本文由论坛会员德鲁伊分享

         PDF 文档存储依赖于分辨率的向量图形、文本和位图,并用于程序的一系列指令中。一个PDF文档可以包含多页的图形和文本。PDF可用于创建跨平台、只读的文档,也可用于绘制依赖于分辨率的图形。
         Quartz 为所有 应用 程序创建高保真的PDF文档,这些文档保留应用的绘制操作,如图13-1所示。PDF文档的结果将通过系统的其它部分或第三方法的 产品 来有针对性地进行优化。Quartz创建的PDF文档在Preview和Acrobat中都能正确的 显示 。

 

         Quartz 不仅仅只使用PDF作为它的数字页,它同样包含一些API来显示和生成PDF文件,及完成一些其它PDF相关的工作。

打开和查看PDF
         Quartz 提供了CGPDFDocumentRef数据类型来表示PDF文档。我们可以使用CGPDFDocumentCreateWithProvider或CGPDFDocumentCreateWithURL来创建CGPDFDocument对象。在创建CGPDFDocument对象后,我们可以将其绘制到图形上下文中。图13-2显示了在一个窗体中绘制PDF文档。


 
代码 清单13-1显示了如何创建一个CGPDFDocument对象及获取文档的页数。

 
复制代码
  1. CGPDFDocumentRefMyGetPDFDocumentRef (const char *filename)
  2. {
  3. CFStringRef path;
  4. CFURLRef url;
  5. CGPDFDocumentRef document;
  6. size_t count;
  7.  
  8. path = CFStringCreateWithCString (NULL, filename, kCFStringEncodingUTF8);
  9.  
  10. url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle,0);  // 1 创建CFURL对象
  11.  
  12. CFRelease (path);
  13.  
  14. document = CGPDFDocumentCreateWithURL (url);                 // 2 创建CFPDFDocument对象
  15. CFRelease(url);
  16.  
  17. count = CGPDFDocumentGetNumberOfPages (document);    // 3 获取文档页数
  18. if (count == 0) {
  19.     printf("`%s' needs at least onepage!", filename);
  20.     return NULL;
  21. }
  22.  
  23. return document;
  24. }



代码清单显示了如何将一个PDF页绘制到图形上下文中。

 
复制代码
  1. void MyDisplayPDFPage (CGContextRefmyContext, size_t pageNumber, const char *filename)
  2. {
  3. CGPDFDocumentRef document;
  4. CGPDFPageRef page;
  5.  
  6. document = MyGetPDFDocumentRef (filename);                                   // 1 创建PDFDocument对象
  7. page = CGPDFDocumentGetPage (document, pageNumber);           // 2 获取指定页的PDF文档
  8. CGContextDrawPDFPage (myContext, page);                                       // 3 将PDF绘制到图形上下文中
  9. CGPDFDocumentRelease (document);
  10. }



为PDF页创建一个转换
     Quartz 提供了函数CGPDFPageGetDrawingTransform来创建一个仿射变换,该变换基于将PDF页的BOX映射到指定的矩形中。函数原型是:

 
复制代码
  1. CGAffineTransformCGPDFPageGetDrawingTransform (
  2. CGPPageRef page,
  3. CGPDFBox box,
  4. CGRect rect,
  5. int rotate,
  6. bool preserveAspectRatio
  7. );



该函数通过如下算法来返回一个仿射变换:
·  将在box参数中指定的PDF box的类型相关的矩形(media, crop, bleed, trim, art)与指定的PDF页的/MediaBox入口求交集。相交的部分即为一个有效的矩形(effectiverectangle)。
·  将effective rectangle旋转参数/Rotate入口指定的角度。
·  将得到的矩形放到rect参数指定的中间。
·  如果rotate参数是一个非零且是90的倍数,函数将effective rectangel旋转该值指定的角度。正值往右旋转;负值往左旋转。需要注意的是我们传入的是角度,而不是弧度。记住PDF页的/Rotate入口也包含一个旋转,我们提供的rotate参数是与/Rotate入口接合在一起的。
·  如果需要,可以缩放矩形,从而与我们提供的矩形保持一致。
·  如果我们通过传递true值给preserveAspectRadio参数以指定保持长宽比,则最后的矩形将与rect参数的矩形的边一致。

【注:上面这段翻译得不是很好】

例如,我们可以 使用 这个函数来创建一个与图13-3类似的PDF浏览程序。如果我们提供一个Rotate Left/Rotate Right属性,则可以调用CGPDFPageGetDrawingTransform来根据当前的窗体大小和旋转设置计算出适当的转换。



程序清单13-3显示了为一个PDF页创建及应用仿射变换,然后绘制PDF。

 
复制代码
  1. Listing 13-3  Creating an affine transform for aPDF page
  2. void MyDrawPDFPageInRect(CGContextRef context, CGPDFPageRef page, CGPDFBox box, CGRect rect, int rotation, bool preserveAspectRatio)
  3. {
  4. CGAffineTransform m;
  5.  
  6. m = CGPDFPageGetDrawingTransform (page, box, rect, rotation, preserveAspectRato);
  7.  
  8. CGContextSaveGState (context);
  9.  
  10. CGContextConcatCTM (context, m);
  11.  
  12. CGContextClipToRect (context,CGPDFPageGetBoxRect (page, box));
  13.  
  14. CGContextDrawPDFPage (context, page);
  15.  
  16. CGContextRestoreGState (context);
  17.  



创建PDF文件
使用Quartz创建PDF与绘制其它图形上下文一下简单。我们指定一个PDF文件地址,设置一个PDF图形上下文,并使用与其它图形上下文一样的绘制程序。如代码清单13-4所示的MyCreatePDFFile函数,显示了创建一个PDF的所有工作。
注意,代码在CGPDFContextBeginPage和CGPDFContextEndPage中来绘制PDF。我们可以传递一个CFDictionary对象来指定页属性,包括media, crop, bleed,trim和art boxes。
Listing 13-4   Creating a PDF file

 
复制代码
  1. void MyCreatePDFFile (CGRectpageRect, const char *filename)
  2. {
  3. CGContextRef pdfContext;
  4. CFStringRef path;
  5. CFURLRef url;
  6. CFData boxData = NULL;
  7. CFMutableDictionaryRef myDictionary = NULL;
  8. CFMutableDictionaryRef pageDictionary = NULL;
  9.  
  10. path = CFStringCreateWithCString (NULL, filename, kCFStringEncodingUTF8);
  11.  
  12. url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0);
  13.  
  14. CFRelease (path);
  15.  
  16. myDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
  17.  
  18. CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("MyPDF File"));
  19.  
  20. CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("MyName"));
  21.  
  22. pdfContext = CGPDFContextCreateWithURL (url, &pageRect,myDictionary);
  23.  
  24. CFRelease(myDictionary);
  25.  
  26. CFRelease(url);
  27.  
  28. pageDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
  29.  
  30. boxData = CFDataCreate(NULL,(const UInt8 *)&pageRect, sizeof(CGRect));
  31.  
  32. CFDictionarySetValue(pageDictionary, kCGPDFContextMediaBox, boxData);
  33.  
  34. CGPDFContextBeginPage (pdfContext, &pageRect);
  35.  
  36. myDrawContent (pdfContext);
  37.  
  38. CGPDFContextEndPage (pdfContext);
  39.  
  40. CGContextRelease (pdfContext);
  41.  
  42. CFRelease(pageDictionary);
  43.  
  44. CFRelease(boxData);
  45. }



添加链接
我们可以在PDF上下文中添加链接和锚点。Quartz提供了三个函数,每个函数都以PDF图形上下文作为参数,还有链接的信息:
·  CGPDFContextSetURLForRect 可以让我们指定在点击当前PDF页中的矩形时打开一个URL。
·  CGPDFContextSetDestinationForRect 指定在点击当前PDF页中的矩形区域时设置目标以进行跳转。我们需要提供一个目标名。
·  CGPDFContextAddDestinationAtPoint 指定在点击当前PDF页中的一个点时设置目标以进行跳转。我们需要提供一个目标名。

保护PDF内容
为了保护PDF内容,我们可以在辅助字典中指定一些安全选项并传递给CGPDFContextCreate。我们可以通过包含如下关键字来设置所有者密码、用户密码、PDF是否可以被打印或拷贝:
·  kCGPDFContextOwnerPassword:  定义PDF文档的所有者密码。如果指定该值,则文档使用所有者密码来加密;否则文档不加密。该关键字的值必须是ASCII编码的CFString对象。只有前32位是用于密码的。该值没有默认值。如果该值不能表示成ASCII,则无法创建文档并返回NULL。Quartz使用40-bit加密。
·  kCGPDFContextUserPassword:  定义PDF文档的用户密码。如果文档加密了,则该值是文档的用户密码。如果没有指定,则用户密码为空。该关键字的值必须是ASCII编码的CFString对象。只有前32位是用于密码的。如果该值不能表示成ASCII,则无法创建文档并返回NULL。
·  kCGPDFContextAllowsPrinting: 指定当使用用户密码锁定时文档是否可以打印。该值必须是CFBoolean对象。默认值是kCGBooleanTrue。
·  kCGPDFContextAllowsCopying:  指定当使用用户密码锁定时文档是否可以拷贝。该值必须是CFBoolean对象。默认值是kCGBooleanTrue。
代码清单14-4(下一章)显示了确认PDF文档是否被锁定,及用密码打开文档。

原文链接: http://www.cocoachina.com/bbs/read.php?tid=83761

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值