2010-09-01 38 views
11

我需要確定postscript中字符串的高度(以給定的比例和字體)。如何確定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 

將打印在(10,10)水平居中(但不垂直)居中的測試。 (看到這個,我也會在10,10處看到一個小圓圈)。我也需要確定字符串的高度以垂直居中文本,但是我找不到它的函數。

回答

9

你熟悉你正在使用的PostScript代碼?還是隻是盲目地從某個地方複製粘貼?如果你想了解它,你應該谷歌的「PostScript語言參考」或「紅皮書」或「PLRM」。這些資源以Adobe的PDF格式提供。

您的PostScript片段使用以下步驟:在堆棧的頂部

  1. (test)地方字符串「測試」。
  2. dup複製堆棧中最頂端的項目。 (現在你將有兩次串在棧上。)
  3. stringwidth。執行此運算符後,最頂端的「test」字符串將被使用,並且兩個值將被添加到堆棧中:字符串的高度(最頂端)和字符串的寬度(頂端第二個)。 [更新:其實,「串的高度」是不完全正確的 - 這是相當垂直當前點的偏移整理繪製字符串後面...]
  4. 接下來,使用pop。這只是刪除堆棧中最高的值。現在只有字符串的寬度保持在堆棧的頂部。
  5. 2 div除以2該值和離開結果(一半stringwidth)。
  6. neg否定堆棧上的最高值。現在負值是最上面的堆棧。
  7. 0將值「0」放在堆棧頂部。
  8. rmoveto然後消費該堆棧上的最上面的2個值,並通過該距離(半字符串的寬度)向左移動的當前點。
  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" 

理解我的變化仰望的charpathdivexchpathbboxrollsub運營商在紅皮書中的含義。

此命令使用的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" 

在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" 

更好的可讀形式是:

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" 

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" 
+1

+1對於PostScript的很好的解釋。 – DaveB 2010-09-08 15:16:38

6

只是增加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 

的方法需要一些字體已經設置。它適用於所選字體(setfont)及其大小(scalefont)。

我使用(HÍpg)獲得可能的最大邊界框,使用強調的大寫字符和「下線」字符。結果足夠好。

另一種方法從盜取dreamlax的答案 - 一些字體不支持charpath運算符。 (見How can you get the height metric of a string in PostScript?

保存和恢復圖形上下文保持當前位置,所以它不會影響文檔的「流」。

希望我幫了忙。

+0

此外,您可以用'currentfont/FontBBox GET'邊界框,而不是使用'charpath pathbbox'得到它......在我的情況下,它完美地工作GhostScript的下;但是,打印機解釋結果不好。 – 2011-08-29 15:29:43

3

這裏的板型最追逐的答案,以補充pipitas的深入解釋。

此過程的位置和示出了中心在指定點的字符串。

/ceshow { % (string) fontsize fontname x y 
    gsave 
     moveto findfont exch scalefont setfont % s 
     gsave 
      dup false charpath flattenpath pathbbox % s x0 y0 x1 y1 
     grestore 
     3 -1 roll sub % s x0 x1 dy 
     3 1 roll sub % s dy -dx 
     2 div exch % s -dx/2 dy 
     -2 div % s -dx/2 -dy/2 
     rmoveto show 
    grestore 
} bind def 
1

我在使用上述方法用丁巴特字體可怕的結果,然後我意識到他們認爲該文本將真正開始在目前的點,在某些情況下是極不準確。

我的解決方案也依靠pathbbox來計算寬度和高度,但它也使用X0和Y0來首先到達原點。

%-- to make things nicer 
/hmoveto { 0 rmoveto } def 
/vmoveto { 0 exch rmoveto } def 
%-- cshow means something else... 
/ccshow { 
    dup %-- charpath consumes the string 
    gsave 
    newpath %-- else there's a strange line somewhere 
    0 0 moveto 
    true charpath flattenpath pathbbox 
    grestore 
    2 index sub -2 div vmoveto 
    2 index sub -2 div hmoveto 
    neg vmoveto 
    neg hmoveto 
    show 
} def 
相關問題