如何在Qt-Embedded中正确输出多语言文本?

3

我的目标系统是:

  • Linux 3.3.7,
  • Qt Embedded(开源版)4.8,
  • Droid字体(从fonts-droid_20111207+git-1_all.deb Debian软件包中获取,并复制到/usr/lib/fonts目录下),
  • Linux Framebuffer用于主Qt GUI应用程序,
  • 所有内容都由Buildroot软件包构建。

我的测试应用程序非常简单:只有一个对话框,在其中有几个静态的QLabel(一个用于中文,一个用于阿拉伯语,一个用于西里尔语等)。

当我在我的Linux桌面上运行它时,所有标签都显示正确。但是当它在我的目标系统上运行时,一些文本消失了。

经过一些研究,我发现了Qt框架行为上的差异:QFontDatabase类报告说我的桌面系统上只有4个Droid字体系列:

Droid Sans [unknown]
Droid Sans [monotype]
Droid Sans Mono
Droid Serif

但是同样的QFontDatabase类报告说,在我的目标系统上有许多不同的字体系列:

Droid Arabic Naskh
Droid Sans
Droid Sans Armenian
Droid Sans Ethiopic
Droid Sans Fallback
Droid Sans Georgian
Droid Sans Hebrew
Droid Sans Japanese
Droid Sans Mono
Droid Sans Thai
Droid Serif

结果是,如果我通过-fn命令行选项或在应用程序内部手动调用setFont()更改了我的应用程序的“默认”字体系列,一些文本标签会显示,而其他文本标签则不会显示(例如,当我使用“Droid Sans Hebrew”字体系列时,韩文缺失,但希伯来文/阿拉伯文正常显示)。
因此,我的问题是:在Qt嵌入式应用程序中输出多语言文本的正确方法是什么?为什么“Droid Sans”字体系列被分开了?有没有办法将它们合并在一起?
谢谢。

我正在尝试做非常类似的事情,你的Qt编译时使用了-embedded标志和-fontconfig标志吗?我认为在Qt嵌入式系统中不支持-fontconfig。 - erelender
@erelender,Qt是使用“-embedded”编译的,且未使用“-fontconfig”。但是这个问题与“字体配置”无关,请查看我的答案。 - qehgt
我明白了,我还有一个问题,你的所有字体都包含在一个ttf文件中,还是多个文件? - erelender
请问您能否发一封电子邮件给我(我的个人资料里有)?看起来您可以帮我解决我烦恼已久的问题 :) - erelender
@erelender,嗯...找不到它。 - qehgt
显示剩余7条评论
3个回答

4

我创建了一个小型的测试应用程序,从文件中加载字体,然后在GUI中使用它。

#include <QtGui>

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

    /* Load font data from file in the same directory as executable */
    QFile fontFile("BaroqueScript.ttf");
    if (!fontFile.open(QIODevice::ReadOnly)) {
        qCritical() << "failed to open font file";
    }
    QByteArray fontData = fontFile.readAll();

    /* Register font to the QFontDatabase */
    if (QFontDatabase::addApplicationFontFromData(fontData) == -1) {
        qCritical() << "failed to add a font";
    }

    /* Create font object and verify font family */
    QFont font("Baroque Script", 10, QFont::Bold);
    QFontInfo fontInfo(font);
    qDebug() << "Expected:" <<  font.family() << "Real:" << fontInfo.family();

    /* Produce GUI which uses loaded font */
    QLabel label("Hello, world");
    label.setFont(font);
    label.show();

    return app.exec();
}

尝试同时在不同的“QLabel”中使用泰语、阿拉伯语和中文文本。您会发现文本输出未被正确处理。 - qehgt
BaroqueScript.ttf 只包含 ASCII 符号的字形,所以这是可以预料的。但是,例如 Droid Sans Fallback 字体包含 43449 个字形,并且具有相当好的覆盖范围。否则,应该为具有不同字符集的标签使用不同的字体。 - divanov
这正是我尝试避免的。我不想分析文本并从一个字体文件切换到另一个字体文件。而且,这种解决方案对于混合文本也行不通。 - qehgt
备用字体虽然好用,但太丑了。我需要使用字体族来让我的应用程序看起来更好。 - qehgt
1
无法使用没有这些符号字形的字体显示所有字符集符号。实际上,在同一标签中显示多种语言的需求很少。如果应用程序中有像维基百科这样的多语言标签,可以使用bool QFontMetrics :: inFont(QChar ch)从字体池中选择适当的字体。 - divanov

2

看起来问题终于找到了解决方案。

Qt嵌入式渲染引擎存在一个错误:由于某些原因,它使用“QPF2”字体引擎(QFontEngineQPF)来呈现“破损”的脚本文本(在我的情况下是希伯来语/阿拉伯语/泰语/韩语)。

为了避免/修复这个问题,只需要在应用程序中运行QWS_NO_SHARE_FONTS=1环境变量(以及-fn "Droid Sans"命令行参数)。

之后所有语言的文本都可以正常显示,没有任何问题。


1

@qehgt,你能否提供你的CJK和阿拉伯字体文件大小?我遇到了类似的问题...问题是由于字体缓存大小的限制导致的。我认为大约为3MB。因此,增加字体缓存大小是一种可能性,或者根据所选语言动态加载字体文件。 希望这有所帮助.. :)


@srikanth-4m 如何更改字体缓存大小?顺便说一句,我们发现了一个解决此问题的方法:我们对一些语言使用Droid ttf字体和qpf字体。 - qehgt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接