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);我如何使用你的功能?等等…第二个将位于第二个索引,即加载的每个文件的aka
LoadFont.Families[1]
,等等。释放Try-Catch块的
Finalize
部分中的非托管内存对mee起到了作用。好的,thans,我现在如何使用它/不确定您的意思,您使用它就像我发布它一样,将新函数添加到表单类中,并用我发布的函数替换现有的
LoadFonts
。我的意思是如何使用这个函数?不是,我使用的是smth,比如label1.Font=新字体(LoadFont.Families[0],9,FontStyle.Bold);我如何使用你的功能?等…第二个将位于第二个索引处,即加载的每个文件的aka
LoadFont.Families[1]
,等等。释放Try-Catch块的
Finalize
部分中的非托管内存,对mee来说就是一个诀窍。