Hello,
we noticed a problem with fonts on a Linux machine. We are converting an html to pdf using Java. The default font for the html is Arial, there may be other true type fonts used in the html. If there are no expected true type fonts installed on the machine, then the font is selected randomly, and it results in either unreadable pdf document, or a 'Font embedding is prohibited because of font license restrictions" exception if the randomly chosen font cannot be embedded.
We tried to set a default font and substitute fonts but it seems that the substitutions are ignored. What is the correct way to implement font substitutions?
I am adding is a sample code below. I tried to make the “Noto Sans” font as a default one and as a font substitute for Arial. I tried to use the FontSettings.setFontSubstitutes to add a font substitution, and FontSettings.getFontSubstitutes(“Arial”) has a Noto Sans in the result list, but another font is used in the output pdf. I also found a sample code https://github.com/aspose-pdf/Aspose.PDF-for-Java/blob/master/Examples/src/main/java/com/aspose/pdf/examples/AsposePdfExamples/DocumentConversion/DefaultFontWhenSpecificFontMissing.java
that uses the class " CustomSubst1 extends CustomFontSubstitutionBase" as can be seen in my sample, but its method trySubstitute is not invoked at all, and FontSettings.getFontSubstitutes(“Arial”) returns an empty list if FontSettings.setFontSubstitutes is not used.
public class FontTest
{
public static void main(String[] args) throws IOException
{
FontTest asposeTest = new FontTest();
asposeTest.loadAsposeLicense();
FontSettings.setDefaultFontName("Noto Sans");
FontSettings.setFontSubstitutes("Arial", new String[]{"Noto Sans"});
String[] currentFontSubstitutes = FontSettings.getFontSubstitutes("Arial");
CustomSubst1 subst1 = new CustomSubst1();
FontRepository.getSubstitutions().add(subst1);
for(String font : currentFontSubstitutes)
{
System.out.println("currentFontSubstitutes: " + font);
}
asposeTest.generateFromSimpleHtml();
}
private void generateFromSimpleHtml()
{
HtmlLoadOptions options = new HtmlLoadOptions();
InputStream is = FontTest.class.getResourceAsStream("/simple.html");
Document document = new Document(is, options);
document.FontSubstitution.add(new Document.FontSubstitutionHandler()
{
public void invoke(Font font, Font newFont)
{
// print substituted FontNames into console
System.out.println("Warning: Font " + font.getFontName() + " was substituted with another font -> " + newFont.getFontName());
}
});
document.save("/opt/arjanos/tmp/simple.pdf");
}
public void loadAsposeLicense()
{
InputStream licenseStream = getClass().getClassLoader().getResourceAsStream("lt/test/Aspose.Pdf.lic");
try(licenseStream)
{
License license = new License();
license.setLicense(licenseStream);
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static class CustomSubst1 extends CustomFontSubstitutionBase
{
public boolean trySubstitute(OriginalFontSpecification originalFontSpecification, /* out */com.aspose.pdf.Font[] substitutionFont)
{
System.out.println("TrySubstitute");
// 1. substitute Arial font with TimesNewRoman font
if("Arial".equals(originalFontSpecification.getOriginalFontName()))
{
System.out.println("Trying to substitute Arial");
substitutionFont[0] = FontRepository.findFont("Noto Sans");
return true;
}
else
{
return super.trySubstitute(originalFontSpecification, substitutionFont);
}
// 2. or substitute all the fonts with the MSGothic font
// substitutionFont[0] = FontRepository.findFont("Noto Sans");
// return true;
}
}
}
simple.html:
<!DOCTYPE html>
@media all {
body {
font-family: Arial, Helvetica, "Helvetica Neue", sans-serif;
}
}
</style>
</head>
<body>
<div>
<p>Test</p>
</div>
</body>
</html>
What are we doing wrong? Or does font substitution work in some other way?
Thank you!
Arjana Bivainiene