先の「文字列が枠内におさまるように自動改行しながら印刷する(PostScript)」はEUC-JPバージョンでした。これを Shift-JIS で行うには1文字と残りの文字列に分けるための判定方法を変更する必要があります。
Shift-JISの半角文字は0x80〜0x9F、0xE0〜0xFF を使わないようになっています。この範囲の値のバイトに合えば全角文字ですから2バイト文字と判断して次のバイトと組み合わせて1文字とする必要があります。
%!PS-Adobe-3.0 % 漢字 (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 %% ------------------------------------------------------ (=== Test is0x81_0x9f ===\n) print 16#80 is0x81_0x9f == % false 16#81 is0x81_0x9f == % true 16#82 is0x81_0x9f == % true 16#9f is0x81_0x9f == % true 16#a0 is0x81_0x9f == % false (=== Test is0xe0_0xef ===\n) print 16#df is0xe0_0xef == % false 16#e0 is0xe0_0xef == % true 16#e1 is0xe0_0xef == % true 16#ef is0xe0_0xef == % true 16#f0 is0xe0_0xef == % false (=== Test isKANJI ===\n) print 16#80 isKANJI == % false 16#81 isKANJI == % true 16#82 isKANJI == % true 16#9f isKANJI == % true 16#a0 isKANJI == % false 16#df isKANJI == % false 16#e0 isKANJI == % true 16#e1 isKANJI == % true 16#ef isKANJI == % true 16#f0 isKANJI == % false
- 文字列が枠内におさまるように自動改行しながら印刷する(Shift-JIS バージョン)
%!PS-Adobe-3.0 2.834645669 2.834645669 scale newpath /MS-Mincho-90ms-RKSJ-H findfont 10 scalefont setfont /vPosition 297 20 sub def % A4 297mm /Space 3 def /CellW 100 def /ADJW CellW Space 2 mul sub def 0.3 setlinewidth /Left 20 def /newLineHight 12 def /hPosition Left Space add def hPosition vPosition moveto CellW 0 rlineto 0 newLineHight 8 mul neg rlineto CellW neg 0 rlineto closepath stroke /newline { /vPosition vPosition newLineHight sub def hPosition Space add vPosition moveto } def % 先頭から指定長の文字列を取得して返す。 /Head { 0 exch getinterval} def % 指定位置より後の文字列を返す。 % 参考:ローカル変数に値を渡す方法 % http://www.cs.kyoto-wu.ac.jp/~konami/documents/ps/psmemo.html#subsec6:5 /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 % 漢字 (2byte) :上位1バイト 0x81〜0x9f、 0xe0〜0xef /isKANJI { dup is0x81_0x9f exch is0xe0_0xef and } def /is0x81_0x9f { dup 16#81 ge exch 16#9f le and } def /is0xe0_0xef { dup 16#e0 ge exch 16#ef le and } def % スタックにある文字列の最初の文字が1バイト文字、2バイト文字であるかを判定し、 % 残りの文字をスタックに積み、1文字をスタックに積 /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 % 残りの文字列が 0 より長いときは foldString を再帰する /ifFoldString { dup length 0 gt { foldString } if } def % 指定位置で折り返しながら文字列を表示。 /foldString { Split dup stringwidth pop % 1文字を複製し、幅を求める currentpoint pop % 現在の座標取得。Y座標は捨てる add % 現在位置 + 文字列の幅 ADJW hPosition add % 終点 le { show ifFoldString } % 終点より座標が少ないときは1文字表示。残り文字があれば再帰。 % 改行して1文字表示。残り文字があれば再帰。 { newline show ifFoldString }ifelse % } def hPosition Space add vPosition moveto newline (本日は晴天なり本日は晴天なり。我輩は猫である。名前はまだない。Hello,world! 枠内に入るよう横幅を調整しています。) foldString showpage