PDFsharp & MigraDoc Forum

PDFsharp - A .NET library for processing PDF & MigraDoc - Creating documents on the fly
It is currently Mon Oct 20, 2025 1:41 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules

Also see our new Tailored Support & Services site.



Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Sat Oct 11, 2025 4:00 pm 
Offline

Joined: Sat Oct 11, 2025 3:47 pm
Posts: 2
Using unity 2022.3.62f, .net standard 2.1 api, pdfsharp / migradoc 6.2.2.
For the past couple of days I have been trying to export a pdf from my unity application but whatever I do I always run into this error:
Error: The font 'Courier New' cannot be resolved for predefined error font. Use another font name or fix your font resolver.
I tried many different variations of the font resolver. I created a PdfSharpFontInitializer that runs at awake of my first scene.
All dll's load without giving me any errors. I made a MinimalPdfTest which gives me the following logs:
[MinimalPdfTest] Font initializer called
[MinimalPdfTest] Document created
[MinimalPdfTest] Normal style set to Helvetica
[MinimalPdfTest] Section added
[MinimalPdfTest] Title paragraph added
[MinimalPdfTest] Body paragraph added
[MinimalPdfTest] Starting document rendering...
[MinimalPdfTest] Calling RenderDocument()...
[UnityFontResolver] Font requested: 'Courier New' (Bold: False, Italic: False)
[UnityFontResolver] Intercepted Courier request - mapping to Helvetica (PdfSharp 6.2.2 workaround)
[UnityFontResolver] GetFont called for 'Helvetica' - returning null (use built-in font)
[MinimalPdfTest] ? FAILED: The font 'Courier New' cannot be resolved for predefined error font. Use another font name or fix your font resolver.
NullReferenceException: Object reference not set to an instance of an object

I checked all the documentation, asked several AI agents, but now I feel like I am hitting a wall.
I hope someone is able to help me out to resolve this error


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 12, 2025 12:04 am 
Offline

Joined: Sat Oct 11, 2025 3:47 pm
Posts: 2
This is the latest font resolver that I tried

Code:
 
using PdfSharp.Fonts;
using UnityEngine;
using System;

/// <summary>
/// Font resolver for PdfSharp/MigraDoc 6.2.2 in Unity.
/// </summary>
public static class R_PdfSharpFontInitializer
{
    private static bool isInitialized = false;

    public static void Initialize()
    {
        if (isInitialized)
        {
            Debug.Log("[PdfSharpFontInitializer] Already initialized, skipping.");
            return;
        }

        try
        {
            Debug.Log("[PdfSharpFontInitializer] Starting initialization...");

            var resolver = new UnityFontResolver();
            GlobalFontSettings.FontResolver = resolver;

            Debug.Log("[PdfSharpFontInitializer] ✓ Font resolver set successfully");
            isInitialized = true;
        }
        catch (Exception ex)
        {
            Debug.LogError($"[PdfSharpFontInitializer] ✗ CRITICAL FAILURE: {ex.Message}");
            Debug.LogException(ex);
        }
    }
}

/// <summary>
/// Custom font resolver that maps all fonts to safe standard PDF fonts.
/// Avoids the problematic "Courier" font due to PdfSharp 6.2.2 bugs.
/// </summary>
public class UnityFontResolver : IFontResolver
{
    public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
    {
        // Debug logging
        Debug.Log($"[UnityFontResolver] Font requested: '{familyName}' (Bold: {isBold}, Italic: {isItalic})");

        if (string.IsNullOrEmpty(familyName))
        {
            Debug.Log("[UnityFontResolver] Null/empty font name, returning Helvetica");
            return new FontResolverInfo("Helvetica", isBold, isItalic);
        }

        string lowerFamilyName = familyName.ToLower();

        // CRITICAL: Never use "Courier" or "Courier New" - PdfSharp 6.2.2 has a bug with these fonts?
        // Map everything including Courier requests to Helvetica, which should universally supported
        if (lowerFamilyName.Contains("courier"))
        {
            Debug.Log($"[UnityFontResolver] Intercepted Courier request - mapping to Helvetica (PdfSharp 6.2.2 workaround)");
            return new FontResolverInfo("Helvetica", isBold, isItalic);
        }

        // Handle Times variants
        if (lowerFamilyName.Contains("times"))
        {
            Debug.Log($"[UnityFontResolver] Mapped '{familyName}' to 'Times-Roman'");
            return new FontResolverInfo("Times-Roman", isBold, isItalic);
        }

        // Default to Helvetica for all other fonts
        Debug.Log($"[UnityFontResolver] Mapped '{familyName}' to 'Helvetica'");
        return new FontResolverInfo("Helvetica", isBold, isItalic);
    }

    public byte[] GetFont(string faceName)
    {
        // Always return null - use standard PDF built-in fonts
        Debug.Log($"[UnityFontResolver] GetFont called for '{faceName}' - returning null (use built-in font)");
        return null;
    }
}


and this is my test code I use in unity
Code:
using System;
using System.IO;
using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
using UnityEngine;
using UnityEngine.UI;

public class MinimalPdfTest : MonoBehaviour
{
    public Button testExportButton;

    private void Start()
    {
        if (testExportButton != null)
        {
            testExportButton.onClick.AddListener(OnTestExportClicked);
        }
    }

    private void OnTestExportClicked()
    {
        Debug.Log("[MinimalPdfTest] Starting minimal PDF export test...");

        try
        {
            // Ensure font resolver is initialized
            R_PdfSharpFontInitializer.Initialize();
            Debug.Log("[MinimalPdfTest] Font initializer called");

            // Create a very simple document
            var doc = new Document();
            Debug.Log("[MinimalPdfTest] Document created");

            // Set default styles BEFORE adding content
            var normalStyle = doc.Styles["Normal"];
            normalStyle.Font.Name = "Helvetica";
            Debug.Log("[MinimalPdfTest] Normal style set to Helvetica");

            // Add a simple section
            var section = doc.AddSection();
            Debug.Log("[MinimalPdfTest] Section added");

            // Add minimal content
            var title = section.AddParagraph("Hello World Test");
            title.Format.Font.Name = "Helvetica";
            title.Format.Font.Size = 24;
            Debug.Log("[MinimalPdfTest] Title paragraph added");

            var body = section.AddParagraph("This is a minimal test to isolate the font issue.");
            body.Format.Font.Name = "Helvetica";
            Debug.Log("[MinimalPdfTest] Body paragraph added");

            // Attempt rendering
            Debug.Log("[MinimalPdfTest] Starting document rendering...");
            var renderer = new PdfDocumentRenderer(true); // true for Unicode rendering (required in 6.2.2)
            renderer.Document = doc;

            // CRITICAL: Set this before rendering to disable MigraDoc error font handling
            try
            {
                var rendererType = renderer.GetType().BaseType;
                var documentRendererType = rendererType.GetNestedType("DocumentRenderer",
                    System.Reflection.BindingFlags.NonPublic);
                if (documentRendererType != null)
                {
                    var predefinedFontsType = documentRendererType.GetNestedType("PredefinedFontsAndChars",
                        System.Reflection.BindingFlags.NonPublic);
                    if (predefinedFontsType != null)
                    {
                        var field = predefinedFontsType.GetField("_errorFontCreationFailed",
                            System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
                        if (field != null)
                        {
                            field.SetValue(null, true);
                            Debug.Log("[MinimalPdfTest] Disabled MigraDoc error font creation");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Log("[MinimalPdfTest] Could not disable error font via reflection: " + ex.Message);
            }

            Debug.Log("[MinimalPdfTest] Calling RenderDocument()...");
            renderer.RenderDocument();
            Debug.Log("[MinimalPdfTest] ✓ RenderDocument() succeeded");

            // Save the file
            string directoryPath = Path.Combine(Application.persistentDataPath, "Reports");
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }

            string filePath = Path.Combine(directoryPath, $"MinimalTest_{DateTime.Now:yyyyMMdd_HHmmss}.pdf");
            renderer.PdfDocument.Save(filePath);

            Debug.Log($"[MinimalPdfTest] SUCCESS! PDF saved to: {filePath}");
            Debug.Log("[MinimalPdfTest] The minimal test passed - font resolver is working correctly");
            Application.OpenURL(directoryPath);
        }
        catch (Exception ex)
        {
            Debug.LogError($"[MinimalPdfTest] ✗ FAILED: {ex.Message}");
            Debug.LogException(ex);
        }
    }
}


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 13, 2025 5:21 am 
Offline

Joined: Mon Oct 13, 2025 4:36 am
Posts: 1
You're writing a custom font resolver. A font resolver maps a request of a typeface e.g. Arial bold to the font face bytes of the file arialbt.ttf. It's in the docs. Your GetFont method is incorrect. It always returns null, but it should never return null because it is a custom resolver. If you only want to avoid "Courier" or if you don't care about the font, you can use
Code:
GlobalFontSettings.FontResolver = new FailsafeFontResolver();

or actually return the bytes of a font file
Code:
public byte[]? GetFont(string faceName)
    {
        string defaultPath = "";
        // return Helvetica as default...
        if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
        {
            defaultPath = "/System/Library/Fonts/Helvetica.ttc"; // replace with the path if this isn't the right one, macOS is tricky for fonts
        }

        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            List<string> WindowsFontLocations =
            [
                @"C:\Windows\Fonts",
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                    @"Microsoft\Windows\Fonts")
            ];

            foreach (var fontLocation in WindowsFontLocations)
            {
                var filepath = Path.Combine(fontLocation, "helvetica" + ".ttf"); // haven't testing this, double check the name and path.
                if (File.Exists(filepath))
                    defaultPath = filepath;
                break;
            }

        }
        return File.ReadAllBytes(defaultPath);
    }


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 13, 2025 5:37 am 
Offline
User avatar

Joined: Thu Mar 06, 2025 10:43 am
Posts: 6
DennisBoersma wrote:
[MinimalPdfTest] ? FAILED: The font 'Courier New' cannot be resolved for predefined error font. Use another font name or fix your font resolver.
NullReferenceException: Object reference not set to an instance of an object
The third sentence of the error message is missing here. It contains two links to the docs site that explain the issue at hand.
It's not a bug, it is a new feature.

DennisBoersma wrote:
[UnityFontResolver] Font requested: 'Courier New' (Bold: False, Italic: False)
[UnityFontResolver] Intercepted Courier request - mapping to Helvetica (PdfSharp 6.2.2 workaround)
[UnityFontResolver] GetFont called for 'Helvetica' - returning null (use built-in font)

Returning null means that Courier is not found. Not helpful.

DennisBoersma wrote:
I checked all the documentation, asked several AI agents, but now I feel like I am hitting a wall.
I hope someone is able to help me out to resolve this error
The answer is in the third sentence of the error message.
https://docs.pdfsharp.net/MigraDoc/DOM/ ... error-font

Set ErrorFontName to a font supported by your font resolver.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 103 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group