I've load the MemoryStream to a PrivateFontCollection and print the Font-Family count.
I've done these process for 10 times and I want the same output for every iteration. I want correct output for two iterations and sometimes the first iteration is also going wrong. I can't have a consistent output.
Provide me a solution to have a consistent output using PrivateFontCollection.
Note: Fonts folder contains 5 different fonts.
private static void Work()
{
string fontPath = @"D:\fonts";
PrivateFontCollection fontCollection = null;
for (int i = 1; i < 11; i++)
{
var fileList = Directory.GetFiles(fontPath, "*.ttf", SearchOption.TopDirectoryOnly);
fontCollection = SafeLoadFontFamily(fileList);
Console.WriteLine(i+" Iteration and families count:"+fontCollection.Families.Length);
fontCollection.Dispose();
}
Console.ReadKey();
}
private static PrivateFontCollection SafeLoadFontFamily(IEnumerable<string> fontList)
{
if (fontList == null) return null;
var fontCollection = new PrivateFontCollection();
foreach (string fontFile in fontList)
{
if (!File.Exists(fontFile)) continue;
byte[] fontBytes = File.ReadAllBytes(fontFile);
var fontData = Marshal.AllocCoTaskMem(fontBytes.Length);
Marshal.Copy(fontBytes, 0, fontData, fontBytes.Length);
fontCollection.AddMemoryFont(fontData, fontBytes.Length);
}
return fontCollection;
}
Expected output for 10 times:
1 Iteration and families count:5
2 Iteration and families count:5
3 Iteration and families count:5
4 Iteration and families count:5
5 Iteration and families count:5
6 Iteration and families count:5
7 Iteration and families count:5
8 Iteration and families count:5
9 Iteration and families count:5
10 Iteration and families count:5
Actual output:[ inconsistent output]
1 Iteration and families count:5
2 Iteration and families count:5
3 Iteration and families count:5
4 Iteration and families count:5
5 Iteration and families count:4
6 Iteration and families count:3
7 Iteration and families count:3
8 Iteration and families count:4
9 Iteration and families count:4
10 Iteration and families count:4
If all you want to do is to print the name of the Font Family of each Font file stored in a directory, you can simplify your code with something like this.
It orders the Font files by name before printing the Family name.
If you instead want to preserve the list of the Fonts Family names (for other uses), add each Family name to a
List<string>(as a Field, here):Using PrivateFontCollection.AddMemoryFont(). This method can be used for both Font Files and font data from a Font added as a Project Resource (it's just a byte array).
Important: The
PrivateFontCollectionthat these methods return MUST be disposed of in theForm.FormClosingorForm.FormClosed(or where the application's termination is handled).Call these methods passing a collection of file paths:
Using
unsafemode and a byte* pointer:(Unsafe code must be enabled in the Project's
Properties -> Buildpanel)Using Marshal.AllocCoTaskMem() and Marshal.Copy().
Do not call Marshal.FreeCoTaskMem() here. Font curruption may occur. Call
PrivateFontCollection.Dispose()instead, as already mentioned.Print the Font Collection content:
System.Windows.Mediaprovides the Fonts.GetFontFamilies() method, just in case.