Qt5.6.1如何使用qpf2字体

1 篇文章 0 订阅

最近在移植Qt到一个商用的小众系统上,Qt版本是Qt5.6.1,Qt是不支持这个系统的,在移植过程中遇到了很多的问题,这里对字体移植遇的问题进行一下记录。(这个办法是可以使用qpf2字体的,但是是不是最好的办法还不知道,希望可以帮助到需要的人,也希望有人一起讨论)

1.问题:

  首先是报找不到字体,当字体的路径设置正确后。程序在调用setText相关方法的时候,整个系统就会dump掉,这个系统经常用dump,内存分配上可能有一些问题。如果字体的路径设置不正确系统倒是可以正确运行,最后经过查找代码和参考网上的经验决定使用qpf字体(优点就是省去了Qt解析字体这个过程,占用内存小(我怀疑系统dump是存上有问题),缺点是qpf字体字号大小是固定的,他是一个二进制的文件)。

2.进展:

  Qt  Help文档说明Qt是支持qpf字体的,在Qt4版本之后支持qpf2字体。把字库下的所有字体删除只留下qpf2字体还是没有办法显示(在PC机上和目标板上尝试都是不可以的)。在网上查到资料说是Qt5虽然说是支持qpf2,但是实际上是个BUG,实现根本不支持(我查看代码后发现,是一个虚函数,当调用子类的方法时就不支持qpf2,当调用父类的方法时就支持qpf2,下面会说一下这个问题),没有找到解决办法。

于是查看源码和PC跟踪程序执行过程。

3.解决:

  在字体相关初始化的过程中会调用qt-everywhere-opensource-src-5.6.1\qtbase\src\platformsupport\fontdatabases\fontconfig\qfontconfigdatabase.cpp文件中的

initializeDb()方法

源码如下:

static void initializeDb()

{

   QFontDatabasePrivate *db = privateDb();

 

   // init by asking for the platformfontdb for the first time or afterinvalidation

   if (!db->count)

       QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();

 

   if (db->reregisterAppFonts) {

       for (int i = 0; i < db->applicationFonts.count(); i++) {

           if (!db->applicationFonts.at(i).families.isEmpty())

               registerFont(&db->applicationFonts[i]);

       }

       db->reregisterAppFonts = false;

    }

}

populateFontDatabase()这个方法有两处实现分别见下面的源码,而initializeDb()方法中调用的实际是populateFontDatabase();方法实现际调用的是QBasicFontDatabase类中实现的。

qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp中

qtbase/src/gui/text/qplatformfontdatabase.cpp中

 

在类QBasicFontDatabase定义中可以看到QBasicFontDatabase是QPlatformFontDatabase子类

class QBasicFontDatabase : publicQPlatformFontDatabase

{

public:

//   void populateFontDatabase() Q_DECL_OVERRIDE;  //change on_ose

/*   QFontEngine *fontEngine(const QFontDef &fontDef, void *handle)Q_DECL_OVERRIDE;

   QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize,QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;

   QStringList addApplicationFont(const QByteArray &fontData, constQString &fileName) Q_DECL_OVERRIDE;

   void releaseHandle(void *handle) Q_DECL_OVERRIDE;

 

   static QStringList addTTFile(const QByteArray &fontData, constQByteArray &file);

*/

};

下面给出QBasicFontDatabase和QPlatformFontDatabase类中populateFontDatabase()方法的实现:

1.

voidQBasicFontDatabase::populateFontDatabase()

{

   QString fontpath = fontDir();

   QDir dir(fontpath);

 

   if (!dir.exists()) {

       qWarning("QFontDatabase: Cannot find font directory %s - is Qtinstalled correctly?",

               qPrintable(fontpath));

       return;

    }

 

   QStringList nameFilters;

   nameFilters << QLatin1String("*.ttf")

                << QLatin1String("*.ttc")

                <<QLatin1String("*.pfa")

                <<QLatin1String("*.pfb")

                <<QLatin1String("*.otf");

 

   foreach (const QFileInfo &fi, dir.entryInfoList(nameFilters,QDir::Files)) {

       const QByteArray file = QFile::encodeName(fi.absoluteFilePath());

       QBasicFontDatabase::addTTFile(QByteArray(), file);

    }

}

2.

voidQPlatformFontDatabase::populateFontDatabase()

{

   QString fontpath = fontDir();

   if(!QFile::exists(fontpath)) {

       qWarning("QFontDatabase: Cannot find font directory '%s' - is Qtinstalled correctly?",

                qPrintable(QDir::toNativeSeparators(fontpath)));

       return;

    }

 

   QDir dir(fontpath);

   dir.setNameFilters(QStringList() <<QLatin1String("*.qpf2"));

   dir.refresh();

   for (int i = 0; i < int(dir.count()); ++i) {

       const QByteArray fileName =QFile::encodeName(dir.absoluteFilePath(dir[i]));

       QFile file(QString::fromLocal8Bit(fileName));

       if (file.open(QFile::ReadOnly)) {

           const QByteArray fileData = file.readAll();

           QByteArray *fileDataPtr = new QByteArray(fileData);

           registerQPF2Font(fileData, fileDataPtr);

       }

    }

}

从两个类的方法中可以看到QBasicFontDatabase::populateFontDatabase()中是在对ttf等字体进行加载。而QPlatformFontDatabase::populateFontDatabase()中是对qpf2字体进行加载。所以这就解释了为什么Qt5.6.1不能使用qpf2字体。这个加载qpf2字体的方法没有被调用啊。肯定怎么也支持不了qpf2。所以果断的将QBasicFontDatabase这个类相关的文件注释掉(这样程序在运行的时候就自动调用了父类也就是QPlatformFontDatabase::populateFontDatabase()方法,这个方法是个虚函数)。这里包括qbasicfontdatabase_p.h中QBasicFontDatabase类的定义和qbasicfontdatabase.cpp整个文件的内容(#if 0 .......#endif即可)。

重新编译Qt源码,将qpf2文件放在字体目录下(lib/fonts/dejavu_sans_11_50.qpf2)。开机运行生程序可显示字符不dump掉了。剩下的工作就是制作字体了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt 5.6.1是一个跨平台的应用程序开发框架,可以帮助开发人员轻松创建图形化界面和跨平台应用程序。安装Qt 5.6.1需要以下步骤: 1. 下载安装包:在Qt官方网站上找到适用于你操作系统的Qt 5.6.1安装包,并下载到本地。 2. 运行安装程序:找到下载的安装包文件,双击运行安装程序。根据提示选择安装路径和组件。 3. 安装依赖项:根据你的操作系统,在安装过程中可能需要安装一些依赖项。安装程序会自动检测并提示你是否安装缺少的依赖项。 4. 设置环境变量:安装完成后,为了在命令行中能够使用Qt命令行工具,需要将Qt的安装目录添加到系统的环境变量中。 5. 启动Qt Creator:安装完成后,你可以启动Qt Creator,这是一个集成开发环境(IDE),它可以帮助你开发和调试Qt应用程序。 6. 创建项目:在Qt Creator中,你可以选择新建一个项目,选择你想要的项目模板和目标平台,然后按照向导完成项目的创建。 7. 编写代码:使用Qt Creator的编辑器,你可以开始编写Qt应用程序的代码。从创建用户界面到处理逻辑,Qt提供了丰富的库和功能。 8. 调试和构建:在Qt Creator中,你可以使用调试器来调试你的应用程序,并使用构建工具来生成可执行文件或者库文件。 通过这些步骤,你可以成功安装并开始使用Qt 5.6.1来开发你自己的应用程序。记得在需要的时候查看Qt的文档和示例代码,以便更好地理解和使用Qt的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值