Windows QT5字体在不同平台上呈现不同

Windows QT5字体在不同平台上呈现不同,windows,macos,qt,fonts,Windows,Macos,Qt,Fonts,我想对一些自定义小部件渲染进行可复制的测试。为了做到这一点,我将它们绘制到一个QImage上,并将结果保存为PNG。与MacOSX相比,Windows上的输出确实不同 我负责: 在所有平台上选择相同的字体(我提供“TTF”字体文件并将代码指向该文件) 在QImage而不是QPixmap上绘制,正如文档所述,QImage画师应该是独立于平台的 我还选择了反序列化和文本反锯齿提示 通过QFontDatabase::font()请求字体,以便指定pointSize而不是pixelSize 我如何确

我想对一些自定义小部件渲染进行可复制的测试。为了做到这一点,我将它们绘制到一个QImage上,并将结果保存为PNG。与MacOSX相比,Windows上的输出确实不同

我负责:

  • 在所有平台上选择相同的字体(我提供“TTF”字体文件并将代码指向该文件)
  • 在QImage而不是QPixmap上绘制,正如文档所述,QImage画师应该是独立于平台的
  • 我还选择了反序列化和文本反锯齿提示
  • 通过QFontDatabase::font()请求字体,以便指定pointSize而不是pixelSize
我如何确保渲染在所有平台上都完全相同,以便我的测试运行是可复制的?换句话说,是否可能强制QT5在所有平台上使用相同的字体引擎(例如freetype)

**

我把这个问题归结于一个简单的渲染测试程序。 代码如下所示:

QFontDatabase fontDb;
fontDb.addApplicationFont(".../fonts/Vera.ttf");

QImage   result(width, height, QImage::Format_RGB32);
QPainter painter(&result);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::TextAntialiasing);


QBrush background(QColor(205, 205, 205));
painter.fillRect(0, 0, 800, 600, background);

QFont font = fontDb.font("Bitstream Vera Sans", "Normal", 10);
painter.setFont(font);

painter.setPen(QColor(0, 0, 0));
painter.drawText(10, 10, "ABCD abcd 01234567");
例如,可以在fontsquirel.com上下载Bitstream Vera字体

查看MacOSX(左)和Win32(右)上的结果,这两种情况非常不同:


下面是N1ghtLight的回答和评论,在阅读了他建议的链接后,我将代码更改为字体:

QFont font = fontDb_->font(("Bitstream Vera Sans", "Normal", -1);

qreal screenDPI  = QApplication::primaryScreen()->physicalDotsPerInch();
qreal RENDER_DPI = 72;

int pixelSize = (int)((qreal)10 * screenDPI / RENDER_DPI);
font.setPixelSize(pixelSize);
这似乎主要解决了字体大小差异很大的问题。至少在MacOSX上,字体现在正好有10像素高。在Windows上,字体呈现得更薄,也更小。我仍然迷路和困惑

这是新结果(左MacOSX,右窗口)。白色刻度表示真实的10像素大小


下面是G_G的回答,我修改了代码(Linux呢?移动平台?这变得非常复杂…)。现在,Windows和MacOSX上的输出字体都是10像素,但渲染效果仍然非常不同(仍然是MacOSX在左侧,Windows在右侧)


谢谢。

这是因为您以像素为单位设置了大小。您需要改用setPointSize()

从Qt 5文档中:

void QFont::setPixelSize(int pixelSize)
将字体大小设置为像素大小。 使用此功能将使字体设备依赖于。使用setPointSize()或setPointSizeF()以独立于设备的方式设置字体大小

此外,有关更多信息,您可以查看帖子。这种差异是由于不同操作系统上的显示密度不同造成的。我自己在一个OSX、Windows跨平台项目中也遇到过这样的问题


[更新]经过我的进一步研究,我发现Qt字体的当前行为只是一个bug。这就是上面的解决方案不起作用的原因(它适用于Qt4)
描述了解决此问题的不同解决方法。祝你好运

对于Windows,渲染DPI变量应为96;对于OSX,渲染DPI变量应为72

根据:

在Macintosh显示器上,名义分辨率为每英寸72点 (dpi),因此72像素宽的图形在概念上为1英寸 宽-虽然很明显实际尺寸取决于个人 班长然而,它总是打印一英寸宽

但在Windows显示器上,分辨率(通常)为96 dpi。这 这意味着,尽管图片仍有72像素宽,但仍将打印出来 0.75英寸


你可以试试这个。这将生成一个包含您将要编写的文本的图像。我正在使用这个代码

QPixmap photo;
QFont qfont;
QPainter painter;
QString txt;

QImage img(x,y,QImage::Format_RGB32);

painter.begin(&img);
img.fill(0xffffffff);
painter.drawPixmap(0,0,x,y,photo);

qfont.setFamily("Sampige");
qfont.setPixelSize(28);
painter.setFont(qfont);
txt = QString::fromUtf8("ನಮಸ್ಕಾರ");
painter.drawText(1,26,txt);
painter.end();
img.save("abcd.jpg");

请注意,将以下内容添加到qt.conf不会改变windows上的任何内容:“[Platforms]WindowsArguments=fontengine=freetype”这也与以下内容有关:没有令人满意的答案,您的mac是视网膜型?没有,它是MacMini。此外,根据QT文档,渲染到QImage应该与屏幕分辨率、图形卡等无关。Alex:事实上,本周末我只使用Freetype实现了渲染。结果是100%准确,100%可跨平台复制…我希望你是真的,但没有。我更改了代码,字体访问现在通过QFontDatabase::font(fontFamily,fontStyle,10)实现。这里的10值是“点大小”,而不是“像素大小”。输出仍然不同,上面的屏幕截图仍然适用。我编辑了上面的代码以反映这一点。调用“setPointSize”如何?Qt文档建议准确地调用它。我刚刚在OSX和Windows上检查了自己,看起来字体真的不同。也许,这是某种缺陷,或者需要一些额外的全局设置。在任何情况下,您的初始源代码都包含对Qt文档的违反,这是导致此类问题的100%原因,例如Qt 4。这是另一个因素。埃里克,在我的额外研究之后,我更新了我的答案。另外,在人们发现问题的真正问题并在答案中做了标记后,更改问题中的初始源代码不是一个好的做法,因为我的答案开始时看起来很奇怪。你能详细说明你的答案吗,也许可以用示例代码?特别是我在问题中添加了更多的代码,用于调整屏幕DPI的像素大小。谢谢。我更新了我的问题,它仍然不起作用。@Eric:在WINDOWS下编译时应该定义WINDOWS,否则编译器将始终输入#else条件,实际上恢复到原始代码当然。我在您的代码中用WIN32更改了WINDOWS,以确保使用96 DPI。谢谢。你买了什么?您可以发布新的渲染图像吗?如果你完全没有抓住要点,继续调查这个问题会很有用。我的示例代码已经演示了如何将文本保存到图像中。但是,不同平台(MacOSX/Windows)的结果并不一致。
QPixmap photo;
QFont qfont;
QPainter painter;
QString txt;

QImage img(x,y,QImage::Format_RGB32);

painter.begin(&img);
img.fill(0xffffffff);
painter.drawPixmap(0,0,x,y,photo);

qfont.setFamily("Sampige");
qfont.setPixelSize(28);
painter.setFont(qfont);
txt = QString::fromUtf8("ನಮಸ್ಕಾರ");
painter.drawText(1,26,txt);
painter.end();
img.save("abcd.jpg");