2

PostScript可以通过计算 SpaceMod 和使用来证明一行widthhow

/SpaceMod % calculated from line width and stringwidth
/h { 0 32 } def 

/Times-Roman findfont
14 scalefont setfont    
SpaceMod h (This line with single font is justified) widthshow

但是我们如何将这种方法用于具有不同字体的行呢?一个简单的例子是在该行中有一个粗体部分

/Times-Roman findfont
14 scalefont setfont    
X h (How to) widthshow

/Times-Roman-Bold findfont
14 scalefont setfont    
X h justify this line) widthshow

/Times-Roman findfont
14 scalefont setfont    
X h (with multi fonts) widthshow

问题是我们没有一个字符串来获取整行stringwidth。即使基于单个字符串计算它,我们如何计算/设置 SpaceMod?

或者我们需要使用另一种方法来对齐多字体?

4

1 回答 1

2

蛮力..

/justifyshow {
    /linerem exch def
    dup length 3 idiv /nsub exch def
    /instring exch def
    instring aload pop
    /spct 0 def
    /setf {3 2 roll findfont 3 2 roll scalefont setfont } def
    nsub {
        setf dup
        stringwidth pop linerem exch sub /linerem exch def
        {32 eq { spct 1 add /spct exch def} if } forall
         } repeat
    /addsp linerem spct div def
    instring aload pop
%cleanup
    [ /spct /linerem /instring ] { userdict exch undef } forall
% comment following three lines to reverse argument order
    /ct nsub def
    nsub 1 sub { ct 1 sub /ct exch def ct 1 add 3 mul  3 roll } repeat
    userdict /ct undef
%
    nsub { setf addsp 0 32 4 -1 roll  widthshow } repeat
} def
% usage [ fontn sizen stringn ...  font1 size1 string1 ]
% linewidth justifyshow

100 100 moveto
[
/Helvetica 12 (hot to justify)
/HelveticaBold 24 ( large bold)
/Helvetica 12 ( in part of a line)
] 400 justifyshow

毫无疑问,这可以收紧一点..

编辑,正如我所说的那样,另一个收紧了一点。

% count spaces in a string
/stringspace {0 exch { 32 eq { 1 add } if}  forall} def
% set font routine
/setf {3 2 roll findfont 3 2 roll scalefont setfont } def
/justifyshow {
% def array length leave line length and array on stack
exch dup length 3 idiv /nsub exch def
aload pop
% split input array into array of [ font size string ] arrays
/incc nsub 3 mul 1 add def
[ nsub { incc 1 roll [ 4 1 roll ] incc 3 sub /incc  exch def } repeat  ] /fstringlist exch def
% reverse sort string order (can comment out this line if needed )
[ nsub 1 sub -1 0 { fstringlist exch get} for ] /fstringlist exch def
% count spaces
0 fstringlist {aload pop 3 1 roll pop pop stringspace add } forall
% count total line length
0 fstringlist {aload pop setf stringwidth pop add } forall
% at this point the target length, actuial length and space count are on the stack
% calculate space to add
3 -1 roll sub neg exch div /addsp exch def
% show strings
fstringlist { aload pop setf addsp 0 32 4 -1 roll  widthshow } forall } def

100 100 moveto
[
/Helvetica 12 (how to justify)
/HelveticaBold 24 ( large bold)
/Helvetica 12 ( in part of a line)
/Helvetica 50 ( !!!)
] 400
justifyshow
于 2012-09-10T19:13:08.423 回答