FontForge の基本的なスプラインデータ構造

## データ型

ここでは、2 つの異なるタイプのフォントの説明を行います。1 つは SplineFont (これは本質的には PostScript フォントです) で、もう 1 つは BDFFont (ビットマップフォントで、本質的には BDF ファイルです) です。2 つのデータ構造には多少の類似性があります。それぞれは基本的に文字の配列 (中に空隙を含むことができます) です。各フォントは、フォント名、文字セット (符号化方式) などの情報も含んでいます。

SplineFont は、多数の SplineChars からなり、個々の SplineChar は 4 つのレイヤを含みます。

- 前面レイヤ。最終結果のフォントに含まれる興味ある事柄をすべて含んでいます。
  - 一連のパス (SplineSet または SplinePointList と呼ばれます——同じデータ構造に 2 つの異なる名前をつけてしまって申し訳ありません)
  - 一連の、他の文字への参照 (RefChar と呼ばれます)。
  - 幅
  - アンドゥ情報
- 背面レイヤ (文字の画像をトレースすることができるような形で使われます) には、以下の情報を含むことができます:
  - 一連の SplineSet
  - 一連の イメージ
  - アンドゥ情報
- グリッドレイヤ。これはフォント内のすべての文字間で共有され、ここにはキャップハイト、x ハイト などを示す線を配置することができます。実際にはここに何を置いても構いませんが、明らかに有用な物が存在します。これはすべての文字から見ることができます。ここには以下の物が含まれます:
  - 一連の SplineSet
  - アンドゥ情報
- ヒントレイヤ。このフォーマットは他のどれとも全然違うもので、水平ヒントと垂直ヒントからなります。これらは単に開始位置と幅の組合せ (ステムを表します。幅は負の値をとることもできます) にすぎません。
  - 一連のヒント。ヒントを編集するには、ヒントメニューにある特別なツールが必要です。
  - !!!! ヒント操作を取り消す方法はありません !!!!

各 SplineChar には名前ならびに、Unicode の符号位置とローカルエンコーディングがつけられています (例えば‘A’は通常 Unicode 符号位置とローカルエンコーディングの両方で 0x0041 という値をもつでしょう)。

各 SplineSet は、開始点・終了点および、それに接続しているスプラインすべてからなります。開始点と終了点は同じ値を取ることができ、これは閉じたパスか、点が 1 個しか存在しない縮退したパスのどちらかであることを示します。

各 SplinePoint は、その点の x, y 座標と、それに付随する 2 個の制御点の位置を含みます。制御点は母点と重なり合うこともできます。SplinePoints は、前側 (previous) の Spline と後ろ側 (next) の Splineの 2 本を含むことができます。各 Spline は 2 個の SplinePoint (始点と終点) へのポインタを含みます。それに加えて、その 2 個の点によって表される Bézier 曲線のパラメータ (x = a*t^3+b*t^2+c*t+d, y=同) もそこに含まれます。ある Spline が直線となるのは、そのスプラインに対して有効な 2 個の制御点が、両端の SplinePoints と重なるときです。

1 個の BDFFont は多数の BDFChar からなります。各 BDFChar は以下の物を含みます:

- ビットマップ
- あるいは可動選択範囲
- 名前と符号位置
- アンドゥ情報
- その文字に伴う SplineChar へのポインタ

>     /* Copyright (C) 2000-2003 by George Williams */
>     /*
>      * Redistribution and use in source and binary forms, with or without
>      * modification, are permitted provided that the following conditions are met:

>      * Redistributions of source code must retain the above copyright notice, this
>      * list of conditions and the following disclaimer.

>      * Redistributions in binary form must reproduce the above copyright notice,
>      * this list of conditions and the following disclaimer in the documentation
>      * and/or other materials provided with the distribution.

>      * The name of the author may not be used to endorse or promote products
>      * derived from this software without specific prior written permission.

>      * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
>      * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
>      * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
>      * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>      * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
>      * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
>      * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
>      * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
>      * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
>      * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>      */
>     #ifndef _SPLINEFONT_H
>     #define _SPLINEFONT_H

>     #include "basics.h"
>     #include "charset.h"

>     enum linejoin {
>         lj_miter,		/* 交差するまで線を延長 */
>         lj_round,		/* 交点を中心に線幅と同じ半径の円を描く */
>         lj_bevel		/* 前後のパスの端点間に直線を引く */
>     };
>     enum linecap {
>         lc_butt,		/* lj_bevel に同じ。両端点間を直線でつなぐ */
>         lc_round,		/* 半円 */
>         lc_square		/* 線を半径と同じ長さだけ延長してから端をつなぐ */
>     };

>     typedef struct strokeinfo {
>         double radius;
>         enum linejoin join;
>         enum linecap cap;
>         unsigned int calligraphic: 1;
>         double penangle;
>         double thickness;			/* 動作しない */
>     } StrokeInfo;

上のデータ構造は、パスを塗りつぶされた図形に変換する ExpandStroke ルーチンで使用します。上記の情報はそれらのルーチンに各種の制御情報を与えます。それらは本質的に、PostScript で利用可能だと考えられているものです。

>     typedef struct ipoint {
>         int x;
>         int y;
>     } IPoint;

整数値をもつ点です。

>     typedef struct basepoint {
>         double x;
>         double y;
>     } BasePoint;

倍精度浮動小数の座標値をもつ点です。SplinePoint およびその制御点の位置情報を与えます。

>     typedef struct tpoint {
>         double x;
>         double y;
>         double t;
>     } TPoint;

浮動小数座標の点に“t”値を加えたものです。スプライン上の位置を表します。(開始点自身は t=0 で、終点は t=1 となり、中間点はその中間の値をとります)。新しいスプラインを近似しようとするときに使用します。

>     typedef struct dbounds {
>         double minx, maxx;
>         double miny, maxy;
>     } DBounds;

Spline, SplineChar, RefChar, Image, またはその他すべてのバウンディングボックスを必要とするデータ構造のバウンディングボックスです。

>     typedef struct bdffloat {
>         int16 xmin,xmax,ymin,ymax;
>         int16 bytes_per_line;
>         uint8 *bitmap;
>     } BDFFloat;

BDFChar 内の可動選択範囲です。

>     typedef struct undoes {
>         struct undoes *next;
>         enum undotype { ut_none=0, ut_state, ut_tstate, ut_width,
>     	    ut_bitmap, ut_bitmapsel, ut_composite, ut_multiple } undotype;
>         union {
>     	struct {
>     	    int16 width;
>     	    int16 lbearingchange;
>     	    struct splinepointlist *splines;
>     	    struct refchar *refs;
>     	    struct imagelist *images;
>     	} state;
>     	int width;
>     	struct {
>     	    /*int16 width;*/	/* 線幅はPostScriptが制御すべきもの */
>     	    int16 xmin,xmax,ymin,ymax;
>     	    int16 bytes_per_line;
>     	    uint8 *bitmap;
>     	    BDFFloat *selection;
>     	    int pixelsize;
>     	} bmpstate;
>     	struct {		/* コピーはアウトライン状態と1組のビットマップ状態を含む */
>     	    struct undoes *state;
>     	    struct undoes *bitmaps;
>     	} composite;
>     	struct {
>     	    struct undoes *mult; /* コピーはいくつかのサブコピー(組合せ、または状態や幅など…)を含む */
>     	} multiple;
>         uint8 *bitmap;
>         } u;
>     } Undoes;

アンドゥ処理用のデータ構造です。SplineChar と BDFChar のどちらでも使用します。クリップボードを保持するためにも使用します (申し訳ありません。私は本物の X クリップボードを使用しているわけではないのです)。各文字レイヤにはいくつかのアンドゥ (およそ 10 個まで。設定変更可能です) を設定できるので、数段階の操作を戻すことができ、next フィールドによって連絡しています (もちろん、リドゥ操作も同様に扱われます)。

アンドゥはいくつかの型に分けられ、ut_none が使用されるのはクリップボードにおいて、そこがもともと空だったときにのみ使用されます。

ut_state は SplineChars によって使用され、その文字の 1 レイヤの現在の状態のダンプを含みます。現在の方式には大幅な最適化の余地があることは明らかですが、簡単に扱えるのが利点です。ut_tstate は ut_state と同じデータ構造をもち、これは座標変換のときに使用されますが、それは、現在変換された物と同時にオリジナルを表示するかどうかを表す単なるフラグにすぎません。

ut_state は SplineChar またはその一部をコピーするときにクリップボードによって使用されます。

ut_width は、幅 (だけ) を変更するときに使用されます。

ut_bitmap は BDFChars によって使用されるデータ構造で、ビットマップの現在の状態のダンプです。これもまた、最適化の余地がありますが現在は簡単な構造です。

ut_bitmapsel は BDFChar のコピーを行うときに用いられます。範囲選択を行っているとき、それ (のみ) は 可動選択範囲 に変換されて、bmpstate 構造体の selection フィールドにコピーされます。 範囲選択を行っていない場合、ビットマップ全体が可動選択範囲に変換され、selection フィールドにコピーされます。

ut_composite はフォントビューからコピーを行うとき、1 文字にスプラインとビットマップとが両方含まれているときに用いられます。

ut_mult は、フォントビューにおいて複数文字のコピーを行うときに使用されます。

>     typedef struct bdfchar {
>         struct splinechar *sc;
>         int16 xmin,xmax,ymin,ymax;
>         int16 width;
>         int16 bytes_per_line;
>         uint8 *bitmap;
>         int enc;
>         struct bitmapview *views;
>         Undoes *undoes;
>         Undoes *redoes;
>         unsigned int changed: 1;
>         unsigned int byte_data: 1;		/* アンチエイリアス文字の場合,各項目は黒白のビット値ではなくグレイスケールのバイト値 */
>         BDFFloat *selection;
>     } BDFChar;

基本的なビットマップ文字の構造体です。ビットマップの作成時に用いられる SplineChar へのリンクが存在します。次に来るのはビットマップのバウンディングボックス、文字の幅 (もちろんピクセル単位です)、ビットマップ配列の行ごとのバイト数、ビットマップを含む配列へのポインタです。ビットマップは 8 ビットごとに、左端のビットが最上位ビットになる 1 バイトにパックした形式で格納されます。すべての行は新しいバイト境界から始まります。各行には (xmax-xmin+1) ビットが含まれ、その大きさは (xmax-xmin+8) / 8 バイトになります。ビット値 1 はそのビットを塗りつぶすことを表し、0 はそのビットが透明であることを表します。その次に来るのが、現在のフォントにおける符号位置の値ですす。このビットマップを参照するすべての BitmapView 構造体のリンクトリストです (ですから、このビットマップへの任意の変更はすべてのビューで再描画を引き起こします)。一連のアンドゥとリドゥです。最後にディスクに保存を行ってから何か変更を行ったかを示すフラグです。

上記の説明は、ビットマップについてのものでました。ここにはバイトマップも格納可能です。データ構造はまったく同じですが、各ピクセルがビットではなくバイトで表される点が異なります。現在のところこれは FontView におけるアンチエイリアス表示にのみ用いられていますが、将来はこれを用いてさらに他の事を行えるようにするつもりです (訳註:現在グレイマップ編集はサポートされています)。 そのために、BDFFont には clut フィールド (これはすべての文字において同じ値です) が存在しますが、基本的には 0=>透明、(2^n-1) =>完全に塗りつぶし を意味し、その他の値は中間の灰色の濃淡を表します。現在のところ私のアンチエイリアスフォントは 0〜15 の値を使用していますが、プログラム上は必要なら 0〜255 を扱う事ができます (私の目には 0〜15 で十分美しく見えます)。

BDFChar の最後にあるのは、(省略可能な) 可動選択範囲です。ユーザが範囲選択を行っている場合か、ペーストまたはそれに類似した行為を行った場合にのみ存在します。

>     typedef struct bdffont {
>         struct splinefont *sf;
>         int charcnt;
>         BDFChar **chars;		/* charcnt 個の要素からなる配列 */
>         BDFChar **temp;		/* ReencodeFont ルーチンで使用する */
>         int pixelsize;
>         int ascent, descent;
>         enum charset encoding_name;
>         struct bdffont *next;
>         struct clut *clut;		/* アンチエイリアスフォントのみ */
>     } BDFFont;

基本的なビットマップフォントです。それと結びつけられている SplineFont への参照があります。その後にはサイズと、BDFChars の配列があります (そのエンコーディングでは文字を定義するデータが存在しない場合、配列内に値が NULL の項目が置かれているという可能性があることに注意してください)。その後にあるのは、フォントの符号化方式を変換する一連のルーチンが使用する一時的な配列があります。em 正方形のピクセルサイズです。(ピクセル単位の) 高さと深さです。この合計は em 正方形と等しくなくてはなりません。SplineFont 内の値と一致する文字セットです。この SplineFont と対応づけられた次のビットマップフォントへのポインタです。

バイトマップフォントを扱っている場合、その後に clut が来るでしょう。これには配列内の各要素のビット数と、配列そのものが含まれます。現在のところビット数は常に 16 ですが、これは変更されるでしょう。

>     enum pointtype { pt_curve, pt_corner, pt_tangent };
>     typedef struct splinepoint {
>         BasePoint me;
>         BasePoint nextcp;		/* 制御点 */
>         BasePoint prevcp;		/* 制御点 */
>         unsigned int nonextcp:1;
>         unsigned int noprevcp:1;
>         unsigned int nextcpdef:1;
>         unsigned int prevcpdef:1;
>         unsigned int selected:1;	/* UI 用 */
>         unsigned int pointtype:2;
>         unsigned int isintersection: 1;
>         uint16 flex;		/* これは,べとべとしたflexの出力を通り抜けるために必要なflexセリフである */
>         struct spline *next;
>         struct spline *prev;
>     } SplinePoint;

SplinePoint は、“me”で指定された位置に置かれています。次の Spline に付随する制御点は nextfp に置かれ、前の Spline に付随する制御点は prevcp に置かれています。それに続き、simplify 処理がテストする 2 個のフラグがあります。nextcp が縮退している (すなわち、me と同じ場所にある) 場合 nonextcp がセットされます。prevcp もそれと同様です。ユーザが制御点の位置を操作していない場合、それらはデフォルト値をもっており、ユーザが点を移動したときには FontForge は制御点の位置を適切に設定しますが、それがデフォルト値と異なるときには FontForge はそれらを単純にオフセットするだけです。

点が選択されているとき、selected ビットがセットされます。

各点は曲線上の点 (pt_curve)、角の点 (pt_corner) および曲線の開始点 (pt_tangent) のいずれかに分類されます。

isintersection ビットは SplineOverlap ルーチンが内部的に使用します。flex 値は flex ヒントのために使用します。Type 1 フォントから読み込まれ、その後は無視されます。いずれはこの情報を使うようにするつもりです。

最後に、この点に接続する 2 本の Spline に対するポインタがあります。

>     typedef struct linelist {
>         IPoint here;
>         struct linelist *next;
>     } LineList;

>     typedef struct linearapprox {
>         double scale;
>         unsigned int oneline: 1;
>         unsigned int onepoint: 1;
>         struct linelist *lines;
>         struct linearapprox *next;
>     } LinearApprox;

これらは Spline を描画するのに用いられる線です。これらはキャッシュされるので、毎回再生成する必要はありません。これらは異なる拡大率の線ごとに (細部の表示量が異なるため) 別々のセットが用意されます。

>     typedef struct spline1d {
>         double a, b, c, d;
>     } Spline1D;

>     typedef struct spline {
>         unsigned int islinear: 1;
>         unsigned int isticked: 1;
>         unsigned int isneeded: 1;
>         unsigned int isunneeded: 1;
>         unsigned int ishorvert: 1;
>         SplinePoint *from, *to;
>         Spline1D splines[2];		/* splines[0]は x 軸のスプライン関数, spline[1]は y 軸 */
>         struct linearapprox *approx;
>         /* 可能な最適化:
>     	バウンディングボックスを予め計算しておく
>     	変曲点を予め計算しておく
>         */
>     } Spline;

Spline は、SplinePoint と SplinePoint の間をつなぎます。Spline の両制御点が縮退している時は、その Spline は直線です (実際には、Spline が直線となるのは別のいくつかの場合があります。場合によってはそれらは検出されて正準形に変換されますが、場合によっては正規化されません)。残りのビットは、Spline を各種の関数で処理する時に用いられます。ほとんどは SplineOverlap ルーチンで用いられるものですが、いくつかは他の場所でも用いられます。

Spline1D 構造体は、x および y 座標のそれぞれに対する等式を与えます (splines[0] は x 軸、spline[1] は y 軸にあたります)。

>     typedef struct splinepointlist {
>         SplinePoint *first, *last;
>         struct splinepointlist *next;
>     } SplinePointList, SplineSet;

SplinePointList (別名 SplineSet) は Spline および SplinePoint の集まりです。各 SplinePoint は 2 本のスプライン (next と prev) に接続します。1 個の SplinePointList は、一つながりのパスを表します。以下の 3 つの場合が存在します。

- `first != last` の場合、開いたパスを表します。この場合 first->prev==NULL かつ last->next==NULL となります。
- `first == last` かつ `first->prev==NULL` の場合、1 個の点からなる縮退したパスを表します。この場合も `last->next==NULL` となります。
- `first == last` かつ `first->prev==NULL` の場合、閉じたパスを表します。これが最も一般的な場合と言えるでしょう。

一般に一連のパスは 1 個の文字を構成し、それらは next フィールドによって連絡しています。

>     typedef struct refchar {
>         int16 adobe_enc, local_enc;
>         int unicode_enc;		/* ペーストのとき用いる */
>         double transform[6];	/* 変換行列 (3×3 行列の上 2 行。省略した行は 0,0,1) */
>         SplinePointList *splines;
>         struct refchar *next;
>         unsigned int checked: 1;
>         unsigned int selected: 1;
>         DBounds bb;
>         struct splinechar *sc;
>     } RefChar;

SplineChar は他の文字への参照を含むことができます。例えば、“Agrave”は“A”と“grave”への参照を含みます。符号位置を表す値には 3 つの異なる種類があり、local_enc は常に最新の状態を保っています。adobe_enc は、Adobe 標準エンコーディングにおける符号位置を表し、Type 1 フォントの seac コマンドで使用されます。この値が -1 であるときにはこの文字が Adobe エンコーディングに含まれていないことを表し、その場合は、Type1 フォントの中でこの文字への参照を行うことはできなくなります (TrueType にはこの制限はありませんが、他の制限があります)。transform[] は、PostScript の標準変換行列です (3 行 2 列)。最初の 2 行が標準的な回転/拡大縮小/反転/傾き…変換を行い、最後の行は平行移動を指定します。(PostScript と TrueType のどちらにも、可能な座標変換の種類に対する制限があります)。splines フィールドは参照された文字を描画するための簡便な方法を提供します。これは、参照された文字のすべてのスプラインに変換行列を適用したものです。参照された文字は複数存在する可能性があり、それらは next フィールドによりリンクしています。checked フィールドは、ループが存在しないか (例えば、自分自身を参照している文字がないか) どうかを確めるために使用します。selected フィールドは、参照が選択されていることを示します。bb フィールドは座標変換を施したバウンディグボックスを提供します。そして、sc フィールドは、参照している SplineChar を指し示します。

>     typedef struct kernpair {
>         struct splinechar *sc;
>         int off;
>         struct kernpair *next;
>     } KernPair;

文字同士がカーニングする場合は、この構造体がその情報を提供します。各 SplineChar は、その文字に接続する KernPairs のリンクトリストをもっています。そのリストでは、sc フィールドがペアに含まれるもう 1 つの文字を示し、off がそれらの間のオフセットを定義します (またはむしろ、それらの各文字の左右のサイドベアリングから得た差の値の方を信ずべきときは、そのようにするべきです)。next は、次の KernPair を指し示します。

>     typedef struct hints {
>         double base, width;
>         double b1, b2, e1, e2;
>         double ab, ae;
>         unsigned int adjustb: 1;
>         unsigned int adjuste: 1;
>         struct hints *next;
>     } Hints;

重要なフィールドと呼べるのは base, width と next だけです。その他は SplineFill ルーチンで一時的に使用するだけです。Base はステム開始位置 (x 座標または y 座標のどちらか) を指定し、width はステムの幅を表します。width は負の値になることもあります (その場合、ステムの終了位置です)。next はその文字の次のヒントを指し示します。

>     typedef struct imagelist {
>         struct gimage *image;
>         double xoff, yoff;		/* 画像の左上端の,文字空間における位置 */
>         double xscale, yscale;	/* 画像の1ピクセルを文字空間の1単位に変換するための拡大率 */
>         DBounds bb;
>         struct imagelist *next;
>         unsigned int selected: 1;
>     } ImageList;

SplineChars は、背景に画像を配置することができます。この構造体は表示される画像へのポインタと、それをどこへ置くべきか・どのように拡大/縮小 (画像に対する変換はこれ以外にサポートしていません) を表す印を含みます。バウンディングボックスは、座標変換が適用された後の値です。next フィールドは次の画像を指し示し、selected は、この画像が選択されているか否かを表します。

>     typedef struct splinechar {
>         char *name;
>         int enc, unicodeenc;
>         int width;
>         int16 lsidebearing;		/* Type1フォントの読み込み時にのみ使用 */
>         int16 ttf_glyph;		/* TTFフォントの書き出し時にのみ使用 */
>         SplinePointList *splines;
>         Hints *hstem;		/* hstemヒントは垂直オフセットを含み,水平に延びる */
>         Hints *vstem;		/* vstemヒントは水平オフセットを含み,垂直に延びる */
>         RefChar *refs;
>         struct charview *views;	/* この文字を参照するすべての CharView */
>         struct splinefont *parent;
>         unsigned int changed: 1;
>         unsigned int changedsincelasthhinted: 1;
>         unsigned int changedsincelastvhinted: 1;
>         unsigned int manualhints: 1;
>         unsigned int ticked: 1;	/* 参照文字の処理用 */
>         unsigned int changed_since_autosave: 1;
>         unsigned int widthset: 1;	/* 文字"emspace"が消えないために必要 */
>         struct splinecharlist { struct splinechar *sc; struct splinecharlist *next;} *dependents;
>     	    /* dependentsリストは現在の文字を直接参照するすべての文字の */
>     	    /*  リストのリスト */
>         SplinePointList *backgroundsplines;
>         ImageList *backimages;
>         Undoes *undoes[2];
>         Undoes *redoes[2];
>         KernPair *kerns;
>         uint8 *origtype1;		/* オリジナルの (符号位置をもたない) Type1 charstring */
>         int origlen;		/* その長さ. これらはユーザが一度変更を加えると解放される */
>     				/* 文字そのもの. その時まで他の方法で理解不能な */
>     				/* ヒント置換を保存しておく */
>     } SplineChar;

すべての文字には名前があります (時には“.notdef”の場合もありますが、その値はここに格納されています)。現在のフォント内における位置 (エンコーディング)、Unicode のコードポイント (Unicode に存在しないことを表す値 -1 になることがあります) があります。各文字の幅は width に格納されます。その後ろの 2 個のフィールドはフォントを適切なフォーマットで読み込みまたは保存する時にのみ意味があります。lbearing は seac コマンドを扱うために必要で、ttf_glyph は TTF フォントを書き出す時にいろいろな用途で使用します。splines フィールドは、すべての前面パス (SplinePointLists) を与えます。hints は水平ステムと垂直ステムです。この文字が参照している一連の文字、これも前面にあるもののみです。その次に来るのはこの SplineChar を表示しているすべての CharViews のリンクトリストです (この文字が変更されたら、それらすべてが変更を反映して更新する必要があります)。この文字を含む SplineFontへのポインタがあります。以下の一連のビットがあります: changed は、最後にディスクへ保存を行って以降その文字が更新されたことを意味します。changedsincelasthhinted は、水平ヒントの自動ヒントづけを行わなければならないことを意味し、changedsincevhinted は垂直ヒントに対するものです。manualhints は、ユーザがヒントづけを自分で制御する選択をしたことを意味し、ユーザの明示的な指示がなければ自動ヒントを行ってはなりません。ticked は、参照された文字の無限ループを避けるための印づけです。changed_since_autosave は、次回自動セーブデータベースを更新する時、この文字をそこに含める必要があることを示します。widthset は、ユーザが幅を変更したことを意味します。このビットをセットしていない時、幅 em の空白には (文字 em スペースを示すのではなく) 何も含まれていないと考える必要があります。

ある SplineChar が他の文字から参照されている場合、オリジナルを変更した時にはそれを参照しているすべての文字も更新しなければなりません (A を変更したら、Agrave も再表示する必要があります)。

その次の backgroundsplines は、背面レイヤにある SplinePointLists を表し、backimages は背面レイヤにある画像を表します。

undoes[0] には前面のアンドゥを格納し、undoes[1] には背面のアンドゥを格納します。redoes も同様です。

最後の kerns は、この文字に続くすべての特別扱いされる文字のカーニングデータのリストを提供します。例えば“VA”の組合せはカーニングを必要とするでしょう。その場合、“V”を表す SplineChar には、“A”に関するデータをもつ KernPair へのポインタが含まれるはずです。

>     typedef struct splinefont {
>         char *fontname, *fullname, *familyname, *weight;
>         char *copyright;
>         char *filename;
>         char *version;
>         double italicangle, upos, uwidth;
>         int ascent, descent;
>         int charcnt;
>         SplineChar **chars;
>         unsigned int changed: 1;
>         unsigned int changed_since_autosave: 1;
>         unsigned int display_antialias: 1;
>         unsigned int dotlesswarn: 1;		/* フォントに文字 dotless i が含まれていることをユーザに警告済 */
>         /*unsigned int wasbinary: 1;*/
>         struct fontview *fv;
>         enum charset encoding_name;
>         SplinePointList *gridsplines;
>         Undoes *gundoes, *gredoes;
>         BDFFont *bitmaps;
>         char *origname;		/* フォントファイルのファイル名 (つまり,SFDでない場合) */
>         char *autosavename;
>         int display_size;
>     } SplineFont;

最初の 4 個の名前は PostScript のものをそのまま使用しており、copyright, version, italicangle, underlinepos, underlineweight も同様です。ascent と descent は、合計が em 正方形の大きさとなります。通常これは 1000 になりますが、必要なら変更可能です。

charcnt は、chars 配列の大きさを表します。配列の途中に穴 (つまり、NULL 値) があっても構いません。

changed は、ファイルを最後に保存して以降どれかの文字・ビットマップ・メトリック・何らかのデータが変更されたことを示します。changed_since_autosaves は、自動セーブが最後に行われてから何らかの変更があった (そのため、次回自動セーブが行われるとき、このフォントの処理を実際に行う必要がある) ことを意味します

display_antialias は、FontView でビットマップフォントではなく、アンチエイリアス表示のバイトマップフォントを表示していることを意味します。より美しい表示が可能ですが速度は低下します。

dotlesswarn は、ユーザが i または j に基づくアクセントつき文字を作成し、それらの文字の点の無いバージョンがフォント内に含まれていないときに警告を行ったことを意味します (警告を再度行うことはありません。操作は点ありのバージョンに基づいて進められます)。

1 個のフォントに付随する FontView は 1 個しか存在しません (他のデータ構造は複数のビューをもつことができますが、フォントは違います)。

フォントには文字集合とエンコーディングベクタが存在します。

gridsplines は、文字の背景グリッドとして表示されるすべてのスプラインの SplinePointLists を表示します。また、gundoes および gredoes はそれらに関連づけられたアンドゥ/リドゥです。

bitmaps は、この SplineFont のために生成されたすべてのビットマップを含みます。

origname は、このフォントを得るために読み込んだファイルの名前を含んでいます。上の filename はこのフォントに関連づけられた .sfd ファイルの名前を含みますが、origname は任意の PostScript または TrueType のフォント名を含むことが可能です。

autosavename は、ディスクにクラッシュ回復情報を保存するのに用いる名前を表します。

display_size は、フォントを FontView でどのくらいの大きさで表示するかを示します。

## 関数宣言

>     struct fontdict;		/* 次の4個のデータ構造はpsfont.hにある */
>     struct chars;
>     struct findsel;
>     struct charprocs;
>     enum charset;			/* charset.hにある */

>     extern SplineFont *SplineFontFromPSFont(struct fontdict *fd);
>     extern bool SFIsFixedWidth(SplineFont *sf);
>     extern struct chars *SplineFont2Chrs(SplineFont *sf, int round);
>     enum fontformat { ff_pfa, ff_pfb, ff_ptype3, ff_ptype0, ff_ttf, ff_none };
>     extern int WritePSFont(char *fontname,SplineFont *sf,enum fontformat format);
>     extern int WriteTTFFont(char *fontname,SplineFont *sf);
>     int SFReencodeFont(SplineFont *sf,enum charset new_map);

>     extern int DoubleNear(double a,double b);
>     extern int DoubleNearish(double a,double b);

>     extern void LineListFree(LineList *ll);
>     extern void LinearApproxFree(LinearApprox *la);
>     extern void SplineFree(Spline *spline);
>     extern void SplinePointFree(SplinePoint *sp);
>     extern void SplinePointListFree(SplinePointList *spl);
>     extern void SplinePointListsFree(SplinePointList *head);
>     extern void RefCharFree(RefChar *ref);
>     extern void RefCharsFree(RefChar *ref);
>     extern void UndoesFree(Undoes *undo);
>     extern void HintsFree(Hints *h);
>     extern Hints *HintsCopy(Hints *h);
>     extern SplineChar *SplineCharCopy(SplineChar *sc);
>     extern BDFChar *BDFCharCopy(BDFChar *bc);
>     extern void ImageListsFree(ImageList *imgs);
>     extern void SplineCharFree(SplineChar *sc);
>     extern void SplineFontFree(SplineFont *sf);
>     extern void SplineRefigure(Spline *spline);
>     extern Spline *SplineMake(SplinePoint *from, SplinePoint *to);
>     extern LinearApprox *SplineApproximate(Spline *spline, double scale);
>     extern int SplinePointListIsClockwise(SplineSet *spl);
>     extern void SplineSetFindBounds(SplinePointList *spl, DBounds *bounds);
>     extern void SplineCharFindBounds(SplineChar *sc,DBounds *bounds);
>     extern void SplineFontFindBounds(SplineFont *sf,DBounds *bounds);
>     extern void SplinePointCategorize(SplinePoint *sp);
>     extern void SCCategorizePoints(SplineChar *sc);
>     extern SplinePointList *SplinePointListCopy(SplinePointList *base);
>     extern SplinePointList *SplinePointListCopySelected(SplinePointList *base);
>     extern SplinePointList *SplinePointListTransform(SplinePointList *base, double transform[6], int allpoints );
>     extern SplinePointList *SplinePointListShift(SplinePointList *base, double xoff, int allpoints );
>     extern SplinePointList *SplinePointListRemoveSelected(SplinePointList *base);
>     extern void SplinePointListSet(SplinePointList *tobase, SplinePointList *frombase);
>     extern void SplinePointListSelect(SplinePointList *spl,int sel);
>     extern void SCRefToSplines(SplineChar *sc,RefChar *rf);
>     extern void SCReinstanciateRefChar(SplineChar *sc,RefChar *rf);
>     extern void SCReinstanciateRef(SplineChar *sc,SplineChar *rsc);
>     extern void SCRemoveDependent(SplineChar *dependent,RefChar *rf);
>     extern void SCRemoveDependents(SplineChar *dependent);
>     extern RefChar *SCCanonicalRefs(SplineChar *sc, int isps);
>     extern void BCCompressBitmap(BDFChar *bdfc);
>     extern void BCRegularizeBitmap(BDFChar *bdfc);
>     extern void BCPasteInto(BDFChar *bc,BDFChar *rbc,int ixoff,int iyoff, int invert);
>     extern BDFChar *SplineCharRasterize(SplineChar *sc, int pixelsize);
>     extern BDFFont *SplineFontRasterize(SplineFont *sf, int pixelsize);
>     extern BDFChar *SplineCharAntiAlias(SplineChar *sc, int pixelsize,int linear_scale);
>     extern BDFFont *SplineFontAntiAlias(SplineFont *sf, int pixelsize,int linear_scale);
>     extern void BDFCharFree(BDFChar *bdfc);
>     extern void BDFFontFree(BDFFont *bdf);
>     extern void BDFFontDump(char *filename,BDFFont *font, char *encodingname);
>     extern double SplineSolve(Spline1D *sp, double tmin, double tmax, double sought_y, double err);
>     extern void SplineFindInflections(Spline1D *sp, double *_t1, double *_t2 );
>     extern int NearSpline(struct findsel *fs, Spline *spline);
>     extern double SplineNearPoint(Spline *spline, BasePoint *bp, double fudge);
>     extern void SCMakeDependent(SplineChar *dependent,SplineChar *base);
>     extern SplinePoint *SplineBisect(Spline *spline, double t);
>     extern Spline *ApproximateSplineFromPoints(SplinePoint *from, SplinePoint *to,
>     	TPoint *mid, int cnt);
>     extern int SplineIsLinear(Spline *spline);
>     extern int SplineInSplineSet(Spline *spline, SplineSet *spl);
>     extern void SplineCharMerge(SplineSet **head);
>     extern void SplineCharSimplify(SplineSet *head);
>     extern void SplineCharRemoveTiny(SplineSet *head);
>     extern SplineFont *SplineFontNew(void);
>     extern SplineFont *SplineFontBlank(int enc,int charcnt);
>     extern SplineSet *SplineSetReverse(SplineSet *spl);
>     extern SplineSet *SplineSetsExtractOpen(SplineSet **tbase);
>     extern SplineSet *SplineSetsCorrect(SplineSet *base);
>     extern void SPAverageCps(SplinePoint *sp);
>     extern void SplineCharDefaultPrevCP(SplinePoint *base, SplinePoint *prev);
>     extern void SplineCharDefaultNextCP(SplinePoint *base, SplinePoint *next);
>     extern void SplineCharTangentNextCP(SplinePoint *sp);
>     extern void SplineCharTangentPrevCP(SplinePoint *sp);
>     extern int PointListIsSelected(SplinePointList *spl);
>     extern void SplineSetsUntick(SplineSet *spl);
>     extern void SFOrderBitmapList(SplineFont *sf);

>     extern SplineSet *SplineSetStroke(SplineSet *spl,StrokeInfo *si);
>     extern SplineSet *SplineSetRemoveOverlap(SplineSet *base);

>     extern void FindBlues( SplineFont *sf, double blues[14], double otherblues[10]);
>     extern void FindHStems( SplineFont *sf, double snaps[12], double cnt[12]);
>     extern void FindVStems( SplineFont *sf, double snaps[12], double cnt[12]);
>     extern void SplineCharAutoHint( SplineChar *sc);
>     extern void SplineFontAutoHint( SplineFont *sf);
>     extern int AfmSplineFont(FILE *afm, SplineFont *sf,int type0);
>     extern char *EncodingName(int map);

>     extern int SFDWrite(char *filename,SplineFont *sf);
>     extern int SFDWriteBak(SplineFont *sf);
>     extern SplineFont *SFDRead(char *filename);
>     extern SplineFont *SFReadTTF(char *filename);
>     extern SplineFont *LoadSplineFont(char *filename);
>     extern SplineFont *ReadSplineFont(char *filename);	/* 使用不可. 代わりにLoadSFを使うこと */

>     extern SplineChar *SCBuildDummy(SplineChar *dummy,SplineFont *sf,int i);
>     extern SplineChar *SFMakeChar(SplineFont *sf,int i);
>     extern BDFChar *BDFMakeChar(BDFFont *bdf,int i);

>     extern void SCUndoSetLBearingChange(SplineChar *sc,int lb);
>     extern Undoes *SCPreserveState(SplineChar *sc);
>     extern Undoes *SCPreserveWidth(SplineChar *sc);
>     extern Undoes *BCPreserveState(BDFChar *bc);
>     extern void BCDoRedo(BDFChar *bc,struct fontview *fv);
>     extern void BCDoUndo(BDFChar *bc,struct fontview *fv);

>     extern int SFIsCompositBuildable(SplineFont *sf,int unicodeenc);
>     extern void SCBuildComposit(SplineFont *sf, SplineChar *sc, int copybmp,
>     	struct fontview *fv);

>     extern void BDFFontDump(char *filename,BDFFont *font, char *encodingname);
>     extern int getAdobeEnc(char *name);

>     extern SplinePointList *SplinePointListInterpretPS(FILE *ps);
>     extern void PSFontInterpretPS(FILE *ps,struct charprocs *cp);

>     extern int SFFindChar(SplineFont *sf, int unienc, char *name );

>     extern char *getFontForgeDir(char *buffer);
>     extern void DoAutoSaves(void);
>     extern int DoAutoRecovery(void);
>     extern SplineFont *SFRecoverFile(char *autosavename);
>     extern void SFAutoSave(SplineFont *sf);
>     extern void SFClearAutoSave(SplineFont *sf);
>     #endif