文字列を指定された幅の文字列に分割して配列に入れる。

表の枠内に印字するときに1行に収まらないときは改行するというのは作りました。
今度は1行に収まるときは縦位置を中央に、2行、3行と増えても縦位置を中央に印字したいのです。
そのために文字の幅に応じて文字列を分割し、配列に入れて表示する手続きに渡します。

  • このソースはShift-JIS で記述されている必要があります。
%!PS-Adobe-3.0
2.834645669 2.834645669 scale
newpath 

/vPosition   297 20 sub def  % A4 297mm
/newLineHight 12 def
/Left 20 def
/Space 3 def
/hPosition Left Space add def

/newline { /vPosition vPosition newLineHight sub def
            hPosition Space add vPosition moveto } def 

% 先頭から指定長の文字列を取得して返す。
/Head { 0 exch getinterval} def

% 指定位置より後ろ文字列を返す。
/ldict 1 dict def
/Tail {
    ldict begin
    /start exch def
    /str   exch def
    /len str length start sub def
    str start len getinterval
    end
} def

% 文字列は Shift-JIS 
% 漢字 (2byte) :上位1バイト  0x81〜0x9f、 0xe0〜0xef 
/isKANJI     { dup is0x81_0x9f exch is0xe0_0xef or } def  % スタックの値は0x81〜0x9f または 0xe0〜0xef
/is0x81_0x9f { dup 16#81 ge exch 16#9f le and }      def  % スタックの値は0x81〜0x9f
/is0xe0_0xef { dup 16#e0 ge exch 16#ef le and }      def  % スタックの値は0xe0〜0xef


/sdict 1 dict def
/Split {
    sdict begin
    /str   exch def
    str 0 get isKANJI { str 2 Tail  str 2 Head}         % 2byte 文字
                      { str 1 Tail  str 1 Head} ifelse  % 1byte 文字
    end
} def

% 二つの文字列を連結する。
% stack : strBase str
/s2dict 1 dict def
/joinString {
    s2dict begin
    /str     exch def
    /strBase exch def
    /baseLen strBase length def
    /strLen  str     length def
    /newString baseLen strLen add string def 
    newString 0 strBase putinterval
    newString baseLen str putinterval
    newString
    end
} def


% 配列にオブジェクトを追加する。
% stack : obj array 
/s3dict 1 dict def
/addToArray {
    s3dict begin
    /obj     exch def                     % 追加するobj
    /baseArray exch def                   % 受け取った配列
    /baseLen baseArray length def         % 受け取った配列の長さ
    /newArray baseLen 1 add array def     % 受け取った配列より1長い返す配列を作る
    baseArray aload                       % 受け取った配列の全要素をスタックへ
    obj                                   % 追加するobjもスタックへ
    exch pop
    newArray astore
    end
} def

% 指定された幅の文字列と残り文字列に分割する。
% splitString : inString outString len
/splitString {
    ldict begin
    /inString  exch def
    /outString exch def
    /slen exch def
    inString length 0 eq {()()}                     % out : ()()
                         { inString Split } ifelse  % out : (s)(rest...)
    /char exch def
    /rest exch def
    /newOut outString char joinString def
    newOut stringwidth pop
    slen lt
           {rest length
            0 gt { slen newOut rest  splitString}
                 { () newOut  } ifelse
            }
           { inString outString }ifelse

    end
} def

% 指定された幅の文字列に分割して配列に入れる。
% foldToArray : inString array len
/foldToArray {
    sdict begin
    /inString  exch def
    /ary exch def
    /len exch def
    len () inString splitString
    ary exch addToArray
    exch dup length 0 gt { len 3 1 roll foldToArray}
                         { pop } ifelse
    end
} def

hPosition vPosition moveto
newline
% フォントサイズにより文字数は変化する。
/MS-Mincho-90ms-RKSJ-H findfont 10 scalefont setfont
40 [] (1234567890helloworld---abc123456789) foldToArray ==
% => [(12345678) (90hellow) (orld---a) (bc123456) (789)]

40 [] (1) foldToArray ==
% => [(1)]

40 [] () foldToArray ==
% => [()]

40 [] (フォントサイズにより文字数は変化する。) foldToArray ==
% => [(\203t\203H\203\223\203g) (\203T\203C\203Y\202\311)
      (\202\346\202\350\225\266\216\232) (\220\224\202\315\225\317\211\273)
      (\202\267\202\351\201B)]

showpage