如果您只想打印存储在目录中的每个字体文件的字体系列的名称,您可以使用类似这样的方式简化您的代码。
它在打印家族名称之前按名称对字体文件进行排序。
string fontsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fonts");
var fontFiles = Directory.GetFiles(fontsPath).OrderBy(s => s).ToList();
fontFiles.ForEach(f => {
using (var fontCollection = new PrivateFontCollection())
{
fontCollection.AddFontFile(f);
Console.WriteLine(fontCollection.Families[0].Name);
};
});
如果您想保留字体家族名称列表(用于其他用途),请将每个家族名称添加到 a List<string>
(作为字段,此处):
// As a field
List<string> fontNames = new List<string>();
// Inside a method
var fontFiles = Directory.GetFiles(fontsPath).ToList();
fontFiles.ForEach(f => {
using (var fontCollection = new PrivateFontCollection())
{
fontCollection.AddFontFile(f);
fontNames.Add(fontCollection.Families[0].Name);
};
});
fontNames = fontNames.OrderBy(s => s).ToList();
fontNames.ForEach(familyName => Console.WriteLine(familyName));
使用PrivateFontCollection.AddMemoryFont()。此方法可用于字体文件和作为项目资源添加的字体中的字体数据(它只是一个字节数组)。
重要提示:PrivateFontCollection
这些方法返回的 必须在Form.FormClosing
or Form.FormClosed
(或处理应用程序终止的地方)中处理。
调用这些方法传递文件路径的集合:
// Field/Class object
PrivateFontCollection fontCollection = null;
// (...)
// Somewhere else
string fontsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fonts");
var fontFiles = Directory.GetFiles(fontsPath);
fontCollection = UnsafeLoadFontFamily(fontFiles);
// Or...
fontCollection = SafeLoadFontFamily(fontFiles);
fontCollection.Families.OrderBy(f => f.Name).ToList().ForEach(font =>
{
Console.WriteLine(font.GetName(0));
});
使用unsafe
模式和字节*指针:(
必须在项目Properties -> Build
面板中启用不安全代码)
private unsafe PrivateFontCollection UnsafeLoadFontFamily(IEnumerable<string> fontList)
{
if (fontList.Length == 0) return null;
var fontCollection = new PrivateFontCollection();
foreach (string fontFile in fontList)
{
if (!File.Exists(fontFile)) continue;
byte[] fontData = File.ReadAllBytes(fontFile);
fixed (byte* fontPtr = fontData)
{
fontCollection.AddMemoryFont(new IntPtr(fontPtr), fontData.Length);
}
}
return fontCollection;
}
使用Marshal.AllocCoTaskMem()和Marshal.Copy()。
不要在这里调用Marshal.FreeCoTaskMem()。可能会出现字体损坏。PrivateFontCollection.Dispose()
如前所述,请改为 致电。
private 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;
}
打印字体集内容:
string fontPath = [The Fonts Path];
PrivateFontCollection fontCollection = null;
for (int i = 0; i < 5; i++) {
var fileList = Directory.GetFiles(fontPath, "*.ttf", SearchOption.TopDirectoryOnly);
fontCollection = SafeLoadFontFamily(fileList);
fontCollection.Families.ToList().ForEach(ff => Console.WriteLine(ff.Name));
fontCollection.Dispose();
}
System.Windows.Media
提供Fonts.GetFontFamilies()方法,以防万一。