当前位置: 首页 > ds >正文

FreeType 字体信息检查工具 - 现代C++实现

文章目录

    • 获取字体的版权信息
    • 工具简介
    • 主要特点
      • 1. 现代C++实现
      • 2. 完整的功能
      • 3. 健壮的错误处理
      • 4. 国际化支持
    • 使用说明
    • 技术亮点

获取字体的版权信息

#include <iostream>      // 标准输入输出流库
#include <string>       // 字符串处理库
#include <vector>
#include <memory>       // 智能指针库
#include <ft2build.h>   // FreeType库头文件
#include FT_FREETYPE_H  // FreeType主头文件
#include FT_SFNT_NAMES_H // SFNT名称表支持
#include FT_TRUETYPE_TABLES_H // TrueType表支持// 使用枚举类替代宏定义,增强类型安全
enum class NameId : uint16_t {Copyright = 0,  // 版权信息IDFamily = 1,     // 字体家族名称IDSubfamily = 2   // 字体子家族名称ID
};// 平台标识枚举
enum class PlatformId : uint16_t {Unicode = 0,    // Unicode平台Macintosh = 1,  // Macintosh平台Microsoft = 3   // Microsoft平台
};// RAII包装器管理FreeType库资源
struct FreeTypeLib {FT_Library lib;  // FreeType库实例// 构造函数初始化库FreeTypeLib() {if (FT_Init_FreeType(&lib)) {throw std::runtime_error("FreeType初始化失败");}}// 析构函数释放资源~FreeTypeLib() {FT_Done_FreeType(lib);}// 类型转换运算符operator FT_Library() const {return lib;}
};// RAII包装器管理字体face资源
struct FreeTypeFace {FT_Face face;  // 字体face对象// 构造函数加载字体文件FreeTypeFace(FT_Library lib, const std::string& path) {if (FT_New_Face(lib, path.c_str(), 0, &face)) {throw std::runtime_error("字体加载失败: " + path);}}// 析构函数释放资源~FreeTypeFace() {if (face) FT_Done_Face(face);}// 类型转换运算符operator FT_Face() const {return face;}
};// 打印字体基本信息
void print_font_info(FT_Face face) {std::cout << "\n字体家族: " << face->family_name    // 字体家族名称<< "\n字体样式: " << face->style_name     // 字体样式名称<< "\n字形数量: " << face->num_glyphs    // 包含的字形数量<< "\nEM单位数: " << face->units_per_EM // 设计网格分辨率<< std::endl;
}// 解码不同平台的字符串编码
std::string decode_string(const FT_SfntName& name) {std::string result;  // 存储解码结果// UTF-16BE解码lambda函数auto decode_utf16be = [](const unsigned char* str, size_t len) {std::string s;for (size_t j = 0; j + 1 < len; j += 2) {uint16_t c = (str[j] << 8) | str[j + 1];  // 组合高低字节if (c <= 0x7F) {  // ASCII字符s += static_cast<char>(c);}else {  // 非ASCII字符s += "\\u" + std::to_string(c);  // 显示Unicode转义序列}}return s;};// 根据平台ID选择解码方式switch (static_cast<PlatformId>(name.platform_id)) {case PlatformId::Microsoft:  // Microsoft平台case PlatformId::Unicode:    // Unicode平台return decode_utf16be(name.string, name.string_len);case PlatformId::Macintosh:  // Macintosh平台for (size_t j = 0; j < name.string_len; ++j) {unsigned char c = name.string[j];if (c >= 0x20 && c <= 0x7E) {  // 可打印ASCII字符result += c;}else {  // 非可打印字符result += "\\x" + std::to_string(c);  // 显示十六进制转义}}break;default:  // 其他平台for (size_t j = 0; j < name.string_len; ++j) {result += name.string[j];  // 直接添加字节}}return result;
}// 从名称表中提取并打印版权信息
void print_copyright_from_names(FT_Face face) {FT_UInt name_count = FT_Get_Sfnt_Name_Count(face);  // 获取名称表条目数std::cout << "\n检查SFNT名称表(" << name_count << "个条目)..." << std::endl;// 遍历所有名称表条目for (FT_UInt i = 0; i < name_count; ++i) {FT_SfntName name;if (FT_Get_Sfnt_Name(face, i, &name) == 0 &&  // 成功获取名称条目name.name_id == static_cast<FT_UShort>(NameId::Copyright)) {  // 是版权信息std::cout << "版权信息(平台" << name.platform_id<< ", 编码" << name.encoding_id << "): "<< decode_string(name) << std::endl;}}
}// 检查字体嵌入权限
void check_font_license(FT_Face face) {// 获取OS/2表(包含字体授权信息)if (auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(face, ft_sfnt_os2))) {std::cout << "\n嵌入权限: ";switch (os2->fsType) {case 0:  std::cout << "允许安装嵌入"; break;case 2:  std::cout << "受限许可嵌入"; break;case 4:  std::cout << "仅预览和打印嵌入"; break;case 8:  std::cout << "可编辑嵌入"; break;default: std::cout << "未知权限(0x" << std::hex << os2->fsType << ")";}std::cout << std::endl;}
}
int main() {// 定义要检查的字体文件列表std::vector<std::string> font_paths = {"D:\\Font\\Alumni_Sans_SC\\AlumniSansSC-VariableFont_wght.ttf","D:\\Font\\Asta_Sans\\AstaSans-VariableFont_wght.ttf","D:\\Font\\Edu_QLD_Hand\\EduQLDHand-VariableFont_wght.ttf","D:\\Font\\Edu_SA_Hand\\EduSAHand-VariableFont_wght.ttf","D:\\Font\\Noto_Sans_JP\\NotoSansJP-VariableFont_wght.ttf","D:\\Font\\Open_Sans\\OpenSans-Italic-VariableFont_wdth,wght.ttf","D:\\Arial-Unicode-MS.ttf"};// 初始化FreeType库(RAII管理)FreeTypeLib library;// 遍历所有字体文件for (const auto& font_path : font_paths) {try {std::cout << "\n\n===== 正在检查字体: " << font_path << " =====" << std::endl;// 加载字体文件(RAII管理)FreeTypeFace face(library, font_path);// 打印字体信息print_font_info(face);// 提取并打印版权信息print_copyright_from_names(face);// 检查字体授权check_font_license(face);}catch (const std::exception& e) {std::cerr << "处理字体 " << font_path << " 时出错: " << e.what() << std::endl;continue; // 继续处理下一个字体}}return EXIT_SUCCESS;
}

工具简介

这是一个使用现代C++编写的字体信息检查工具,基于FreeType库开发,可以读取并显示字体文件的详细信息,包括:

  1. 基本字体信息(家族名称、样式名称等)
  2. 版权信息
  3. 字体嵌入权限

主要特点

1. 现代C++实现

  • 使用RAII(资源获取即初始化)技术自动管理资源
  • 采用异常处理替代传统错误码检查
  • 使用枚举类增强类型安全
  • 利用lambda表达式简化复杂逻辑

2. 完整的功能

  • 显示字体家族名称和样式
  • 提取并解码字体版权信息(支持多种编码格式)
  • 检查字体嵌入权限(安装、编辑、打印等)

3. 健壮的错误处理

  • 统一的异常处理机制
  • 详细的错误信息提示
  • 自动资源释放

4. 国际化支持

  • 所有输出信息使用中文
  • 完整的代码中文注释
  • 支持Unicode字符显示

使用说明

  1. 修改代码中的 font_path 变量为您的字体文件路径
  2. 编译运行程序
  3. 程序将输出字体的详细信息

技术亮点

  • ​自动资源管理​​:通过 FreeTypeLibFreeTypeFace 类自动管理FreeType资源
  • ​智能编码处理​​:自动识别并处理不同平台的字体编码(Unicode、MacRoman等)
  • ​清晰的输出​​:格式化显示所有字体信息,便于阅读和理解

这个工具非常适合字体开发者、图形设计师或任何需要检查字体属性的开发人员使用。

http://www.xdnf.cn/news/12053.html

相关文章:

  • selenium学习实战【Python爬虫】
  • 【贪心、DP、线段树优化】Leetcode 376. 摆动序列
  • 当AI遇上防火墙:新一代智能安全解决方案全景解析
  • Elasticsearch中的自定义分析器(Custom Analyzer)介绍
  • 2025最新Java日志框架深度解析:Log4j 2 vs Logback性能实测+企业级实战案例
  • 一个完整的时间序列异常检测系统,使用Flask作为后端框架,实现了AE(自编码器)、TimesNet和LSTM三种模型,并提供可视化展示
  • Asp.Net Core基于StackExchange Redis 缓存
  • 使用TypeScript构建一个最简单的MCP服务器
  • PDF处理控件Aspose.PDF教程:在 C# 中更改 PDF 页面大小
  • 【从零学习JVM|第二篇】字节码文件
  • Android 项目的核心配置文件
  • 数据结构第一章
  • 边缘计算网关赋能沸石转轮运行故障智能诊断的配置实例
  • Flutter如何支持原生View
  • Unity安卓平台开发,启动app并传参
  • 如何配置一个sql server使得其它用户可以通过excel odbc获取数据
  • 【大模型:知识图谱】--5.neo4j数据库管理(cypher语法2)
  • rknn优化教程(一)
  • DPO算法微调实战
  • 微信小程序动态组件加载的应用场景与实现方式
  • 双电机差速控制的MATLAB Simulink仿真方案,使用PWM和PID调节实现360°转向与速度控制
  • 分类预测 | Matlab实现CNN-BiLSTM-Attention高光谱数据分类预测
  • PostgreSQL的扩展 pg_buffercache
  • TDengine 开发指南——高效写入
  • ​BEV和OCC学习-3:mmdet3d 坐标系
  • 知识拓展卡————————关于Access、Trunk、Hybrid端口
  • Duix.HeyGem:以“离线+开源”重构数字人创作生态
  • Rust 控制流
  • 共识机制全景图:PoW、PoS 与 DAG 的技术对比
  • 华为设备OSPF配置与实战指南