You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在PostScript内部计算任意PostScript代码的边界框

单次PostScript调用内获取内容边界框并实现居中/缩放

核心思路

要在单次PostScript解释器调用中完成「预跑代码收集边界框→计算变换→实际绘图」的流程,关键在于重定义绘图相关操作符,在不实际输出的前提下,收集所有路径(包括文本路径)的边界框,合并得到内容的全局边界框,再基于页面尺寸计算缩放和平移参数,最后应用变换后执行实际绘图。

由于目标代码可能包含多条独立路径或文本,直接使用pathbbox只能获取当前路径的边界,因此需要通过拦截stroke、fill、show等操作,每次执行前先提取当前路径/文本的边界并更新全局边界框。

完整实现代码

% --------------------------
% 1. 初始化全局边界框变量(初始值设为极值)
% --------------------------
/bbox [1e38 1e38 -1e38 -1e38] def

% --------------------------
% 2. 定义更新全局边界框的过程
% 接收pathbbox返回的四个值:minx miny maxx maxy,与当前全局bbox比较并更新
% --------------------------
/updatebbox {
    pathbbox
    % 更新最小x
    0 get bbox 0 get lt { exch bbox 0 exch put } if
    % 更新最小y
    1 get bbox 1 get lt { exch bbox 1 exch put } if
    % 更新最大x
    2 get bbox 2 get gt { exch bbox 2 exch put } if
    % 更新最大y
    3 get bbox 3 get gt { exch bbox 3 exch put } if
} def

% --------------------------
% 3. 保存原操作符,重定义绘图命令以收集边界框
% --------------------------
save
% 保存原stroke/fill/show等操作
/origstroke stroke load def
/origfill fill load def
/origshow show load def
/origashow ashow load def
/origwidthshow widthshow load def

% 重定义stroke:先更新bbox,再执行原stroke
/stroke { updatebbox origstroke } def
% 重定义fill:先更新bbox,再执行原fill
/fill { updatebbox origfill } def
% 重定义文本显示命令:先将文本转换为路径,再更新bbox,最后执行原命令
/show {
    gsave
    currentpoint moveto
    true charpath pathbbox
    % 更新全局bbox
    0 get bbox 0 get lt { exch bbox 0 exch put } if
    1 get bbox 1 get lt { exch bbox 1 exch put } if
    2 get bbox 2 get gt { exch bbox 2 exch put } if
    3 get bbox 3 get gt { exch bbox 3 exch put } if
    grestore
    origshow
} def
% 处理其他文本显示命令(ashow/widthshow),逻辑与show一致
/ashow {
    gsave
    currentpoint moveto
    true charpath pathbbox
    0 get bbox 0 get lt { exch bbox 0 exch put } if
    1 get bbox 1 get lt { exch bbox 1 exch put } if
    2 get bbox 2 get gt { exch bbox 2 exch put } if
    3 get bbox 3 get gt { exch bbox 3 exch put } if
    grestore
    origashow
} def
/widthshow {
    gsave
    currentpoint moveto
    true charpath pathbbox
    0 get bbox 0 get lt { exch bbox 0 exch put } if
    1 get bbox 1 get lt { exch bbox 1 exch put } if
    2 get bbox 2 get gt { exch bbox 2 exch put } if
    3 get bbox 3 get gt { exch bbox 3 exch put } if
    grestore
    origwidthshow
} def

% --------------------------
% 4. 运行目标代码(仅收集边界框,不实际输出)
% --------------------------
% 替换为你的任意PostScript代码
200 200 moveto 100 0 lineto 0 100 lineto closepath stroke
500 500 moveto (Hello PostScript!) show

% --------------------------
% 5. 恢复原操作符,结束边界框收集阶段
% --------------------------
restore

% --------------------------
% 6. 计算缩放和平移参数(以A4页面为例,边距20pt)
% --------------------------
/bboxminx bbox 0 get def
/bboxminy bbox 1 get def
/bboxmaxx bbox 2 get def
/bboxmaxy bbox 3 get def

/bboxwidth bboxmaxx bboxminx sub def
/bboxheight bboxmaxy bboxminy sub def

% 页面尺寸(A4:595pt宽,842pt高)
/pagewidth 595 def
/pageheight 842 def
/margin 20 def
/usablewidth pagewidth margin 2 mul sub def
/usableheight pageheight margin 2 mul sub def

% 处理内容为空的极端情况
bboxwidth 0 eq bboxheight 0 eq or {
    /scalefactor 1 def
    /translatex margin def
    /translatey margin def
} {
    % 计算缩放比例:取宽高方向适配可用区域的较小值
    /scalefactor usablewidth bboxwidth div usableheight bboxheight div min def
    % 计算平移量,使内容在可用区域居中
    /translatex margin usablewidth scalefactor sub 2 div bboxminx scalefactor mul sub def
    /translatey margin usableheight scalefactor sub 2 div bboxminy scalefactor mul sub def
} ifelse

% --------------------------
% 7. 应用变换并实际绘制目标代码
% --------------------------
% 重置图形状态
gsave
    translate translatex translatey
    scale scalefactor scalefactor
    % 再次运行你的任意PostScript代码
    200 200 moveto 100 0 lineto 0 100 lineto closepath stroke
    500 500 moveto (Hello PostScript!) show
grestore

% 结束作业
showpage

关键细节说明

  1. 边界框收集逻辑:通过重定义stroke、fill等绘图操作,在执行原操作前调用pathbbox获取当前路径的边界,更新全局边界框;对于文本,使用true charpath将文本转换为路径后再提取边界。
  2. 操作符保护:使用save/restore保存和恢复原操作符,避免修改全局环境影响后续代码。
  3. 极端情况处理:当内容为空(边界框宽高为0)时,直接使用默认平移量,避免除以0错误。
  4. 兼容性:基于PostScript Level 3特性实现,可在任意兼容Level 3的PostScript解释器上运行,不依赖GhostScript等特定实现。

内容的提问来源于stack exchange,提问作者user31708

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:09:57