c语言调用pdf文档,使用PDFLib生成PDF文档方法介绍(C语言版)

本文介绍了如何使用PDFLib在C语言环境中创建、编辑和嵌入PDF文档,包括基本环境设置、文字输出、图像和图形处理、颜色管理以及嵌入PDF页面。重点讲解了字体加载、颜色模式、图像缩放和复杂图形操作等内容。
摘要由CSDN通过智能技术生成

本文简单介绍了PDFLib生成PDF文档(C语言版)的基本使用方法。

1.基本环境

① 打开、关闭、文档信息设定:

新建PDFLib对象,PDF_new()

设定错误处理的方式,PDF_set_parameter(p, "errorpolicy", "return"),return标示当发生错误时直接从Lib函数中返回。

设定文档信息,PDF_set_value()

新建一个PDF文件,PDF_begin_document()

新建一个页面,PDF_begin_page_ext()

关闭一个页面,PDF_end_page_ext()

关闭PDF文件,PDF_end_document()

释放PDFLib对象,PDF_delete()

例外处理,PDF_TRY()和PDF_CATCH()

② 示例代码:

#include

#include "pdflib.h"

int main(int argc, char *argv[])

{

Example();

return 0;

}

int Example(void)

{

PDF *p;

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, "d://hello.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_parameter(p, "fakebold", "true");

PDF_set_info(p, "Creator", "hello.c");

PDF_set_info(p, "Author", "Thomas Merz");

PDF_set_info(p, "Title", "Hello, world (C)!");

PDF_begin_page_ext(p, a4_width, a4_height, "");

PDF_setcolor(p, "fill", "cmyk", 1, 0,0,0);

PDF_rect(p, 250,250, 100, 50);

PDF_fill(p);

PDF_end_page_ext(p, "");

PDF_end_document(p, "");

}

PDF_CATCH(p) {

printf("PDFlib exception occurred in sample:/n");

printf("[%d] %s: %s/n",

PDF_get_errnum(p), PDF_get_apiname(p), PDF_get_errmsg(p));

PDF_delete(p);

getchar();

return(2);

}

PDF_delete(p);

return 0;

}

2.文字输出

① 加载字体

使用PDF_load_font()函数。目前在Windows 平台下,似乎只能加载可以安装到Windows系统中的字体。

如果加载已经安装到系统中的字体(在C:/windows/fonts文件夹下),可以直接通过字体的名字加载,如:

font = PDF_load_font(p, "MS UI Gothic", 0, "host", "");

font = PDF_load_font(p, "MKZ2", 0, "unicode", "");

也可以通过制定字体文件加载字体,如:

PDF_set_parameter(p, "FontOutline", "MKZ2=C://windows//fonts// MKZ2.ttf");

font= PDF_load_font(p, "MKZ2", 0, "unicode", "");

"host"和"unicode"是用于字体编码的方式,host日文系统下具体与代码页cp932等相关,中文系统下与cp936相关。Unicode与PDF所规定的CMAP文件相关,如:UniJIS-UCS2-H、EUC-H等的编码文件。因为字体已经安装到了Windows系统中,具体的字体编码方式,操作系统能够自动处理,无需我们显式的指定。

加载字体是一件很耗费时间的工作,大概能占到整个处理的1/4左右。PDFLib已经作了些优化,当一个字体只要加载过一次,再次加载就会使用前面产生的字体句柄,不再重新生成。

PDFLIb加载字体时默认是嵌入的,这样会增大输出的PDF文件。好处是当文件被移动到其他系统上时,打开文件时不受字体的影响,否则,打开文件前需要先安装字体。我们这次的项目,生成的PDF文件需要用FTP转送到Solaris系统,并且要送入打印机,所以必须以嵌入方式加载的字体。

② 设置字体

使用PDF_setfont()函数,如:

PDF_setfont(p, font, 30);

30指的是字号,也就是字体的高度。但这个和系统的缩放比例相关。如果设字体前设定系统的缩放比例为2,实际输出的字体的高度为60个单位。PSEdit的字体的输出过程中,绝大部分采用的是变换系统坐标的方法来确定字体的大小,所以编程中使用了PDF_setfont(p, font, 1)的方式,即字体的大小为当前系统的缩放比例的值相同。

③ 文字输出

PDFLib的文字处理,较PostScript而言,加强了功能,增加了大量文字及段落等的处理。但本次PSEdit编程中,受于以前软件框架的限制,只使用了单字输出的功能PDF_info_textline(),尽管这个函数也能用于输出一个字符串。

PDF_info_textline函数有个选项列表,提供的功能相当丰富。基本上覆盖了对字体的所有的变化和变形。如:倾斜、旋转、缩放、着色、偏移以及指定字体等等。

④ 文字阴影

采用在相互错开的位置上输出两次同样的字符,实现阴影。

⑤ 空心字

通过指定PDF_info_textline函数的三个选项参数textrendering、strokewidth 、strokecolor来实现。如输出空心字,边缘宽1个单位,边缘色为青色,边缘线圆头连接:

PDF_setlinejoin(p, 1);

PDF_fit_textline(p, "ABCDEF", 0, 50, 550, "textrendering=1 strokewidth=1 strokecolor={CMYK 1 0 0 0}");

⑥ 立体字和艺术字,这个属于描画字的范围,输出方式是组合起来的多组直线和曲线,线段封闭后,剪切区域形成字体的轮廓区域,然后再用某中颜色或填充模式进行填充。所以每一个立体字和艺术字,都是一个复杂的剪切图形。

3.图像输出

①   图像的输出使用PDF_load_image和PDF_fit_image,输出图像变得相当简单了。当然,简单的副作用就是,限制了许多对所加载的图像的处理功能。保留的几个功能是:着色,缩放,旋转。这似乎对一般的PDF文件也足够了。

②   图像的最小网点,似乎只是报纸打印行业为了使图像不失真而采取的一种特殊的图像离散化处理。这种处理功能在很通用的图像处理中间件LeadTools中没有提供,可见最小网点并非一种普遍适用的图像处理手段,应该在更为专业性的图像处理工具中才有。

4.图形输出

① 路径(path),指的是某个特定区域的边界。路径是任何图形的基础。

② 能够长生路径的操作事实上只有两种:画直线(PDF_moveto,PDF_lineto)和画曲线(圆PDF_circle、弧PDF_arc和PDF_arcn、曲线PDF_curveto)

③ 描边(PDF_stroke),沿路经使用指定的颜色(PDF_setcolor)和指定的线宽(PDF_setlinewidth)进行着色。

④ 填充(PDF_fill),首先关闭路径(PDF_closepath把最后一个点和开始点连接直线),然后用指定的颜色(PDF_setcolor)对封闭区域着色。

⑤ 梯度填充(PDF_shfill),是从一种颜色平滑过渡到令一种颜色的填充。填充前先需要生成颜色模式(PDF_shading)。例如梯度填充一个矩形,颜色为从蓝色从红色过渡:

PDF_setcolor(p, "fill", "cmyk", 1, 0, 0, 0);

PDF_rect(p, 200 , 500, 200, 100);

PDF_clip(p);

handle = PDF_shading( p, "axial", 210, 550, 350, 550, 0, 1, 0, 0,"extend0=true extend1=true N=1" );

PDF_shfill( p, handle );

要实现多组颜色梯度填充,只能把区域安相关颜色分成多个区域,每个区域安两种颜色填充。

⑥ 剪切(PDF_clip),把当前封闭的区域独立出来,任何超出这个剪切区域的操作都将无效。剪切,尤其是复杂区域的剪切是图形图像处理中的高级处理,其低层实现需要极高超的编程技巧和理论水平。剪切处理应当说是PostScript和PDF中最具有技术含量的部分。

剪切时值得注意的是,要恢复到前切前的状态,只能使用PDF_save和PDF_restore完成。

⑦ 坐标变换:位移(PDF_translate)、旋转(PDF_rotate)、缩放(PDF_scale)、歪斜(PDF_skew)、应用转换矩阵(PDF_concate)。这种对于应用者而言比较简单的坐标系统,其实是整个系统的精华所在,它为各种形式的图形表现,提供的最基本和坚实的支持。

5.嵌入PDF文档

① 把其他的PDF文件的页嵌入到当前的PDF文件中,可以指定位置、大小、旋转,但无法改变颜色。例:

handle = PDF_open_pdi_document(p, "d://font.pdf", 0, "");

if (handle == -1) {

printf("Error: %s/n", PDF_get_errmsg(p));

return(2);

}

page = PDF_open_pdi_page(p, handle, 1, "");

if (handle == -1) {

printf("Error: %s/n", PDF_get_errmsg(p));

return(2);

}

PDF_fit_pdi_page(p, page, 50, 150, "");

PDF_close_pdi_page(p, page);

PDF_close_pdi_document(p, handle);

6.颜色

① CMYK色:和本次开发相关的颜色空间是CMYK色彩空间。颜色的值为0~1,全部为0标示白色,全部为1表示黑色。

② 专色:和这个名字反映出来的意思一样,就是某种特殊的颜色。一般都和打印机相关,指某种超出打印机混合色之外的颜色。

在PSEdit的改造过程中使用了两个(但不一定都用了)自定义的特色:S1和S2。没有使用其他的­(如工业标准定义的)特色。但为什么要这么做,我还无法理解,也许仅仅是为了分版的需要,

③ 在PDFLib中,每一个特色都得按一个颜色空间的级别对待。比如画一条线,除了基本的CMYK色要画一次外,应用几个特色,就需要重画几次,在PDF文件中,可以设定OverPrint属性,来查看最终的(混合色)显示效果。

④ 例:

调用内置专色:

handle = PDF_makespotcolor(p, "PANTONE 871 C", 0);

PDF_setcolor(p, "stroke", "spot", handle, 0.5, 0, 0);

PDF_moveto(p, 100, 620);

PDF_lineto(p, 250, 620);

PDF_stroke(p);

生成自定义专色:

PDF_setcolor(p, "stroke", "cmyk", 0, 0, 1, 0);

handle = PDF_makespotcolor(p, "S1", 0);

PDF_setcolor(p, "stroke", "spot", handle, 0.4, 0, 0);

PDF_moveto(p, 100, 620);

PDF_lineto(p, 250, 620);

PDF_stroke(p);

标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至hey@evget.com

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言教程(原书第4) 《c语言教程(原书第4)》是一本优秀的c程序设计语言教材,完整描述了ansi c语言及其语法特性,并对c语言的高级特性和应用作了深入阐述,介绍了从c到c++和java过渡的相关知识。《c语言教程(原书第4)》的一个鲜明特色就是结合大量示例描述c语言的重要特征,并对很多工作代码给出了逐步的分析,以这种独特的教学方法向读者解释新接触的编程元素及一些惯用法。   《c语言教程(原书第4)》系统、完整,可作为c语言的参考手册,也非常适合作为学习c语言的入门和高级课程教材。 前言 第0章 从零开始 0.1 为什么要用c 0.2 ansi c标准 0.3 从c到c++ 0.4 从c和c++到java 第1章 c语言概述 1.1 编程和预备知识 1.2 程序输出 1.3 变量、表达式和赋值 1.4 使用#define和#include 1.5 使用printf()和scanf() 1.6 控制流 1.7 函数 1.8 数组、字符串和指针 1.8.1 数组 1.8.2 字符串 1.8.3 指针 1.9 文件 1.10 与操作系统有关的内容 1.10.1 编写和运行c程序 1.10.2 中断程序 1.10.3 输入文件尾标志 1.10.4 输入和输出的重定向 1.11 总结 1.12 练习 第2章 词法元素、操作符和c系统 2.1 字符和词法元素 2.2 语法规则 2.3 注释 2.4 关键字 2.5 标识符 2.6 常量 2.7 字符串常量 2.8 操作符和标点符号 2.9 操作符的优先级和结合性 2.10 增值操作符和减值操作符 2.11 赋值操作符 2.12 例子:计算2的乘方 2.13 c系统 2.13.1 预处理器 2.13.2 标准函数库 2.14 总结 2.15 练习 第3章 基本数据类型 3.1 声明、表达式和赋值 3.2 基本数据类型 3.3 字符和char数据类型 3.4 int数据类型 3.5 整数类型short、long和unsigned 3.6 浮点类型 3.7 typedef的用法 3.8 sizeof操作符 3.9 使用getchar()和putchar() 3.10 数学函数 3.10.1 使用abs()和fabs() 3.10.2 unix和数学函数库 3.11 隐式类型转换和强制类型转换 3.11.1 整型提升 3.11.2 寻常算术转换 3.11.3 强制类型转换 3.12 十六进制和八进制常量 3.13 总结 3.14 练习 第4章 控制流 4.1 关系操作符、相等操作符和逻辑操作符 4.2 关系操作符和表达式 4.3 相等操作符和表达式 4.4 逻辑操作符和表达式 4.5 复合语句 4.6 表达式和空语句 4.7 if和if-else语句 4.8 while语句 4.9 for语句 4.10 例子:布尔变量 4.11 逗号操作符 4.12 do语句 4.13 例子:斐波那契数 4.14 goto语句 4.15 break和continue语句 4.16 switch语句 4.17 条件操作符 4.18 总结 4.19 练习 第5章 函数 5.1 函数定义 5.2 return语句 5.3 函数原型 5.4 例子:创建乘方表 5.5 从编译器的角度观察函数原型 5.6 函数定义顺序的另一种风格 5.7 函数调用和传值调用 5.8 开发大型程序 5.9 使用断言 5.10 作用域规则 5.10.1 平行和嵌套代码块 5.10.2 以调试为目的使用代码块 5.11 存储类型 5.11.1 auto存储类型 5.11.2 extern存储类型 5.11.3 register存储类型 5.11.4 static存储类型 5.12 静态外部变量 5.13 默认初始化 5.14 递归 5.15 例子:汉诺塔 5.16 总结 5.17 练习 第6章 数组、指针和字符串 6.1 一维数组 6.1.1 初始化 6.1.2 下标 6.2 指针 6.3 传引用调用 6.4 数组和指针之间的关系 6.5 指针运算和元素的大小 6.6 数组作为函数的实参 6.7 例子:冒泡排序 6.8 用calloc()和malloc()进行动态内存分配 6.9 例子:归并和归并排序 6.10 字符串 6.11 标准函数库中的字符串处理函数 6.12 多维数组 6.12.1 二维数组 6.12.2 存储映射函数 6.12.3 形式参数声明 6.12.4 三维数组 6.12.5 初始化 6.12.6 使用typedef 6.13 指针数组 6.14 main()函数的参数 6.15 不规则数组 6.16 函数作为参数 6.17 例子:使用二分法寻找函数的根 6.18 函数指针数组 6.19 类型限定符const和volatile 6.20 总结 6.21 练习 第7章 位操作符和枚举类型 7.1 位操作符和表达式 7.1.1 按位求反 7.1.2 补码 7.1.3 位逻辑操作符 7.1.4 左移位和右移位操作符 7.2 掩码 7.3 软件工具:打印int值的二进制形式 7.4 包装和解包 7.5 枚举类型 7.6 例子:“石头、剪刀、布”游戏 7.7 总结 7.8 练习 第8章 预处理器 8.1 #include的使用 8.2 使用#define 8.3 带参数的宏 8.4 stddef.h中的类型定义和宏 8.5 例子:用qsort()进行排序 8.6 例子:带参数的宏 8.7 stdio.h和ctype.h中的宏 8.8 条件编译 8.9 预定义的宏 8.10 “#”和“##”操作符 8.11 assert()宏 8.12 使用#error和#pragma 8.13 行号 8.14 对应的函数 8.15 例子:快速排序 8.16 总结 8.17 练习 第9章 结构和联合 9.1 结构 9.2 访问结构成员 9.3 操作符的优先级和结合性的总结 9.4 在函数中使用结构 9.5 结构的初始化 9.6 例子:玩扑克牌 9.7 联合 9.8 位字段 9.9 例子:访问位和字节 9.10 adt堆栈 9.11 总结 9.12 练习 第10章 结构和列表处理 10.1 自引用的结构 10.2 线性链表 10.3 链表操作 10.4 一些链表处理函数 10.4.1 插入 10.4.2 删除 10.5 堆栈 10.6 例子:波兰记法和堆栈求值 10.7 队列 10.8 二叉树 10.8.1 二叉树的遍历 10.8.2 创建树 10.9 普通的树 10.9.1 遍历 10.9.2 calloc()的用法以及树的创建 10.10 总结 10.11 练习 第11章 输入/输出和操作系统 11.1 输出函数printf() 11.2 输入函数scanf() 11.3 fprintf()、fscanf()、sprintf() 和sscanf()函数 11.4 fopen()和fclose()函数 11.5 例子:对文件进行空间加倍 11.6 使用临时文件和优雅函数 11.7 随机访问文件 11.8 文件描述符输入/输出 11.9 文件访问权限 11.10 在c程序内部执行命令 11.11 在c程序内部使用管道 11.12 环境变量 11.13 c编译器 11.14 使用性能评估程序 11.15 函数库 11.16 对c代码进行计时 11.17 使用make 11.18 使用touch 11.19 其他有用的工具 11.20 总结 11.21 练习 第12章 高级应用 12.1 用fork()创建并发进程 12.2 进程的叠加:exec...()函数族系 12.3 使用pipe()实现进程间的通信 12.4 信号 12.5 例子:哲学家用餐问题 12.6 矩阵的动态分配 12.6.1 为什么二维数组无法满足要求 12.6.2 用指针数组创建矩阵 12.6.3 调整下标范围 12.6.4 一次分配所有内存 12.7 返回状态 12.8 总结 12.9 练习 第13章 从c到c++ 13.1 输出 13.2 输入 13.3 函数 13.4 类和抽象数据类型 13.5 重载 13.6 构造函数和析构函数 13.7 面向对象编程和继承 13.8 多态 13.9 模板 13.10 c++的异常 13.11 面向对象编程的优点 13.12 总结 13.13 练习 第14章 从c到java 14.1 输出 14.2 变量和类型 14.3 类和抽象数据类型 14.4 重载 14.5 类的创建和销毁 14.6 面向对象编程和继承 14.7 多态和重写方法 14.8 applet 14.9 java的异常 14.10 java和oop的优势 14.11 总结 14.12 练习 附录a 标准函数库 附录b c的语法 附录c ansi c与传统c的比较 附录d ascii字符码 附录e 操作符的优先级和结合性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值