处理adobe打印pdf不全问题
问题
wine下使用adobe打开pdf文件后打印到cups-pdf打印机的时候无法打印pdf图片
分析
- 使用wine10.14打印,打印多页但是pdf打印机输出的pdf只有一页
- 打开psdrv和winspool发现startpage/endpage存在次数和我本地pdf页数文件一致
1
2
3
4
5
6
7
80184:trace:psdrv:PSDRV_StartPage 440101A3
0184:trace:psdrv:PSDRV_EndPage 440101A3
0184:trace:psdrv:PSDRV_StartPage 440101A3
0184:trace:psdrv:PSDRV_EndPage 440101A3
0184:trace:psdrv:PSDRV_StartPage 440101A3
0184:trace:psdrv:PSDRV_EndPage 440101A3
0184:trace:psdrv:PSDRV_StartPage 440101A3
0184:trace:psdrv:PSDRV_EndPage 440101A3 - wine中模拟window打印是将打印的目标pdf文件转换为ps(Photo Graphic)文件进行输出
- 截取wine下打印数据目前在高版本wine下需要从
/dlls/localspl/cups.c中打印逻辑中提取1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24static NTSTATUS write_doc(void *args)
{
const struct write_doc_params *params = args;
doc_t *doc = (doc_t *)(size_t)params->doc;
/* =========== 新增:保存 PostScript 数据 =========== */
static FILE *ps_file = NULL;
if (!ps_file)
{
ps_file = fopen("/tmp/wine_print.ps", "wb");
if (!ps_file)
ERR("Failed to open PS debug file\n");
}
if (ps_file)
{
fwrite(params->buf, 1, params->size, ps_file);
fflush(ps_file);
TRACE("Saved %u bytes to /tmp/wine_print.ps\n", params->size);
}
/* =============================================== */
return doc->write_doc(doc, params->buf, params->size);
} - 打印截取的
.ps文件直接用pdf查看工具打开发现页面正常 - 将该
ps文件使用lpr命令打印发现文件只有第一页,后面的未能正常显示 - 查看
/var/spool/cups/d00060-001文件,该文件是发送至cups的文件,该文件也是正常的 - 怀疑本地pdf打印机问题,不支持wine下的ps格式写法,通过命令
gs -dNOPAUSE -dBATCH -sDEVICE=ps2write -sOutputFile=1_fixed.ps 1.ps后ps文件打印正常 - 新建系统其他的pdf打印机,基于cups,在
http://localhost:631/网页上进行打印机添加
- 在/etc/cups/cups-files.conf文件中修改
FileDevice Yes这一项 - 添加打印机中选择
AppSocket/HP JetDirect这一项 - 在Connection这一项中填写
file:/tmp/1.ps - 选择驱动的时候选
Generic-PDF_Printer-PDF.ppd - 打印后生成文件在
/tmp/1.ps下可以直接打开
- wine下使用基于cups的pdf打印机进行文件打印,页数正常
解决方案
- 创建一个自定义的pdf打印机解决
- 仿照pdf打印机中的ppd,创建一个自己的ppd文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34*PPD-Adobe: "4.3"
*FormatVersion: "4.3"
*FileVersion: "1.1"
*LanguageVersion: English
*LanguageEncoding: ISOLatin1
*PCFileName: "GENERIC.PPD"
*Manufacturer: "Generic"
*Product: "(PostScript Printer)"
*ModelName: "Generic PostScript Printer"
*ShortNickName: "Generic PostScript Printer"
*NickName: "Generic PostScript Printer"
*PSVersion: "(2014.0) 0"
*LanguageLevel: "2"
*ColorDevice: True
*DefaultColorSpace: RGB
*FileSystem: False
*Throughput: "8"
*LandscapeOrientation: Plus90
*TTRasterizer: Type42
*DefaultResolution: 600dpi
*OpenUI *PageSize/Media Size: PickOne
*OrderDependency: 10 AnySetup *PageSize
*DefaultPageSize: A4
*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
*CloseUI: *PageSize
*OpenUI *PageRegion: PickOne
*OrderDependency: 10 AnySetup *PageRegion
*DefaultPageRegion: A4
*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
*CloseUI: *PageRegion
*DefaultImageableArea: A4
*ImageableArea A4/A4: "0 0 595 842"
*DefaultPaperDimension: A4
*PaperDimension A4/A4: "595 842" - 创建一个自己的backend,里面运行命令类似是
gs -dNOPAUSE -dBATCH -sDEVICE=ps2write -sOutputFile=1_fixed.ps 1.ps,将pdf输出到指定目录 - 在deb安装脚本中将backend和ppd关联起来
lpadmin -p "MyManualPDF" -v "mypdf://" -E -P /usr/share/cups/model/manual_generic.ppd, 我的backend就是mypdf,打印用到我这个ppd就会找到我的backend
- 仿照pdf打印机中的ppd,创建一个自己的ppd文件