根据Qfont中的family 得到字体文件的路径和文件名称

2023-05-16

转载:https://www.zhihu.com/question/25834024
根据Qfont中的family 得到字体文件的路径和文件名称;

源码:
//头文件
#include
#include
#include <windows.h>
#include
#include
#include
#include

源码:

std::string GetFontPathFromQFont::GetSystemFontFile(const std::string &faceName) {
	static const LPWSTR fontRegistryPath = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
    HKEY hKey;
    LONG result;
    std::wstring wsFaceName(faceName.begin(), faceName.end());
  
    // Open Windows font registry key
    result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fontRegistryPath, 0, KEY_READ, &hKey);
    if (result != ERROR_SUCCESS) {
        return "";
    }

    DWORD maxValueNameSize, maxValueDataSize;
    result = RegQueryInfoKey(hKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &maxValueNameSize, &maxValueDataSize, nullptr, nullptr);
    if (result != ERROR_SUCCESS) {
        return "";
    }

    DWORD valueIndex = 0;
    LPWSTR valueName = new WCHAR[maxValueNameSize];
    LPBYTE valueData = new BYTE[maxValueDataSize];
    DWORD valueNameSize, valueDataSize, valueType;
    std::wstring wsFontFile;

    // Look for a matching font name
    do {

        wsFontFile.clear();
        valueDataSize = maxValueDataSize;
        valueNameSize = maxValueNameSize;

        result = RegEnumValue(hKey, valueIndex, valueName, &valueNameSize, nullptr, &valueType, valueData, &valueDataSize);

        valueIndex++;

        if (result != ERROR_SUCCESS || valueType != REG_SZ) {
            continue;
        }

        std::wstring wsValueName(valueName, valueNameSize);

        // Found a match
        if (_wcsnicmp(wsFaceName.c_str(), wsValueName.c_str(), wsFaceName.length()) == 0) {

            wsFontFile.assign((LPWSTR)valueData, valueDataSize);
            break;
        }
    }
    while (result != ERROR_NO_MORE_ITEMS);

    delete[] valueName;
    delete[] valueData;

    RegCloseKey(hKey);

    if (wsFontFile.empty()) {
        return "";
    }

    // Build full font file path
    WCHAR winDir[MAX_PATH];
    GetWindowsDirectory(winDir, MAX_PATH);

    std::wstringstream ss;
    ss << winDir << "\\Fonts\\" << wsFontFile;
    wsFontFile = ss.str();

    return std::string(wsFontFile.begin(), wsFontFile.end());
}

```cpp
#define MAKE_TAG(ch1, ch2, ch3, ch4) (\
    (((quint32)(ch4)) << 24) | \
    (((quint32)(ch3)) << 16) | \
    (((quint32)(ch2)) << 8) | \
    ((quint32)(ch1)) \
    )

quint16 GetFontPathFromQFont::getUShort(const unsigned char *p)
{
    quint16 val;
    val = static_cast<quint16>(*p++ << 8);
    val |= *p;

    return val;
}
QString GetFontPathFromQFont::getEnglishName(const uchar *table, quint32 bytes)
{
    QString i18n_name;
    enum {
        NameRecordSize = 12,
        FamilyId = 1,
        MS_LangIdEnglish = 0x009
    };

    // get the name table
    quint16 count;
    quint16 string_offset;
    const unsigned char *names;

    int microsoft_id = -1;
    int apple_id = -1;
    int unicode_id = -1;

    if(getUShort(table) != 0)
        goto error;

    count = getUShort(table+2);
    string_offset = getUShort(table+4);
    names = table + 6;

    if(string_offset >= bytes || 6 + count*NameRecordSize > string_offset)
        goto error;

    for(int i = 0; i < count; ++i) {
        // search for the correct name entry

        quint16 platform_id = getUShort(names + i*NameRecordSize);
        quint16 encoding_id = getUShort(names + 2 + i*NameRecordSize);
        quint16 language_id = getUShort(names + 4 + i*NameRecordSize);
        quint16 name_id = getUShort(names + 6 + i*NameRecordSize);

        if(name_id != FamilyId)
            continue;

        enum {
            PlatformId_Unicode = 0,
            PlatformId_Apple = 1,
            PlatformId_Microsoft = 3
        };

        quint16 length = getUShort(names + 8 + i*NameRecordSize);
        quint16 offset = getUShort(names + 10 + i*NameRecordSize);
        if(DWORD(string_offset + offset + length) >= bytes)
            continue;

        if ((platform_id == PlatformId_Microsoft
            && (encoding_id == 0 || encoding_id == 1))
            && (language_id & 0x3ff) == MS_LangIdEnglish
            && microsoft_id == -1)
            microsoft_id = i;
        // not sure if encoding id 4 for Unicode is utf16 or ucs4...
        else if(platform_id == PlatformId_Unicode && encoding_id < 4 && unicode_id == -1)
            unicode_id = i;
        else if(platform_id == PlatformId_Apple && encoding_id == 0 && language_id == 0)
            apple_id = i;
    }
    {
        bool unicode = false;
        int id = -1;
        if(microsoft_id != -1) {
            id = microsoft_id;
            unicode = true;
        } else if(apple_id != -1) {
            id = apple_id;
            unicode = false;
        } else if (unicode_id != -1) {
            id = unicode_id;
            unicode = true;
        }
        if(id != -1) {
            quint16 length = getUShort(names + 8 + id*NameRecordSize);
            quint16 offset = getUShort(names + 10 + id*NameRecordSize);
            if(unicode) {
                // utf16

                length /= 2;
                i18n_name.resize(length);
                QChar *uc = (QChar *) i18n_name.unicode();
                const unsigned char *string = table + string_offset + offset;
                for(int i = 0; i < length; ++i)
                    uc[i] = getUShort(string + 2*i);
            } else {
                // Apple Roman
                i18n_name.resize(length);
                QChar *uc = (QChar *) i18n_name.unicode();
                const unsigned char *string = table + string_offset + offset;
                for(int i = 0; i < length; ++i)
                    uc[i] = QLatin1Char(string[i]);
            }
        }
    }
error:
    //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data());
    return i18n_name;
}

QString GetFontPathFromQFont::getEnglishName(const QString &familyName)
{
    QString i18n_name;

    HDC hdc = GetDC( nullptr );
    LOGFONT lf;
    memset(&lf, 0, sizeof(LOGFONT));
    memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t));
    lf.lfCharSet = DEFAULT_CHARSET;
    HFONT hfont = CreateFontIndirect(&lf);
    if(!hfont) {
        ReleaseDC(nullptr, hdc);
        return QString();
    }

    HGDIOBJ oldobj = SelectObject( hdc, hfont );

    const DWORD name_tag = MAKE_TAG( 'n', 'a', 'm', 'e' );

    // get the name table
    unsigned char *table = nullptr;

    DWORD bytes = GetFontData( hdc, name_tag, 0, nullptr, 0 );
    if ( bytes == GDI_ERROR ) {
        // ### Unused variable
        /* int err = GetLastError(); */
        goto error;
    }

    table = new unsigned char[bytes];
    GetFontData(hdc, name_tag, 0, table, bytes);
    if ( bytes == GDI_ERROR )
        goto error;

    i18n_name = getEnglishName(table, bytes);
error:
    delete [] table;
    SelectObject( hdc, oldobj );
    DeleteObject( hfont );
    ReleaseDC( nullptr, hdc );

    //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data());
    return i18n_name;
}
使用方法:
std::string path = GetFontPathFromQFont::GetSystemFontFile(GetFontPathFromQFont::getEnglishName(font.family()).toStdString());
    QString fontPath = QString().fromLocal8Bit(path.c_str());//根据字体得到字体文件名和路径

结果输入 根据QFontComboBox 选择字体宋体
结果输出 C:\\Windows\\Fonts\\simsun.ttc
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据Qfont中的family 得到字体文件的路径和文件名称 的相关文章

  • 宝塔配置Workerman

    map span class token variable http upgrade span span class token variable connection upgrade span span class token punct
  • px4飞控和机载电脑通信:机载电脑接收飞控的自定义px4消息

    机载电脑接收飞控的自定义px4消息 mavros功能包能够实现px4飞控和机载电脑之间的实时通信 而对于大部分的消息通信mavros都已经有相应接口可以调用 xff0c 例如 xff1a 位置 期望位置 速度 四元素等消息都可以通过C 43
  • px4飞控和机载电脑通信:飞控接收机载电脑的自定义mavlink消息

    前面一篇讲了机载电脑怎么接受飞控的px4消息 这一篇讲解如何飞控怎么接收从机载电脑传过来的消息 分成两部分 机载电脑发送消息 飞控接收消息 pixhawk版本 pixhawk4 px4版本 1 11 2 ros版本 1 14 10 机载电脑
  • 多无人机通信-路由器实现

    多无人机通信 多无人机之间相互通信是实现编队飞行的基础 而想要实现通信就需要组建网络 在网络之间实现数据信息的互相传输 按结构分成两大类 中心节点网络和无中心节点网络 我们这里所用的路由器就是中心节点网络 所有的数据的传输都要经过中心节点
  • js做文件分片上传

    js做文件分片上传 分片上传视频 xff0c 图片 xff0c 音频 xff0c 转base64 64 Layout 61 null lt DOCTYPE html gt lt html gt lt head gt lt meta name
  • 锐捷交换机基本配置命令

    锐捷交换机基本配置命令 锐捷交换机 xff0c 忘记colsole口的en密码 xff0c 重启交换机 xff0c 立即按ctrl 43 c xff0c 进入bootloader 菜单 xff0c 再按ctrl 43 q xff0c 然后输
  • 驱动设计思想(机制、策略、分离、分层)

    1 机制和策略 1 机制就是提供什么功能 xff0c 策略就是怎么使用这些功能 在编写驱动时需要在编程时间和驱动的灵活性之间取一个可接受的折中 xff0c 驱动提供机制 xff0c 尽量不提供策略 xff0c 策略让上层应用去做 2 机制和
  • debian重启没办法进入图形界面

    在遇到重启有时候没办法进入图形界面的情况下 xff0c 你可以考虑是自己电脑或者服务器显卡的问题 xff0c 如果你进入了命令行的界面 xff0c 执行 etc init d kdm restart 可以重新启动图形界面的话那么就可以肯定时
  • linux线程详解:线程概念、线程调度、线程安全、线程模型

    1 线程与进程的区别 1 线程是轻量级的进程 xff0c 是程序执行流的最小单位 xff1b 2 进程是资源分配的最小单位 xff0c 线程是调度的最小单位 xff1b 3 进程可以创建线程 xff0c 线程不可以创建进程 xff1b 4
  • ARM架构的中断机制详解(S5PV210芯片)

    1 中断介绍 1 中断是指计算机运行过程中 xff0c 出现某些意外情况需主机干预时 xff0c 机器能自动停止正在运行的程序并转入处理新情况的程序 xff0c 处理完毕后又返回原被暂停的程序继续运行 2 中断是为了实现宏观上的并发 比如我
  • USB接口WIFI(MT7601芯片)的驱动源码移植过程详解(驱动源码编译、wpa_supplicant工具交叉编译、文件系统移植)

    1 MT7601的移植步骤 1 确认你的WT7601网卡硬件是正常的 xff1b 2 修改驱动源码 xff0c 依赖内核源码树编译并加载 xff1b 3 交叉编译wpa supplicant工具 xff0c 移植到根文件系统里 xff1b
  • 时钟芯片DS1302时序分析、读写代码解析

    1 DS1302芯片原理图分析 引脚名称功能X1 X2外接32 768kHz 晶振 xff0c 用于内部计时SCLK和主控通信的时钟线I O数据输入输出引脚CE使能引脚VCC1接电池供电 xff0c 保证主板掉电时间能继续走VCC2主板的电
  • 服务器重启后vncserver无法启动、连接不上问题解决

    解决方案 xff1a 1 终端输入 xff1a vncserver xff0c 那么可能出现如下结果 xff1a root 64 hadoop vncserver Warning hadoop 1 is taken because of t
  • 课堂笔记之大数据技术基础——NoSQL数据库

    本文概要 NoSQL与关系数据库的比较NoSQL的四大类型 三大基石NoSQL和NewSQL数据库的区别文档数据库MongoDB编程实践 一 NoSQL概述 NoSQL 61 Not Only SQL 关系型数据库不可能被完全取代 xff0
  • ros 安装及卸载 gazebo7/8/9,gazebo版本升级与降级

    相关安装 xff1a ros python3 tf2参考他人博客 xff1a gazebo 7 0 升级到7 15 1 rqt sudo apt get install ros kinetic rqt sudo apt get instal
  • ST-LINK 到 SWD接线图

    1 ST LINK的外形图如下图所示 xff1a 2 接口引脚顺序定义如下图所示 xff0c 注意缺口位置 3 具体引脚定义如下图所示 4 ST LINK 到 SWD接线 SWD接口一般4个引脚 xff0c 分别为 xff1a 电源正 TC
  • MSCKF-vio源码阅读

    作为一个菜狗来说 xff0c 一开始弄明白kf ekf等滤波方法实属不易 xff0c 但是一旦理解原理之后再发散到基于滤波的状态估计方法 xff0c 学习起来就会事半功倍 xff0c 就像导航包中的robot pose ekf xff0c
  • R3Live系列学习(二)FAST-LIO源码阅读

    在上一篇我们提到 xff0c livox雷达给业界内的3D激光领域提供了一大补充 xff0c 而loam livox在温柔的使用下表现也还不错 xff0c 但在比较颠簸激烈的环境下也难以维持高精度 xff0c 因此lidar与imu的结合使
  • mkdir -m 777 tt 创建777属性的文件

    mkdir m 777 tt 创建777属性的文件 转载于 https www cnblogs com todayORtomorrow p 10486514 html
  • 妄图用多线程控制ROS的消息回调函数的输出-_-!

    今天需要用一个标志位来决定回调函数是否执行 xff0c 那这边先写一个chatter的publish xff0c 10Hz外发 xff1b 这边准备额外多一个线程控制唤醒回调函数 首先在接收节点程序中 xff0c 写一个互斥锁和条件变量 x

随机推荐

  • 韦东山:机会总是留给有准备的人(转)

    最近电子发烧友 xff08 以下称 39 发烧友 39 xff09 采访了韦东山老师 xff0c 本文是采访原稿 xff0c 展示出来让大家更深入了解韦老师的同时也进一步学习嵌入式Linux经验 机会总是留给有准备的人 发烧友 为什么要学习
  • MYSQL:Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column

    使用Qt5 11 0运行代码时 xff0c 在对表进行操作时出该错误 xff0c 报错为 xff1a Expression 2 of SELECT list is not in GROUP BY clause and contains no
  • Ubuntu 20.04 搜狗输入法安裝

    本文基于 解决Ubuntu 18 04中文输入法的问题 xff0c 安装搜狗拼音 修改 参考 ubuntu 20 04 安装好搜狗输入法无法输入中文 xff0c 只能输入英文的问题 xff0c 因为没有安装依赖 如果本篇还解决不了问题 xf
  • www服务

    www服务 1 概述 1 1 WWW服务简介 www服务全称为World Wide Web xff0c 常称为Web xff0c 中文译为 万维网 它是目前互联网上最受用户欢迎的信息服务形式 HTTP协议的WWW服务应用的默认端口为80 x
  • NUC11 PAHi5 拆机及清理灰尘

    这个NUC买了两年了 xff0c 现在正值春天 xff0c 温度还算适中 xff0c 20度左右 xff0c NUC就挂了两个下载任务 xff0c 开了网页 xff0c 风扇就狂转不停 xff0c 一查看cpu温度达到了70度 xff0c
  • 华为云服务器使用教程

    华为云服务器初始化 账户密码初始化远程登录的问题命令行界面登录文件传输图形界面win10的远程桌面登录centos6 账户 账户根据你选择的服务器的系统来定 xff0c 如果是Linux则是root xff0c 如果是windows则是ad
  • 一劳永逸解决Matplotlib中文和负号显示错误并给出RuntimeWarning的问题

    出错情况 xff1a 提示 xff1a RuntimeWarning Glyph XXXXX missing from current font font set text s 0 0 flags 61 flags 同时中文 负号以方框代替
  • 使用Python实现二分图的KM算法在出租车订单匹配上的应用

    1 需求 想要使用Python实现一个出租车仿真环境 xff0c 其中每个时间窗口内产生的request及其周围的taxi满足一个二分图的关系 原本计划request与taxi之间的匹配按照接客时间权值最小为目标进行匹配 xff0c 但是后
  • 人脸识别Haar算法总结

    参考https blog csdn net zhangbijun1230 article details 81676792
  • 【转帖】【详细】Notepad++使用心得和特色功能介绍 -> notepad/ultraedit的最好的替代品...

    notepad 43 43 简介 Notepad 43 43 是旨在替代Windows默认的notepad而生 xff0c 比notepad的功能强大很多很多 Notepad 43 43 有两个版本 xff0c 一个是ANSI版本 xff0
  • stm32--工程结构的简单理解

    作为一个新手入门stm32的同学 xff0c 我也就做了一个比较简单的工程 xff0c 但是感觉自己并没有对这个stme32有一个比较好的理解 xff0c 因此 xff0c 由于工作原因 xff0c 需要帮别人调试程序 xff0c 在移植工
  • FreeRTOS移植STM32

    第一步 xff1a FreeRTOS官网 https www freertos org https www freertos org 第二步 xff1a OS移植文件 复制 FreeRTOSv202104 00 FreeRTOS Sourc
  • freeOS-----primask faultmask basepri中断屏蔽寄存器

    primask暂时屏蔽中断寄存器 在许多应用中 需要暂时屏蔽所有的中断一执行一些对时序要求严格的任务 这个时候就 可以使用 PRIMASK 寄存器 PRIMASK 用于禁止除 复位 NMI 不可屏蔽中断 和 HardFalut 硬故障寄存器
  • freeOS快速笔记-----任务4种状态

    运行态 当一个任务正在运行时 那么就说这个任务处于运行态 处于运行态的任务就是当前正在 使用处理器的任务 如果使用的是单核处理器的话那么不管在任何时刻永远都只有一个任务处于运行态 就绪态 处于就绪态的任务是那些已经准备就绪 这些任务没有被阻
  • freeOS笔记-----列表与列表项

    xff08 2 xff09 uxNumberOfItems 用来记录列表中列表项的数量 xff08 3 xff09 pxIndex 用来记录当前列表项索引号 用于遍历列表 xff08 4 xff09 列表中最后一个列表项 用来表示列表结束
  • FreeRTOS快速笔记————队列

    队列 xff08 任务之间 全局变量 xff09 在实际的应用中 常常会遇到一个任务或者中断服务需要和另外一个任务进行 沟通交流 这个 沟通交流 的过程其实就是消息传递的过程 在没有操作系统的时候两个应用程序进行 消息传递一般使用全局变量的
  • FreeRTOS快速笔记——信号量

    信号量的阻塞时间 单位是系统的节拍周期configTICK RATE HZ 为100 xff0c 则系统节拍时钟周期为10ms xff0c 设置0就是不等待 xff0c 设置1 无限就是按时钟节拍算时间 xff0c 设置portMAX DE
  • Python获取Excel中超链接并下载至本地

    在这一任务的处理中 xff0c 我是用的是 xlrd模块 xff0c 它是用来读取Excel表格数据的模块 特别注意 xff1a 高版本的xlrd目前去除了对xlsx格式的支持 xff0c 仅支持 xls格式 xlrd biffh XLRD
  • MATLAB:梯度下降法求解一元和多元函数极小值和极大值

    梯度下降法 xff0c 顾名思义即通过梯度下降的方法 对于一个函数而言 xff0c 梯度是一个向量 xff0c 方向是表示函数值增长最快的方向 xff0c 而大小则表示该方向的导数 下面展示了用梯度下降法求解一元函数的MATLAB代码 xf
  • 根据Qfont中的family 得到字体文件的路径和文件名称

    转载 xff1a https www zhihu com question 25834024 根据Qfont中的family 得到字体文件的路径和文件名称 xff1b 源码 xff1a 头文件 include include include