Font Management
ComPDF SDK can read font families and styles installed on the device and generate a font PsName that can be used in annotations, forms, watermarks, headers & footers, Bates numbers, and other scenarios. This chapter focuses on three things: understanding font families and styles, getting available fonts, and importing custom fonts.
Understanding font families, styles, and PsName
Font Family
Font family is the series name of a font and represents a collection of fonts with a consistent design style.
For example, Helvetica is a font family that may include multiple styles:
- Helvetica Regular
- Helvetica Bold
- Helvetica Italic
These fonts share the same overall style but differ in weight or italicization.
Font Style
Font style distinguishes specific variants within the same font family, such as Regular, Bold, and Italic.
PsName
PsName is the final font name used by the SDK when setting a font. In most cases, you first get the font family and style, then generate the corresponding PsName with CPDFTextAttribute.FontNameHelper.obtainFontName().
Getting Fonts
If you want to set fonts for annotations or forms, the usual flow is:
- Retrieve all available font families (Font Family) on the system.
- Select a target font family from the list and obtain the corresponding
CPDFFontNameobject. - From
CPDFFontName, retrieve the list of supported styles (Font Style) for that family. - Generate the corresponding font
PsNamebased on the font family name and style name. - Use the generated
PsNameto set fonts for annotations, forms, and other features.
The example below shows how to obtain a usable PsName. In a real project, you can also display the font list and style list in the UI and let the user choose the font.
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
)
}After you get a PsName, you can apply it to the corresponding feature object:
- For FreeText annotations, call
CPDFFreetextAnnotation.setFreetextDa(new CPDFTextAttribute(psName, fontSize, fontColor)). - For ListBox forms, call
CPDFListboxWidget.setFontName(psName). - Other scenarios, such as watermarks, headers & footers, and Bates numbers, can reuse the same
PsName.
Importing Custom Fonts
By default, the SDK uses fonts installed on the device system. Since system font sets may vary across regions and devices, you can extend the available fonts by importing custom fonts.
Before you start, make sure that:
- You have prepared the font files you want to import, such as
.ttfor.otf. - The font files are copied to a local directory that the app can access.
CPDFSdk.setImportFontDir()is called beforeCPDFSdk.init().- If your project enables SDK auto-initialization, switch to manual
CPDFSdk.init()so the font directory is configured first.
The example below uses the demo helper CFileUtils.copyAssetsDirToPhone() to copy assets/extraFonts into the app's private directory. If your project does not include this helper, use your own file copy logic to complete the same step.
// Copy fonts from assets to the app storage directory
String fontDir = new File(getFilesDir(), "extraFonts/").getAbsolutePath();
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts",
getFilesDir().getAbsolutePath()
);
// Whether to also load system fonts
boolean addSysFont = true;
// Set font import directory
CPDFSdk.setImportFontDir(fontDir, addSysFont);
// Initialize SDK
CPDFSdk.init(this, "your license key", true);// Copy fonts from assets to the app storage directory
val fontDir = File(filesDir, "extraFonts/").absolutePath
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts",
filesDir.absolutePath
)
// Whether to also load system fonts
val addSysFont = true
// Set font import directory
CPDFSdk.setImportFontDir(fontDir, addSysFont)
// Initialize SDK
CPDFSdk.init(this, "your license key", true)Note The font import directory must be set before SDK initialization, otherwise the fonts in that directory will not be loaded during the current initialization flow.
Updating the Imported Font Directory
After the SDK has been initialized, you can still dynamically update the current font directory via CPDFDocument.setImportFontDir().
Steps:
- Prepare a new font directory and copy the font files into it.
- Call
CPDFDocument.setImportFontDir(fontDir, addSysFont)to update the current font source. - Call
CPDFFont.getFontName()again to get the latest available font list.
String fontDir = new File(getFilesDir(), "extraFonts2/").getAbsolutePath();
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts2",
getFilesDir().getAbsolutePath()
);
boolean addSysFont = true;
// Update font directory
CPDFDocument.setImportFontDir(fontDir, addSysFont);val fontDir = File(filesDir, "extraFonts2/").absolutePath
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts2",
filesDir.absolutePath
)
val addSysFont = true
// Update font directory
CPDFDocument.setImportFontDir(fontDir, addSysFont)Note After re-specifying the font directory, any previously set font directories will be cleared, and only the fonts in the currently specified directory will be retained.
After the update, you can follow the previous section again to regenerate PsName and apply it to the corresponding feature object.