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

Mac 平台 字体Unicode范围分析器

字体Unicode范围分析器

#include <CoreText/CoreText.h>       // CoreText框架头文件,用于字体处理
#include <CoreFoundation/CoreFoundation.h> // CoreFoundation框架头文件
#include <stdio.h>                   // 标准输入输出
#include <stdlib.h>                  // 标准库函数
#include <string.h>                  // 字符串处理
#include <vector>                    // C++向量容器
#include <map>                       // C++映射容器
#include <string>                    // C++字符串// 定义Unicode范围结构体,表示一个连续的Unicode字符范围
typedef struct {uint32_t start;  // 范围起始码点uint32_t end;    // 范围结束码点
} UnicodeRange;// 全局映射表,存储字体名称和对应的Unicode范围集合
// key: 字体名称(string)
// value: 该字体支持的Unicode范围集合(vector<UnicodeRange>)
std::map<std::string, std::vector<UnicodeRange>> fontUnicodeRanges;// 函数:获取字体支持的Unicode范围
// 参数:字体引用(CTFontRef)
// 返回值:该字体支持的Unicode范围集合(vector<UnicodeRange>)
std::vector<UnicodeRange> getSupportedUnicodeRanges(CTFontRef font) {std::vector<UnicodeRange> tempRanges; // 临时存储范围集合if (!font) {  // 检查字体引用是否有效return tempRanges; // 无效则返回空集合}// 1. 获取字体支持的字符集CFCharacterSetRef charset = CTFontCopyCharacterSet(font); // 复制字体字符集// 创建字符集的位图表示CFDataRef bitmapData = CFCharacterSetCreateBitmapRepresentation(kCFAllocatorDefault, charset);const UInt8 *bitmap = CFDataGetBytePtr(bitmapData); // 获取位图数据指针CFIndex length = CFDataGetLength(bitmapData);      // 获取位图数据长度bool inRange = false;   // 标记是否处于连续范围内uint32_t start = 0;     // 当前范围的起始码点uint32_t maxChar = 0;   // 当前范围的结束码点// 2. 遍历位图,检测并合并连续范围for (uint32_t byteIndex = 0; byteIndex < length; byteIndex++) {UInt8 byte = bitmap[byteIndex]; // 获取当前字节if (byte == 0) {  // 如果字节为0,表示没有支持的字符if (inRange) { // 如果之前处于范围内,则结束当前范围tempRanges.push_back({start, (byteIndex << 3) - 1});inRange = false;}continue; // 跳过后续处理}// 检查字节中的每一位(共8位)for (uint32_t bit = 0; bit < 8; bit++) {uint32_t currentChar = (byteIndex << 3) + bit; // 计算当前字符码点bool isSupported = (byte & (1 << bit)) != 0;   // 检查当前位是否被支持if (isSupported) {  // 如果字符被支持if (!inRange) { // 如果不在范围内,则开始新范围start = currentChar;inRange = true;}maxChar = currentChar; // 更新范围结束码点} else if (inRange) { // 如果字符不被支持但之前处于范围内tempRanges.push_back({start, currentChar - 1}); // 结束当前范围inRange = false;}}}// 处理最后一个范围(如果遍历结束时仍处于范围内)if (inRange) {tempRanges.push_back({start, maxChar});}// 3. 压缩范围(合并相邻或重叠的范围)if (!tempRanges.empty()) {size_t compressedCount = 0; // 压缩后的范围计数// 遍历所有范围for (size_t i = 1; i < tempRanges.size(); i++) {// 如果当前范围与前一个范围相邻或重叠if (tempRanges[i].start <= tempRanges[compressedCount].end + 1) {// 合并范围(取最大的结束码点)if (tempRanges[i].end > tempRanges[compressedCount].end) {tempRanges[compressedCount].end = tempRanges[i].end;}} else {// 不重叠则保留当前范围compressedCount++;tempRanges[compressedCount] = tempRanges[i];}}// 调整向量大小为压缩后的数量tempRanges.resize(compressedCount + 1);}// 释放资源CFRelease(bitmapData);CFRelease(charset);return tempRanges; // 返回最终的范围集合
}// 函数:获取字体名称
// 参数:字体引用(CTFontRef)
// 返回值:字体名称(string)
std::string getFontName(CTFontRef font) {if (!font) return ""; // 检查字体引用// 获取字体的PostScript名称CFStringRef fontName = CTFontCopyPostScriptName(font);if (!fontName) return ""; // 检查名称是否有效// 尝试直接获取C字符串const char* name = CFStringGetCStringPtr(fontName, kCFStringEncodingUTF8);std::string result;if (name) { // 如果直接获取成功result = name;} else {// 需要手动转换字符串CFIndex length = CFStringGetLength(fontName);CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;char* buffer = new char[maxSize]; // 分配缓冲区// 将CFString转换为C字符串if (CFStringGetCString(fontName, buffer, maxSize, kCFStringEncodingUTF8)) {result = buffer;}delete[] buffer; // 释放缓冲区}CFRelease(fontName); // 释放CFStringreturn result;      // 返回转换后的字符串
}// 函数:添加字体到全局映射表
// 参数:字体引用(CTFontRef)
void addFontToMap(CTFontRef font) {std::string fontName = getFontName(font); // 获取字体名称if (!fontName.empty()) { // 如果名称有效// 将字体名称和对应的Unicode范围存入映射表fontUnicodeRanges[fontName] = getSupportedUnicodeRanges(font);}
}// 函数:打印所有字体的Unicode范围
void printAllFontRanges() {// 遍历映射表中的所有字体for (const auto& pair : fontUnicodeRanges) {printf("字体: %s\n", pair.first.c_str()); // 打印字体名称// 打印该字体支持的所有Unicode范围for (const auto& range : pair.second) {printf("  支持范围: U+%04X - U+%04X\n", range.start, range.end);}printf("\n"); // 打印空行分隔不同字体}
}// 主函数
int main() {// 示例:创建并分析三种字体// 1. 创建苹方字体CTFontRef font1 = CTFontCreateWithName(CFSTR("PingFangSC-Regular"), 16.0, nullptr);if (font1) {addFontToMap(font1); // 添加到映射表CFRelease(font1);    // 释放字体}// 2. 创建Helvetica字体CTFontRef font2 = CTFontCreateWithName(CFSTR("Helvetica"), 16.0, nullptr);if (font2) {addFontToMap(font2);CFRelease(font2);}// 3. 创建Times New Roman字体CTFontRef font3 = CTFontCreateWithName(CFSTR("TimesNewRomanPSMT"), 16.0, nullptr);if (font3) {addFontToMap(font3);CFRelease(font3);}// 打印所有已分析字体的Unicode范围printAllFontRanges();return 0;
}

代码中文名称:字体Unicode范围分析器

功能说明:

  1. 核心功能:分析字体文件支持的Unicode字符范围

  2. 数据结构:使用map容器存储字体名称及其支持的Unicode范围

  3. 技术特点:
    • 使用CoreText框架获取字体信息

    • 通过位图分析高效检测字符支持情况

    • 自动合并相邻或重叠的Unicode范围

  4. 输出格式:清晰的字体支持范围列表

适用场景:
• 字体管理工具开发

• 多语言文本处理应用

• 字体兼容性检查

• 文字渲染优化

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

相关文章:

  • 使用迁移学习的自动驾驶汽车信息物理系统安全策略
  • MySQL数据库创建、删除、修改
  • Android NDK版本迭代与FFmpeg交叉编译完全指南
  • ubuntu24.04安装anaconda
  • SwiftData 数据持久化解决方案
  • 如何使用极狐GitLab 软件包仓库功能托管 python?
  • git设置tabsize
  • Kubernetes client-go 客户端类型与初始化指南
  • 驱动开发硬核特训 · Day 30(上篇):深入理解 I2C 总线驱动模型(以 at24 EEPROM 为例)
  • Dynamic Causal Modeling在医疗AI领域的编程案例与应用研究
  • 〖 Linux 〗解决 VS Code 远程连接服务器的常见问题
  • iPhone手机连接WiFi异常解决方法
  • 【hadoop】案例:Sqoop迁移仓库数据
  • 5、开放式PLC梯形图编程组件 - /自动化与控制组件/open-plc-programming
  • Lua学习笔记
  • 无刷电机控制算法策略
  • AI驱动的制造工艺:系统化探索与创新
  • 【hadoop】Hbase java api 案例
  • 【嵌入式开发-CAN】
  • 美化IDEA注释:Idea 中快捷键 Ctrl + / 自动注释的缩进(避免添加注释自动到行首)以及 Ctrl + Alt + l 全局格式化代码的注释缩进
  • Java 异常
  • 深入理解 Docker 网络原理:构建高效、灵活的容器网络
  • 缓存局部性保留
  • 【Python】PDF文件处理(PyPDF2、borb、fitz)
  • 2022年8月,​韩先超对中移信息进行微服务架构原理(Docker+k8s+DevOps+Go等)培训
  • MYSQL的行级锁到底锁的是什么东西
  • iOS 模块化开发流程
  • DeepSeek多尺度数据:无监督与原则性诊断方案全解析
  • 查看jdk是否安装并且配置成功?(Android studio安装前的准备)
  • Vue3 + Node.js 实现客服实时聊天系统(WebSocket + Socket.IO 详解)