Order of the fonts in the Font Substituion Table

Our product is using Aspose.Words for Java 19.4 and convert word docx/doc/xml(word2003) to PDF.

The current default Linux font table substitution rule provided by Aspose from common Windows system font is as follows in the order specified:

<Item OriginalFont=“Arial” SubstituteFonts=“Garuda, FreeSans, Liberation Sans, DejaVu Sans” />
<Item OriginalFont=“Courier New” SubstituteFonts=“FreeMono, Liberation Mono, DejaVu Sans Mono” />
<Item OriginalFont=“Times New Roman” SubstituteFonts=“FreeSerif, Liberation Serif, DejaVu Serif” />

e.g. if Arial is not available, Aspose uses Garuda. If Garuda is not found, it looks for FreeSans, Liberation Sans, and DejaVu Sans in this order.

When Arial is substituted to Garuda, you see huge line spacing. (see arial_Garuda.docx.out.pdf)
This would be from the font metrics(ascender/descender) difference as Garuda supports Thai which requires tall font metrics. Also as glyph width is different, word wrap positions are different. In addition, Garuda doesn’t have many language coverage which would result in appearing more glyphs appearing with fallback-font or square boxes. Also, when FreeSans is substituted, it shows same huge line spacing and different word wrap position. Note that FreeSans has many language coverage unlike Garuda. (arial_FreeSans.docx.out.pdf) Whereas Liberation Sans has same font metrics as Arial which gives same word-wrap position and line spacing. (arial_LiberationSans.docx.out.pdf)

Garuda and FreeSans looks more like Arial per the appearance, but Liberation would be better to be first due to the line spacing and word wrapping position problem.
Or is it a bug in aspose as FreeMono or FreeSerif doesn’t have the line spacing problem(* see below)?

Courier New mapping order, “FreeMono->Liberation Mono->DejaVu Sans Mono” is reasonable as FreeMono gives same word-wrapping position and line spacing. Note that ascender/descender are different from Courier New but FreeMono does NOT have the huge line spacing problem unlike Arial to FreeSans mapping. Also Liberation Mono is not Sans Serif but FreeMono is. So FreeMono has priority is good.

Yet for Times New Roman mapping to FreeSerif->Liberation Serif->DejaVu Serif order, the word-wrapping position is slightly different. It could be Liberation Serif could come first before FreeSans. But FreeSerif has more language coverage, this would be reasonable it comes first.

Hereby questions are:

  • Would you please share the background of the order of those substituted fonts?
  • Why Arial to Garuda/FreeSans has huge line spacing? e.g. how Aspose calculate the line spacing?

substituteTestcase.zip (629.2 KB)


Your understanding about font substitution is correct. The answer of your query is well explained in the following article.
Font Availability and Substitution

Moreover, you can use TableSubstitutionRule.AddSubstitutes method to add substitute font names for given original font name according to your requirement.

Please ZIP and attach Garuda and FreeSans fonts here for testing. We will investigate the issue and provide you more information on it.

Tahir, thank you for looking into this so quickly. Please find the attached font filestestcase4Aspose_font.zip (3.8 MB)

And would you please explain why you defined Garuda and FreeSans comes prior to LiberationSans by default?


We have tested the scenario using the latest version of Aspose.Words for Java 19.11 and have not found this issue at our end. So, please use Aspose.Words for Java 19.11.

We are checking this case at our end. We will get back to you soon.


After further investigation, we have noticed that line spacing is incorrect in output PDF when font Arial is substituted to FreeSans. For the sake of correction, we have logged this problem in our issue tracking system as WORDSNET-19597. You will be notified via this forum thread once this issue is resolved.

We apologize for your inconvenience.

Unfortunately, we are unable to generate the same Font.TableSubstitutionRule.default.xml that you shared in this thread using your code example. It seems that you are using different code to generate it. We suggest you please try the latest version of Aspose.Words for Java 19.11 and let us know how it goes on your side.

Thank you. Tried 19.11 (aspose-words-19.11-jdk17.jar) but I am getting same Font.TableSubstitutionRule.default.xml.
Note that I am running on Linux.(Oracle Linux Server release 6.6, Red Hat Enterprise Linux Server release 6.6 (Santiago)) And it’s exactly same rule as when loadLinuxSettings is called.
TableSubstitutionRule substitutionRule = fontSettings.getSubstitutionSettings().getTableSubstitution();
substitutionRule.save(outDir + “Font.TableSubstitutionRule.Linux.xml”);


We have logged this problem in our issue tracking system as WORDSNET-19600 . You will be notified via this forum thread once this issue is resolved.

We apologize for your inconvenience.

The issues you have found earlier (filed as WORDSNET-19597) have been fixed in this Aspose.Words for .NET 19.12 update and this Aspose.Words for Java 19.12 update.

The issues you have found earlier (filed as WORDSNET-19600) have been fixed in this Aspose.Words for .NET 20.2 update and this Aspose.Words for Java 20.2 update.