PDF 转 HTML5 —— HTML5 填充图形不支持 Even-Odd 奇偶规则?(第二部分)

这是关于该主题的第二部分。如果你还没有阅读第一部分,请先阅读,以便理解"绕组规则"的问题。

快速回顾一下:HTML5 只支持 Non-Zero(非零)绕组规则,而 PDF 同时支持 Non-Zero 和 Even-Odd(奇偶)两种规则。

这意味着我们必须对使用了 Even-Odd 填充规则的图形做些处理,否则它们在 HTML5 中可能无法正确显示。

为了演示这个问题,我会用以下这个例子:

看上去只是个红色的圆?

我第一次看到的时候也是这么想的。直到我把填充改为描边模式,才意识到它实际上是什么。

为了帮助理解发生了什么,我们再来看一张图,加上箭头,显示路径的绘制方向。

我们首先想到的是,可能需要改变图形的绘制方式。最直接的想法就是改变路径的方向,也就是"转换"成 Non-Zero 绕组规则的等价图形。

交替使用顺时针和逆时针方向可行吗?

值得一试,看看会发生什么。反正只需要一分钟时间试一下。

结果证明,这其实挺头疼的。如果只是用 lineTo 画个方框还好说,但涉及贝塞尔曲线的话,情况就复杂得多。

如果你只是简单地反转绘制指令的顺序,就会得到像这样的问题:

控制点的顺序会影响曲线的绘制方式。那么,我们能否也反转控制点的顺序呢?

哦------这样也不太对。我们使用的是 bezierCurveTo,它的意思是:从当前位置(由上一个绘图命令决定)开始,通过两个控制点绘制一段曲线,终点是我们指定的位置。这就意味着我们还必须反向地重新组织控制点和终点的顺序,这样曲线才能按正确的方式被绘制出来。

做对了之后,我们就能反转路径方向,让图形按预期绘制出来:

那么问题解决了吗?没有。

对于我们的"禁止通行"标志来说,或许可以这样处理------我们可以手动控制路径的顺序和方向。但在现实世界中,这种做法不能适用于通用场景。我们不可能为每个具体的 PDF 文件都手动处理,我们需要的是一套普适的代码逻辑,让它能应对任何 PDF 文件。

这也就意味着交替改变路径方向并不能真正解决问题。比如看一下我们禁止通行标志在这种方式下的效果:

我的下一个想法是:用背景色填充被遮挡的区域。但这也行不通,因为路径的绘制顺序还是关键。即使我们把两个 "D" 字母填充为白色,当外面的圆形被填充时,它还是会把我们之前的工作覆盖掉。

而且如果两个形状只是部分重叠,那么只有重叠部分才需要"未填充"。更关键的是,这些"未填充"的部分是真正的透明区域,如果你用背景色填充,就会失去透明性,导致我们无法在后面放其他图层,比如显示"你不可以做这件事"的提示。

那怎么办?

如果不能改变绘制顺序,也不能改变路径方向,也不能通过填色伪装,我们还能怎么改造图形,让它在使用 Non-Zero 绕组规则时正常显示?

或许我们可以非常巧妙地将图形切割成许多小块,然后分析每一块该如何绘制,再分别填充这些小块。

像这样:


| |

||| |

|_____|


| __|

|__|

__

|__|

__

__| |

|_____|

但这就太复杂了。对于我们的需求来说,有点大材小用了。而且,这种做法计算量大,会降低我们转换器的性能。更现实的是,我也没那么聪明,写不出来这样的算法。

其实从我开始研究这些形状开始,脑海里就一直有一个小声音在说:

"要不,我们干脆把这些图形输出成图片得了?"

确实,这样做是可行的,但并不理想。实际上,使用 Non-Zero 和 Even-Odd 绕组规则绘制图形,最终渲染结果真正不同的情况并不多。

所以,如果我们每次遇到 Even-Odd 绘制规则就输出成图片,那会产生大量没必要的图像文件。

这也不理想,因为矢量图形本身非常好用:缩放不会失真,从 PDF 转到 HTML5 非常快速,占用空间也远远小于图片。

那我们还能怎么办?

我们只能妥协。

最合理的做法就是:设定一套规则,只有当图形符合某些特定条件时,才把它输出为图片。

其余情况我们仍然尽可能用原始的路径绘制方式进行呈现。这样,在保持性能和显示效果之间取得一个平衡。

我们的主页:PDF 转 HTML5、Java 图像库、Java PDF SDK - IDRsolutions

相关推荐
User_芊芊君子1 小时前
【JavaSE】复习总结
java·开发语言·python
我有一颗五叶草1 小时前
线程间通信
java·开发语言
somethingGoWay2 小时前
wpf .netcore 导出pdf文件
pdf·wpf·.netcore
我真的是大笨蛋5 小时前
K8S-Pod(下)
java·笔记·云原生·容器·kubernetes
碳水加碳水5 小时前
Java代码审计实战:XML外部实体注入(XXE)深度解析
java·安全·web安全·代码审计
努力也学不会java7 小时前
【设计模式】 原型模式
java·设计模式·原型模式
方渐鸿7 小时前
【2024】k8s集群 图文详细 部署安装使用(两万字)
java·运维·容器·kubernetes·k8s·运维开发·持续部署
晓衣7 小时前
2025“獬豸杯”全国电子数据取证竞赛-k8s服务器取证wp
服务器·经验分享·程序人生·网络安全·容器·kubernetes·学习方法
学亮编程手记7 小时前
K8S v1.33 版本主要新特性介绍
java·容器·kubernetes
Haven-8 小时前
Java-面试八股文-JVM篇
java·jvm·面试