Bézier1 スプライン

技術的には、PostScript は 3 次 Bézier スプラインを使用します。各制御点は、対応する端点におけるスプラインの傾きを決定します。TrueType が使用している 2 次 Bézier スプラインでは、2 個の端点の間には 1 個の制御点しかなく、その点が隣接する両方の端点における傾きを決定します。両フォーマットとも直線 (これは線形な Bézier スプラインです) も併用します。

他の次数の Bézier スプラインを作成することも可能です。4 次スプラインでは 3 個の制御点が存在し、5 次スプラインでは 4 個の制御点が、という具合です。そのなかで我々が関心をもっているのは線形, 2 次と 3 次のスプラインです――それらは TrueType と PostScript で使用されています。

The examples at left are cubic splines with two control points, each determining the slope at the nearest end point, while the example at right shows a quadratic spline with one control point used to determine the slopes at both end points. --> 左の例は 2 個の制御点をもつ 3 次スプラインで、それぞれ近い側の端点における傾きを決定しています。一方、右に示した例は 2 次スプラインで、1 個の制御点が両側の端点における傾きを決定しています。

一般的に、P0, P1,... Pn というラベルのついた (n+1) 個の点がある場合、P0 と Pn が端点となり (その他はすべて制御点です)、Bézier スプラインを定義する等式は、 となります。点が 2 個のときは、これは単に 2 個の端点を結ぶ線分となります。点が 3 個のときは TrueType で用いられている 2 次スプラインで、4 個のときは PostScript で用いられている 3 次スプラインです。

3 次 Bézier 曲線はのように表示することができます:

x = ax*t3 + bx*t2 + cx*t +dx
y = ay*t3 + by*t2 + cy*t +dy

ここで
      dx = P0.x dy = P0.y
cx = 3*P1.x-3*P0.x cy = 3*P1.y-3*P0.y
bx = 3*P2.x-6*P1.x+3*P0.x by = 3*P2.y-6*P1.y+3*P0.y
ax = P3.x-3*P2.x+3*P1.x-P0.x ay = P3.y-3*P2.y+3*P1.y-P0.y
です。

また、2 次 Bézier 曲線は以下のようになります:
      dx = P0.x dy = P0.y
cx = 2*P1.x-2*P0.x cy = 2*P1.y-2*P0.y
bx = P2.x-2*P1.x+P0.x by = P2.y-2*P1.y+P0.y

そして直線は以下のとおりです:
      dx = P0.x dy = P0.y
cx = P1.x-P0.x cy = P1.y-P0.y

TrueType を PostScript に変換する方法

直線のフォーマット変換には数学は一切必要ありません.

任意の 2 次スプラインは 3 次の表現をもちます (その場合、3 次の項が 0 となる)。3 次のときの端点は 2 次のときと同じです。

CP0 = QP0
CP3 = QP2

3 次表現での 2 個の制御点は、以下のようになります。

CP1 = QP0 + 2/3 *(QP1-QP0)
CP2 = CP1 + 1/3 *(QP2-QP0)

ですから、TrueType から PostScript への変換は自明です。丸めに伴う微小な誤差はありますが、それはほとんど気づかない程度のものです。

(Anish Mehta から、TrueType ではピクセルの中間に位置する点を指定する (すなわち、x や y の値が 1/2 の端数をもつ) ことができるという指摘を受けました。これも PostScript への変換を行うときに丸め誤差を持ち込む原因となり得ます。しかし解決方法は単純です: フォント野 EM 正方形を 2 倍に拡大すれば、問題はなくなります)。

PostScript を TrueType に変換する方法

ほとんどすべての 3 次スプラインは 2 次スプラインで正確に表現することができません (それどころか、2 次スプラインを連結しても表現できません)。可能な最良の手段は、3 次曲線をある程度の許容誤差の範囲で近似することです。ここにそれを行う方法を示します:

3 次スプラインが与えられたとしましょう。スプライン上の 2 個の点に注目しましょう。その場合、それらの 2 点における傾きが求める値であるスプラインは、それら 2 個の点の間に 1 本しか引くことができません。(その 2 次曲線は、その区間の端点を端点とし、その制御点は、3 次曲線のその区間の始点と終点における接線の交点です)。

Start from the end of the spline and every so often (ie. within the margin of error) check to see if the one permissible quadratic approximation actually matches the cubic closely enough . スプライン上の片方の端点から始め、時折 (すなわち、許容誤差の範囲内で) ある許される 2 次近似が本当に、3 次曲線に十分密接に合致しているかをチェックします。

もしこの近似がうまく行ったら、結果の一部としてそれらを保存し、開始点を 3 次スプラインに沿って、私たちがいま作成した 2 次曲線の端点に向かって延長します。

(指定された点において 2 次近似が存在するとは限らない (例えば交点がたまたま交点だった場合など) ため、何らかの微妙な複雑さが含まれている場合があります。しかしこれらは簡単に解消することができます)。

もちろん、場合によっては、与えられた "3 次曲線" が実際には 2 次曲線であることもあります (3 次の項が 0 である場合)。その最もありふれた原因は、そのフォントの元データが TrueType である場合です。この場合、2 次曲線の制御点は以下のようになります:

QP1 = CP0 + 3/2 * (CP1 - CP0)

私がネット上で読んだ他の情報源では、3 次スプラインに変曲点 (これは 2 次曲線には存在しません) があるかどうかをチェックし、そこで強制的に分割することを提案しています。私の目には、この方法は実際にはより悪い結果をもたらすように見えます。より多くの点が必要になり、近似結果は、変曲点を無視したときほど元の線に近くないように見えます。そういうわけで、私はこれを無視することにしました。

OpenType, もう一つの解決法

Adobe と Microsoft は TrueType フォントと PostScript フォントのどちらを格納することも可能なフォントフォーマットを作成することに決定しました。これは OpenType と呼ばれています。これは本質的には TrueType の拡張です。すべての TrueType フォントは正しい OpenType フォントですが、 OpenType フォントは PostScript を含むこともできます。OpenType をサポートするシステムではどれも、PostScript と TrueType の間の変換を必要としないでしょう。

参照

1 Bézier スプラインは Pierre Bézier (1910-1999) によって開発されました。

-- -- 目次 -- --