如何在PostScript中确定字符串高度?

wil*_*lem 12 postscript ghostscript

我需要在postscript中确定字符串的高度(以给定的比例和字体).

/Helvetic-Oblique findfont
10 scalefont
setfont
10 10 1 0 360 arc fill
10 10 moveto (test) dup stringwidth pop 2 div neg 0 rmoveto show
Run Code Online (Sandbox Code Playgroud)

将在(10,10)水平(但尚未垂直)打印测试.(看到这个,我还在10,10处显示一个小圆圈).我还需要确定字符串高度以使文本垂直居中,但我无法找到它的功能.

Kur*_*fle 9

您熟悉正在使用的PostScript代码吗?或者只是盲目地从某个地方复制和粘贴?如果您想了解它,您应该谷歌搜索"PostScript语言参考"或"红皮书"或"PLRM".这些资源以Adobe的PDF格式提供.

您的PostScript代码段使用以下步骤:

  1. (test) 将字符串"test"放在堆栈顶部.
  2. dup复制堆栈中最顶层的项目.(你现在在堆栈上有两次字符串.)
  3. stringwidth.执行此运算符后,最顶层的"test"字符串将被消耗,并且将向堆栈添加两个值:字符串的高度(最顶部)和字符串的宽度(从顶部开始的第二个).[ 更新: 实际上,"字符串的高度"并不完全正确 - 它是完成绘制字符串后的当前点的垂直偏移... ]
  4. 接下来,你使用pop.这只是删除堆栈上的最高值.现在只有字符串的宽度保留在堆栈的顶部.
  5. 2 div 将该值除以2并保留结果(字符串宽度的一半).
  6. neg否定堆栈的最高值.现在,负值是堆栈中最重要的.
  7. 0 将值"0"放在堆栈顶部.
  8. rmoveto 然后消耗堆栈上的两个最高值,并将当前点移动该距离(字符串宽度的一半)向左移动.
  9. show 消耗第一个"测试"字符串,它始终保持在堆栈底部并"显示"它.

那么考虑弦的高度会有什么效果呢?尝试作为你的最后一行:

200 700 moveto (test) dup true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 200 700 moveto rmoveto show"
Run Code Online (Sandbox Code Playgroud)

要了解我的变化抬头的意思charpath,div,exch,pathbbox,rollsub运营商的红皮书.

此命令使用Ghostscript从代码中在Windows上创建PDF文件(更易于查看和检查结果):

 gswin32c.exe ^
      -o my.pdf ^
      -sDEVICE=pdfwrite ^
      -c "/Helvetic-Oblique findfont 10 scalefont setfont 200 700 1 0 360 arc fill 0 0 moveto (test test) dup true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 200 700 moveto rmoveto show"
Run Code Online (Sandbox Code Playgroud)

在Linux上使用:

 gs \
      -o my.pdf \
      -sDEVICE=pdfwrite \
      -c "/Helvetic-Oblique findfont 10 scalefont setfont 200 700 1 0 360 arc fill 0 0 moveto (test test) dup true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 200 700 moveto rmoveto show"
Run Code Online (Sandbox Code Playgroud)

更好的可读形式是:

  gswin32c ^
     -o my.pdf ^
     -sDEVICE=pdfwrite ^
     -c "/Helvetic-Oblique findfont 10 scalefont setfont" ^
     -c "200 700 1 0 360 arc fill 0 0 moveto (test test) dup" ^
     -c "true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll" ^
     -c "sub 2 div exch 200 700 moveto rmoveto show"
Run Code Online (Sandbox Code Playgroud)

  gs \
     -o my.pdf \
     -sDEVICE=pdfwrite \
     -c "/Helvetic-Oblique findfont 10 scalefont setfont" \
     -c "200 700 1 0 360 arc fill 0 0 moveto (test test) dup" \
     -c "true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll" \
     -c "sub 2 div exch 200 700 moveto rmoveto show"
Run Code Online (Sandbox Code Playgroud)


Ric*_*lde 7

只需添加到pipitas答案:

/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
Run Code Online (Sandbox Code Playgroud)

该方法需要设置某些字体.它适用于所选的font(setfont)及其大小(scalefont).

我使用(HÍpg)来获得最大的边界框,使用强调的大写字符和"下线"字符.结果很好.

替代方法从dreamlax的回答中窃取- 一些字体不支持charpath运算符.(请参阅如何在PostScript中获取字符串的高度指标?)

保存和恢复图形上下文可以保持当前点,因此它不会影响文档的"流".

希望我帮了.