HarmonyOS鸿蒙Next中qt下使用鸿蒙字体在x86和arm机器上表现不一致
HarmonyOS鸿蒙Next中qt下使用鸿蒙字体在x86和arm机器上表现不一致 如下图,在arm平台机器和x86上机器同样使用鸿蒙字体的程序截图, 在x86机器上的文字要窄一些。

代码都是同一套代码,想知道为什么会有这种差异。使用qt默认自带的字体不会有这个问题。
下面是字体初始化的代码
void Application::Initialize()
{
{
// 字体设置
QFont font;
font.setFamily(":/font/HarmonyOS_Sans_Medium.ttf");
font.setPointSize(12);
font.setWeight(QFont::Normal); // 字重
font.setItalic(false); // 斜体
font.setKerning(true); // 字距调整
font.setStyleStrategy(QFont::PreferAntialias); // 强制抗锯齿
font.setHintingPreference(QFont::PreferFullHinting); // 控制字体边缘的平滑度
// 应用全局字体
setFont(font);
}
QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, false);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
}
更多关于HarmonyOS鸿蒙Next中qt下使用鸿蒙字体在x86和arm机器上表现不一致的实战教程也可以访问 https://www.itying.com/category-93-b0.html
这个问题解决了,上面 font.setFamily(":/font/HarmonyOS_Sans_Medium.ttf"); 这种方式设置字体只能设置系统自带的字体。而指定设置资源或者路径下的ttf字体,只能使用以下方式:
int fontId = QFontDatabase::addApplicationFont(":/fonts/HarmonyOS_Sans_SC_Regular.ttf");
if (fontId != -1) {
QString family = QFontDatabase::applicationFontFamilies(fontId).at(0);
QFont font(family, 12);
application_->setFont(font);
}
所以之前的代码虽然没报错,但是其实是未成功设置鸿蒙字体。所以在不同机器下,字体表现不一致。
更多关于HarmonyOS鸿蒙Next中qt下使用鸿蒙字体在x86和arm机器上表现不一致的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
还有不同机器上屏幕分辨率,dpi也会影响最终的显示效果,这些都需要统一才能保证最终显示效果一致,
HarmonyOS Sans 本身设计差异
这个字体在不同平台的渲染结果会受 hinting 策略影响更明显,因为它是可变字重(variable font)。
如果 FreeType 在不同 CPU 架构上 fallback 到不同 hinting 方式,就会看到窄/宽的差异。
你好楼主,x86和ARM平台底层图形库的字体度量计算方式不同,可能导致同一字体在不同架构下显示宽度不同,还有鸿蒙字体可能存在针对ARM架构的优化设计,在x86未充分适配,这是我个人猜测。
另外ARM架构可能启用了NEON指令集优化路径,会影响字体缩放算法,而x86架构可能使用不同的浮点运算单元精度设置,影响字体抗锯齿效果。
ARM更依赖字体自带的Hinting信息,而x86平台可能强制应用系统级调整,setHintingPreference在不同平台对矢量字体的微调效果也是可能不同的。总而言之影响因素很多,这也是个人的猜测。。。
楼主可以试试添加字体加载状态检测:
int fontId = QFontDatabase::addApplicationFont(":/font/HarmonyOS_Sans_Medium.ttf");
if(fontId == -1) {
qWarning() << "Failed to load embedded font";
}
根据架构调整字体参数
#if defined(Q_PROCESSOR_X86)
font.setHintingPreference(QFont::PreferNoHinting);
font.setStretch(105); // 略微增加拉伸系数
#elif defined(Q_PROCESSOR_ARM)
font.setStyleStrategy(QFont::ForceIntegerMetrics);
#endif
观察真仔细,我感觉是屏幕分辨率的原因。
用“Nimbus Sans Narrow”这个字体就没有差异,用鸿蒙字体就有差异。
在HarmonyOS Next中,Qt使用鸿蒙字体时,x86与ARM架构下表现不一致,主要因字体渲染引擎和系统字体库差异导致。x86平台可能依赖通用字体渲染,而ARM平台直接调用鸿蒙原生字体接口。需检查字体文件路径、格式兼容性及Qt字体配置,确保跨架构一致性。建议统一使用鸿蒙系统字体库,并验证Qt字体加载机制。
这个问题通常是由于不同CPU架构(x86 vs ARM)上Qt字体渲染引擎的差异,特别是字体Hinting(微调)处理方式不同导致的。在x86平台上,Qt的字体渲染可能应用了更激进的水平方向Hinting来适应传统的像素网格,导致字形被轻微压缩。
关键点在于您代码中的 setHintingPreference(QFont::PreferFullHinting)。Full Hinting会为了在低分辨率下清晰可读而显著调整字形轮廓,这种调整在不同架构的渲染后端上可能不一致。
建议的排查和解决步骤:
-
修改Hinting设置:将
setHintingPreference改为QFont::PreferNoHinting或QFont::PreferVerticalHinting。这能减少渲染引擎对字形水平方向的干预,使跨平台表现更一致。font.setHintingPreference(QFont::PreferNoHinting); // 或 PreferVerticalHinting -
检查字体文件:确认嵌入资源的
HarmonyOS_Sans_Medium.ttf文件是同一版本。不同版本的字形数据可能存在细微差别。 -
验证DPI缩放:虽然您已启用高DPI缩放(
AA_EnableHighDpiScaling),但请确认两台测试机器的屏幕逻辑DPI是否相同。可以在运行时打印QScreen::logicalDotsPerInch()进行对比。不同的DPI值会影响setPointSize的实际渲染像素大小。 -
使用绝对像素尺寸:作为诊断方法,可以尝试使用
setPixelSize替代setPointSize,以消除因DPI计算差异带来的影响。 -
检查Qt平台插件:在x86和ARM设备上,Qt可能使用了不同的底层字体渲染引擎(如CoreText、DirectWrite、FreeType)。这可能导致Hinting策略的执行结果存在固有差异。
根本原因分析: 跨架构的字体渲染差异通常并非HarmonyOS Next本身的问题,而是Qt框架为了适配不同硬件和操作系统,在字体微调算法上做出的妥协。使用系统自带字体时,Qt可能采用了更统一的回退策略,因此表现一致。
通过调整Hinting偏好,通常可以显著改善或消除这种不一致性。

