てきとうに書いて作ったフォントができるまで(2)
てきとうに書いて作ったフォントについて、(1)からの続き。
Perl を覚える
割り当て表を作ったら、そこからシートを生成する。が、コンピュータに生成してもらうためには、何かプログラムを書かなければならない。手書きフォント生成のキモになる、スキャン画像の分割も同じ。ということで、Perl を勉強してみた。
では、なぜ Perl なのか?ということだが、特に深い理由は無い。最初に参考にした「mieki256 wiki - フォント作成手順」にあるスクリプトが Perl で書かれていたので、とりあえずそれを読むために Perl の入門サイトをざっと見てみた、というところ。
それまでは「Perl って id:dankogai がちょくちょくなんか書いてるアレだよね、よく知らんけど」という程度の認識しかなかったが、調べているうちに「文字列処理が楽」で「PerlMagickとかいうので画像の加工ができる」らしいことが分かったので、ちょうどいいやと思ってもう少し勉強してみた。一種の遅延評価勉強法?
コードリストと手書きシートを生成する
作っておいた文字割り当て表(前回参照)から、まず扱いやすいように Unicode のコードポイントに変換したリスト*1を作る。
あ い う え お か き く け こ …
例えば、↑これが↓こうなる。
3042 # あ 3044 # い 3046 # う 3048 # え 304a # お 304b # か 304d # き 304f # く 3051 # け 3053 # こ : :
で、ついでに手書きシートのテンプレート(_template.svg*2)から、実際に書き込むシートを生成する。処理としては、ダミーで入れておいた “*” をそれぞれの文字で置き換えるだけ。
ということで、書いてみたのが下のスクリプト。エラーの処理とかほとんど考えてないけど、とりあえず動いたからまぁいっか、という状態。本当にこれでいいんだろうか。変なところがあったらぜひツッコミを。
#!/usr/bin/perl # # 文字割り当て表からコードポイントのリスト(code/_*.txt)を作成し、 # さらにテンプレートから手書きシート(sheet/svg/*.svg, sheet/*.pdf)を作成 # # usage: perl codesheet.pl [chartable] use strict; use warnings; use File::Basename; my $chartable = $ARGV[0]; # 文字割り当て表 my $codelist = "code/_" . basename($chartable); # コードリスト my $template = "sheet/svg/_template.svg"; # テンプレート my $svgsheet = "sheet/svg/" . fileparse($chartable, '.txt') . ".svg"; # 手書きシート(svg) my $pdfsheet = "sheet/" . fileparse($chartable, '.txt') . ".pdf"; # 手書きシート(pdf) # コードリスト作成 open(CHARTABLE, "<:utf8", $chartable) or die "$!"; open(CODELIST, ">:utf8", $codelist) or die "$!"; my @charlist = (); # 文字のリスト while (<CHARTABLE>) { $_ =~ s/(\r\n|\n|\r)$//g; # 行末の改行を削除 if ($_ !~ /^#/) { # コメント行は無視 my @char = split(/ /); # コードポイントを出力 foreach (@char) { print CODELIST sprintf("%04x", unpack("U", "$_"))." # $_\n"; } push(@charlist, @char); # リスト末尾に追加 } } close(CHARTABLE); close(CODELIST); print "wrote codelist: $codelist\n"; # 手書きシート作成 open(TEMPLATE, "<:utf8", $template) or die "$!"; open(SVGSHEET, ">:utf8", $svgsheet) or die "$!"; while (<TEMPLATE>) { if (/\*/) { my $c = shift(@charlist); $c = '&' if $c eq '&'; # 半角 &, <, > は実体参照に置換 $c = '<' if $c eq '<'; $c = '>' if $c eq '>'; $_ =~ s/\*/$c/; } print SVGSHEET $_; } close(TEMPLATE); close(SVGSHEET); print "wrote svg-sheet: $svgsheet\n"; # Inkscspe で PDF に変換 system("inkscape -f $svgsheet -A $pdfsheet -T"); print "wrote pdf-sheet: $pdfsheet\n"; exit;
自分の環境では設定が悪いのか、Ubuntu から手書きシートを印刷すると上にズレてしまう。そのため、他の環境から(SVG の読めるソフトがインストールされていなくても)すぐ印刷できるよう、最後に PDF へ変換しておいた。
途中、“Wide character in print at ***.pl line *.” のようなエラーが出てきて困ったが、調べてみると UTF8 フラグというものが関係しているらしい。とりあえず “:utf8” をつけることで回避したが、まだよく理解していない*3のであとで読む。
ここまででできたもの*4
文字種 | 割り当て表 | コードリスト | シート(SVG) | シート(PDF) |
---|---|---|---|---|
テンプレート | - | - | _template.svg | _template.pdf |
ひらがな・全角英数・記号その1 | hira.txt | _hira.txt | hira.svg | hira.pdf |
カタカナ・記号その2 | kata.txt | _kata.txt | kata.svg | kata.pdf |
特殊文字・ギリシャ文字・キリル文字 | scgc.txt | _scgc.txt | scgc.svg | scgc.pdf |
半角文字 | half.txt | _half.txt | half.svg | half.pdf |