I have a .NET 3.5 application that loads fonts into memory using PrivateFontCollection.AddMemoryFont and uses these to produce images. I have recently installed this on Windows Server 2012 R2 and it is producing intermittent errors.
The problem is illustrated by this method:
private Bitmap getImage(byte[] fontFile)
{
using (PrivateFontCollection fontCollection = new PrivateFontCollection())
{
IntPtr fontBuffer = Marshal.AllocCoTaskMem(fontFile.Length);
Marshal.Copy(fontFile, 0, fontBuffer, fontFile.Length);
fontCollection.AddMemoryFont(fontBuffer, fontFile.Length);
Bitmap image = new Bitmap(200, 50);
using (Font font = new Font(fontCollection.Families[0], 11f, FontStyle.Regular))
{
using (Graphics graphics = Graphics.FromImage(image))
{
graphics.DrawString(String.Format("{0:HH:mm:ss}", DateTime.Now), font, Brushes.White, new PointF(0f, 0f));
}
}
return image;
}
}
On Windows 7 this works consistently. On Windows Server 2012 R2 it fails if called repeatedly using more than one font. For example:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
works even if called hundreds of times, but calling with more than one font:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Wingding.ttf"));
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
will work for the first several calls (20 or so) but will then start to produce random results (the second call will sometimes return an image with text in wingdings - ie it's mixing up the fonts).
I also occasionally (rarely) get "A generic error occurred in GDI+" on the DrawString call.
None of these errors occur on Windows 7.
I have tried various options to clean up without any success.
As a workaround I have tried writing the font file to disk, then loading with AddFontFile, but (on Windows 2012 R2) the font file gets locked for the life of the process so cannot be deleted. This makes this option unacceptable.
Any help with either getting AddMemoryFont to work consistently, or getting AddFontFile to unlock the file, would be hugely appreciated.