Why is there extra spacing for some characters which cause QPainter::drawText to be cutoff?

48 Views Asked by At

I'm trying to use QPainter::drawText() to render some Chinese characters. But in certain fonts, there is extra top spacing when drawing the text. Why is this happening to some characters only?

Tested on Qt version 6.6.3 & 5.15.2

Googled some info, but nothing really answers the question:

As you can see below: green box is with metric height, while red is with bounding height. Sure, the bounding height does bound the entire text, but there is extra top and bottom spacing.

enter image description here

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QPainter>
#include <QFont>
#include <QFontMetrics>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent* event)
{
    // Call base class implementation first
    QMainWindow::paintEvent(event);

    // Obtain the QPainter object
    QPainter paint(this);

    QFont font;
    font.fromString("Apple LiGothic");
    font.setPointSize(50);
    QFontMetrics metric(font);

    paint.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing, true);
    paint.setFont(font);
    paint.setPen(Qt::white);
    const int align = Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap;

    QString text = "钳禾日当午";
    QRect bound = metric.boundingRect(text);
    bound = QRect(0, 0, bound.width(), bound.height());
    QRect metricBound(0, 0, bound.width(), metric.height());
    paint.translate(10, 100);
    paint.setPen(Qt::red);
    paint.drawRect(bound);
    paint.setPen(Qt::green);
    paint.drawRect(metricBound/*.adjusted(0,10,0,10)*/); // hack adjustment
    paint.setPen(Qt::white);
    paint.drawText(0, 0, bound.width(), bound.height(), align, text);

    text = "汗滴禾下土";
    bound = metric.boundingRect(text);
    bound = QRect(0, 0, bound.width(), bound.height());
    metricBound = QRect(0, 0, bound.width(), metric.height());
    paint.translate(0, 100);
    paint.setPen(Qt::red);
    paint.drawRect(bound);
    paint.setPen(Qt::green);
    paint.drawRect(metricBound);
    paint.setPen(Qt::white);
    paint.drawText(0, 0, bound.width(), bound.height(), align, text);
}
0

There are 0 best solutions below