PostScript の小枝

back

PostScript は Adobe によって開発されたプリンタ印刷用の プログラミング言語です。ふつうはプログラムが自動的に 生成するものであり、人間が手で書くことはまずないのですが、 ちょっと勉強すれば短いコードでもずいぶん面白い図形が描けるようになります。


プリンタのテスト用, A4用紙いっぱいに X を書く

%!PS
/x 595 def /y 842 def
0 0 moveto 0 y lineto
x y lineto x 0 lineto closepath stroke
0 0 moveto x y lineto stroke
0 y moveto x 0 lineto stroke
showpage

実行結果 (PNG, 15KBytes)


再帰的な木

%!PS
300 300 translate 2 2 scale
/tree { 1 sub dup dup 0 gt newpath 0 0 moveto 0 70 lineto stroke {
gsave 0 20 translate 20 rotate -0.7 0.7 scale tree grestore
gsave 0 40 translate -18 rotate -0.8 0.8 scale tree grestore
} {pop pop} ifelse } def
10 tree showpage

実行結果 (PNG, 65KBytes)


「ほげ」の印刷

%!PS
/rnd4 { rand 4 mod } def
/xrnd { rand 101 mod 50 sub } def
/yrnd { rand 51 mod 25 sub } def
/mov1 { dup 0 eq { pop xrnd -25 } { dup 1 eq { pop 50 yrnd }
{ dup 2 eq { pop xrnd 25 } { pop -50 yrnd } ifelse } ifelse } ifelse } def
/line1 { { rnd4 dup rnd4 dup 3 1 roll ne { exit } if pop pop } loop
newpath mov1 moveto mov1 lineto stroke } def
300 400 translate 7 8 scale 90 rotate
[ 1 0.2 0.2 1 0 0 ] concat 0 setlinewidth
/Ryumin-Light-H findfont 40 scalefont setfont
($[$2) dup stringwidth pop 2 div 0 exch sub -16 moveto false charpath clip
1000 { line1 } repeat showpage

実行結果 (PNG, 100KBytes)


「げぶげぶ」の印刷

%!PS
300 400 translate 4.0 4.0 scale 90 rotate /GothicBBB-Medium-H
findfont 40 scalefont setfont ($2$V$2$V) dup stringwidth pop 2 div
0 exch sub -16 moveto false charpath clip 5000 { newpath rand 100
mod 100 div setgray rand 201 mod 100 sub rand 101 mod 50 sub rand
100 mod 50 div 0 360 arc fill } repeat showpage

実行結果 (PNG, 34KBytes)


EPS ファイルの構造

%!PS-Adobe-1.0 EPSF
%%Title: タイトル
%%Creator: 作成したプログラム
%%CreationDate: 作成した日付
%%BoundingBox: x0 y0 x1 y1
%%Pages: 総ページ数
%%DocumentFonts: フォント1 フォント2 ...
%%EndComments

%%Page: ページ番号

%%BeginDocument: ファイル名
... 別のEPSファイル ...
%%EndDocument

%%Trailer
... 追加情報 ...

用紙さいず

(単位: point)


dvips の出力から指定ページをとり出す perl スクリプト

#!/usr/local/bin/perl5
foreach $i (@ARGV) {
    if ($i =~ /^-p([-,0-9]+)$/) {
        $i = $1;
        while($i ne '') {
            if ($i =~ /^([0-9]+)-([0-9]+)\b/) {
                $i = substr($i, length("$1-$2"));
                for($x = $1; $x <= $2; $x++) { $range[$x] = 1; }
            } elsif ($i =~ /^([0-9]+)\b/) {
                $i = substr($i, length("$1"));
                $range[$1] = 1;
            } else {
                $i = substr($i, 1);
            }
        }
    } else {
        close(STDIN); open(STDIN, $i);
    }
}
$page = 0; $output = 1;
while() {
    chop;
    if (/^%%Page:\s*([-0-9]+)\s+([0-9]+)/) {
        $page++;
        $output = $range[$page];
    }
    if ($output) { print "$_\n"; }
    if (/\beop$/ || /^EP$/) { $output = 1; }
}
close(IN);

Last Modified: Tue May 27 01:27:23 EDT 2003 (05/27, 14:27 JST)
Yusuke Shinyama