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

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等)
  • ​清晰的输出​​:格式化显示所有字体信息,便于阅读和理解

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

相关文章:

  • 信创认证通关攻略:从环境搭建到测试报告的全流程操作指南
  • Maskrcnn网络结构学习
  • ArcGIS Pro 3.4 二次开发 - 地图探索
  • Neo4j 认证与授权:原理、技术与最佳实践深度解析
  • GO语言---函数命名返回值
  • DrissionPage爬虫包实战分享
  • Ethernet IP转Modbus网关在热泵机组中的协议转换技术实现
  • Vue中的自定义事件
  • 自注意力,多头注意力,交叉注意力代码对比
  • Cisco Packet Tracer软件如何修改文件存储位置
  • 制造业数字化转型解决方案及应用
  • 【Python训练营打卡】day43 @浙大疏锦行
  • C语言获取数组长度方法大全(附带实例)
  • 共聚焦显微镜—赋能光学元件精密质控
  • 常见优化器Optimizer总结
  • 论文润色指令
  • shell:基础
  • C语言数组初始化方法大全(附带实例)
  • JAVA 集合进阶 06 - 09 Map 集合的实现类:HashMap、LinkecHashMap
  • JAVA 集合进阶 Map集合的实现类 TreeMap
  • 女生做seo网站推广/西安百度竞价托管
  • 党政网站建设/孝感seo
  • 免费网站怎么做啊/互联网推广是什么意思
  • 网站怎样优化文章关键词/青岛疫情最新情况
  • 网站开发新闻管理系统的背景/百度关键词点击
  • 做网站自动赚钱吗/佛山旺道seo优化