I have been trying to get migradocs to generate a pdf on an azure serverless function for a few days now, and I have been unable to get it to work. I first ran into an error stating that I needed to write my own MyFontResolver class, and following some code guides I have assembled the following:
Code:
public class MyFontResolver : IFontResolver
{
public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
{
// Ignore case of font names.
var name = familyName.ToLower();
// Deal with the fonts we know.
switch (name)
{
case "ubuntu":
if (isBold)
{
if (isItalic)
return new FontResolverInfo("Ubuntu#bi");
return new FontResolverInfo("Ubuntu#b");
}
if (isItalic)
return new FontResolverInfo("Ubuntu#i");
return new FontResolverInfo("Ubuntu#");
case "janitor":
return new FontResolverInfo("Janitor#");
}
// We pass all other font requests to the default handler.
// When running on a web server without sufficient permission, you can return a default font at this stage.
return PlatformFontResolver.ResolveTypeface(familyName, isBold, isItalic);
}
private byte[] LoadFontData(string name)
{
var assembly = Assembly.GetExecutingAssembly();
// Test code to find the names of embedded fonts - put a watch on "ourResources"
//var ourResources = assembly.GetManifestResourceNames();
using (Stream stream = assembly.GetManifestResourceStream(name))
{
if (stream == null)
throw new ArgumentException("No resource with name " + name);
int count = (int)stream.Length;
byte[] data = new byte[count];
stream.Read(data, 0, count);
return data;
}
}
public byte[] GetFont(string faceName)
{
switch (faceName)
{
case "Arial#":
return LoadFontData("MyProject.fonts.arial.arial.ttf"); ;
case "Arial#b":
return LoadFontData("MyProject.fonts.arial.arialbd.ttf"); ;
case "Arial#i":
return LoadFontData("MyProject.fonts.arial.ariali.ttf");
case "Arial#bi":
return LoadFontData("MyProject.fonts.arial.arialbi.ttf");
}
return null;
}
}
Since then, I have set GlobalFontSettings.FontResolver = new MyFontResolver(); and also paragraph.Format.Font.Name = "ubuntu"; where paragraph is a MigraDoc.DocumentObjectModel.Paragraph that holds the text. The error I am now getting is:
Code:
System.NullReferenceException: Object reference not set to an instance of an object.
at PdfSharp.Fonts.OpenType.OpenTypeFontface.CetOrCreateFrom(XFontSource fontSource)
at PdfSharp.Drawing.XGlyphTypeface.GetOrCreateFrom(String familyName, FontResolvingOptions fontResolvingOptions)
at PdfSharp.Drawing.XFont.Initialize()
at MigraDoc.Rendering.FontHandler.FontToXFont(Font font, PdfFontEncoding encoding)
at MigraDoc.Rendering.ParagraphRenderer.get_CurrentFont()
at MigraDoc.Rendering.ParagraphRenderer.InitFormat(Area area, FormatInfo previousFormatInfo)
at MigraDoc.Rendering.ParagraphRenderer.Format(Area area, FormatInfo previousFormatInfo)
at MigraDoc.Rendering.TopDownFormatter.FormatOnAreas(XGraphics gfx, Boolean topLevel)
at MigraDoc.Rendering.FormattedDocument.Format(XGraphics gfx)
at MigraDoc.Rendering.DocumentRenderer.PrepareDocument()
at MigraDoc.Rendering.PdfDocumentRenderer.PrepareDocumentRenderer(Boolean prepareCompletely)
at MigraDoc.Rendering.PdfDocumentRenderer.PrepareRenderPages()
at MigraDoc.Rendering.PdfDocumentRenderer.RenderDocument()
at EmailQueue.AddCopyToEFolder.<Run>d__3.MoveNext()
If I add paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50); Then I get a different error:
Code:
System.ArgumentNullException: Value cannot be null.
Parameter name: buffer
at PdfSharp.Drawing.FontHelper.CalcChecksum(Byte[] buffer)
at PdfSharp.Drawing.XFontSource.GetOrCreateFrom(Byte[] bytes)
at PdfSharp.Fonts.FontFactory.ResolveTypeface(String familyName, FontResolvingOptions fontResolvingOptions, String typefaceKey)
at PdfSharp.Drawing.XGlyphTypeface.GetOrCreateFrom(String familyName, FontResolvingOptions fontResolvingOptions)
at PdfSharp.Drawing.XFont.Initialize()
at MigraDoc.Rendering.FontHandler.FontToXFont(Font font, PdfFontEncoding encoding)
at MigraDoc.Rendering.ParagraphRenderer.get_CurrentFont()
at MigraDoc.Rendering.ParagraphRenderer.InitFormat(Area area, FormatInfo previousFormatInfo)
at MigraDoc.Rendering.ParagraphRenderer.Format(Area area, FormatInfo previousFormatInfo)
at MigraDoc.Rendering.TopDownFormatter.FormatOnAreas(XGraphics gfx, Boolean topLevel)
at MigraDoc.Rendering.FormattedDocument.Format(XGraphics gfx)
at MigraDoc.Rendering.DocumentRenderer.PrepareDocument()
at MigraDoc.Rendering.PdfDocumentRenderer.PrepareDocumentRenderer(Boolean prepareCompletely)
at MigraDoc.Rendering.PdfDocumentRenderer.PrepareRenderPages()
at MigraDoc.Rendering.PdfDocumentRenderer.RenderDocument()
at EmailQueue.AddCopyToEFolder.<Run>d__3.MoveNext()
I honestly just want to get a plain text document, so if there is an easier way to do this, I'm happy to listen