Skip to main content
GameDev.net gamedev.net
🔒 Locked

[.net] Using Custom/Embedded Font Resources

Started by Maxamor Jul 1, 2006 at 2:01 AM 2 replies 8.2k views
Original Post
Maxamor
Maxamor
Hello all. I've been struggling to get embedded font resources to wokr inside of my C# applications. If the font is loaded from a file outside of my assembly, it works fine and displays inside the application. If I, however, embed the font as a resouce it will not display in run-time. The default font is displayed. There is also other strange behaviour associated with this. If I double-click the font and am viewing it in the font viewer, and THEN I launch my application the font will be displayed in the application like it should. Has anyone else expereinced thins kind of problem? It's not a big deal if I had to install my font on a the user's machine. And it's not that big of a deal if I were to use the font as an external resource. But I really wanted to keep my application in as few files as possible by embedding most of my resources. Here's the code I use to pull font files from my embedded resources.
public static PrivateFontCollection GetEmbeddedFonts()
        {
            PrivateFontCollection fontCollection = new PrivateFontCollection();
            Assembly asm = Assembly.GetCallingAssembly();

            string[] embeddedResources = asm.GetManifestResourceNames();

            foreach(string resourceName in embeddedResources)
            {
                if(resourceName.ToLower().EndsWith("ttf"))
                {
                    Stream fontStream = asm.GetManifestResourceStream(resourceName);
                    byte[] buffer = new byte[fontStream.Length];
                    
                    fontStream.Read(buffer, 0, (int)fontStream.Length);
                    fontStream.Close();

                    unsafe
                    {
                        fixed (byte* pFontData = buffer)
                        {
                            fontCollection.AddMemoryFont((System.IntPtr)pFontData, buffer.Length);
                        }
                    }
                }
                
            }
            return fontCollection;
        }

It's late so I'm sorry if there is any bad grammar/typos. EDIT: Another interesting tidbit: If I override my Form's OnPaint method and use Graphics.DrawString() the font is displayed correctly but if the font is used on a label or component it is draw as the default font. Intly when it is explicitly called through Graphics.DrawString() does it show up correctly...
mutex
mutex
Do you load embedded fonts before any UI object is created?

jods
jods
I'm using embedded private fonts, too. I feel your pain, because it has been a very long and frustrating experience for me. Apparently, embedded font resources aren't very well-supported, and the feedback I got about my bug reports makes me think that Ms doesn't care a lot about them.

I'm using C# 2.0, here's my code to load one font, included as a resource in my assembly:

 class AnyClass{  // This is used to correct a bug in GDI+.   // Private fonts return garbage in GetKerningPairs if they are not installed on the system.  // Also, they don't print correctly.  [DllImport("gdi32.dll")]  private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);   private PrivateFontCollection pfc = new PrivateFontCollection();   public AnyClass()   {      unsafe      {        fixed (byte* pFontData = Resources.MyFont)        {          pfc.AddMemoryFont((IntPtr)pFontData, Resources.MyFont.Length);          AddFontMemResourceEx((IntPtr)pFontData, (uint)Resources.MyFont.Length, IntPtr.Zero, ref dummy);        }     }   }}


Note that I've included an interop call to the GDI AddFontMemResourceEx function. I managed to make my program work without this call, but it had two bugs:
- trying to get the kerning pairs for the font returned meaningless garbage.
- printing didn't work, the font was substitued by another one.

I'm accessing the font data with the compiler-generated Resources class.

Finally, I haven't tried using this font directly in the GUI (I mean: with the designer), but I'm using it successfully in some calls to DrawString.

I hope this will help you.
jods
Maxamor
Maxamor
@mutex: I'm actually working in DirectX but the test applications that I wrote created the components first and then loaded the font.

@jods: Woohoo! Thanks! The code you provided worked in my Windows Form application and in my DirectX application. I have read some of the same information as you and you're right--it's as if Microsoft doesn't want to fix it. Those punks!

But anyway, thanks again. I was almost about to just start using one big image with all the characters on it and cutting it up... which I imagine would be slow.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.