Using fonts from another .dotx when converting .dotx into PDF

Hi,

I have a .dotx without fonts RD-133_without_fonts (1).docx (11.8 KB)

While converting this .dotx into PDF I set up the fontssources folder where I have extracted the fonts subfolder from RD-133_with_fonts (1).docx (22.9 KB)

Unfortunately the .pdf created has not used the correct font, while when I simply convert the the .dotx that contains the fonts, it works all fine.

Furthermore, when I download the font in .otf format in my folder, it works fine.

What I see is that the font embedded in the .dotx has .odttf format. Might the issue be that .odttf format is not supported in in a fonts folder?

Is there another way that I can let aspose use the embedded fonts from another .dotx when it does not find a font?

@avandenhoogen .odtff is not considered as font format by Aspose.Words. If you need to extract the embedded font from DOCX document, you can use the following code:

Document doc = new Document("C:\\Temp\\in.docx");

int[] fontStyles = new int[] { EmbeddedFontStyle.REGULAR, EmbeddedFontStyle.BOLD, EmbeddedFontStyle.ITALIC, EmbeddedFontStyle.BOLD_ITALIC };
for (FontInfo info : doc.getFontInfos())
{
    for (int style : fontStyles)
    {
        byte[] embeddedFont = info.getEmbeddedFont(EmbeddedFontFormat.OPEN_TYPE, style);
        if (embeddedFont != null)
        {
            String fontFileName = "C:\\Temp\\fonts\\" + info.getName() + "_" + EmbeddedFontStyle.toString(style) + ".otf";
            Files.write(Paths.get(fontFileName), embeddedFont);
        }
    }
}

when using this sample code to extract embedded fonts from a DOCX document, the “embeddedFonts” variable is always null ( nothing is created), but the DOCX document definitely has embedded fonts.

Furthermore, if .odtff is not considered as font format by Aspose.Words, how come when converting the .dotx that contains this embedded font files, the fonts are seen well and PDF is created correctly?

also is it possible to convert .odttf to .otf? Does Aspose support this?

@avandenhoogen

I can successfully extract fonts from the DOCX document you have attached in the initial post.

Aspose.Words internally decodes the embedded fonts and uses them upon rendering documents.

Thank you very much for the quick responses. It works now!

I do have another question: is it possible to not have to extract the fonts to a physical folder, instead have a callback implemented that will provide inputstreams to the fonts when Aspose needs them?

@avandenhoogen You can achieve this using StreamFontSource.

1 Like

Dear @alexey.noskov,

While using StreamFontSource does seem to work, it looks like that when it’s set, Aspose will only use that as source for fonts.

FontSettings fontSettings = new FontSettings();
fontSettings.setFontsSources(new FontSourceBase[] { new StreamFontSourceFile() });
document.setFontSettings(fontSettings);

Is it also possible to tell Aspose to look at thie specified fonts source, only when certain fonts cannot be found? So, when font is installed and availabel on OS level, Aspose should use that, otherwise it should look at the specified font source.

@avandenhoogen You can specify several font sources using FontSettings.setFontsSources. In the font source, through the constructor, you can specify font source priority. The font source priority is used when there are fonts with the same family name and style in different font sources. In this case Aspose.Words selects the font from the source with the higher priority value.

@alexey.noskov I have tried this approach, however, unfortunately the exported font loses it’s font name, making it unusable later on when resolving fonts.

new MemoryFontSource(embeddedFont).getAvailableFonts().get(0).getFullFontName()

returns ___WRD_EMBED_SUB_43, while info.getName() returns Cristo Rey.

Later on, when I set FontSource on my document using this MemoryFontSource, it’s not able to find the ‘Cristo Rey’ font and substitutes with another font.

How to ensure that the exported font (by info.getEmbeddedFont) has the correct font name, such that it can be used later on to resolve fonts when converting docx to PDF?

See FontsExportedFromDotxLosesFontName.zip (30.9 KB)

Furthermore, when I try to set font substitution, it doesn’t work and Aspose still uses it’s own substitution: fontSettings.getSubstitutionSettings().getTableSubstitution().addSubstitutes("Cristo Rey", new String[] { "Arial" });
still causes
Aspose Warning: Font 'Cristo Rey' has not been found. Using 'Calibri' font instead. Reason: alternative name from document.

@avandenhoogen Font name of the attached font is ___WRD_EMBED_SUB_43:

Also, if convert your DOTX document to PDF using MS Word, it also does not use the embedded Cristo Rey font. Though Aspose.Words is able to use this font when convert the attached DOTX to PDF: out.pdf (10.4 KB)

Alternative name font substitution rule is applied before Table Substitution rule. Please see our documentation for more information:
https://docs.aspose.com/words/java/manipulate-and-substitute-truetype-fonts/#font-availability-and-substitution

Thanks for the quick response. Is there a way to let Aspose not use the alternative name font? Or is there a way to clear the altName node from the fontTable using Aspose?

Based on the input above, I found the following solution.

Instead of using the substitution table rule, I simply change the altNames of the corresponding fontInfos in the document.

FontInfoCollection fontInfos = document.getFontInfos();
for (int i = 0; i < fontInfos.getCount(); i++) {
    FontInfo fontInfo = fontInfos.get(i);
    if (fontInfo.getName().equals("Cristo Rey")) {
        fontInfo.setAltName("___WRD_EMBED_SUB_43");
    }
}

I am just not 100% sure, will all fonts used in the .docx be listed in fontInfos?

@avandenhoogen Document.FontInfos list the fonts which are in the document’s font table. It is not required for the consumer applications to update the font table. So it might contain not actual data about the fonts used in the document. In such case, however, the solution with Table Substitution rule should work for your, since there are no alt names for fonts specified in the document.