フォントに関するよくある質問
詳細な説明に入る前に、フォントが難しい問題である理由を説明したいと思います。Graphviz(および他のプログラム)におけるテキストフォントの命名とレンダリングは複雑です。いくつかの理由があります。
- Graphvizは、Linuxやその他のUnix系、Microsoft Windows、Macなど、幅広いシステムで動作します。
- Graphvizは、PNGやGIFのようなラスター指向の形式、Postscript、PDF、SVGのようなパスベースの形式、troff PICのような特異なレガシー形式など、幅広い出力形式をサポートしています。
- 多くの場合、出力は、レイアウトが作成されたものとは異なるコンピューターまたは他のデバイスにダウンロードされ、表示されます。
- Graphvizレイアウトは、出力形式に関係なく、サイズと外観が同一である必要があります。
- Graphvizは、テキストフォントの命名とレンダリングに役立つ外部ライブラリを使用できますが、それらは必須ではなく、それらなしで簡素化されたGraphvizツールを構築できます。実際、Graphvizは、フォントファイルがインストールされていないシステムで実行される場合があります。
- サポートする必要がある主要なフォントファイル形式がいくつかあります。
- 非西洋の国際文字セットをサポートする必要があります。
- Graphvizは、標準的なフォントの優れたセットを提供する必要があります。
- 標準フォントを簡単に指定できるようにする必要があります。
- ユーザーは独自のフォントをロードできる必要があります。
- ダウンロードが速くなるように出力を小さくする必要があります。
- 指定された形式で可能な限り最高のレンダリングを許可する必要があります。
- 出力ファイルを簡単に後処理できるようにする必要があります。たとえば、可能であれば元のグラフのオブジェクトを保持します。
- サポートライブラリや一般的な外部ツールの既知のバグや欠落機能を回避することは非常に役立ちます。
これは大きな注文です。目標の中には矛盾するものもあります。一般的に、当社の取り組みは、利便性と見栄えの良い出力を優先し、ユーザーにデフォルトをオーバーライドするオプションを与えるデフォルトを定義することです。
概要
以下では、デスクトップシステムまたはサーバーで標準的なフォントファイルのインストールを行い、完全なサポートライブラリ(fontconfig、gd、Cairo、Pango)を備えた「標準」バージョンのGraphvizを使用することを前提とします。
graphvizレイアウトエンジン(dot、neatoなど)は、テキストラベルを囲むようにサイズが調整されたノードを含むレイアウトを作成します。これには、テキストブロックのサイズを知る必要があり、それは次にフォントグリフのメトリクスとその単語への構成を知ること、ワードスペーシング、カーニング、ヒンティングなどを考慮する必要があります。したがって、全体的なプロセスは、フォントの指定、テキストレイアウト、Graphviz出力(およびターゲットディスプレイまたはデバイスでの最終的なレンダリング(Graphvizツールによる可能性もあります))です。
フォントは通常、ファミリー名(fontname
)およびその他のプロパティ(下記の「フォントの選択」を参照)で選択されます。次に、fontconfigは要求をシステムフォントに一致させます。
注:古いバージョンのGraphvizでは、fontname
は単なるファイル名でした。これには、正確なファイル名の一致が必要でした(内部で少し便利な名前の変更、たとえば、WindowsシステムでTimes-Roman
をTimes
に変換したり、Helvetica
をArial
に変換したりするなど(はい、違いがあることはわかっています)。fontconfigの下では、fontnamesはファミリー名であり、fontconfigは最も近いフォントに一致させます。これは常に「成功」しますが、残念ながら、fontconfigの「近い」という考え方があなたの考えと一致しない場合、驚くべき結果をもたらします。これは、Steve-North-Handwriting
のようなカスタム(または存在しない)フォントを指定し、fontconfigがサイレントでタイプライターフォントのような安全なものにフォールバックする場合に発生する可能性があります。
テキストレイアウトはpangoによって実行され、テキストを受け入れてノードサイズを決定するメトリクスを含むレイアウトを計算します。
線描画は多くの出力形式(そして将来さらに増える可能性があります)に対してcairoによって提供されますが、ラスター出力形式の場合、フォントレンダリングはcairoからfreetypeに渡されます。 gdが描画に使用される場合もfreetypeが呼び出されます。(cairoなしでGraphvizがビルドされている場合、gdは明示的に要求することもできます(例:dot -Tpng:gd
)、またはデフォルトで要求することもできます)。Freetypeは、アンチエイリアシング、ヒンティング、カーニング、その他の低レベルのフォント機能を提供します。
フォントメトリクスは、Graphvizを実行しているシステムにインストールされているフォントから取得されます。Graphvizがラスター形式を出力する場合、freetypeがフォントをピクセルに即座にレンダリングするため、結果は保証されます。一方、Postscript(-Tps
)やSVG(-Tsvg
)のようなパスベースの形式では、最終的なレンダリングはまったく異なるプラットフォームで行われ、異なるフォントファイルがインストールされている可能性があります。明らかに、結果は様々です(Your Mileage May Vary)。Postscriptの場合、Graphvizのドライバはテキストブロックの期待されるメトリクスをレンダラーに渡し、レイアウト時に有効であったメトリクスにテキストを合わせるために最終的な伸縮(または圧縮)を行うよう要求します。Graphviz SVGでは、SVGレンダリングプログラムのフォントが、Graphvizの実行時にfontconfigとfreetypeが使用したフォントと一致することを期待するしかありません。(詳細は後述します。)
デフォルトフォントとPostScriptフォント
graphvizのデフォルトフォントは、常にTimes-Roman
です。
Graphvizは歴史的に、いくつかの「標準」Postscriptフォント、当初はTimes-Roman
、Helvetica
、Courier
、Symbol
をサポートしていました。このリストは後にAdobeによって拡大され、35のフォントが含まれるようになりました。
AvantGarde-Book AvantGarde-BookOblique AvantGarde-Demi
AvantGarde-DemiOblique Bookman-Demi Bookman-DemiItalic
Bookman-Light Bookman-LightItalic Courier Courier-Bold
Courier-BoldOblique Courier-Oblique Helvetica
Helvetica-Bold Helvetica-BoldOblique Helvetica-Narrow
Helvetica-Narrow-Bold Helvetica-Narrow-BoldOblique
Helvetica-Narrow-Oblique Helvetica-Oblique NewCenturySchlbk-Bold
NewCenturySchlbk-BoldItalic NewCenturySchlbk-Italic
NewCenturySchlbk-Roman Palatino-Bold Palatino-BoldItalic
Palatino-Italic Palatino-Roman Symbol Times-Bold Times-BoldItalic
Times-Italic Times-Roman ZapfChancery-MediumItalic ZapfDingbats
残念ながら、fontconfigはPostScriptスタイルのフォント名を直接認識しないため、GraphvizはPostScipt名のリストからfontconfigファミリー名へのカスタムマッピングを作成し、すべてのcairoとgdベースのレンダラーで使用しています。-Tps
出力では、これらのフォントは名前変換なしで使用されます。
フォントの選択
.gvグラフのfontname属性は、fontconfigスタイルの指定です。
引用元:http://www.fontconfig.org/fontconfig-user.html
Fontconfigは、ライブラリが受け入れ、生成できるパターンのテキスト表現を提供します。表現は3つの部分に分かれています。最初のファミリー名リスト、2番目のポイントサイズリスト、そして最後に追加のプロパティリストです。
<families>-<point sizes>:<name1>=<values1>:<name2>=<values2>...
リスト内の値はカンマで区切られています。名前にはファミリー名とポイントサイズを含める必要はありません。省略できます。さらに、名前と値の両方を同時に示すシンボリック定数もあります。いくつかの例を以下に示します。
名前 意味 Times-12
12ポイント Times Roman Times-12:bold
12ポイント Times Bold Courier:italic
デフォルトサイズのCourier Italic Monospace:matrix=1 .1 0 1
ユーザーが優先するモノスペースフォントで、人工的な斜体を使用
Graphvizは現在、フォントサイズを指定するための個別の属性を持っています。
TODO:fontconfigスタイルの指定を許可する必要があります。Times-20
は現在、20ptフォントになりません。これはおそらく、Postscriptフォント名に対する-
の特殊な処理が原因です。
TODO:フォント名での:
の使用にバグがあるようです。これはおそらく、Windowsでのファイル名の特殊な処理が原因です。フォント名では、値の区切りに:
ではなく<space>
を使用してください。-Nfontname="Courier:italic"
はgraphviz-2.16.1では斜体フォントを生成しませんが、-Nfontname="Courier italic"
は機能します。しかし、-Nfontname="Monospace matrix=1 .1 0 1"
は機能しません。
fontconfigを使用したフォント管理
使用可能なフォントを確認するにはどうすればよいですか?
$ fc-list
dotが使用しているフォントを確認するにはどうすればよいですか?
$ dot foo.gv -Tpng -o foo.png -v 2>&1 | grep font
カスタムフォントを追加するにはどうすればよいですか?
fontconfig、Cairo、Pangoを使用する現在のバージョンのGraphvizでは、単にファイルを現在のディレクトリに配置したり、DOTFONTPATH環境変数を設定するだけでは実行できません。カスタムフォントは、fontconfigツールによって明示的にインストールする必要があります。
単一のフォント(例:foo.ttf
)の場合
$ mkdir -p ~/.fonts
$ cp foo.ttf ~/.fonts/
fc-cache
を実行して、fontconfigの使用を高速化できます。
$ fc-cache
Windowsユーザーの場合、C:\windows\fonts
フォルダに移動し、プルダウンメニューから[ファイル] -> [新しいフォントのインストール]を使用してフォントをインストールできます。
新しいフォントディレクトリ(例:/Library/Fonts
)の場合、新しい<dir>
要素を
<dir>/Library/Fonts</dir>
.conf
ファイルに追加します。ファイルは、fontconfigのfonts.dtd
で指定された正しいxml構造を持っている必要があります。.conf
ファイルとして選択できるのは、システム全体のfonts.conf
ファイルと同じディレクトリにあるlocal.conf、またはホームディレクトリにある.fonts.conf
です。
…フォントするにはどうすればよいですか?
参照:http://www.fontconfig.org/fontconfig-user.html
ファミリー名ではなくファイル名でフォントを指定できますか?
申し訳ありませんが、答えはノーです。(これが機能するには、Graphvizがfontconfigが呼び出される前にフォントルックアップをインターセプトする必要があり、フォントがPangoによってルックアップされている場合はこれを実行できません。)
一部のバージョンのfontconfigはパス名を認識し、それを利用しようとしますが、常にそうとは限りません。
特定のフォントが確実に選択されていることを確認するにはどうすればよいですか?
fontnameに十分な指定を行い、fc-match
を使用してテストして、目的のフォントが選択されていることを確認してください。(ただし、最終的なプリンターまたはコンピューターで使用可能なフォントに依存する-Tps
または-Tsvg
レンダリングでは、同じフォントが使用されることが保証されるわけではありません。)
前に述べたように、欠点は、fontconfigが非常に良い一致を見つけることができなかった場合、Graphvizは警告することがほとんどできないことです。なぜなら、fontconfigは単に喜んで標準フォントにフォールバックするからです。fontconfigの開発者が、APIでフォントの一致の品質を反映するメトリクスを提供してくれたら本当に良いでしょう。
SVGフォントはどうなりますか?
Graphvizには、私たちが作成したネイティブのSVGドライバ(デフォルト)と、cairoのSVGドライバ(-Tsvg:cairo
で取得)があります。
GraphvizのネイティブSVGドライバは、デフォルトでTimes New Roman
やArial
などのWindows互換の名前を生成します。これらの名前は多くの状況(Windowsで実行されているFirefoxなど)で機能しますが、移植性が保証されているわけではありません。-Gfontnames=ps
を設定すると、Times-Roman
などのPostscript名が取得されます。-Gfontnames=svg
を設定すると、堅牢で標準に準拠したSVGが確実に取得されます。SVG標準では、有効な汎用フォント名はSerif
、Sans-Serif
、Monospace
(およびGraphvizでは使用しないCursive
とFantasy
)です。これらの名前を生成します。悪いニュースは、様々なダウンストリームレンダラーとエディターが汎用フォント名を異なる方法で解決するため、SVGがどのように表示されるかは必ずしも明確ではないことです。多くのW3Cの例では、ルックアップの優先順位に従ってフォントファミリー名のリストを与えることでこの問題を回避する方法を示すCSS(カスケーディングスタイルシート)の使用を示していますが、一部のダウンストリームプロセッサ(Linuxのinkscapeエディターなど)はCSSを実装していないため、ここで行き詰まってしまいます。
cairo SVGドライバは、これを効果的で力ずくの方法で解決します。つまり、必要なフォントをターゲットSVGの線と曲線としてエンコードして埋め込むだけです。小さな例では、-Tsvg:cairo
は-Tsvg
のおよそ10倍のサイズになりますが、正確性のためには価値があるかもしれません。もう1つの問題は、このようなSVGのレンダリング速度がはるかに遅いことです。これは間違いなく、システムのフォントレンダリングサービスをバイパスし、昔ながらの方法で行っているためです。
Postscriptフォントはどうなりますか?
TODO:ここで何かを記述する。Latin1
のような非ASCII文字はどうなりますか?古いアウトラインフォントの例のように、-L
を使用して独自のフォントを読み込むことはできますか。
非標準のGraphvizビルドに関する「もし〜だったら」の問題
以下は、ソースコードを構成してコンパイルして独自のカスタム実行ファイルをビルドすることにより、独自のGraphvizバージョンをビルドする場合にのみ適用されます。この意味がわからない場合は、間違いなくあなたには関係ありません。
freetypeなし
freetypeがないシステムでgraphvizをビルドする場合、ビットマップ出力にはgdレンダラーのみが使用可能になり、使用可能なフォントは、組み込みの少数のビットマップフォントのみになります。これらのフォントの品質の悪さは明らかであり、また、dot ... -v 2>&1 | grep font
はフォントが<internal>
であると表示します。これは、フォントがインストールされていない可能性のあるサーバーに最小限のgraphvizプログラムをインストールする場合に実際には望ましい場合があります。
fontconfigなし
fontconfigがないシステム(例:Redhat-7)でgraphvizをビルドする場合、fontname属性はフォントファイル名として解釈されます。システムディレクトリでこれが検索されるか、GDFONTPATH
環境変数(または歴史的な理由でDOTFONTPATH
)でディレクトリを指定できます。Graphvizは、gdとfreetypeを使用してメトリクスを取得し、テキストをレンダリングします。fontconfigのサポートがないと、pango/cairoレンダラーは使用できません。
fontconfigの無効化
Pango/cairoはfontconfigに依存しているため、fontconfigを無効にするには、pango/cairoも無効にする必要があります。これの一時的な簡単な方法は、/usr/lib/graphviz/config
を編集して、libpango
ブロック全体を削除することです。
このファイルへの変更は、次回graphvizが更新されたとき、またはインストーラー権限でdot -c
が実行されたときに失われます。
pangoが無効になっている場合、graphvizはgdを使用します。これは、fontconfigのサポートを備えてビルドされていたとしても、フォント名をファイル名として指定することを許可します。
構成スクリプトオプションを使用して、ビルド時にcairopangoを無効にすることもできます。
gdなし
Cairopangoはgdなしで動作します。Graphvizをpango/cairoライブラリに移行していますが、gdはまだJPEG、GIF、パレットカラーのビットマップ出力など、置き換えが困難な機能を提供しています。ただし、pango、cairo、fontconfig、freetypeが使用可能であれば、フォントのサポートはgdなしでも完全に機能します。
pango/cairoなし
pango/cairoがない場合、主要なレンダラーの一部はgdでのみ使用可能であり、低品質(ただし小さい)の出力が生成されます。
将来に向けて、行の折り返し、ラベルごとの複数のフォント、双方向テキスト、その他の国際化機能などについて、pangoにより多く依存することを期待しています。
gdとcairopangoの両方なし
これは基本的に、外部フォントを使用しない元のGraphvizです。ラスター形式をレンダリングできないため、主にPostscriptに適しています。いくつかの内部フォントテーブルに依存しています。