Hello, we are getting an error within our company’s application that our font path cannot be found as a file or resource. We recently purchased a new license, and had to update the aspose-words dependency so that we could remove the “Evaluation Only’” red watermark text from our generated documents. Following the upgrade of the dependency, our application cannot find the primary font that we use. We have a method that utilizes the FontSettings class and the setFontsFolder method to reference a hard-coded path within our property files for each environment that the application eventually gets deployed to; though it is the same path for each environment aside from our local properties file. Just as a test, we deployed the application to one of our lower environments and verified that the font path that the application looks for actually exists within that environment; which it does. We are unable to determine why this same path no longer works correctly following the dependency update, but they seem to be directly related. The previous version of aspose-words that we used was version 10.6 and we are now using version 23.7, so there was a significant jump in versions. Can provide more details as needed. Thank you!
@s.vance Please make sure the specified folder exists and is accessible. Also, please try specifying absolute path to the fonts folder. Please see our documentation to learn how to specify fonts location:
https://docs.aspose.com/words/java/specify-truetype-fonts-location/
Also, please try using FolderFontSource
and specify WarningCallback
to get notification about issues while loading fronts from the specified font source.
Hello @alexey.noskov and thank you for your reply. The specified folder does exist, as we verified that the path & font exist when looking into the server that our application is deployed to. Additionally, this path was working completely fine before updating the aspose-words dependency. We have attempted changing to an absolute path, however this unfortunately has not proven successful. Currently we are specifying font location by creating a new FontSettings and setting it via the SetFontsFolder method; which is listed within the “Specify One or Multiple Font Folders” section of the “specify-truetype-fonts-location” documentation that you had linked. Seemingly, the only difference is that we are not initializing a new Document; and it doesn’t seem like there are any references in the application to a new Document. (Perhaps the older version of aspose-words did not require this previously?) Additionally, the fonts within our application do not default to the “Fanwood” font, it cannot find our base font and seems to substitute for something else. I mention this because the documentation mentions that if all folders were ignored, Aspose.Words will use Fanwood font as a default - which it is not doing. When including getDefaultInstance into fontsettings, I do get a message that “Fanwood” font is being used, whereas typically our application throws an error that it cannot find our base font as a file or resource and uses a different substitution font that is not “Fanwood”. I have also attempted to use FolderFontSource to use a local system folder which contains fonts as a font source with no success. It just throws the same error. I am confused as to why our original way of accessing the font path is no longer working
@s.vance Please try setting font folder for default font setting instance as shown below:
FontSettings.getDefaultInstance().setFontsFolders(new String[] {"C:\\Temp\\fonts"}, true);
@alexey.noskov We are using a fontpath defined as a hard-coded path (/usr/fonts-local) within our different environment property files. The fontpath variable (called fontPath) is referenced when we’re setting the font folders, so I tried the line you sent above, and additionally tried to replace the “C:\Temp\fonts” path with our variable and also tried it with the hard-coded path of our font. All three attempts were met with the same error - “/usr/fonts-local/CALIBRI.TTF not found as file or resource.”
@s.vance Unfortunately, I cannot reproduce the problem on my side. Could you please provide a full code that will allow us to reproduce the problem? I have used the following code:
FontSettings.getDefaultInstance().setFontsFolders(new String[] {"C:\\Temp\\fonts"}, true);
Document doc = new Document("C:\\Temp\\in.docx");
doc.setWarningCallback(new FontSubstitutionWarningCollector());
doc.save("C:\\Temp\\out.pdf");
private static class FontSubstitutionWarningCollector implements IWarningCallback {
public void warning(WarningInfo info) {
if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) {
System.out.println(info.getDescription());
}
}
}
This is the code we’re using to reference the font path. -
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent)
{
String fontPath = environmentContext.getProperty("fontPath");
LOGGER.info("Setting font path to '" + fontPath + "'");
FontSettings fontSettings = new FontSettings();
fontSettings.setFontsFolder(fontPath, false);
}
In our environmentContext file the fontpath is defined as - "fontPath=/usr/fonts".
We have the font we’re using defined within a different class -
"public static final BaseFont Calibri = getIdentityFont( "CALIBRI.TTF" );"
and this is the getIdentitifyFont method we’re using -
private static BaseFont getIdentityFont( String fontName ) {
BaseFont baseFont = null;
try {
String path = ContextHolder.getBean( EnvironmentContext.class ).getProperty( "fontPath" ) + "/" + fontName;
File f = new File( path );
if( !f.exists() ) {
path = ContextHolder.getBean( EnvironmentContext.class ).getProperty( "fontPath" ) + "/" + fontName;
}
if( path.toLowerCase().endsWith( ".ttc" ) ) {
path = path + ",0";
}
baseFont = BaseFont.createFont( path, BaseFont.IDENTITY_H, BaseFont.EMBEDDED );
baseFont.setSubset( true );
} catch( Exception e ) {
log.error( e.getMessage(), e );
e.printStackTrace();
}
return baseFont;
}
Unfortunately, I am limited in what I can provide to you on a public forum, but hopefully this gives you more context.
@s.vance First of all in your onApplicationEvent
you create a new instance of FontSettings
and set font folder for it. But the created instance is not used anywhere. You should either assign the created FontSettings
instance to the Document
or use default FontSettings
instance:
FontSettings.getDefaultInstance().setFontsFolders(new String[] {fontPath}, true);
Also, as I can see the method getIdentityFont
that actually throws an exception does not use Aspose.Words.
@alexey.noskov thank you for your reply, that seems to have worked and is now pulling the correct font, however the Encoding type is different now from what our production environment has for that particular font. We have four uses of the Calibri font in our documents, and all four uses are utilizing the Identity-H encoding type; whereas now they seem to be using ANSI. When testing a different font, it seems to also use the ANSI encoding. Is there a way to set the encoding for a font so that it will be Identity-H encoding to match our production environment?
@s.vance Upon saving document as PDF, Aspose.Words is using WinAnsiEncoding
for Latin text and Identity-H
encoding for other Unicode text. Unicode mapping is specified in ToUnicode
CMap which in turn uses UTF-16BE (which is required by PDF specification). Also in specific cases when there are no direct CID->Unicode mapping Aspose.Words uses ActualText
in marked content sequence which also uses UTF-16BE.