三十五年前的代码,在今天的浏览器中焕发新生。HP C2089A「PostScript Cartridge Plus」是惠普于 1991 年为 LaserJet II/III 打印机推出的扩展配件,其核心是一颗包含 Adobe PostScript Level 2 参考解释器(版本 2010.118)的 2 MB ROM。有趣的是,这段代码至今仍然是「现行有效」的 PostScript 实现 —— 语言本身几乎未曾改变。Michael Steil 的 retro-ps 项目正是利用 WebAssembly 技术,将这段 35 年前的机器码重新带入现代浏览器,在客户端直接渲染 PostScript 文件,整个过程不依赖任何服务器。
硬件基础与移植挑战
原始的 PostScript cartridges 运行在 LaserJet III 的主板上:一颗 8 MHz 的 Motorola 68000 处理器,1 MB 系统 RAM(可扩展至 4 MB),以及一个 - cartridge 端口负责将外部 ROM 映射到 CPU 地址空间。PostScript 解释器、字体、半调处理和分带输出全部运行在 cartridge ROM 中,依赖主板 RAM 完成工作。
将这套系统迁移到浏览器的核心挑战在于:解释器并非为桌面环境设计,而是专为特定的打印机硬件优化。retro-ps 需要模拟多个关键组件才能让解释器正常运作。首先是 CPU 层面,原版使用 68000 架构,项目采用了 68020 模拟以获得更大的地址空间 ——16 MB 的模拟 RAM 远超原版的 4 MB 上限,这种「裕量」使得高分辨率页面渲染成为可能,而无需修改解释器本身的内存分配逻辑。其次是主板与引擎的缺失:模拟器必须伪造打印机主板提供的软陷阱(soft-traps),包括打印机型号字节、IPC 字节流、引擎状态轮询等,同时模拟引擎完成中断以驱动 cartridges 的状态机前进。
遗留代码现代化的工程参数
在将 PostScript cartridges 移植到浏览器的工程实践中,有几个关键参数需要精确控制。分辨率方面,原版 cartridges 针对 300 DPI 优化,但解释器本身并无硬性限制,可以通过 DPI 缩放实现更高的输出精度 —— 不过半调单元需要手动注入调整,原版的手工调校单元在低分辨率下表现优异,但超过 300 DPI 后默认单元渲染过于稀疏,灰度填充会出现粉状瑕疵。项目中通过注入 DPI 缩放的 setscreen prolog 解决此问题。
页面尺寸与边距同样被「lifted」—— 原版受限于 300 DPI 固定纸张尺寸和 0.25 英寸硬件边距,而模拟器支持任意纸张尺寸和更高的 DPI,仅在显式指定 --lj3 参数时才恢复原始约束。需要注意的是,PostScript 解释器的 clip 操作符存在一个内置上限:每个坐标轴约 16,000 个设备像素,这是 Adobe 代码中的硬性限制,实际 DPI 上限随纸张尺寸变化 ——Letter 纸张上约为 1,450 DPI。
渲染管线的现代集成
retro-ps 的渲染管线完全运行在客户端。当用户将 .ps 文件拖放到页面时,模拟器加载 cartridge ROM、初始化 68020 解释器环境、注入必要的 prolog 参数,然后执行渲染流程。最终输出通过 Canvas 2D 或 WebGL 呈现给用户。这种架构的优势在于:无需服务器端资源,不存在隐私问题,且可以离线使用。
对于遗留 PostScript 代码的维护者而言,这一案例提供了宝贵的参考:古老的代码并非只能束之高阁,只要语言本身保持向后兼容,完全可以通过模拟层让它在现代平台上继续发挥作用。Adobe 的 PostScript 解释器证明了一个有趣的事实 —— 真正稳定的接口设计,可以跨越三十五年的硬件变迁而无需修改。
资料来源
- Michael Steil, "Running Adobe's 1991 PostScript Interpreter in the Browser", pagetable.com, 2026-05-01
- HP C2089A PostScript Cartridge Plus 硬件规格与 ROM 版本 2010.118