Qtフォントのギモン解決:setKerning()の動作とトラブルシューティング

2025-06-06

QFont::setKerning()関数は、QtのQFontクラスに属するもので、テキストのカーニング(Kerning)設定を制御するために使用されます。

カーニングとは何か?

カーニングとは、特定の文字の組み合わせにおいて、文字間のスペースを調整することで、テキストの可読性を高め、見た目を美しくする組版技術です。例えば、「VA」や「To」のような文字の組み合わせでは、標準の文字間隔だと文字が離れすぎたり、不自然に見えたりすることがあります。カーニングは、このような特定のペアの文字間を詰めることで、より自然でバランスの取れた外観を作り出します。

QFont::setKerning()の機能

QFont::setKerning(bool enable)は、このカーニング機能の有効/無効を切り替えるために使われます。

  • enablefalseの場合: フォントのカーニング機能が無効になります。この場合、文字間のスペースは均一に保たれ、カーニングによる調整は行われません。これは、特定のデザイン上の理由や、パフォーマンスが非常に重要な場合に選択されることがあります。
  • enabletrueの場合: フォントのカーニング機能が有効になります。これにより、フォントに組み込まれているカーニング情報(特定の文字ペア間の推奨スペース調整)が適用され、テキストがより美しく表示されます。ほとんどの場合、これをtrueに設定することで、より良いテキストの描画結果が得られます。

使用例

#include <QApplication>
#include <QLabel>
#include <QFont>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QLabel label;
    QFont font("Times New Roman", 36); // フォントとサイズを設定

    // カーニングを有効にする
    font.setKerning(true);
    label.setFont(font);
    label.setText("VAIO"); // カーニングの効果が見えやすい例
    label.show();

    QLabel labelNoKerning;
    QFont fontNoKerning("Times New Roman", 36);

    // カーニングを無効にする
    fontNoKerning.setKerning(false);
    labelNoKerning.setFont(fontNoKerning);
    labelNoKerning.setText("VAIO (No Kerning)");
    labelNoKerning.move(0, 100); // 位置をずらして表示
    labelNoKerning.show();

    return app.exec();
}

上記の例では、一つ目のQLabelはカーニングが有効な状態で「VAIO」を表示し、二つ目のQLabelはカーニングが無効な状態で同じテキストを表示します。これにより、カーニングがテキストの見た目に与える影響を視覚的に比較することができます。



QFont::setKerning()は、テキストのカーニングを制御するための便利な関数ですが、期待通りに動作しない場合があります。ここでは、一般的な問題点とそれに対するトラブルシューティング方法を説明します。

カーニングが全く適用されない

問題の症状
setKerning(true)を設定しても、テキストの文字間隔が視覚的に変化しない。

考えられる原因と解決策

  • Qtが使用しているフォントレンダリングバックエンドの問題

    • 原因
      QtはプラットフォームのネイティブなフォントレンダリングAPI(WindowsのDirectWrite、macOSのCore Text、LinuxのFontconfig/FreeTypeなど)を利用することがあります。これらのバックエンドやその設定に問題がある場合、カーニングが正しく機能しないことがあります。
    • 解決策
      特定のプラットフォームで問題が発生している場合、そのプラットフォームのフォント設定やドライバーなどを確認してみてください。稀に、Qtのビルドオプションや環境変数によってフォントレンダリングの動作が変わることもあります。
  • 小さなフォントサイズ

    • 原因
      フォントサイズが非常に小さい場合、カーニングによる文字間隔の変化が視覚的にほとんど認識できないことがあります。
    • 解決策
      フォントサイズを大きくして、カーニングの効果がはっきりと見えるか確認してください。例えば、30pt以上のサイズでテストすると良いでしょう。
  • OpenTypeフォントの高度なカーニング(GPOS)がQtで完全に対応していない可能性

    • 原因
      過去のQtのバージョン(特に古いもの)では、OpenTypeフォントが持つ高度なカーニング機能(GPOS: Glyph Positioning)を完全にサポートしていない時期がありました。GPOSは従来のkernテーブルよりも複雑で強力なカーニング情報を提供しますが、Qtがこの情報を適切に解析できない場合、カーニングが適用されません。
    • 解決策
      Qtのバージョンを最新に更新することを検討してください。新しいバージョンでは、フォントレンダリングの改善やより多くのOpenType機能への対応が進んでいる可能性があります。
    • 備考
      これは特定のフォント(特に最新のOpenTypeフォント)で発生しやすい問題です。
    • 原因
      多くのフォントはカーニング情報(kernテーブルやGPOSテーブル)を含んでいますが、全てのフォントがそうではありません。特に古いフォント形式や、デザイナーがカーニングを意図的に無効にしているフォントでは、カーニングが適用されません。
    • 解決策
      別のフォント(特にモダンなTrueTypeやOpenTypeフォント)を試してみてください。例えば、「Times New Roman」や「Arial」のような一般的なフォントは通常、カーニング情報を持っています。
    • 確認方法
      フォントビューアツール(Windowsのフォント設定、macOSのFont Bookなど)で、そのフォントがカーニングをサポートしているか確認できる場合があります。

Qtスタイルシートとの競合

問題の症状
setFont()setKerning(true)を設定しても、スタイルシートで設定されたフォントが優先されて、カーニングが適用されない。

考えられる原因と解決策

  • 解決策
    1. スタイルシートでカーニングを設定する(推奨されない)
      残念ながら、Qtのスタイルシートには直接カーニングを有効/無効にするプロパティは提供されていません。フォントファミリー、サイズ、太さなどは設定できますが、カーニングの有無は通常、フォントの属性に依存します。
    2. スタイルシートではなく、C++コードでフォントを設定する
      確実にカーニングを制御したい場合は、スタイルシートでのフォント設定を避け、C++コードでsetFont()setKerning()を使用します。
    3. 特定のウィジェットにスタイルシートを適用する際の優先順位を考慮する
      スタイルシートを適用する対象を限定したり、より具体的なセレクタ(例: QLabel#myLabel { ... })を使用して、意図しないフォントの上書きを防ぐようにしてください。
  • 原因
    Qtのスタイルシートは、ウィジェットのフォント設定を上書きする強力なメカニズムです。スタイルシートでフォントが設定されている場合、C++コードでQWidget::setFont()QFont::setKerning()を呼び出しても、その設定が無視されることがあります。

動的にフォントを変更した場合の更新不足

問題の症状
アプリケーションの実行中に動的にフォントを変更したが、カーニングの状態が更新されない。

考えられる原因と解決策

  • 解決策
    QFont currentFont = label->font(); // 現在のフォントを取得
    currentFont.setKerning(true);      // カーニングを有効にする
    label->setFont(currentFont);       // 変更したフォントを再設定
    label->update();                   // 必要に応じてウィジェットを更新
    
    このように、変更を加えたいフォントオブジェクトを取得し、変更を加えてから、再度そのフォントをウィジェットに設定し直す必要があります。update()repaint()を呼び出すことで、ウィジェットの再描画を強制し、変更を反映させることができます。
  • 原因
    QFontオブジェクトを作成し、setKerning()を呼び出した後、そのQFontオブジェクトをウィジェットに設定する必要があります。フォントオブジェクトの内容を変更しただけでは、既に表示されているウィジェットにその変更が自動的に反映されるわけではありません。
  • 最小限の再現コード

    • 問題が複雑なアプリケーションの一部で発生している場合、問題を再現する最小限のコードスニペットを作成してみてください。これにより、問題の原因を特定しやすくなります。
  • 異なるフォントでのテスト

    • 問題が特定のフォントに依存しているかを確認するために、複数の異なるフォント(特にシステムにデフォルトでインストールされている一般的なフォント)でテストを行うのが効果的です。
  • QFont::kerning()の確認

    • QFontオブジェクトのkerning()メソッドを呼び出すことで、カーニングが有効になっているか(trueが返るか)を確認できます。これがtrueを返しているにもかかわらず視覚的に変化がない場合は、上記で述べたフォント自体の問題やレンダリングバックエンドの問題である可能性が高いです。
    • 例: qDebug() << "Kerning enabled:" << myFont.kerning();


基本的な使用例:カーニングの有効化と無効化

この例では、2つのQLabelウィジェットを使って、同じテキストをカーニング有効と無効の状態で表示し、その違いを比較します。

#include <QApplication> // QApplicationクラスを使用するために必要
#include <QLabel>         // QLabelクラスを使用するために必要
#include <QFont>          // QFontクラスを使用するために必要
#include <QDebug>         // デバッグ出力(オプション)

int main(int argc, char *argv[])
{
    QApplication app(argc, argv); // Qtアプリケーションオブジェクトを作成

    // --- カーニングを有効にしたQLabel ---
    QLabel labelWithKerning; // 新しいQLabelウィジェットを作成
    QFont fontWithKerning("Times New Roman", 36); // "Times New Roman"フォント、サイズ36ptを設定

    // QFont::setKerning(true)でカーニングを有効にする
    fontWithKerning.setKerning(true);
    qDebug() << "Kerning enabled for labelWithKerning:" << fontWithKerning.kerning(); // カーニングが有効か確認

    labelWithKerning.setFont(fontWithKerning); // フォントをQLabelに設定
    labelWithKerning.setText("VAIO (Kerning ON)"); // 表示するテキストを設定
    labelWithKerning.move(50, 50); // ウィンドウ内の位置を設定
    labelWithKerning.show(); // QLabelを表示

    // --- カーニングを無効にしたQLabel ---
    QLabel labelNoKerning; // 別のQLabelウィジェットを作成
    QFont fontNoKerning("Times New Roman", 36); // 同じフォントとサイズを設定

    // QFont::setKerning(false)でカーニングを無効にする
    fontNoKerning.setKerning(false);
    qDebug() << "Kerning enabled for labelNoKerning:" << fontNoKerning.kerning(); // カーニングが有効か確認

    labelNoKerning.setFont(fontNoKerning); // フォントをQLabelに設定
    labelNoKerning.setText("VAIO (Kerning OFF)"); // 表示するテキストを設定
    labelNoKerning.move(50, 120); // ウィンドウ内の別の位置に設定
    labelNoKerning.show(); // QLabelを表示

    return app.exec(); // アプリケーションのイベントループを開始
}

コードの解説

  1. インクルード
    • QApplication: Qtアプリケーションの実行に必要な基本クラスです。
    • QLabel: テキストを表示するためのウィジェットです。
    • QFont: フォントの設定を行うためのクラスです。
    • QDebug: デバッグメッセージをコンソールに出力するために使います(オプション)。
  2. QApplicationの初期化
    • QApplication app(argc, argv);でアプリケーションオブジェクトを作成します。Qt GUIアプリケーションには必須です。
  3. labelWithKerning(カーニング有効)
    • QLabel labelWithKerning;QLabelのインスタンスを作成します。
    • QFont fontWithKerning("Times New Roman", 36);で、"Times New Roman"というフォントファミリーと36ポイントのサイズを持つQFontオブジェクトを作成します。
    • fontWithKerning.setKerning(true);: ここが今回のポイントです。この行で、カーニング機能を有効にしています。これにより、このフォントを使用するテキストでは、フォントに定義されているカーニング情報に基づいて文字間のスペースが調整されます。
    • qDebug() << ...; で、fontWithKerning.kerning()メソッドを呼び出し、実際にカーニング設定がtrueになっているかを確認しています。
    • labelWithKerning.setFont(fontWithKerning);で、設定済みのQFontオブジェクトをQLabelに適用します。
    • labelWithKerning.setText("VAIO (Kerning ON)");で表示テキストを設定します。「VAIO」のような文字の組み合わせは、カーニングの効果が顕著に現れやすい例です。
    • labelWithKerning.move(50, 50);で、アプリケーションウィンドウの左上からのX座標50、Y座標50の位置にラベルを配置します。
    • labelWithKerning.show();で、ラベルを画面に表示します。
  4. labelNoKerning(カーニング無効)
    • 上記のlabelWithKerningとほとんど同じですが、fontNoKerning.setKerning(false);の行で、カーニング機能を無効にしています。これにより、フォントがカーニング情報を持っていても、その調整は適用されず、文字は標準の等間隔で表示されます。
    • labelNoKerning.move(50, 120);で、一つ目のラベルの下に配置して比較しやすくしています。
  5. app.exec();
    • アプリケーションのイベントループを開始します。これにより、ウィンドウが表示され、ユーザーの入力(マウス、キーボードなど)に応答できるようになります。

動的にカーニングを切り替える例

この例では、ボタンをクリックすることで、表示されているテキストのカーニングを動的に有効/無効に切り替える方法を示します。

#include <QApplication>
#include <QWidget>    // 基本ウィジェット
#include <QLabel>
#include <QPushButton> // QPushButtonクラスを使用するために必要
#include <QVBoxLayout> // レイアウト管理
#include <QFont>
#include <QDebug>

class KerningToggleWidget : public QWidget
{
    Q_OBJECT // シグナル&スロットを使用するために必要

public:
    explicit KerningToggleWidget(QWidget *parent = nullptr) : QWidget(parent)
    {
        // レイアウトの設定
        QVBoxLayout *layout = new QVBoxLayout(this);

        // テキスト表示用ラベル
        m_label = new QLabel("AVA To (Dynamic Kerning)", this);
        m_font.setFamily("Times New Roman"); // フォントファミリーを設定
        m_font.setPointSize(48);             // サイズを設定
        m_font.setKerning(true);             // 初期状態ではカーニングを有効に
        m_label->setFont(m_font);
        layout->addWidget(m_label);

        // カーニング切り替えボタン
        m_toggleButton = new QPushButton("Toggle Kerning (Currently ON)", this);
        // ボタンがクリックされたらtoggleKerning()スロットを呼び出す
        connect(m_toggleButton, &QPushButton::clicked, this, &KerningToggleWidget::toggleKerning);
        layout->addWidget(m_toggleButton);

        setLayout(layout); // ウィジェットにレイアウトを設定
    }

private slots:
    void toggleKerning()
    {
        // 現在のカーニング状態を反転させる
        bool currentKerningState = m_font.kerning();
        m_font.setKerning(!currentKerningState); // カーニングを切り替える

        // 変更されたフォントをラベルに再設定
        m_label->setFont(m_font);

        // ボタンのテキストを更新して現在の状態を示す
        if (m_font.kerning()) {
            m_toggleButton->setText("Toggle Kerning (Currently ON)");
            qDebug() << "Kerning is now ON";
        } else {
            m_toggleButton->setText("Toggle Kerning (Currently OFF)");
            qDebug() << "Kerning is now OFF";
        }
        // ラベルを強制的に再描画して変更を反映させる(通常は不要だが、確実のために)
        m_label->update();
    }

private:
    QLabel *m_label;
    QPushButton *m_toggleButton;
    QFont m_font; // QFontオブジェクトをメンバ変数として保持
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    KerningToggleWidget window;
    window.setWindowTitle("Dynamic Kerning Example");
    window.resize(400, 200);
    window.show();

    return a.exec();
}

#include "main.moc" // mocファイルを含める(Qtのメタオブジェクトシステム用)

コードの解説

  1. KerningToggleWidgetクラス
    • QWidgetを継承したカスタムウィジェットです。
    • Q_OBJECTマクロ
      シグナルとスロットを使用するために必須です。このマクロがあることで、Qtのメタオブジェクトコンパイラ(moc)が追加のC++コードを生成します。
  2. コンストラクタ
    • QVBoxLayoutを使用して、QLabelQPushButtonを縦方向に配置しています。
    • m_labelの初期化
      • m_font(クラスのメンバ変数)でフォントを設定し、初期状態ではm_font.setKerning(true);でカーニングを有効にしています。
      • このm_fontオブジェクトは、カーニングの状態を保持するためにクラスのメンバ変数として宣言されています。
    • m_toggleButtonの初期化
      • ボタンがクリックされたときにtoggleKerning()スロットが呼び出されるように、connect関数でシグナルとスロットを接続しています。
  3. toggleKerning()スロット
    • この関数は、ボタンがクリックされるたびに実行されます。
    • bool currentKerningState = m_font.kerning();で、現在のフォントのカーニング状態を取得します。
    • m_font.setKerning(!currentKerningState);: カーニングの状態を現在の状態の逆(ONならOFF、OFFならON)に設定します。
    • m_label->setFont(m_font);: ここが非常に重要です。m_fontオブジェクトのカーニング設定を変更した後、その変更されたQFontオブジェクトを再度m_labelに設定し直す必要があります。これでQLabelが新しいフォント設定を認識します。
    • ボタンのテキストも更新して、現在のカーニング状態をユーザーに知らせます。
    • m_label->update();は、通常setFont()を呼び出すと自動的に再描画がトリガーされますが、念のため明示的に再描画を要求しています。

上記のコードをコンパイルして実行するには、Qt開発環境がセットアップされている必要があります。

  1. テキストエディタでコードを保存します(例: main.cpp)。
  2. プロジェクトファイル(例: kerning_example.pro)を作成します。
    QT += widgets # GUIアプリケーションに必要なモジュール
    
    SOURCES += main.cpp # ソースファイル
    
  3. ターミナル(コマンドプロンプトやBashなど)でプロジェクトディレクトリに移動し、以下のコマンドを実行します。
    qmake -project # 最初の例の場合のみ。二つ目の例では手動で.proファイルを作成
    qmake # プロジェクトファイルからMakefileを生成
    make # または nmake (Windowsの場合) / mingw32-make (MinGWの場合)
    
  4. 実行可能ファイルが生成されるので、それを実行します。


QFont::setKerning()はQtでフォントのカーニングを制御する主要な方法ですが、特定のシナリオやより高度なテキストレンダリングのニーズがある場合、他のアプローチを検討する必要があるかもしれません。

QFont::setKerning()が推奨される理由と、代替の考慮事項

まず、なぜ通常はQFont::setKerning()が推奨されるのかを理解することが重要です。

  • パフォーマンス
    Qtのレンダリングパイプラインに統合されており、通常は最適化されています。
  • フォント依存
    フォントに埋め込まれたカーニング情報を利用するため、フォントデザイナーの意図を最も忠実に再現します。
  • 簡単さ
    最もシンプルで、かつほとんどの場合に十分な結果を提供するAPIです。

しかし、以下のようなケースでは代替方法を検討する必要があります。

  • カスタムテキストレンダリング
    Qtの標準のテキスト描画機能では不十分で、ピクセル単位でテキストの描画を制御したい場合。
  • OpenTypeの高度なタイポグラフィ機能の利用
    合字(ligatures)、字形(glyphs)の代替、バリアブルフォントなど、カーニング以外のより複雑なタイポグラフィ機能を利用したい場合。
  • より詳細な文字間隔制御が必要
    カーニングとは異なる、一般的な文字間隔(トラッキング/アキ)や、特定の文字ペアにカスタムの間隔を適用したい場合。
  • 特定のフォントでカーニングが機能しない
    フォント自体がカーニング情報を持っていない、またはQtがそのフォントの特定のカーニング機能をサポートしていない場合。

QFontMetricsF / QFontMetrics を使用した手動の文字配置

これは、Qtが提供するフォントメトリクス情報を使って、開発者が自分で文字の位置を計算し、描画する方法です。

アプローチ

  1. QFontMetricsF (または QFontMetrics):
    • boundingRect(): 文字列全体の矩形を取得。
    • horizontalAdvance(): 文字列または個々の文字の水平方向の幅を取得。
    • width(): 文字列の幅を取得。
  2. QPainter::drawText() のオーバーロードや、個々の文字をループで描画。

メリット

  • 特定の文字ペアのカスタム調整
    QFont::setKerning()ではできない、特定の文字ペアに独自のアキやツメを適用できます。
  • 完全な制御
    文字間のスペースを完全に自由に制御できます。カーニングだけでなく、トラッキング(文字間隔の全体的な調整)も実装できます。

デメリット

  • カーニング情報の再実装
    既にあるフォントのカーニング情報を自分で解析して再実装するのは困難です。これは、カーニングが機能しない場合の「代替」というよりも、「フォントにカーニング情報がない場合の独自実装」に近いかもしれません。
  • パフォーマンス
    手動での計算と描画は、Qtの最適化された内部レンダリングパスに比べて遅くなる可能性があります。
  • 複雑さ
    非常に実装が複雑になります。特に多言語対応、複雑なスクリプト(アラビア語など)、双方向テキストなどを考慮すると大変です。

コード例(擬似コード):

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QFont font("Arial", 24);
    painter.setFont(font);

    // QFontMetricsF を使用して文字幅を計算
    QFontMetricsF fm(font);

    QString text = "VAIO";
    qreal x = 10;
    qreal y = 50;

    for (int i = 0; i < text.length(); ++i) {
        QString charStr = text.at(i);
        painter.drawText(x, y, charStr);

        // ここでカスタムの文字間隔を適用
        // 例: 'V' と 'A' の間に特殊なアキ/ツメを入れる
        if (charStr == "V" && i + 1 < text.length() && text.at(i+1) == 'A') {
            x += fm.horizontalAdvance(charStr) * 0.7; // 標準より少し詰める
        } else {
            x += fm.horizontalAdvance(charStr); // 標準の文字幅を進める
        }
    }
}

QTextLayout / QTextLine を使用したより高度なテキストレイアウト

QTextLayoutは、複雑なテキストブロックのレイアウトと描画を管理するための、Qtのより高レベルなクラスです。これは、カーニング、合字、双方向テキスト、リッチテキストなどを自動的に処理します。

アプローチ

  1. QTextLayoutオブジェクトを作成し、setText()setFont()を設定します。
  2. QTextLayout::beginLayout()createLine()endLayout()を使って行を構築します。
  3. QTextLineオブジェクトを使って、各行のレンダリングを行います。

メリット

  • プラットフォーム依存のレンダリング最適化
    Qtのテキストレンダリングエンジンは、プラットフォーム固有のAPI(DirectWrite, Core Text, FreeTypeなど)を活用し、最適化された描画を行います。
  • 複雑なレイアウト
    段落、アラインメント、行の折り返しなどを自動で処理します。
  • リッチテキスト対応
    HTMLのようなリッチテキストのレンダリングも可能です。
  • カーニング/合字の自動処理
    QTextLayoutは、基礎となるQTextEngineを通じて、フォントが持つカーニング情報や合字(ligatures)などのOpenTypeタイポグラフィ機能を自動的に適用します。QFont::setKerning()trueであれば、これらが有効になります。

デメリット

  • 単純なテキスト描画にはオーバーヘッドがある可能性があります。
  • QFont::setKerning()falseの場合、手動でカーニングを実装することはできません。

コード例

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QTextLayout>
#include <QTextLine>
#include <QFont>

class CustomTextWidget : public QWidget
{
public:
    CustomTextWidget(QWidget *parent = nullptr) : QWidget(parent)
    {
        setFont(QFont("Times New Roman", 48)); // ウィジェットの基本フォントを設定
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing); // アンチエイリアスを有効に

        QTextLayout textLayout;
        // フォントを設定(ここで QFont::setKerning(true) が implicitly 適用されるか確認)
        // QFont::setKerning() の効果は、QTextLayout が内部で QFont の設定を読み取って適用します。
        // デフォルトではカーニングが有効になっていることが多いですが、明示的に設定することも可能です。
        QFont textFont = font(); // ウィジェットのフォントを取得
        textFont.setKerning(true); // 明示的にカーニングを有効に
        textLayout.setFont(textFont);

        textLayout.setText("AVAIO To (QTextLayout)"); // 表示するテキスト
        textLayout.beginLayout();

        // テキストを行に分割(ここでは1行のみ)
        QTextLine line = textLayout.createLine();
        if (line.isValid()) {
            line.setLineWidth(width()); // 行の幅を設定
            qreal x = 10;
            qreal y = 50;
            line.draw(&painter, QPointF(x, y)); // 行を描画
        }
        textLayout.endLayout();
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CustomTextWidget w;
    w.setWindowTitle("QTextLayout Kerning Example");
    w.resize(600, 200);
    w.show();
    return a.exec();
}

低レベルのフォントレンダリングAPIの直接利用(高度)

これはQtの範疇を越えて、OSが提供するフォントレンダリングAPI(例えばFreeType、DirectWrite、Core Textなど)を直接利用する方法です。

アプローチ

  • Core Text (macOS)
    macOSの低レベルなテキストレンダリングフレームワークを利用します。
  • DirectWrite (Windows)
    WindowsのよりモダンなテキストレンダリングAPIを利用します。
  • FreeType (Linux/クロスプラットフォーム)
    フォントファイルを直接読み込み、グリフ情報を取得し、レンダリングを行います。

メリット

  • カスタムキャッシュ/レンダリングパイプライン
    独自のテキストレンダリングエンジンを構築する際に役立ちます。
  • 究極の制御
    フォントのあらゆる側面にわたって、最も低レベルな制御が可能です。OpenTypeの非常に複雑な機能(バリアブルフォントの軸調整、特定のグリフの選択など)も実装可能です。

デメリット

  • パフォーマンス最適化の手間
    自分でパフォーマンスを考慮した実装を行う必要があります。
  • Qtとの統合
    Qtのウィジェットやグラフィックビューとの統合が難しく、多くの場合、QImageに描画してからQtで表示するといった手順が必要になります。
  • 極めて複雑
    OSごとのAPI学習と実装が必要で、開発コストが非常に高いです。
  • カスタムのテキストエディタやDTPアプリケーションをゼロから構築する場合。
  • Qtの標準的なテキストレンダリングでは実現できない、特定のタイポグラフィ機能(例えば、特定のフォントの特定のOpenType機能セットを強制的に使用したい場合)を完全にコントロールしたい場合。
  • 特殊なテキスト効果(歪曲、グリフ単位のアニメーションなど)が必要な場合。
  • Qtのレンダリングパイプラインでは実現できない特殊な要件
    OSの低レベルAPIを直接利用することを検討しますが、これは非常に高度な選択肢であり、通常は推奨されません。
  • 究極の制御、または特定のフォントでQFont::setKerning()が全く機能しない場合
    QFontMetricsFを使った手動描画を検討しますが、実装コストが高いです。
  • 複雑なテキストブロックやリッチテキスト
    QTextLayoutがより適しています。QFont::setKerning(true)を設定したQFontQTextLayoutに渡すことで、カーニングを含む高度なレンダリングが期待できます。
  • ほとんどの場合
    QFont::setKerning()を使うのが最もシンプルで効果的です。