How do I Embed a font with my C# application? (using Visual Studio 2005)

后端 未结 4 1226
刺人心
刺人心 2020-11-30 09:11

What is the best way to embed a truetype font within the application i\'m developing? Basically i want to make sure a particular font is available to my application when ins

相关标签:
4条回答
  • 2020-11-30 09:25

    Here's Will's answer, translated to C# (untested):

    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);
    }
    

    along with their Paint() method:

    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);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 09:32

    it might not be the best way but couldn't you just include the font with your resources and then copy it to the font's folder on the windows dir?

    0 讨论(0)
  • 2020-11-30 09:42

    This blog post should help you.

    Basically you add the font as an embedded resource then load it into a PrivateFontCollection object.

    0 讨论(0)
  • 2020-11-30 09:43

    Its easier than this seems; you can embed the font as a resource in your app and access it as a strongly-typed property within the Properties namespace of your app. But the given link should be a good starting point.


    For the VB-disabled:

    Add the font as a resource in your application. Call the resource MyFontLol. You can access this resource (as a byte array) from Properties.Resources.MyFontLol.

    I haven't tested the following, but it appears to be workable:

    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
        }
    }
    

    One last note. The PFC stores the font as a GDI+ font. These aren't compatible with some forms controls. From the docs:

    To use the memory font, text on a control must be rendered with GDI+. Use the SetCompatibleTextRenderingDefault method, passing true, to set GDI+ rendering on the application, or on individual controls by setting the control's UseCompatibleTextRendering property to true. Some controls cannot be rendered with GDI+.

    0 讨论(0)
提交回复
热议问题