読者です 読者をやめる 読者になる 読者になる

しろもじメモランダム

文字についてあれこれと。

てきとうに書いて作ったフォントができるまで(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 = '&amp;' if $c eq '&';      # 半角 &, <, > は実体参照に置換
    $c = '&lt;' if $c eq '<';
    $c = '&gt;' 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のであとで読む

Perl 5.8.x Unicode関連

ここまででできたもの*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

(3)へ続く

*1:動画では触れなかった。

*2:PDF に変換したもの:_template.pdf

*3:一応ここは文字関係のブログなんですけどね!

*4:お、「で」が3連続。