即席でフォントを作ってみた@サマースクール
何か発表しないといけないらしい
サマースクールに参加しようと問い合わせをしたのは開催当日2日前、8月18日になってからのこと。返信のメールによると幸いにもまだ一人分空きがあったのだが、
その後の勉強会では
参加者のみなさん一人ずつにお話をしていただきます。
持ち時間は30分です。
テーマは自由ですが、しいてつければ「私の仕事」
30分、しゃべってもらってもいいですし、
参加者に質問を投げかけて応えてもらいながら進めるとか
進行は自由に考えてください。
なんと。発表が必須らしい。おいおいおい初耳だよやっべどうしよと焦る焦る。
文字や印刷関係の仕事をしているわけでもないし、かといって30分話せるようなネタを持ち合わせているわけでもない。ネタがあったらどんどんこのブログに書いてしまう性質なので、ストックなんてものは基本的にない。悩みに悩んだ挙句、最終的に「即席でフォントを作ってみよう」というテーマにした。
元ネタは、以前動画を作ってわりと好評だったこの記事*1。
発表の場で作ってみた
今回は時間もなかったので、A4の用紙に一人10文字ずつ書いていただき、それを10人分、計100文字からなるひらがなフォントを作成することにした。
これをスキャンできれば楽なのだが、残念ながら今回はスキャナーがない。そこでスマートフォンのカメラで用紙を撮影し、手作業で画像を修整した。これに一番時間がかかった(笑)
その後は画像を1文字ずつ切り出し。PerlMagick を利用した。ここからの流れは前回とほとんど同じなので、以前の記事や動画を参考にしてほしい。
#!/usr/bin/perl # sheet_img/ 内の画像(ka.png など)をグリフごとに分割し、out/pgm/uxxxx.pgm として保存 # usage: perl split.pl use strict; use warnings; use utf8; binmode(STDOUT, ":utf8"); use File::Basename; use Image::Magick; my @files = glob "sheet_img/*"; # 手書きシートの画像を開く foreach my $file (@files) { my $img = Image::Magick->new; $img->Read($file); splitGlyphs($img, getCodepoints($file)); undef $img; } exit; sub getCodepoints { my $file = shift; my %table = ( a => "あいうえおがぎぐげご", ka => "かきくけこざじずぜぞ", sa => "さしすせそだぢづでど", ta => "たちつてとばびぶべぼ", na => "なにぬねのぱぴぷぺぽ", ha => "はひふへほぁぃぅぇぉ", ma => "まみむめもゃ、ゅ。ょ", ya => "やっゆーよ?!・「」", ra => "らりるれろ12345", wa => "わゐんゑを67890", ); my $basename = basename($file, ".png"); print "$file $table{$basename}\n"; my @codepoints = unpack "U*", $table{$basename}; return \@codepoints; } # セルに切り分けpgmで保存 sub splitGlyphs { my ($img, $codepoints) = @_; my ($imgWidth, $imgHeight) = $img->Get('width', 'height'); my $cellWidth = $imgWidth * (4 / 24); my $cellHeight = $imgHeight * (4 / 11); my $marginX = $imgWidth * (1 / 24); my $marginY = $imgHeight * (3 / 11); my $paddingX = $cellWidth * 0.05; my $paddingY = $cellHeight * 0.05; foreach my $row (0..1) { my $offsetY = $row * ($cellHeight + $marginY); foreach my $col (0..4) { my $offsetX = $col * ($cellWidth + $marginX); my $cellImg = $img->Clone(); $cellImg->Crop( width => $cellWidth - 2 * $paddingX, height => $cellHeight - 2 * $paddingY, x => $offsetX + $paddingX, y => $offsetY + $paddingY, ); my $cellCodeStr = sprintf "u%x", (shift @$codepoints); $cellImg->Write(type => "Grayscale", filename => "out/pgm/$cellCodeStr.pgm"); } } }
これで1文字ずつのビットマップ画像に切り分けられたので、Potrace でベクターに変換。
#!/bin/bash # グリフ画像(out/pgm/uxxxx.pgm)を、potraceですべてSVG(out/svg/uxxxx.svg)に変換 # usage: ./pgm2svg.sh pushd out for i in pgm/*.pgm ; do echo $i potrace -s $i -W 10cm -H 10cm -o svg/`basename $i .pgm`.svg done popd
あとはお馴染み FontForge を利用して、OpenType フォントに纏め上げる。
#!/usr/bin/fontforge -script _fontname = "out/sokuseki.otf" _importfile = "out/svg/u*.svg" New() # .notdef作成 Select(0x0000) SetWidth(1000) SetGlyphName(".notdef") # エンコードにUnicodeを指定 Reencode("unicode") # SVGをすべてインポート Print("import...") Import(_importfile, 0) # 自動ヒントづけOFF SelectAll() DontAutoHint() # 整数値に丸める RoundToInt() # 半角スペース作成 Select(0u0020) SetWidth(500) # 全角スペース作成 Select(0u3000) SetWidth(1000) # フォント情報設定 SetFontNames("SokusekideTsukuttaFont",\ "Sokusekide Tsukutta Font",\ "Sokusekide Tsukutta Font",\ "Medium",\ "2011.8.21 Osaka DTP no Benkyo-beya Summer School",\ "1.00") SetTTFName(0x411, 1, "即席で作ったフォント") SetTTFName(0x411, 4, "即席で作ったフォント") SetOS2Value("WinAscent", 200) SetOS2Value("WinDescent", 200) SetOS2Value("HHeadAscent", 200) SetOS2Value("HHeadDescent", -200) # OTF生成 Generate(_fontname, "", 0x94) Print("generated: "+ _fontname) Close() Quit()
これで完成。できあがりはこんな感じ。
というわけで
なんとか無事にフォントが完成した。技術的には3年前から何も進歩していないし、そもそもが特に難しいことをやっているわけでもない(ツールさまさまです)ので、いずれはもうちょいスゴいことをやってみたいと思う所存。
*1:いま見返してみるといろいろとツッコミどころが……(笑)