QT从字体名获取字库文件路径(从宋体获取到simsun.ttc)

2023-05-16

MFC版本的从字体名获取字库文件路径点击此处

最近弄的一份项目需要裁剪ttf字库,故需要用到此功能!

用了几年QT,个人感觉类库是非常强大的!

QT相比VS的话亮点在开源的类库非常的丰富,几乎无所不能的覆盖到位,以及在大型项目中能轻松实现多语言功能!

唯一美中不足的就是他的gcc开发包非常蛋疼,一旦遇到崩溃闪退bug非常难找,有些根本断不到点,甚至切换成QT+VS+DMP都无法定位的!

------------------------------------------------------------------------------------------------------------

从VC6或VS目录拷贝一份user32.lib与gdi32.lib

在pro文件加两行

LIB += user32.lib

LIB += gdi32.lib

#include <windows.h>
#include <sstream>
#include <QApplication>
#include <QSettings>
#include <QDebug>
#include <QFont>
#include <QFontInfo>
#include <QFontComboBox>
#include <QWidget>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QTime>
#include <QDir>

// Get system font file path
std::string 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, 0, 0, 0, 0, 0, 0, 0, &maxValueNameSize, &maxValueDataSize, 0, 0);
	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, 0, &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());
}

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

static inline quint16 getUShort(const unsigned char *p)
{
	quint16 val;
	val = *p++ << 8;
	val |= *p;

	return val;
}

static QString 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;
}

static QString getEnglishName(const QString &familyName)
{
	QString i18n_name;

	HDC hdc = GetDC( 0 );
	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(0, 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 = 0;

	DWORD bytes = GetFontData( hdc, name_tag, 0, 0, 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( 0, hdc );

	//qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data());
	return i18n_name;
}


class TextEdit : public QTextEdit
{
public:
	TextEdit()
	{
		startTimer(1000);
		setReadOnly(true);
	}

	void timerEvent(QTimerEvent *)
	{
		QFont font = currentFont();
		std::string path = GetSystemFontFile(getEnglishName(font.family()).toStdString());
		setText(QString().fromLocal8Bit(path.c_str()));
	}
};

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

	QWidget widget;
	QFontComboBox fontCombb;
	TextEdit textEdit;
	QVBoxLayout layout;
	QObject::connect(&fontCombb, SIGNAL(currentFontChanged(const QFont&)), &textEdit, SLOT(setCurrentFont(const QFont&)));
	layout.addWidget(&fontCombb);
	layout.addWidget(&textEdit);
	widget.setLayout(&layout);
	widget.show();

    return app.exec();
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT从字体名获取字库文件路径(从宋体获取到simsun.ttc) 的相关文章

  • 【深度学习】Yolov3详解笔记及Pytorch代码

    Yolov3详解笔记及Pytorch代码 预测部分网络结构backbone xff1a Darknet 53output预测结果的解码 训练部分计算loss所需参数pred是什么target是什么loss的计算过程 预测部分 网络结构 DB
  • 【深度学习】各种卷积的理解笔记(2D,3D,1x1,可分离卷积)

    卷积 1 2D卷积单通道版本多通道版本 2 3D卷积3 1x1卷积作用应用 4 卷积算法5 可分离卷积空间可分离卷积深度可分离卷积 1 2D卷积 卷积的目的是从输入中提取有用的特征 在图像处理中 xff0c 卷积可以选择多种不同的滤波器 每
  • 【深度学习】(2+1)D模型框架结构笔记

    xff08 2 43 1 xff09 D 模型框架结构笔记 SpatioTemporalConv模块结构SpatioTemporalResBlock模块结构SpatioTemporalResLayer模块结构2Plus1DNet Spati
  • 【机器学习】LR回归(逻辑回归)和softmax回归

    LR回归 xff08 逻辑回归 xff09 和softmax回归 1 LR回归Logistic回归的函数形式Logistic回归的损失函数Logistic回归的梯度下降法Logistic回归防止过拟合Multinomial Logistic
  • 【深度学习】时间注意力模块与空间注意力模块

    注意力模块 通道 xff08 时间 xff09 注意力模块空间注意力模块 通道 xff08 时间 xff09 注意力模块 为了汇总空间特征 xff0c 作者采用了全局平均池化和最大池化两种方式来分别利用不同的信息 输入是一个 H W C 的
  • 【机器学习】机器学习与统计分布的关系

    这里写目录标题 1 常见的统计学分布1 xff09 离散分布a 伯努利分布b 二项分布c 泊松分布 2 xff09 连续分布a 正态分布 xff08 高斯分布 xff09 b 均匀分布 为什么我们喜欢用 sigmoid 这类 S 型非线性变
  • AKKA入门

    1 Guardian java package com example demo import akka actor typed javadsl ActorContext import akka actor typed ActorRef i
  • 【深度学习】深入理解Batch Normalization批标准化

    Batch Normalization 1 Internal Covariate Shift 问题2 BatchNorm的本质思想1 xff09 函数图像说明2 xff09 算法3 xff09 引入参数恢复表达能力4 xff09 公式 3
  • Autolabelimg自动标注工具

    目录 前言 一 工具原理和功能 1 原理 2 功能列表 二 实战 1 下载与安装 2 配置环境 3 开始使用 4 导入模型 5 选择标注类别 6 进行自动标注 三 总结 前言 在做机器视觉有监督方面 通常会面对很多数据集 xff0c 然后去
  • anchor base,anchor free和基于分割的图像检测

    目录 1 anchor base 2 anchor free 3 基于分割 reference 1 anchor base 什么是anchor based的目标检测方法呢 如果要让你定一个规则去一个图片上框一个物体 xff0c 你会怎么做呢
  • 我的2013:从北京到石家庄的软件开发历程

    记得是正月初八那天早上离开了老家 xff0c 坐上了开往北京的大巴车去北京准备新 的一年的奋斗 xff0c 车票120元了 涨价了20 xff0c 而且还没有地方报销去了 gt lt 因为年底的时候已经离职了 考虑到各公司部门人员 xff0
  • [机器学习] ML重要概念:梯度(Gradient)与梯度下降法(Gradient Descent)

    引言 机器学习栏目记录我在学习Machine Learning过程的一些心得笔记 xff0c 涵盖线性回归 逻辑回归 Softmax回归 神经网络和SVM等等 xff0c 主要学习资料来自网上的免费课程和一些经典书籍 xff0c 免费课程例
  • TPMS胎压芯片选择:英飞凌SP370、英飞凌SP40、飞思卡尔FXTH87

    简介TPMS Tire Pressure Monitoring System xff08 TPMS xff09 xff0c 轮胎压力监测系统 xff0c TPMS的作用是在汽车行驶过程中对轮胎气压进行实时自动监测 xff0c 并对轮胎漏气和
  • 2014年计算机求职总结--准备篇

    版权所有 xff0c 转载请注明出处 xff0c 谢谢 xff01 http blog csdn net walkinginthewind article details 13000431 找工作是一个长期准备的过程 xff0c 突击是没什
  • Code::Blocks之设置字体

    设置 S gt 编辑器 D gt 常规设置 gt 编辑器设置 xff1b 在 34 字体 34 中选择 34 选择 34 按钮 xff0c 进行字体 字形 大小的选择 xff1b 确定
  • 嵌入式软件面试问题总结

    1 DCS 答 xff1a DCS一般指分散控制系统 分散控制系统是以微处理器为基础 xff0c 采用控制功能分散 显示操作集中 兼顾分而自治和综合协调的设计原则的新一代仪表控制系统 集散控制系统简称DCS 也可直译为 分散控制系统 或 分
  • 通过字体名获取字体文件

    由于在GLFT FreeType中需要传入字体文件作为参数 xff0c 所以需要通过字体名来寻找字体文件 现已完成 xff0c 特此总结分享 参考链接 xff1a https www codeproject com Articles 123
  • C++老鼠迷宫

    include lt iostream gt 输入输出流 include lt fstream gt 文件头文件 include lt conio h gt include lt time h gt 时间的头文件 include lt wi
  • Crazypony四轴飞行器代码框架

    软件框架讲解 作者 xff1a nieyong 飞控源代码部分 xff0c 都是属于一砖一瓦敲出来的 没有使用实时操作系统 xff08 RTOS xff09 xff0c 我们称之为裸机代码 xff0c 托管在Github上 xff0c 名字
  • STM32F103学习笔记(三):PB3、PB4、PA13、PA14、PA15用作普通IO口的配置

    最近使用stm32f103c8t6进行按键上拉输入配置的时候 xff0c 发现一样的电路 xff0c 只是将代码PA1 PA4换做PB3 PB6接口 xff0c 怎么也无法得出对应的实验结果 xff0c 测得电压PB3 xff0c PB4引

随机推荐

  • nginx反向代理后tomcat获取客户端的真实ip

    xff08 1 xff09 nginx的nginx conf文件修改 server listen 80 server name localhost location proxy redirect off proxy pass http 19
  • 报错:Uncaught Error: Cannot find module ‘core-js/library/fn/object/assign‘

    情况描述 xff1a 在项目中 xff0c vuepress写文档说明时 xff0c 加载element ui报错 enhanceApp js文件中 xff0c 将Vue use ElementUI 注释掉就不报错了 xff0c 但我要利用
  • 问题——STM32用flyMcu烧录“写入出错在0kb,进度0%,耗时1029毫秒”的错误

    目录 1 原因 2 现象 3 解决办法 1 原因 因勾选 编程到FLASH时写选项字节 出错 2 现象 xff08 1 xff09 flyMcu烧录 xff08 2 xff09 用JTAG烧录提示 xff1a Flash Download
  • ubuntn14.04 版本内核更换详细步骤

    Ubuntu14 04 版本 xff0c 内核为 3 13 XX 更换为 3 2 66 的方法 首先 xff0c 3 2 66第二个数字为偶数 xff0c 就是稳定版 xff08 现在是不是不拿这个区分了 xff1f 没搞清 xff0c 但
  • 设计模式_spring框架中常用的8种设计模式

    spring框架中常用到的8种设计模式清单如下 xff1a 设计模式 使用地方 备注 工厂模式 BeanFactory ApplicationContext 单例模式 Spring中的Bean 代理模式 Spring AOP java反射实
  • eclipse 部署与开发 cas 6.3

    安装前 xff0c 需要准备eclipse xff0c tomcat9 xff0c jdk11安装 eclipse安装gradle插件 打开eclipse xff0c 选择help eclipse market place 搜索builds
  • 2011研发工作总结

    转眼这一年又将过去 xff0c 伴随着公司的成立 xff0c 我们辛苦而又忙碌的从年头走到了年尾 以下是总结下这一年中工作的情况 xff0c 谈谈经验感想 xff0c 说说得失 公司成立 2011年刚开始 xff0c 公司就成立了 我们在喜
  • 论文笔记——EXPLAINING AND HARNESSING ADVERSARIAL EXAMPLES(解释和利用对抗样本)

    本文参考了三篇笔记 xff0c 帮助很大 xff1a Explaining and Harnessing Adversarial Examples 阅读笔记 论文笔记 Explaining amp Harnessing Adversaria
  • C++验证哥德巴赫猜想

    include lt iostream gt using namespace std bool Prime int i 判断是否为质数的函数 int j if i lt 61 1 return 0 如果小于等于1返回0 if i 61 61
  • 能ping通Linux&nbsp;但是ssh连不上问题…

    问题 xff1a 能ping通Linux服务器 但是ssh连不上 lt Linux redhat AS4 版本 gt 解决方法这个问题花了我20分钟去查资料 xff0c 网上写的解决方法也是五花八门 xff0c 不过 xff0c 总算解决了
  • RuntimeError: NCCL error in:torch/lib/c10d/ProcessGroupNCCL.cpp:514, invalid usage, NCCL version 踩坑

    运行pytorch分布式任务时 xff0c 可能在执行dist barrier 这条代码时会触发NCCL错误 xff1a RuntimeError NCCL error in torch lib c10d ProcessGroupNCCL
  • 有一种服务称为MaaS

    Metal as a Service 有一种服务称为MaaS xff08 开源 xff09 xff1a 云管理平台中必不可少的服务 为服务对象提供裸机 xff08 1或n xff09 xff0c 服务对象可以用来安装云OS和其他云功能 使用
  • UDP网络编程服务器与客户端代码

    一 xff0c 通信模型 服务器 xff1a 1 创建socket xff0c 使用socket函数 2 准备通信地址 xff0c 使用结构体类型 3 绑定socket和通信地址 xff0c 使用bind函数 4 监听 xff0c 使用li
  • SAMBA共享工具安装

    1 xff0c 环境win7 b4位 xff0c ubuntu16 04 xff0c 确定ubuntu已连接到互联网 xff0c 执行如下命令下载 Samba 工具 xff1a sudo apt get install samba samb
  • K8s ❉ node节点未找到cni0/flannel.1网络

    问题描述 xff1a 现有测试环境有3台k8s服务器 xff0c 现在新添加两台服务器 xff0c 发现新加的服务器flannel 1和cni0网卡没有生成 root 64 slave1 ifconfig docker0 flags 61
  • 学习一下freertos streambuffer

    学习一下freertos stream buffer 最近在自己从0到1写rtos xff0c 主要是为了学习rtos xff0c 并没有其他卵用 xff0c 光学会调API是不够的 xff0c 看源码又恼火 xff0c 所以学习的最好办法
  • Writable接口

    在org apache hadoop io中 xff0c hadoop使用自己的序列化格式Writables接口 xff0c 具有紧凑 xff0c 快速的特点 xff0c 不过目前只有用Java才能较容易扩展 在hadoop中 xff0c
  • 解决数据库连接慢问题

    解决数据库连接慢问题方法 xff1a 方法一 连接数据库时 xff0c 使用localhost xff0c 不要使用明确的IP地址 xff08 远程数据库除外 xff09 xff1b 方法二 在my cnf配置文件里 xff0c 添加ski
  • 难忘的2011

    前言 xff1a 这些年 xff0c 每到年终之时 xff0c 我都会写个总结 2009年的 优化生活 规划未来 记录了一位初级网络优化工程师09年的所想与所做以及对10年的规划与展望 xff1b 2010年的 今天的2010 xff0c
  • QT从字体名获取字库文件路径(从宋体获取到simsun.ttc)

    MFC版本的从字体名获取字库文件路径点击此处 最近弄的一份项目需要裁剪ttf字库 xff0c 故需要用到此功能 xff01 用了几年QT xff0c 个人感觉类库是非常强大的 xff01 QT相比VS的话亮点在开源的类库非常的丰富 xff0