Hi there
When trying to convert a word document to a PDF, where the fonts used within the word document are not part of the underlying system, Aspose tries to find a suitable substitution font (as stated at http://www.aspose.com/docs/display/wordsjava/How+Aspose.Words+Uses+True+Type+Fonts).
Code Snippet:
public static void convertToPdf(File inputFile, File outputFile) throws Exception {
try (FileInputStream fis = new FileInputStream(inputFile); FileOutputStream fos = new FileOutputStream(outputFile)) {
Document doc = new Document(fis);
doc.setWarningCallback(new HandleDocumentWarnings());
doc.save(fos, new PdfSaveOptions());
}
}
Warning callback is implemented as described in http://www.aspose.com/docs/display/wordsjava/How+to+Receive+Notification+of+Missing+Fonts+and+Font+Substitution+during+Rendering
Output for System 1
Font substitution: Font ‘Calibri’ has not been found. Using ‘Cousine’ font instead. Reason: first available font.
Font substitution: Font ‘Times New Roman’ has not been found. Using ‘Cousine’ font instead. Reason: first available font.
Output for System 2
Font substitution: Font ‘Calibri’ has not been found. Using ‘Symbol Neu’ font instead. Reason: first available font.
Font substitution: Font ‘Times New Roman’ has not been found. Using ‘Symbol Neu’ font instead. Reason: first available font.
Tested with Aspose Words 16.2 and 16.4.
Both systems have Ubuntu 14.04.4 LTS (server edition) with only the following three fonts package installed (see https://en.wikipedia.org/wiki/Croscore_fonts):
fonts-croscore
fonts-crosextra-caladea
fonts-crosextra-carlito
Questions:
1. How is “most suitable font” defined (point 4) [PANOSE?]? Is there a way to give hints to Aspose for finding a suitable font? I don’t use addFontSubstitutes because the font substitution would be checked right after Point 1, which is to early because embedded fonts would be omitted. I would expect that Carlito would be a suitable substitution for Calibri for example.
2. “First available font” doesn’t seem to be deterministic because resulting in different fonts on different systems. Is there a way that I can assure a “last” font option? Setting FontSettings.DefaultFontName would always use the default font instead of finding a more suitable one, thus not really a preferable solution. Font “Symbol” might always be a bad choice
A callback to allow specific fonts to be chosen dynamically as stated in http://www.aspose.com/docs/display/wordsjava/How+to+Specify+the+Default+Font+to+use+when+Rendering would be really great.
Kind regards and thanks
Stephan
Document doc = new Document(getMyDir() + "Rendering.doc");
// Retrieve the array of environment-dependent font sources that are searched by default.
// We add this array to a new ArrayList to make adding or removing font entries much easier.
ArrayList fontSources = new ArrayList(Arrays.asList(FontSettings.getDefaultInstance().getFontsSources()));
// Add a new folder source which will instruct Aspose.Words to search the following folder for fonts.
FolderFontSource folderFontSource = new FolderFontSource("/usr/myfonts/", true);
// Add the custom folder which contains our fonts to the list of existing font sources.
fontSources.add(folderFontSource);
// Convert the Arraylist of source back into a primitive array of FontSource objects.
FontSourceBase[] updatedFontSources = (FontSourceBase[])fontSources.toArray(new FontSourceBase[fontSources.size()]);
// Apply the new set of font sources to use.
FontSettings.getDefaultInstance().setFontsSources(updatedFontSources);
doc.save(getMyDir() + "Rendering.SetFontsFolders Out.pdf");
Hi Tahir
Thank you for your response.
I output the font sources to the console by iterating over FontSettings.getDefaultInstance().getFontsSources() and by using SystemFontSource.getSystemFontFolders()). They are identical on both systems and already contain the path where the croscore fonts are located (subfolder of /usr/share/fonts/ in my case). I still used your code and added two paths explicitly (/usr/share/fonts/truetype/croscore/, /usr/share/fonts/truetype/crosextra/), the result is the same. One system uses “Symbol Neu” as fallback, the other ones uses “Cousine”.
By using FontSettings.AddFontSubstitutes it works as expected but this isn’t a preferable solution due to the reason mentioned in the first post (see question 1). Because of this a new question (or maybe more a feature request) arises beside the 2 stated in the first post already.
Question 3 (related to http://www.aspose.com/docs/display/wordsjava/How+Aspose.Words+Uses+True+Type+Fonts):
Wouldn’t it be in general more useful if the explicitly defined font substitutions would be checked after step #2 (instead of after step #1)? If the font is provided within the document, I assume it’s better to take that one as to take a substitution font).
Kind regards
Stephan
// Aspose.Words will prefer fonts from "Folder1" over the fonts from "Folder2". FolderFontSource folder1 = new FolderFontSource("Folder1", false, 2); FolderFontSource folder2 = new FolderFontSource("Folder2", false, 1); FontSettings.setFontsSources(new FontSourceBase[] {folder1, folder2});
Hi Tahir
SetFontSubstutites/AddFontSubstitutes
Exactly, I assume that checking if the required font is part of the embedded fonts of the document is preferred over applying font substitution first. I recommend thus applying font substitution after step #2 and not after step #1 as it currently is. I’m not completely sure what you mean by your question, so here is an example:
- document with font Calibri
- font Calibri is embedded within Word document
- no font Calibri is installed
- font Carlito is installed
- font substitution Calibri -> Carlito is added via addFontSubstitutes
#1: No exact font match
Font substitution is applied, thus Carlito is used
Desired behavior
#1: No exact font match
#2: Font Carlibri is found within document -> Calibri is used
"most suitable font" (question 1 from first post)
Is there any way where this will not result in the reason ‘first available font’?
If not, then question 2 from the first post is obsolete.
FontSourceBase.Priority
Thanks for the information about FontSourceBase.Priority. The priority value seems to be ignored at least for ‘first available font’, but the order in which the font sources are added to the list seems to be relevant according to my tests (maybe priority works as expected when used for fonts with same family name and style as you mentioned):
Test run #1
Folder: /usr/share/fonts/truetype/crosextra/ (recursive: true, priority 2)
Folder: /usr/share/fonts/truetype/croscore/ (recursive: true, priority 1)
-> Font substitution: Font ‘Calibri’ has not been found. Using ‘Carlito’ font instead. Reason: first available font.
Test run #2
Folder: /usr/share/fonts/truetype/crosextra/ (recursive: true, priority 1)
Folder: /usr/share/fonts/truetype/croscore/ (recursive: true, priority 2)
-> Font substitution: Font ‘Calibri’ has not been found. Using ‘Carlito’ font instead. Reason: first available font.
Test run #3
Folder: /usr/share/fonts/truetype/croscore/ (recursive: true, priority 2)
Folder: /usr/share/fonts/truetype/crosextra/ (recursive: true, priority 1)
-> Font substitution: Font ‘Calibri’ has not been found. Using ‘Symbol Neu’ font instead. Reason: first available font.
Test run #4
Folder: /usr/share/fonts/truetype/croscore/ (recursive: true, priority 1)
Folder: /usr/share/fonts/truetype/crosextra/ (recursive: true, priority 2)
-> Font substitution: Font ‘Calibri’ has not been found. Using ‘Symbol Neu’ font instead. Reason: first available font.
Kind regards and thanks again
Stephan
bsiagch:
#1: No exact font matchFont substitution is applied, thus Carlito is usedDesired behavior#1: No exact font match#2: Font Carlibri is found within document -> Calibri is used
bsiagch:
The priority value seems to be ignored at least for 'first available font', but the order in which the font sources are added to the list seems to be relevant according to my tests (maybe priority works as expected when used for fonts with same family name and style as you mentioned):
Thank you very much Tahir for the feedback and logging the feature request.
A final question remains:
How is “most suitable font” defined (point 4)? Is there any way where this will not result in the reason ‘first available font’?
Kind regards
Stephan
Thanks for the response and the fix. I will test it as soon as 16.7 is released.
Kind regards
Stephan
The issues you have found earlier (filed as WORDSNET-13817) have been fixed in this .NET update and this Java update.
This message was posted using Notification2Forum from Downloads module by aspose.notifier.
Thanks, tested successfully with 16.8.0
Kind regards
Stephan