字体管理
ComPDF SDK 可以读取设备中已安装的字体字族及其样式,并生成可用于注释、表单、水印、页眉页脚、贝茨码等场景的字体 PsName。 本章重点说明三件事:如何理解字族与样式、如何获取可用字体,以及如何导入自定义字体。
理解字族、样式和 PsName
Font Family(字族)
字族是字体的系列名称,用于表示一组设计风格一致的字体集合。
例如,Helvetica 是一个字体字族,该字族下可能包含多种样式:
- Helvetica Regular
- Helvetica Bold
- Helvetica Italic
这些字体在整体风格上保持一致,但在字重或倾斜程度上有所区别。
Font Style(样式)
样式用于区分同一字族中的具体变体,例如 Regular、Bold、Italic。
PsName
PsName 是 SDK 用于设置字体的最终名称。通常需要先拿到字族和样式,再通过 CPDFTextAttribute.FontNameHelper.obtainFontName() 生成对应的 PsName。
获取字体
如果您要为注释或表单设置字体,通常按以下顺序操作:
- 获取系统中可用的所有字体字族(Font Family)。
- 从字族列表中选择目标字族,获取对应的
CPDFFontName对象。 - 从
CPDFFontName中获取该字族支持的样式列表(Font Style)。 - 根据字族名称与样式名称,生成对应的字体
PsName。 - 使用生成的
PsName为注释、表单等功能设置字体。
下面的示例演示如何获取一个可直接使用的 PsName。实际项目中,您也可以将 fontList 和 fontStyles 展示到界面上,让用户自行选择字体。
public String getFontPsName() {
List<CPDFFontName> fontList = CPDFFont.getFontName();
if (fontList.isEmpty()) {
return null;
}
CPDFFontName fontName = fontList.get(0);
List<String> fontStyles = fontName.getStyleName();
if (fontStyles.isEmpty()) {
return null;
}
return CPDFTextAttribute.FontNameHelper.obtainFontName(
fontName.getFamilyName(),
fontStyles.get(0)
);
}fun getFontPsName(): String? {
val fontName = CPDFFont.getFontName().firstOrNull() ?: return null
val styleName = fontName.styleName.firstOrNull() ?: return null
return CPDFTextAttribute.FontNameHelper.obtainFontName(
fontName.familyName,
styleName
)
}拿到 PsName 后,可按对应功能对象的 API 设置字体。例如:
- FreeText 注释可调用
CPDFFreetextAnnotation.setFreetextDa(new CPDFTextAttribute(psName, fontSize, fontColor))。 - ListBox 表单可调用
CPDFListboxWidget.setFontName(psName)。 - 其他场景(如水印、页眉页脚、贝茨码)也可复用同一个
PsName。
导入自定义字体
默认情况下,SDK 使用设备系统中已安装的字体。由于不同地区、不同设备的系统字体集可能存在差异,您可以通过字体导入接口扩展可用字体。
在开始前,请先确认:
- 已准备好要导入的字体文件,例如
.ttf或.otf。 - 字体文件会被复制到应用可访问的本地目录。
CPDFSdk.setImportFontDir()会在CPDFSdk.init()之前调用。- 如果项目启用了 SDK 自动初始化,请改为手动调用
CPDFSdk.init(),以确保字体目录先完成配置。
下面的示例使用 Demo 中的 CFileUtils.copyAssetsDirToPhone() 将 assets/extraFonts 复制到应用私有目录。如果您的项目没有这个工具类,请使用自己的文件复制逻辑完成相同步骤。
// 将 assets 中的字体复制到应用存储目录
String fontDir = new File(getFilesDir(), "extraFonts/").getAbsolutePath();
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts",
getFilesDir().getAbsolutePath()
);
// 是否同时加载系统字体
boolean addSysFont = true;
// 设置字体导入目录
CPDFSdk.setImportFontDir(fontDir, addSysFont);
// 初始化 SDK
CPDFSdk.init(this, "your license key", true);// 将 assets 中的字体复制到应用存储目录
val fontDir = File(filesDir, "extraFonts/").absolutePath
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts",
filesDir.absolutePath
)
// 是否同时加载系统字体
val addSysFont = true
// 设置字体导入目录
CPDFSdk.setImportFontDir(fontDir, addSysFont)
// 初始化 SDK
CPDFSdk.init(this, "your license key", true)注意 字体导入目录必须在 SDK 初始化之前设置,否则当前初始化流程不会加载该目录中的字体。
更新导入的字体目录
在 SDK 初始化完成后,您仍可通过 CPDFDocument.setImportFontDir() 动态更新当前使用的字体目录。
操作步骤:
- 准备新的字体目录,并将字体文件复制到该目录。
- 调用
CPDFDocument.setImportFontDir(fontDir, addSysFont)更新当前字体来源。 - 重新调用
CPDFFont.getFontName(),获取最新的可用字体列表。
String fontDir = new File(getFilesDir(), "extraFonts2/").getAbsolutePath();
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts2",
getFilesDir().getAbsolutePath()
);
boolean addSysFont = true;
// 更新字体目录
CPDFDocument.setImportFontDir(fontDir, addSysFont);val fontDir = File(filesDir, "extraFonts2/").absolutePath
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts2",
filesDir.absolutePath
)
val addSysFont = true
// 更新字体目录
CPDFDocument.setImportFontDir(fontDir, addSysFont)注意 重新指定字体目录后,之前已设置的字体目录会被清除,仅保留当前指定目录中的字体。
更新完成后,您可以按上一节的流程重新生成 PsName,并将其应用到对应功能对象。