New to Telerik Document Processing? Start a free 30-day trial

Fonts

Updated on Sep 23, 2026

RadPdfProcessing automatically discovers installed system fonts in cross-platform .NET Standard and .NET (Target OS: None) applications. The FixedExtensibilityManager class also lets you provide font data explicitly when your application needs fonts that are not installed on the host system.

Setting and Exporting Fonts

RadPdfProcessing loads font data when it creates text and exports a PDF. On cross-platform targets, the first access to FixedExtensibilityManager.FontsProvider automatically activates the system-font provider. You do not need to register a provider for fonts that are installed in a supported system font directory.

The system-font provider searches the following locations. The provider scans directories recursively and uses supported .ttf, .otf, and .ttc files that it can access and parse.

PlatformDefault font locations
WindowsThe Windows Fonts directory and the current user's Microsoft\Windows\Fonts directory.
Linux/usr/share/fonts, /usr/local/share/fonts, /var/lib/flatpak/exports/share/fonts, the user's ~/.fonts directory, and the user's ~/.local/share/fonts directory.
macOS/System/Library/Fonts, /Library/Fonts, and the current user's ~/Library/Fonts directory.
iOS/System/Library/Fonts and /Library/Fonts.
Android/system/fonts, /system/product/fonts, and /product/fonts.

The provider builds its font index lazily. If a directory does not exist, a font file is inaccessible, a file is larger than 50 MB, or a font file is corrupted or unsupported, the provider skips that item. The provider returns no data for a font family that is not found, so the resulting document can use font substitution according to the PDF and application settings.

When you assign a custom provider to FixedExtensibilityManager.FontsProvider, the custom provider takes precedence. Use a custom provider when you need to:

  • Bundle fonts with your application instead of relying on fonts installed on the host system.
  • Use fonts stored in an application-specific location or another data source.
  • Control font resolution for repeatable output across machines, containers, or mobile devices.

You can find a detailed FixedExtensibilityManager and FontsProvider implementation in the How to implement a FontsProvider article.

When converting a document (for example, DOCX or HTML) to PDF format, the system-font provider can resolve a font only when the matching font is installed in a directory that the provider searches. Fonts embedded in the source document, fonts stored in another application location, and custom fonts that are not installed require a custom provider that returns the font data. If the requested font cannot be resolved, the PDF model can substitute another font, which may change the document's appearance or text layout.

Implementing a FontsProviderBase

C#
public class FontsProvider : Telerik.Documents.Extensibility.FontsProviderBase
{
    public override byte[] GetFontData(Telerik.Documents.Core.Fonts.FontProperties fontProperties)
    {
        string fontFileName = fontProperties.FontFamilyName + ".ttf";
        string fontFolder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);

        //The fonts can differ depending on the file
        if (fontProperties.FontFamilyName == "Arial")
        {
            if (fontProperties.FontStyle == FontStyles.Italic && fontProperties.FontWeight == FontWeights.Bold)
            {
                fontFileName = $"arialbi.ttf";
            }
            else if (fontProperties.FontStyle == FontStyles.Italic)
            {
                fontFileName = $"ariali.ttf";
            }
            else if (fontProperties.FontWeight == FontWeights.Normal)
            {
                fontFileName = "arial.ttf";
            }
            else if (fontProperties.FontWeight == FontWeights.Bold)
            {
                fontFileName = $"arialbd.ttf";
            }
        }

        //...add more fonts if needed...

        DirectoryInfo directory = new DirectoryInfo(fontFolder);
        FileInfo[] fontFiles = directory.GetFiles();

        var fontFile = fontFiles.FirstOrDefault(f => f.Name.Equals(fontFileName, StringComparison.InvariantCultureIgnoreCase));
        if (fontFile != null)
        {
            var targetPath = fontFile.FullName;
            using (FileStream fileStream = File.OpenRead(targetPath))
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    fileStream.CopyTo(memoryStream);
                    return memoryStream.ToArray();
                }
            }
        }

        return null;
    }
}

public abstract class StreamFontsProviderBase : Telerik.Documents.Extensibility.FontsProviderBase
{
    public virtual Stream GetFontStream(Telerik.Documents.Core.Fonts.FontProperties fontProperties)
    {
        return null;
    }
}

public class StreamFontsProvider : StreamFontsProviderBase
{
    public override byte[] GetFontData(Telerik.Documents.Core.Fonts.FontProperties fontProperties)
    {
        return null;
    }

    public override Stream GetFontStream(Telerik.Documents.Core.Fonts.FontProperties fontProperties)
    {
        if (fontProperties.FontFamilyName == "Some Font")
        {
            return File.OpenRead("some-font.ttf");
        }

        return null;
    }
}
C#
Telerik.Documents.Extensibility.FontsProviderBase fontsProvider = new FontsProvider();
Telerik.Documents.Extensibility.FixedExtensibilityManager.FontsProvider = fontsProvider;

Providing Font Streams

To provide fonts stored outside system font directories, override FontsProviderBase.GetFontStream(FontProperties). The method must return a readable, seekable stream.

This approach lets RadPdfProcessing read font data lazily instead of requiring the provider to load the complete font into a byte[].

C#
public override byte[] GetFontData(Telerik.Documents.Core.Fonts.FontProperties fontProperties)
{
    return null;
}

public override Stream GetFontStream(Telerik.Documents.Core.Fonts.FontProperties fontProperties)
{
    if (fontProperties.FontFamilyName == "Some Font")
    {
        return File.OpenRead("some-font.ttf");
    }

    return null;
}

Override GetFontData(FontProperties) because it is abstract. Return null when the provider serves all fonts through GetFontStream().

RadPdfProcessing owns the stream that GetFontStream() returns. Return a new stream for every request. Do not dispose the stream after returning it.

Providers that override only GetFontData(FontProperties) remain supported. The base GetFontStream() method creates a stream from the returned byte array.

See Also