c++ Qt 6:应用字体而不使用任何反锯齿-任何策略都不受尊重

omqzjyyz  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(235)

我正在尝试用QPainter渲染文本,但我不希望应用抗锯齿。我对QT还很陌生,所以可能在这里做错了什么。无论我尝试过什么,总有一些抗锯齿。我将在下面分享我的代码,其中包含一些关于各种不同的不起作用的事情的注解行

class TextExample : public QMainWindow {
protected:
    void paintEvent(QPaintEvent* aEvent) override {
        QPainter painter(this);

        painter.setRenderHint(QPainter::Antialiasing, false);
        painter.setRenderHint(QPainter::TextAntialiasing, false);
        painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
        painter.setBrush(Qt::black);

        QFont myFont{"Times New Roman", 12};
        myFont.setStyleStrategy(QFont::NoAntialias);
        painter.setFont(myFont);

        // painter.drawStaticText(QPoint{0,0}, QStaticText{"Hello, world!"});

        painter.drawText(10, 50, "Hello, world!");

        // QTextDocument td;
        // td.setHtml("Hello, world!");
        // td.drawContents(&painter);
    }
};

int main(int aArgc, char *aArgv[]) {
    QApplication myApplication{aArgc, aArgv};

    // QFont myFont{"Informal Roman", 12};
    // myFont.setStyleStrategy(QFont::NoAntialias);
    // myFont.setStyleStrategy(QFont::NoSubpixelAntialias);
    // QApplication::setFont(myFont);

    for (const auto myStr : QFontDatabase::families()) {
        qDebug() << myStr;
    }

    TextExample myMainWindow;
    myMainWindow.setWindowTitle("Text Example");
    myMainWindow.resize(800, 600);
    myMainWindow.show();

    return myApplication.exec();
}

我在qt6.4.0中运行这个,如果这在windows10上很重要的话
需要注意的是,它实际上可以与QPainterPath一起工作,但我宁愿避免这种情况,因为它更昂贵,而且似乎还有其他绘制文本的问题。
另一件事要注意的是,一些字体没有抗锯齿,到目前为止,我可以看到,一个很好的例子是'MS Sans Serif'。但对我来说,这是一个很好的不那么友好的警告,同样,QT也不尊重策略,使我能够为这些添加抗锯齿,

DirectWrite: CreateFontFaceFromHDC() failed (Indicates an error in an input file such as a font file.) for QFontDef(Family="MS Sans Serif", pointsize=12, pixelsize=16, styleHint=5, weight=400, stretch=100, hintingPreference=0) LOGFONT("MS Sans Serif", lfWidth=0, lfHeight=-16) dpi=144

任何帮助都将不胜感激

pb3s4cty

pb3s4cty1#

最后能够确定问题.字体策略被尊重,但在Qt 6我们有高DPI缩放不像QT 5,当然你可以通过设置环境变量QT_ENABLE_HIGHDPI_SCALING为0禁用(这也为我修复了它).然而,如果你想保持DPI缩放,这是我能够找到工作的解决方案.
它以前不工作的原因是因为文本被缩放到这个更高的分辨率DPI,并且缩放自动应用了抗锯齿。
我们需要告诉qt 6尝试根据目标windows分辨率选择字体大小。我使用的是高DPI显示器,这就是为什么我最初甚至无法看到我发布的解决方案在常规缩放显示器上工作。
只是一个警告,从阅读文档这可能不适用于OSX,但随时添加下面,如果它没有为他人着想!此解决方案适用于Windows:

class TextExample : public QMainWindow {
    void paintEvent(QPaintEvent*) final {
        QFont myFont{"Times New Roman", 16};
        myFont.setStyleStrategy(QFont::NoAntialias);

        // THIS is the key line:
        myFont.setHintingPreference(QFont::HintingPreference::PreferFullHinting);

        QPainter myPainter{this};
        myPainter.setFont(myFont);
        myPainter.drawText(10, 50, "Hello, world!");
    }
};

int main(int aArgc, char *aArgv[]) {
    QApplication myApplication{aArgc, aArgv};

    TextExample myMainWindow;
    myMainWindow.setWindowTitle("Text Example");
    myMainWindow.resize(800, 600);
    myMainWindow.show();

    return myApplication.exec();
}

我真的希望有一天这能帮助到别人,因为这给我带来了一个世界的痛苦。

相关问题