Font Substitution Issue When Converting PDF to PDF/A-3: Helvetica Bold Not Preserved

Hello Aspose Team,

I am using the latest version(25.4) of Aspose.PDF for Java to convert regular PDFs to PDF/A-3 format. In the input PDFs, the font used is Helvetica, including some text with bold styling.

Since I’m working on a Debian machine where Helvetica is unavailable, during the conversion to PDF/A-3, Helvetica is being replaced with OpenSansRegular. However, the bold styling is lost, and all text is displayed in regular weight, even where it was originally bold.

I have Liberation Sans installed on my system, and my expectation is that Helvetica should be replaced with Liberation Sans. How can I ensure that font substitution works correctly, preserving the bold styling during the conversion?

@anishk11

Below method or code snippet can be used to add font substitution and monitor it:

document.FontSubstitution.add(new Document.FontSubstitutionHandler() {
            public void invoke(Font font, Font newFont) {
                System.out.println("WARNING: Font " + font.getFontName() + " was substituted with another font -> " + newFont
                        .getFontName());
            }
        });

In case you still notice any issues, please let us know by sharing your sample file and complete sample code snippet. We will further proceed accordingly to assist you.

1 Like

Thank you for your response. I’ve integrated the suggested code to monitor font substitution, and I can confirm that “Helvetica-Bold” is being replaced with “Open Sans Regular” during processing.

Please see the log output below for reference:
**WARNING: Font Helvetica-Bold was substituted with another font → Open Sans Regular **
WARNING: Font Helvetica was substituted with another font → Open Sans Regular

For further context, I’m including the complete code I’m using below.

public class PDFAService extends FunctionService {

public PDFAService(Context context) throws IAException {
    super(context);

    try (InputStream licenseStream = getClass().getClassLoader().getResourceAsStream("Aspose.PDF.Java.lic")) {
        if (licenseStream == null) {
            throw new IAException("PDF-1005", EMPTY_PLACEHOLDERS, "to-archive-format", null);
        }
        License license = new License();
        license.setLicense(licenseStream);
        log.info("PDF-CONVERSION_INIT: Setting license");
    } catch (Exception e) {
        throw new IAException("PDF-1005", EMPTY_PLACEHOLDERS, "to-archive-format", null);
    }
}


public FileDownloadDTO convertPDF(FileDTO request) throws IAException {

    log.info("PDF-CONVERSION_BEGIN: Convert pdf document");
    if (request == null) {
        throw new IAException("PDF-1001", EMPTY_PLACEHOLDERS, "to-archive-format", null);
    }
    IAInboundFile fileContent = request.getFileContent();
    MultipartFile uploadedFile = fileContent.file();
    if (uploadedFile == null || uploadedFile.getContentType() == null ||
            !uploadedFile.getContentType().equals("application/pdf")) {
        throw new IAException("PDF-1002", EMPTY_PLACEHOLDERS, "to-archive-format", null);
    }
    String inputFilePath = uploadedFile.getOriginalFilename();
    if (inputFilePath == null || !inputFilePath.endsWith(".pdf")) {
        throw new IAException("PDF-1002", EMPTY_PLACEHOLDERS, "to-archive-format", null);
    }

    ByteArrayOutputStream logOutputStream = new ByteArrayOutputStream();
    FileDownloadDTO fileDownloadDTO = new FileDownloadDTO();
    // Create a ByteArrayOutputStream to capture the log output
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    try {
        Document doc = new Document(request.getFileContent().file().getInputStream());
        doc.FontSubstitution.add(new Document.FontSubstitutionHandler() {
            public void invoke(Font font, Font newFont) {
                log.warn("WARNING: Font " + font.getFontName() + " was substituted with another font -> " + newFont
                        .getFontName());
            }
        });
        log.info("PDF-CONVERSION_INFO: created document object");
        if (!doc.convert(logOutputStream, PdfFormat.PDF_A_3A, ConvertErrorAction.Delete)) {
            throw new RuntimeException("PDF conversion failed! The document is not convertible. Check the log.");
        }
        log.info("PDF-CONVERSION_INFO: converted document object");
        doc.save(byteArrayOutputStream, SaveFormat.Pdf);
        log.info("PDF-CONVERSION_INFO: saved document object");
    } catch (Exception e) {
        log.error("PDF-CONVERSION_ERROR: convertion failed", e);
        log.error("PDF/A-3a conversion log: " + logOutputStream.toString());
        throw new IAException("PDF-1003", EMPTY_PLACEHOLDERS, "to-archive-format", null);
    }

    try {
        String outputFileName = inputFilePath.replace(".pdf", "_archive.pdf");
        Resource resource = new SIByteArrayResource(byteArrayOutputStream.toByteArray(), outputFileName);
        fileDownloadDTO.addFile(outputFileName, resource);
    } catch (Exception e) {
        log.error("PDF-CONVERSION_DOWNLOAD_ERROR: download failed", e);
        throw new IAException("PDF-1004", EMPTY_PLACEHOLDERS, "to-archive-format", null);
    }

    return fileDownloadDTO;
}

}

In order to achieve font substitution, you can force it using below method:

FontRepository.getSubstitutions().add(new SimpleFontSubstitution("originalFontName", "SubstitutionFontName"));

Please use above code and let us know if you face any issues.

1 Like

Thank you! The font substitution below resolved the issue and allowed me to successfully convert the PDF to PDF/A-3 format.

FontRepository.getSubstitutions().add(new SimpleFontSubstitution(“Helvetica”, “Liberation Sans”));
FontRepository.getSubstitutions().add(new SimpleFontSubstitution(“Helvetica-Bold”, “Liberation Sans Bold”));

@anishk11

Its nice to know that your issue has been resolved. Please keep using the API and feel free to let us know in case you face any other issues by creating a new forum thread.