如何在我的C#应用程序中嵌入字体?(使用VisualStudio2005)

如何在我的C#应用程序中嵌入字体?(使用VisualStudio2005),c#,fonts,C#,Fonts,在我正在开发的应用程序中嵌入truetype字体的最佳方法是什么?基本上,我希望确保在安装到另一台机器上时,我的应用程序可以使用特定的字体。我有*.ttf字体文件,只需要一种嵌入它或在应用程序运行时自动安装它的方法 我是否需要将安装程序设置为在安装期间安装字体,还是可以在应用程序运行期间动态加载字体?事实上,两个人都很高兴知道 该应用程序是在C#中使用.NET2.0开发的。比看起来更容易;您可以将字体作为资源嵌入应用程序中,并在应用程序的属性命名空间中作为强类型属性访问它。但给定的链接应该是一个

在我正在开发的应用程序中嵌入truetype字体的最佳方法是什么?基本上,我希望确保在安装到另一台机器上时,我的应用程序可以使用特定的字体。我有*.ttf字体文件,只需要一种嵌入它或在应用程序运行时自动安装它的方法

我是否需要将安装程序设置为在安装期间安装字体,还是可以在应用程序运行期间动态加载字体?事实上,两个人都很高兴知道


该应用程序是在C#中使用.NET2.0开发的。

比看起来更容易;您可以将字体作为资源嵌入应用程序中,并在应用程序的属性命名空间中作为强类型属性访问它。但给定的链接应该是一个良好的起点


对于禁用的VB:

调用资源MyFontLol。您可以从Properties.Resources.MyFontLol访问此资源(作为字节数组)

我没有测试以下内容,但它似乎是可行的:

public void LoadMyFontLolKThx()
{
    // get our font and wrap it in a memory stream
    byte[] myFont = Properties.Resources.MyFontLol;
    using (var ms = new MemoryStream(myFont))
    {
        // used to store our font and make it available in our app
        PrivateFontCollection pfc = new PrivateFontCollection();
        // The next call requires a pointer to our memory font
        // I'm doing it this way; not sure what best practice is
        GCHandle handle = GCHandle.Alloc(ms, GCHandleType.Pinned);
        // If Length > int.MaxValue this will throw
        checked
        {
            pfc.AddMemoryFont(
                handle.AddrOfPinnedObject(), (int)ms.Length); 
        }
        var font = new Font(pfc.Families[0],12);

        // use your font here
    }
}
最后一个音符。PFC将字体存储为GDI+字体。这些控件与某些窗体控件不兼容。从文档中:

要使用内存字体,请在 控件必须使用GDI+呈现。 使用 方法,传递true,以设置GDI+ 在应用程序上渲染,或在 通过设置 控制的 属性设置为true。有些控件不能 可以使用GDI+进行渲染

这应该对你有帮助


基本上,您可以将字体添加为嵌入式资源,然后将其加载到对象中。

以下是威尔的答案,翻译为C#(未测试):

以及它们的Paint()方法:


这可能不是最好的方法,但你能不能在资源中包含字体,然后将其复制到windows目录中字体的文件夹中?

当我尝试使用使用此技术创建的字体绘制某些文本时,有时会引发异常,除非我保留对PrivateFontCollection的引用。我想我有我的字体,为什么我还需要这些收藏?我假设字体使用了来自它的信息,然后它被垃圾收集或者其他什么。没错,@coffee\u machine。我敢肯定,b是在using块中声明的,并且可以被删除。实际上,您是在for循环中处理它。这只适用于第一次迭代。很好。这就是我直接翻译别人的代码所得到的。谢谢,@咖啡机@这基本上是别人现在删除的答案在VB中的翻译。我不知道我从哪里得到了元帅分配的资料,所以我还不能回答你,但给我一点时间,我看看我能找到什么。@J-Roel:希望我能记得,这样我就能告诉你了。在这一点上,我已经有4年没有做过C#了。字体。Lol。这是你能想到的最好的名称吗?我可以挖掘方法名称LOLKTHX。当我尝试此方法时,将MemoryStream传递给GCHandle肯定有问题。Alloc-不是原始类型对象是异常的要点。shrug@Will:问题,当我转到第一个链接时,会收到恶意网页警告。“因为它告诉我是这样”是链接的文本。这是假阳性吗?@johncarcenter,它坏了。我正要把它拿出来。顺便说一句,我喜欢这个东西。
PrivateFontCollection pfc = new PrivateFontCollection();

using (Stream fontStream = GetType().Assembly.GetManifestResourceStream("Alphd___.ttf"))
{
    if (null == fontStream)
    {
        return;
    }

    int fontStreamLength = (int) fontStream.Length;

    IntPtr data = Marshal.AllocCoTaskMem(fontStreamLength);

    byte[] fontData = new byte[fontStreamLength];
    fontStream.Read(fontData, 0, fontStreamLength);

    Marshal.Copy(fontData, 0, data, fontStreamLength);

    pfc.AddMemoryFont(data, fontStreamLength);

    Marshal.FreeCoTaskMem(data);
}
protected void Form1_Paint(object sender, PaintEventArgs e)
{
    bool bold = false;
    bool italic = false;

    e.Graphics.PageUnit = GraphicsUnit.Point;

    using (SolidBrush b = new SolidBrush(Color.Black))
    {
        int y = 5;

        foreach (FontFamily fontFamily in pfc.Families)
        {
            if (fontFamily.IsStyleAvailable(FontStyle.Regular))
            {
                using (Font font = new Font(fontFamily, 32, FontStyle.Regular))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }
            if (fontFamily.IsStyleAvailable(FontStyle.Bold))
            {
                bold = true;
                using (Font font = new Font(fontFamily, 32, FontStyle.Bold))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }
            if (fontFamily.IsStyleAvailable(FontStyle.Italic))
            {
                italic = true;
                using (Font font = new Font(fontFamily, 32, FontStyle.Italic))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }

            if(bold && italic)
            {
                using(Font font = new Font(fontFamily, 32, FontStyle.Bold | FontStyle.Italic))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }

            using (Font font = new Font(fontFamily, 32, FontStyle.Underline))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                y += 40;
            }

            using (Font font = new Font(fontFamily, 32, FontStyle.Strikeout))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
            }
        }
    }
}