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);
}
}
}