C++字体库开发之字体包解析十二

发布时间:2026/11/2 10:45:57

C++字体库开发之字体包解析十二 parse.h#ifndef FONT_SUBSET_EXPORT_H #define FONT_SUBSET_EXPORT_H #ifndef FONT_SUBSET_API # ifdef FONT_SUBSET_LIBRATY # ifdef _MSC_VER # if defined FONT_SUBSET_LIBRATY # define FONT_SUBSET_API __declspec(dllexport) # else # define FONT_SUBSET_API __declspec(dllimport) # endif # else # define FONT_SUBSET_API __attribute__((visibility(default))) # endif # else # define FONT_SUBSET_API # endif #endif struct FontTTCByteData{ unsigned char *buffer nullptr; unsigned int length 0; }; struct FontSubSetByteDatas { struct One{ unsigned char *buffer nullptr; unsigned int length 0; char* familyName nullptr; unsigned int nameLength 0; } *subsets; unsigned int size 0; }; FONT_SUBSET_API FontSubSetByteDatas createSubsetFonts(FontTTCByteData ttcSteam); FONT_SUBSET_API FontSubSetByteDatas createSubsetFonts(const char* path); FONT_SUBSET_API void releaseSubsetFonts(FontSubSetByteDatas datas); FONT_SUBSET_API bool isTTC(FontTTCByteData ttcSteam); #endif // FONT_SUBSET_EXPORT_Hparse.cpp#include sfntly/data/memory_byte_array.h #include sfntly/font_factory.h #include sfntly/port/file_input_stream.h #include sfntly/port/memory_output_stream.h #include sfntly/table/core/name_table.h #include sfntly/tag.h #include iostream #include unicode/ustring.h #include parseTTC.h #include sfntly/port/memory_input_stream.h FONT_SUBSET_API FontSubSetByteDatas createSubsetFonts(sfntly::InputStream* inputStream) { using namespace sfntly; FontFactoryPtr factory; factory.Attach(FontFactory::GetInstance()); // File based FontBuilderArray font_builder_array; factory-LoadFontsForBuilding(inputStream, font_builder_array); // 创建输出流数组 FontSubSetByteDatas fontSubSetByteDatas; fontSubSetByteDatas.subsets new FontSubSetByteDatas::One[font_builder_array.size()]; fontSubSetByteDatas.size font_builder_array.size(); for (int index 0; index fontSubSetByteDatas.size; index) { const auto font_builder font_builder_array.at(index); NameTableBuilderPtr name_builder down_castNameTable::Builder*( font_builder-GetTableBuilder(Tag::name)); // // Change the font name. // auto findName name_builder-Has(PlatformId::kWindows, // WindowsEncodingId::kUnicodeUCS2, // WindowsLanguageId::kEnglish_UnitedStates, // NameId::kFontFamilyName); NameEntryBuilderPtr neb name_builder-NameBuilder(PlatformId::kWindows, WindowsEncodingId::kUnicodeUCS2, WindowsLanguageId::kEnglish_UnitedStates, NameId::kFontFamilyName); UChar* name neb-name_entry()-Name(); // U_STRING_DECL(new_name, Timothy, 7); // neb-SetName(new_name); // Build the font. FontPtr font; font.Attach(font_builder-Build()); // auto digest font-digest(); // Serialize and reload the serialized font. MemoryOutputStream os; factory-SerializeFont(font, os); // ByteArrayPtr new_ba new MemoryByteArray(os.Get(), os.Size()); auto fileStream new unsigned char[os.Size()]; std::copy(os.Get(), os.Get() os.Size(), fileStream); int32_t nameLen u_strlen(name); auto asciiName new char[nameLen * 2]; u_austrncpy(asciiName, name, nameLen 1); // auto copyChar u_austrncpy(asciiName, name, nameLen 1); // auto asciiNameLen strlen(copyChar); // asciiName[asciiNameLen 1] \0; fontSubSetByteDatas.subsets[index].familyName asciiName; fontSubSetByteDatas.subsets[index].nameLength strnlen_s(asciiName, nameLen * 2); fontSubSetByteDatas.subsets[index].buffer fileStream; fontSubSetByteDatas.subsets[index].length os.Size(); delete[] name; } return fontSubSetByteDatas; } FONT_SUBSET_API FontSubSetByteDatas createSubsetFonts(const char* path) { using namespace sfntly; sfntly::FileInputStream is; if(!is.Open(path)) { std::cout path file open is fail std::endl; return {}; } std::shared_ptrvoid finally(nullptr, [is](...) { is.Close(); }); return createSubsetFonts(is); } FONT_SUBSET_API FontSubSetByteDatas createSubsetFonts(FontTTCByteData ttcSteam) { using namespace sfntly; sfntly::MemoryInputStream memoryInputStream; memoryInputStream.Attach(ttcSteam.buffer, ttcSteam.length); return createSubsetFonts(memoryInputStream); } FONT_SUBSET_API void releaseSubsetFonts(FontSubSetByteDatas datas) { for (int i 0; i datas.size; i) { delete[] datas.subsets[i].buffer; delete[] datas.subsets[i].familyName; } delete[] datas.subsets; } FONT_SUBSET_API bool isTTC(FontTTCByteData ttcSteam) { using namespace sfntly; sfntly::MemoryInputStream memoryInputStream; memoryInputStream.Attach(ttcSteam.buffer, ttcSteam.length); std::vectoruint8_t tag(4); memoryInputStream.Read(tag); memoryInputStream.Unread(tag); return Tag::ttcf GenerateTag(tag[0], tag[1], tag[2], tag[3]); } FONT_SUBSET_API std::string getFontFormat(FontTTCByteData ttcSteam) { using namespace sfntly; sfntly::MemoryInputStream memoryInputStream; memoryInputStream.Attach(ttcSteam.buffer, ttcSteam.length); std::vectoruint8_t tag(4, 0); memoryInputStream.Read(tag); memoryInputStream.Unread(tag); auto format GenerateTag(tag[0], tag[1], tag[2], tag[3]); if(0x00010000 format) return ttf; if(0x4f54544f format) return otf; return std::string((char*)tag[0], 4); }main.cpp#include parse.h #include iostream #include fstream int main() { const char* path C:\\Users\\Downloads\\msyh.ttc; auto fontDatas createSubsetFonts(path); if(0 fontDatas.size) { std::cout path parse fail! std::endl; return 1; } for (int i 0; i fontDatas.size; i) { // write file std::ofstream outFile((const char*)fontDatas.subsets[i].familyName, std::ios::binary); if (!outFile) { // error continue; } outFile.write(reinterpret_castconst char*(fontDatas.subsets[i].buffer), fontDatas.subsets[i].length * sizeof(uint8_t)); outFile.close(); } releaseSubsetFonts(fontDatas); return 0; }参考https://github.com/googlei18n/sfntlyhttps://pkg.go.dev/golang.org/x/image/font/sfnt#CollectionC字体库开发之字体列表十一-CSDN博客创作不易小小的支持一下吧
延伸阅读

更多相关文章

2026/11/2 10:45:57

输入网址后发生了什么:从HTTPS请求到页面绘制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 10:45:57

【12】火焰烟雾数据集(有v5/v8模型)/YOLO火焰烟雾检测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 10:45:57

【9】工程车辆数据集(有v5/v8模型)/YOLO工程车辆检测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 11:46:10

Cobalt Strike Beacon隐蔽技术:BeaconGate+UDRL+Sleepmask实战

1. 项目概述在红队攻防对抗中,Cobalt Strike(简称CS)作为主流渗透测试框架,其Beacon载荷的隐蔽性直接决定了攻击行动的成败。最近我在实际项目中遇到了一个棘手问题:传统睡眠混淆技术已逐渐被EDR产品识别,急…

2026/11/2 11:46:10

AI辅助测试用例编写:提示词设计与实践

1. 为什么需要AI辅助测试用例编写 在软件测试领域,编写高质量的测试用例往往需要耗费大量时间。根据业界统计,测试人员平均每天要花费40%的工作时间在用例编写和维护上。传统手工编写方式存在三个明显痛点: 首先,测试场景覆盖率与…

2026/11/2 11:46:10

工业自动化TVA选型:避免误区与全生命周期成本优化

1. 项目概述:TVA选型的核心痛点解析 在工业自动化领域,终端执行器(Terminal Valve Actuator,简称TVA)的选型决策常常陷入两个极端:要么过度关注技术参数表中的数字竞赛,要么单纯追求采购成本最低…

2026/11/2 11:46:10

HTML转PDF实战:渲染引擎选型、分页控制与字体避坑指南

简介:这份资源面向.NET开发者与文档处理场景,聚焦HTML到PDF的转换需求,提供基于Aspose.Pdf库的完整示例工程。压缩包共32个文件,约10.62MB,以cs源码、aspx页面、dll程序集、config配置及pdf示例文档为主,另…

2026/11/2 11:46:10

CTFshow Web安全实战:Base64编码与HTTP头注入解析

1. CTFshow Web安全入门实战解析作为一名长期活跃在CTF赛场的Web安全研究员,我经常遇到新手对CTFshow平台上的Web题目感到困惑。今天我们就来深度剖析CTFshow《Web应用安全与防护》第一章的核心考点,通过6个典型场景带你掌握Web安全基础技能。1.1 Base64…

2026/11/2 11:41:09

城市运管服平台安全架构与关键技术解析

1. 城市运管服平台的安全定位与核心价值 城市运管服平台作为现代城市治理的"数字中枢",其安全防线直接决定了城市运行的底线保障能力。这个看似抽象的概念,在实际场景中体现为:当暴雨导致城市内涝时,平台能否实时感知积…

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 1:04:04

工业级SPI隔离设计:硬件抗扰与信号完整性实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 1:04:04

PLFM_RADAR:主动探测数据通道,构建低误报的数据感知系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 1:04:04

工业SPI隔离设计:MAX14431与STM32F746硬件抗干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑