标签:c winforms fonts embedded-resource
我在我的资源中嵌入了一个.ttf字体文件(特别是“Amatic Bold”),我使用下面的代码来获取Font.
我试过这篇文章的代码: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中安装该字体,它可以工作(我想很明显…)
我搜索了一个现有的答案,但无法找到我的确切问题……
任何帮助将不胜感激.
提前致谢.
解决方法:
那么,那……我想我明白了!
我将解释我“发现”的内容(无论是否显而易见):
>首先:对于要在控件中呈现的内存字体,必须将Application.SetCompatibleTextRenderingDefault设置为true.
(也可以使用Control.UseCompatibleTextRendering)
它在Microsoft文档中完美指定但我错过了:-(
>第二:PrivateFontCollection.Families返回一组添加的字体,但是..惊喜!按字母顺序排列!
无论您添加字体或您使用的方法(AddMemoryFont / AddFontFile)的顺序是什么,您都可以按字母顺序排序!
因此,如果您要添加多个字体,然后尝试获取已添加的最后一种字体,则可能会出错.
>第三:我也尝试在集合中添加字体或在表单关闭时执行FreeCoTaskMem().两个都在为我工作!
我不知道这个的确切含义……
这是我的最终代码:
//This list is used to properly dispose PrivateFontCollection after usage
static private List<PrivateFontCollection> _fontCollections;
[STAThread]
private static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true); //Mandatory in order to have Memory fonts rendered in the controls.
//Dispose all used PrivateFontCollections when exiting
Application.ApplicationExit += delegate {
if (_fontCollections != null) {
foreach (var fc in _fontCollections) if (fc != null) fc.Dispose();
_fontCollections = null;
}
};
Application.Run(new frmMain());
}
void frmMain_Load(object sender, EventArgs e)
{
Font font1 = GetCustomFont(Properties.Resources.Amatic_Bold, 25, FontStyle.Bold);
//or...
Font font1 = GetCustomFont("Amatic-Bold.ttf", 25, FontStyle.Bold);
labelTestFont1.Font = font1;
Font font2 = GetCustomFont(Properties.Resources.<font_resource>, 25, FontStyle.Bold);
//or...
Font font2 = GetCustomFont("<font_filename>", 25, FontStyle.Bold);
labelTestFont2.Font = font2;
//...
}
static public Font GetCustomFont (byte[] fontData, float size, FontStyle style)
{
if (_fontCollections == null) _fontCollections = new List<PrivateFontCollection>();
PrivateFontCollection fontCol = new PrivateFontCollection();
IntPtr fontPtr = Marshal.AllocCoTaskMem(fontData.Length);
Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
fontCol.AddMemoryFont(fontPtr, fontData.Length);
Marshal.FreeCoTaskMem(fontPtr); //<-- It works!
_fontCollections.Add (fontCol);
return new Font(fontCol.Families[0], size, style);
}
static public Font GetCustomFont (string fontFile, float size, FontStyle style)
{
if (_fontCollections == null) _fontCollections = new List<PrivateFontCollection>();
PrivateFontCollection fontCol = new PrivateFontCollection();
fontCol.AddFontFile (fontFile);
_fontCollections.Add (fontCol);
return new Font(fontCol.Families[0], size, style);
}
如您所见,我决定为每种字体创建一个独有的PrivateFontCollection,然后将其存储到List以便在应用程序端进行最终处理.
这是在3种不同的PC(都有Windows 7,32和64位)和3种不同的.ttf字体中测试的.
结果的一个例子:
我不知道我的方法是否足够好,但我希望它对其他人有用!
还有一个细节:
与我的预期不同,AddMemoryFont比AddFontFile慢(21ms vs. 15 ms)
再次感谢所有评论!
标签:c,winforms,fonts,embedded-resource 来源: https://codeday.me/bug/20190628/1311965.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。