Font Substitution in Word to Image Conversion

24 Jul 202613 minutes to read

When the necessary fonts used in the Word document have not been installed in the production machine, then Essential® DocIO uses the “Microsoft Sans Serif” as the default font for rendering the text. This leads to preservation differences in the generated image, as each font has different glyphs for characters. To learn more about the default font substitution, click here.

To avoid this, the Essential® DocIO library allows you to specify an alternate font for any missing font used in the Word document.

Use alternate font from installed fonts

You can use any other alternate fonts instead of “Microsoft Sans Serif” to layout and render the text during Word to Image conversion by using the SubstituteFont event.

NOTE

Hook the SubstituteFont event only after the Word document is loaded to ensure it works correctly.

The following code example shows how to use alternate font instead of “Microsoft Sans Serif” when the specified font is not installed in the machine.

using (FileStream fileStream = new FileStream(Path.GetFullPath(@"Data/Template.docx"), FileMode.Open))
{
    //Loads an existing Word document.
    using (WordDocument wordDocument = new WordDocument(fileStream, Syncfusion.DocIO.FormatType.Automatic))
    {
        //Hooks the font substitution event.
        wordDocument.FontSettings.SubstituteFont += FontSettings_SubstituteFont;
        //Creates an instance of DocIORenderer.
        using (DocIORenderer renderer = new DocIORenderer())
        {
            //Convert the entire Word document to images.
            Stream[] imageStreams = wordDocument.RenderAsImages();
            int i = 0;
            foreach (Stream stream in imageStreams)
            {
                //Reset the stream position.
                stream.Position = 0;
                //Save the stream as file.
                using (FileStream fileStreamOutput = File.Create(Path.GetFullPath(@"Output/WordToImage_" + i + ".jpeg")))
                {
                    stream.CopyTo(fileStreamOutput);
                }
                i++;
            }
        }
        //Unhooks the font substitution event after converting to Image.
        wordDocument.FontSettings.SubstituteFont -= FontSettings_SubstituteFont;
    }
}
//Loads an existing Word document
WordDocument wordDocument = new WordDocument("Template.docx", FormatType.Docx);
//Initializes the ChartToImageConverter for converting charts during Word to Image conversion
wordDocument.ChartToImageConverter = new ChartToImageConverter();
//Hooks the font substitution event
wordDocument.FontSettings.SubstituteFont += FontSettings_SubstituteFont;
//Set the scaling mode for charts (Normal mode reduces the file size).
wordDocument.ChartToImageConverter.ScalingMode = ScalingMode.Normal;
//Convert the entire Word document to images.
Image[] images = wordDocument.RenderAsImages(ImageType.Bitmap);
for (int i = 0; i < images.Length; i++)
{
    //Save the image as jpeg.
    images[i].Save("WordToImage_" + i + ".jpeg", ImageFormat.Jpeg);
}
//Unhooks the font substitution event after converting to image
wordDocument.FontSettings.SubstituteFont -= FontSettings_SubstituteFont;
//Closes the instance of Word document object
wordDocument.Close();
'Loads an existing Word document
Dim wordDocument As New WordDocument("Template.docx", FormatType.Docx)
'Initializes the ChartToImageConverter for converting charts during Word to Image conversion
wordDocument.ChartToImageConverter = New ChartToImageConverter()
'Hooks the font substitution event
AddHandler wordDocument.FontSettings.SubstituteFont, AddressOf FontSettings_SubstituteFont
'Set the scaling mode for charts (Normal mode reduces the file size).
wordDocument.ChartToImageConverter.ScalingMode = ScalingMode.Normal
'Convert the entire Word document to images.
Dim images As Image() = wordDocument.RenderAsImages(ImageType.Bitmap)
For i As Integer = 0 To images.Length - 1
    'Save the image as jpeg.
    images(i).Save("WordToImage_" & i & ".jpeg", ImageFormat.Jpeg)
Next
'Unhooks the font substitution event after converting to image
RemoveHandler wordDocument.FontSettings.SubstituteFont, AddressOf FontSettings_SubstituteFont
'Closes the instance of Word document object
wordDocument.Close()

Event Handler to use alternate installed font

The following code example shows how to set the alternate installed font instead of “Microsoft Sans Serif” during Word to Image conversion.

private void FontSettings_SubstituteFont(object sender, SubstituteFontEventArgs args)
{
    //Sets the alternate font when a specified font is not installed in the production environment
    //If "Arial Unicode MS" font is not installed, then it uses the "Arial" font
    //For other missing fonts, uses the "Times New Roman"
    if (args.OriginalFontName == "Arial Unicode MS")
        args.AlternateFontName = "Arial";
    else
        args.AlternateFontName = "Times New Roman";
}
private void FontSettings_SubstituteFont(object sender, SubstituteFontEventArgs args)
{
    //Sets the alternate font when a specified font is not installed in the production environment
    //If "Arial Unicode MS" font is not installed, then it uses the "Arial" font
    //For other missing fonts, uses the "Times New Roman"
    if (args.OriginalFontName == "Arial Unicode MS")
        args.AlternateFontName = "Arial";
    else
        args.AlternateFontName = "Times New Roman";
}
Private Sub FontSettings_SubstituteFont(ByVal sender As Object, ByVal args As SubstituteFontEventArgs)
    'Sets the alternate font when a specified font is not installed in the production environment
    'If "Arial Unicode MS" font is not installed, then it uses the "Arial" font
    'For other missing fonts, uses the "Times New Roman"
    If args.OriginalFontName = "Arial Unicode MS" Then
        args.AlternateFontName = "Arial"
    Else
        args.AlternateFontName = "Times New Roman"
    End If
End Sub

You can download a complete working sample from GitHub.

Event Handler to use alternate font without installing

The following code example shows how to use the alternate fonts instead of “Microsoft Sans Serif” without installing the fonts into production machine.

private void FontSettings_SubstituteFont(object sender, SubstituteFontEventArgs args)
{
    //Sets the alternate font when a specified font is not installed in the production environment
    if (args.OriginalFontName == "Arial Unicode MS")
    {
        //Sets the alternate font based on the font style.
        switch (args.FontStyle)
        {
            case FontStyle.Italic:
                args.AlternateFontStream = new FileStream("Arial_italic.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                break;
            case FontStyle.Bold:
                args.AlternateFontStream = new FileStream("Arial_bold.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                break;
            default:
                args.AlternateFontStream = new FileStream("Arial.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                break;
        }
    }
}
private void FontSettings_SubstituteFont(object sender, SubstituteFontEventArgs args)
{
    //Sets the alternate font when a specified font is not installed in the production environment
    if (args.OriginalFontName == "Arial Unicode MS")
    {
        //Sets the alternate font based on the font style.
        switch (args.FontStyle)
        {
            case FontStyle.Italic:
                args.AlternateFontStream = new FileStream("Arial_italic.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                break;
            case FontStyle.Bold:
                args.AlternateFontStream = new FileStream("Arial_bold.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                break;
            default:
                args.AlternateFontStream = new FileStream("Arial.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                break;
        }
    }
}
Private Sub FontSettings_SubstituteFont(ByVal sender As Object, ByVal args As SubstituteFontEventArgs)
    'Sets the alternate font when a specified font is not installed in the production environment
    If args.OriginalFontName = "Arial Unicode MS" Then
        'Sets the alternate font based on the font style.
        Select Case args.FontStyle
           Case FontStyle.Italic
               args.AlternateFontStream = New FileStream("Arial_italic.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
           Case FontStyle.Bold
               args.AlternateFontStream = New FileStream("Arial_bold.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
           Case Else
               args.AlternateFontStream = New FileStream("Arial.TTF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        End Select
    End If
End Sub

You can download a complete working sample from GitHub.

NOTE

The above event will be triggered only if the specified font is not installed in production machine.

See Also