C# LoadFont stock

本文关键字:stock LoadFont | 更新日期: 2023-09-27 18:03:10

我有以下代码从资源中加载自定义字体:

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。接下来是什么?提前感谢

C# LoadFont stock

我会把它分解成一个单独的函数:

    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包装在using中,但这不会清理未管理的资源。

我是这样做的:

        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);
                }
            }
        }
相关文章: