
PDF中AAAAAD+SourceHanSansCN-Normal和BIISMY+SourceHanSansCN-Normal等格式的字体名,其“+”前六位大写字母是PDF规范定义的字体子集唯一标签(Subset Tag),用于标识嵌入的字形子集来源,而非字体家族或变体名称。
pdf中aaaaad+sourcehansanscn-normal和biismy+sourcehansanscn-normal等格式的字体名,其“+”前六位大写字母是pdf规范定义的字体子集唯一标签(subset tag),用于标识嵌入的字形子集来源,而非字体家族或变体名称。
在使用iText 5.x(如5.5.8)解析PDF字体时,调用 TextRenderInfo.getFont().getPostscriptFontName() 获取的字体名常以 XXXXXX+FontName 形式出现(如 AAAAAD+SourceHanSansCN-Normal)。这一结构并非自定义命名,而是严格遵循 ISO 32000-2(PDF 2.0)第9.9.2节“Font subsets” 的强制规范。
✅ 字体子集标签(Subset Tag)的规范定义
根据PDF标准:
- 当PDF嵌入的是字体子集(即仅包含文档实际用到的少量字形,而非完整字体文件)时,其 BaseFont 和字体描述符中的 FontName 必须采用如下格式:
+ - 是任意6个大写英文字母(如 AAAAAD、BIISMY),由生成PDF的工具(如PowerPoint)在嵌入时动态生成;
- 同一PDF文件中,若多次嵌入同一原始字体的不同子集,每个子集必须使用不同的6字母标签,以确保可区分性;
- 标签本身无语义含义(不表示字体粗细、宽度、语言等),仅作唯一性标识;
- 子集字体中必须包含 .notdef 字形,用于处理缺失字形的回退渲染。
? 示例对照:
- AAAAAD+SourceHanSansCN-Normal → PowerPoint「嵌入字体」导出,嵌入了简体中文常用字子集;
- BIISMY+SourceHanSansCN-Normal → PowerPoint「不嵌入字体」导出?❌ 实际上,该场景更可能是「嵌入字体但使用不同子集策略」——例如两份PPT分别只用到了Source Han Sans CN的不同字符集(如一份含标点与数字,另一份含汉字),导致生成器分配了不同标签。注意:“不嵌入字体”通常会导致字体名直接为 SourceHanSansCN-Normal(无前缀),并依赖系统字体,此时 getPostscriptFontName() 返回值不会含+。因此,出现 BIISMY+... 说明该PDF仍嵌入了子集,只是子集内容或生成上下文不同。
? 在代码中正确识别与归一化字体
在字体审计、合规检查或字体替换等场景中,需忽略子集标签,还原原始字体名:
public static String getOriginalFontName(String postScriptName) {
if (postScriptName == null) return null;
int plusIndex = postScriptName.indexOf('+');
if (plusIndex == 6 && postScriptName.length() > 7) { // 符合"6字母+原始名"结构
String tag = postScriptName.substring(0, 6);
if (tag.chars().allMatch(Character::isUpperCase) &&
tag.chars().filter(Character::isLetter).count() == 6) {
return postScriptName.substring(7); // 跳过 '+',取后半部分
}
}
return postScriptName; // 非子集字体,原样返回
}
// 使用示例
String fullName = textRenderInfo.getFont().getPostscriptFontName();
String baseName = getOriginalFontName(fullName); // → "SourceHanSansCN-Normal"
System.out.println(text + " → 原始字体: " + baseName);⚠️ 注意事项与最佳实践
- 勿将子集标签误判为字体变体:AAAAAD+ 与 BIISMY+ 不代表不同字重、宽度或语言版本,二者极大概率源自同一款 SourceHanSansCN-Normal 字体的不同子集;
- 跨PDF比较需归一化:分析多份PDF的字体使用情况时,应统一提取 + 后的原始字体名,否则会错误统计为多个“不同字体”;
- 子集≠不嵌入:带 + 的字体名明确表示已嵌入子集;若PDF未嵌入任何字体,getPostscriptFontName() 可能返回系统默认字体名(如 Helvetica)或空值,但绝不会出现6字母+格式;
- iText 5.x兼容性提示:该版本对OpenType/CFF字体子集解析稳定,但若需深度分析字形覆盖率,建议升级至 iText 7.x 并结合 PdfFont.getFontProgram().getFontNames() 进行验证。
掌握子集标签机制,不仅能准确识别PDF真实使用的字体资源,更是实现自动化字体合规审计、文档精简优化及跨平台渲染一致性保障的关键基础。










