pdf - 在不同 PDF 查看器中具有不同输出的 PDF(带阴影)
问题描述
考虑以下 PostScript 文件
[1 0 0.5 0.866 150 550] concat
<<
/ShadingType 2
/Coords [ 0 0 100 100]
/BBox [ 0 0 100 100]
/ColorSpace [ /DeviceRGB ]
/Function
<<
/FunctionType 0
/Domain [0 1]
/Range [0 1 0 1 0 1]
/BitsPerSample 8
/Size [2]
/DataSource <FFA0A0FFE0E0>
>>
/Extend [false false]
>>
shfill
考虑一下我们使用 GhostScript (ps2pdf) 或 Adobe Distiller 将该文件转换为 PDF。
生成的 PDF 在不同的 PDF 查看器中呈现方式不同:
- 在 Adobe Reader 或 Firefox(使用 PDF.js)中,我们有一个平行四边形(不是矩形)。
- 在 SumatraPDF(使用 MuPDF)和 Chrome(使用 PDFium)中,我们有一个矩形。
谁是对的?
解决方案
在我看来,Adobe Acrobat 是正确的,但规范也可以有不同的解读。
您的 PDF 包含以下内容流:
/GS1 gs
q
1 0 .5 .866 150 550 cm
/Sh1 sh
Q
即首先改变当前的变换矩阵,它被剪切和挤压一点,然后着色Sh1被绘制。该阴影又被定义为
<</BBox[0 0 100 100]/ColorSpace/DeviceRGB/Coords[0 0 100 100]/Function 15 0 R/ShadingType 2>>
即具有 100×100 方形边界框(解释为临时附加剪切路径)和沿其 (0, 0) 到 (100, 100) 对角线的轴向阴影,与您的后记定义相匹配。
着色运算符sh
指定为
操作数 | 操作员 | 描述 |
---|---|---|
姓名 | 嘘 | (PDF 1.3)根据当前的剪切路径绘制由阴影字典描述的形状和颜色阴影。图形状态中的当前颜色既不使用也不改变。该效果不同于使用阴影图案作为当前颜色绘制路径的效果。name 是当前资源字典的 Shading 子字典中的着色字典资源的名称(参见 7.8.3,“资源字典”)。着色字典中的所有坐标都相对于当前用户空间进行解释。(相比之下,当在 Type 2 模式中使用着色字典时,坐标在模式空间中表示。)所有颜色都在由着色字典的ColorSpace标识的颜色空间中解释条目(参见“表 77 - 所有着色字典通用的条目”)。后台条目(如果存在)将被忽略。 此运算符应仅应用于有界或几何定义的阴影。如果应用于无界着色,它会在整个剪切区域上绘制着色的渐变填充,这可能会很耗时。 |
(ISO 32000-2:2017,表 76 — 着色运算符)
特别是:着色字典中的所有坐标都相对于当前用户空间进行解释。
因此,正方形边界框/临时剪辑路径被当前变换矩阵挤压和剪切成非矩形平行四边形,如可以在 Adobe Acrobat 中查看的那样:
我在上面提到,规范也可以有不同的理解:如果将BBox条目视为两个点的坐标,即盒子的左下角和右上角,并在将结果变为盒子之前应用转换,一个会得到一个压扁的、拉长的矩形,可以在 Chrome 中查看:
但是这里的BBox被指定为一个由四个数字组成的数组,分别给出着色边界框的左、下、右和上坐标(同上,表 77 - 所有着色字典共有的条目),而不是作为对角线的两个端点。因此,我赞成 Adobe 也实施的第一种解释。
我还没有 ISO 32000-2:2020 的副本,所以也许已经以某种方式澄清了这一点。
如果在填充指令期间将用作当前颜色的图案中使用了阴影,情况将有所不同。在这种情况下,规范说:
图案的外观是相对于它自己的内部坐标系来描述的。每个模式都有一个模式矩阵,一个将模式的内部坐标系映射到模式的父内容流(将模式定义为资源的内容流)的默认坐标系的转换矩阵。模式矩阵与父内容流的连接建立了模式坐标空间,在其中解释模式中的所有图形对象。
(ISO 32000-2:2017,第 8.7.2 节 - 模式的一般属性)
在这种情况下,带有对角轴向阴影的方形边界框不会受到当前变换矩阵的影响。
推荐阅读
- laravel - 如何在 laravel 查询中编写 where 条件?
- c++ - 如何在 C++ 中将向量拆分为三个变量
- html - 按钮背景错误
- c# - WebAPI 限制外部 HttpClient 调用以等待其他请求的结果
- flutter - Flutter 能否拍一张 Flutter 框架中所有类的类图?像UML图
- r - 在 R 中运行回归时出错:数学函数的非数字参数
- c# - 从依赖注入配置进行依赖调用
- openstack - 无法为 ML2 机制驱动程序开发安装 Devstack
- android - 用户提出新请求时如何取消协程?
- java - 有人知道在使用布局管理器的同时进行绝对定位的方法吗?