【发布时间】:2016-07-28 21:57:59
【问题描述】:
我在我的资源中嵌入了一个 .ttf 字体文件(特别是“Amatic Bold”),我正在使用下面的代码来获取字体。 我尝试了这篇文章的代码:How do I Embed a font with my C# application? (using Visual Studio 2005)
这是我的实现:
static public Font GetCustomFont (byte[] fontData, float size, FontStyle style)
{
if (_fontCollection == null) _fontCollection = new PrivateFontCollection();
IntPtr fontPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);
System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
_fontCollection.AddMemoryFont(fontPtr, fontData.Length);
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);
return new Font(_fontCollection.Families[0], size, style);
}
我就是这样使用它的:
Font font = GetCustomFont(Properties.MainResources.Amatic_Bold, 25, System.Drawing.FontStyle.Bold);
问题是字体正在加载,但使用时显示不正确;它看起来像“Arial”或其他标准字体,而不是应有的字体。 如果我在 Windows 中安装字体,它可以工作(我想很明显......)
我搜索了一个现有的答案,但找不到我的确切问题...
任何帮助将不胜感激。 提前致谢。
【问题讨论】:
-
那可怕的漏洞代码就像病毒一样,很难摆脱。您正在被字体保存,它是一种 OpenType 字体。仅可在 WPF 或 Direct2D 应用程序中使用。字体映射器找到可以在 Winforms 应用程序中工作的替代品。
-
谢谢,@HansPassant。有没有什么好的替代方法可以不用安装字体就可以使用?
-
安装字体时它真的有效吗?然后修复此代码中的错误。在无法再使用字体并且调用 ._fontCollection.Dispose() 方法之前,您不能调用 Marshal.FreeCoTaskMem() 并且 _fontCollection.Families[0] 总是返回第一个字体,而不是最后加载的字体。
-
好的,我试试。我知道 _fontCollection.Families[0] 问题,这是我最初计划的行为,尽管我将对其进行修改。再次感谢。
-
Adam,你需要重新组织你的内存管理,所以你只创建一次字体集合,
AllocCoTaskMem和AddMemoryFont,然后只在窗体/控件时处理字体集合和FreeCoTaskMem处置。如果您尝试在控件上使用字体,则对兼容的文本渲染有一些要求here - 如果这是错误的,字体将被忽略。
标签: c# winforms fonts embedded-resource