C#装入字体库
我有以下代码用于从资源加载自定义字体:C#装入字体库,c#,C#,我有以下代码用于从资源加载自定义字体: using System.Reflection; using System.Runtime.InteropServices; using System.Drawing.Text; public Form1() { InitializeComponent(); LoadFonts(); } PrivateFontCollection LoadFont = new PrivateFontCollection(); priva
using System.Reflection;
using System.Runtime.InteropServices;
using System.Drawing.Text;
public Form1()
{
InitializeComponent();
LoadFonts();
}
PrivateFontCollection LoadFont = new PrivateFontCollection();
private void LoadFonts()
{
Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("embedded_font.osb.ttf");
System.IntPtr data = Marshal.AllocCoTaskMem((int)fontStream.Length);
byte[] fontdata = new byte[fontStream.Length];
fontStream.Read(fontdata, 0, (int)fontStream.Length);
Marshal.Copy(fontdata, 0, data, (int)fontStream.Length);
LoadFont.AddMemoryFont(data, (int)fontStream.Length);
fontStream.Close();
Marshal.FreeCoTaskMem(data);
}
private void label1_Click(object sender, EventArgs e)
{
label1.Font = new Font(LoadFont.Families[0], 9, FontStyle.Bold);
label1.UseCompatibleTextRendering = true;
}
没关系,很好用,但我不想加载两种字体,我该怎么做?例如,我有osb.ttf和os.ttf。下一步是什么?感谢advace我将把它分解成一个单独的函数:
private void LoadFontFromResourcesByName(string FontName)
{
Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(FontName);
System.IntPtr data = Marshal.AllocCoTaskMem((int)fontStream.Length);
byte[] fontdata = new byte[fontStream.Length];
fontStream.Read(fontdata, 0, (int)fontStream.Length);
Marshal.Copy(fontdata, 0, data, (int)fontStream.Length);
LoadFont.AddMemoryFont(data, (int)fontStream.Length);
fontStream.Close();
Marshal.FreeCoTaskMem(data);
}
private void LoadFonts()
{
LoadFontFromResourcesByName("embedded_font.osb.ttf");
LoadFontFromResourcesByName("embedded_font.os.ttf");
}
这是一种简单的重构,是您应该学习的技能。尽可能地泛化函数,以便能够与其他地方不同或重复地使用它们
如果加载字体时出现错误,您可能还希望保护加载代码不造成内存泄漏。通常我会说使用将fontStream
包装在中,但这不会清理非托管资源
我会这样做:
private void LoadFontFromResourcesByName(string FontName)
{
using (Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(FontName))
{
System.IntPtr data = System.IntPtr.Zero;
try
{
data = Marshal.AllocCoTaskMem((int)fontStream.Length);
byte[] fontdata = new byte[fontStream.Length];
fontStream.Read(fontdata, 0, (int)fontStream.Length);
Marshal.Copy(fontdata, 0, data, (int)fontStream.Length);
LoadFont.AddMemoryFont(data, (int)fontStream.Length);
}
finally
{
if (data != System.IntPtr.Zero)
Marshal.FreeCoTaskMem(data);
}
}
}
我将把它分解成一个单独的函数:
private void LoadFontFromResourcesByName(string FontName)
{
Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(FontName);
System.IntPtr data = Marshal.AllocCoTaskMem((int)fontStream.Length);
byte[] fontdata = new byte[fontStream.Length];
fontStream.Read(fontdata, 0, (int)fontStream.Length);
Marshal.Copy(fontdata, 0, data, (int)fontStream.Length);
LoadFont.AddMemoryFont(data, (int)fontStream.Length);
fontStream.Close();
Marshal.FreeCoTaskMem(data);
}
private void LoadFonts()
{
LoadFontFromResourcesByName("embedded_font.osb.ttf");
LoadFontFromResourcesByName("embedded_font.os.ttf");
}
这是一种简单的重构,是您应该学习的技能。尽可能地泛化函数,以便能够与其他地方不同或重复地使用它们
如果加载字体时出现错误,您可能还希望保护加载代码不造成内存泄漏。通常我会说使用
将fontStream
包装在中,但这不会清理非托管资源
我会这样做:
private void LoadFontFromResourcesByName(string FontName)
{
using (Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(FontName))
{
System.IntPtr data = System.IntPtr.Zero;
try
{
data = Marshal.AllocCoTaskMem((int)fontStream.Length);
byte[] fontdata = new byte[fontStream.Length];
fontStream.Read(fontdata, 0, (int)fontStream.Length);
Marshal.Copy(fontdata, 0, data, (int)fontStream.Length);
LoadFont.AddMemoryFont(data, (int)fontStream.Length);
}
finally
{
if (data != System.IntPtr.Zero)
Marshal.FreeCoTaskMem(data);
}
}
}
好的,thans,我现在怎么用呢/不确定您的意思,您使用它就像我发布它一样,将新函数添加到表单类中,并用我发布的函数替换现有的LoadFonts
。我的意思是如何使用这个函数?不是,我使用的是smth,比如label1.Font=新字体(LoadFont.Families[0],9,FontStyle.Bold);我如何使用你的功能?等等…第二个将位于第二个索引,即加载的每个文件的akaLoadFont.Families[1]
,等等。释放Try-Catch块的Finalize
部分中的非托管内存对mee起到了作用。好的,thans,我现在如何使用它/不确定您的意思,您使用它就像我发布它一样,将新函数添加到表单类中,并用我发布的函数替换现有的LoadFonts
。我的意思是如何使用这个函数?不是,我使用的是smth,比如label1.Font=新字体(LoadFont.Families[0],9,FontStyle.Bold);我如何使用你的功能?等…第二个将位于第二个索引处,即加载的每个文件的akaLoadFont.Families[1]
,等等。释放Try-Catch块的Finalize
部分中的非托管内存,对mee来说就是一个诀窍。