フォントの作り方


BDF,TTF から QPF なフォントを作る。 山場は 4 つ。けっこ道は長い。 てか、作業が 3 日にまたがったのは PyQt に続いて 2 つ目だな。 unismall が作られた時の資料、もーちょっと まともに整えておいてくれれば手間が 3 割くらい減ったのに ...

いろいろと始めるまえに

QPF なフォントを dump するといっても、出来ることと出来ないことがある。 注意事項から。
Anti alias について
bdf からの他、ttf なフォントからのコンバートもできることになっている。 ... .pfa, .pfb なんかもできそーな記述があるんだけども、 そのまんまだと .ttf の変換ができるだけ。よーわからん。 ついでに ISO 10646-1 な encoding でないといけないんで、実際に変換できるフォントは限られる。

ttftobdf 等を中継すれば ttf から qpf にもってくることはできるが、 anti-alias をサポートした qpf を作るには bdf を経由できないので、できれば ttf から直接変換したい。 もちろんメモリ喰いの anti-alias を使わないんなら、bdf に直してからのほうが、ゆーずーが効く。 ... それに anti-alias の効いたフォントを使うのって qpdf とか gs の時くらいかもなぁ。

LC Font について
QPF フォーマットで配付されているようにみえるが実は似て非なるフォーマットで qt-embedded-free からでは扱えない (エラーにはならんのに、グリフが読めない ...)。 このため、libqte 内に細工して LC font を dump するダンプするといったことはできない。 せっかく作ったのに。まぁ image に直接描いてもってくればなんでもありなんで、そのうち。
makeqpf
qpf を作る小さなプログラム。中身は単に Qt/Embedded の関数ひとっつ叩いてるだけで、 もろもろの処理は qte のサーバが担当する。 makeqpf は何故か Qt for X11 にも付属しているが ... ってのはつまり libqt.so を link している makeqpf もあるという意味だが、 Transformed をサポートしてないので使いもんにならない。 Qt/Embedded のほう (libqte.so を link してるもの) を使う。

QPF dump をサポートしたQt/E サーバの準備

Qtopia サポートな qt/e を作ると bdf や ttf の使えない libqte が出来てしまう。 まずは bdf, ttf サポートを組み込んだ libqte 作りから。

qconfig-fat.h
目的のためには、qconfig.h から
#define QT_NO_FREETYPE
#define QT_NO_BDF
をコメントアウトすればいい ... んだが、なにか付け加えるたびに libqte の rebuild もシャクなんで、
% cat qconfig-fat.h
#define QT_NO_PROPERTIES
#define QT_NO_DRAGANDDROP
というだけのファイルを作った。 つまり、properties と Drag and Drop だけ外した libqte を作る。

QT_NO_PROPERTIES も外すとアプリケーションが qconfig-qpe.h で作ったものと互換でなくなる (Default arguments の有無の絡みで関数の引数が変わって link できなくなるものがある) ので外せない。 QT_NO_DRAGANDDROP のほうは外せないこともないが、qtopia-free の examples の make の時に error が出るものが多い (Drag and Drop が無いことを仮定した部分とあってもよいとした部分が衝突する; 手で直せるけど量が多い) ので入れた。

余談だが。この二つの項は何気に匿名さん家の 「今回の Makefile のポイント」 と同じものだ。きっと似たような問題からなんだろな。

Transformed サーバ
フォントを作る目的は landscape 用のフォントにある。 ふつーの VNC, QVFb, LinuxFb サーバの中では横倒しなフォントは dump できない。 Transformed サーバを使う必要がある ... んだが、 この Transformed サーバ、名前からして向きを変えるなどの transformation のあとに 任意のサーバに出力できるのかと思いきや、LinuxFb サーバに決め打ちになっている。 これを QVFb サーバへ繋ぎかえる。

もちろん linuxfb を相手にしたまま makeqpf を使うこともできるが、 ひとたび qte が linuxfb とコンソールを握ってしまうと 二度と戻ってこれない (無理矢理 kill するとキーボードが unicode map になって、 キーボード初期化のためのコマンドすら打てなくなった) ので、QVFb に繋いだほうが使い勝手はいい。 というか、いちいち reboot してたら makeqpf の debug できねーってば。

さて、第一の関門。TTF to QPF HOWTO にある QVFB 対応パッチを qt-embedded 2.3.2 に当てるとそのままあたるくせにきっちりバグったコードになって、 実際に使うと seg. fault してくださる。 まあ、2.3.3 対応パッチなんで、2.3.2 では動かないってのもしょうがないかもしれないが ... などと甘やかすと実は 2.3.3 でも落ちる (-_-;; とりあえず直したもの:

なお、これを Zaurus 実機で使う libqte 用のソースに当ててはいけない。 Transformed サーバの接続先が QVFb になるので rotation できなくなる。

Qt-Embedded の build.
てことで、build.

% cd /home/src/Qt/qt-embedded-2.3.2
% zcat ../qt-embedded-2.3.2-k2.diff.gz | patch -p1
% cp ../qtconfig-fat.h src/tools
% export QTDIR=/home/src/Qt/qt-embedded-2.3.2
% ./configure -qvfb -vnc -qconfig fat -system-jpeg -gif -depths 8,16,24,32 -debug
% make
% su root
# cp lib/libqte.so.2.3.2 /usr/local/qte/lib
# cd /usr/local/qte/lib
# ln -sf libqte.so.2.3.2 libqte.so.2
# ln -sf libqte.so.2.3.2 libqte.so
# exit
% make

この時点でこういうことができるようになる:

% qvfb -width 320 -height 320 &
% /usr/local/qte/bin/calculator -qws -diplay Transformed:Rot90
QVFB 内で横倒ししてみる

... 何が嬉しいかってーと、よくわからんが、ボケてる暇もなく次へいく。まだ先は長い。

BDF ソースの準備

BDF の ISO10646-1 化
たいていの日本語フォントが JIS X 0208 になっている (最初から ISO 10646-1 になってるのが付属してるのもある)。 TEXT_CODEC が入った libqte なら JIS X 0208 のまま扱わせることもできるんだが、 フォントセットという概念をもたない Qt/E では JIS X 0208 のフォントしか使えないので意味がない (ASCII や JIS X 0201 等と同時に使えない)。 ASCII, JIS X 0208 などを埋め込んだ ISO 10646-1 な BDF を用意しなければならない。

当初は JIS X 0208 → UTF-8 のテーブルを nkf -w で作って、 それをさらに UCS-2 (ISO 10646-1) に対応させたテーブルを一つ作り、 それを使って BDF を ISO 10646-1 化 ... なんてことをしたんだが、 mona font 付属の tool に jis2unicode なるものがあって、今や ENCODE の変換は一発:

% jis2unicode -b < knj10.bdf > knj10u.bdf
ただし jis2unicode はフォント名までは差し替えない。"-jisx0208.1983-0" のままである。 また、FONT, CHARSET_REGISTRY, CHARSET_ENCODING, DEFAULT_CHAR の各タグは直す必要がある。これは次の項にて。 ... てか、DEFAULT_CHAR の項が JIS X 0208 のままなんは mona font のバグだろ。

ところで、単純そうにみえて、この段階での BDF の変形が意外に難物だった。 Qt が扱える bdf の形式は bdf として表現できる範囲よりもかなり狭い。 k14 のように FONT タグを二つもつものはダメだし、名前をくくるのに 「"」も使えない。

スクリプト一発で変形したやつをそのまま makeqpf に食わせると segmentation fault で落ちてくれたりする。 結局 qte のソース (src/kernel/qfontfactorybdf_qws.cpp) 見ながら タグ書き換えの試行錯誤するハメになった。 ったく、このプロセスがあるから何度も作る気せんのだよな。

ISO 8859-1 との合成と default font width
テキストファイルだからといって BDF フォント同士の合成は editor で加えて終り、というわけにいかない。

ふつー組み合わせる ISO 8859-1 と JIS X 0208 のフォントの幅は大きく違うから、 合成した ISO 10646-1 なフォントは固定幅ではありえない。 embedded-konsole-ja では、たいがいそうであるように ASCII と JIS X 0208 のフォントの幅が 1:2 であると仮定する。 そして ASCII 内での最大の幅をもつものを基準幅として使う (TEWidget::fontChange(const QFont &) )。

ISO 8859-1 用に 5x10.bdf, JIS X 0208 に naga10 使ってそのまま合成すれば ASCII は 5x10.bdf のほうのやつ(ぜんぶ 5 pixel だな)になって、 JIS X 0208 の 10 pixel 幅の naga10 とつじつまがあうはずだが ──

ここで JIS X 0208 → UCS-2 の変換で ASCII と同じ文字に わりあたってしまう文字があると embedded konsole-ja は JIS X 0208 由来の そのグリフを含めて基準幅を算出してしまうため、表示が崩れる。

プロンプト(これはほとんど ASCII のはずだ) のすぐ右にカーソルがでず、 すこし右にずれた位置に表示されるとすれば、以上のようなメカニズムが働いている。 カーソルを移動するのに基準幅 x プロンプト文字数、ってやってるから。 文字を描くのはそれぞれの文字の幅にあわせて描くので、カーソルが飛ぶトコだけおかしくなる。

本題にもどると、JIS X 0208 由来のうち、ASCII に重なるフォントを除いて ISO 10646-1 フォントとする。 それと、そのまま合わせるとフォント名の spacing の項が "C" (等幅、コンソール用) になると思うけど、 ASCII と JIS X 0208 で合わせたフォントはもちろん等幅なんかでない。 でも別に気にしなくていい。この項、Qt/E はまったく参照してないんで ...。

% cat 5x10a.bdf knj10u.bdf > knj10u2.bdf
% patch < knji10u2.diff

TTF ソースの準備

もうひとつ、TTF のほうはというと ──
libqte に TrueType サポートを入れてあっても .ttc は扱えない。 ttc2ttf で ttf に直す。
% ./ttc2ttf msgothic.ttc
msgothic0.ttf, msgothic1.ttf なる二つのファイルが出来た。 ... えーと、どっちがどっちだっけ?

サーバに BDF, TTF を読み込ませる

作ったばっかの BDF, TTF をサーバに読ませるのにも一悶着ある。

... いや、読ませることはそんなでもないんだが ... qpf に dump する際、 makeqpf を使うが、その dump の時は makeqpf 自身が qte サーバになる。 にもかかわらず、「サーバが使うフォント」と「makeqpf が扱うフォント」が異なる概念なんである。

Qt/E のフォントは $QTDIR/lib/fonts/ におかれる。 そして qpf でないフォントは $QTDIR/lib/fonts/fontdir にリストアップされていなければならない。 一方、makeqpf は $QTDIR/etc/fonts/fontdir から自分が扱うフォントのリストを得る。

makeqpf は qpf に dump するためのフォントリストを $QTDIR/etc/fonts/fontdir から得て、 それを dump すべくサーバに問い合わせる。 くだんのサーバ (makeqpf 自身である ...) は リクエストされたフォント名にできるだけ一致するようなフォントを $QTDIR/lib/fonts/ から探して、それを目的のフォントとして扱う。

つまり、dump しようとするフォントはこの両者から認識されなければならない。

% cd /usr/local/qte/etc/fonts
% ln -sf /usr/local/qte/lib/fonts/fontdir fontdir
BDF フォント等は $QTDIR/lib/fonts/ のほうにおく。Dump する主体はサーバだからだ。 TTF のほうはここ以外でもサーバが適当に探し出してきてくれる (xft が自分の流儀のトコを探してる) が、 その探す場所は決して $QTDIR/etc/fonts/ ではない。 $QTDIR/etc/fonts/fontdir ってば、何のためにあるんかよーわからん。
makefontdir-qws
$QTDIR/lib/fonts 内の bdf から fontdir を作る。
# cd /usr/local/qte/lib/fonts
# ./mkfontdir-qws *.bdf > fontdir
# chown root.users .
# chmod 1775 .
ttf が扱えるわけではないんで中途半端だけど、mkfontdir-qws が扱えないような形式の bdf は Qt/E から扱えないんで、事前チェックのかわりくらいにはなる。

それと、dump した qpf の置き場所は $QTDIR/lib/fonts になるが、この位置は ふつー一般ユーザーから書き込めないはずだ。makeqpf を一般ユーザーから動かすとすれば、 一時的に書き込みを許可しておく。

... うちの環境はそもそも /usr を read only mount してるんで、 通常は root からすら書き込みできない。 mount -o rw,remount /usr しなきゃならんかった。 なんかな、こういうのは /var/local/lib/fonts に書くとかしてほしい。

fontdir
fontdir のフォーマットは こちら ... なんだが、3.0.4 になって変更されたのかどーか、微妙に形式が違う。 実際に使うのはこんなの:
% cat fontdir
nagaten knj10u2.bdf BDF n 50 90 u
msgothic msgothic0.ttf FT n 50 0 su 90,100,160,170,220
FT のケースでのフラグの右側は作成する qpf font のサイズ。

QPF のダンプ

やっと dump 本番。
% qvfb -width 20 -height 20 -depth 32 &
% for rot in  Rot0 Rot90 Rot180 Rot270 ; do
   ./makeqpf -qws -display Transformed:$rot -A
  done
オプションの "-A" を指定しなければ makeqpf はフォントの選択画面に入るが、 "-A" 指定すると一気にいくので qvfb には何にも表示されない。 邪魔なだけなんで、スクリーンサイズはやたら小さい(笑)。

スクリーンショット

Anti-alias な konsole と mona font を landscape に使った konqueror.
anti-alias font konsole 流石だよな俺ら
... しかし、konsole じゃ anti-alias 嬉しくないぞ。qpdf (← まだ anti-alias 非対応) で使えんと。

もひとつ追加。

# cd /home/QtPalmtop/lib
# for name in monafont_110*qpf ; do
    ln -sf $name lcfont_${name##monafont_}
  done
# kill -TERM `ps -o pid= -C qpe`
してから /home/root/Documents/.q2chrc でフォントサイズを 11 にし、さらに (右辺を下にして) landscape にしたもの:
AA by q2ch

カーソルキー「下」 (本来の向きでいうと右矢印) を押すと下にページスクロールするという、 すっごく使いやすい形になってたりする。
そして抜けてるグリフがあることも発覚 ... "~" とか。むぅ。

なお q2ch は 0.2.6 から article font が指定できるようになったので、 ascii-art をみるくらいのことで上述のような symlink は必要なくなった。

フォントパッケージ

当然だが、msgothic は配付できない。

Rotation 方向によって t5, t10, t15 が使い分けられるが、どれがどの向きだか忘れた(をい)。 無印が正立、t5 が 180 度逆、t10 が左辺が下、t15 が右辺が下だっけか。

... ところでこれ、向き別よりサイズ別のほうが使いでがあるかな? nagaten がぜんぶ込みなんで、monafont 無印が正立のみってのは混乱しそう。

追記

なお、フォントはナガ10 のほうがそれそれ "nagaten", "nagamaru", "nagamin"、 モナーフォントのほうが "monafont" になっている。

ふつーのアプリから利用可能なのは "lcfont", "fixed", "helvetica", "unifont" くらいだろうが、上のフォントをインストールしても自動で置き換えたりはしない。

konqueror などフォント名を直接指定できるアプリ以外で使うためには、 これらの名前に置き換えてやる。

# cd /home/QtPalmtop/lib
# for name in nagaten*qpf ; do
    ln -sf $name fixed_${name##nagaten_}
  done
# kill -TERM `ps -o pid= -C qpe`
とか。 もっとも上の konsole の例はこーやって link 張ったんではなくて、 embedded-konsole-ja のソースを書き換えて font 名を追加してしまったが ... だって、font menu にリストされてるフォントって役にたたない(カーソル位置が崩れる) やつが多いんだもん。

このあたり、真面目に管理しようとするならやっぱ font package manager が要るんかなぁ。

メモ

どとーの誤字修正 (Jan. 15, 2003)。

さらに追記

C700 はビュースタイルが向きの基準。 これで使うフォントの向きが正立のもので、 インプットスタイルで使うフォントは「左辺が下」のものになる。
ゆえに monafont を使うなら必要になるのは無印と t10.

A300 は本来の向きが正立。フォントは少なくとも無印が必要。Rotation かけるならその向きのも。 SL5x00 は右辺が下になる向き(カーソルキーが液晶の左に来る向き) が正立で、本来の向きは「左辺が下」状態。

もひとつ追記

monafont, nagaten ともども zaurus-ja に上げた。 emmie の feed/ からは可及的すみやかに消去される予定 (Jan. 22, 2003)。
[日記へ] [目次へ]