C++によるQt GUIプログラミング:QFontMetrics::fontDpi()でDPI情報を取得して、高品質なフォントレンダリングを実現


この関数は、以下の情報を提供します。

  • 論理 DPI と物理 DPI の区別
    論理 DPI は、画面上のピクセル密度を表し、物理 DPI は、実際の印刷解像度を表します。QFontMetrics::fontDpi() は、論理 DPI を返します。
  • 現在のフォントの DPI
    ペインターやウィジェットで使用されているフォントの DPI を返します。

使用例

QFont font("Arial", 12);
QPainter painter(&widget);
QFontMetrics fm(font, painter);

qreal dpi = fm.fontDpi();
qDebug() << "DPI:" << dpi;

この例では、"Arial" フォント (サイズ 12pt) の DPI を取得し、コンソールに出力しています。

  • Qt 5.11 以降では、QFontMetrics::xHeight() 関数を使用して、フォントの X 高さを取得することを推奨しています。X 高さは、小文字の "x" の高さであり、フォント サイズを比較する際に役立ちます。
  • QFontMetrics::fontDpi() は、フォントが実際にレンダリングされるデバイスの DPI を返します。異なるデバイスでは、異なる DPI 値が返される可能性があります。


例 1: フォントの DPI を取得し、コンソールに出力する

#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QPainter>
#include <QFontMetrics>

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

  QLabel label("Hello, World!");
  label.setFont(QFont("Arial", 12));
  label.show();

  QPainter painter(&label);
  QFontMetrics fm(label.font(), painter);

  qreal dpi = fm.fontDpi();
  qDebug() << "DPI:" << dpi;

  return app.exec();
}

例 2: DPI に基づいてフォント サイズを調整する

#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QPainter>
#include <QFontMetrics>

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

  QLabel label("Hello, World!");
  label.setFont(QFont("Arial", 12));
  label.show();

  QPainter painter(&label);
  QFontMetrics fm(label.font(), painter);

  qreal dpi = fm.fontDpi();
  int fontSize = 12 * (dpi / 96); // 96 DPI を基準にフォント サイズを調整

  label.setFont(QFont("Arial", fontSize));

  return app.exec();
}

例 3: 論理 DPI と物理 DPI の違いを調べる

#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QPainter>
#include <QFontMetrics>

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

  QLabel label("Hello, World!");
  label.setFont(QFont("Arial", 12));
  label.show();

  QPainter painter(&label);
  QFontMetrics fm(label.font(), painter);

  qreal logicalDpi = fm.fontDpi(); // 論理 DPI を取得
  qreal physicalDpi = painter.device()->physicalDpiX(); // 物理 DPI を取得

  qDebug() << "Logical DPI:" << logicalDpi;
  qDebug() << "Physical DPI:" << physicalDpi;

  return app.exec();
}

これらの例は、QFontMetrics::fontDpi() 関数の基本的な使用方法を示しています。実際のアプリケーションでは、これらのコードを状況に合わせて調整する必要があります。



QPainter::device()->physicalDpiX() を使用する

QPainter painter(&widget);
qreal physicalDpi = painter.device()->physicalDpiX();

この方法は、現在のペインター デバイスの物理 DPI を取得します。QFontMetrics::fontDpi() と同様に、論理 DPI ではなく物理 DPI を返します。

利点

  • デバイスの DPI を直接取得するため、より正確な値を取得できます。
  • より汎用的な方法であり、フォントに依存しません。

欠点

  • 論理 DPI と物理 DPI の区別ができません。

QScreen::logicalDpiX() を使用する

qreal logicalDpi = QScreen::logicalDpiX();

この方法は、現在のスクリーンの論理 DPI を取得します。QFontMetrics::fontDpi() と同様に、論理 DPI を返します。

利点

  • 画面全体の DPI を取得できるため、複数のウィジェットに適用できます。

欠点

  • ペインター デバイスの DPI と異なる場合があります。
class MyFontMetrics : public QFontMetrics {
public:
  MyFontMetrics(const QFont &font, QPainter *painter) : QFontMetrics(font, painter) {}

  qreal fontDpi() const override {
    // カスタム ロジックを使用して DPI を計算
    // 例: デバイスの DPI とスクリーンの DPI の平均を返す
    return (painter->device()->physicalDpiX() + QScreen::logicalDpiX()) / 2;
  }
};

この方法は、より柔軟な DPI 計算ロジックを実装したい場合に役立ちます。

利点

  • カスタム ロジックを使用して DPI を計算できるため、より正確な値を取得できます。

欠点

  • 複雑な実装が必要になる場合があります。

状況に応じた適切な方法を選択

上記の代替方法はそれぞれ異なるメリットとデメリットがあります。状況に応じて適切な方法を選択する必要があります。

  • 高度な DPI 計算ロジックが必要な場合
    カスタムのフォント メトリクス クラスを作成する.
  • より正確な DPI 値が必要な場合
    QPainter::device()->physicalDpiX() または QScreen::logicalDpiX() を使用する.
  • シンプルなアプリケーションの場合
    QFontMetrics::fontDpi() を使用するのが最も簡単です。