最近工作中涉及到cups打印,需要对打印选项做精确设置,就像Windows下做的打印设置那般。
功能强大的cups是支持选项定制的。如果用命令行的形式,在lp命令-o添加options参数即可。但是,cups options参数组织复杂,不同的打印方向(横向/纵向),运用相同的options,打印效果可能也不相同。要想很好的控制打印动作,需要对各options做精准的了解,才能运用自如。闲言少叙,下面以bmp图像打印为例,叙述本人对各option作用的了解。若有错误之处,还望各位更正。
首先指出三点,
1. 对bmp文件,cups会启动imagetopdf进程(根据mime/convs设置而异,启动也可能是imagetops。本文只解析某一特定案例,下同)。此进程读取PPD环境变量下的ppd文件,并解析cups options。至于之后流程,从error_log可见一斑:
D [31/Oct/2018:10:43:31 +0800] [Job 15] Filetype: PDF
D [31/Oct/2018:10:43:31 +0800] [Job 15] PostScript option found: PageSize=Letter: \"<</PageSize[612 792]/ImagingBBox null>>setpagedevice\"
D [31/Oct/2018:10:43:31 +0800] [Job 15] Driver does not understand PDF input, converting to PostScript
D [31/Oct/2018:10:43:31 +0800] [Job 15] Storing temporary files in /tmp
D [31/Oct/2018:10:43:31 +0800] [Job 15] PID 3985 (/usr/lib/cups/filter/imagetopdf) exited with no errors.
D [31/Oct/2018:10:43:31 +0800] [Job 15] Starting process \"pdf-to-ps\" (generation 1)
...
D [31/Oct/2018:10:43:31 +0800] [Job 15] Filetype: PostScript
D [31/Oct/2018:10:43:31 +0800] [Job 15] Reading PostScript input ...
以上log为foomatic-rip打出,并且pdf-to-ps也是它启动的。父子进程间通过pipe通信,这是cups惯用的方式。
2. log分析很重要。接触新的事物,有时未必一味钻入code中不能自拔。良好的log输出,能让我们迅速掌握整个框架和运行流程。即所谓,先知其然(what+why),再知其所以然(how)。不可冒进。
3. 参考cups-filter 1.21.2
最后,list各option及本人的理解:
1. landscape:表示横向打印;当赋值不是"no"/"off"/"false"时,开启旋转来控制是否横向。此选项可使旋转90度。ppd文件中LandscapeOrientation配置数值>0,为90度顺时针转向;否则为-90度逆时针转向。
2. orientation-requested:此选项在没有配置landscape时生效。数值为3到6。
/*
* Map IPP orientation values to 0 to 3:
*
* 3 = 0 degrees = 0
* 4 = 90 degrees = 1
* 5 = -90 degrees = 3
* 6 = 180 degrees = 2
*/
cups-filter 1.21.2中此选项不支持-90 degrees = 3情况。
3. page-left/page-right/page-bottom/page-top:margin设置。此选项是覆盖ppd中的ImageableArea中的数值。至于ImageableArea,拿A4举例,
*ImageableArea A4/A4: "18 36 577 806"分别是
D [31/Oct/2018:10:43:31 +0800] [Job 15] PageLeft=18, PageRight=577, PageWidth=595
D [31/Oct/2018:10:43:31 +0800] [Job 15] PageBottom=36, PageTop=806, PageLength=842
必须说明的是,ppd中"PageWidth=595"和“PageLength=842”为72 ppi对应纸A4张尺寸的像素数值;PageLeft/PageBottom/PageRight/PageTop都是指绝对像素坐标!!!具体含义如下表,可知此设置数值确实如margin字面意思,而非绝对像素位置。
0(旋转0度) | 1(旋转90度) | 2(旋转-90度) | 3(旋转180度) | ||
page-left | x | PageLeft = x | PageBottom=x | PageRight=PageWidth-x | PageTop=PageLength-x |
page-right | x | PageRight=PageWidth-x | PageTop=PageLength-x | PageLeft=x | PageBottom=x |
page-bottom | x | PageBottom=x | PageLeft=x | PageTop=PageLength-x | PageRight=PageWidth-x |
page-top | x | PageTop=PageLength-x | PageRight=PageWidth-x | PageBottom=x | PageLeft=x |
4. Duplex/sides:配置可选"true"/"on"/"yes",与ppd中的Duplex联合作用;sides数值可选"two-sided-long-edge"/"two-sided-short-edge",亦与ppd中的Duplex联合作用。
5. OutputOrder:可直接配置成"Reverse",配置生效。其他数值,会依次查找ppd文件中的OutputOrder/OutputBin/DefaultOutputOrder。
6. cupsEvenDuplex:配置可选true/on/yes,直接开启选项。其他数值,查找ppd中cupsEvenDuplex。
7. multiple-document-handling:数值为separate-documents-uncollated-copies或其他。意义可参考程序注释,
/*
* This IPP attribute is unnecessarily complicated...
*
* single-document, separate-documents-collated-copies, and
* single-document-new-sheet all require collated copies.
*
* separate-documents-uncollated-copies allows for uncollated copies.
*/
8. Collate:可配置为true。不配置的话,用ppd中的Collate。
9. gamma:int型数值。最终gammaval = atoi(val) * 0.001f;
10. brightness:int型数值。最终brightness = atoi(val) * 0.01f;
11. scaling/fit-to-page/fitplot/natural-scaling:scaling为int型数值。最终zoom = atoi(val) * 0.01; 若没有配置scaling,依次查找fit-to-page/fitplot,若二者被配置成yes/on/true, zoom = 1.0;否则zoom = 0。 若没有配置fit-to-page/fitplot,查找natural-scaling,若此选项配置成任何文本zoom = 0.0。这些配置联同landscape/orientation-requested很大程度上决定是否分页,对打印效果影响极大。
12. ppi:%dx%d形式配置。若xppi和yppi数值相同,可只配置一个。此选项会使zoom = 0.0。
13. position:可配置为center/top/left/right/top-left/top-right/bottom/bottom-left/bottom-right。此选项跟旋转方向耦合较深。
14. saturation:int型数值。
15. hue:int型数值。
16. mirror:为true、
17. emit-jcl:false/off/no/o时关闭;不配置或配置成其他值打开。参考注释,
/* pdftopdf only adds JCL to the job if the printer is a native PDF
printer and the PPD is for this mode, having the "*JCLToPDFInterpreter:"
keyword. We need to read this keyword manually from the PPD and replace
the content of ppd->jcl_ps by the value of this keyword, so that
ppdEmitJCL() actalually adds JCL based on the presence on
"*JCLToPDFInterpreter:". */
至此,主要的options列出完毕。下面log说明了imagetopdf对bmp的变换过程中,从bmp抽取的文件信息,及最终计算图形打印布局部分信息,
bmp文件信息,
D [31/Oct/2018:10:43:30 +0800] [Job 15] info_size = 40, xsize = 1700, ysize = 1400, planes = 1, depth = 1
D [31/Oct/2018:10:43:30 +0800] [Job 15] compression = 0, image_size = 302400, xppi = 223, yppi = 288
D [31/Oct/2018:10:43:30 +0800] [Job 15] colors_used = 2, colors_important = 2
计算打印布局,
D [31/Oct/2018:10:43:31 +0800] [Job 15] Before scaling: xppi=0, yppi=0, zoom=1.00
D [31/Oct/2018:10:43:31 +0800] [Job 15] Before scaling: xprint=8.3, yprint=10.7
D [31/Oct/2018:10:43:31 +0800] [Job 15] cupsImageGetXPPI(img) = 223, cupsImageGetYPPI(img) = 288, aspect = 1.291480
D [31/Oct/2018:10:43:31 +0800] [Job 15] Portrait size is 8.26 x 5.27 inches
D [31/Oct/2018:10:43:31 +0800] [Job 15] Landscape size is 10.69 x 6.82 inches
D [31/Oct/2018:10:43:31 +0800] [Job 15] Auto orientation...
D [31/Oct/2018:10:43:31 +0800] [Job 15] Using landscape orientation...
I [31/Oct/2018:10:43:31 +0800] Expiring subscriptions...
D [31/Oct/2018:10:43:31 +0800] [Job 15] xpages = 1x10.69in, ypages = 1x6.82in
D [31/Oct/2018:10:43:31 +0800] [Job 15] XPosition=-1, YPosition=-1, Orientation=1
D [31/Oct/2018:10:43:31 +0800] [Job 15] xprint=11, yprint=7
D [31/Oct/2018:10:43:31 +0800] [Job 15] PageLeft=0, PageRight=595, PageWidth=595
D [31/Oct/2018:10:43:31 +0800] [Job 15] PageBottom=36, PageTop=806, PageLength=842
D [31/Oct/2018:10:43:31 +0800] [Job 15] left=36.00, top=0.00
其中,
a)xppi=0, yppi=0可由-o ppi控制;zoom的控制,上文已经提及。
b) cupsImageGetXPPI(img) = 223, cupsImageGetYPPI(img) = 288, aspect = 1.291480来自bmp文件,aspect = 288/223
c) xprint=8.3, yprint=10.7来自ppd文件中PageSzie:xPrint=(PageRight - PageLeft) / 72.0; yprint = (PageTop - PageBottom) / 72.0。
d) D [31/Oct/2018:10:43:31 +0800] [Job 15] Portrait size is 8.26 x 5.27 inches
和
D [31/Oct/2018:10:43:31 +0800] [Job 15] Landscape size is 10.69 x 6.82 inches
是最终根据a)+b)+c)计算的每页宽*高。
e) xpages = 1x10.69in, ypages = 1x6.82in是分页信息。总页数为1x1,不必分页。
f) left=36.00, top=0.00为最终算得的margin。
总体感觉cups选项配置复杂,有的options之间会有直接影响。下步工作:观察整体现象,并探究出它的规律,将之熟练应用在工作中。