QT5字体在各种平台上呈现不同

时间:2014-09-10 09:12:23

标签: windows macos qt fonts

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

我照顾:

  • 在所有平台上选择相同的字体(我提供“TTF”字体文件并将代码指向它)
  • 绘制到QImage而不是QPixmap,因为文档说QImage画家应该是平台独立的
  • 我还选择了Antialisating和TextAntialiasing提示
  • 通过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");

Bitstream Vera字体可以在fontsquirel.com上下载。

在MacOSX(左)和Win32(右)上查看结果,这些结果非常不同:

enter image description here


以下是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,右侧Windows)。白色刻度表示真正的10像素大小。

enter image description here


下面通过G_G回答我改编了代码(关于Linux?移动平台呢?这变得非常复杂......)。现在,Windows和MacOSX上的输出中的字体都是10像素,但仍然是非常不同(左边是MacOSX,右边是Windows)。

enter image description here

感谢。

3 个答案:

答案 0 :(得分:2)

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

根据: http://www.rfwilmut.clara.net/about/fonts.html

  

在Macintosh显示器上,名义分辨率为72点/英寸   (dpi),因此72像素宽的图形在概念上是1英寸   宽 - 虽然显然实际大小取决于个人   监控。但是它总是会打印一英寸宽。

     

但在Windows显示器上,分辨率(通常)为96 dpi。这个   意味着虽然图片仍然是72像素宽,但它会打印出来   在0.75英寸处。

QFont font = fontDb_->font(("Bitstream Vera Sans", "Normal", -1);
qreal screenDPI  = QApplication::primaryScreen()->physicalDotsPerInch();

#ifdef WINDOWS
qreal RENDER_DPI = 96;
#else
qreal RENDER_DPI = 72;
#endif

int pixelSize = (int)((qreal)10 * screenDPI / RENDER_DPI);
font.setPixelSize(pixelSize);

答案 1 :(得分:1)

这是因为您设置了像素大小。您需要使用setPointSize()。

来自Qt 5文档:

void QFont::setPixelSize(int pixelSize)

将字体大小设置为pixelSize像素。 使用此功能可使字体设备相关。使用setPointSize()或setPointSizeF()以独立于设备的方式设置字体大小。

另外,有关详情,请查看this帖子。出现这种差异是因为不同操作系统上的显示密度不同。我在一个OS X,Windows跨平台项目中遇到过这样的问题。


[更新]经过我的额外研究,我发现,Qt字体的当前行为只是一个错误。这就是为什么上面的解决方案不起作用的原因(适用于Qt 4) Here描述了解决此问题的不同解决方法。祝你好运!

答案 2 :(得分:-2)

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

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");