文字列座標系

OpenType の座標

[1] 文字文字列 (を表すグリフグリフの列) の座標空間は複雑です。

基線

基線

OpenType の座標

[4] フォント単位

[70] kern

[42] hdmx グリフadvance width を各フォントサイズにおける画素単位の整数に変換した値を格納しています。 >>41

[71] LTSH - Linear Threshold (OpenType 1.9) - Typography | Microsoft Docs, PeterCon, https://docs.microsoft.com/ja-jp/typography/opentype/spec/ltsh

[73] OS/2, post, sbix, STAT


[53] head は、 xMin, yMin, xMax, yMax の4つの int16 値を持ちます。 >>52

[45] glyf TrueType outline グリフデータは、 xMin, yMin, xMax, yMax の4つの int16 値を持ちます。 >>44

[54] グリフ (がい) (せつ) (ばこ) (bounding box) は、 グリフのすべての制御点を含む最小の矩形です。 >>52

[55] head のこの4値は、 フォント中のすべてのグリフを含む外接箱を表します。 contour なきグリフは無視します。 >>52

[47] TrueType outline グリフのこの4値はグリフの点 (on-curve pointoff-curve point も)座標データから直接得ます。 rasterrizer が計算した phantom point は算入しません。 >>44

[46] TrueType outline グリフ (がい) (せつ) () (けい) (bounding rectangle) は、 左下 (xMin, yMin)、 右上 (xMax, yMax) の方形です。 >>44

[48] 制御点により定義される外接箱outlineを含むことが保証されます。 outline に接するとは限りません。 >>44
[56] 外接箱外接矩形の2種類の語が使われていますが、表記揺れで同じ概念と思われます。

[58] CFF (CFF 1) outlineadvance width を持ちます。 PostScript processor はこれを使います。 OpenType はこれを使いません。 >>43

[59] CFF2 outlineadvance width を持ちません。 >>43

[60] CFF CFF2グリフデータには xMin = lsb, xMax を明示的には含みません。 side bearingCharString データに暗示的に含まれていて、 CFF / CFF2 rasterizer から得られます。 >>43

[51] variable font の場合は記述された外接箱が得られたグリフのものを表すとは限りません >>44, >>52。 必要なら得られたグリフ制御点等から計算する必要があります。 side bearingphantom point を使って、あるいは HVAR のデータから計算できます >>43CFF2 outlinevariable fontleft side bearingadvance widthnon-default instance では hmtxHVAR を総合して得るべきです (should) >>43

[49] xMinlsb と等しくなるようにグリフ座標を取ると scaler には都合がいいです。 >>44 すべてのフォントがそうである場合には head のその旨のフラグを設定できます >>52TrueType outline を持つ variable font ではこのフラグを設定しなければなりません (must) し、 グリフをそのように設計しなければなりません (must) >>52

[61] フォント生成ツールは、 layout engine によっては hmtxleft side bearing を使うかも知れませんから、 left side bearingCFF / CFF2 outlineCharString が暗示する xMin が一致するようにするべきです (should) >>43

[57] グリフleft side bearingadvance widthhmtx に格納できます。 >>43

[50] right side bearingleft side bearingadvance width から求められます。 bottom side bearingtop side bearingadvance height から求められます。 >>44

[62] TrueType outlineグリフxMinxMax は、 glyf グリフデータによります。 >>43

[63] TrueType outlineグリフadvance width (aw) と left side bearing (lsb) は、 TrueType rasterizer の計算するグリフphantom point から得られます。 hmtx からも得られます。 >>43

[64] right side bearing (rsb) は、次の式によります。 >>43

rsb = aw - (lsb + xMax - xMin)

[65] pp1, pp2lsb, rsb を制御する TrueType phantom point とするとき、 その X軸方向の初期位置は、次の式によります。 >>43

pp1 = xMin - lsb

pp2 = pp1 + aw

[66] グリフcontour を持たないとき、 xMin, xMax は定義されません。 hmtxleft side bearing0 とするべきです (should) >>43

縦書き用座標値

[77] 横書き用の座標値を格納する hhea, hmtx に対して、 縦書き用の vheavmtx があります。

[79] 縦書き用のフォントでは vhea を使うことになっていますが >>78WindowsChrome, Firefox とも vhea がないからといって縦書き表示に特別支障となることは無さそうです。

[80] vhea には vmtx 用のグリフ数の欄がありますが、 Chrome, Firefox とも vmtx が存在しなくてもエラーにはならないようです。 (一方 hmtx がないとエラーになります。)

グリフ位置決定

[5] TrueType では、 グリフの位置は基準となる pen point (pen position) からの配置 (placement) 前進 (advance) の2値で決まります。 すなわち、 現在の pen point からテキスト (text) の線に対して、 配置量だけ移動したところにグリフを置きます。 そして次のグリフpen point前進量だけ移動したところに置きます。 >>3

[8] TrueType における配置前進は、 横書きではX軸, 縦書きではY軸の1次元値です。 >>3

[10] TrueType では、 kern を使って2つのグリフの間の空間の増減を指定できます。 >>3 前のグリフ前進量に kern による調整量を足し合わせることで適切なスペースに調整できます。

[11] OpenType では、 GPOS を使って配置前進X軸, Y軸の2次元で指定できます。 値はフォント単位によります。 >>3

[12] GPOS では更に装置依存の調整もできます。 >>3

[17] GPOS による位置調整は、 lookup によって一致条件と一致した場合の挙動が記述されますが lookup 、 同じグリフに対する複数の lookup による指定は、蓄積されていきます。 >>3

[18] 機能1により X軸方向に3前進し、 機能2により Y軸方向に6前進し、 機能3により X軸方向に-2前進すると、 X軸方向には1前進し、 Y軸方向には6前進することになります。

[75] GPOS では kern 機能カーニング指定ができますが、 その他の機能でも同様の位置調整を行えます。

[68] JstfMax lookup では justification において加除するX軸Y軸配置前進の最大値を指定できます。 実装はこれを使って 0 以上指定された値以下の調整を行えます。 >>67

[76] 結合文字関係固有の挙動は、結合文字のレンダリングの項を参照。

[74] GPOSのCursive Attachment Positioningについて - にせねこメモ, https://nixeneko.hatenablog.com/entry/2017/01/14/200258

curs

添付点

[6] OpenType では、 GPOS を使ってグリフ添付点 (glyph attachment point) によるグリフ間の位置調整も可能です。 >>3

[16] 添付点基底グリフダイアクリティカルマークの位置調整のために、 あるいは続け字 (cursive) における前後のグリフの位置調整のために使えます。 >>3

[15] OpenType ではグリフは0個以上の添付点 (attachment point) を持つことが出来ます。 >>3 それぞれ上のダイアクリティカルマーク位置、 下のダイアクリティカルマーク位置といったように使います。

[21] GPOS lookupType 3 (cursive attachment positioning) では、 グリフentry point anchorexit point anchor を設定できます。 両 point anchor は、 位置 (X軸座標と Y軸座標の組) を指定します。 >>3

[24] 2つのグリフを並べるとき、1つ目のグリフexit point から 2つ目のグリフentry point へと続くようにします。

[23] line-layout direction の調整については、 論理順で1つ目のグリフ前進を調整します。 結果的に2つ目のグリフが移動されて anchor 位置を揃えます。 >>3

[25] cross-stream direction の調整については、 一方のグリフ配置を調整して他方のグリフと anchor 位置を揃えます。 RIGHT_TO_LEFT0 の場合、 2つ目のグリフを調整します。 RIGHT_TO_LEFT1 の場合、 1つ目のグリフを調整します。 >>3

[26] entry point / exit point の指定されたグリフが続く場合、 そのグリフ列全体の配置が連続的に影響されていきます。 RIGHT_TO_LEFT0 なら、 最初のグリフ基線基準で配置され、 以後どんどんずれていく形になります。 RIGHT_TO_LEFT1 なら、 最後のグリフ基線基準で配置され、 それに向けてどんどんずれが解消してく形になります。

[27] RIGHT_TO_LEFT フラグlookuplookupFlag ビット欄の第0ビットです。 >>28 lookup の条件を記述する他のフラグと違って RIGHT_TO_LEFT フラグlookupType 3グリフ位置調整にだけ作用します。

[29] 名前に反して右横書きにはあまり関係ありません。 が巷のフォントでは lookupType と無関係に右横書き向けのグリフが収容された lookup にこのフラグが設定されていたりするようです。 (lookupType 3 以外では指定されていてもいなくても動作は変わりません。)
[30] entry pointexit point は、書字方向によって違う位置にしなければならないのが普通です。 1つの lookup で同じグリフに対して複数の書字方向用の anchor は記述できませんから、 書字方向ごとの lookup を用意しなければなりません。 (続け字で同じグリフで違う書字方向にそのまま適用できる例の方が稀かもしれませんが。)

[31] GPOS lookupType 4 (Mark-to-Base Attachment Positioning, MarkBasePos) は、 基底グリフマークグリフの組み合わせについて、 両グリフにそれぞれの anchor point を指定するものです。 >>3

[34] GPOS lookupType 5 (Mark-to-Ligature Attachment Positioning, MarkLigPos) は、 合字グリフマークグリフの組み合わせについて、 両グリフにそれぞれの anchor point を指定するものです。 >>3

[37] GPOS lookupType 6 (Mark-to-Mark Attachment Positioning, MarkMarkPos) は、 基底となるマークグリフ mark2 とそれに付加するマークグリフ mark1 の組み合わせについて、 両グリフにそれぞれの anchor point を指定するものです。 >>3

[35] 基底グリフの場合は anchor point は1組だけ指定できます。 合字グリフは見かけ上複数の構成部品 (component) があるかもしれないので、 anchor point をそれに合わせて複数組設定できます。 >>3

[32] マークグリフは、基底グリフと互いの anchor point が揃うように配置を調整します。 マークグリフの位置決定は、 基底グリフ前進後の pen point を基準とします。 基底グリフ配置は変更しません。 両グリフ前進は変更しません。 >>3

[36] 合字グリフの場合も基底グリフと同じようにします。 >>3 ただし合字グリフのときは複数組ある(かもしれない) anchor point のいずれを選ぶかが問題となります。 文字のレンダリング

[38] マークグリフ同士の場合も基底となるマークグリフ mark2 に対して同じようにします。 >>3

[33] lookup の機能的に求められる基底グリフ合字グリフマークグリフといったグリフ級と、 実際に lookup に記述されたグリフに割り当てられたグリフ級は、 一致しないこともデータ構造上はあり得ます。 そのような場合にどうするべきかは言及もされていません。 素直に考えると、これらの lookupグリフ級によって使う、 使わないがまず判断されるのですから、 グリフ級が一致しないデータが混じっていても単に無視されるだけなのが好ましい実装でしょうか。

[22] 複数の lookup の指定は蓄積されることになっていますが >>3、 適用されるべき entry point anchor, exit point anchor, マークグリフ用の anchor point が重複するときどう処理するべきかは不明です。 そのような指定は意味を持ちませんから、 フォントはそのような lookup を持つべきではないのでしょう。

[39] 基底グリフまたは合字グリフマークグリフとの関係による anchor pointマークグリフマークグリフとの関係による anchor point の両方が適用可能なときは、 マークグリフマークグリフanchor point が優先されることを意図していると考えるのが自然です。

[40] こちらの場合は基底グリフマークグリフの単体の組み合わせも意味があるのですから、 マークグリフマークグリフanchor との衝突は lookup の設計の誤りではなく、 優先度が仕様上明確でないことの問題です。

[69] JstfMax lookup添付点を指定することは OpenType 仕様上明確に禁止されていませんが、 その意味が定められていません。 >>103 添付点と「最大値」という JstfMax lookup の性質はなじまないので、 利用ではないかもしれません。 (justification によって添付点が変化するべきなら、 JstfMax lookup ではなく有効または無効にするべき lookup として別に記述できます。 JSTF )

SVG 字形配置

[86] SVG グリフは、 SVG文書内の座標系によって配置された図形を文字列 (のグリフ列) の座標空間に配置することになります。

[87] SVG文書の default units は、フォントの font design units と等しい (equivalent) です。 >>85

[88] SVG原点 (0, 0) は、フォント側の design grid の原点に揃えます。 y = 0 は、 text layout に使う既定の水平基線です。 >>85

[89] フォント側では y 軸は下方向がとなりますが、 SVG座標系では y 軸は上方向がとなります。 >>85 従って SVG文書単体で表示するのと上下逆転することになります。

[93] このため字形の大部分は xy象限に配置されることがあります。 一般的な図形編集では xy象限に配置するので、 例えば svg 要素viewBox 属性0 1000 1000 1000 のように設定して、 SVG 座標系y 軸方向に 1000 ずらしておく技法があります。 あるいは対象となる要素transform="translate(0,-1000)" と指定することでずらす技法があります。 フォント開発工具は、 設計環境からフォント内の形式へと適切に移すことが期待されています。 >>85 (Note, 例示)

[90] SVG文書の initial viewport の size は、 em square です。 すなわち、 高さ = = headunitsPerEm です。 >>85

[91] svg 要素viewBox 属性高さが指定されていて >>90 と異なるときは、 SVG 利用者座標系の scale transformation の効果を持つことになります。 svg 要素height 属性width 属性が指定されているときは、 やはり座標系の scale transformation の効果を持つことになります。 >>85

[92] initial viewport の size は em square ですが、 viewportclip してはなりません (must not) svg 要素clip 特性の値が autooverflow 特性の値が visible があるものとみなします。 svg 要素clip 特性overflow 特性の違う値が指定されていても、無視しなければなりません (must) フォントsvg 要素clip 特性overflow 特性を指定するべきではありません (should not) >>85

[94] グリフadvance widthhmtx の、 advance heightvmtx の指定によります。 >>85

[95] つまり他の形式のグリフの場合と共通です。

[96] SVGアニメーションCSSアニメーションに対応している場合でも、 グリフの advance はアニメーションで変化してはなりません (must not) >>85

[98] グリフbounding boxフォント内に明示的には記述されません。 bounding box が必要なときはレンダリングしたグリフの “ink” bounding box を使うべきです (should) 。 これは animated rendering と static rendering で違うかもしれません。 >>85

[97] hmtxleft side bearing, vmtxtop side bearing, headflags の第1ビットは、 SVG グリフでは使いません。 >>85

選択と hit testing

[81] 少なくても WindowsChrome では、 OS/2usWinAscentusWinDescent行箱の上下の決定に寄与しているように見えます。

[82] 縦書きの左右位置にも影響しているのかいないのか。 基線

vertical-align

[83] CSSvertical-align (baseline-shift) では、選ばれた基線を基準に、上方 (横書き) をとする値を使います。

[84] その移動量は <length><percentage> で、後者のときは line-height に対する割合となります。

ヲコト点

[2] ヲコト点座標

関連

[72] Adobe Font Metrics File Format

メモ