KANOU Hiroki
kanou****@khdd*****
2005年 5月 21日 (土) 11:16:40 JST
狩野です。 先ほどの続きで、処理の前半部における問題点をお送りします。 後半部の問題点については、現在書いている途中ですのでしばらく お待ちください。 1. 複数の部品を組み合わせてバランスの良いスケルトンを作る段階 まだソースを完全に理解していないので、問題点を十分把握していません。 組み合わせ時の部品の変形・配置方法については、論文を読んだだけで 指摘可能な問題点 (多くは、単純化のための意図的な割り切りですが) がいくつかありますが、組合せ処理の方法を問題にする以前に、組合せ 時に与える大きさのパラメータがうまく計算できていないために文字 バランスが悪い文字がたくさんあるのを直さないとならないのが現状です。 つまり、美しくない文字の多くは、部品の大きさの相対比の計算がうまく いっていないことが原因です。 これについては時間をかけてソースを読んで、系統的に大きさを過大/過小 評価している部品をピックアップし、内部の定数をチューニングしたり 見逃している評価方法を導入したりすれば改善できるでしょう。 短期的には、スケルトンエディタで手動調整してしまう方が早いです。 今度の CodeFest では改造するのにちょっと時間が足りないでしょう。 2. スケルトンを肉付けに合うように変形などの後処理をする段階 試してみて分かったのですが、どのように骨組みを作ると美しいアウトライン フォントが得られるかは、明朝・ゴシックなどの書体ごとに異なる肉付け アルゴリズムや、文字のウェイト(太さ) に依存します。 2.1. 明示的な後処理 (rm-geta) 書体ごとに字形を変化させる処理は、現在のところ角/丸ゴシック体に rm-geta という処理を施しているだけです (gothic.l で定義されています)。 (defprimitive によって特定の書体専用のスケルトンを作り分けておく こともできますが、後処理とは次元の異なる話です)。「明示的に」と いうのは、deftypehook で登録した後処理関数 (gothic-prim, maru-prim) の 中から呼ばれているという意味です。 「下駄ばき」とは書体設計の用語で、「山」の字の横画の位置よりも、左右の 縦画の端点が下に延びる処理を言いますが、その飛び出した下駄ばきの部分を 取り除いてしまう処理が rm-geta です。 丸ゴシックでは無条件にこれを行っていいのですが、一般的な角ゴシックの デザインでは、通常は下駄ばきを残しておき、やむを得ない時だけ削るのが 一般的です。端的に言えば、高さ方向に余裕が無い時に削ります。それも、 文字の一番下端よりも、中間にあるものを優先的に省略していきます。例えば 「暑」なら、上の「日」だけ処理し、下の「日」は下駄ばきを残すといった 具合です。 現在は、下駄ばき部分の長さが仮想ボディの 30/400 を超えた場合に削除 しています。角ゴシックも丸ゴシックも同じ閾値を用いている問題、文字の 下端にあるか中間にあるかを区別していないという問題の他に、下駄ばき 部分の長さに若干の差がある場合に、片方だけが除去されてもう片方が 残ってしまうということがよく起こります。 顕著に左右で下駄ばきの長さを変えたい場合 (日へん、山へんとか) を除いて、 これはあまり嬉しくないものです。 ここまではアルゴリズムは難しくないのですが、ほんとうは、下駄ばきを 取り除いたことによって縦方向に余裕ができた空間の一部を削って、 それをバランスよく上下の隙間に配分する必要があります。これには、 なんらかの調整ヒューリスティックか、バランスの再計算 (下駄ばきを除去 したバージョンの部品を使う) を行う必要があります。 どちらの方式でやるにしても、影響範囲を適切に選択するためには、各部品の 組合せによる文字定義をプリミティブ定義形式の文字定義に展開した後も、 各エレメントが最初の定義では元々どのプリミティブに含まれていたかの 情報を保持していなければなりません。 また、下駄ばきを取り除くだけでなく、下駄ばきを残すと決めたのであれば、 肉付け処理をした後でも潰れないように、スケルトンの段階での長さは、 横画の幅 (単純には gothicwidth) よりも大きくしなければなりません。 縦画の下端を下に移動するなり、横画を上に移動するなりする必要が 生じてきます。横画を上に移動した場合、その上にある空間が小さくなり ますので、1 本だけ移動するよりも、「縦画を延ばして、はみ出した部分を 元の縦画と重ね合わせるようなアフィン変換を部分字形に施す」という 方式を用いるのがいいでしょう。 2.2 暗黙の後処理 (normkanji) 組合せ計算の後始末として、デザイナーの知らない所で行われる後処理が あります。それが normkanji という物で、各部品にアフィン変換を適用 して組合せを求めた後で、それが枠の中央に収まるようなサイズにサイズを 変更する処理です。(FontForge+CLWFK の文字編集画面で、「表示(V)」→ 「漢字サイズを規格化」を選択してチェックをいれておいたときに、 肉付けがスケルトンの中心と一致しなくなるのは、肉付けの前にサイズ 変更を行っているからです。) この処理の明らかな問題点は、肉付けされる線の太さを意識していないこと です。明朝体の場合、エレメント kokoro を文字の右端に持つ文字などで、 文字の端が仮想ボディを超えているのがよく見られます。 また、字面 (文字全体が収まるべき空間の大きさのこと。具体的には、 normkanji の中で呼び出している region2region の第 2 引数。現在は '(15 15 385 385) に固定)も、文字の複雑さ (現在の組合せアルゴリズム の場合、xunit と yunit に相当) と、文字の外側の線の向き (囗のように 平行か、十のように垂直か) を考慮して可変にするべきです。(さらに、 肉付けされて太ることを考慮した分だけ小さくしなければなりません) ここの調整の加減も、書体の「ふところ」の大きさをデザイナーが設定 するための手段の一つとなるでしょう。 また、文字のバウンディングボックスを計算するのに xlimit, ylimit を 使用していますが、この値は組合せアルゴリズムの不備を補うために 手動で設定することができるので、いったん値をクリアして再計算 しないと、はみ出さないかどうかを確認することができません。(新たに 計算した「真の」xlimit, ylimit は、字面を縮めるためには使えますが、 膨らませるために使うのは無理だと思います。) 最後に言うと、アフィン変換で文字全体を均等に変形させるのではなく、 はみ出した所だけを内側に移動させる処理をするほうが好都合です。 とくに、画数の多い文字では空間の埋め方が均等になるような方向で 調整する必要があるでしょう。 2.3 追加したい処理 (set-stroke-width) エレメントごとに太さを設定する処理および、それに合わせて再度カウンター スペースが均一になるようにエレメントの位置を調整する処理を追加する ことを考えています。 これについては、エレメント間の距離の計算などで使い回せる処理がたくさん あるとは思いますが、とりあえず必要な処理を別個に書き起こすつもりです。 簡単な処理を書き始めています。 狩野 宏樹 <kanou****@khdd*****>