如何在PostScript中获取字符串的高度度量?

11
你可以使用 stringwidth 获取当前字体下字符串的宽度,虽然这实际上会在堆栈上推入偏移坐标,但 y 值似乎总是没有用处。有没有办法确定字符串的精确高度,可能包括下降部分?
3个回答

5
我已经在如何确定PostScript中字符串的高度?中回答过这个问题,但是这里也很有用。
只是补充一下的答案:
/textheight { 
    gsave                                  % save graphic context
    {                            
        100 100 moveto                     % move to some point 
        (HÍpg) true charpath pathbbox      % gets text path bounding box (LLx LLy URx URy)
        exch pop 3 -1 roll pop             % keeps LLy and URy
        exch sub                           % URy - LLy
    }
    stopped                                % did the last block fail?
    {
        pop pop                            % get rid of "stopped" junk
        currentfont /FontMatrix get 3 get  % gets alternative text height
    }
    if
    grestore                               % restore graphic context
} bind def

/jumpTextLine { 
    textheight 1.25 mul                    % gets textheight and adds 1/4
    0 exch neg rmoveto                     % move down only in Y axis
} bind def

该方法需要预先设置一些字体。它会在选定的字体(setfont)和其大小(scalefont)上操作。
我使用(HÍpg)来获取可能的最大边界框,使用带重音的大写字符和“下划线”字符。结果已经足够好了。
另一种替代方法则借鉴了dreamlax的答案 -- 一些字体不支持charpath运算符。
保存和还原图形上下文将保持当前点的位置,因此对您的文档的“流程”没有影响。
希望我能帮到您。

此外,您可以使用 currentfont /FontBBox get 来获取边界框,而不是使用 charpath pathbbox 来获取它... 在我的情况下,在 GhostScript 下它完美地工作;然而,当打印机解释时结果并不好。 - Ricardo Nolde

5

stringwidth,如其名,不返回字符串的高度。(在我查看的所有情况中,在执行 stringwidth 后栈上第二个整数是 0,对于水平方向运行的字符串来说。)stringwidth 给出执行 (string) show 后当前点的相对坐标。

PLRM 对 stringwidth 有这样的说明:

请注意,stringwidth 返回的宽度被定义为当前点的移动。它与字形轮廓的尺寸无关。

那么,考虑字符串的高度应该怎么做呢?在 PLRM 中需要了解的魔法词汇是 charpathpathbbox。试试这个:

%!
/Helvetica findfont 60 scalefont setfont
200 700 4 0 360 arc fill 
200 700 moveto (test test) dup 
true charpath pathbbox 
3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 
1 0 0 setrgbcolor
200 700 moveto rmoveto show showpage

它计算字符串(以红色印刷)的高度,并使用该信息尝试将一个小填充圆(以黑色印刷)居中放置在其边界框的中心:

Sample PostScript visualized


3

这似乎大多数时间都有效:

/fontheight { currentfont /FontMatrix get 3 get } bind def
/lineheight { fontheight 1.2 mul } bind def

这并非适用于所有的 /FontType


如果矩阵中存在任何Y剪切,则这也不起作用。 如果“/ FontMatrix get 5 get”不为零,则字形的高度将取决于其宽度。 - luser droog
要使用更多的字体类型,您还需要使用FontBBox:https://dev59.com/questions/aV3Va4cB1Zd3GeqPC7Sp#19263342 - jcomeau_ictx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接