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

news2025/6/7 1:11:24

文章目录

    • 获取字体的版权信息
    • 工具简介
    • 主要特点
      • 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,  // 版权信息ID
    Family = 1,     // 字体家族名称ID
    Subfamily = 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.coloradmin.cn/o/2400738.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【使用JAVA调用deepseek】实现自能回复

在Spring Boot系统中接入DeepSeek服务&#xff0c;并将其提供给用户使用&#xff0c;通常需要以下步骤&#xff1a; 一、准备工作 &#xff08;1&#xff09;注册DeepSeek开发者账号 访问DeepSeek官网&#xff0c;注册并创建应用&#xff0c;获取API Key。 API文档&#xff1…

【Linux系列】rsync命令详解与实践

博客目录 高效文件同步的艺术&#xff1a;rsync 命令详解与实践rsync 命令解析rsync 的核心优势1. 增量传输&#xff1a;效率的革命2. 归档模式(-a)&#xff1a;保留文件所有属性3. 人性化输出(-h)与进度显示(--progress) 实际应用场景1. 文件备份与版本管理2. 跨设备同步3. 大…

Windows系统工具:WinToolsPlus 之 SQL Server Suspect/质疑/置疑/可疑/单用户等 修复

数据库在数据库列表状态是 Suspect/质疑/置疑/可疑/单用户等 非正常状态时&#xff0c; 使用WinToolsPlus 数据库页签 先设置 数据源 &#xff0c; 选择 需要清理日志的数据库&#xff0c; 点击 Suspect/质疑/置疑/可疑/单用户 按钮即可进修复。 修复过程会有数据库服务停止和启…

C++——智能指针 unique_ptr

unique_ptr的实现原理&#xff1a;简单粗暴的防拷贝 目录 一、使用C11中的新用法unique_ptr 二、使用c11模拟实现 三、使用c98特性实现 四、模拟实现unique_ptr 五、发现问题 一、使用C11中的新用法unique_ptr 由于限制了拷贝以及赋值 导致缺陷&#xff1a;unique_ptr管理…

【Python训练营打卡】day43 @浙大疏锦行

DAY 43 复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 我选择的是music_instruments 链接&#xff1a;Musical Instruments (kaggle.com) #导包 import torch import torch.nn as…

1-【源码剖析】kafka核心概念

从今天开始开始在csdn上记录学习的笔记&#xff0c;主要包括以下几个方面&#xff1a; kafkaflinkdoris 本系列笔记主要记录Kafka学习相关的内容。在进行kafka源码学习之前&#xff0c;先介绍一下Kafka的核心概念。 消息 消息是kafka中最基本的数据单元&#xff0c;由key和…

思科设备网络实验

一、 总体拓扑图 图 1 总体拓扑图 二、 IP地址规划 表格 1 接口地址规划 设备名称 接口/VLAN IP 功能 PC0 VLAN580 10.80.1.1 访问外网 PC1 VLAN581 10.80.2.1 访问外网 PC2 Fa0 20.80.1.100 端口镜像监控流量 PC3 VLAN585 10.80.6.1 远程登陆多层交换机0…

AWS之数据分析

目录 数据分析产品对比 1. Amazon Athena 3. AWS Lake Formation 4. AWS Glue 5. Amazon OpenSearch Service 6. Amazon Kinesis Data Analytics 7. Amazon Redshift 8.Amazon Redshift Spectrum 搜索服务对比 核心功能与定位对比 适用场景 关键差异总结 注意事项 …

C# Onnx 动漫人物头部检测

目录 效果 模型信息 项目 代码 下载 参考 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-10-19T12:32:20.920471 description&#xff1a;Ultralytics best model trained on /root/datasets/yolo/anime_head_detection/data.yaml au…

【Ragflow】24.Ragflow-plus开发日志:增加分词逻辑,修复关键词检索失效问题

概述 在RagflowPlus v0.3.0 版本推出之后&#xff0c;反馈比较多的问题是&#xff1a;检索时&#xff0c;召回块显著变少了。 如上图所示&#xff0c;进行检索测试时&#xff0c;关键词相似度得分为0&#xff0c;导致混合相似度(加权相加得到)也被大幅拉低&#xff0c;低于设定…

Zookeeper 集群部署与故障转移

Zookeeper 介绍 Zookeeper 是一个开源的分布式协调服务&#xff0c;由Apache基金会维护&#xff0c;专为分布式应用提供高可用、强一致性的核心基础能力。它通过简单的树形命名空间&#xff08;称为ZNode树&#xff09;存储数据节点&#xff08;ZNode&#xff09;&#xff0c;…

Redis最佳实践——电商应用的性能监控与告警体系设计详解

Redis 在电商应用的性能监控与告警体系设计 一、原子级监控指标深度拆解 1. 内存维度监控 核心指标&#xff1a; # 实时内存组成分析&#xff08;单位字节&#xff09; used_memory: 物理内存总量 used_memory_dataset: 数据集占用量 used_memory_overhead: 管理开销内存 us…

区域徘徊检测算法AI智能分析网关V4助力公共场所/工厂等多场景安全升级

一、项目背景 随着数字化安全管理需求激增&#xff0c;重点场所急需强化人员异常行为监测。区域徘徊作为潜在安全威胁的早期征兆&#xff0c;例如校园围墙外的陌生逗留者&#xff0c;都可能引发安全隐患。传统人工监控模式效率低、易疏漏&#xff0c;AI智能分析网关V4的区域徘…

修复与升级suse linux

suse linux enterprise desktop 10提示&#xff1a;xxx service failed when loaded shared lib . error ibgobject.so.2.0:no such file or directory. suse linux enterprise server 12.iso 通过第一启动项引导&#xff0c;按照如下方式直接升级解决。

电力高空作业安全检测(2)数据集构建

数据集构建的重要性 在电力高空作业安全检测领域&#xff0c;利用 计算机视觉技术 进行安全监测需要大量的图像数据&#xff0c;这些数据需要准确标注不同的安全设备与作业人员行为。只有构建出包含真实场景的高质量数据集&#xff0c;才能通过深度学习等算法对高空作业中的潜…

嵌入式开发之STM32学习笔记day18

STM32F103C8T6 SPI通信读写W25Q64 1 W25Q64简介 W25Qxx系列是一种低成本、小型化且易于使用的非易失性存储器&#xff08;NOR Flash&#xff09;&#xff0c;它广泛应用于需要持久化存储数据的各种场景&#xff0c;如数据存储、字库存储以及固件程序存储等。该系列存储器采用…

[论文阅读]PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning

PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning | IJCAI IJCAI-22 发表于2022年的论文&#xff0c;当时大家还都在做小模型NLP的相关工作&#xff08;BERT&#xff0c;Ro…

汽车安全:功能安全FuSa、预期功能安全SOTIF与网络安全Cybersecurity 解析

汽车安全的三重防线&#xff1a;深入解析FuSa、SOTIF与网络安全技术 现代汽车已成为装有数千个传感器的移动计算机&#xff0c;安全挑战比传统车辆复杂百倍。 随着汽车智能化、网联化飞速发展&#xff0c;汽车电子电气架构已从简单的分布式控制系统演变为复杂的移动计算平台。现…

【C++高级主题】虚继承

目录 一、菱形继承&#xff1a;虚继承的 “导火索” 1.1 菱形继承的结构与问题 1.2 菱形继承的核心矛盾&#xff1a;多份基类实例 1.3 菱形继承的具体问题&#xff1a;二义性与数据冗余 二、虚继承的语法与核心目标 2.1 虚继承的声明方式 2.2 虚继承的核心目标 三、虚继…

基于 ZYNQ 的实时运动目标检测系统设计

摘 要: 传统视频监控系统在实时运动目标检测时&#xff0c;存在目标检测不完整和目标检测错误的局限 性 。 本研究基于体积小 、 实时性高的需求&#xff0c;提出了一种将动态三帧差分法与 Sobel 边缘检测算法结 合的实时目标检测方法&#xff0c;并基于 ZYNQ 构建了视频…