{{toc}}

! CLWFK の使い方

!! 概要
CLWFK (Common Lisp port of Wada-laboratory Font Kit) は、 
和田研フォントキットを Common Lisp に移植したバージョンです。
[[さざなみフォント]]の漢字データを作成するのに使用されています。

このページでは、CLWFK をインストールして動かしてみたい人のために
必要な情報をまとめたものです。

! 入手方法

CLWFK 自体は多くの利用者が見込めないため、開発の途中でリリースを
行うことはありません。(さざなみフォントのリリース時にはその時の
コード一式をアーカイブしていますが、2 年以上前の版です)。
sourceforge.jp の CVS から最新のアーカイブを入手できます。

http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/efont/#dirlist
にアクセスし、ページの下にある 'Download tarball' から
ダウンロードしてください。

必要なサブディレクトリは wadalab-fontkit と sazanami の 2 つ
だけですので、他の 3 つは消してもかまいません。

! 開発環境の整備

!! CMUCL

CLWFK の漢字定義は日本語 EUC で書かれていますので、EUC が通る
Common Lisp 処理系が必要です。
移植時には、CMUCL と GNU clisp の 2 つをターゲットとして、
その両方で動くことを確認しながら作業を行いましたが、
その後の開発は (主に実行速度の問題により) CMUCL のみで
行っています。

[[SBCL|http://www.sbcl.org/]] (CMUCL からの fork なので
互換性は高く、性能も同等と考えられる) には Windows への
試験的な port が存在するので、移植できたならば開発をそちらに
移行したいと願っていますが、現在のところ移植する余力がありません。(ちなみに、Mac OS X では 
[[CMUCL Darwin Port|http://www.pmsf.de/personal/darwin/]] が
使用できるはずです)。

!! FontForge

現在、さざなみフォントの生成に使われる出力ファイルは 
FontForge の SFD ファイルですので、
FontForge をインストールしていないとあまり役に立ちません。

* [[FontForge|http://fontforge.sourceforge.net/ja/]]
* [[Windows 版 FontForge 簡単・お手軽パッケージ|http://www.geocities.jp/meir/fontforge/]]

漢字のプリミティブ定義を行う Lisp ファイルを直接読み込んで
編集したり、肉付けをしたりできるパッチを作成しています。
* [[FF+CLWFK|http://khdd.net/kanou/fonts/ff/ff+clwfk.html]]

! Common Lisp について

!! Lisp の勉強に使っているページなど

:[[CMUCL|http://www.cons.org/cmucl/]]:cons.org にあるCMUCL 公式ページです。
:[[よろずや|http://www.geocities.co.jp/SiliconValley-SanJose/7474/index.html]]:CMUCL の使い方(日本語シンボルの通し方とか)に関して、ここの情報にお世話になりました。
:[[CLtL2|http://www.cs.cmu.edu/Groups/AI/html/cltl/cltl2.html]]:Common Lisp the Language, 2nd Edition の全文です。HTML の tarball をダウンロードしてローカルに置くことをお勧めします。言語のコアの機能だけ抜粋していることと、過去の有名な処理系の組込み関数が Common Lisp ではどのように書けるかを紹介しているため、私はこれをメインに使っています。
:[[Common Lisp Hyperspec|http://www.lispworks.com/documentation/HyperSpec/]]:ANSI Common Lispの規格書(1100ページある)をハイパーテキスト化したものです。
:[[ANSI Common Lisp(書籍)|http://www.pearsoned.co.jp/hed/search/onlinecatalog.html?id=276]]:規格書だけで言語を学ぶのはたいへんですので、ちゃんと勉強するには教科書を読むのが近道です。CLWFK にかぎらず Common Lisp を使う人にとって、この本には買う価値があります。
:[[on Lisp|http://user.ecc.u-tokyo.ac.jp/~t50473/onlispjhtml/index.html]]:言語仕様を知っただけではピンと来ないのが Lisp です。和田研フォントキットは Lisp ならではの書き方で書かれているプログラムなので、Lisp の発送に馴染むための副読本として On Lisp をお勧めします。著者は前項の書籍と同じポール・グレアム。書籍版の刊行が待たれます。

! コンパイル
CLWFK を実行するには、まず renderer/ ディレクトリの下でコンパイルする必要があります。
Makefile が用意されていますが、compile.l を実行しているだけです。
関数 compile-file-if-updated の中にデバッグ用の optimize 宣言が
コメントアウトした形で入っていますので、お好みに応じて
コメントを外してください。

警告がかなり出ますが、とりあえずは無視して平気です 
(潜在的な問題点はいろいろあるので、精査して修正してくださる方は
大歓迎です)。

ファイルを修正した後は、更新したファイルのみをコンパイルします。
ファイルコンパイル時にあらかじめ読み込むのは compat.l と lib.l 
だけですので、別ファイルで用いられるマクロ定義は
これらのどちらかのファイル内で行う必要があります。

! 実行してみる

フォント生成を実行する作業ディレクトリとして、sazanami/ を
使用しています。
Makefile に書かれている LISP と FONTFORGE のパスが正しければ、
make 一発でコンパイルできるはずです。

CLWFK による SFD ファイルの生成は sazanami/makeall.l が
行っています。

 lisp -load makeall.l

とすれば Sznm-M-K.sfd,  Sznm-G-K.sfd,  Sznm-O-K.sfd の 
3 つの SFD ファイルが書き出されます。

とくに注意すべき事柄をいくつか挙げておきます。

* 画面表示も入力ファイルも EUC です。
* Makefile からは -batch オプションつきで呼び出されていますので、エラー発生時にはデバッガに落ちずに終了してしまいます。
* エラーが発生する時には、十中八九、線の結合処理でこけています。:remove-overlap t を :remove-overlap '''nil''' に置き換えてみてください。

----

自分でゼロから好きな式を評価したい場合のために、CLWFK ソース一式の読み込み作業は "load.l" にまとめてあります。

例えば、漢字のスケルトンを表示する簡単な方法です。

 % lisp -quiet
 * (load "load.l")
 
 T
 * (skeleton2list (applykanji 一 'gothic) 'gothic)
 (((ANGLE 15.000371 205.0) (ANGLE 385.99628 205.0) (ANGLE 385.99628 179.0)
   (ANGLE 15.000371 179.0)))

! デバッグ方法

!! 注意点
* CMUCLは強力な最適化機能を持つコンパイラで、let* や do で定義された中間変数は存在しないことが多いです。wadalab-fontkit/renderer/compile.l の declare 宣言をコメントアウトしてあるので、(declare (optimize (debug 3))) を有効にしてコンパイルした方がいいでしょう。
* load.l では、ディレクトリ wadalab-fontkit を相対パスで指定しているので、他のディレクトリで動かすためには修正が必要です。
* load.l では sazanami-patch.l で和田研フォントのオリジナルの字形定義を置き換えている物がありますので、注意してください。
* 逆に、primdata/ の下の一部のファイルでは読み込まれていないファイルがあります。
* CLWFK では do ループの中で l や ll という変数名を多用していますが、同名のデバッガコマンド (ll は list-locals の略称) が衝突するため、変数名を打っただけでは表示できません。(progn ll) のように progn で囲む必要があります。

!!! 字形のダンプ

デバッグをしやすくするために字形を SVG に書き出す機能を作りました。

!!! (dump-skeleton-to-svg filename skel)

スケルトンを書き出します。

使用例:

 (dump-skeleton-to-svg "U+6F22.svg"
                       (applykanji 漢 'mincho2))

偏(へん)と旁(つくり)がどのように変形されるかを
色塗りで表示しています。
また、最も近接している縦画を他のスケルトンと別の色で表示します。

!!! (dump-outline-to-svg filename outline)

アウトラインを filename に書き出します。

使用例:

 (dump-outline-to-svg "U+6F22.svg"
  (makeoutline (skeleton2list (rm-limit (applykanji 漢 'mincho2)) 'mincho2)))

!!!! キーワード引数:

文字の外の枠を表示したくない場合は引数 :no-frame t を指定します。

アウトラインを幅のある線で表示したくない場合は :fill t を
指定します。FontForge で SVG 取り込み機能を使用する時
には、:no-frame t :fill t をともに指定するとよいでしょう。

! ソースの構造

!! 参考文献
!!! 論文
ソースの構造を理解する前に、全体としての処理の流れを
情報処理学会論文誌に掲載された 2 本の原論文でつかんでおくと
いいでしょう。著者による投稿版がオリジナル版
和田研フォントキットのサイトで公開されています。
[[論文リスト|http://gps.tanaka.ecc.u-tokyo.ac.jp/wadalabfont/pukiwiki.php?%5B%5B%CF%C0%CA%B8%A5%EA%A5%B9%A5%C8%5D%5D]] 
のページからダウンロードできます。

!!! Web
太田一樹氏によって「[[CLWFK (Common Lisp port of Wadalab Font Kit)を読む。|http://kzk9.net/column/wadaken/]]」が公開されています。

!! wadalab-fontkit 以下のディレクトリ構造

:build/:ビルドテスト用のディレクトリ (現在フォントの生成には ../sazanami/ にあるスクリプトを使う)
:jointdata/:S 式による文字の部品組合せ定義
:kanjidata/:文字コード表
:primdata/:プリミティブ (分解できない部品) の定義
:renderer/:処理プログラム

!! renderer のファイル一覧

(1) 共通ライブラリ
:compat.l:和田研フォントキットが最初に開発されたプラットフォームである UtiLisp との互換性を取るためのレイヤ。
:lib.l:ベクトル演算と平面幾何学の関連ルーチン、def〜 で始まるデータ構造定義。

(2) スケルトン組み立て
:apply.l: 偏と旁(つくり)などの部品を組み合わせて漢字のスケルトン定義を組み立てる。
:pack.l: 他の部品の組合せで定義されている部品の定義を展開して入れ子になったリスト表現に展開する。
:newjoint.l: 2つの部品と相互関係を与えられた時にバランスを自動計算して結合する
:transform.l: 部品と変換行列を与えられた時に、変形処理を行って部品のリスト構造をつなぎ合わせる
:unit.l: 部品の持つ横幅・高さの自然な大きさ (xunit, yunit) を計算する
:yokosort.l: 横画と横画の間の適切と思われる間隔を計算する
:center.l: 中心軸を持つ字形を検出し、中心線のの座標を計算する
:limit.l: 「並列するストロークがぶつからない」という制約条件を表す連立不等式を解く
:limitrule.l:  その制約条件を deflimit というマクロの記述形式で書き並べたもの
:region.l: (他のいくつかのファイルに分割して移動した方がいいと思う)

(3) アウトライン組み立て
:skel2list.l: スケルトンを肉付けしてアウトライン定義に置き換える。apply.l から分離した。
:outline.l: 重なり合うアウトラインを連結する
:mincho.l: 明朝体の肉付け定義
:gothic.l: ゴシック体の肉付け定義
:maru.l: 丸ゴシック体の肉付け定義

:interpol.l: 補間によるアウトライン生成手法の試験的実装。新しく書き起こした。
:mincho2.l: 補間に基づいた明朝体の ten の定義。新しく書き起こした。

(4) 出力
:out2ps.l: Type1 フォントや、それを埋め込んだ PS ファイルを書き出す。もとからあった出力ルーチン。
:type1.l: PostScript Type1 フォントのデータ構造を出力するためのサブルーチン群。
:out2sfd.l: FontForge の SFD (Spline Font Database) ファイルを書き出す。現在こちらを使用。
:out2svg.l: スケルトンまたは肉付けしたアウトラインを書き出す。1 文字単位のデバッグ用。

(5) その他重要でないファイル
:compile.l: コンパイル。
:load.l: ロード。

:sym.l: outline というストローク (和田研フォントの記号定義に使っていた) を出力する。
:hiranew.l: ストロークと同じようにして定義された平仮名の肉付けを行う。

!! エントリポイント

out-to-{ps,sfd}-all の中に、概略以下のような処理のパイプラインがあります。

 (makeoutline (skeleton2list (normkanji (rm-limit (applykanji kanji tag))) tag))

とくに以下の3つの関数が重要です。

:applykanji: 文字名 → スケルトン
:skeleton2list: スケルトン → アウトライン
:makeoutline: アウトライン → 重複除去

!! データ構造

! オリジナルの和田研フォントキットとの違い

* 平仮名・記号の編集機能はちゃんと移植されていない。
* スケルトンエディタが移植されていない (ためしに動かしてみたらすごく遅かった)
* 浮動小数点数のデフォルトが単精度

! 助力求む

* SBCL への移植。
* 警告を無くすなどのソースの整理
* アウトラインの結合ルーチンのバグ修正や、演算誤差に対するロバストネスの向上。