含shfill的PostScript转PDF时填充消失问题及临时方案
shfill填充在ps2pdf转PDF时消失的问题分析与解决
问题描述
我有一个包含shfill的PostScript文件,在gv等查看工具中显示正常,用Ghostscript直接转换为PNG格式也能正确显示渐变填充,但在Linux上使用ps2pdf(推测调用Ghostscript的PDFWriter设备)转换为PDF时,shfill的填充效果完全消失。
原始PostScript代码如下:
%%BoundingBox: 40 13 555 829 %%HiResBoundingBox: 40.2072703937 13.1732283465 554.7927296063 828.8267716535 %%PageOrientation: Portrait %%Pages: 1 %%EndComments %%Page: page 1 grestore gsave %pre-tile 0 14.1732283465 14.1732283465 translate %portrait 27.0340420472 0.0000000000 translate %539.619501 813.653543 scale 0.0040682677 0.0040682677 scale newpath grestore gsave %pre-tile 0 14.1732283465 14.1732283465 translate %portrait 27.0340420472 0.0000000000 translate %539.619501 813.653543 scale 0.0040682677 0.0040682677 scale << /ShadingType 5 /ColorSpace /DeviceRGB /VerticesPerRow 2 /DataSource [ 119726 154712 1.00 0.56 0.38 123209 154712 1.00 0.56 0.38 119726 158195 1.00 0.65 0.50 123209 158195 1.00 0.65 0.50 119726 161679 1.00 0.74 0.62 123209 161679 1.00 0.74 0.62 119726 165163 1.00 0.82 0.75 123209 165163 1.00 0.82 0.75 119726 168647 1.00 0.91 0.87 123209 168647 1.00 0.91 0.87 119726 172131 1.00 1.00 1.00 123209 172131 1.00 1.00 1.00 119726 175614 0.91 1.00 1.00 123209 175614 0.91 1.00 1.00 119726 179098 0.82 0.99 1.00 123209 179098 0.82 0.99 1.00 119726 182582 0.73 0.99 1.00 123209 182582 0.73 0.99 1.00 119726 186066 0.64 0.99 1.00 123209 186066 0.64 0.99 1.00 119726 189550 0.55 0.99 1.00 123209 189550 0.55 0.99 1.00 ] >> shfill
运行环境
- 操作系统:已更新的Ubuntu 20
- Ghostscript版本:GPL Ghostscript 9.50 (2019-10-15)
临时解决方案
移除scale运算符,手动通过mul对shfill的顶点坐标进行缩放后,PDF转换可正常显示填充效果。修改后的代码如下:
%!PS-Adobe-3.0 EPSF-3.0 14.1732283465 14.1732283465 translate 27.0340420472 0.0000000000 translate %0.0040682677 0.0040682677 scale << /ShadingType 5 /ColorSpace /DeviceRGB /VerticesPerRow 2 /DataSource [ 119726 0.0040682677 mul 154712 0.0040682677 mul 1.00 0.56 0.38 123209 0.0040682677 mul 154712 0.0040682677 mul 1.00 0.56 0.38 119726 0.0040682677 mul 158195 0.0040682677 mul 1.00 0.65 0.50 123209 0.0040682677 mul 158195 0.0040682677 mul 1.00 0.65 0.50 119726 0.0040682677 mul 161679 0.0040682677 mul 1.00 0.74 0.62 123209 0.0040682677 mul 161679 0.0040682677 mul 1.00 0.74 0.62 119726 0.0040682677 mul 165163 0.0040682677 mul 1.00 0.82 0.75 123209 0.0040682677 mul 165163 0.0040682677 mul 1.00 0.82 0.75 119726 0.0040682677 mul 168647 0.0040682677 mul 1.00 0.91 0.87 123209 0.0040682677 mul 168647 0.0040682677 mul 1.00 0.91 0.87 119726 0.0040682677 mul 172131 0.0040682677 mul 1.00 1.00 1.00 123209 0.0040682677 mul 172131 0.0040682677 mul 1.00 1.00 1.00 119726 0.0040682677 mul 175614 0.0040682677 mul 0.91 1.00 1.00 123209 0.0040682677 mul 175614 0.0040682677 mul 0.91 1.00 1.00 119726 0.0040682677 mul 179098 0.0040682677 mul 0.82 0.99 1.00 123209 0.0040682677 mul 179098 0.0040682677 mul 0.82 0.99 1.00 119726 0.0040682677 mul 182582 0.0040682677 mul 0.73 0.99 1.00 123209 0.0040682677 mul 182582 0.0040682677 mul 0.73 0.99 1.00 119726 0.0040682677 mul 186066 0.0040682677 mul 0.64 0.99 1.00 123209 0.0040682677 mul 186066 0.0040682677 mul 0.64 0.99 1.00 119726 0.0040682677 mul 189550 0.0040682677 mul 0.55 0.99 1.00 123209 0.0040682677 mul 189550 0.0040682677 mul 0.55 0.99 1.00 ] >> shfill
原因分析
- Ghostscript的PDFWriter设备和渲染类设备(如PNG设备)对
shfill的处理逻辑存在差异:渲染设备会实时将图形状态的缩放变换应用到渐变顶点,而PDFWriter在生成PDF Shading对象时,可能没有正确把当前图形状态的scale变换纳入计算,导致缩放后的顶点坐标超出PDF页面可见范围,或者变换计算错误,最终填充无法显示。 - 手动用
mul提前缩放坐标,相当于绕过了PDFWriter对图形状态变换处理的bug,直接提供了正确的页面坐标,因此能正常生成渐变填充。 - 该问题属于Ghostscript 9.50版本的已知缺陷,升级到9.55及以上版本的Ghostscript可直接修复,后续版本优化了Shading变换的处理逻辑。
内容的提问来源于stack exchange,提问作者Waslap
相关产品推荐
相关产品推荐

